From 69eb6efd6ef4ae46399faf83aafbe1145fc1301c Mon Sep 17 00:00:00 2001 From: Gilles De Mey Date: Tue, 19 Apr 2022 15:55:54 +0200 Subject: [PATCH 001/120] Alerting: add confirmation modal for deleting notification policies (#47819) --- .../components/amroutes/AmRoutesTable.tsx | 50 ++++++++++++------- 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/public/app/features/alerting/unified/components/amroutes/AmRoutesTable.tsx b/public/app/features/alerting/unified/components/amroutes/AmRoutesTable.tsx index 8719728235e..5d8db06fc1d 100644 --- a/public/app/features/alerting/unified/components/amroutes/AmRoutesTable.tsx +++ b/public/app/features/alerting/unified/components/amroutes/AmRoutesTable.tsx @@ -1,5 +1,5 @@ import React, { FC, useCallback, useEffect, useMemo, useState } from 'react'; -import { Button, HorizontalGroup, IconButton } from '@grafana/ui'; +import { Button, ConfirmModal, HorizontalGroup, IconButton } from '@grafana/ui'; import { AmRouteReceiver, FormAmRoute } from '../../types/amroutes'; import { prepareItems } from '../../utils/dynamicTable'; import { DynamicTable, DynamicTableColumnProps, DynamicTableItemProps } from '../DynamicTable'; @@ -75,6 +75,7 @@ export const AmRoutesTable: FC = ({ alertManagerSourceName, }) => { const [editMode, setEditMode] = useState(false); + const [showDeleteModal, setShowDeleteModal] = useState(false); const [expandedId, setExpandedId] = useState(); const permissions = getNotificationsPermissions(alertManagerSourceName); const canEditRoutes = contextSrv.hasPermission(permissions.update); @@ -135,27 +136,40 @@ export const AmRoutesTable: FC = ({ }; return ( - - - { + <> + + + { + setShowDeleteModal(true); + }} + type="button" + /> + + { const newRoutes = deleteRoute(routes, item.data); onChange(newRoutes); }} - type="button" + onDismiss={() => setShowDeleteModal(false)} /> - + ); }, size: '100px', From 2d8d9bc137efd7d4b06922b6ef5ddf0a41df6add Mon Sep 17 00:00:00 2001 From: Andres Martinez Gotor Date: Tue, 19 Apr 2022 07:23:52 -0700 Subject: [PATCH 002/120] AzureMonitor: Fix Microsoft.ClassicCompute/domainNames namespace (#47877) --- .../azure_monitor/supported_namespaces.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/supported_namespaces.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/supported_namespaces.ts index d744a229e0d..8bfcfec5435 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/supported_namespaces.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/supported_namespaces.ts @@ -10,7 +10,7 @@ export default class SupportedNamespaces { 'Microsoft.Cdn/cdnwebapplicationfirewallpolicies', 'Microsoft.Cdn/profiles', 'Microsoft.ClassicCompute/virtualMachines', - 'Microsoft.ClassicCompute/domainNames/slots/roles', + 'Microsoft.ClassicCompute/domainNames', 'Microsoft.CognitiveServices/accounts', 'Microsoft.Compute/virtualMachines', 'Microsoft.Compute/virtualMachineScaleSets', @@ -96,7 +96,7 @@ export default class SupportedNamespaces { 'Microsoft.Cdn/cdnwebapplicationfirewallpolicies', 'Microsoft.Cdn/profiles', 'Microsoft.ClassicCompute/virtualMachines', - 'Microsoft.ClassicCompute/domainNames/slots/roles', + 'Microsoft.ClassicCompute/domainNames', 'Microsoft.CognitiveServices/accounts', 'Microsoft.Compute/virtualMachines', 'Microsoft.Compute/virtualMachineScaleSets', @@ -153,7 +153,7 @@ export default class SupportedNamespaces { 'Microsoft.Cdn/cdnwebapplicationfirewallpolicies', 'Microsoft.Cdn/profiles', 'Microsoft.ClassicCompute/virtualMachines', - 'Microsoft.ClassicCompute/domainNames/slots/roles', + 'Microsoft.ClassicCompute/domainNames', 'Microsoft.Compute/virtualMachines', 'Microsoft.Compute/virtualMachineScaleSets', 'Microsoft.DBforMySQL/servers', @@ -205,7 +205,7 @@ export default class SupportedNamespaces { 'Microsoft.Cdn/cdnwebapplicationfirewallpolicies', 'Microsoft.Cdn/profiles', 'Microsoft.ClassicCompute/virtualMachines', - 'Microsoft.ClassicCompute/domainNames/slots/roles', + 'Microsoft.ClassicCompute/domainNames', 'Microsoft.CognitiveServices/accounts', 'Microsoft.Compute/virtualMachines', 'Microsoft.Compute/virtualMachineScaleSets', From 992c0604f9badc2de1356ce721cd0a5667712bb4 Mon Sep 17 00:00:00 2001 From: Isabella Siu Date: Tue, 19 Apr 2022 10:50:18 -0400 Subject: [PATCH 003/120] CloudWatch: add dimensions component to variable editor (#47596) --- package.json | 2 +- .../Dimensions.test.tsx | 0 .../Dimensions.tsx | 12 +- .../FilterItem.tsx | 6 +- .../VariableQueryEditor.test.tsx | 98 ++++++++-- .../VariableQueryEditor.tsx | 37 ++-- .../VariableQueryField.tsx | 7 +- .../VariableQueryEditor/VariableTextField.tsx | 4 +- .../datasource/cloudwatch/components/index.ts | 2 +- .../datasource/cloudwatch/migration.test.ts | 13 +- .../datasource/cloudwatch/migrations.ts | 13 +- .../plugins/datasource/cloudwatch/types.ts | 9 +- .../datasource/cloudwatch/variables.test.ts | 172 ++++++++++++++++++ .../datasource/cloudwatch/variables.ts | 16 +- yarn.lock | 10 +- 15 files changed, 338 insertions(+), 63 deletions(-) rename public/app/plugins/datasource/cloudwatch/components/{MetricStatEditor => Dimensions}/Dimensions.test.tsx (100%) rename public/app/plugins/datasource/cloudwatch/components/{MetricStatEditor => Dimensions}/Dimensions.tsx (88%) rename public/app/plugins/datasource/cloudwatch/components/{MetricStatEditor => Dimensions}/FilterItem.tsx (96%) create mode 100644 public/app/plugins/datasource/cloudwatch/variables.test.ts diff --git a/package.json b/package.json index 2706e103b50..8c2633c5788 100644 --- a/package.json +++ b/package.json @@ -249,7 +249,7 @@ "@grafana/aws-sdk": "0.0.35", "@grafana/data": "workspace:*", "@grafana/e2e-selectors": "workspace:*", - "@grafana/experimental": "0.0.2-canary.22", + "@grafana/experimental": "^0.0.2-canary.25", "@grafana/google-sdk": "0.0.3", "@grafana/lezer-logql": "^0.0.11", "@grafana/runtime": "workspace:*", diff --git a/public/app/plugins/datasource/cloudwatch/components/MetricStatEditor/Dimensions.test.tsx b/public/app/plugins/datasource/cloudwatch/components/Dimensions/Dimensions.test.tsx similarity index 100% rename from public/app/plugins/datasource/cloudwatch/components/MetricStatEditor/Dimensions.test.tsx rename to public/app/plugins/datasource/cloudwatch/components/Dimensions/Dimensions.test.tsx diff --git a/public/app/plugins/datasource/cloudwatch/components/MetricStatEditor/Dimensions.tsx b/public/app/plugins/datasource/cloudwatch/components/Dimensions/Dimensions.tsx similarity index 88% rename from public/app/plugins/datasource/cloudwatch/components/MetricStatEditor/Dimensions.tsx rename to public/app/plugins/datasource/cloudwatch/components/Dimensions/Dimensions.tsx index ae645e73d6e..baccc38d70e 100644 --- a/public/app/plugins/datasource/cloudwatch/components/MetricStatEditor/Dimensions.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/Dimensions/Dimensions.tsx @@ -1,13 +1,13 @@ import { isEqual } from 'lodash'; -import React, { useMemo, useState } from 'react'; +import React, { useEffect, useState } from 'react'; import { SelectableValue } from '@grafana/data'; import { EditorList } from '@grafana/experimental'; import { CloudWatchDatasource } from '../../datasource'; -import { CloudWatchMetricsQuery, Dimensions as DimensionsType } from '../../types'; +import { Dimensions as DimensionsType, DimensionsQuery } from '../../types'; import { FilterItem } from './FilterItem'; export interface Props { - query: CloudWatchMetricsQuery; + query: DimensionsQuery; onChange: (dimensions: DimensionsType) => void; datasource: CloudWatchDatasource; dimensionKeys: Array>; @@ -43,8 +43,8 @@ const filterConditionsToDimensions = (filters: DimensionFilterCondition[]) => { }; export const Dimensions: React.FC = ({ query, datasource, dimensionKeys, disableExpressions, onChange }) => { - const dimensionFilters = useMemo(() => dimensionsToFilterConditions(query.dimensions), [query.dimensions]); - const [items, setItems] = useState(dimensionFilters); + const [items, setItems] = useState([]); + useEffect(() => setItems(dimensionsToFilterConditions(query.dimensions)), [query.dimensions]); const onDimensionsChange = (newItems: Array>) => { setItems(newItems); @@ -67,7 +67,7 @@ export const Dimensions: React.FC = ({ query, datasource, dimensionKeys, function makeRenderFilter( datasource: CloudWatchDatasource, - query: CloudWatchMetricsQuery, + query: DimensionsQuery, dimensionKeys: Array>, disableExpressions: boolean ) { diff --git a/public/app/plugins/datasource/cloudwatch/components/MetricStatEditor/FilterItem.tsx b/public/app/plugins/datasource/cloudwatch/components/Dimensions/FilterItem.tsx similarity index 96% rename from public/app/plugins/datasource/cloudwatch/components/MetricStatEditor/FilterItem.tsx rename to public/app/plugins/datasource/cloudwatch/components/Dimensions/FilterItem.tsx index b9c95a4a6c2..649d706f390 100644 --- a/public/app/plugins/datasource/cloudwatch/components/MetricStatEditor/FilterItem.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/Dimensions/FilterItem.tsx @@ -5,12 +5,12 @@ import { GrafanaTheme2, SelectableValue, toOption } from '@grafana/data'; import { InputGroup, AccessoryButton } from '@grafana/experimental'; import { Select, stylesFactory, useTheme2 } from '@grafana/ui'; import { CloudWatchDatasource } from '../../datasource'; -import { CloudWatchMetricsQuery, Dimensions } from '../../types'; +import { Dimensions, DimensionsQuery } from '../../types'; import { appendTemplateVariables } from '../../utils/utils'; import { DimensionFilterCondition } from './Dimensions'; export interface Props { - query: CloudWatchMetricsQuery; + query: DimensionsQuery; datasource: CloudWatchDatasource; filter: DimensionFilterCondition; dimensionKeys: Array>; @@ -96,7 +96,7 @@ export const FilterItem: FunctionComponent = ({ } }} /> - + ); diff --git a/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableQueryEditor.test.tsx b/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableQueryEditor.test.tsx index 62d5c7cc65c..942bf5e7a83 100644 --- a/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableQueryEditor.test.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableQueryEditor.test.tsx @@ -1,7 +1,7 @@ -import { render, screen, waitFor } from '@testing-library/react'; +import { render, screen, waitFor, within } from '@testing-library/react'; import React from 'react'; import { select } from 'react-select-event'; -import { VariableQueryType } from '../../types'; +import { Dimensions, VariableQueryType } from '../../types'; import { setupMockedDataSource } from '../../__mocks__/CloudWatchDataSource'; import { VariableQueryEditor, Props } from './VariableQueryEditor'; @@ -11,7 +11,6 @@ const defaultQuery = { region: '', metricName: '', dimensionKey: '', - dimensionFilters: '', ec2Filters: '', instanceID: '', attributeName: '', @@ -37,26 +36,42 @@ ds.datasource.getMetrics = jest.fn().mockResolvedValue([ { label: 'i3', value: 'i3' }, { label: 'j3', value: 'j3' }, ]); -ds.datasource.getDimensionKeys = jest.fn().mockImplementation((namespace: string, region: string) => { - if (region === 'a1') { - return Promise.resolve([ - { label: 'q4', value: 'q4' }, - { label: 'r4', value: 'r4' }, - { label: 's4', value: 's4' }, - ]); - } - return Promise.resolve([{ label: 't4', value: 't4' }]); -}); +ds.datasource.getDimensionKeys = jest + .fn() + .mockImplementation((namespace: string, region: string, dimensionFilters?: Dimensions) => { + if (!!dimensionFilters) { + return Promise.resolve([ + { label: 's4', value: 's4' }, + { label: 'v4', value: 'v4' }, + ]); + } + if (region === 'a1') { + return Promise.resolve([ + { label: 'q4', value: 'q4' }, + { label: 'r4', value: 'r4' }, + { label: 's4', value: 's4' }, + ]); + } + return Promise.resolve([{ label: 't4', value: 't4' }]); + }); +ds.datasource.getDimensionValues = jest.fn().mockResolvedValue([ + { label: 'foo', value: 'foo' }, + { label: 'bar', value: 'bar' }, +]); ds.datasource.getVariables = jest.fn().mockReturnValue([]); +const onChange = jest.fn(); const defaultProps: Props = { - onChange: jest.fn(), + onChange: onChange, query: defaultQuery, datasource: ds.datasource, onRunQuery: () => {}, }; describe('VariableEditor', () => { + beforeEach(() => { + onChange.mockClear(); + }); describe('and a new variable is created', () => { it('should trigger a query using the first query type in the array', async () => { const props = defaultProps; @@ -100,6 +115,56 @@ describe('VariableEditor', () => { expect(metricSelect).not.toBeInTheDocument(); }); }); + it('should parse dimensionFilters correctly', async () => { + const props = defaultProps; + props.query = { + ...defaultQuery, + queryType: VariableQueryType.DimensionValues, + namespace: 'z2', + region: 'a1', + metricName: 'i3', + dimensionKey: 's4', + dimensionFilters: { s4: 'foo' }, + }; + render(); + + const filterItem = screen.getByTestId('cloudwatch-dimensions-filter-item'); + expect(filterItem).toBeInTheDocument(); + expect(within(filterItem).getByText('s4')).toBeInTheDocument(); + expect(within(filterItem).getByText('foo')).toBeInTheDocument(); + + // change filter key + const keySelect = screen.getByRole('combobox', { name: 'Dimensions filter key' }); + // confirms getDimensionKeys was called with filter and that the element uses keysForDimensionFilter + await select(keySelect, 'v4', { + container: document.body, + }); + expect(ds.datasource.getDimensionKeys).toHaveBeenCalledWith('z2', 'a1', {}, ''); + expect(onChange).toHaveBeenCalledWith({ + ...defaultQuery, + queryType: VariableQueryType.DimensionValues, + namespace: 'z2', + region: 'a1', + metricName: 'i3', + dimensionKey: 's4', + dimensionFilters: { v4: undefined }, + }); + + // set filter value + const valueSelect = screen.getByRole('combobox', { name: 'Dimensions filter value' }); + await select(valueSelect, 'bar', { + container: document.body, + }); + expect(onChange).toHaveBeenCalledWith({ + ...defaultQuery, + queryType: VariableQueryType.DimensionValues, + namespace: 'z2', + region: 'a1', + metricName: 'i3', + dimensionKey: 's4', + dimensionFilters: { v4: 'bar' }, + }); + }); }); describe('and a different region is selected', () => { it('should clear invalid fields', async () => { @@ -111,6 +176,7 @@ describe('VariableEditor', () => { region: 'a1', metricName: 'i3', dimensionKey: 's4', + dimensionFilters: { s4: 'foo' }, }; render(); @@ -118,7 +184,6 @@ describe('VariableEditor', () => { expect(querySelect).toBeInTheDocument(); expect(screen.queryByText('Dimension Values')).toBeInTheDocument(); const regionSelect = screen.getByRole('combobox', { name: 'Region' }); - regionSelect.click(); await select(regionSelect, 'b1', { container: document.body, }); @@ -133,8 +198,9 @@ describe('VariableEditor', () => { region: 'b1', // metricName i3 exists in the new region and should not be removed metricName: 'i3', - // dimensionKey s4 does not exist in the new region and should be removed + // dimensionKey s4 and valueDimension do not exist in the new region and should be removed dimensionKey: '', + dimensionFilters: {}, }); }); }); diff --git a/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableQueryEditor.tsx b/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableQueryEditor.tsx index 6a02346cfb7..c95173f860a 100644 --- a/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableQueryEditor.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableQueryEditor.tsx @@ -7,6 +7,8 @@ import { useDimensionKeys, useMetrics, useNamespaces, useRegions } from '../../h import { CloudWatchJsonData, CloudWatchQuery, VariableQuery, VariableQueryType } from '../../types'; import { migrateVariableQuery } from '../../migrations'; import { VariableQueryField } from './VariableQueryField'; +import { Dimensions } from '..'; +import { InlineField } from '@grafana/ui'; export type Props = QueryEditorProps; @@ -25,11 +27,12 @@ const queryTypes: Array<{ value: string; label: string }> = [ export const VariableQueryEditor = ({ query, datasource, onChange }: Props) => { const parsedQuery = migrateVariableQuery(query); - const { region, namespace, metricName, dimensionKey } = parsedQuery; + const { region, namespace, metricName, dimensionKey, dimensionFilters } = parsedQuery; const [regions, regionIsLoading] = useRegions(datasource); const namespaces = useNamespaces(datasource); const metrics = useMetrics(datasource, region, namespace); const dimensionKeys = useDimensionKeys(datasource, region, namespace, metricName); + const keysForDimensionFilter = useDimensionKeys(datasource, region, namespace, metricName, dimensionFilters ?? {}); const onRegionChange = async (region: string) => { const validatedQuery = await sanitizeQuery({ @@ -48,7 +51,10 @@ export const VariableQueryEditor = ({ query, datasource, onChange }: Props) => { }; const onQueryChange = (newQuery: VariableQuery) => { - onChange({ ...newQuery, refId: 'CloudWatchVariableQueryEditor-VariableQuery' }); + onChange({ + ...newQuery, + refId: 'CloudWatchVariableQueryEditor-VariableQuery', + }); }; // Reset dimensionValue parameters if namespace or region change @@ -58,7 +64,6 @@ export const VariableQueryEditor = ({ query, datasource, onChange }: Props) => { await datasource.getMetrics(namespace, region).then((result: Array>) => { if (!result.find((metric) => metric.value === metricName)) { metricName = ''; - dimensionFilters = ''; } }); } @@ -66,7 +71,7 @@ export const VariableQueryEditor = ({ query, datasource, onChange }: Props) => { await datasource.getDimensionKeys(namespace, region).then((result: Array>) => { if (!result.find((key) => key.value === dimensionKey)) { dimensionKey = ''; - dimensionFilters = ''; + dimensionFilters = {}; } }); } @@ -86,7 +91,6 @@ export const VariableQueryEditor = ({ query, datasource, onChange }: Props) => { VariableQueryType.DimensionKeys, VariableQueryType.DimensionValues, ].includes(parsedQuery.queryType); - return ( <> { options={queryTypes} onChange={(value: VariableQueryType) => onQueryChange({ ...parsedQuery, queryType: value })} label="Query Type" + inputId={`variable-query-type-${query.refId}`} /> {hasRegionField && ( { onChange={(value: string) => onRegionChange(value)} label="Region" isLoading={regionIsLoading} + inputId={`variable-query-region-${query.refId}`} /> )} {hasNamespaceField && ( @@ -110,6 +116,7 @@ export const VariableQueryEditor = ({ query, datasource, onChange }: Props) => { options={namespaces} onChange={(value: string) => onNamespaceChange(value)} label="Namespace" + inputId={`variable-query-namespace-${query.refId}`} /> )} {parsedQuery.queryType === VariableQueryType.DimensionValues && ( @@ -119,20 +126,26 @@ export const VariableQueryEditor = ({ query, datasource, onChange }: Props) => { options={metrics} onChange={(value: string) => onQueryChange({ ...parsedQuery, metricName: value })} label="Metric" + inputId={`variable-query-metric-${query.refId}`} /> onQueryChange({ ...parsedQuery, dimensionKey: value })} label="Dimension Key" + inputId={`variable-query-dimension-key-${query.refId}`} /> - onQueryChange({ ...parsedQuery, dimensionFilters: value })} - label="Filters" - /> + + { + onChange({ ...parsedQuery, dimensionFilters: dimensions }); + }} + dimensionKeys={keysForDimensionFilter} + disableExpressions={true} + datasource={datasource} + /> + )} {parsedQuery.queryType === VariableQueryType.EBSVolumeIDs && ( diff --git a/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableQueryField.tsx b/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableQueryField.tsx index cb1fa8e82dc..890f00ba2c0 100644 --- a/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableQueryField.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableQueryField.tsx @@ -10,9 +10,9 @@ interface VariableQueryFieldProps { options: SelectableValue[]; value: T | null; label: string; + inputId?: string; allowCustomValue?: boolean; isLoading?: boolean; - inputId?: string; } export const VariableQueryField = ({ @@ -22,9 +22,10 @@ export const VariableQueryField = ({ options, allowCustomValue = false, isLoading = false, + inputId = label, }: VariableQueryFieldProps) => { return ( - + setLocalValue(e.currentTarget.value)} onBlur={() => onBlur(localValue)} - width={TEXT_WIDTH} /> ); diff --git a/public/app/plugins/datasource/cloudwatch/components/index.ts b/public/app/plugins/datasource/cloudwatch/components/index.ts index 3de2ca07ed2..0362b31b34f 100644 --- a/public/app/plugins/datasource/cloudwatch/components/index.ts +++ b/public/app/plugins/datasource/cloudwatch/components/index.ts @@ -1,4 +1,4 @@ -export { Dimensions } from './MetricStatEditor/Dimensions'; +export { Dimensions } from './Dimensions/Dimensions'; export { QueryInlineField, QueryField } from './Forms'; export { Alias } from './Alias'; export { PanelQueryEditor } from './PanelQueryEditor'; diff --git a/public/app/plugins/datasource/cloudwatch/migration.test.ts b/public/app/plugins/datasource/cloudwatch/migration.test.ts index 4c56fd06946..7f92bc72411 100644 --- a/public/app/plugins/datasource/cloudwatch/migration.test.ts +++ b/public/app/plugins/datasource/cloudwatch/migration.test.ts @@ -206,7 +206,7 @@ describe('migration', () => { expect(query.namespace).toBe('AWS/RDS'); expect(query.metricName).toBe('CPUUtilization'); expect(query.dimensionKey).toBe('DBInstanceIdentifier'); - expect(query.dimensionFilters).toBe(''); + expect(query.dimensionFilters).toStrictEqual({}); }); }); describe('and filter param is defined by user', () => { @@ -219,9 +219,18 @@ describe('migration', () => { expect(query.namespace).toBe('AWS/RDS'); expect(query.metricName).toBe('CPUUtilization'); expect(query.dimensionKey).toBe('DBInstanceIdentifier'); - expect(query.dimensionFilters).toBe('{"InstanceId":"$instance_id"}'); + expect(query.dimensionFilters).toStrictEqual({ InstanceId: '$instance_id' }); }); }); }); }); + describe('when resource_arns query is used', () => { + it('should parse the query', () => { + const query = migrateVariableQuery('resource_arns(us-east-1,rds:db,{"environment":["$environment"]})'); + expect(query.queryType).toBe(VariableQueryType.ResourceArns); + expect(query.region).toBe('us-east-1'); + expect(query.resourceType).toBe('rds:db'); + expect(query.tags).toBe('{"environment":["$environment"]}'); + }); + }); }); diff --git a/public/app/plugins/datasource/cloudwatch/migrations.ts b/public/app/plugins/datasource/cloudwatch/migrations.ts index 8bc3387e28d..5bac7b8f45f 100644 --- a/public/app/plugins/datasource/cloudwatch/migrations.ts +++ b/public/app/plugins/datasource/cloudwatch/migrations.ts @@ -80,7 +80,7 @@ export function migrateVariableQuery(rawQuery: string | VariableQuery): Variable region: '', metricName: '', dimensionKey: '', - dimensionFilters: '', + dimensionFilters: {}, ec2Filters: '', instanceID: '', attributeName: '', @@ -122,7 +122,14 @@ export function migrateVariableQuery(rawQuery: string | VariableQuery): Variable newQuery.namespace = dimensionValuesQuery[2]; newQuery.metricName = dimensionValuesQuery[3]; newQuery.dimensionKey = dimensionValuesQuery[4]; - newQuery.dimensionFilters = dimensionValuesQuery[6] || ''; + newQuery.dimensionFilters = {}; + if (!!dimensionValuesQuery[6]) { + try { + newQuery.dimensionFilters = JSON.parse(dimensionValuesQuery[6]); + } catch { + throw new Error(`unable to migrate poorly formed filters: ${dimensionValuesQuery[6]}`); + } + } return newQuery; } @@ -148,7 +155,7 @@ export function migrateVariableQuery(rawQuery: string | VariableQuery): Variable newQuery.queryType = VariableQueryType.ResourceArns; newQuery.region = resourceARNsQuery[1]; newQuery.resourceType = resourceARNsQuery[2]; - newQuery.tags = JSON.parse(resourceARNsQuery[3]) || ''; + newQuery.tags = resourceARNsQuery[3] || ''; return newQuery; } diff --git a/public/app/plugins/datasource/cloudwatch/types.ts b/public/app/plugins/datasource/cloudwatch/types.ts index 472d400b55b..c3f661b5333 100644 --- a/public/app/plugins/datasource/cloudwatch/types.ts +++ b/public/app/plugins/datasource/cloudwatch/types.ts @@ -35,6 +35,13 @@ export interface SQLExpression { limit?: number; } +export interface DimensionsQuery extends DataQuery { + namespace: string; + region: string; + metricName?: string; + dimensions?: Dimensions; +} + export interface CloudWatchMetricsQuery extends DataQuery { queryMode?: 'Metrics'; metricQueryType?: MetricQueryType; @@ -386,7 +393,7 @@ export interface VariableQuery extends DataQuery { region: string; metricName: string; dimensionKey: string; - dimensionFilters: string; + dimensionFilters?: Dimensions; ec2Filters: string; instanceID: string; attributeName: string; diff --git a/public/app/plugins/datasource/cloudwatch/variables.test.ts b/public/app/plugins/datasource/cloudwatch/variables.test.ts new file mode 100644 index 00000000000..5b2d09e77da --- /dev/null +++ b/public/app/plugins/datasource/cloudwatch/variables.test.ts @@ -0,0 +1,172 @@ +import { VariableQuery, VariableQueryType } from './types'; +import { CloudWatchVariableSupport } from './variables'; +import { setupMockedDataSource } from './__mocks__/CloudWatchDataSource'; + +const defaultQuery: VariableQuery = { + queryType: VariableQueryType.Regions, + namespace: 'foo', + region: 'bar', + metricName: '', + dimensionKey: '', + ec2Filters: '', + instanceID: '', + attributeName: '', + resourceType: '', + tags: '', + refId: '', +}; + +const ds = setupMockedDataSource(); +ds.datasource.getRegions = jest.fn().mockResolvedValue([{ label: 'a', value: 'a' }]); +ds.datasource.getNamespaces = jest.fn().mockResolvedValue([{ label: 'b', value: 'b' }]); +ds.datasource.getMetrics = jest.fn().mockResolvedValue([{ label: 'c', value: 'c' }]); +ds.datasource.getDimensionKeys = jest.fn().mockResolvedValue([{ label: 'd', value: 'd' }]); +const getDimensionValues = jest.fn().mockResolvedValue([{ label: 'e', value: 'e' }]); +const getEbsVolumeIds = jest.fn().mockResolvedValue([{ label: 'f', value: 'f' }]); +const getEc2InstanceAttribute = jest.fn().mockResolvedValue([{ label: 'g', value: 'g' }]); +const getResourceARNs = jest.fn().mockResolvedValue([{ label: 'h', value: 'h' }]); + +const variables = new CloudWatchVariableSupport(ds.datasource); + +describe('variables', () => { + it('should run regions', async () => { + const result = await variables.execute({ ...defaultQuery }); + expect(result).toEqual([{ text: 'a', value: 'a', expandable: true }]); + }); + + it('should run namespaces', async () => { + const result = await variables.execute({ ...defaultQuery, queryType: VariableQueryType.Namespaces }); + expect(result).toEqual([{ text: 'b', value: 'b', expandable: true }]); + }); + + it('should run metrics', async () => { + const result = await variables.execute({ ...defaultQuery, queryType: VariableQueryType.Metrics }); + expect(result).toEqual([{ text: 'c', value: 'c', expandable: true }]); + }); + + it('should run dimension keys', async () => { + const result = await variables.execute({ ...defaultQuery, queryType: VariableQueryType.DimensionKeys }); + expect(result).toEqual([{ text: 'd', value: 'd', expandable: true }]); + }); + + describe('dimension values', () => { + const query = { + ...defaultQuery, + queryType: VariableQueryType.DimensionValues, + metricName: 'abc', + dimensionKey: 'efg', + dimensionFilters: { a: 'b' }, + }; + beforeEach(() => { + ds.datasource.getDimensionValues = getDimensionValues; + getDimensionValues.mockClear(); + }); + + it('should not run if dimension key not set', async () => { + const result = await variables.execute({ ...query, dimensionKey: '' }); + expect(getDimensionValues).not.toBeCalled(); + expect(result).toEqual([]); + }); + + it('should not run if metric name not set', async () => { + const result = await variables.execute({ ...query, metricName: '' }); + expect(getDimensionValues).not.toBeCalled(); + expect(result).toEqual([]); + }); + it('should run if values are set', async () => { + const result = await variables.execute(query); + expect(getDimensionValues).toBeCalledWith( + query.region, + query.namespace, + query.metricName, + query.dimensionKey, + query.dimensionFilters + ); + expect(result).toEqual([{ text: 'e', value: 'e', expandable: true }]); + }); + }); + + describe('EBS volume ids', () => { + beforeEach(() => { + ds.datasource.getEbsVolumeIds = getEbsVolumeIds; + getEbsVolumeIds.mockClear(); + }); + + it('should not run if instance id not set', async () => { + const result = await variables.execute({ ...defaultQuery, queryType: VariableQueryType.EBSVolumeIDs }); + expect(getEbsVolumeIds).not.toBeCalled(); + expect(result).toEqual([]); + }); + + it('should run if instance id set', async () => { + const result = await variables.execute({ + ...defaultQuery, + queryType: VariableQueryType.EBSVolumeIDs, + instanceID: 'foo', + }); + expect(getEbsVolumeIds).toBeCalledWith(defaultQuery.region, 'foo'); + expect(result).toEqual([{ text: 'f', value: 'f', expandable: true }]); + }); + }); + + describe('EC2 instance attributes', () => { + const query = { + ...defaultQuery, + queryType: VariableQueryType.EC2InstanceAttributes, + attributeName: 'abc', + ec2Filters: '{"a":["b"]}', + }; + beforeEach(() => { + ds.datasource.getEc2InstanceAttribute = getEc2InstanceAttribute; + getEc2InstanceAttribute.mockClear(); + }); + + it('should not run if instance id not set', async () => { + const result = await variables.execute({ ...query, attributeName: '' }); + expect(getEc2InstanceAttribute).not.toBeCalled(); + expect(result).toEqual([]); + }); + + it('should run if instance id set', async () => { + const result = await variables.execute(query); + expect(getEc2InstanceAttribute).toBeCalledWith(query.region, query.attributeName, { a: ['b'] }); + expect(result).toEqual([{ text: 'g', value: 'g', expandable: true }]); + }); + }); + + describe('resource arns', () => { + const query = { + ...defaultQuery, + queryType: VariableQueryType.ResourceArns, + resourceType: 'abc', + tags: '{"a":["b"]}', + }; + beforeEach(() => { + ds.datasource.getResourceARNs = getResourceARNs; + getResourceARNs.mockClear(); + }); + + it('should not run if instance id not set', async () => { + const result = await variables.execute({ ...query, resourceType: '' }); + expect(getResourceARNs).not.toBeCalled(); + expect(result).toEqual([]); + }); + + it('should run if instance id set', async () => { + const result = await variables.execute(query); + expect(getResourceARNs).toBeCalledWith(query.region, query.resourceType, { a: ['b'] }); + expect(result).toEqual([{ text: 'h', value: 'h', expandable: true }]); + }); + }); + + it('should run statistics', async () => { + const result = await variables.execute({ ...defaultQuery, queryType: VariableQueryType.Statistics }); + expect(result).toEqual([ + { text: 'Average', value: 'Average', expandable: true }, + { text: 'Maximum', value: 'Maximum', expandable: true }, + { text: 'Minimum', value: 'Minimum', expandable: true }, + { text: 'Sum', value: 'Sum', expandable: true }, + { text: 'SampleCount', value: 'SampleCount', expandable: true }, + ]); + }); +}); diff --git a/public/app/plugins/datasource/cloudwatch/variables.ts b/public/app/plugins/datasource/cloudwatch/variables.ts index 1443df38ce3..cea8084b049 100644 --- a/public/app/plugins/datasource/cloudwatch/variables.ts +++ b/public/app/plugins/datasource/cloudwatch/variables.ts @@ -91,11 +91,13 @@ export class CloudWatchVariableSupport extends CustomVariableSupport ({ text: s.label, value: s.value, @@ -119,7 +121,7 @@ export class CloudWatchVariableSupport extends CustomVariableSupport Date: Tue, 19 Apr 2022 16:54:08 +0200 Subject: [PATCH 004/120] Show error when operations, but no stream selector (#47890) --- .../components/LokiQueryBuilder.test.tsx | 14 ++++++++++++-- .../components/LokiQueryBuilder.tsx | 17 +++++++++++++++-- .../querybuilder/shared/LabelFilters.tsx | 10 ++++++---- .../prometheus/querybuilder/testUtils.ts | 2 +- 4 files changed, 34 insertions(+), 9 deletions(-) diff --git a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.test.tsx b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.test.tsx index f931249082a..09d3e069942 100644 --- a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.test.tsx +++ b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.test.tsx @@ -3,7 +3,7 @@ import { render, screen, getAllByRole, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { LokiQueryBuilder } from './LokiQueryBuilder'; import { LokiDatasource } from '../../datasource'; -import { LokiVisualQuery } from '../types'; +import { LokiOperationId, LokiVisualQuery } from '../types'; import { PanelData } from '@grafana/data'; const defaultQuery: LokiVisualQuery = { @@ -17,10 +17,20 @@ describe('LokiQueryBuilder', () => { datasource.languageProvider.fetchSeriesLabels = jest.fn().mockReturnValue({ job: ['a'], instance: ['b'] }); userEvent.click(screen.getByLabelText('Add')); const labels = screen.getByText(/Labels/); - const selects = getAllByRole(labels.parentElement!, 'combobox'); + const selects = getAllByRole(labels.parentElement!.parentElement!.parentElement!, 'combobox'); userEvent.click(selects[3]); await waitFor(() => expect(screen.getByText('job')).toBeInTheDocument()); }); + + it('shows error for query with operations and no stream selector', async () => { + setup({ labels: [], operations: [{ id: LokiOperationId.Logfmt, params: [] }] }); + expect(screen.getByText('You need to specify at least 1 label filter (stream selector)')).toBeInTheDocument(); + }); + + it('shows no error for query with empty __line_contains operation and no stream selector', async () => { + setup({ labels: [], operations: [{ id: LokiOperationId.LineContains, params: [''] }] }); + expect(screen.queryByText('You need to specify at least 1 label filter (stream selector)')).not.toBeInTheDocument(); + }); }); function setup(query: LokiVisualQuery = defaultQuery, data?: PanelData) { diff --git a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.tsx b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.tsx index 9b84ad88348..01f000e0e29 100644 --- a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.tsx +++ b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.tsx @@ -1,5 +1,5 @@ -import React from 'react'; -import { LokiVisualQuery } from '../types'; +import React, { useMemo } from 'react'; +import { LokiOperationId, LokiVisualQuery } from '../types'; import { LokiDatasource } from '../../datasource'; import { LabelFilters } from 'app/plugins/datasource/prometheus/querybuilder/shared/LabelFilters'; import { OperationList } from 'app/plugins/datasource/prometheus/querybuilder/shared/OperationList'; @@ -57,6 +57,18 @@ export const LokiQueryBuilder = React.memo(({ datasource, query, nested, return result[forLabelInterpolated] ?? []; }; + const labelFilterError: string | undefined = useMemo(() => { + const { labels, operations: op } = query; + if (!labels.length && op.length) { + // We don't want to show error for initial state with empty line contains operation + if (op.length === 1 && op[0].id === LokiOperationId.LineContains && op[0].params[0] === '') { + return undefined; + } + return 'You need to specify at least 1 label filter (stream selector)'; + } + return undefined; + }, [query]); + return ( <> @@ -69,6 +81,7 @@ export const LokiQueryBuilder = React.memo(({ datasource, query, nested, } labelsFilters={query.labels} onChange={onChangeLabels} + error={labelFilterError} /> diff --git a/public/app/plugins/datasource/prometheus/querybuilder/shared/LabelFilters.tsx b/public/app/plugins/datasource/prometheus/querybuilder/shared/LabelFilters.tsx index bc0ca2608a6..87632d740f5 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/shared/LabelFilters.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/shared/LabelFilters.tsx @@ -1,5 +1,6 @@ import { SelectableValue } from '@grafana/data'; -import { EditorField, EditorFieldGroup, EditorList } from '@grafana/experimental'; +import { EditorFieldGroup, EditorList } from '@grafana/experimental'; +import { Field } from '@grafana/ui'; import { isEqual } from 'lodash'; import React, { useEffect, useState } from 'react'; import { QueryBuilderLabelFilter } from '../shared/types'; @@ -10,9 +11,10 @@ export interface Props { onChange: (labelFilters: QueryBuilderLabelFilter[]) => void; onGetLabelNames: (forLabel: Partial) => Promise; onGetLabelValues: (forLabel: Partial) => Promise; + error?: string; } -export function LabelFilters({ labelsFilters, onChange, onGetLabelNames, onGetLabelValues }: Props) { +export function LabelFilters({ labelsFilters, onChange, onGetLabelNames, onGetLabelValues, error }: Props) { const defaultOp = '='; const [items, setItems] = useState>>([{ op: defaultOp }]); @@ -36,7 +38,7 @@ export function LabelFilters({ labelsFilters, onChange, onGetLabelNames, onGetLa return ( - + )} /> - + ); } diff --git a/public/app/plugins/datasource/prometheus/querybuilder/testUtils.ts b/public/app/plugins/datasource/prometheus/querybuilder/testUtils.ts index d45952cbd65..8fe90238744 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/testUtils.ts +++ b/public/app/plugins/datasource/prometheus/querybuilder/testUtils.ts @@ -2,7 +2,7 @@ import { screen, getAllByRole } from '@testing-library/react'; export function getLabelSelects(index = 0) { const labels = screen.getByText(/Labels/); - const selects = getAllByRole(labels.parentElement!, 'combobox'); + const selects = getAllByRole(labels.parentElement!.parentElement!.parentElement!, 'combobox'); return { name: selects[3 * index], value: selects[3 * index + 2], From a4081aebb7a347d2726fc10b27e5f25658e9c672 Mon Sep 17 00:00:00 2001 From: Kat Yang <69819079+yangkb09@users.noreply.github.com> Date: Tue, 19 Apr 2022 10:55:49 -0400 Subject: [PATCH 005/120] Chore: Remove x from Org User (#47850) * Chore: Remove x from org users * Chore: Remove x.Dialect() from org users * :poo: * Update pkg/services/sqlstore/org_users.go Co-authored-by: ying-jeanne <74549700+ying-jeanne@users.noreply.github.com> * Update pkg/services/sqlstore/org_users.go Co-authored-by: ying-jeanne <74549700+ying-jeanne@users.noreply.github.com> * Update pkg/services/sqlstore/org_users.go Co-authored-by: ying-jeanne <74549700+ying-jeanne@users.noreply.github.com> Co-authored-by: ying-jeanne <74549700+ying-jeanne@users.noreply.github.com> --- pkg/services/sqlstore/org_users.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pkg/services/sqlstore/org_users.go b/pkg/services/sqlstore/org_users.go index 60d7e5ca8f7..a80bdad0e6b 100644 --- a/pkg/services/sqlstore/org_users.go +++ b/pkg/services/sqlstore/org_users.go @@ -107,8 +107,8 @@ func (ss *SQLStore) GetOrgUsers(ctx context.Context, query *models.GetOrgUsersQu whereParams = append(whereParams, query.UserID) } - whereConditions = append(whereConditions, fmt.Sprintf("%s.is_service_account = ?", dialect.Quote("user"))) - whereParams = append(whereParams, dialect.BooleanStr(false)) + whereConditions = append(whereConditions, fmt.Sprintf("%s.is_service_account = ?", ss.Dialect.Quote("user"))) + whereParams = append(whereParams, ss.Dialect.BooleanStr(false)) if ss.Cfg.IsFeatureToggleEnabled(featuremgmt.FlagAccesscontrol) && query.User != nil { acFilter, err := accesscontrol.Filter(query.User, "org_user.user_id", "users:id:", accesscontrol.ActionOrgUsersRead) @@ -121,7 +121,7 @@ func (ss *SQLStore) GetOrgUsers(ctx context.Context, query *models.GetOrgUsersQu if query.Query != "" { queryWithWildcards := "%" + query.Query + "%" - whereConditions = append(whereConditions, "(email "+dialect.LikeStr()+" ? OR name "+dialect.LikeStr()+" ? OR login "+dialect.LikeStr()+" ?)") + whereConditions = append(whereConditions, "(email "+ss.Dialect.LikeStr()+" ? OR name "+ss.Dialect.LikeStr()+" ? OR login "+ss.Dialect.LikeStr()+" ?)") whereParams = append(whereParams, queryWithWildcards, queryWithWildcards, queryWithWildcards) } @@ -186,7 +186,7 @@ func (ss *SQLStore) SearchOrgUsers(ctx context.Context, query *models.SearchOrgU if query.Query != "" { queryWithWildcards := "%" + query.Query + "%" - whereConditions = append(whereConditions, "(email "+dialect.LikeStr()+" ? OR name "+dialect.LikeStr()+" ? OR login "+dialect.LikeStr()+" ?)") + whereConditions = append(whereConditions, "(email "+ss.Dialect.LikeStr()+" ? OR name "+ss.Dialect.LikeStr()+" ? OR login "+ss.Dialect.LikeStr()+" ?)") whereParams = append(whereParams, queryWithWildcards, queryWithWildcards, queryWithWildcards) } @@ -260,7 +260,7 @@ func (ss *SQLStore) RemoveOrgUser(ctx context.Context, cmd *models.RemoveOrgUser } } - // validate that after delete there is at least one user with admin role in org + // validate that after delete, there is at least one user with admin role in org if err := validateOneAdminLeftInOrg(cmd.OrgId, sess); err != nil { return err } From 0c31399e34ce1a4d9cb0d1453b2e72f3cd6d54ba Mon Sep 17 00:00:00 2001 From: Yuriy Tseretyan Date: Tue, 19 Apr 2022 11:47:28 -0400 Subject: [PATCH 006/120] Alerting: Fix nav-links for RBAC and other (#47798) --- pkg/api/index.go | 4 ++-- pkg/services/ngalert/accesscontrol.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/api/index.go b/pkg/api/index.go index d7d8f5e133a..0d7f0412e01 100644 --- a/pkg/api/index.go +++ b/pkg/api/index.go @@ -484,7 +484,7 @@ func (hs *HTTPServer) buildAlertNavLinks(c *models.ReqContext, uaVisibleForOrg b hasAccess := ac.HasAccess(hs.AccessControl, c) var alertChildNavs []*dtos.NavLink - if hasAccess(ac.ReqSignedIn, ac.EvalAny(ac.EvalPermission(ac.ActionAlertingRuleRead), ac.EvalPermission(ac.ActionAlertingNotificationsExternalRead))) { + if hasAccess(ac.ReqSignedIn, ac.EvalAny(ac.EvalPermission(ac.ActionAlertingRuleRead), ac.EvalPermission(ac.ActionAlertingRuleExternalRead))) { alertChildNavs = append(alertChildNavs, &dtos.NavLink{ Text: "Alert rules", Id: "alert-list", Url: hs.Cfg.AppSubURL + "/alerting/list", Icon: "list-ul", }) @@ -572,7 +572,7 @@ func (hs *HTTPServer) buildCreateNavLinks(c *models.ReqContext) []*dtos.NavLink _, uaIsDisabledForOrg := hs.Cfg.UnifiedAlerting.DisabledOrgs[c.OrgId] uaVisibleForOrg := hs.Cfg.UnifiedAlerting.IsEnabled() && !uaIsDisabledForOrg - if uaVisibleForOrg { + if uaVisibleForOrg && hasAccess(ac.ReqSignedIn, ac.EvalAny(ac.EvalPermission(ac.ActionAlertingRuleCreate), ac.EvalPermission(ac.ActionAlertingRuleExternalWrite))) { children = append(children, &dtos.NavLink{ Text: "Alert rule", SubTitle: "Create an alert rule", Id: "alert", Icon: "bell", Url: hs.Cfg.AppSubURL + "/alerting/new", diff --git a/pkg/services/ngalert/accesscontrol.go b/pkg/services/ngalert/accesscontrol.go index 2689ef03dc1..6c77aff47a8 100644 --- a/pkg/services/ngalert/accesscontrol.go +++ b/pkg/services/ngalert/accesscontrol.go @@ -165,7 +165,7 @@ var ( Version: 2, Permissions: accesscontrol.ConcatPermissions(rulesEditorRole.Role.Permissions, instancesEditorRole.Role.Permissions, notificationsEditorRole.Role.Permissions), }, - Grants: []string{string(models.ROLE_EDITOR)}, + Grants: []string{string(models.ROLE_EDITOR), string(models.ROLE_ADMIN)}, } ) From 785145c0453a96b623096eb2815e449a094e6629 Mon Sep 17 00:00:00 2001 From: Konrad Lalik Date: Tue, 19 Apr 2022 18:43:33 +0200 Subject: [PATCH 007/120] Alerting: FGAC bug bash fixes (#47873) * Improve new alert and new silence buttons permission handling * Prevent loading alert rules when no sufficient permissions provided * Improve add and edit rule permissions * Add new rule CTA button for non-editors * Update mock * Fix imports --- .../features/alerting/unified/RuleEditor.tsx | 14 +- .../features/alerting/unified/RuleList.tsx | 30 ++-- .../alerting/unified/api/buildInfo.test.ts | 1 + .../unified/components/rules/NoRulesCTA.tsx | 10 +- .../components/silences/NoSilencesCTA.tsx | 5 +- .../alerting/unified/utils/access-control.ts | 149 ++++++++++-------- .../unified/utils/accessControlHooks.ts | 6 + .../alerting/unified/utils/datasource.ts | 24 ++- .../alerting/unified/utils/rule-form.ts | 21 +-- 9 files changed, 158 insertions(+), 102 deletions(-) create mode 100644 public/app/features/alerting/unified/utils/accessControlHooks.ts diff --git a/public/app/features/alerting/unified/RuleEditor.tsx b/public/app/features/alerting/unified/RuleEditor.tsx index 143c1f597ab..8fbd3315bc3 100644 --- a/public/app/features/alerting/unified/RuleEditor.tsx +++ b/public/app/features/alerting/unified/RuleEditor.tsx @@ -4,7 +4,6 @@ import { Alert, LinkButton, LoadingPlaceholder, useStyles2, withErrorBoundary } import Page from 'app/core/components/Page/Page'; import { useCleanup } from 'app/core/hooks/useCleanup'; import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; -import { contextSrv } from 'app/core/services/context_srv'; import { RuleIdentifier } from 'app/types/unified-alerting'; import React, { FC, useEffect } from 'react'; import { useDispatch } from 'react-redux'; @@ -13,6 +12,7 @@ import { AlertRuleForm } from './components/rule-editor/AlertRuleForm'; import { useIsRuleEditable } from './hooks/useIsRuleEditable'; import { useUnifiedAlertingSelector } from './hooks/useUnifiedAlertingSelector'; import { fetchAllPromBuildInfoAction, fetchEditableRuleAction } from './state/actions'; +import { useRulesAccess } from './utils/accessControlHooks'; import * as ruleId from './utils/rule-id'; interface ExistingRuleEditorProps { @@ -38,6 +38,7 @@ const ExistingRuleEditor: FC = ({ identifier }) => { ); } + if (error) { return ( @@ -47,12 +48,15 @@ const ExistingRuleEditor: FC = ({ identifier }) => { ); } + if (!result) { return Sorry! This rule does not exist.; } + if (isEditable === false) { return Sorry! You do not have permission to edit this rule.; } + return ; }; @@ -67,10 +71,16 @@ const RuleEditor: FC = ({ match }) => { await dispatch(fetchAllPromBuildInfoAction()); }, [dispatch]); - if (!(contextSrv.hasEditPermissionInFolders || contextSrv.isEditor)) { + const { canCreateGrafanaRules, canCreateCloudRules, canEditRules } = useRulesAccess(); + + if (!canCreateGrafanaRules && !canCreateCloudRules) { return Sorry! You are not allowed to create rules.; } + if (identifier && !canEditRules(identifier.ruleSourceName)) { + return Sorry! You are not allowed to edit rules.; + } + if (loading) { return ( diff --git a/public/app/features/alerting/unified/RuleList.tsx b/public/app/features/alerting/unified/RuleList.tsx index a2ca8e82e2f..3ca8b91ca73 100644 --- a/public/app/features/alerting/unified/RuleList.tsx +++ b/public/app/features/alerting/unified/RuleList.tsx @@ -1,24 +1,24 @@ +import { css } from '@emotion/css'; import { GrafanaTheme2, urlUtil } from '@grafana/data'; -import { useStyles2, LinkButton, withErrorBoundary, Button } from '@grafana/ui'; +import { Button, LinkButton, useStyles2, withErrorBoundary } from '@grafana/ui'; +import { useQueryParams } from 'app/core/hooks/useQueryParams'; import React, { useEffect, useMemo, useState } from 'react'; import { useDispatch } from 'react-redux'; +import { useLocation } from 'react-router-dom'; import { AlertingPageWrapper } from './components/AlertingPageWrapper'; import { NoRulesSplash } from './components/rules/NoRulesCTA'; -import { useUnifiedAlertingSelector } from './hooks/useUnifiedAlertingSelector'; -import { useFilteredRules } from './hooks/useFilteredRules'; -import { fetchAllPromAndRulerRulesAction } from './state/actions'; -import { getAllRulesSourceNames } from './utils/datasource'; -import { css } from '@emotion/css'; -import { useCombinedRuleNamespaces } from './hooks/useCombinedRuleNamespaces'; -import { RULE_LIST_POLL_INTERVAL_MS } from './utils/constants'; -import RulesFilter from './components/rules/RulesFilter'; +import { RuleListErrors } from './components/rules/RuleListErrors'; import { RuleListGroupView } from './components/rules/RuleListGroupView'; import { RuleListStateView } from './components/rules/RuleListStateView'; -import { useQueryParams } from 'app/core/hooks/useQueryParams'; -import { useLocation } from 'react-router-dom'; -import { contextSrv } from 'app/core/services/context_srv'; +import RulesFilter from './components/rules/RulesFilter'; import { RuleStats } from './components/rules/RuleStats'; -import { RuleListErrors } from './components/rules/RuleListErrors'; +import { useCombinedRuleNamespaces } from './hooks/useCombinedRuleNamespaces'; +import { useFilteredRules } from './hooks/useFilteredRules'; +import { useUnifiedAlertingSelector } from './hooks/useUnifiedAlertingSelector'; +import { fetchAllPromAndRulerRulesAction } from './state/actions'; +import { useRulesAccess } from './utils/accessControlHooks'; +import { RULE_LIST_POLL_INTERVAL_MS } from './utils/constants'; +import { getAllRulesSourceNames } from './utils/datasource'; import { getFiltersFromUrlParams } from './utils/misc'; const VIEWS = { @@ -38,6 +38,8 @@ const RuleList = withErrorBoundary( const filters = getFiltersFromUrlParams(queryParams); const filtersActive = Object.values(filters).some((filter) => filter !== undefined); + const { canCreateGrafanaRules, canCreateCloudRules } = useRulesAccess(); + const view = VIEWS[queryParams['view'] as keyof typeof VIEWS] ? (queryParams['view'] as keyof typeof VIEWS) : 'groups'; @@ -93,7 +95,7 @@ const RuleList = withErrorBoundary( )} - {(contextSrv.hasEditPermissionInFolders || contextSrv.isEditor) && ( + {(canCreateGrafanaRules || canCreateCloudRules) && ( {}); jest.mock('@grafana/runtime', () => ({ getBackendSrv: () => ({ fetch }), })); diff --git a/public/app/features/alerting/unified/components/rules/NoRulesCTA.tsx b/public/app/features/alerting/unified/components/rules/NoRulesCTA.tsx index 2a74d453395..536f959e6bd 100644 --- a/public/app/features/alerting/unified/components/rules/NoRulesCTA.tsx +++ b/public/app/features/alerting/unified/components/rules/NoRulesCTA.tsx @@ -1,10 +1,12 @@ -import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA'; -import { contextSrv } from 'app/core/services/context_srv'; -import React, { FC } from 'react'; import { CallToActionCard } from '@grafana/ui'; +import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA'; +import React, { FC } from 'react'; +import { useRulesAccess } from '../../utils/accessControlHooks'; export const NoRulesSplash: FC = () => { - if (contextSrv.hasEditPermissionInFolders || contextSrv.isEditor) { + const { canCreateGrafanaRules, canCreateCloudRules } = useRulesAccess(); + + if (canCreateGrafanaRules || canCreateCloudRules) { return ( = ({ alertManagerSourceName }) => { - if (contextSrv.isEditor) { + const permissions = getInstancesPermissions(alertManagerSourceName); + + if (contextSrv.hasAccess(permissions.create, contextSrv.isEditor)) { return ( fallBackUserRoles, actions); }; } + +export function getRulesAccess() { + return { + canCreateGrafanaRules: + contextSrv.hasEditPermissionInFolders && + contextSrv.hasAccess(rulesPermissions.create.grafana, contextSrv.isEditor), + canCreateCloudRules: contextSrv.hasAccess(rulesPermissions.create.external, contextSrv.isEditor), + canEditRules: (rulesSourceName: string) => + contextSrv.hasAccess(getRulesPermissions(rulesSourceName).update, contextSrv.isEditor), + }; +} diff --git a/public/app/features/alerting/unified/utils/accessControlHooks.ts b/public/app/features/alerting/unified/utils/accessControlHooks.ts new file mode 100644 index 00000000000..1181005f133 --- /dev/null +++ b/public/app/features/alerting/unified/utils/accessControlHooks.ts @@ -0,0 +1,6 @@ +import { useMemo } from 'react'; +import { getRulesAccess } from './access-control'; + +export function useRulesAccess() { + return useMemo(() => getRulesAccess(), []); +} diff --git a/public/app/features/alerting/unified/utils/datasource.ts b/public/app/features/alerting/unified/utils/datasource.ts index e494c62dda3..3d2385886fd 100644 --- a/public/app/features/alerting/unified/utils/datasource.ts +++ b/public/app/features/alerting/unified/utils/datasource.ts @@ -1,5 +1,7 @@ import { DataSourceJsonData, DataSourceInstanceSettings } from '@grafana/data'; +import { contextSrv } from 'app/core/services/context_srv'; import { AlertManagerDataSourceJsonData, AlertManagerImplementation } from 'app/plugins/datasource/alertmanager/types'; +import { AccessControlAction } from 'app/types'; import { RulesSource } from 'app/types/unified-alerting'; import { getAllDataSources } from './config'; @@ -15,13 +17,17 @@ export enum DataSourceType { export const RulesDataSourceTypes: string[] = [DataSourceType.Loki, DataSourceType.Prometheus]; export function getRulesDataSources() { + if (!contextSrv.hasPermission(AccessControlAction.AlertingRuleExternalRead)) { + return []; + } + return getAllDataSources() .filter((ds) => RulesDataSourceTypes.includes(ds.type) && ds.jsonData.manageAlerts !== false) .sort((a, b) => a.name.localeCompare(b.name)); } export function getRulesDataSource(rulesSourceName: string) { - return getAllDataSources().find((x) => x.name === rulesSourceName); + return getRulesDataSources().find((x) => x.name === rulesSourceName); } export function getAlertManagerDataSources() { @@ -42,11 +48,23 @@ export function getLotexDataSourceByName(dataSourceName: string): DataSourceInst } export function getAllRulesSourceNames(): string[] { - return [...getRulesDataSources().map((r) => r.name), GRAFANA_RULES_SOURCE_NAME]; + const availableRulesSources: string[] = getRulesDataSources().map((r) => r.name); + + if (contextSrv.hasPermission(AccessControlAction.AlertingRuleRead)) { + availableRulesSources.push(GRAFANA_RULES_SOURCE_NAME); + } + + return availableRulesSources; } export function getAllRulesSources(): RulesSource[] { - return [...getRulesDataSources(), GRAFANA_RULES_SOURCE_NAME]; + const availableRulesSources: RulesSource[] = getRulesDataSources(); + + if (contextSrv.hasPermission(AccessControlAction.AlertingRuleRead)) { + availableRulesSources.push(GRAFANA_RULES_SOURCE_NAME); + } + + return availableRulesSources; } export function getRulesSourceName(rulesSource: RulesSource): string { diff --git a/public/app/features/alerting/unified/utils/rule-form.ts b/public/app/features/alerting/unified/utils/rule-form.ts index bf9326f252e..c288586f1dd 100644 --- a/public/app/features/alerting/unified/utils/rule-form.ts +++ b/public/app/features/alerting/unified/utils/rule-form.ts @@ -1,39 +1,41 @@ import { DataQuery, + DataSourceRef, + getDefaultRelativeTimeRange, + IntervalValues, rangeUtil, RelativeTimeRange, ScopedVars, - getDefaultRelativeTimeRange, TimeRange, - IntervalValues, - DataSourceRef, } from '@grafana/data'; import { getDataSourceSrv } from '@grafana/runtime'; -import { contextSrv } from 'app/core/services/context_srv'; +import { ExpressionDatasourceRef } from '@grafana/runtime/src/utils/DataSourceWithBackend'; import { getNextRefIdChar } from 'app/core/utils/query'; import { DashboardModel, PanelModel } from 'app/features/dashboard/state'; import { ExpressionDatasourceUID } from 'app/features/expressions/ExpressionDatasource'; import { ExpressionQuery, ExpressionQueryType } from 'app/features/expressions/types'; import { RuleWithLocation } from 'app/types/unified-alerting'; import { + AlertQuery, Annotations, GrafanaAlertStateDecision, - AlertQuery, Labels, PostableRuleGrafanaRuleDTO, RulerRuleDTO, } from 'app/types/unified-alerting-dto'; import { EvalFunction } from '../../state/alertDef'; import { RuleFormType, RuleFormValues } from '../types/rule-form'; +import { getRulesAccess } from './access-control'; import { Annotation } from './constants'; import { isGrafanaRulesSource } from './datasource'; import { arrayToRecord, recordToArray } from './misc'; import { isAlertingRulerRule, isGrafanaRulerRule, isRecordingRulerRule } from './rules'; import { parseInterval } from './time'; -import { ExpressionDatasourceRef } from '@grafana/runtime/src/utils/DataSourceWithBackend'; -export const getDefaultFormValues = (): RuleFormValues => - Object.freeze({ +export const getDefaultFormValues = (): RuleFormValues => { + const { canCreateGrafanaRules, canCreateCloudRules } = getRulesAccess(); + + return Object.freeze({ name: '', labels: [{ key: '', value: '' }], annotations: [ @@ -42,7 +44,7 @@ export const getDefaultFormValues = (): RuleFormValues => { key: Annotation.runbookURL, value: '' }, ], dataSourceName: null, - type: !contextSrv.isEditor ? RuleFormType.grafana : undefined, // viewers can't create prom alerts + type: canCreateGrafanaRules ? RuleFormType.grafana : canCreateCloudRules ? RuleFormType.cloudAlerting : undefined, // viewers can't create prom alerts // grafana folder: null, @@ -60,6 +62,7 @@ export const getDefaultFormValues = (): RuleFormValues => forTime: 1, forTimeUnit: 'm', }); +}; export function formValuesToRulerRuleDTO(values: RuleFormValues): RulerRuleDTO { const { name, expression, forTime, forTimeUnit, type } = values; From f4e285b8b485aee7058428135de96bd1d397c272 Mon Sep 17 00:00:00 2001 From: Ryan McKinley Date: Tue, 19 Apr 2022 17:24:54 -0700 Subject: [PATCH 008/120] Timeseries: add zoom to data button (#47862) --- .../panel/candlestick/CandlestickPanel.tsx | 3 + .../state-timeline/StateTimelinePanel.tsx | 2 + .../status-history/StatusHistoryPanel.tsx | 2 + .../panel/timeseries/TimeSeriesPanel.tsx | 3 + .../timeseries/plugins/OutsideRangePlugin.tsx | 57 +++++++++++++++++++ 5 files changed, 67 insertions(+) create mode 100644 public/app/plugins/panel/timeseries/plugins/OutsideRangePlugin.tsx diff --git a/public/app/plugins/panel/candlestick/CandlestickPanel.tsx b/public/app/plugins/panel/candlestick/CandlestickPanel.tsx index fd691d5b84f..1a072900c35 100644 --- a/public/app/plugins/panel/candlestick/CandlestickPanel.tsx +++ b/public/app/plugins/panel/candlestick/CandlestickPanel.tsx @@ -19,6 +19,7 @@ import { AxisProps } from '@grafana/ui/src/components/uPlot/config/UPlotAxisBuil import { prepareCandlestickFields } from './fields'; import uPlot from 'uplot'; import { PanelDataErrorView } from '@grafana/runtime'; +import { OutsideRangePlugin } from '../timeseries/plugins/OutsideRangePlugin'; interface CandlestickPanelProps extends PanelProps {} @@ -311,6 +312,8 @@ export const CandlestickPanel: React.FC = ({ onThresholdsChange={onThresholdsChange} /> )} + + ); }} diff --git a/public/app/plugins/panel/state-timeline/StateTimelinePanel.tsx b/public/app/plugins/panel/state-timeline/StateTimelinePanel.tsx index 265b3b3d86c..eab594d6d89 100755 --- a/public/app/plugins/panel/state-timeline/StateTimelinePanel.tsx +++ b/public/app/plugins/panel/state-timeline/StateTimelinePanel.tsx @@ -6,6 +6,7 @@ import { TimelineChart } from './TimelineChart'; import { prepareTimelineFields, prepareTimelineLegendItems } from './utils'; import { StateTimelineTooltip } from './StateTimelineTooltip'; import { getLastStreamingDataFramePacket } from 'app/features/live/data/StreamingDataFrame'; +import { OutsideRangePlugin } from '../timeseries/plugins/OutsideRangePlugin'; interface TimelinePanelProps extends PanelProps {} @@ -114,6 +115,7 @@ export const StateTimelinePanel: React.FC = ({ timeZone={timeZone} renderTooltip={renderCustomTooltip} /> + ); }} diff --git a/public/app/plugins/panel/status-history/StatusHistoryPanel.tsx b/public/app/plugins/panel/status-history/StatusHistoryPanel.tsx index 4552ac8477e..4c62207981e 100755 --- a/public/app/plugins/panel/status-history/StatusHistoryPanel.tsx +++ b/public/app/plugins/panel/status-history/StatusHistoryPanel.tsx @@ -5,6 +5,7 @@ import { StatusPanelOptions } from './types'; import { TimelineChart } from '../state-timeline/TimelineChart'; import { TimelineMode } from '../state-timeline/types'; import { prepareTimelineFields, prepareTimelineLegendItems } from '../state-timeline/utils'; +import { OutsideRangePlugin } from '../timeseries/plugins/OutsideRangePlugin'; interface TimelinePanelProps extends PanelProps {} @@ -68,6 +69,7 @@ export const StatusHistoryPanel: React.FC = ({ <> + ); }} diff --git a/public/app/plugins/panel/timeseries/TimeSeriesPanel.tsx b/public/app/plugins/panel/timeseries/TimeSeriesPanel.tsx index 5eb7e489b41..06c19a7a434 100644 --- a/public/app/plugins/panel/timeseries/TimeSeriesPanel.tsx +++ b/public/app/plugins/panel/timeseries/TimeSeriesPanel.tsx @@ -12,6 +12,7 @@ import { AnnotationEditorPlugin } from './plugins/AnnotationEditorPlugin'; import { ThresholdControlsPlugin } from './plugins/ThresholdControlsPlugin'; import { config } from 'app/core/config'; import { PanelDataErrorView } from '@grafana/runtime'; +import { OutsideRangePlugin } from './plugins/OutsideRangePlugin'; interface TimeSeriesPanelProps extends PanelProps {} @@ -134,6 +135,8 @@ export const TimeSeriesPanel: React.FC = ({ onThresholdsChange={onThresholdsChange} /> )} + + ); }} diff --git a/public/app/plugins/panel/timeseries/plugins/OutsideRangePlugin.tsx b/public/app/plugins/panel/timeseries/plugins/OutsideRangePlugin.tsx new file mode 100644 index 00000000000..c8f37bf5aa5 --- /dev/null +++ b/public/app/plugins/panel/timeseries/plugins/OutsideRangePlugin.tsx @@ -0,0 +1,57 @@ +import React, { useLayoutEffect, useRef } from 'react'; +import { TimeRange, AbsoluteTimeRange } from '@grafana/data'; +import { UPlotConfigBuilder, Button } from '@grafana/ui'; +import uPlot from 'uplot'; + +interface ThresholdControlsPluginProps { + config: UPlotConfigBuilder; + range: TimeRange; + onChangeTimeRange: (timeRange: AbsoluteTimeRange) => void; +} + +export const OutsideRangePlugin: React.FC = ({ config, range, onChangeTimeRange }) => { + const plotInstance = useRef(); + + useLayoutEffect(() => { + config.addHook('init', (u) => { + plotInstance.current = u; + }); + }, [config]); + + const timevalues = plotInstance.current?.data?.[0]; + if (!timevalues || !plotInstance.current || timevalues.length < 2 || !onChangeTimeRange) { + return null; + } + + // Time values are always sorted for uPlot to work + const first = timevalues[0]; + const last = timevalues[timevalues.length - 1]; + const fromX = range.from.valueOf(); + const toX = range.to.valueOf(); + + // (StartA <= EndB) and (EndA >= StartB) + if (first <= toX && last >= fromX) { + return null; + } + + return ( +
+
+
Data outside time range
+ +
+
+ ); +}; + +OutsideRangePlugin.displayName = 'OutsideRangePlugin'; From 89fa35a53fd8582b97e116739688944822f73730 Mon Sep 17 00:00:00 2001 From: Ryan McKinley Date: Tue, 19 Apr 2022 17:42:29 -0700 Subject: [PATCH 009/120] Testdata: introduce basic simulation framework (#47863) --- .github/CODEOWNERS | 1 + pkg/tsdb/testdatasource/flight_path.go | 135 -------- pkg/tsdb/testdatasource/resource_handler.go | 2 + pkg/tsdb/testdatasource/scenarios.go | 8 +- pkg/tsdb/testdatasource/sims/engine.go | 305 ++++++++++++++++++ pkg/tsdb/testdatasource/sims/engine_test.go | 64 ++++ pkg/tsdb/testdatasource/sims/flight_path.go | 131 ++++++++ .../{ => sims}/flight_path_test.go | 30 +- .../testdata/flight_path_query_A.txt} | 6 +- pkg/tsdb/testdatasource/sims/types.go | 51 +++ pkg/tsdb/testdatasource/sims/utils.go | 76 +++++ pkg/tsdb/testdatasource/sims/utils_test.go | 30 ++ pkg/tsdb/testdatasource/sims/waveform.go | 115 +++++++ pkg/tsdb/testdatasource/stream_handler.go | 89 +++-- pkg/tsdb/testdatasource/testdata.go | 8 + .../datasource/testdata/QueryEditor.tsx | 38 ++- .../components/SimulationQueryEditor.tsx | 83 +++++ .../app/plugins/datasource/testdata/types.ts | 13 + 18 files changed, 968 insertions(+), 217 deletions(-) delete mode 100644 pkg/tsdb/testdatasource/flight_path.go create mode 100644 pkg/tsdb/testdatasource/sims/engine.go create mode 100644 pkg/tsdb/testdatasource/sims/engine_test.go create mode 100644 pkg/tsdb/testdatasource/sims/flight_path.go rename pkg/tsdb/testdatasource/{ => sims}/flight_path_test.go (61%) rename pkg/tsdb/testdatasource/{testdata/flight-simple-X.txt => sims/testdata/flight_path_query_A.txt} (95%) create mode 100644 pkg/tsdb/testdatasource/sims/types.go create mode 100644 pkg/tsdb/testdatasource/sims/utils.go create mode 100644 pkg/tsdb/testdatasource/sims/utils_test.go create mode 100644 pkg/tsdb/testdatasource/sims/waveform.go create mode 100644 public/app/plugins/datasource/testdata/components/SimulationQueryEditor.tsx diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index fe6e7f3b57c..b421e6f3663 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -59,6 +59,7 @@ go.sum @grafana/backend-platform /pkg/services/searchV2/ @grafana/grafana-edge-squad /pkg/services/store/ @grafana/grafana-edge-squad /pkg/infra/filestore/ @grafana/grafana-edge-squad +pkg/tsdb/testdatasource/sims/ @grafana/grafana-edge-squad # Alerting /pkg/services/ngalert @grafana/alerting-squad-backend diff --git a/pkg/tsdb/testdatasource/flight_path.go b/pkg/tsdb/testdatasource/flight_path.go deleted file mode 100644 index 1176768f92f..00000000000 --- a/pkg/tsdb/testdatasource/flight_path.go +++ /dev/null @@ -1,135 +0,0 @@ -package testdatasource - -import ( - "context" - "fmt" - "math" - "time" - - "github.com/grafana/grafana-plugin-sdk-go/backend" - "github.com/grafana/grafana-plugin-sdk-go/data" - "github.com/grafana/grafana/pkg/components/simplejson" -) - -func (s *Service) handleFlightPathScenario(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) { - resp := backend.NewQueryDataResponse() - - for _, q := range req.Queries { - _, err := simplejson.NewJson(q.JSON) - if err != nil { - return nil, fmt.Errorf("failed to parse query json: %v", err) - } - - timeWalkerMs := q.TimeRange.From.UnixNano() / int64(time.Millisecond) - to := q.TimeRange.To.UnixNano() / int64(time.Millisecond) - stepMillis := q.Interval.Milliseconds() - - cfg := newFlightConfig() - - maxPoints := q.MaxDataPoints * 2 - f := cfg.initFields() - for i := int64(0); i < maxPoints && timeWalkerMs < to; i++ { - t := time.Unix(timeWalkerMs/int64(1e+3), (timeWalkerMs%int64(1e+3))*int64(1e+6)).UTC() - f.append(cfg.getNextPoint(t)) - - timeWalkerMs += stepMillis - } - - // When close to now, link to the live streaming channel - if q.TimeRange.To.Add(time.Second * 2).After(time.Now()) { - f.frame.Meta = &data.FrameMeta{ - Channel: "plugin/testdata/flight-5hz-stream", - } - } - - respD := resp.Responses[q.RefID] - respD.Frames = append(respD.Frames, f.frame) - resp.Responses[q.RefID] = respD - } - - return resp, nil -} - -type flightDataPoint struct { - time time.Time - lat float64 // gps - lng float64 // gps - heading float64 // degree - altitude float64 // above ground -} - -type flightConfig struct { - centerLat float64 - centerLng float64 - radius float64 - altitudeMin float64 - altitudeMax float64 - periodS float64 // angular speed -} - -func newFlightConfig() *flightConfig { - return &flightConfig{ - centerLat: 37.83, // San francisco - centerLng: -122.42487, - radius: 0.01, // raw gps degrees - altitudeMin: 350, - altitudeMax: 400, - periodS: 10, //model.Get("period").MustFloat64(10), - } -} - -type flightFields struct { - time *data.Field - lat *data.Field - lng *data.Field - heading *data.Field - altitude *data.Field - - frame *data.Frame -} - -func (f *flightConfig) initFields() *flightFields { - ff := &flightFields{ - time: data.NewFieldFromFieldType(data.FieldTypeTime, 0), - lat: data.NewFieldFromFieldType(data.FieldTypeFloat64, 0), - lng: data.NewFieldFromFieldType(data.FieldTypeFloat64, 0), - heading: data.NewFieldFromFieldType(data.FieldTypeFloat64, 0), - altitude: data.NewFieldFromFieldType(data.FieldTypeFloat64, 0), - } - ff.time.Name = "time" - ff.lat.Name = "lat" - ff.lng.Name = "lng" - ff.heading.Name = "heading" - ff.altitude.Name = "altitude" - - ff.frame = data.NewFrame("", ff.time, ff.lat, ff.lng, ff.heading, ff.altitude) - return ff -} - -func (f *flightFields) append(v flightDataPoint) { - f.frame.AppendRow(v.time, v.lat, v.lng, v.heading, v.altitude) -} - -func (f *flightFields) set(idx int, v flightDataPoint) { - f.time.Set(idx, v.time) - f.lat.Set(idx, v.lat) - f.lng.Set(idx, v.lng) - f.heading.Set(idx, v.heading) - f.altitude.Set(idx, v.altitude) -} - -func (f *flightConfig) getNextPoint(t time.Time) flightDataPoint { - periodNS := int64(f.periodS * float64(time.Second)) - ms := t.UnixNano() % periodNS - per := float64(ms) / float64(periodNS) - rad := per * 2.0 * math.Pi // 0 >> 2Pi - delta := f.altitudeMax - f.altitudeMin - - return flightDataPoint{ - time: t, - lat: f.centerLat + math.Sin(rad)*f.radius, - lng: f.centerLng + math.Cos(rad)*f.radius, - heading: (rad * 180) / math.Pi, // (math.Atanh(rad) * 180.0) / math.Pi, // in degrees - altitude: f.altitudeMin + (delta * per), // clif - } -} diff --git a/pkg/tsdb/testdatasource/resource_handler.go b/pkg/tsdb/testdatasource/resource_handler.go index 76bbed47e42..8b64a2cfeb8 100644 --- a/pkg/tsdb/testdatasource/resource_handler.go +++ b/pkg/tsdb/testdatasource/resource_handler.go @@ -23,6 +23,8 @@ func (s *Service) registerRoutes() *http.ServeMux { mux.Handle("/test", createJSONHandler(s.logger)) mux.Handle("/test/json", createJSONHandler(s.logger)) mux.HandleFunc("/boom", s.testPanicHandler) + mux.HandleFunc("/sims", s.sims.GetSimulationHandler) + mux.HandleFunc("/sim/", s.sims.GetSimulationHandler) return mux } diff --git a/pkg/tsdb/testdatasource/scenarios.go b/pkg/tsdb/testdatasource/scenarios.go index e49d760cef2..c73ec20497f 100644 --- a/pkg/tsdb/testdatasource/scenarios.go +++ b/pkg/tsdb/testdatasource/scenarios.go @@ -30,7 +30,7 @@ const ( predictablePulseQuery queryType = "predictable_pulse" predictableCSVWaveQuery queryType = "predictable_csv_wave" streamingClientQuery queryType = "streaming_client" - flightPath queryType = "flight_path" + simulation queryType = "simulation" usaQueryKey queryType = "usa" liveQuery queryType = "live" grafanaAPIQuery queryType = "grafana_api" @@ -135,9 +135,9 @@ Timestamps will line up evenly on timeStepSeconds (For example, 60 seconds means }) s.registerScenario(&Scenario{ - ID: string(flightPath), - Name: "Flight path", - handler: s.handleFlightPathScenario, + ID: string(simulation), + Name: "Simulation", + handler: s.sims.QueryData, }) s.registerScenario(&Scenario{ diff --git a/pkg/tsdb/testdatasource/sims/engine.go b/pkg/tsdb/testdatasource/sims/engine.go new file mode 100644 index 00000000000..f2e0ba33500 --- /dev/null +++ b/pkg/tsdb/testdatasource/sims/engine.go @@ -0,0 +1,305 @@ +package sims + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "strconv" + "strings" + "sync" + "time" + + "github.com/grafana/grafana/pkg/infra/log" + + "github.com/grafana/grafana-plugin-sdk-go/backend" + "github.com/grafana/grafana-plugin-sdk-go/data" +) + +var ( + _ backend.StreamHandler = (*SimulationEngine)(nil) + _ backend.QueryDataHandler = (*SimulationEngine)(nil) +) + +type SimulationEngine struct { + logger log.Logger + + // Lookup by Type + registry map[string]simulationInfo + + // The running instances + running map[string]Simulation + + // safe changes + mutex sync.Mutex +} + +func (s *SimulationEngine) register(info simulationInfo) error { + if info.create == nil { + return fmt.Errorf("invalid simulation -- missing create function: " + info.Type) + } + if info.Type == "" { + return fmt.Errorf("missing type") + } + + s.mutex.Lock() + defer s.mutex.Unlock() + + _, ok := s.registry[info.Type] + if ok { + return fmt.Errorf("already registered") + } + + s.registry[info.Type] = info + return nil +} + +type simulationInitializer = func() simulationInfo + +func NewSimulationEngine() (*SimulationEngine, error) { + s := &SimulationEngine{ + registry: make(map[string]simulationInfo), + running: make(map[string]Simulation), + logger: log.New("tsdb.sims"), + } + // Initialize each type + initializers := []simulationInitializer{ + newFlightSimInfo, + newSinewaveInfo, + } + + for _, init := range initializers { + err := s.register(init()) + if err != nil { + return s, err + } + } + return s, nil +} + +func (s *SimulationEngine) Lookup(info simulationState) (Simulation, error) { + hz := info.Key.TickHZ + if hz < (1 / 60.0) { + return nil, fmt.Errorf("frequency is too slow") + } + if hz > 50 { + return nil, fmt.Errorf("frequency is too fast") + } + if info.Key.Type == "" { + return nil, fmt.Errorf("missing simulation type") + } + + key := info.Key.String() + s.mutex.Lock() + defer s.mutex.Unlock() + + v, ok := s.running[key] + if ok { + return v, nil + } + + t, ok := s.registry[info.Key.Type] + if !ok { + return nil, fmt.Errorf("unknown simulation type") + } + + v, err := t.create(info) + if err == nil { + s.running[key] = v + } + return v, err +} + +type simulationQuery struct { + simulationState + Last bool `json:"last"` + Stream bool `json:"stream"` +} + +type dumbQueryQrapper struct { + Sim simulationQuery `json:"sim"` +} + +func (s *SimulationEngine) QueryData(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) { + resp := backend.NewQueryDataResponse() + + for _, q := range req.Queries { + wrap := &dumbQueryQrapper{} + err := json.Unmarshal(q.JSON, wrap) + if err != nil { + return nil, fmt.Errorf("failed to parse query json: %v", err) + } + sq := wrap.Sim + if sq.Key.TickHZ == 0 { + sq.Key.TickHZ = 10 + } + + sim, err := s.Lookup(sq.simulationState) + if err != nil { + return nil, fmt.Errorf("error fetching simulation: %v", err) + } + + if sim == nil { + return nil, fmt.Errorf("invalid simulation: %v", sq) + } + + frame := sim.NewFrame(0) + if sq.Last { + v := sim.GetValues(q.TimeRange.To) + appendFrameRow(frame, v) + } else { + timeWalkerMs := q.TimeRange.From.UnixNano() / int64(time.Millisecond) + to := q.TimeRange.To.UnixNano() / int64(time.Millisecond) + stepMillis := q.Interval.Milliseconds() + + maxPoints := q.MaxDataPoints * 2 + for i := int64(0); i < maxPoints && timeWalkerMs < to; i++ { + t := time.UnixMilli(timeWalkerMs).UTC() + appendFrameRow(frame, sim.GetValues(t)) + timeWalkerMs += stepMillis + } + } + + if sq.Stream && req.PluginContext.DataSourceInstanceSettings != nil { + uid := req.PluginContext.DataSourceInstanceSettings.UID + frame.Meta = &data.FrameMeta{ + Channel: fmt.Sprintf("ds/%s/sim/%s", uid, sim.GetState().Key.String()), + } + } + + respD := resp.Responses[q.RefID] + respD.Frames = append(respD.Frames, frame) + resp.Responses[q.RefID] = respD + } + + return resp, nil +} + +func (s *SimulationEngine) getSimFromPath(path string) (Simulation, error) { + idx := strings.Index(path, "sim/") + if idx >= 0 { + path = path[idx+4:] + } + + parts := strings.Split(path, "/") + if len(parts) < 2 { + return nil, fmt.Errorf("missing frequency") + } + if !strings.HasSuffix(parts[1], "hz") { + return nil, fmt.Errorf("invalid path frequency. Expecting `hz` suffix") + } + hz, err := strconv.ParseFloat(strings.TrimSuffix(parts[1], "hz"), 64) + if err != nil { + return nil, fmt.Errorf("error parsing frequency from: %s", parts[1]) + } + if len(parts) == 2 { + parts = append(parts, "") // empty UID + } + + key := simulationKey{ + Type: parts[0], + TickHZ: hz, + UID: parts[2], + } + if path != key.String() { + return nil, fmt.Errorf("path should match: %s", key.String()) + } + + return s.Lookup(simulationState{ + Key: key, + }) +} + +func (s *SimulationEngine) GetSimulationHandler(rw http.ResponseWriter, req *http.Request) { + var result interface{} + path := req.URL.Path + if path == "/sims" { + v := make([]simulationInfo, 0, len(s.registry)) + for _, value := range s.registry { + v = append(v, value) + } + result = v + } else if strings.HasPrefix(path, "/sim/") { + rw.WriteHeader(400) + sim, err := s.getSimFromPath(path) + if err != nil { + http.Error(rw, err.Error(), http.StatusNotFound) + return + } + + // With a POST, update the values + if req.Method == "POST" { + body, err := getBodyFromRequest(req) + if err == nil { + err = sim.SetConfig(body) + } + if err != nil { + http.Error(rw, err.Error(), http.StatusBadRequest) + return + } + } + result = sim.GetState() + } + + bytes, err := json.Marshal(&result) + if err != nil { + s.logger.Error("Failed to marshal response body to JSON", "error", err) + } + + rw.Header().Set("Content-Type", "application/json") + rw.WriteHeader(http.StatusOK) + if _, err := rw.Write(bytes); err != nil { + s.logger.Error("Failed to write response", "error", err) + } +} + +func (s *SimulationEngine) SubscribeStream(ctx context.Context, req *backend.SubscribeStreamRequest) (*backend.SubscribeStreamResponse, error) { + sim, err := s.getSimFromPath(req.Path) // includes sim + if err != nil { + return nil, err + } + + frame := sim.NewFrame(1) + setFrameRow(frame, 0, sim.GetValues(time.Now())) + initial, err := backend.NewInitialFrame(frame, data.IncludeAll) + + return &backend.SubscribeStreamResponse{ + Status: backend.SubscribeStreamStatusOK, + InitialData: initial, + }, err +} + +func (s *SimulationEngine) RunStream(ctx context.Context, req *backend.RunStreamRequest, sender *backend.StreamSender) error { + sim, err := s.getSimFromPath(req.Path) // includes sim + if err != nil { + return err + } + + frequency := 1.0 / sim.GetState().Key.TickHZ + ticker := time.NewTicker(time.Duration(frequency * float64(time.Second))) + defer ticker.Stop() + + mode := data.IncludeDataOnly + + frame := sim.NewFrame(1) + + for { + select { + case <-ctx.Done(): + return ctx.Err() + + case t := <-ticker.C: + setFrameRow(frame, 0, sim.GetValues(t)) + err := sender.SendFrame(frame, mode) + if err != nil { + return err + } + } + } +} + +func (s *SimulationEngine) PublishStream(_ context.Context, req *backend.PublishStreamRequest) (*backend.PublishStreamResponse, error) { + return &backend.PublishStreamResponse{ + Status: backend.PublishStreamStatusPermissionDenied, + }, nil +} diff --git a/pkg/tsdb/testdatasource/sims/engine_test.go b/pkg/tsdb/testdatasource/sims/engine_test.go new file mode 100644 index 00000000000..3f406d46304 --- /dev/null +++ b/pkg/tsdb/testdatasource/sims/engine_test.go @@ -0,0 +1,64 @@ +package sims + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestCoreSimulationRegistry(t *testing.T) { + sims, err := NewSimulationEngine() + require.NoError(t, err) + v, err := sims.Lookup(simulationState{ + Key: simulationKey{ + Type: "flight", + TickHZ: 1, + }, + Config: map[string]interface{}{ + "period": 100, + "radius": 0.05, + }, + }) + require.NoError(t, err) + + cfg, err := json.MarshalIndent(v.GetState(), "", " ") + require.NoError(t, err) + require.JSONEq(t, `{ + "key": { + "type": "flight", + "tick": 1 + }, + "config": { + "centerLat":37.83, + "centerLng":-122.42487, + "altitudeMax":400, + "altitudeMin":350, + "period":100, + "radius":0.05 + } + }`, string(cfg)) + + path := v.GetState().Key.String() + found, err := sims.getSimFromPath("sim/" + path) + require.NoError(t, err) + require.Equal(t, v, found) + + found, err = sims.getSimFromPath("/sim/" + path) + require.NoError(t, err) + require.Equal(t, v, found) + + found, err = sims.getSimFromPath(path) + require.NoError(t, err) + require.Equal(t, v, found) + + // In valid paths + _, err = sims.getSimFromPath("flight/1.00hz") + require.Error(t, err) + + _, err = sims.getSimFromPath("flight/1") + require.Error(t, err) + + _, err = sims.getSimFromPath("flight/1/") + require.Error(t, err) +} diff --git a/pkg/tsdb/testdatasource/sims/flight_path.go b/pkg/tsdb/testdatasource/sims/flight_path.go new file mode 100644 index 00000000000..0bc00fc5395 --- /dev/null +++ b/pkg/tsdb/testdatasource/sims/flight_path.go @@ -0,0 +1,131 @@ +package sims + +import ( + "math" + "time" + + "github.com/grafana/grafana-plugin-sdk-go/data" +) + +type flightSim struct { + key simulationKey + cfg flightConfig +} + +var ( + _ Simulation = (*flightSim)(nil) +) + +type flightDataPoint struct { + time time.Time + lat float64 // gps + lng float64 // gps + heading float64 // degree + altitude float64 // above ground +} + +type flightConfig struct { + CenterLat float64 `json:"centerLat"` + CenterLng float64 `json:"centerLng"` + Radius float64 `json:"radius"` + AltitudeMin float64 `json:"altitudeMin"` + AltitudeMax float64 `json:"altitudeMax"` + Period float64 `json:"period"` // angular speed (seconds) +} + +func (s *flightSim) GetState() simulationState { + return simulationState{ + Key: s.key, + Config: s.cfg, + } +} + +func (s *flightSim) SetConfig(vals map[string]interface{}) error { + return updateConfigObjectFromJSON(s.cfg, vals) +} + +func (s *flightSim) NewFrame(size int) *data.Frame { + frame := data.NewFrameOfFieldTypes("", size, + data.FieldTypeTime, // time + data.FieldTypeFloat64, // lat + data.FieldTypeFloat64, // lng + data.FieldTypeFloat64, // heading + data.FieldTypeFloat64, // altitude + ) + frame.Fields[0].Name = "time" + frame.Fields[1].Name = "lat" + frame.Fields[2].Name = "lng" + frame.Fields[3].Name = "heading" + frame.Fields[4].Name = "altitude" + return frame +} + +func (s *flightSim) GetValues(t time.Time) map[string]interface{} { + p := s.cfg.getNextPoint(t) + + return map[string]interface{}{ + "time": p.time, + "lat": p.lat, + "lng": p.lng, + "heading": p.heading, + "altitude": p.altitude, + } +} + +func (s *flightSim) Close() error { + return nil +} + +func newFlightSimInfo() simulationInfo { + sf := flightConfig{ + CenterLat: 37.83, // San francisco + CenterLng: -122.42487, + Radius: 0.01, // raw gps degrees + AltitudeMin: 350, + AltitudeMax: 400, + Period: 10, //model.Get("period").MustFloat64(10), + } + + df := data.NewFrame("") + df.Fields = append(df.Fields, data.NewField("centerLat", nil, []float64{sf.CenterLat})) + df.Fields = append(df.Fields, data.NewField("centerLng", nil, []float64{sf.CenterLng})) + df.Fields = append(df.Fields, data.NewField("radius", nil, []float64{sf.Radius})) + df.Fields = append(df.Fields, data.NewField("altitudeMin", nil, []float64{sf.AltitudeMin})) + df.Fields = append(df.Fields, data.NewField("altitudeMax", nil, []float64{sf.AltitudeMax})) + + f := data.NewField("period", nil, []float64{sf.Period}) + f.Config = &data.FieldConfig{Unit: "s"} // seconds + df.Fields = append(df.Fields, f) + + return simulationInfo{ + Type: "flight", + Name: "Flight", + Description: "simple circling airplain", + SetupFields: df, + OnlyForward: false, + create: func(cfg simulationState) (Simulation, error) { + s := &flightSim{ + key: cfg.Key, + cfg: sf, // default value + } + err := updateConfigObjectFromJSON(&s.cfg, cfg.Config) // override any fields + return s, err + }, + } +} + +func (f *flightConfig) getNextPoint(t time.Time) flightDataPoint { + periodNS := int64(f.Period * float64(time.Second)) + ms := t.UnixNano() % periodNS + per := float64(ms) / float64(periodNS) + rad := per * 2.0 * math.Pi // 0 >> 2Pi + delta := f.AltitudeMax - f.AltitudeMin + + return flightDataPoint{ + time: t, + lat: f.CenterLat + math.Sin(rad)*f.Radius, + lng: f.CenterLng + math.Cos(rad)*f.Radius, + heading: (rad * 180) / math.Pi, // (math.Atanh(rad) * 180.0) / math.Pi, // in degrees + altitude: f.AltitudeMin + (delta * per), // clif + } +} diff --git a/pkg/tsdb/testdatasource/flight_path_test.go b/pkg/tsdb/testdatasource/sims/flight_path_test.go similarity index 61% rename from pkg/tsdb/testdatasource/flight_path_test.go rename to pkg/tsdb/testdatasource/sims/flight_path_test.go index 24ca8a80755..b62a68e31e6 100644 --- a/pkg/tsdb/testdatasource/flight_path_test.go +++ b/pkg/tsdb/testdatasource/sims/flight_path_test.go @@ -1,4 +1,4 @@ -package testdatasource +package sims import ( "context" @@ -10,39 +10,47 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/experimental" - "github.com/grafana/grafana/pkg/setting" "github.com/stretchr/testify/require" ) -func TestFlightPathScenario(t *testing.T) { - cfg := setting.NewCfg() - s := &Service{ - cfg: cfg, - } +func TestFlightPathQuery(t *testing.T) { + s, err := NewSimulationEngine() + require.NoError(t, err) t.Run("simple flight", func(t *testing.T) { + sq := &simulationQuery{} + sq.Key = simulationKey{ + Type: "flight", + TickHZ: 1, + } + sq.Stream = true + sb, err := json.Marshal(map[string]interface{}{ + "sim": sq, + }) + require.NoError(t, err) + start := time.Date(2020, time.January, 10, 23, 0, 0, 0, time.UTC) qr := &backend.QueryDataRequest{ Queries: []backend.DataQuery{ { - RefID: "X", + RefID: "A", TimeRange: backend.TimeRange{ From: start, To: start.Add(time.Second * 10), }, Interval: time.Second, MaxDataPoints: 10, - JSON: json.RawMessage(`{}`), // always 10s? + JSON: sb, }, }, } - rsp, err := s.handleFlightPathScenario(context.Background(), qr) + rsp, err := s.QueryData(context.Background(), qr) require.NoError(t, err) require.NotNil(t, rsp) for k, v := range rsp.Responses { dr := v - filePath := filepath.Join("testdata", fmt.Sprintf("flight-simple-%s.txt", k)) + filePath := filepath.Join("testdata", fmt.Sprintf("flight_path_query_%s.txt", k)) err = experimental.CheckGoldenDataResponse(filePath, &dr, true) require.NoError(t, err) } diff --git a/pkg/tsdb/testdatasource/testdata/flight-simple-X.txt b/pkg/tsdb/testdatasource/sims/testdata/flight_path_query_A.txt similarity index 95% rename from pkg/tsdb/testdatasource/testdata/flight-simple-X.txt rename to pkg/tsdb/testdatasource/sims/testdata/flight_path_query_A.txt index eef49197339..a7ce0755c65 100644 --- a/pkg/tsdb/testdatasource/testdata/flight-simple-X.txt +++ b/pkg/tsdb/testdatasource/sims/testdata/flight_path_query_A.txt @@ -1,7 +1,7 @@ 🌟 This was machine generated. Do not edit. 🌟 -Frame[0] -Name: +Frame[0] +Name: Dimensions: 5 Fields by 10 Rows +-------------------------------+--------------------+---------------------+-----------------+-----------------+ | Name: time | Name: lat | Name: lng | Name: heading | Name: altitude | @@ -22,4 +22,4 @@ Dimensions: 5 Fields by 10 Rows ====== TEST DATA RESPONSE (arrow base64) ====== -FRAME=QVJST1cxAAD/////gAIAABAAAAAAAAoADgAMAAsABAAKAAAAFAAAAAAAAAEDAAoADAAAAAgABAAKAAAACAAAAFAAAAACAAAAKAAAAAQAAAAM/v//CAAAAAwAAAAAAAAAAAAAAAUAAAByZWZJZAAAACz+//8IAAAADAAAAAAAAAAAAAAABAAAAG5hbWUAAAAABQAAAJABAAAkAQAAzAAAAGwAAAAEAAAAlv7//xQAAABAAAAAQAAAAAAAAANAAAAAAQAAAAQAAACE/v//CAAAABQAAAAIAAAAYWx0aXR1ZGUAAAAABAAAAG5hbWUAAAAAAAAAAH7+//8AAAIACAAAAGFsdGl0dWRlAAAAAPr+//8UAAAAPAAAADwAAAAAAAADPAAAAAEAAAAEAAAA6P7//wgAAAAQAAAABwAAAGhlYWRpbmcABAAAAG5hbWUAAAAAAAAAAN7+//8AAAIABwAAAGhlYWRpbmcAVv///xQAAAA4AAAAOAAAAAAAAAM4AAAAAQAAAAQAAABE////CAAAAAwAAAADAAAAbG5nAAQAAABuYW1lAAAAAAAAAAA2////AAACAAMAAABsbmcAqv///xQAAAA4AAAAOAAAAAAAAAM4AAAAAQAAAAQAAACY////CAAAAAwAAAADAAAAbGF0AAQAAABuYW1lAAAAAAAAAACK////AAACAAMAAABsYXQAAAASABgAFAAAABMADAAAAAgABAASAAAAFAAAAEQAAABMAAAAAAAACkwAAAABAAAADAAAAAgADAAIAAQACAAAAAgAAAAQAAAABAAAAHRpbWUAAAAABAAAAG5hbWUAAAAAAAAAAAAABgAIAAYABgAAAAAAAwAEAAAAdGltZQAAAAD/////SAEAABQAAAAAAAAADAAWABQAEwAMAAQADAAAAJABAAAAAAAAFAAAAAAAAAMDAAoAGAAMAAgABAAKAAAAFAAAALgAAAAKAAAAAAAAAAAAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAUAAAAAAAAABQAAAAAAAAAKAAAAAAAAAAAAAAAAAAAACgAAAAAAAAAFAAAAAAAAAA8AAAAAAAAAAAAAAAAAAAAPAAAAAAAAAAUAAAAAAAAABAAQAAAAAAAAAAAAAAAAAAQAEAAAAAAABQAAAAAAAAAAAAAAAFAAAACgAAAAAAAAAAAAAAAAAAAAoAAAAAAAAAAAAAAAAAAAAKAAAAAAAAAAAAAAAAAAAACgAAAAAAAAAAAAAAAAAAAAoAAAAAAAAAAAAAAAAAAAAAYOc1vajoFQAqgnG9qOgVAPQcrb2o6BUAvrfovajoFQCIUiS+qOgVAFLtX76o6BUAHIibvqjoFQDmIte+qOgVALC9Er+o6BUAelhOv6joFQrXo3A96kJAsQSkC/7qQkC7AgsVdetCQLsCCxV160JAsQSkC/7qQkAK16NwPepCQGOpo9V86UJAWas8zAXpQkBZqzzMBelCQGOpo9V86UJA24XmOo2aXsBW7k6FrJpewA8N1HD+ml7AiXkNs2ObXsBCmJKetZtewL0A++jUm17AQpiSnrWbXsCJeQ2zY5tewA8N1HD+ml7AVu5OhayaXsAAAAAAAAAAAAAAAAAAAEJAAAAAAAAAUkAAAAAAAABbQAAAAAAAAGJAAAAAAACAZkAAAAAAAABrQAAAAAAAgG9AAAAAAAAAckAAAAAAAEB0QAAAAAAA4HVAAAAAAAAwdkAAAAAAAIB2QAAAAAAA0HZAAAAAAAAgd0AAAAAAAHB3QAAAAAAAwHdAAAAAAAAQeEAAAAAAAGB4QAAAAAAAsHhAEAAAAAwAFAASAAwACAAEAAwAAAAQAAAALAAAADwAAAAAAAMAAQAAAJACAAAAAAAAUAEAAAAAAACQAQAAAAAAAAAAAAAAAAAAAAAAAAAACgAMAAAACAAEAAoAAAAIAAAAUAAAAAIAAAAoAAAABAAAAAz+//8IAAAADAAAAAAAAAAAAAAABQAAAHJlZklkAAAALP7//wgAAAAMAAAAAAAAAAAAAAAEAAAAbmFtZQAAAAAFAAAAkAEAACQBAADMAAAAbAAAAAQAAACW/v//FAAAAEAAAABAAAAAAAAAA0AAAAABAAAABAAAAIT+//8IAAAAFAAAAAgAAABhbHRpdHVkZQAAAAAEAAAAbmFtZQAAAAAAAAAAfv7//wAAAgAIAAAAYWx0aXR1ZGUAAAAA+v7//xQAAAA8AAAAPAAAAAAAAAM8AAAAAQAAAAQAAADo/v//CAAAABAAAAAHAAAAaGVhZGluZwAEAAAAbmFtZQAAAAAAAAAA3v7//wAAAgAHAAAAaGVhZGluZwBW////FAAAADgAAAA4AAAAAAAAAzgAAAABAAAABAAAAET///8IAAAADAAAAAMAAABsbmcABAAAAG5hbWUAAAAAAAAAADb///8AAAIAAwAAAGxuZwCq////FAAAADgAAAA4AAAAAAAAAzgAAAABAAAABAAAAJj///8IAAAADAAAAAMAAABsYXQABAAAAG5hbWUAAAAAAAAAAIr///8AAAIAAwAAAGxhdAAAABIAGAAUAAAAEwAMAAAACAAEABIAAAAUAAAARAAAAEwAAAAAAAAKTAAAAAEAAAAMAAAACAAMAAgABAAIAAAACAAAABAAAAAEAAAAdGltZQAAAAAEAAAAbmFtZQAAAAAAAAAAAAAGAAgABgAGAAAAAAADAAQAAAB0aW1lAAAAALACAABBUlJPVzE= +FRAME=QVJST1cxAAD/////gAIAABAAAAAAAAoADgAMAAsABAAKAAAAFAAAAAAAAAEEAAoADAAAAAgABAAKAAAACAAAAFAAAAACAAAAKAAAAAQAAAAM/v//CAAAAAwAAAAAAAAAAAAAAAUAAAByZWZJZAAAACz+//8IAAAADAAAAAAAAAAAAAAABAAAAG5hbWUAAAAABQAAAJABAAAkAQAAzAAAAGwAAAAEAAAAlv7//xQAAABAAAAAQAAAAAAAAANAAAAAAQAAAAQAAACE/v//CAAAABQAAAAIAAAAYWx0aXR1ZGUAAAAABAAAAG5hbWUAAAAAAAAAAH7+//8AAAIACAAAAGFsdGl0dWRlAAAAAPr+//8UAAAAPAAAADwAAAAAAAADPAAAAAEAAAAEAAAA6P7//wgAAAAQAAAABwAAAGhlYWRpbmcABAAAAG5hbWUAAAAAAAAAAN7+//8AAAIABwAAAGhlYWRpbmcAVv///xQAAAA4AAAAOAAAAAAAAAM4AAAAAQAAAAQAAABE////CAAAAAwAAAADAAAAbG5nAAQAAABuYW1lAAAAAAAAAAA2////AAACAAMAAABsbmcAqv///xQAAAA4AAAAOAAAAAAAAAM4AAAAAQAAAAQAAACY////CAAAAAwAAAADAAAAbGF0AAQAAABuYW1lAAAAAAAAAACK////AAACAAMAAABsYXQAAAASABgAFAAAABMADAAAAAgABAASAAAAFAAAAEQAAABMAAAAAAAACkwAAAABAAAADAAAAAgADAAIAAQACAAAAAgAAAAQAAAABAAAAHRpbWUAAAAABAAAAG5hbWUAAAAAAAAAAAAABgAIAAYABgAAAAAAAwAEAAAAdGltZQAAAAD/////SAEAABQAAAAAAAAADAAWABQAEwAMAAQADAAAAJABAAAAAAAAFAAAAAAAAAMEAAoAGAAMAAgABAAKAAAAFAAAALgAAAAKAAAAAAAAAAAAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAUAAAAAAAAABQAAAAAAAAAKAAAAAAAAAAAAAAAAAAAACgAAAAAAAAAFAAAAAAAAAA8AAAAAAAAAAAAAAAAAAAAPAAAAAAAAAAUAAAAAAAAABAAQAAAAAAAAAAAAAAAAAAQAEAAAAAAABQAAAAAAAAAAAAAAAFAAAACgAAAAAAAAAAAAAAAAAAAAoAAAAAAAAAAAAAAAAAAAAKAAAAAAAAAAAAAAAAAAAACgAAAAAAAAAAAAAAAAAAAAoAAAAAAAAAAAAAAAAAAAAAYOc1vajoFQAqgnG9qOgVAPQcrb2o6BUAvrfovajoFQCIUiS+qOgVAFLtX76o6BUAHIibvqjoFQDmIte+qOgVALC9Er+o6BUAelhOv6joFQrXo3A96kJAsQSkC/7qQkC7AgsVdetCQLsCCxV160JAsQSkC/7qQkAK16NwPepCQGOpo9V86UJAWas8zAXpQkBZqzzMBelCQGOpo9V86UJA24XmOo2aXsBW7k6FrJpewA8N1HD+ml7AiXkNs2ObXsBCmJKetZtewL0A++jUm17AQpiSnrWbXsCJeQ2zY5tewA8N1HD+ml7AVu5OhayaXsAAAAAAAAAAAAAAAAAAAEJAAAAAAAAAUkAAAAAAAABbQAAAAAAAAGJAAAAAAACAZkAAAAAAAABrQAAAAAAAgG9AAAAAAAAAckAAAAAAAEB0QAAAAAAA4HVAAAAAAAAwdkAAAAAAAIB2QAAAAAAA0HZAAAAAAAAgd0AAAAAAAHB3QAAAAAAAwHdAAAAAAAAQeEAAAAAAAGB4QAAAAAAAsHhAEAAAAAwAFAASAAwACAAEAAwAAAAQAAAALAAAADwAAAAAAAQAAQAAAJACAAAAAAAAUAEAAAAAAACQAQAAAAAAAAAAAAAAAAAAAAAAAAAACgAMAAAACAAEAAoAAAAIAAAAUAAAAAIAAAAoAAAABAAAAAz+//8IAAAADAAAAAAAAAAAAAAABQAAAHJlZklkAAAALP7//wgAAAAMAAAAAAAAAAAAAAAEAAAAbmFtZQAAAAAFAAAAkAEAACQBAADMAAAAbAAAAAQAAACW/v//FAAAAEAAAABAAAAAAAAAA0AAAAABAAAABAAAAIT+//8IAAAAFAAAAAgAAABhbHRpdHVkZQAAAAAEAAAAbmFtZQAAAAAAAAAAfv7//wAAAgAIAAAAYWx0aXR1ZGUAAAAA+v7//xQAAAA8AAAAPAAAAAAAAAM8AAAAAQAAAAQAAADo/v//CAAAABAAAAAHAAAAaGVhZGluZwAEAAAAbmFtZQAAAAAAAAAA3v7//wAAAgAHAAAAaGVhZGluZwBW////FAAAADgAAAA4AAAAAAAAAzgAAAABAAAABAAAAET///8IAAAADAAAAAMAAABsbmcABAAAAG5hbWUAAAAAAAAAADb///8AAAIAAwAAAGxuZwCq////FAAAADgAAAA4AAAAAAAAAzgAAAABAAAABAAAAJj///8IAAAADAAAAAMAAABsYXQABAAAAG5hbWUAAAAAAAAAAIr///8AAAIAAwAAAGxhdAAAABIAGAAUAAAAEwAMAAAACAAEABIAAAAUAAAARAAAAEwAAAAAAAAKTAAAAAEAAAAMAAAACAAMAAgABAAIAAAACAAAABAAAAAEAAAAdGltZQAAAAAEAAAAbmFtZQAAAAAAAAAAAAAGAAgABgAGAAAAAAADAAQAAAB0aW1lAAAAALACAABBUlJPVzE= diff --git a/pkg/tsdb/testdatasource/sims/types.go b/pkg/tsdb/testdatasource/sims/types.go new file mode 100644 index 00000000000..42b9e7735d7 --- /dev/null +++ b/pkg/tsdb/testdatasource/sims/types.go @@ -0,0 +1,51 @@ +package sims + +import ( + "fmt" + "io" + "strings" + "time" + + "github.com/grafana/grafana-plugin-sdk-go/data" +) + +type simulationKey struct { + Type string `json:"type"` + TickHZ float64 `json:"tick"` // events/second + UID string `json:"uid,omitempty"` // allows many instances of the same type +} + +func (k simulationKey) String() string { + hz := strings.TrimRight(strings.TrimRight(fmt.Sprintf("%.2f", k.TickHZ), "0"), ".") + if k.UID != "" { + return fmt.Sprintf("%s/%shz/%s", k.Type, hz, k.UID) + } + return fmt.Sprintf("%s/%shz", k.Type, hz) +} + +type simulationState struct { + // Identify the simulation instance + Key simulationKey `json:"key"` + + // Saved in panel options, and used to set initial values + Config interface{} `json:"config"` +} + +type simulationInfo struct { + Type string `json:"type"` + Name string `json:"name"` + Description string `json:"description"` + OnlyForward bool `json:"forward"` + SetupFields *data.Frame `json:"setup"` // the default setup fields (and types) + + // Create a simulation instance + create func(q simulationState) (Simulation, error) +} + +type Simulation interface { + io.Closer + GetState() simulationState + SetConfig(vals map[string]interface{}) error + NewFrame(size int) *data.Frame + GetValues(t time.Time) map[string]interface{} +} diff --git a/pkg/tsdb/testdatasource/sims/utils.go b/pkg/tsdb/testdatasource/sims/utils.go new file mode 100644 index 00000000000..39a9c8e43c7 --- /dev/null +++ b/pkg/tsdb/testdatasource/sims/utils.go @@ -0,0 +1,76 @@ +package sims + +import ( + "encoding/json" + "net/http" + + "github.com/grafana/grafana-plugin-sdk-go/data" +) + +// updateConfigObjectFromJSON will use json serialization to update any properties +func updateConfigObjectFromJSON(cfg interface{}, input interface{}) error { + current, err := asStringMap(cfg) + if err != nil { + return err + } + next, err := asStringMap(input) + if err != nil { + return err + } + + for k, v := range next { + if v == nil { + delete(current, k) + } else { + current[k] = v + } + } + + b, err := json.Marshal(current) + if err != nil { + return err + } + return json.Unmarshal(b, cfg) +} + +func asStringMap(input interface{}) (map[string]interface{}, error) { + v, ok := input.(map[string]interface{}) + if ok { + return v, nil + } + v = make(map[string]interface{}) + b, err := json.Marshal(input) + if err != nil { + return nil, err + } + err = json.Unmarshal(b, &v) + return v, err +} + +func setFrameRow(frame *data.Frame, idx int, values map[string]interface{}) { + for _, field := range frame.Fields { + v, ok := values[field.Name] + if ok { + field.Set(idx, v) + } + } +} + +func appendFrameRow(frame *data.Frame, values map[string]interface{}) { + for _, field := range frame.Fields { + v, ok := values[field.Name] + if ok { + field.Append(v) + } else { + field.Extend(1) // fill with nullable value + } + } +} + +func getBodyFromRequest(req *http.Request) (map[string]interface{}, error) { + result := make(map[string]interface{}, 10) + + err := json.NewDecoder(req.Body).Decode(&result) + // TODO? create the map based on form parameters not JSON post + return result, err +} diff --git a/pkg/tsdb/testdatasource/sims/utils_test.go b/pkg/tsdb/testdatasource/sims/utils_test.go new file mode 100644 index 00000000000..f38b4c423d3 --- /dev/null +++ b/pkg/tsdb/testdatasource/sims/utils_test.go @@ -0,0 +1,30 @@ +package sims + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestSimulationUtils(t *testing.T) { + a := map[string]interface{}{ + "hello": "world", + "bool": true, + "number": 10, + } + + err := updateConfigObjectFromJSON(&a, map[string]interface{}{ + "bool": false, + "number": 5, + }) + require.NoError(t, err) + + cfg, err := json.MarshalIndent(a, "", " ") + require.NoError(t, err) + require.JSONEq(t, `{ + "hello": "world", + "bool": false, + "number": 5 + }`, string(cfg)) +} diff --git a/pkg/tsdb/testdatasource/sims/waveform.go b/pkg/tsdb/testdatasource/sims/waveform.go new file mode 100644 index 00000000000..6f78dd4b2a9 --- /dev/null +++ b/pkg/tsdb/testdatasource/sims/waveform.go @@ -0,0 +1,115 @@ +package sims + +import ( + "math" + "math/rand" + "time" + + "github.com/grafana/grafana-plugin-sdk-go/data" +) + +type waveformSim struct { + key simulationKey + cfg waveformConfig + calculator func(x float64, cfg *waveformConfig) float64 +} + +var ( + _ Simulation = (*waveformSim)(nil) +) + +type waveformConfig struct { + Period float64 `json:"period"` // seconds + Offset float64 `json:"offset,omitempty"` // Y shift + Phase float64 `json:"phase,omitempty"` // X shift // +- 1 (will scale the ) + Amplitude float64 `json:"amplitude"` // Y size + Noise float64 `json:"noise,omitempty"` // random noise to add +} + +func (s *waveformSim) GetState() simulationState { + return simulationState{ + Key: s.key, + Config: s.cfg, + } +} + +func (s *waveformSim) SetConfig(vals map[string]interface{}) error { + return updateConfigObjectFromJSON(s.cfg, vals) +} + +func (s *waveformSim) NewFrame(size int) *data.Frame { + frame := data.NewFrameOfFieldTypes("", size, + data.FieldTypeTime, // time + data.FieldTypeFloat64, // value + ) + frame.Fields[0].Name = data.TimeSeriesTimeFieldName + frame.Fields[1].Name = data.TimeSeriesValueFieldName + return frame +} + +func (s *waveformSim) GetValues(t time.Time) map[string]interface{} { + x := 0.0 + if s.cfg.Period > 0 { + periodMS := s.cfg.Period * 1000 + ms := t.UnixMilli() % int64(periodMS) + x = ((float64(ms) / periodMS) * 2 * math.Pi) // 0 >> 2Pi + } + + v := s.calculator(x, &s.cfg) + + noise := s.cfg.Noise + if noise > 0 { + gen := rand.New(rand.NewSource(t.UnixMilli())) // consistent for the value + v += (gen.Float64() * 2.0 * noise) - noise + } + + return map[string]interface{}{ + data.TimeSeriesTimeFieldName: t, + data.TimeSeriesValueFieldName: v, + } +} + +func (s *waveformSim) Close() error { + return nil +} + +func newSinewaveInfo() simulationInfo { + sf := waveformConfig{ + Period: 10, + Amplitude: 1, + Offset: 0, + Phase: 0, + } + + df := data.NewFrame("") + df.Fields = append(df.Fields, data.NewField("period", nil, []float64{sf.Period})) + df.Fields = append(df.Fields, data.NewField("offset", nil, []float64{sf.Offset})) + df.Fields = append(df.Fields, data.NewField("phase", nil, []float64{sf.Phase})) + df.Fields = append(df.Fields, data.NewField("amplitude", nil, []float64{sf.Amplitude})) + df.Fields = append(df.Fields, data.NewField("noise", nil, []float64{sf.Noise})) + + f := data.NewField("period", nil, []float64{sf.Period}) + f.Config = &data.FieldConfig{Unit: "s"} // seconds + df.Fields = append(df.Fields, f) + + return simulationInfo{ + Type: "sine", + Name: "Sine", + Description: "Sinewave generator", + SetupFields: df, + OnlyForward: false, + create: func(cfg simulationState) (Simulation, error) { + s := &waveformSim{ + key: cfg.Key, + cfg: sf, // default value + calculator: sinewaveCalculator, + } + err := updateConfigObjectFromJSON(&s.cfg, cfg.Config) // override any fields + return s, err + }, + } +} + +func sinewaveCalculator(x float64, cfg *waveformConfig) float64 { + return (math.Sin(x) * cfg.Amplitude) + cfg.Offset +} diff --git a/pkg/tsdb/testdatasource/stream_handler.go b/pkg/tsdb/testdatasource/stream_handler.go index c71b9e3b03c..1b7c7a1c40e 100644 --- a/pkg/tsdb/testdatasource/stream_handler.go +++ b/pkg/tsdb/testdatasource/stream_handler.go @@ -15,22 +15,18 @@ import ( var random20HzStreamRegex = regexp.MustCompile(`random-20Hz-stream(-\d+)?`) -func (s *Service) SubscribeStream(_ context.Context, req *backend.SubscribeStreamRequest) (*backend.SubscribeStreamResponse, error) { +func (s *Service) SubscribeStream(ctx context.Context, req *backend.SubscribeStreamRequest) (*backend.SubscribeStreamResponse, error) { s.logger.Debug("Allowing access to stream", "path", req.Path, "user", req.PluginContext.User) + + if strings.HasPrefix(req.Path, "sim/") { + return s.sims.SubscribeStream(ctx, req) + } + initialData, err := backend.NewInitialFrame(s.frame, data.IncludeSchemaOnly) if err != nil { return nil, err } - // For flight simulations, send the more complex schema - if strings.HasPrefix(req.Path, "flight") { - ff := newFlightConfig().initFields() - initialData, err = backend.NewInitialFrame(ff.frame, data.IncludeSchemaOnly) - if err != nil { - return nil, err - } - } - if strings.Contains(req.Path, "-labeled") { initialData, err = backend.NewInitialFrame(s.labelFrame, data.IncludeSchemaOnly) if err != nil { @@ -49,8 +45,13 @@ func (s *Service) SubscribeStream(_ context.Context, req *backend.SubscribeStrea }, nil } -func (s *Service) PublishStream(_ context.Context, req *backend.PublishStreamRequest) (*backend.PublishStreamResponse, error) { +func (s *Service) PublishStream(ctx context.Context, req *backend.PublishStreamRequest) (*backend.PublishStreamResponse, error) { s.logger.Debug("Attempt to publish into stream", "path", req.Path, "user", req.PluginContext.User) + + if strings.HasPrefix(req.Path, "sim/") { + return s.sims.PublishStream(ctx, req) + } + return &backend.PublishStreamResponse{ Status: backend.PublishStreamStatusPermissionDenied, }, nil @@ -58,6 +59,11 @@ func (s *Service) PublishStream(_ context.Context, req *backend.PublishStreamReq func (s *Service) RunStream(ctx context.Context, request *backend.RunStreamRequest, sender *backend.StreamSender) error { s.logger.Debug("New stream call", "path", request.Path) + + if strings.HasPrefix(request.Path, "sim/") { + return s.sims.RunStream(ctx, request, sender) + } + var conf testStreamConfig switch { case request.Path == "random-2s-stream": @@ -75,11 +81,6 @@ func (s *Service) RunStream(ctx context.Context, request *backend.RunStreamReque Drop: 0.2, // keep 80% Labeled: true, } - case request.Path == "flight-5hz-stream": - conf = testStreamConfig{ - Interval: 200 * time.Millisecond, - Flight: newFlightConfig(), - } case random20HzStreamRegex.MatchString(request.Path): conf = testStreamConfig{ Interval: 50 * time.Millisecond, @@ -93,7 +94,6 @@ func (s *Service) RunStream(ctx context.Context, request *backend.RunStreamReque type testStreamConfig struct { Interval time.Duration Drop float64 - Flight *flightConfig Labeled bool } @@ -104,12 +104,6 @@ func (s *Service) runTestStream(ctx context.Context, path string, conf testStrea ticker := time.NewTicker(conf.Interval) defer ticker.Stop() - var flight *flightFields - if conf.Flight != nil { - flight = conf.Flight.initFields() - flight.append(conf.Flight.getNextPoint(time.Now())) - } - labelFrame := data.NewFrame("labeled", data.NewField("labels", nil, make([]string, 2)), data.NewField("Time", nil, make([]time.Time, 2)), @@ -131,37 +125,30 @@ func (s *Service) runTestStream(ctx context.Context, path string, conf testStrea mode = data.IncludeAll } - if flight != nil { - flight.set(0, conf.Flight.getNextPoint(t)) - if err := sender.SendFrame(flight.frame, mode); err != nil { + delta := rand.Float64() - 0.5 + walker += delta + + if conf.Labeled { + secA := t.Second() / 3 + secB := t.Second() / 7 + + labelFrame.Fields[0].Set(0, fmt.Sprintf("s=A,s=p%d,x=X", secA)) + labelFrame.Fields[1].Set(0, t) + labelFrame.Fields[2].Set(0, walker) + + labelFrame.Fields[0].Set(1, fmt.Sprintf("s=B,s=p%d,x=X", secB)) + labelFrame.Fields[1].Set(1, t) + labelFrame.Fields[2].Set(1, walker+10) + if err := sender.SendFrame(labelFrame, mode); err != nil { return err } } else { - delta := rand.Float64() - 0.5 - walker += delta - - if conf.Labeled { - secA := t.Second() / 3 - secB := t.Second() / 7 - - labelFrame.Fields[0].Set(0, fmt.Sprintf("s=A,s=p%d,x=X", secA)) - labelFrame.Fields[1].Set(0, t) - labelFrame.Fields[2].Set(0, walker) - - labelFrame.Fields[0].Set(1, fmt.Sprintf("s=B,s=p%d,x=X", secB)) - labelFrame.Fields[1].Set(1, t) - labelFrame.Fields[2].Set(1, walker+10) - if err := sender.SendFrame(labelFrame, mode); err != nil { - return err - } - } else { - s.frame.Fields[0].Set(0, t) - s.frame.Fields[1].Set(0, walker) // Value - s.frame.Fields[2].Set(0, walker-((rand.Float64()*spread)+0.01)) // Min - s.frame.Fields[3].Set(0, walker+((rand.Float64()*spread)+0.01)) // Max - if err := sender.SendFrame(s.frame, mode); err != nil { - return err - } + s.frame.Fields[0].Set(0, t) + s.frame.Fields[1].Set(0, walker) // Value + s.frame.Fields[2].Set(0, walker-((rand.Float64()*spread)+0.01)) // Min + s.frame.Fields[3].Set(0, walker+((rand.Float64()*spread)+0.01)) // Max + if err := sender.SendFrame(s.frame, mode); err != nil { + return err } } } diff --git a/pkg/tsdb/testdatasource/testdata.go b/pkg/tsdb/testdatasource/testdata.go index b99b735d046..3cedd2f91ef 100644 --- a/pkg/tsdb/testdatasource/testdata.go +++ b/pkg/tsdb/testdatasource/testdata.go @@ -12,6 +12,7 @@ import ( "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/setting" + "github.com/grafana/grafana/pkg/tsdb/testdatasource/sims" ) func ProvideService(cfg *setting.Cfg, features featuremgmt.FeatureToggles) *Service { @@ -34,6 +35,12 @@ func ProvideService(cfg *setting.Cfg, features featuremgmt.FeatureToggles) *Serv cfg: cfg, } + var err error + s.sims, err = sims.NewSimulationEngine() + if err != nil { + s.logger.Error("unable to initialize SimulationEngine", "err", err) + } + s.registerScenarios() s.resourceHandler = httpadapter.New(s.registerRoutes()) @@ -49,6 +56,7 @@ type Service struct { queryMux *datasource.QueryTypeMux resourceHandler backend.CallResourceHandler features featuremgmt.FeatureToggles + sims *sims.SimulationEngine } func (s *Service) QueryData(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) { diff --git a/public/app/plugins/datasource/testdata/QueryEditor.tsx b/public/app/plugins/datasource/testdata/QueryEditor.tsx index a10116b875f..040be750b3a 100644 --- a/public/app/plugins/datasource/testdata/QueryEditor.tsx +++ b/public/app/plugins/datasource/testdata/QueryEditor.tsx @@ -22,6 +22,7 @@ import { CSVFileEditor } from './components/CSVFileEditor'; import { CSVContentEditor } from './components/CSVContentEditor'; import { USAQueryEditor, usaQueryModes } from './components/USAQueryEditor'; import ErrorEditor from './components/ErrorEditor'; +import { SimulationQueryEditor } from './components/SimulationQueryEditor'; const showLabelsFor = ['random_walk', 'predictable_pulse']; const endpoints = [ @@ -57,7 +58,12 @@ export const QueryEditor = ({ query, datasource, onChange, onRunQuery }: Props) }); } - return datasource.getScenarios(); + const vals = await datasource.getScenarios(); + const hideAlias = ['simulation']; + return vals.map((v) => ({ + ...v, + hideAliasField: hideAlias.includes(v.id), + })); }, []); const onUpdate = (query: TestDataQuery) => { @@ -101,6 +107,9 @@ export const QueryEditor = ({ query, datasource, onChange, onRunQuery }: Props) case 'live': update.channel = 'random-2s-stream'; // default stream break; + case 'simulation': + update.sim = { key: { type: 'flight', tick: 10 } }; // default stream + break; case 'predictable_pulse': update.pulseWave = defaultPulseQuery; break; @@ -194,18 +203,20 @@ export const QueryEditor = ({ query, datasource, onChange, onRunQuery }: Props) />
)} - - - + {Boolean(!currentScenario?.hideAliasField) && ( + + + + )} {showLabels && ( } {scenarioId === 'streaming_client' && } {scenarioId === 'live' && } + {scenarioId === 'simulation' && } {scenarioId === 'raw_frame' && } {scenarioId === 'csv_file' && } {scenarioId === 'csv_content' && } diff --git a/public/app/plugins/datasource/testdata/components/SimulationQueryEditor.tsx b/public/app/plugins/datasource/testdata/components/SimulationQueryEditor.tsx new file mode 100644 index 00000000000..3b566970220 --- /dev/null +++ b/public/app/plugins/datasource/testdata/components/SimulationQueryEditor.tsx @@ -0,0 +1,83 @@ +import { SelectableValue } from '@grafana/data'; +import { InlineField, InlineFieldRow, InlineSwitch, Input, Label, Select } from '@grafana/ui'; +import React, { FormEvent } from 'react'; +import { EditorProps } from '../QueryEditor'; +import { SimulationQuery } from '../types'; + +export const SimulationQueryEditor = ({ onChange, query }: EditorProps) => { + const simQuery = query.sim ?? ({} as SimulationQuery); + const simKey = simQuery.key ?? ({} as typeof simQuery.key); + const options = [ + { label: 'Flight', value: 'flight' }, + { label: 'Sine', value: 'sine' }, + ]; + + const onUpdateKey = (key: typeof simQuery.key) => { + onChange({ ...query, sim: { ...simQuery, key } }); + }; + + const onUIDChanged = (e: FormEvent) => { + const { value } = e.target as HTMLInputElement; + onUpdateKey({ ...simKey, uid: value ?? undefined }); + }; + + const onTickChanged = (e: FormEvent) => { + const tick = e.currentTarget.valueAsNumber; + onUpdateKey({ ...simKey, tick }); + }; + + const onTypeChange = (v: SelectableValue) => { + onUpdateKey({ ...simKey, type: v.value! }); + }; + + const onToggleStream = () => { + onChange({ ...query, sim: { ...simQuery, stream: !simQuery.stream } }); + }; + + const onToggleLast = () => { + onChange({ ...query, sim: { ...simQuery, last: !simQuery.last } }); + }; + + return ( + <> + + + + + + + + + + + + + + ); +}; diff --git a/public/app/plugins/datasource/testdata/types.ts b/public/app/plugins/datasource/testdata/types.ts index 56ce9f569f4..d3c521e4667 100644 --- a/public/app/plugins/datasource/testdata/types.ts +++ b/public/app/plugins/datasource/testdata/types.ts @@ -5,6 +5,7 @@ export interface Scenario { name: string; stringInput: string; description?: string; + hideAliasField?: boolean; } export interface TestDataQuery extends DataQuery { @@ -13,6 +14,7 @@ export interface TestDataQuery extends DataQuery { stringInput?: string; stream?: StreamingQuery; pulseWave?: PulseWaveQuery; + sim?: SimulationQuery; csvWave?: CSVWave[]; labels?: string; lines?: number; @@ -40,6 +42,17 @@ export interface StreamingQuery { url?: string; // the Fetch URL } +export interface SimulationQuery { + key: { + type: string; + tick: number; + uid?: string; + }; + config?: Record; + stream?: boolean; + last?: boolean; +} + export interface PulseWaveQuery { timeStep?: number; onCount?: number; From aa98123e7209bbd5c0dce5a04409b29cd6888acf Mon Sep 17 00:00:00 2001 From: Leon Sorokin Date: Tue, 19 Apr 2022 23:20:09 -0500 Subject: [PATCH 010/120] TimeSeries: always try to detect & fix reverse-sorted time field (#47906) --- .../transformers/joinDataFrames.test.ts | 2 +- .../transformers/joinDataFrames.ts | 30 +++++++++++-------- .../prepareTimeSeries/prepareTimeSeries.ts | 1 - public/app/plugins/panel/barchart/utils.ts | 9 +++++- .../app/plugins/panel/candlestick/fields.ts | 9 +++++- 5 files changed, 34 insertions(+), 17 deletions(-) diff --git a/packages/grafana-data/src/transformations/transformers/joinDataFrames.test.ts b/packages/grafana-data/src/transformations/transformers/joinDataFrames.test.ts index d1612fdc839..a5d11987b68 100644 --- a/packages/grafana-data/src/transformations/transformers/joinDataFrames.test.ts +++ b/packages/grafana-data/src/transformations/transformers/joinDataFrames.test.ts @@ -188,7 +188,7 @@ describe('align frames', () => { ], }); - const out = outerJoinDataFrames({ frames: [series1], enforceSort: true, keepOriginIndices: true })!; + const out = outerJoinDataFrames({ frames: [series1], keepOriginIndices: true })!; expect( out.fields.map((f) => ({ name: f.name, diff --git a/packages/grafana-data/src/transformations/transformers/joinDataFrames.ts b/packages/grafana-data/src/transformations/transformers/joinDataFrames.ts index 4288f3690e4..c366a55e5ff 100644 --- a/packages/grafana-data/src/transformations/transformers/joinDataFrames.ts +++ b/packages/grafana-data/src/transformations/transformers/joinDataFrames.ts @@ -48,13 +48,6 @@ export interface JoinOptions { */ keep?: FieldMatcher; - /** - * When the result is a single frame, this will to a quick check to see if the values are sorted, - * and sort if necessary. If the first/last values are in order the whole vector is assumed to be - * sorted - */ - enforceSort?: boolean; - /** * @internal -- used when we need to keep a reference to the original frame/field index */ @@ -65,6 +58,21 @@ function getJoinMatcher(options: JoinOptions): FieldMatcher { return options.joinBy ?? pickBestJoinField(options.frames); } +/** + * @internal + */ +export function maybeSortFrame(frame: DataFrame, fieldIdx: number) { + if (fieldIdx >= 0) { + let sortByField = frame.fields[fieldIdx]; + + if (sortByField.type !== FieldType.string && !isLikelyAscendingVector(sortByField.values)) { + frame = sortDataFrame(frame, fieldIdx); + } + } + + return frame; +} + /** * This will return a single frame joined by the first matching field. When a join field is not specified, * the default will use the first time field @@ -109,12 +117,8 @@ export function outerJoinDataFrames(options: JoinOptions): DataFrame | undefined } } - if (options.enforceSort) { - if (joinIndex >= 0) { - if (!isLikelyAscendingVector(frameCopy.fields[joinIndex].values)) { - frameCopy = sortDataFrame(frameCopy, joinIndex); - } - } + if (joinIndex >= 0) { + frameCopy = maybeSortFrame(frameCopy, joinIndex); } if (options.keep) { diff --git a/public/app/features/transformers/prepareTimeSeries/prepareTimeSeries.ts b/public/app/features/transformers/prepareTimeSeries/prepareTimeSeries.ts index 4d237750620..e2248bc4502 100644 --- a/public/app/features/transformers/prepareTimeSeries/prepareTimeSeries.ts +++ b/public/app/features/transformers/prepareTimeSeries/prepareTimeSeries.ts @@ -301,7 +301,6 @@ export const prepareTimeSeriesTransformer: SynchronousDataTransformerInfo f.type === FieldType.time) + ) + : outerJoinDataFrames({ frames: series }); if (!frame) { return { warn: 'Unable to join data' } as BarChartDisplayValues; } diff --git a/public/app/plugins/panel/candlestick/fields.ts b/public/app/plugins/panel/candlestick/fields.ts index b81b98af79b..be833fbde45 100644 --- a/public/app/plugins/panel/candlestick/fields.ts +++ b/public/app/plugins/panel/candlestick/fields.ts @@ -7,6 +7,7 @@ import { GrafanaTheme2, outerJoinDataFrames, } from '@grafana/data'; +import { maybeSortFrame } from '@grafana/data/src/transformations/transformers/joinDataFrames'; import { findField } from 'app/features/dimensions'; import { prepareGraphableFields } from '../timeseries/utils'; import { CandlestickOptions, CandlestickFieldMap, VizDisplayMode } from './models.gen'; @@ -102,7 +103,13 @@ export function prepareCandlestickFields( // All fields const fieldMap = options.fields ?? {}; - const aligned = series.length === 1 ? series[0] : outerJoinDataFrames({ frames: series, enforceSort: true }); + const aligned = + series.length === 1 + ? maybeSortFrame( + series[0], + series[0].fields.findIndex((f) => f.type === FieldType.time) + ) + : outerJoinDataFrames({ frames: series }); if (!aligned?.length) { return null; } From 24038d99852a647bdae623d731de4033ba9d9916 Mon Sep 17 00:00:00 2001 From: Emil Tullstedt Date: Wed, 20 Apr 2022 09:14:12 +0200 Subject: [PATCH 011/120] Chore: Update Go version (#47914) * Remove makefile (it's not used anymore) * Directly download and install nodejs package The Packages file for deb.nodesource.com/node_16.x doesn't list older versions, so only the most recent version of nodejs is available. We don't want to require every update to the build container to have to update nodejs if a never version is available, so I manually download the deb and install it with dpkg. * Update Go version * Update lib.star * Generate new .drone.yml --- .drone.yml | 448 +++++++++++++++--------------- Dockerfile | 2 +- Dockerfile.ubuntu | 2 +- scripts/build/ci-build/Dockerfile | 8 +- scripts/build/ci-build/Makefile | 54 ---- scripts/build/ci-build/README.md | 13 - scripts/drone/steps/lib.star | 4 +- 7 files changed, 233 insertions(+), 298 deletions(-) delete mode 100644 scripts/build/ci-build/Makefile diff --git a/.drone.yml b/.drone.yml index b28736013e1..c35b9687f3a 100644 --- a/.drone.yml +++ b/.drone.yml @@ -15,7 +15,7 @@ steps: name: identify-runner - commands: - mkdir -p bin - - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.37/grabpl + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.41/grabpl - chmod +x bin/grabpl image: byrnedo/alpine-curl:0.1.8 name: grabpl @@ -23,17 +23,17 @@ steps: - ./bin/grabpl gen-version --build-id ${DRONE_BUILD_NUMBER} depends_on: - grabpl - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: gen-version - commands: - make gen-go - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: wire-install - commands: - yarn install --immutable depends_on: - grabpl - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: yarn-install - commands: - ./bin/grabpl verify-drone @@ -51,13 +51,13 @@ steps: wan" > words_to_ignore.txt - codespell -I words_to_ignore.txt docs/ - rm words_to_ignore.txt - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: codespell - commands: - ./bin/grabpl shellcheck depends_on: - grabpl - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: shellcheck - commands: - ./bin/grabpl lint-backend --edition oss @@ -65,7 +65,7 @@ steps: - wire-install environment: CGO_ENABLED: "1" - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: lint-backend - commands: - yarn run prettier:check @@ -76,19 +76,19 @@ steps: - yarn-install environment: TEST_MAX_WORKERS: 50% - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: lint-frontend - commands: - ./bin/grabpl test-backend --edition oss depends_on: - wire-install - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: test-backend - commands: - ./bin/grabpl integration-tests --edition oss depends_on: - wire-install - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: test-backend-integration - commands: - yarn run ci:test-frontend @@ -96,7 +96,7 @@ steps: - yarn-install environment: TEST_MAX_WORKERS: 50% - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: test-frontend trigger: event: @@ -126,7 +126,7 @@ steps: name: identify-runner - commands: - mkdir -p bin - - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.37/grabpl + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.41/grabpl - chmod +x bin/grabpl image: byrnedo/alpine-curl:0.1.8 name: grabpl @@ -134,17 +134,17 @@ steps: - ./bin/grabpl gen-version --build-id ${DRONE_BUILD_NUMBER} depends_on: - grabpl - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: gen-version - commands: - make gen-go - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: wire-install - commands: - yarn install --immutable depends_on: - grabpl - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: yarn-install - commands: - ./bin/grabpl build-backend --jobs 8 --edition oss --build-id ${DRONE_BUILD_NUMBER} @@ -152,7 +152,7 @@ steps: depends_on: - gen-version - wire-install - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: build-backend - commands: - ./bin/grabpl build-frontend --jobs 8 --edition oss --build-id ${DRONE_BUILD_NUMBER} @@ -161,7 +161,7 @@ steps: - yarn-install environment: NODE_OPTIONS: --max_old_space_size=8192 - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: build-frontend - commands: - ./bin/grabpl build-frontend-packages --jobs 8 --edition oss --build-id ${DRONE_BUILD_NUMBER} @@ -170,7 +170,7 @@ steps: - yarn-install environment: NODE_OPTIONS: --max_old_space_size=8192 - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: build-frontend-packages - commands: - ./bin/grabpl build-plugins --jobs 8 --edition oss @@ -178,13 +178,13 @@ steps: - gen-version - yarn-install environment: null - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: build-plugins - commands: - ./bin/linux-amd64/grafana-cli cue validate-schema --grafana-root . depends_on: - build-backend - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: validate-scuemata - commands: - '# It is required that the generated Typescript be in sync with the input CUE @@ -197,7 +197,7 @@ steps: - ./bin/linux-amd64/grafana-cli cue gen-ts --grafana-root . --diff depends_on: - validate-scuemata - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: ensure-cuetsified - commands: - . scripts/build/gpg-test-vars.sh && ./bin/grabpl package --jobs 8 --edition oss @@ -208,7 +208,7 @@ steps: - build-frontend - build-frontend-packages environment: null - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: package - commands: - ./scripts/grafana-server/start-server @@ -221,7 +221,7 @@ steps: environment: ARCH: linux-amd64 PORT: 3001 - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: grafana-server - commands: - apt-get install -y netcat @@ -299,7 +299,7 @@ steps: - build-frontend-packages environment: NODE_OPTIONS: --max_old_space_size=4096 - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: build-storybook - commands: - yarn wait-on http://$HOST:$PORT @@ -319,7 +319,7 @@ steps: - cp dist/*.tar.gz* packaging/docker/ depends_on: - package - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: copy-packages-for-docker - commands: - ./bin/grabpl build-docker --edition oss -archs amd64 @@ -377,7 +377,7 @@ services: steps: - commands: - mkdir -p bin - - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.37/grabpl + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.41/grabpl - chmod +x bin/grabpl image: byrnedo/alpine-curl:0.1.8 name: grabpl @@ -398,7 +398,7 @@ steps: GRAFANA_TEST_DB: postgres PGPASSWORD: grafanatest POSTGRES_HOST: postgres - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: postgres-integration-tests - commands: - apt-get update @@ -413,7 +413,7 @@ steps: environment: GRAFANA_TEST_DB: mysql MYSQL_HOST: mysql - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: mysql-integration-tests trigger: event: @@ -445,7 +445,7 @@ services: [] steps: - commands: - mkdir -p bin - - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.37/grabpl + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.41/grabpl - chmod +x bin/grabpl image: byrnedo/alpine-curl:0.1.8 name: grabpl @@ -457,13 +457,13 @@ steps: - ./bin/grabpl gen-version --build-id ${DRONE_BUILD_NUMBER} depends_on: - grabpl - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: gen-version - commands: - yarn install --immutable depends_on: - grabpl - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: yarn-install - commands: - |- @@ -475,7 +475,7 @@ steps: wan" > words_to_ignore.txt - codespell -I words_to_ignore.txt docs/ - rm words_to_ignore.txt - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: codespell - commands: - yarn run prettier:checkDocs @@ -483,7 +483,7 @@ steps: - yarn-install environment: NODE_OPTIONS: --max_old_space_size=8192 - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: lint-docs - commands: - ./bin/grabpl build-frontend-packages --jobs 8 --edition oss --build-id ${DRONE_BUILD_NUMBER} @@ -492,13 +492,13 @@ steps: - yarn-install environment: NODE_OPTIONS: --max_old_space_size=8192 - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: build-frontend-packages - commands: - ./scripts/ci-reference-docs-lint.sh ci depends_on: - build-frontend-packages - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: build-frontend-docs - commands: - mkdir -p /hugo/content/docs/grafana @@ -533,7 +533,7 @@ services: [] steps: - commands: - mkdir -p bin - - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.37/grabpl + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.41/grabpl - chmod +x bin/grabpl image: byrnedo/alpine-curl:0.1.8 name: grabpl @@ -545,13 +545,13 @@ steps: - ./bin/grabpl gen-version --build-id ${DRONE_BUILD_NUMBER} depends_on: - grabpl - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: gen-version - commands: - yarn install --immutable depends_on: - grabpl - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: yarn-install - commands: - |- @@ -563,7 +563,7 @@ steps: wan" > words_to_ignore.txt - codespell -I words_to_ignore.txt docs/ - rm words_to_ignore.txt - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: codespell - commands: - yarn run prettier:checkDocs @@ -571,7 +571,7 @@ steps: - yarn-install environment: NODE_OPTIONS: --max_old_space_size=8192 - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: lint-docs - commands: - ./bin/grabpl build-frontend-packages --jobs 8 --edition oss --build-id ${DRONE_BUILD_NUMBER} @@ -580,13 +580,13 @@ steps: - yarn-install environment: NODE_OPTIONS: --max_old_space_size=8192 - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: build-frontend-packages - commands: - ./scripts/ci-reference-docs-lint.sh ci depends_on: - build-frontend-packages - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: build-frontend-docs - commands: - mkdir -p /hugo/content/docs/grafana @@ -622,7 +622,7 @@ steps: name: identify-runner - commands: - mkdir -p bin - - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.37/grabpl + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.41/grabpl - chmod +x bin/grabpl image: byrnedo/alpine-curl:0.1.8 name: grabpl @@ -630,17 +630,17 @@ steps: - ./bin/grabpl gen-version --build-id ${DRONE_BUILD_NUMBER} depends_on: - grabpl - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: gen-version - commands: - make gen-go - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: wire-install - commands: - yarn install --immutable depends_on: - grabpl - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: yarn-install - commands: - ./bin/grabpl verify-drone @@ -658,13 +658,13 @@ steps: wan" > words_to_ignore.txt - codespell -I words_to_ignore.txt docs/ - rm words_to_ignore.txt - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: codespell - commands: - ./bin/grabpl shellcheck depends_on: - grabpl - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: shellcheck - commands: - ./bin/grabpl lint-backend --edition oss @@ -672,7 +672,7 @@ steps: - wire-install environment: CGO_ENABLED: "1" - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: lint-backend - commands: - yarn run prettier:check @@ -683,19 +683,19 @@ steps: - yarn-install environment: TEST_MAX_WORKERS: 50% - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: lint-frontend - commands: - ./bin/grabpl test-backend --edition oss depends_on: - wire-install - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: test-backend - commands: - ./bin/grabpl integration-tests --edition oss depends_on: - wire-install - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: test-backend-integration - commands: - yarn run ci:test-frontend @@ -703,7 +703,7 @@ steps: - yarn-install environment: TEST_MAX_WORKERS: 50% - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: test-frontend trigger: branch: main @@ -731,7 +731,7 @@ steps: name: identify-runner - commands: - mkdir -p bin - - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.37/grabpl + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.41/grabpl - chmod +x bin/grabpl image: byrnedo/alpine-curl:0.1.8 name: grabpl @@ -739,17 +739,17 @@ steps: - ./bin/grabpl gen-version --build-id ${DRONE_BUILD_NUMBER} depends_on: - grabpl - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: gen-version - commands: - make gen-go - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: wire-install - commands: - yarn install --immutable depends_on: - grabpl - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: yarn-install - commands: - git clone "https://$${GITHUB_TOKEN}@github.com/grafana/grafana-enterprise.git" @@ -770,7 +770,7 @@ steps: from_secret: github_token TEST_TAG: v0.0.0-test failure: ignore - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: trigger-test-release when: paths: @@ -794,7 +794,7 @@ steps: depends_on: - gen-version - wire-install - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: build-backend - commands: - ./bin/grabpl build-frontend --jobs 8 --edition oss --build-id ${DRONE_BUILD_NUMBER} @@ -803,7 +803,7 @@ steps: - yarn-install environment: NODE_OPTIONS: --max_old_space_size=8192 - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: build-frontend - commands: - ./bin/grabpl build-frontend-packages --jobs 8 --edition oss --build-id ${DRONE_BUILD_NUMBER} @@ -812,7 +812,7 @@ steps: - yarn-install environment: NODE_OPTIONS: --max_old_space_size=8192 - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: build-frontend-packages - commands: - ./bin/grabpl build-plugins --jobs 8 --edition oss --sign --signing-admin @@ -822,13 +822,13 @@ steps: environment: GRAFANA_API_KEY: from_secret: grafana_api_key - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: build-plugins - commands: - ./bin/linux-amd64/grafana-cli cue validate-schema --grafana-root . depends_on: - build-backend - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: validate-scuemata - commands: - '# It is required that the generated Typescript be in sync with the input CUE @@ -841,7 +841,7 @@ steps: - ./bin/linux-amd64/grafana-cli cue gen-ts --grafana-root . --diff depends_on: - validate-scuemata - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: ensure-cuetsified - commands: - ./bin/grabpl package --jobs 8 --edition oss --build-id ${DRONE_BUILD_NUMBER} --sign @@ -859,7 +859,7 @@ steps: from_secret: gpg_pub_key GRAFANA_API_KEY: from_secret: grafana_api_key - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: package - commands: - ./scripts/grafana-server/start-server @@ -872,7 +872,7 @@ steps: environment: ARCH: linux-amd64 PORT: 3001 - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: grafana-server - commands: - apt-get install -y netcat @@ -950,7 +950,7 @@ steps: - build-frontend-packages environment: NODE_OPTIONS: --max_old_space_size=4096 - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: build-storybook - commands: - ./bin/grabpl store-storybook --deployment canary --src-bucket grafana-storybook @@ -991,7 +991,7 @@ steps: GRAFANA_MISC_STATS_API_KEY: from_secret: grafana_misc_stats_api_key failure: ignore - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: publish-frontend-metrics when: repo: @@ -1001,7 +1001,7 @@ steps: - cp dist/*.tar.gz* packaging/docker/ depends_on: - package - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: copy-packages-for-docker - commands: - ./bin/grabpl build-docker --edition oss @@ -1079,7 +1079,7 @@ steps: environment: NPM_TOKEN: from_secret: npm_token - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: release-canary-npm-packages when: repo: @@ -1163,7 +1163,7 @@ services: steps: - commands: - mkdir -p bin - - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.37/grabpl + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.41/grabpl - chmod +x bin/grabpl image: byrnedo/alpine-curl:0.1.8 name: grabpl @@ -1184,7 +1184,7 @@ steps: GRAFANA_TEST_DB: postgres PGPASSWORD: grafanatest POSTGRES_HOST: postgres - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: postgres-integration-tests - commands: - apt-get update @@ -1199,7 +1199,7 @@ steps: environment: GRAFANA_TEST_DB: mysql MYSQL_HOST: mysql - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: mysql-integration-tests trigger: branch: main @@ -1235,7 +1235,7 @@ steps: name: identify-runner - commands: - $$ProgressPreference = "SilentlyContinue" - - Invoke-WebRequest https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.37/windows/grabpl.exe + - Invoke-WebRequest https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.41/windows/grabpl.exe -OutFile grabpl.exe image: grafana/ci-wix:0.1.1 name: windows-init @@ -1322,7 +1322,7 @@ services: [] steps: - commands: - mkdir -p bin - - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.37/grabpl + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.41/grabpl - chmod +x bin/grabpl image: byrnedo/alpine-curl:0.1.8 name: grabpl @@ -1406,7 +1406,7 @@ steps: name: identify-runner - commands: - mkdir -p bin - - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.37/grabpl + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.41/grabpl - chmod +x bin/grabpl image: byrnedo/alpine-curl:0.1.8 name: grabpl @@ -1414,24 +1414,24 @@ steps: - ./bin/grabpl gen-version ${DRONE_TAG} depends_on: - grabpl - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: gen-version - commands: - make gen-go - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: wire-install - commands: - yarn install --immutable depends_on: - grabpl - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: yarn-install - commands: - ./bin/grabpl build-backend --jobs 8 --edition oss ${DRONE_TAG} depends_on: - gen-version - wire-install - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: build-backend - commands: - ./bin/grabpl build-frontend --jobs 8 --edition oss ${DRONE_TAG} @@ -1440,7 +1440,7 @@ steps: - yarn-install environment: NODE_OPTIONS: --max_old_space_size=8192 - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: build-frontend - commands: - ./bin/grabpl build-frontend-packages --jobs 8 --edition oss ${DRONE_TAG} @@ -1449,7 +1449,7 @@ steps: - yarn-install environment: NODE_OPTIONS: --max_old_space_size=8192 - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: build-frontend-packages - commands: - ./bin/grabpl build-plugins --jobs 8 --edition oss --sign --signing-admin @@ -1459,13 +1459,13 @@ steps: environment: GRAFANA_API_KEY: from_secret: grafana_api_key - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: build-plugins - commands: - ./bin/linux-amd64/grafana-cli cue validate-schema --grafana-root . depends_on: - build-backend - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: validate-scuemata - commands: - '# It is required that the generated Typescript be in sync with the input CUE @@ -1478,7 +1478,7 @@ steps: - ./bin/linux-amd64/grafana-cli cue gen-ts --grafana-root . --diff depends_on: - validate-scuemata - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: ensure-cuetsified - commands: - ./bin/grabpl package --jobs 8 --edition oss --sign ${DRONE_TAG} @@ -1496,14 +1496,14 @@ steps: from_secret: gpg_pub_key GRAFANA_API_KEY: from_secret: grafana_api_key - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: package - commands: - ls dist/*.tar.gz* - cp dist/*.tar.gz* packaging/docker/ depends_on: - package - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: copy-packages-for-docker - commands: - ./bin/grabpl build-docker --edition oss --shouldSave @@ -1540,7 +1540,7 @@ steps: environment: ARCH: linux-amd64 PORT: 3001 - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: grafana-server - commands: - apt-get install -y netcat @@ -1618,7 +1618,7 @@ steps: - build-frontend-packages environment: NODE_OPTIONS: --max_old_space_size=4096 - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: build-storybook - commands: - ./bin/grabpl upload-cdn --edition oss --src-bucket "$${PRERELEASE_BUCKET}" --src-dir @@ -1712,7 +1712,7 @@ steps: name: identify-runner - commands: - mkdir -p bin - - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.37/grabpl + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.41/grabpl - chmod +x bin/grabpl image: byrnedo/alpine-curl:0.1.8 name: grabpl @@ -1720,23 +1720,23 @@ steps: - ./bin/grabpl gen-version ${DRONE_TAG} depends_on: - grabpl - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: gen-version - commands: - make gen-go - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: wire-install - commands: - yarn install --immutable depends_on: - grabpl - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: yarn-install - commands: - ./bin/grabpl shellcheck depends_on: - grabpl - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: shellcheck - commands: - |- @@ -1748,7 +1748,7 @@ steps: wan" > words_to_ignore.txt - codespell -I words_to_ignore.txt docs/ - rm words_to_ignore.txt - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: codespell - commands: - ./bin/grabpl lint-backend --edition oss @@ -1756,7 +1756,7 @@ steps: - wire-install environment: CGO_ENABLED: "1" - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: lint-backend - commands: - yarn run prettier:check @@ -1767,19 +1767,19 @@ steps: - yarn-install environment: TEST_MAX_WORKERS: 50% - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: lint-frontend - commands: - ./bin/grabpl test-backend --edition oss depends_on: - wire-install - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: test-backend - commands: - ./bin/grabpl integration-tests --edition oss depends_on: - wire-install - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: test-backend-integration - commands: - yarn run ci:test-frontend @@ -1787,7 +1787,7 @@ steps: - yarn-install environment: TEST_MAX_WORKERS: 50% - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: test-frontend trigger: event: @@ -1836,7 +1836,7 @@ services: steps: - commands: - mkdir -p bin - - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.37/grabpl + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.41/grabpl - chmod +x bin/grabpl image: byrnedo/alpine-curl:0.1.8 name: grabpl @@ -1857,7 +1857,7 @@ steps: GRAFANA_TEST_DB: postgres PGPASSWORD: grafanatest POSTGRES_HOST: postgres - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: postgres-integration-tests - commands: - apt-get update @@ -1872,7 +1872,7 @@ steps: environment: GRAFANA_TEST_DB: mysql MYSQL_HOST: mysql - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: mysql-integration-tests trigger: event: @@ -1913,7 +1913,7 @@ steps: name: identify-runner - commands: - $$ProgressPreference = "SilentlyContinue" - - Invoke-WebRequest https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.37/windows/grabpl.exe + - Invoke-WebRequest https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.41/windows/grabpl.exe -OutFile grabpl.exe image: grafana/ci-wix:0.1.1 name: windows-init @@ -1972,7 +1972,7 @@ services: [] steps: - commands: - mkdir -p bin - - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.37/grabpl + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.41/grabpl - chmod +x bin/grabpl image: byrnedo/alpine-curl:0.1.8 name: grabpl @@ -1987,7 +1987,7 @@ steps: environment: GITHUB_TOKEN: from_secret: github_token - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: clone-enterprise - commands: - mv bin/grabpl /tmp/ @@ -2003,32 +2003,32 @@ steps: environment: GITHUB_TOKEN: from_secret: github_token - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: init-enterprise - commands: - make gen-go depends_on: - init-enterprise - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: wire-install - commands: - yarn install --immutable depends_on: - init-enterprise - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: yarn-install - commands: - ./bin/grabpl gen-version ${DRONE_TAG} depends_on: - init-enterprise - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: gen-version - commands: - ./bin/grabpl build-backend --jobs 8 --edition enterprise ${DRONE_TAG} depends_on: - gen-version - wire-install - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: build-backend - commands: - ./bin/grabpl build-frontend --jobs 8 --edition enterprise ${DRONE_TAG} @@ -2037,7 +2037,7 @@ steps: - yarn-install environment: NODE_OPTIONS: --max_old_space_size=8192 - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: build-frontend - commands: - ./bin/grabpl build-frontend-packages --jobs 8 --edition enterprise ${DRONE_TAG} @@ -2046,7 +2046,7 @@ steps: - yarn-install environment: NODE_OPTIONS: --max_old_space_size=8192 - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: build-frontend-packages - commands: - ./bin/grabpl build-plugins --jobs 8 --edition enterprise --sign --signing-admin @@ -2056,13 +2056,13 @@ steps: environment: GRAFANA_API_KEY: from_secret: grafana_api_key - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: build-plugins - commands: - ./bin/linux-amd64/grafana-cli cue validate-schema --grafana-root . depends_on: - build-backend - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: validate-scuemata - commands: - '# It is required that the generated Typescript be in sync with the input CUE @@ -2075,14 +2075,14 @@ steps: - ./bin/linux-amd64/grafana-cli cue gen-ts --grafana-root . --diff depends_on: - validate-scuemata - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: ensure-cuetsified - commands: - ./bin/grabpl build-backend --jobs 8 --edition enterprise2 ${DRONE_TAG} depends_on: - gen-version - wire-install - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: build-backend-enterprise2 - commands: - ./bin/grabpl package --jobs 8 --edition enterprise --sign ${DRONE_TAG} @@ -2101,14 +2101,14 @@ steps: from_secret: gpg_pub_key GRAFANA_API_KEY: from_secret: grafana_api_key - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: package - commands: - ls dist/*.tar.gz* - cp dist/*.tar.gz* packaging/docker/ depends_on: - package - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: copy-packages-for-docker - commands: - ./bin/grabpl build-docker --edition enterprise --shouldSave @@ -2146,7 +2146,7 @@ steps: ARCH: linux-amd64 PORT: 3001 RUNDIR: scripts/grafana-server/tmp-grafana-enterprise - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: grafana-server - commands: - apt-get install -y netcat @@ -2267,7 +2267,7 @@ steps: from_secret: gpg_pub_key GRAFANA_API_KEY: from_secret: grafana_api_key - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: package-enterprise2 - commands: - ./bin/grabpl upload-cdn --edition enterprise2 --src-bucket "$${PRERELEASE_BUCKET}" @@ -2329,7 +2329,7 @@ services: [] steps: - commands: - mkdir -p bin - - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.37/grabpl + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.41/grabpl - chmod +x bin/grabpl image: byrnedo/alpine-curl:0.1.8 name: grabpl @@ -2344,7 +2344,7 @@ steps: environment: GITHUB_TOKEN: from_secret: github_token - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: clone-enterprise - commands: - mv bin/grabpl /tmp/ @@ -2360,25 +2360,25 @@ steps: environment: GITHUB_TOKEN: from_secret: github_token - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: init-enterprise - commands: - make gen-go depends_on: - init-enterprise - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: wire-install - commands: - yarn install --immutable depends_on: - init-enterprise - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: yarn-install - commands: - ./bin/grabpl gen-version ${DRONE_TAG} depends_on: - init-enterprise - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: gen-version - commands: - |- @@ -2390,7 +2390,7 @@ steps: wan" > words_to_ignore.txt - codespell -I words_to_ignore.txt docs/ - rm words_to_ignore.txt - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: codespell - commands: - ./bin/grabpl lint-backend --edition enterprise @@ -2398,7 +2398,7 @@ steps: - wire-install environment: CGO_ENABLED: "1" - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: lint-backend - commands: - yarn run prettier:check @@ -2409,19 +2409,19 @@ steps: - yarn-install environment: TEST_MAX_WORKERS: 50% - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: lint-frontend - commands: - ./bin/grabpl test-backend --edition enterprise depends_on: - wire-install - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: test-backend - commands: - ./bin/grabpl integration-tests --edition enterprise depends_on: - wire-install - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: test-backend-integration - commands: - yarn run ci:test-frontend @@ -2429,7 +2429,7 @@ steps: - yarn-install environment: TEST_MAX_WORKERS: 50% - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: test-frontend - commands: - ./bin/grabpl lint-backend --edition enterprise2 @@ -2437,19 +2437,19 @@ steps: - wire-install environment: CGO_ENABLED: "1" - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: lint-backend-enterprise2 - commands: - ./bin/grabpl test-backend --edition enterprise2 depends_on: - wire-install - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: test-backend-enterprise2 - commands: - ./bin/grabpl integration-tests --edition enterprise2 depends_on: - wire-install - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: test-backend-integration-enterprise2 trigger: event: @@ -2508,7 +2508,7 @@ services: steps: - commands: - mkdir -p bin - - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.37/grabpl + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.41/grabpl - chmod +x bin/grabpl image: byrnedo/alpine-curl:0.1.8 name: grabpl @@ -2523,7 +2523,7 @@ steps: environment: GITHUB_TOKEN: from_secret: github_token - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: clone-enterprise - commands: - mv bin/grabpl /tmp/ @@ -2539,7 +2539,7 @@ steps: environment: GITHUB_TOKEN: from_secret: github_token - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: init-enterprise - commands: - apt-get update @@ -2554,7 +2554,7 @@ steps: GRAFANA_TEST_DB: postgres PGPASSWORD: grafanatest POSTGRES_HOST: postgres - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: postgres-integration-tests - commands: - apt-get update @@ -2569,7 +2569,7 @@ steps: environment: GRAFANA_TEST_DB: mysql MYSQL_HOST: mysql - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: mysql-integration-tests - commands: - dockerize -wait tcp://redis:6379/0 -timeout 120s @@ -2578,7 +2578,7 @@ steps: - init-enterprise environment: REDIS_URL: redis://redis:6379/0 - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: redis-integration-tests - commands: - dockerize -wait tcp://memcached:11211 -timeout 120s @@ -2587,7 +2587,7 @@ steps: - init-enterprise environment: MEMCACHED_HOSTS: memcached:11211 - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: memcached-integration-tests trigger: event: @@ -2632,7 +2632,7 @@ steps: name: identify-runner - commands: - $$ProgressPreference = "SilentlyContinue" - - Invoke-WebRequest https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.37/windows/grabpl.exe + - Invoke-WebRequest https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.41/windows/grabpl.exe -OutFile grabpl.exe - git clone "https://$$env:GITHUB_TOKEN@github.com/grafana/grafana-enterprise.git" - cd grafana-enterprise @@ -2707,7 +2707,7 @@ services: [] steps: - commands: - mkdir -p bin - - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.37/grabpl + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.41/grabpl - chmod +x bin/grabpl image: byrnedo/alpine-curl:0.1.8 name: grabpl @@ -2785,7 +2785,7 @@ services: [] steps: - commands: - mkdir -p bin - - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.37/grabpl + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.41/grabpl - chmod +x bin/grabpl image: byrnedo/alpine-curl:0.1.8 name: grabpl @@ -2846,7 +2846,7 @@ services: [] steps: - commands: - mkdir -p bin - - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.37/grabpl + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.41/grabpl - chmod +x bin/grabpl image: byrnedo/alpine-curl:0.1.8 name: grabpl @@ -2925,7 +2925,7 @@ services: [] steps: - commands: - mkdir -p bin - - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.37/grabpl + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.41/grabpl - chmod +x bin/grabpl image: byrnedo/alpine-curl:0.1.8 name: grabpl @@ -2987,7 +2987,7 @@ services: [] steps: - commands: - mkdir -p bin - - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.37/grabpl + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.41/grabpl - chmod +x bin/grabpl image: byrnedo/alpine-curl:0.1.8 name: grabpl @@ -3025,7 +3025,7 @@ services: [] steps: - commands: - mkdir -p bin - - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.37/grabpl + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.41/grabpl - chmod +x bin/grabpl image: byrnedo/alpine-curl:0.1.8 name: grabpl @@ -3063,7 +3063,7 @@ services: [] steps: - commands: - mkdir -p bin - - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.37/grabpl + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.41/grabpl - chmod +x bin/grabpl image: byrnedo/alpine-curl:0.1.8 name: grabpl @@ -3085,7 +3085,7 @@ steps: environment: NPM_TOKEN: from_secret: npm_token - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: release-npm-packages trigger: event: @@ -3113,7 +3113,7 @@ services: [] steps: - commands: - mkdir -p bin - - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.37/grabpl + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.41/grabpl - chmod +x bin/grabpl image: byrnedo/alpine-curl:0.1.8 name: grabpl @@ -3180,7 +3180,7 @@ steps: name: identify-runner - commands: - mkdir -p bin - - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.37/grabpl + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.41/grabpl - chmod +x bin/grabpl image: byrnedo/alpine-curl:0.1.8 name: grabpl @@ -3188,24 +3188,24 @@ steps: - ./bin/grabpl gen-version --build-id ${DRONE_BUILD_NUMBER} depends_on: - grabpl - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: gen-version - commands: - make gen-go - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: wire-install - commands: - yarn install --immutable depends_on: - grabpl - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: yarn-install - commands: - ./bin/grabpl build-backend --jobs 8 --edition oss --build-id ${DRONE_BUILD_NUMBER} depends_on: - gen-version - wire-install - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: build-backend - commands: - ./bin/grabpl build-frontend --jobs 8 --edition oss --build-id ${DRONE_BUILD_NUMBER} @@ -3214,7 +3214,7 @@ steps: - yarn-install environment: NODE_OPTIONS: --max_old_space_size=8192 - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: build-frontend - commands: - ./bin/grabpl build-frontend-packages --jobs 8 --edition oss --build-id ${DRONE_BUILD_NUMBER} @@ -3223,7 +3223,7 @@ steps: - yarn-install environment: NODE_OPTIONS: --max_old_space_size=8192 - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: build-frontend-packages - commands: - ./bin/grabpl build-plugins --jobs 8 --edition oss --sign --signing-admin @@ -3233,13 +3233,13 @@ steps: environment: GRAFANA_API_KEY: from_secret: grafana_api_key - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: build-plugins - commands: - ./bin/linux-amd64/grafana-cli cue validate-schema --grafana-root . depends_on: - build-backend - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: validate-scuemata - commands: - '# It is required that the generated Typescript be in sync with the input CUE @@ -3252,7 +3252,7 @@ steps: - ./bin/linux-amd64/grafana-cli cue gen-ts --grafana-root . --diff depends_on: - validate-scuemata - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: ensure-cuetsified - commands: - ./bin/grabpl package --jobs 8 --edition oss --build-id ${DRONE_BUILD_NUMBER} --sign @@ -3270,14 +3270,14 @@ steps: from_secret: gpg_pub_key GRAFANA_API_KEY: from_secret: grafana_api_key - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: package - commands: - ls dist/*.tar.gz* - cp dist/*.tar.gz* packaging/docker/ depends_on: - package - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: copy-packages-for-docker - commands: - ./bin/grabpl build-docker --edition oss --shouldSave @@ -3314,7 +3314,7 @@ steps: environment: ARCH: linux-amd64 PORT: 3001 - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: grafana-server - commands: - apt-get install -y netcat @@ -3392,7 +3392,7 @@ steps: - build-frontend-packages environment: NODE_OPTIONS: --max_old_space_size=4096 - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: build-storybook - commands: - ./bin/grabpl upload-cdn --edition oss --src-bucket "grafana-static-assets" @@ -3456,7 +3456,7 @@ steps: name: identify-runner - commands: - mkdir -p bin - - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.37/grabpl + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.41/grabpl - chmod +x bin/grabpl image: byrnedo/alpine-curl:0.1.8 name: grabpl @@ -3464,23 +3464,23 @@ steps: - ./bin/grabpl gen-version --build-id ${DRONE_BUILD_NUMBER} depends_on: - grabpl - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: gen-version - commands: - make gen-go - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: wire-install - commands: - yarn install --immutable depends_on: - grabpl - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: yarn-install - commands: - ./bin/grabpl shellcheck depends_on: - grabpl - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: shellcheck - commands: - |- @@ -3492,7 +3492,7 @@ steps: wan" > words_to_ignore.txt - codespell -I words_to_ignore.txt docs/ - rm words_to_ignore.txt - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: codespell - commands: - ./bin/grabpl lint-backend --edition oss @@ -3500,7 +3500,7 @@ steps: - wire-install environment: CGO_ENABLED: "1" - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: lint-backend - commands: - yarn run prettier:check @@ -3511,19 +3511,19 @@ steps: - yarn-install environment: TEST_MAX_WORKERS: 50% - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: lint-frontend - commands: - ./bin/grabpl test-backend --edition oss depends_on: - wire-install - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: test-backend - commands: - ./bin/grabpl integration-tests --edition oss depends_on: - wire-install - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: test-backend-integration - commands: - yarn run ci:test-frontend @@ -3531,7 +3531,7 @@ steps: - yarn-install environment: TEST_MAX_WORKERS: 50% - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: test-frontend trigger: ref: @@ -3574,7 +3574,7 @@ services: steps: - commands: - mkdir -p bin - - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.37/grabpl + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.41/grabpl - chmod +x bin/grabpl image: byrnedo/alpine-curl:0.1.8 name: grabpl @@ -3595,7 +3595,7 @@ steps: GRAFANA_TEST_DB: postgres PGPASSWORD: grafanatest POSTGRES_HOST: postgres - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: postgres-integration-tests - commands: - apt-get update @@ -3610,7 +3610,7 @@ steps: environment: GRAFANA_TEST_DB: mysql MYSQL_HOST: mysql - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: mysql-integration-tests trigger: ref: @@ -3645,7 +3645,7 @@ steps: name: identify-runner - commands: - $$ProgressPreference = "SilentlyContinue" - - Invoke-WebRequest https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.37/windows/grabpl.exe + - Invoke-WebRequest https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.41/windows/grabpl.exe -OutFile grabpl.exe image: grafana/ci-wix:0.1.1 name: windows-init @@ -3693,7 +3693,7 @@ services: [] steps: - commands: - mkdir -p bin - - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.37/grabpl + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.41/grabpl - chmod +x bin/grabpl image: byrnedo/alpine-curl:0.1.8 name: grabpl @@ -3708,7 +3708,7 @@ steps: environment: GITHUB_TOKEN: from_secret: github_token - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: clone-enterprise - commands: - mv bin/grabpl /tmp/ @@ -3721,32 +3721,32 @@ steps: depends_on: - clone-enterprise environment: {} - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: init-enterprise - commands: - make gen-go depends_on: - init-enterprise - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: wire-install - commands: - yarn install --immutable depends_on: - init-enterprise - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: yarn-install - commands: - ./bin/grabpl gen-version --build-id ${DRONE_BUILD_NUMBER} depends_on: - init-enterprise - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: gen-version - commands: - ./bin/grabpl build-backend --jobs 8 --edition enterprise --build-id ${DRONE_BUILD_NUMBER} depends_on: - gen-version - wire-install - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: build-backend - commands: - ./bin/grabpl build-frontend --jobs 8 --edition enterprise --build-id ${DRONE_BUILD_NUMBER} @@ -3755,7 +3755,7 @@ steps: - yarn-install environment: NODE_OPTIONS: --max_old_space_size=8192 - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: build-frontend - commands: - ./bin/grabpl build-frontend-packages --jobs 8 --edition enterprise --build-id @@ -3765,7 +3765,7 @@ steps: - yarn-install environment: NODE_OPTIONS: --max_old_space_size=8192 - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: build-frontend-packages - commands: - ./bin/grabpl build-plugins --jobs 8 --edition enterprise --sign --signing-admin @@ -3775,13 +3775,13 @@ steps: environment: GRAFANA_API_KEY: from_secret: grafana_api_key - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: build-plugins - commands: - ./bin/linux-amd64/grafana-cli cue validate-schema --grafana-root . depends_on: - build-backend - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: validate-scuemata - commands: - '# It is required that the generated Typescript be in sync with the input CUE @@ -3794,7 +3794,7 @@ steps: - ./bin/linux-amd64/grafana-cli cue gen-ts --grafana-root . --diff depends_on: - validate-scuemata - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: ensure-cuetsified - commands: - ./bin/grabpl build-backend --jobs 8 --edition enterprise2 --build-id ${DRONE_BUILD_NUMBER} @@ -3802,7 +3802,7 @@ steps: depends_on: - gen-version - wire-install - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: build-backend-enterprise2 - commands: - ./bin/grabpl package --jobs 8 --edition enterprise --build-id ${DRONE_BUILD_NUMBER} @@ -3822,14 +3822,14 @@ steps: from_secret: gpg_pub_key GRAFANA_API_KEY: from_secret: grafana_api_key - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: package - commands: - ls dist/*.tar.gz* - cp dist/*.tar.gz* packaging/docker/ depends_on: - package - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: copy-packages-for-docker - commands: - ./bin/grabpl build-docker --edition enterprise --shouldSave @@ -3867,7 +3867,7 @@ steps: ARCH: linux-amd64 PORT: 3001 RUNDIR: scripts/grafana-server/tmp-grafana-enterprise - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: grafana-server - commands: - apt-get install -y netcat @@ -3945,7 +3945,7 @@ steps: - build-frontend-packages environment: NODE_OPTIONS: --max_old_space_size=4096 - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: build-storybook - commands: - ./bin/grabpl upload-cdn --edition enterprise --src-bucket "grafana-static-assets" @@ -3993,7 +3993,7 @@ steps: from_secret: gpg_pub_key GRAFANA_API_KEY: from_secret: grafana_api_key - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: package-enterprise2 - commands: - ./bin/grabpl upload-cdn --edition enterprise2 --src-bucket "grafana-static-assets" @@ -4048,7 +4048,7 @@ services: [] steps: - commands: - mkdir -p bin - - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.37/grabpl + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.41/grabpl - chmod +x bin/grabpl image: byrnedo/alpine-curl:0.1.8 name: grabpl @@ -4063,7 +4063,7 @@ steps: environment: GITHUB_TOKEN: from_secret: github_token - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: clone-enterprise - commands: - mv bin/grabpl /tmp/ @@ -4076,25 +4076,25 @@ steps: depends_on: - clone-enterprise environment: {} - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: init-enterprise - commands: - make gen-go depends_on: - init-enterprise - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: wire-install - commands: - yarn install --immutable depends_on: - init-enterprise - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: yarn-install - commands: - ./bin/grabpl gen-version --build-id ${DRONE_BUILD_NUMBER} depends_on: - init-enterprise - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: gen-version - commands: - |- @@ -4106,7 +4106,7 @@ steps: wan" > words_to_ignore.txt - codespell -I words_to_ignore.txt docs/ - rm words_to_ignore.txt - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: codespell - commands: - ./bin/grabpl lint-backend --edition enterprise @@ -4114,7 +4114,7 @@ steps: - wire-install environment: CGO_ENABLED: "1" - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: lint-backend - commands: - yarn run prettier:check @@ -4125,19 +4125,19 @@ steps: - yarn-install environment: TEST_MAX_WORKERS: 50% - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: lint-frontend - commands: - ./bin/grabpl test-backend --edition enterprise depends_on: - wire-install - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: test-backend - commands: - ./bin/grabpl integration-tests --edition enterprise depends_on: - wire-install - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: test-backend-integration - commands: - yarn run ci:test-frontend @@ -4145,7 +4145,7 @@ steps: - yarn-install environment: TEST_MAX_WORKERS: 50% - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: test-frontend - commands: - ./bin/grabpl lint-backend --edition enterprise2 @@ -4153,19 +4153,19 @@ steps: - wire-install environment: CGO_ENABLED: "1" - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: lint-backend-enterprise2 - commands: - ./bin/grabpl test-backend --edition enterprise2 depends_on: - wire-install - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: test-backend-enterprise2 - commands: - ./bin/grabpl integration-tests --edition enterprise2 depends_on: - wire-install - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: test-backend-integration-enterprise2 trigger: ref: @@ -4218,7 +4218,7 @@ services: steps: - commands: - mkdir -p bin - - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.37/grabpl + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.41/grabpl - chmod +x bin/grabpl image: byrnedo/alpine-curl:0.1.8 name: grabpl @@ -4233,7 +4233,7 @@ steps: environment: GITHUB_TOKEN: from_secret: github_token - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: clone-enterprise - commands: - mv bin/grabpl /tmp/ @@ -4246,7 +4246,7 @@ steps: depends_on: - clone-enterprise environment: {} - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: init-enterprise - commands: - apt-get update @@ -4261,7 +4261,7 @@ steps: GRAFANA_TEST_DB: postgres PGPASSWORD: grafanatest POSTGRES_HOST: postgres - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: postgres-integration-tests - commands: - apt-get update @@ -4276,7 +4276,7 @@ steps: environment: GRAFANA_TEST_DB: mysql MYSQL_HOST: mysql - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: mysql-integration-tests - commands: - dockerize -wait tcp://redis:6379/0 -timeout 120s @@ -4285,7 +4285,7 @@ steps: - init-enterprise environment: REDIS_URL: redis://redis:6379/0 - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: redis-integration-tests - commands: - dockerize -wait tcp://memcached:11211 -timeout 120s @@ -4294,7 +4294,7 @@ steps: - init-enterprise environment: MEMCACHED_HOSTS: memcached:11211 - image: grafana/build-container:1.5.3 + image: grafana/build-container:1.5.4 name: memcached-integration-tests trigger: ref: @@ -4333,7 +4333,7 @@ steps: name: identify-runner - commands: - $$ProgressPreference = "SilentlyContinue" - - Invoke-WebRequest https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.37/windows/grabpl.exe + - Invoke-WebRequest https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.41/windows/grabpl.exe -OutFile grabpl.exe - git clone "https://$$env:GITHUB_TOKEN@github.com/grafana/grafana-enterprise.git" - cd grafana-enterprise @@ -4530,6 +4530,6 @@ kind: secret name: gcp_upload_artifacts_key --- kind: signature -hmac: 803ec2a67b1758ce82ddda8ba1fb276fd23e4cfbfc3c5736bf2fa9e98edc2e6b +hmac: aea46d49d8ad417e04e7b6bc48a7a02affb1b53a1048d0970d4ec7a0d9858eaf ... diff --git a/Dockerfile b/Dockerfile index 711dc84fb05..455a24b0774 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,7 +20,7 @@ COPY emails emails ENV NODE_ENV production RUN yarn build -FROM golang:1.17.8-alpine3.15 as go-builder +FROM golang:1.17.9-alpine3.15 as go-builder RUN apk add --no-cache gcc g++ make diff --git a/Dockerfile.ubuntu b/Dockerfile.ubuntu index a8c2760a639..f8ee00a412d 100644 --- a/Dockerfile.ubuntu +++ b/Dockerfile.ubuntu @@ -21,7 +21,7 @@ COPY emails emails ENV NODE_ENV production RUN yarn build -FROM golang:1.17.8 AS go-builder +FROM golang:1.17.9 AS go-builder WORKDIR /src/grafana diff --git a/scripts/build/ci-build/Dockerfile b/scripts/build/ci-build/Dockerfile index d1cfb26dcb7..3a8b7454685 100644 --- a/scripts/build/ci-build/Dockerfile +++ b/scripts/build/ci-build/Dockerfile @@ -110,7 +110,7 @@ RUN rm dockerize-linux-amd64-v${DOCKERIZE_VERSION}.tar.gz # Use old Debian (this has support into 2022) in order to ensure binary compatibility with older glibc's. FROM debian:stretch-20210208 -ENV GOVERSION=1.17.8 \ +ENV GOVERSION=1.17.9 \ PATH=/usr/local/go/bin:$PATH \ GOPATH=/go \ NODEVERSION=16.14.0-1nodesource1 \ @@ -147,8 +147,10 @@ RUN apt-get update && \ unzip && \ gem install -N fpm && \ ln -s /usr/bin/llvm-dsymutil-6.0 /usr/bin/dsymutil && \ - curl -fsL https://deb.nodesource.com/setup_16.x | bash - && \ - apt-get update && apt-get install -yq nodejs=${NODEVERSION} && \ + curl -fsS https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - && \ + curl -O https://deb.nodesource.com/node_16.x/pool/main/n/nodejs/nodejs_${NODEVERSION}_amd64.deb &&\ + dpkg -i nodejs_${NODEVERSION}_amd64.deb &&\ + rm nodejs_${NODEVERSION}_amd64.deb &&\ curl -fsS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \ echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \ apt-get update && apt-get install -yq yarn=${YARNVERSION} && \ diff --git a/scripts/build/ci-build/Makefile b/scripts/build/ci-build/Makefile deleted file mode 100644 index 5645595c348..00000000000 --- a/scripts/build/ci-build/Makefile +++ /dev/null @@ -1,54 +0,0 @@ -VERSION = dev -TAG = grafana/build-container -USER_ID = $(shell id -u) -GROUP_ID = $(shell id -g) - -all: build deploy - -build: - docker build -t "${TAG}:${VERSION}" . - -deploy: - docker push "${TAG}:${VERSION}" - -run: - docker run -ti \ - -e "CIRCLE_BRANCH=local" \ - -e "CIRCLE_BUILD_NUM=472" \ - ${TAG}:${VERSION} \ - bash - -run-with-local-source-live: - docker run -d \ - -e "CIRCLE_BRANCH=local" \ - -e "CIRCLE_BUILD_NUM=472" \ - -w "/go/src/github.com/grafana/grafana" \ - --name grafana-build \ - -v "${GOPATH}/src/github.com/grafana/grafana:/go/src/github.com/grafana/grafana" \ - ${TAG}:${VERSION} \ - bash -c "/tmp/bootstrap.sh; mkdir /.cache; chown "${USER_ID}:${GROUP_ID}" /.cache; tail -f /dev/null" - docker exec -ti --user "${USER_ID}:${GROUP_ID}" grafana-build bash - -run-with-local-source-copy: - docker run -d \ - -e "CIRCLE_BRANCH=local" \ - -e "CIRCLE_BUILD_NUM=472" \ - -w "/go/src/github.com/grafana/grafana" \ - --name grafana-build \ - ${TAG}:${VERSION} \ - bash -c "/tmp/bootstrap.sh; tail -f /dev/null" - docker cp "${GOPATH}/src/github.com/grafana/grafana" grafana-build:/go/src/github.com/grafana/ - docker exec -ti grafana-build bash - -update-source: - docker cp "${GOPATH}/src/github.com/grafana/grafana" grafana-build:/go/src/github.com/grafana/ - -attach: - docker exec -ti grafana-build bash - -attach-live: - docker exec -ti --user "${USER_ID}:${GROUP_ID}" grafana-build bash - -stop: - docker kill grafana-build - docker rm grafana-build diff --git a/scripts/build/ci-build/README.md b/scripts/build/ci-build/README.md index 61a9695f7c2..94790a90a7c 100644 --- a/scripts/build/ci-build/README.md +++ b/scripts/build/ci-build/README.md @@ -5,19 +5,6 @@ is in Dockerfile, but there are supporting scripts such as the Makefile, for bui The image is based on Debian Stretch, since we want an older Linux distribution (Stretch has long-term support into 2022) to build binaries that are as portable as possible. -## Makefile targets - -- `make run-with-local-source-copy` - - Starts the container locally and copies your local sources into the container -- `make run-with-local-source-live` - - Starts the container (as your user) locally and maps your Grafana project dir into the container -- `make update-source` - - Updates the sources in the container from your local sources -- `make stop` - - Kills the container -- `make attach` - - Opens bash within the running container - ## Build/Publish Docker Image In order to build and publish the Grafana build Docker image, execute the following: diff --git a/scripts/drone/steps/lib.star b/scripts/drone/steps/lib.star index 55c861d9968..02e3afe4873 100644 --- a/scripts/drone/steps/lib.star +++ b/scripts/drone/steps/lib.star @@ -1,7 +1,7 @@ load('scripts/drone/vault.star', 'from_secret', 'github_token', 'pull_secret', 'drone_token', 'prerelease_bucket') -grabpl_version = 'v2.9.37' -build_image = 'grafana/build-container:1.5.3' +grabpl_version = 'v2.9.41' +build_image = 'grafana/build-container:1.5.4' publish_image = 'grafana/grafana-ci-deploy:1.3.1' deploy_docker_image = 'us.gcr.io/kubernetes-dev/drone/plugins/deploy-image' alpine_image = 'alpine:3.15' From 70802447a5b582561fd2a6a8e2c7a8de741faaf8 Mon Sep 17 00:00:00 2001 From: Andres Martinez Gotor Date: Wed, 20 Apr 2022 00:27:04 -0700 Subject: [PATCH 012/120] AzureMonitor: Update kusto-monaco package (#47897) --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 8c2633c5788..b3cc652ef93 100644 --- a/package.json +++ b/package.json @@ -257,7 +257,7 @@ "@grafana/slate-react": "0.22.10-grafana", "@grafana/ui": "workspace:*", "@jaegertracing/jaeger-ui-components": "workspace:*", - "@kusto/monaco-kusto": "5.0.0", + "@kusto/monaco-kusto": "5.1.1", "@lezer/common": "0.15.12", "@lezer/lr": "0.15.8", "@lingui/core": "3.13.2", diff --git a/yarn.lock b/yarn.lock index d725dede624..105b341fcfd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5180,15 +5180,15 @@ __metadata: languageName: node linkType: hard -"@kusto/monaco-kusto@npm:5.0.0": - version: 5.0.0 - resolution: "@kusto/monaco-kusto@npm:5.0.0" +"@kusto/monaco-kusto@npm:5.1.1": + version: 5.1.1 + resolution: "@kusto/monaco-kusto@npm:5.1.1" dependencies: "@kusto/language-service": 2.0.0-beta.0 "@kusto/language-service-next": 0.0.54 peerDependencies: monaco-editor: 0.33.0 - checksum: 961bcae8a84562ad0d1aa199bdacbe5adfffafb01e98a2cf927883331d45ad8fcdf7385f9bde00eed16f74a33e0dea41f9eb80127e2e5a341ea3b8a2aa9fb2d8 + checksum: 51771a0a128640d6385d693200ef1128fa2d55250e4f8db97aa4e9c46350dc94c93238958a9a9640939c6813caad117fe3a858b50e7b72a413baa78e964a359c languageName: node linkType: hard @@ -20434,7 +20434,7 @@ __metadata: "@grafana/tsconfig": ^1.2.0-rc1 "@grafana/ui": "workspace:*" "@jaegertracing/jaeger-ui-components": "workspace:*" - "@kusto/monaco-kusto": 5.0.0 + "@kusto/monaco-kusto": 5.1.1 "@lezer/common": 0.15.12 "@lezer/lr": 0.15.8 "@lingui/cli": 3.13.2 From e58a015bafc9d3a2a0447b15c0a1ff17f5b00240 Mon Sep 17 00:00:00 2001 From: Sofia Papagiannaki <1632407+papagian@users.noreply.github.com> Date: Wed, 20 Apr 2022 10:27:25 +0300 Subject: [PATCH 013/120] Swagger: annotate RoleType as enumeration (#47902) --- pkg/models/apikey.go | 1 + pkg/models/org_user.go | 1 + public/api-merged.json | 89 ++++++++++++++++++++++++++---------------- public/api-spec.json | 89 ++++++++++++++++++++++++++---------------- 4 files changed, 114 insertions(+), 66 deletions(-) diff --git a/pkg/models/apikey.go b/pkg/models/apikey.go index 430dddf311f..aabbc4e78b4 100644 --- a/pkg/models/apikey.go +++ b/pkg/models/apikey.go @@ -26,6 +26,7 @@ type ApiKey struct { // --------------------- // COMMANDS +// swagger:model type AddApiKeyCommand struct { Name string `json:"name" binding:"Required"` Role RoleType `json:"role" binding:"Required"` diff --git a/pkg/models/org_user.go b/pkg/models/org_user.go index d2f0f732dd4..f91c28f0b58 100644 --- a/pkg/models/org_user.go +++ b/pkg/models/org_user.go @@ -14,6 +14,7 @@ var ( ErrOrgUserAlreadyAdded = errors.New("user is already added to organization") ) +// swagger:enum RoleType type RoleType string const ( diff --git a/public/api-merged.json b/public/api-merged.json index 2a329b78226..c889a5034df 100644 --- a/public/api-merged.json +++ b/public/api-merged.json @@ -506,14 +506,6 @@ "summary": "Add a user role assignment.", "operationId": "addUserRole", "parameters": [ - { - "type": "integer", - "format": "int64", - "x-go-name": "UserID", - "name": "user_id", - "in": "path", - "required": true - }, { "x-go-name": "Body", "name": "body", @@ -522,6 +514,14 @@ "schema": { "$ref": "#/definitions/AddUserRoleCommand" } + }, + { + "type": "integer", + "format": "int64", + "x-go-name": "UserID", + "name": "user_id", + "in": "path", + "required": true } ], "responses": { @@ -547,14 +547,6 @@ "summary": "Remove a user role assignment.", "operationId": "removeUserRole", "parameters": [ - { - "type": "integer", - "format": "int64", - "x-go-name": "UserID", - "name": "user_id", - "in": "path", - "required": true - }, { "type": "string", "x-go-name": "RoleUID", @@ -568,6 +560,14 @@ "description": "A flag indicating if the assignment is global or not. If set to false, the default org ID of the authenticated user will be used from the request to remove assignment.", "name": "global", "in": "query" + }, + { + "type": "integer", + "format": "int64", + "x-go-name": "UserID", + "name": "user_id", + "in": "path", + "required": true } ], "responses": { @@ -4625,15 +4625,15 @@ "parameters": [ { "type": "string", - "x-go-name": "DatasourceID", - "name": "datasource_id", + "x-go-name": "PermissionID", + "name": "permissionId", "in": "path", "required": true }, { "type": "string", - "x-go-name": "PermissionID", - "name": "permissionId", + "x-go-name": "DatasourceID", + "name": "datasource_id", "in": "path", "required": true } @@ -9550,7 +9550,10 @@ "x-go-name": "Name" }, "role": { - "$ref": "#/definitions/RoleType" + "type": "string", + "enum": ["Viewer", "Editor", "Admin"], + "x-go-enum-desc": "Viewer ROLE_VIEWER\nEditor ROLE_EDITOR\nAdmin ROLE_ADMIN", + "x-go-name": "Role" }, "secondsToLive": { "type": "integer", @@ -9660,7 +9663,10 @@ "x-go-name": "Name" }, "role": { - "$ref": "#/definitions/RoleType" + "type": "string", + "enum": ["Viewer", "Editor", "Admin"], + "x-go-enum-desc": "Viewer ROLE_VIEWER\nEditor ROLE_EDITOR\nAdmin ROLE_ADMIN", + "x-go-name": "Role" }, "sendEmail": { "type": "boolean", @@ -9677,7 +9683,10 @@ "x-go-name": "LoginOrEmail" }, "role": { - "$ref": "#/definitions/RoleType" + "type": "string", + "enum": ["Viewer", "Editor", "Admin"], + "x-go-enum-desc": "Viewer ROLE_VIEWER\nEditor ROLE_EDITOR\nAdmin ROLE_ADMIN", + "x-go-name": "Role" } }, "x-go-package": "github.com/grafana/grafana/pkg/models" @@ -10440,7 +10449,10 @@ "x-go-name": "Name" }, "role": { - "$ref": "#/definitions/RoleType" + "type": "string", + "enum": ["Viewer", "Editor", "Admin"], + "x-go-enum-desc": "Viewer ROLE_VIEWER\nEditor ROLE_EDITOR\nAdmin ROLE_ADMIN", + "x-go-name": "Role" } }, "x-go-package": "github.com/grafana/grafana/pkg/models" @@ -11039,7 +11051,10 @@ "x-go-name": "PermissionName" }, "role": { - "$ref": "#/definitions/RoleType" + "type": "string", + "enum": ["Viewer", "Editor", "Admin"], + "x-go-enum-desc": "Viewer ROLE_VIEWER\nEditor ROLE_EDITOR\nAdmin ROLE_ADMIN", + "x-go-name": "Role" }, "slug": { "type": "string", @@ -11106,7 +11121,10 @@ "$ref": "#/definitions/PermissionType" }, "role": { - "$ref": "#/definitions/RoleType" + "type": "string", + "enum": ["Viewer", "Editor", "Admin"], + "x-go-enum-desc": "Viewer ROLE_VIEWER\nEditor ROLE_EDITOR\nAdmin ROLE_ADMIN", + "x-go-name": "Role" }, "teamId": { "type": "integer", @@ -14876,10 +14894,6 @@ }, "x-go-package": "github.com/grafana/grafana/pkg/services/accesscontrol" }, - "RoleType": { - "type": "string", - "x-go-package": "github.com/grafana/grafana/pkg/models" - }, "Route": { "description": "A Route is a node that contains definitions of how to handle alerts. This is modified\nfrom the upstream alertmanager in that it adds the ObjectMatchers property.", "type": "object", @@ -15857,7 +15871,10 @@ "x-go-name": "OrgId" }, "role": { - "$ref": "#/definitions/RoleType" + "type": "string", + "enum": ["Viewer", "Editor", "Admin"], + "x-go-enum-desc": "Viewer ROLE_VIEWER\nEditor ROLE_EDITOR\nAdmin ROLE_ADMIN", + "x-go-name": "Role" }, "status": { "$ref": "#/definitions/TempUserStatus" @@ -16538,7 +16555,10 @@ "type": "object", "properties": { "role": { - "$ref": "#/definitions/RoleType" + "type": "string", + "enum": ["Viewer", "Editor", "Admin"], + "x-go-enum-desc": "Viewer ROLE_VIEWER\nEditor ROLE_EDITOR\nAdmin ROLE_ADMIN", + "x-go-name": "Role" } }, "x-go-package": "github.com/grafana/grafana/pkg/models" @@ -16727,7 +16747,10 @@ "x-go-name": "OrgId" }, "role": { - "$ref": "#/definitions/RoleType" + "type": "string", + "enum": ["Viewer", "Editor", "Admin"], + "x-go-enum-desc": "Viewer ROLE_VIEWER\nEditor ROLE_EDITOR\nAdmin ROLE_ADMIN", + "x-go-name": "Role" } }, "x-go-package": "github.com/grafana/grafana/pkg/models" diff --git a/public/api-spec.json b/public/api-spec.json index 117b03382c3..3ccfe18d1ef 100644 --- a/public/api-spec.json +++ b/public/api-spec.json @@ -506,14 +506,6 @@ "summary": "Add a user role assignment.", "operationId": "addUserRole", "parameters": [ - { - "type": "integer", - "format": "int64", - "x-go-name": "UserID", - "name": "user_id", - "in": "path", - "required": true - }, { "x-go-name": "Body", "name": "body", @@ -522,6 +514,14 @@ "schema": { "$ref": "#/definitions/AddUserRoleCommand" } + }, + { + "type": "integer", + "format": "int64", + "x-go-name": "UserID", + "name": "user_id", + "in": "path", + "required": true } ], "responses": { @@ -547,14 +547,6 @@ "summary": "Remove a user role assignment.", "operationId": "removeUserRole", "parameters": [ - { - "type": "integer", - "format": "int64", - "x-go-name": "UserID", - "name": "user_id", - "in": "path", - "required": true - }, { "type": "string", "x-go-name": "RoleUID", @@ -568,6 +560,14 @@ "description": "A flag indicating if the assignment is global or not. If set to false, the default org ID of the authenticated user will be used from the request to remove assignment.", "name": "global", "in": "query" + }, + { + "type": "integer", + "format": "int64", + "x-go-name": "UserID", + "name": "user_id", + "in": "path", + "required": true } ], "responses": { @@ -3675,15 +3675,15 @@ "parameters": [ { "type": "string", - "x-go-name": "DatasourceID", - "name": "datasource_id", + "x-go-name": "PermissionID", + "name": "permissionId", "in": "path", "required": true }, { "type": "string", - "x-go-name": "PermissionID", - "name": "permissionId", + "x-go-name": "DatasourceID", + "name": "datasource_id", "in": "path", "required": true } @@ -7797,7 +7797,10 @@ "x-go-name": "Name" }, "role": { - "$ref": "#/definitions/RoleType" + "type": "string", + "enum": ["Viewer", "Editor", "Admin"], + "x-go-enum-desc": "Viewer ROLE_VIEWER\nEditor ROLE_EDITOR\nAdmin ROLE_ADMIN", + "x-go-name": "Role" }, "secondsToLive": { "type": "integer", @@ -7907,7 +7910,10 @@ "x-go-name": "Name" }, "role": { - "$ref": "#/definitions/RoleType" + "type": "string", + "enum": ["Viewer", "Editor", "Admin"], + "x-go-enum-desc": "Viewer ROLE_VIEWER\nEditor ROLE_EDITOR\nAdmin ROLE_ADMIN", + "x-go-name": "Role" }, "sendEmail": { "type": "boolean", @@ -7924,7 +7930,10 @@ "x-go-name": "LoginOrEmail" }, "role": { - "$ref": "#/definitions/RoleType" + "type": "string", + "enum": ["Viewer", "Editor", "Admin"], + "x-go-enum-desc": "Viewer ROLE_VIEWER\nEditor ROLE_EDITOR\nAdmin ROLE_ADMIN", + "x-go-name": "Role" } }, "x-go-package": "github.com/grafana/grafana/pkg/models" @@ -8553,7 +8562,10 @@ "x-go-name": "Name" }, "role": { - "$ref": "#/definitions/RoleType" + "type": "string", + "enum": ["Viewer", "Editor", "Admin"], + "x-go-enum-desc": "Viewer ROLE_VIEWER\nEditor ROLE_EDITOR\nAdmin ROLE_ADMIN", + "x-go-name": "Role" } }, "x-go-package": "github.com/grafana/grafana/pkg/models" @@ -9047,7 +9059,10 @@ "x-go-name": "PermissionName" }, "role": { - "$ref": "#/definitions/RoleType" + "type": "string", + "enum": ["Viewer", "Editor", "Admin"], + "x-go-enum-desc": "Viewer ROLE_VIEWER\nEditor ROLE_EDITOR\nAdmin ROLE_ADMIN", + "x-go-name": "Role" }, "slug": { "type": "string", @@ -9114,7 +9129,10 @@ "$ref": "#/definitions/PermissionType" }, "role": { - "$ref": "#/definitions/RoleType" + "type": "string", + "enum": ["Viewer", "Editor", "Admin"], + "x-go-enum-desc": "Viewer ROLE_VIEWER\nEditor ROLE_EDITOR\nAdmin ROLE_ADMIN", + "x-go-name": "Role" }, "teamId": { "type": "integer", @@ -11254,10 +11272,6 @@ }, "x-go-package": "github.com/grafana/grafana/pkg/services/accesscontrol" }, - "RoleType": { - "type": "string", - "x-go-package": "github.com/grafana/grafana/pkg/models" - }, "SaveDashboardCommand": { "type": "object", "properties": { @@ -11709,7 +11723,10 @@ "x-go-name": "OrgId" }, "role": { - "$ref": "#/definitions/RoleType" + "type": "string", + "enum": ["Viewer", "Editor", "Admin"], + "x-go-enum-desc": "Viewer ROLE_VIEWER\nEditor ROLE_EDITOR\nAdmin ROLE_ADMIN", + "x-go-name": "Role" }, "status": { "$ref": "#/definitions/TempUserStatus" @@ -12181,7 +12198,10 @@ "type": "object", "properties": { "role": { - "$ref": "#/definitions/RoleType" + "type": "string", + "enum": ["Viewer", "Editor", "Admin"], + "x-go-enum-desc": "Viewer ROLE_VIEWER\nEditor ROLE_EDITOR\nAdmin ROLE_ADMIN", + "x-go-name": "Role" } }, "x-go-package": "github.com/grafana/grafana/pkg/models" @@ -12370,7 +12390,10 @@ "x-go-name": "OrgId" }, "role": { - "$ref": "#/definitions/RoleType" + "type": "string", + "enum": ["Viewer", "Editor", "Admin"], + "x-go-enum-desc": "Viewer ROLE_VIEWER\nEditor ROLE_EDITOR\nAdmin ROLE_ADMIN", + "x-go-name": "Role" } }, "x-go-package": "github.com/grafana/grafana/pkg/models" From 39d3c8afd7f7009d2c88740d18e46b4c7bc7cfd5 Mon Sep 17 00:00:00 2001 From: Peter Holmberg Date: Wed, 20 Apr 2022 09:40:57 +0200 Subject: [PATCH 014/120] Alerting: Fix issue with Slack contact point validation (#47559) * secureFields and secureSettings * revert channelIndex * readd lost code * use specific return * register secure fields and use not hard coded index * fix for determineReadOnly * fix lint error * fix test suite Co-authored-by: gillesdemey --- .../ngalert/notifier/available_channels.go | 6 +- .../receivers/form/ChannelOptions.tsx | 10 +--- .../receivers/form/ChannelSubForm.tsx | 6 +- .../receivers/form/fields/OptionField.tsx | 57 ++++++++++++++----- 4 files changed, 53 insertions(+), 26 deletions(-) diff --git a/pkg/services/ngalert/notifier/available_channels.go b/pkg/services/ngalert/notifier/available_channels.go index 65c52ff48e1..317b59db4bb 100644 --- a/pkg/services/ngalert/notifier/available_channels.go +++ b/pkg/services/ngalert/notifier/available_channels.go @@ -383,7 +383,7 @@ func GetAvailableNotifiers() []*alerting.NotifierPlugin { Description: "Specify channel, private group, or IM channel (can be an encoded ID or a name) - required unless you provide a webhook", PropertyName: "recipient", Required: true, - DependsOn: "secureSettings.url", + DependsOn: "url", }, // Logically, this field should be required when not using a webhook, since the Slack API needs a token. // However, since the UI doesn't allow to say that a field is required or not depending on another field, @@ -397,7 +397,7 @@ func GetAvailableNotifiers() []*alerting.NotifierPlugin { PropertyName: "token", Secure: true, Required: true, - DependsOn: "secureSettings.url", + DependsOn: "url", }, { Label: "Username", @@ -463,7 +463,7 @@ func GetAvailableNotifiers() []*alerting.NotifierPlugin { PropertyName: "url", Secure: true, Required: true, - DependsOn: "secureSettings.token", + DependsOn: "token", }, { // New in 8.4. Label: "Endpoint URL", diff --git a/public/app/features/alerting/unified/components/receivers/form/ChannelOptions.tsx b/public/app/features/alerting/unified/components/receivers/form/ChannelOptions.tsx index 875cd515e29..0e107f86e4c 100644 --- a/public/app/features/alerting/unified/components/receivers/form/ChannelOptions.tsx +++ b/public/app/features/alerting/unified/components/receivers/form/ChannelOptions.tsx @@ -47,12 +47,7 @@ export function ChannelOptions({ value="Configured" suffix={ readOnly ? null : ( - ) @@ -74,7 +69,8 @@ export function ChannelOptions({ readOnly={readOnly} key={key} error={error} - pathPrefix={option.secure ? `${pathPrefix}secureSettings.` : `${pathPrefix}settings.`} + pathPrefix={pathPrefix} + pathSuffix={option.secure ? 'secureSettings.' : 'settings.'} option={option} /> ); diff --git a/public/app/features/alerting/unified/components/receivers/form/ChannelSubForm.tsx b/public/app/features/alerting/unified/components/receivers/form/ChannelSubForm.tsx index 57cad1a84c6..b605088aab2 100644 --- a/public/app/features/alerting/unified/components/receivers/form/ChannelSubForm.tsx +++ b/public/app/features/alerting/unified/components/receivers/form/ChannelSubForm.tsx @@ -37,12 +37,15 @@ export function ChannelSubForm({ }: Props): JSX.Element { const styles = useStyles2(getStyles); const name = (fieldName: string) => `${pathPrefix}${fieldName}`; - const { control, watch, register, trigger, formState } = useFormContext(); + const { control, watch, register, trigger, formState, setValue } = useFormContext(); const selectedType = watch(name('type')) ?? defaultValues.type; // nope, setting "default" does not work at all. const { loading: testingReceiver } = useUnifiedAlertingSelector((state) => state.testReceivers); useEffect(() => { register(`${pathPrefix}.__id`); + /* Need to manually register secureFields or else they'll + be lost when testing a contact point */ + register(`${pathPrefix}.secureFields`); }, [register, pathPrefix]); const [_secureFields, setSecureFields] = useState(secureFields ?? {}); @@ -52,6 +55,7 @@ export function ChannelSubForm({ const updatedSecureFields = { ...secureFields }; delete updatedSecureFields[key]; setSecureFields(updatedSecureFields); + setValue(`${pathPrefix}.secureFields`, updatedSecureFields); } }; diff --git a/public/app/features/alerting/unified/components/receivers/form/fields/OptionField.tsx b/public/app/features/alerting/unified/components/receivers/form/fields/OptionField.tsx index 3d6c6df0329..4ed2456f06d 100644 --- a/public/app/features/alerting/unified/components/receivers/form/fields/OptionField.tsx +++ b/public/app/features/alerting/unified/components/receivers/form/fields/OptionField.tsx @@ -1,5 +1,6 @@ import React, { FC, useEffect } from 'react'; import { Checkbox, Field, Input, InputControl, Select, TextArea } from '@grafana/ui'; +import { isEmpty } from 'lodash'; import { NotificationChannelOption } from 'app/types'; import { useFormContext, FieldError, DeepMap } from 'react-hook-form'; import { SubformField } from './SubformField'; @@ -13,11 +14,22 @@ interface Props { option: NotificationChannelOption; invalid?: boolean; pathPrefix: string; + pathSuffix?: string; error?: FieldError | DeepMap; readOnly?: boolean; } -export const OptionField: FC = ({ option, invalid, pathPrefix, error, defaultValue, readOnly = false }) => { +export const OptionField: FC = ({ + option, + invalid, + pathPrefix, + pathSuffix = '', + error, + defaultValue, + readOnly = false, +}) => { + const optionPath = `${pathPrefix}${pathSuffix}`; + if (option.element === 'subform') { return ( = ({ option, invalid, pathPrefix, error, def defaultValue={defaultValue} option={option} errors={error as DeepMap | undefined} - pathPrefix={pathPrefix} + pathPrefix={optionPath} /> ); } @@ -35,7 +47,7 @@ export const OptionField: FC = ({ option, invalid, pathPrefix, error, def readOnly={readOnly} defaultValues={defaultValue} option={option} - pathPrefix={pathPrefix} + pathPrefix={optionPath} errors={error as Array> | undefined} /> ); @@ -48,18 +60,26 @@ export const OptionField: FC = ({ option, invalid, pathPrefix, error, def error={error?.message} > ); }; -const OptionInput: FC = ({ option, invalid, id, pathPrefix = '', readOnly = false }) => { +const OptionInput: FC = ({ + option, + invalid, + id, + pathPrefix = '', + pathIndex = '', + readOnly = false, +}) => { const { control, register, unregister, getValues } = useFormContext(); const name = `${pathPrefix}${option.propertyName}`; @@ -87,11 +107,11 @@ const OptionInput: FC = ({ option, invalid, id, pathPref return ( (option.validationRule !== '' ? validateOption(v, option.validationRule) : true), })} placeholder={option.placeholder} @@ -165,19 +185,26 @@ const validateOption = (value: string, validationRule: string) => { return RegExp(validationRule).test(value) ? true : 'Invalid format'; }; -const determineRequired = (option: NotificationChannelOption, getValues: any) => { +const determineRequired = (option: NotificationChannelOption, getValues: any, pathIndex: string) => { if (!option.dependsOn) { return option.required ? 'Required' : false; } - - const dependentOn = getValues(`items[0].${option.dependsOn}`); - return !dependentOn && option.required ? 'Required' : false; + if (isEmpty(getValues(`${pathIndex}secureFields`))) { + const dependentOn = getValues(`${pathIndex}secureSettings.${option.dependsOn}`); + return !Boolean(dependentOn) && option.required ? 'Required' : false; + } else { + const dependentOn: boolean = getValues(`${pathIndex}secureFields.${option.dependsOn}`); + return !dependentOn && option.required ? 'Required' : false; + } }; -const determineReadOnly = (option: NotificationChannelOption, getValues: any) => { +const determineReadOnly = (option: NotificationChannelOption, getValues: any, pathIndex: string) => { if (!option.dependsOn) { return false; } - - return getValues(`items[0].${option.dependsOn}`); + if (isEmpty(getValues(`${pathIndex}secureFields`))) { + return getValues(`${pathIndex}secureSettings.${option.dependsOn}`); + } else { + return getValues(`${pathIndex}secureFields.${option.dependsOn}`); + } }; From 1588cd393aa3633a92919572cb5629c68b597bad Mon Sep 17 00:00:00 2001 From: Ieva Date: Wed, 20 Apr 2022 08:43:42 +0100 Subject: [PATCH 015/120] check that the user has RBAC permissions to save dashboard annotation (#47882) --- pkg/api/annotations.go | 88 ++++++++++++++----------------------- pkg/api/annotations_test.go | 12 +++++ 2 files changed, 46 insertions(+), 54 deletions(-) diff --git a/pkg/api/annotations.go b/pkg/api/annotations.go index 195c931fe76..7ddb11df2dd 100644 --- a/pkg/api/annotations.go +++ b/pkg/api/annotations.go @@ -64,22 +64,7 @@ func (hs *HTTPServer) PostAnnotation(c *models.ReqContext) response.Response { return response.Error(http.StatusBadRequest, "bad request data", err) } - var canSave bool - var err error - if cmd.DashboardId != 0 { - canSave, err = canSaveDashboardAnnotation(c, cmd.DashboardId) - } else { // organization annotations - if !hs.Features.IsEnabled(featuremgmt.FlagAccesscontrol) { - canSave = canSaveOrganizationAnnotation(c) - } else { - // This is an additional validation needed only for FGAC Organization Annotations. - // It is not possible to do it in the middleware because we need to look - // into the request to determine if this is a Organization annotation or not - canSave, err = hs.canCreateOrganizationAnnotation(c) - } - } - - if err != nil || !canSave { + if canSave, err := hs.canCreateAnnotation(c, cmd.DashboardId); err != nil || !canSave { return dashboardGuardianResponse(err) } @@ -198,16 +183,7 @@ func (hs *HTTPServer) UpdateAnnotation(c *models.ReqContext) response.Response { return resp } - canSave := true - if annotation.GetType() == annotations.Dashboard { - canSave, err = canSaveDashboardAnnotation(c, annotation.DashboardId) - } else { - if !hs.Features.IsEnabled(featuremgmt.FlagAccesscontrol) { - canSave = canSaveOrganizationAnnotation(c) - } - } - - if err != nil || !canSave { + if canSave, err := hs.canSaveAnnotation(c, annotation); err != nil || !canSave { return dashboardGuardianResponse(err) } @@ -245,15 +221,7 @@ func (hs *HTTPServer) PatchAnnotation(c *models.ReqContext) response.Response { return resp } - canSave := true - if annotation.GetType() == annotations.Dashboard { - canSave, err = canSaveDashboardAnnotation(c, annotation.DashboardId) - } else { - if !hs.Features.IsEnabled(featuremgmt.FlagAccesscontrol) { - canSave = canSaveOrganizationAnnotation(c) - } - } - if err != nil || !canSave { + if canSave, err := hs.canSaveAnnotation(c, annotation); err != nil || !canSave { return dashboardGuardianResponse(err) } @@ -364,16 +332,7 @@ func (hs *HTTPServer) DeleteAnnotationByID(c *models.ReqContext) response.Respon return resp } - canSave := true - if annotation.GetType() == annotations.Dashboard { - canSave, err = canSaveDashboardAnnotation(c, annotation.DashboardId) - } else { - if !hs.Features.IsEnabled(featuremgmt.FlagAccesscontrol) { - canSave = canSaveOrganizationAnnotation(c) - } - } - - if err != nil || !canSave { + if canSave, err := hs.canSaveAnnotation(c, annotation); err != nil || !canSave { return dashboardGuardianResponse(err) } @@ -388,7 +347,18 @@ func (hs *HTTPServer) DeleteAnnotationByID(c *models.ReqContext) response.Respon return response.Success("Annotation deleted") } -func canSaveDashboardAnnotation(c *models.ReqContext, dashboardID int64) (bool, error) { +func (hs *HTTPServer) canSaveAnnotation(c *models.ReqContext, annotation *annotations.ItemDTO) (bool, error) { + if annotation.GetType() == annotations.Dashboard { + return canEditDashboard(c, annotation.DashboardId) + } else { + if !hs.Features.IsEnabled(featuremgmt.FlagAccesscontrol) { + return c.SignedInUser.HasRole(models.ROLE_EDITOR), nil + } + return true, nil + } +} + +func canEditDashboard(c *models.ReqContext, dashboardID int64) (bool, error) { guard := guardian.New(c.Req.Context(), dashboardID, c.OrgId, c.SignedInUser) if canEdit, err := guard.CanEdit(); err != nil || !canEdit { return false, err @@ -397,10 +367,6 @@ func canSaveDashboardAnnotation(c *models.ReqContext, dashboardID int64) (bool, return true, nil } -func canSaveOrganizationAnnotation(c *models.ReqContext) bool { - return c.SignedInUser.HasRole(models.ROLE_EDITOR) -} - func findAnnotationByID(ctx context.Context, repo annotations.Repository, annotationID int64, user *models.SignedInUser) (*annotations.ItemDTO, response.Response) { query := &annotations.ItemQuery{ AnnotationId: annotationID, @@ -478,9 +444,23 @@ func AnnotationTypeScopeResolver() (string, accesscontrol.AttributeScopeResolveF return accesscontrol.ScopeAnnotationsProvider.GetResourceScope(""), annotationTypeResolver } -func (hs *HTTPServer) canCreateOrganizationAnnotation(c *models.ReqContext) (bool, error) { - evaluator := accesscontrol.EvalPermission(accesscontrol.ActionAnnotationsCreate, accesscontrol.ScopeAnnotationsTypeOrganization) - return hs.AccessControl.Evaluate(c.Req.Context(), c.SignedInUser, evaluator) +func (hs *HTTPServer) canCreateAnnotation(c *models.ReqContext, dashboardId int64) (bool, error) { + if dashboardId != 0 { + if hs.Features.IsEnabled(featuremgmt.FlagAccesscontrol) { + evaluator := accesscontrol.EvalPermission(accesscontrol.ActionAnnotationsCreate, accesscontrol.ScopeAnnotationsTypeDashboard) + if canSave, err := hs.AccessControl.Evaluate(c.Req.Context(), c.SignedInUser, evaluator); err != nil || !canSave { + return canSave, err + } + } + return canEditDashboard(c, dashboardId) + } else { // organization annotations + if hs.Features.IsEnabled(featuremgmt.FlagAccesscontrol) { + evaluator := accesscontrol.EvalPermission(accesscontrol.ActionAnnotationsCreate, accesscontrol.ScopeAnnotationsTypeOrganization) + return hs.AccessControl.Evaluate(c.Req.Context(), c.SignedInUser, evaluator) + } else { + return c.SignedInUser.HasRole(models.ROLE_EDITOR), nil + } + } } func (hs *HTTPServer) canMassDeleteAnnotations(c *models.ReqContext, dashboardID int64) (bool, error) { @@ -494,7 +474,7 @@ func (hs *HTTPServer) canMassDeleteAnnotations(c *models.ReqContext, dashboardID return false, err } - canSave, err = canSaveDashboardAnnotation(c, dashboardID) + canSave, err = canEditDashboard(c, dashboardID) if err != nil || !canSave { return false, err } diff --git a/pkg/api/annotations_test.go b/pkg/api/annotations_test.go index 300a751454a..a67272b11ed 100644 --- a/pkg/api/annotations_test.go +++ b/pkg/api/annotations_test.go @@ -615,6 +615,18 @@ func TestAPI_Annotations_AccessControl(t *testing.T) { }, want: http.StatusForbidden, }, + { + name: "AccessControl create dashboard annotation with incorrect permissions is forbidden", + args: args{ + permissions: []*accesscontrol.Permission{{ + Action: accesscontrol.ActionAnnotationsCreate, Scope: accesscontrol.ScopeAnnotationsTypeOrganization, + }}, + url: "/api/annotations", + method: http.MethodPost, + body: mockRequestBody(postDashboardCmd), + }, + want: http.StatusForbidden, + }, { name: "AccessControl create organization annotation with permissions is allowed", args: args{ From cbd2d09d70b1e164f59e2f8f14094acb9a6bf757 Mon Sep 17 00:00:00 2001 From: Vardan Torosyan Date: Wed, 20 Apr 2022 09:45:45 +0200 Subject: [PATCH 016/120] Update API Keys UI to adjust based on users permissions (#47802) * Update API Keys UI to adjust based on users permissions Since API Keys support now RBAC we need to ensure that UI is adjusted based on the user permissions. * Applying PR suggestions --- pkg/api/accesscontrol.go | 8 ++--- pkg/services/serviceaccounts/manager/roles.go | 8 ++--- public/app/features/api-keys/ApiKeysForm.tsx | 5 +-- .../features/api-keys/ApiKeysPage.test.tsx | 3 ++ public/app/features/api-keys/ApiKeysPage.tsx | 31 ++++++++++++++++--- public/app/features/api-keys/ApiKeysTable.tsx | 13 ++++++-- public/app/types/accessControl.ts | 2 ++ 7 files changed, 49 insertions(+), 21 deletions(-) diff --git a/pkg/api/accesscontrol.go b/pkg/api/accesscontrol.go index e1c3eed6acd..9f948866810 100644 --- a/pkg/api/accesscontrol.go +++ b/pkg/api/accesscontrol.go @@ -174,19 +174,15 @@ func (hs *HTTPServer) declareFixedRoles() error { DisplayName: "APIKeys writer", Description: "Gives access to add and delete api keys.", Group: "API Keys", - Permissions: []ac.Permission{ + Permissions: ac.ConcatPermissions(apikeyReaderRole.Role.Permissions, []ac.Permission{ { Action: ac.ActionAPIKeyCreate, }, - { - Action: ac.ActionAPIKeyRead, - Scope: ac.ScopeAPIKeysAll, - }, { Action: ac.ActionAPIKeyDelete, Scope: ac.ScopeAPIKeysAll, }, - }, + }), }, Grants: []string{string(models.ROLE_ADMIN)}, } diff --git a/pkg/services/serviceaccounts/manager/roles.go b/pkg/services/serviceaccounts/manager/roles.go index 7c323043a95..b0164c2319a 100644 --- a/pkg/services/serviceaccounts/manager/roles.go +++ b/pkg/services/serviceaccounts/manager/roles.go @@ -31,11 +31,7 @@ func RegisterRoles(ac accesscontrol.AccessControl) error { DisplayName: "Service accounts writer", Description: "Create, delete, read, or query service accounts.", Group: "Service accounts", - Permissions: []accesscontrol.Permission{ - { - Action: serviceaccounts.ActionRead, - Scope: serviceaccounts.ScopeAll, - }, + Permissions: accesscontrol.ConcatPermissions(saReader.Role.Permissions, []accesscontrol.Permission{ { Action: serviceaccounts.ActionWrite, Scope: serviceaccounts.ScopeAll, @@ -47,7 +43,7 @@ func RegisterRoles(ac accesscontrol.AccessControl) error { Action: serviceaccounts.ActionDelete, Scope: serviceaccounts.ScopeAll, }, - }, + }), }, Grants: []string{string(models.ROLE_ADMIN)}, } diff --git a/public/app/features/api-keys/ApiKeysForm.tsx b/public/app/features/api-keys/ApiKeysForm.tsx index 9ad93b70f2a..1bf8c97c4e2 100644 --- a/public/app/features/api-keys/ApiKeysForm.tsx +++ b/public/app/features/api-keys/ApiKeysForm.tsx @@ -15,6 +15,7 @@ interface Props { show: boolean; onClose: () => void; onKeyAdded: (apiKey: NewApiKey) => void; + disabled: boolean; } function isValidInterval(value: string): boolean { @@ -40,7 +41,7 @@ const timeRangeValidationEvents: ValidationEvents = { const tooltipText = 'The API key life duration. For example, 1d if your key is going to last for one day. Supported units are: s,m,h,d,w,M,y'; -export const ApiKeysForm: FC = ({ show, onClose, onKeyAdded }) => { +export const ApiKeysForm: FC = ({ show, onClose, onKeyAdded, disabled }) => { const [name, setName] = useState(''); const [role, setRole] = useState(OrgRole.Viewer); const [secondsToLive, setSecondsToLive] = useState(''); @@ -102,7 +103,7 @@ export const ApiKeysForm: FC = ({ show, onClose, onKeyAdded }) => {
- +
diff --git a/public/app/features/api-keys/ApiKeysPage.test.tsx b/public/app/features/api-keys/ApiKeysPage.test.tsx index e7adf743e62..4b33ab79096 100644 --- a/public/app/features/api-keys/ApiKeysPage.test.tsx +++ b/public/app/features/api-keys/ApiKeysPage.test.tsx @@ -37,6 +37,9 @@ const setup = (propOverrides: Partial) => { includeExpired: false, includeExpiredDisabled: false, toggleIncludeExpired: toggleIncludeExpiredMock, + canRead: true, + canCreate: true, + canDelete: true, }; Object.assign(props, propOverrides); diff --git a/public/app/features/api-keys/ApiKeysPage.tsx b/public/app/features/api-keys/ApiKeysPage.tsx index 6e3d8273275..4d78f5add1f 100644 --- a/public/app/features/api-keys/ApiKeysPage.tsx +++ b/public/app/features/api-keys/ApiKeysPage.tsx @@ -1,7 +1,7 @@ import React, { PureComponent } from 'react'; import { connect, ConnectedProps } from 'react-redux'; // Utils -import { ApiKey, NewApiKey, StoreState } from 'app/types'; +import { AccessControlAction, ApiKey, NewApiKey, StoreState } from 'app/types'; import { getNavModel } from 'app/core/selectors/navModel'; import { getApiKeys, getApiKeysCount, getIncludeExpired, getIncludeExpiredDisabled } from './state/selectors'; import { addApiKey, deleteApiKey, loadApiKeys, toggleIncludeExpired } from './state/actions'; @@ -19,8 +19,13 @@ import { ApiKeysActionBar } from './ApiKeysActionBar'; import { ApiKeysTable } from './ApiKeysTable'; import { ApiKeysController } from './ApiKeysController'; import { ShowModalReactEvent } from 'app/types/events'; +import { contextSrv } from 'app/core/core'; function mapStateToProps(state: StoreState) { + const canRead = contextSrv.hasAccess(AccessControlAction.ActionAPIKeysRead, true); + const canCreate = contextSrv.hasAccess(AccessControlAction.ActionAPIKeysCreate, true); + const canDelete = contextSrv.hasAccess(AccessControlAction.ActionAPIKeysDelete, true); + return { navModel: getNavModel(state.navIndex, 'apikeys'), apiKeys: getApiKeys(state.apiKeys), @@ -30,6 +35,9 @@ function mapStateToProps(state: StoreState) { timeZone: getTimeZone(state.user), includeExpired: getIncludeExpired(state.apiKeys), includeExpiredDisabled: getIncludeExpiredDisabled(state.apiKeys), + canRead: canRead, + canCreate: canCreate, + canDelete: canDelete, }; } @@ -120,6 +128,9 @@ export class ApiKeysPageUnconnected extends PureComponent { timeZone, includeExpired, includeExpiredDisabled, + canRead, + canCreate, + canDelete, } = this.props; if (!hasFetched) { @@ -146,23 +157,35 @@ export class ApiKeysPageUnconnected extends PureComponent { onClick={toggleIsAdding} buttonTitle="New API key" proTip="Remember, you can provide view-only API access to other applications." + buttonDisabled={!canCreate} /> ) : null} {showTable ? ( ) : null} - + {showTable ? ( - + ) : null} diff --git a/public/app/features/api-keys/ApiKeysTable.tsx b/public/app/features/api-keys/ApiKeysTable.tsx index 06445bf09e1..ed063b1392e 100644 --- a/public/app/features/api-keys/ApiKeysTable.tsx +++ b/public/app/features/api-keys/ApiKeysTable.tsx @@ -9,9 +9,11 @@ interface Props { apiKeys: ApiKey[]; timeZone: TimeZone; onDelete: (apiKey: ApiKey) => void; + canRead: boolean; + canDelete: boolean; } -export const ApiKeysTable: FC = ({ apiKeys, timeZone, onDelete }) => { +export const ApiKeysTable: FC = ({ apiKeys, timeZone, onDelete, canRead, canDelete }) => { const theme = useTheme2(); const styles = getStyles(theme); @@ -25,7 +27,7 @@ export const ApiKeysTable: FC = ({ apiKeys, timeZone, onDelete }) => { - {apiKeys.length > 0 ? ( + {canRead && apiKeys.length > 0 ? ( {apiKeys.map((key) => { const isExpired = Boolean(key.expiration && Date.now() > new Date(key.expiration).getTime()); @@ -44,7 +46,12 @@ export const ApiKeysTable: FC = ({ apiKeys, timeZone, onDelete }) => { )} - onDelete(key)} /> + onDelete(key)} + disabled={!canDelete} + /> ); diff --git a/public/app/types/accessControl.ts b/public/app/types/accessControl.ts index 969985ba21a..12d2341559f 100644 --- a/public/app/types/accessControl.ts +++ b/public/app/types/accessControl.ts @@ -110,6 +110,8 @@ export enum AccessControlAction { AlertingNotificationsExternalRead = 'alert.notifications.external:read', ActionAPIKeysRead = 'apikeys:read', + ActionAPIKeysCreate = 'apikeys:create', + ActionAPIKeysDelete = 'apikeys:delete', } export interface Role { From f9f4a4cbf6155103fb0fdae00bf62a85a6bc0f28 Mon Sep 17 00:00:00 2001 From: kay delaney <45561153+kaydelaney@users.noreply.github.com> Date: Wed, 20 Apr 2022 10:02:26 +0100 Subject: [PATCH 017/120] Export: Explicitly include default datasources in exported dashboard json (#47244) * Export: Explicitly include default datasources in exported dashboard json --- .../DashExportModal/DashboardExporter.test.ts | 25 +++++++++++++++++-- .../DashExportModal/DashboardExporter.ts | 11 +++++--- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/public/app/features/dashboard/components/DashExportModal/DashboardExporter.test.ts b/public/app/features/dashboard/components/DashExportModal/DashboardExporter.test.ts index 83482884b08..1b8d2eda579 100644 --- a/public/app/features/dashboard/components/DashExportModal/DashboardExporter.test.ts +++ b/public/app/features/dashboard/components/DashExportModal/DashboardExporter.test.ts @@ -276,6 +276,10 @@ describe('given dashboard with repeated panels', () => { }, ], }, + { + id: 5, + targets: [{ scenarioId: 'random_walk', refId: 'A' }], + }, ], }; @@ -312,6 +316,23 @@ describe('given dashboard with repeated panels', () => { expect(panel.datasource.uid).toBe('${DS_GFDB}'); }); + it('should explicitly specify default datasources', () => { + const panel = exported.panels[7]; + expect(exported.__inputs.some((ds: Record) => ds.name === 'DS_GFDB')).toBeTruthy(); + expect(panel.datasource.uid).toBe('${DS_GFDB}'); + expect(panel.targets[0].datasource).toBe('${DS_GFDB}'); + }); + + it('should not include default datasource in __inputs unnecessarily', async () => { + const testJson: any = { + panels: [{ id: 1, datasource: { uid: 'other', type: 'other' }, type: 'graph' }], + }; + const testDash = new DashboardModel(testJson); + const exporter = new DashboardExporter(); + const exportedJson: any = await exporter.makeExportable(testDash); + expect(exportedJson.__inputs.some((ds: Record) => ds.name === 'DS_GFDB')).toBeFalsy(); + }); + it('should replace datasource refs in collapsed row', () => { const panel = exported.panels[6].panels[0]; expect(panel.datasource.uid).toBe('${DS_GFDB}'); @@ -453,7 +474,7 @@ stubs['other2'] = { meta: { id: 'other2', info: { version: '1.2.1' }, name: 'OtherDB_2' }, }; -stubs['-- Mixed --'] = { +stubs['mixed'] = { name: 'mixed', meta: { id: 'mixed', @@ -463,7 +484,7 @@ stubs['-- Mixed --'] = { }, }; -stubs['-- Grafana --'] = { +stubs['grafana'] = { name: '-- Grafana --', meta: { id: 'grafana', diff --git a/public/app/features/dashboard/components/DashExportModal/DashboardExporter.ts b/public/app/features/dashboard/components/DashExportModal/DashboardExporter.ts index 3e7886e4c1c..6cc3219be7b 100644 --- a/public/app/features/dashboard/components/DashExportModal/DashboardExporter.ts +++ b/public/app/features/dashboard/components/DashExportModal/DashboardExporter.ts @@ -126,15 +126,18 @@ export class DashboardExporter { }; const processPanel = (panel: PanelModel) => { - if (panel.datasource !== undefined && panel.datasource !== null) { + const isRegularPanel = + (panel.repeatPanelId === undefined || panel.repeatPanelId === null) && + !('collapsed' in panel) && + !('panels' in panel); + + if (isRegularPanel) { templateizeDatasourceUsage(panel); } if (panel.targets) { for (const target of panel.targets) { - if (target.datasource !== undefined) { - templateizeDatasourceUsage(target); - } + templateizeDatasourceUsage(target); } } From 1696a9abee106e4b89fa8d49810a0d9902858427 Mon Sep 17 00:00:00 2001 From: JM Date: Wed, 20 Apr 2022 02:05:59 -0700 Subject: [PATCH 018/120] Dashboard: remove name requirement from CleanLibraryPanelsForDashboard (#44692) Co-authored-by: kay delaney --- pkg/services/librarypanels/librarypanels.go | 13 +-- .../librarypanels/librarypanels_test.go | 87 ++++--------------- 2 files changed, 19 insertions(+), 81 deletions(-) diff --git a/pkg/services/librarypanels/librarypanels.go b/pkg/services/librarypanels/librarypanels.go index c23268a03a8..95ec44e4b1d 100644 --- a/pkg/services/librarypanels/librarypanels.go +++ b/pkg/services/librarypanels/librarypanels.go @@ -81,14 +81,12 @@ func loadLibraryPanelsRecursively(elements map[string]libraryelements.LibraryEle elementInDB, ok := elements[UID] if !ok { - name := libraryPanel.Get("name").MustString() elem := parent.Get("panels").GetIndex(i) elem.Set("gridPos", panelAsJSON.Get("gridPos").MustMap()) elem.Set("id", panelAsJSON.Get("id").MustInt64()) - elem.Set("type", fmt.Sprintf("Name: \"%s\", UID: \"%s\"", name, UID)) + elem.Set("type", fmt.Sprintf("Library panel with UID: \"%s\"", UID)) elem.Set("libraryPanel", map[string]interface{}{ - "uid": UID, - "name": name, + "uid": UID, }) continue } @@ -174,10 +172,6 @@ func cleanLibraryPanelsRecursively(parent *simplejson.Json) error { if len(UID) == 0 { return errLibraryPanelHeaderUIDMissing } - name := libraryPanel.Get("name").MustString() - if len(name) == 0 { - return errLibraryPanelHeaderNameMissing - } // keep only the necessary JSON properties, the rest of the properties should be safely stored in library_panels table gridPos := panelAsJSON.Get("gridPos").MustMap() @@ -186,8 +180,7 @@ func cleanLibraryPanelsRecursively(parent *simplejson.Json) error { "id": ID, "gridPos": gridPos, "libraryPanel": map[string]interface{}{ - "uid": UID, - "name": name, + "uid": UID, }, }) } diff --git a/pkg/services/librarypanels/librarypanels_test.go b/pkg/services/librarypanels/librarypanels_test.go index 26f28a798c2..cfd3a9896e9 100644 --- a/pkg/services/librarypanels/librarypanels_test.go +++ b/pkg/services/librarypanels/librarypanels_test.go @@ -186,8 +186,7 @@ func TestLoadLibraryPanelsForDashboard(t *testing.T) { }, "datasource": "${DS_GDEV-TESTDATA}", "libraryPanel": map[string]interface{}{ - "uid": sc.initialResult.Result.UID, - "name": sc.initialResult.Result.Name, + "uid": sc.initialResult.Result.UID, }, "title": "Inside row", "type": "text", @@ -204,8 +203,7 @@ func TestLoadLibraryPanelsForDashboard(t *testing.T) { }, "datasource": "${DS_GDEV-TESTDATA}", "libraryPanel": map[string]interface{}{ - "uid": outsidePanel.UID, - "name": outsidePanel.Name, + "uid": outsidePanel.UID, }, "title": "Outside row", "type": "text", @@ -401,8 +399,7 @@ func TestLoadLibraryPanelsForDashboard(t *testing.T) { "y": 0, }, "libraryPanel": map[string]interface{}{ - "uid": sc.initialResult.Result.UID, - "name": sc.initialResult.Result.Name, + "uid": sc.initialResult.Result.UID, }, }, }, @@ -438,10 +435,9 @@ func TestLoadLibraryPanelsForDashboard(t *testing.T) { "y": 0, }, "libraryPanel": map[string]interface{}{ - "uid": sc.initialResult.Result.UID, - "name": sc.initialResult.Result.Name, + "uid": sc.initialResult.Result.UID, }, - "type": fmt.Sprintf("Name: \"%s\", UID: \"%s\"", sc.initialResult.Result.Name, sc.initialResult.Result.UID), + "type": fmt.Sprintf("Library panel with UID: \"%s\"", sc.initialResult.Result.UID), }, }, } @@ -476,8 +472,7 @@ func TestCleanLibraryPanelsForDashboard(t *testing.T) { }, "datasource": "${DS_GDEV-TESTDATA}", "libraryPanel": map[string]interface{}{ - "uid": sc.initialResult.Result.UID, - "name": sc.initialResult.Result.Name, + "uid": sc.initialResult.Result.UID, }, "title": "Text - Library Panel", "type": "text", @@ -515,8 +510,7 @@ func TestCleanLibraryPanelsForDashboard(t *testing.T) { "y": 0, }, "libraryPanel": map[string]interface{}{ - "uid": sc.initialResult.Result.UID, - "name": sc.initialResult.Result.Name, + "uid": sc.initialResult.Result.UID, }, }, }, @@ -586,8 +580,7 @@ func TestCleanLibraryPanelsForDashboard(t *testing.T) { }, "datasource": "${DS_GDEV-TESTDATA}", "libraryPanel": map[string]interface{}{ - "uid": sc.initialResult.Result.UID, - "name": sc.initialResult.Result.Name, + "uid": sc.initialResult.Result.UID, }, "title": "Inside row", "type": "text", @@ -604,8 +597,7 @@ func TestCleanLibraryPanelsForDashboard(t *testing.T) { }, "datasource": "${DS_GDEV-TESTDATA}", "libraryPanel": map[string]interface{}{ - "uid": outsidePanel.UID, - "name": outsidePanel.Name, + "uid": outsidePanel.UID, }, "title": "Outside row", "type": "text", @@ -663,8 +655,7 @@ func TestCleanLibraryPanelsForDashboard(t *testing.T) { "y": 13, }, "libraryPanel": map[string]interface{}{ - "uid": sc.initialResult.Result.UID, - "name": sc.initialResult.Result.Name, + "uid": sc.initialResult.Result.UID, }, }, }, @@ -678,8 +669,7 @@ func TestCleanLibraryPanelsForDashboard(t *testing.T) { "y": 19, }, "libraryPanel": map[string]interface{}{ - "uid": outsidePanel.UID, - "name": outsidePanel.Name, + "uid": outsidePanel.UID, }, }, }, @@ -729,46 +719,6 @@ func TestCleanLibraryPanelsForDashboard(t *testing.T) { err := sc.service.CleanLibraryPanelsForDashboard(dashInDB) require.EqualError(t, err, errLibraryPanelHeaderUIDMissing.Error()) }) - - scenarioWithLibraryPanel(t, "When an admin tries to store a dashboard with a library panel without name, it should fail", - func(t *testing.T, sc scenarioContext) { - dashJSON := map[string]interface{}{ - "panels": []interface{}{ - map[string]interface{}{ - "id": int64(1), - "gridPos": map[string]interface{}{ - "h": 6, - "w": 6, - "x": 0, - "y": 0, - }, - }, - map[string]interface{}{ - "id": int64(2), - "gridPos": map[string]interface{}{ - "h": 6, - "w": 6, - "x": 6, - "y": 0, - }, - "datasource": "${DS_GDEV-TESTDATA}", - "libraryPanel": map[string]interface{}{ - "uid": sc.initialResult.Result.UID, - }, - "title": "Text - Library Panel", - "type": "text", - }, - }, - } - dash := models.Dashboard{ - Title: "Testing CleanLibraryPanelsForDashboard", - Data: simplejson.NewFromAny(dashJSON), - } - dashInDB := createDashboard(t, sc.sqlStore, sc.user, &dash, sc.folder.Id) - - err := sc.service.CleanLibraryPanelsForDashboard(dashInDB) - require.EqualError(t, err, errLibraryPanelHeaderNameMissing.Error()) - }) } func TestConnectLibraryPanelsForDashboard(t *testing.T) { @@ -795,8 +745,7 @@ func TestConnectLibraryPanelsForDashboard(t *testing.T) { }, "datasource": "${DS_GDEV-TESTDATA}", "libraryPanel": map[string]interface{}{ - "uid": sc.initialResult.Result.UID, - "name": sc.initialResult.Result.Name, + "uid": sc.initialResult.Result.UID, }, "title": "Text - Library Panel", "type": "text", @@ -877,8 +826,7 @@ func TestConnectLibraryPanelsForDashboard(t *testing.T) { }, "datasource": "${DS_GDEV-TESTDATA}", "libraryPanel": map[string]interface{}{ - "uid": sc.initialResult.Result.UID, - "name": sc.initialResult.Result.Name, + "uid": sc.initialResult.Result.UID, }, "title": "Inside row", "type": "text", @@ -895,8 +843,7 @@ func TestConnectLibraryPanelsForDashboard(t *testing.T) { }, "datasource": "${DS_GDEV-TESTDATA}", "libraryPanel": map[string]interface{}{ - "uid": outsidePanel.UID, - "name": outsidePanel.Name, + "uid": outsidePanel.UID, }, "title": "Outside row", "type": "text", @@ -997,8 +944,7 @@ func TestConnectLibraryPanelsForDashboard(t *testing.T) { }, "datasource": "${DS_GDEV-TESTDATA}", "libraryPanel": map[string]interface{}{ - "uid": unused.UID, - "name": unused.Name, + "uid": unused.UID, }, "title": "Unused Libray Panel", "description": "Unused description", @@ -1034,8 +980,7 @@ func TestConnectLibraryPanelsForDashboard(t *testing.T) { }, "datasource": "${DS_GDEV-TESTDATA}", "libraryPanel": map[string]interface{}{ - "uid": sc.initialResult.Result.UID, - "name": sc.initialResult.Result.Name, + "uid": sc.initialResult.Result.UID, }, "title": "Text - Library Panel", "type": "text", From ff60f39e969c4c5fe98174daf82d47cdcf3487f1 Mon Sep 17 00:00:00 2001 From: kay delaney <45561153+kaydelaney@users.noreply.github.com> Date: Wed, 20 Apr 2022 10:15:36 +0100 Subject: [PATCH 019/120] Revert "DataLinks: Encode variable params for data link URLs (#46100)" (#47763) This reverts commit b47f5433d7534ab8623d69a3fd08ea1bd09297ae. --- ...plating-dashboard-links-and-variables.json | 62 +------------------ ...ting-dashboard-links-and-variables.spec.ts | 10 +-- .../grafana-data/src/field/fieldOverrides.ts | 5 +- 3 files changed, 5 insertions(+), 72 deletions(-) diff --git a/devenv/dev-dashboards/feature-templating/templating-dashboard-links-and-variables.json b/devenv/dev-dashboards/feature-templating/templating-dashboard-links-and-variables.json index ab94db3f055..f5751ec42f5 100644 --- a/devenv/dev-dashboards/feature-templating/templating-dashboard-links-and-variables.json +++ b/devenv/dev-dashboards/feature-templating/templating-dashboard-links-and-variables.json @@ -16,7 +16,7 @@ "gnetId": null, "graphTooltip": 0, "id": null, - "iteration": 1646409057541, + "iteration": 1601526910610, "links": [ { "icon": "external link", @@ -73,61 +73,6 @@ "timeShift": null, "title": "${custom.text}", "type": "text" - }, - { - "id": 4, - "gridPos": { - "h": 9, - "w": 9, - "x": 12, - "y": 0 - }, - "type": "stat", - "title": "Panel Title", - "fieldConfig": { - "defaults": { - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "color": { - "mode": "thresholds" - }, - "links": [ - { - "title": "Var Link", - "url": "/d/vmie2cmWz/bar-gauge-demo?var-custom=$custom" - } - ] - }, - "overrides": [] - }, - "options": { - "reduceOptions": { - "values": false, - "calcs": [ - "lastNotNull" - ], - "fields": "" - }, - "orientation": "auto", - "textMode": "auto", - "colorMode": "value", - "graphMode": "area", - "justifyMode": "auto" - }, - "pluginVersion": "8.5.0-pre", - "datasource": null } ], "schemaVersion": 26, @@ -167,11 +112,6 @@ "selected": false, "text": "p3", "value": "p3" - }, - { - "selected": false, - "text": "p4", - "value": "test%25value" } ], "query": "p1,p2,p3", diff --git a/e2e/dashboards-suite/templating-dashboard-links-and-variables.spec.ts b/e2e/dashboards-suite/templating-dashboard-links-and-variables.spec.ts index 2c4fe236baf..c2eb79f780c 100644 --- a/e2e/dashboards-suite/templating-dashboard-links-and-variables.spec.ts +++ b/e2e/dashboards-suite/templating-dashboard-links-and-variables.spec.ts @@ -34,7 +34,7 @@ e2e.scenario({ expect(links).to.have.length.greaterThan(13); for (let index = 0; index < links.length; index++) { - expect(Cypress.$(links[index]).attr('href')).contains(`var-custom=${encodeURI(variableValue)}`); + expect(Cypress.$(links[index]).attr('href')).contains(`var-custom=${variableValue}`); } }); }; @@ -44,14 +44,6 @@ e2e.scenario({ // verify all links, should have All value verifyLinks('All'); - // Data links should percent encode var values - e2e() - .get('[aria-label="Data link"]') - .should('exist') - .and((link) => { - expect(link.attr('href')).contains(encodeURI('test%25value')); - }); - e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownValueLinkTexts('All').should('be.visible').click(); e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('p2').should('be.visible').click(); diff --git a/packages/grafana-data/src/field/fieldOverrides.ts b/packages/grafana-data/src/field/fieldOverrides.ts index d6358395d80..a2292847c2f 100644 --- a/packages/grafana-data/src/field/fieldOverrides.ts +++ b/packages/grafana-data/src/field/fieldOverrides.ts @@ -1,6 +1,7 @@ import { ApplyFieldOverrideOptions, DataFrame, + DataLink, DisplayProcessor, DisplayValue, DynamicConfigValue, @@ -352,7 +353,7 @@ export const getLinksSupplier = const timeRangeUrl = locationUtil.getTimeRangeUrlParams(); const { timeField } = getTimeField(frame); - return field.config.links.map((link) => { + return field.config.links.map((link: DataLink) => { const variablesQuery = locationUtil.getVariablesUrlParams(); let dataFrameVars = {}; let valueVars = {}; @@ -438,7 +439,7 @@ export const getLinksSupplier = } let href = locationUtil.assureBaseUrl(link.url.replace(/\n/g, '')); - href = replaceVariables(href, variables, encodeURIComponent); + href = replaceVariables(href, variables); href = locationUtil.processUrl(href); const info: LinkModel = { From c1490a464a589b385b0c7a966abe5da8a1ce52b0 Mon Sep 17 00:00:00 2001 From: Giordano Ricci Date: Wed, 20 Apr 2022 10:37:26 +0100 Subject: [PATCH 020/120] Explore: minor copy changes (#47922) * Explore: minor copy changes * fix tests --- .../explore/AddToDashboard/AddToDashboardModal.tsx | 8 ++++---- public/app/features/explore/AddToDashboard/index.test.tsx | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/public/app/features/explore/AddToDashboard/AddToDashboardModal.tsx b/public/app/features/explore/AddToDashboard/AddToDashboardModal.tsx index 161f6b57443..3323ef01ff4 100644 --- a/public/app/features/explore/AddToDashboard/AddToDashboardModal.tsx +++ b/public/app/features/explore/AddToDashboard/AddToDashboardModal.tsx @@ -18,11 +18,11 @@ enum SaveTarget { const SAVE_TARGETS: Array> = [ { - label: 'New Dashboard', + label: 'New dashboard', value: SaveTarget.NewDashboard, }, { - label: 'Existing Dashboard', + label: 'Existing dashboard', value: SaveTarget.ExistingDashboard, }, ]; @@ -141,7 +141,7 @@ export const AddToDashboardModal = ({ onClose, exploreId }: Props) => { ( - + )} @@ -195,7 +195,7 @@ export const AddToDashboardModal = ({ onClose, exploreId }: Props) => { Open in new tab diff --git a/public/app/features/explore/AddToDashboard/index.test.tsx b/public/app/features/explore/AddToDashboard/index.test.tsx index 62db02ba6b4..fe265e71545 100644 --- a/public/app/features/explore/AddToDashboard/index.test.tsx +++ b/public/app/features/explore/AddToDashboard/index.test.tsx @@ -86,7 +86,7 @@ describe('AddToDashboardButton', () => { await openModal(); - userEvent.click(screen.getByRole('button', { name: /open$/i })); + userEvent.click(screen.getByRole('button', { name: /open dashboard$/i })); await waitForAddToDashboardResponse(); @@ -138,7 +138,7 @@ describe('AddToDashboardButton', () => { await openModal(); - userEvent.click(screen.getByRole('button', { name: /open$/i })); + userEvent.click(screen.getByRole('button', { name: /open dashboard$/i })); await waitForAddToDashboardResponse(); @@ -170,7 +170,7 @@ describe('AddToDashboardButton', () => { userEvent.click(screen.getByRole('radio', { name: /existing dashboard/i })); - userEvent.click(screen.getByRole('button', { name: /open$/i })); + userEvent.click(screen.getByRole('button', { name: /open dashboard$/i })); await waitForAddToDashboardResponse(); expect(locationService.push).not.toHaveBeenCalled(); @@ -255,7 +255,7 @@ describe('AddToDashboardButton', () => { }); userEvent.click(screen.getByLabelText('Select option')); - userEvent.click(screen.getByRole('button', { name: /open$/i })); + userEvent.click(screen.getByRole('button', { name: /open dashboard$/i })); await waitFor(async () => { expect(screen.queryByRole('dialog')).not.toBeInTheDocument(); From be3f52abb19b870bea44ed05c1756a8bfb08f898 Mon Sep 17 00:00:00 2001 From: Gilles De Mey Date: Wed, 20 Apr 2022 11:41:33 +0200 Subject: [PATCH 021/120] Alerting: grafana managed group names (#47785) --- .../alerting/unified/RuleEditor.test.tsx | 7 +- .../alerting/unified/RuleList.test.tsx | 8 +- .../unified/components/RuleLocation.tsx | 21 +++ .../components/rule-editor/AlertTypeStep.tsx | 78 ++++++--- .../rule-editor/GrafanaConditionsStep.tsx | 6 +- .../unified/components/rules/GrafanaRules.tsx | 11 +- .../rules/RuleListGroupView.test.tsx | 6 +- .../unified/components/rules/RulesFilter.tsx | 11 +- .../unified/components/rules/RulesGroup.tsx | 9 +- .../unified/components/rules/RulesTable.tsx | 13 +- .../hooks/useCombinedRuleNamespaces.test.ts | 57 ++++++ .../hooks/useCombinedRuleNamespaces.ts | 34 ++-- .../alerting/unified/state/actions.ts | 8 +- .../alerting/unified/types/rule-form.ts | 2 +- .../alerting/unified/utils/rule-form.ts | 3 +- .../unified/utils/rulerClient.test.ts | 31 ---- .../alerting/unified/utils/rulerClient.ts | 163 ++++++++++-------- 17 files changed, 312 insertions(+), 156 deletions(-) create mode 100644 public/app/features/alerting/unified/components/RuleLocation.tsx create mode 100644 public/app/features/alerting/unified/hooks/useCombinedRuleNamespaces.test.ts delete mode 100644 public/app/features/alerting/unified/utils/rulerClient.test.ts diff --git a/public/app/features/alerting/unified/RuleEditor.test.tsx b/public/app/features/alerting/unified/RuleEditor.test.tsx index d257846c641..fc860ea5669 100644 --- a/public/app/features/alerting/unified/RuleEditor.test.tsx +++ b/public/app/features/alerting/unified/RuleEditor.test.tsx @@ -1,4 +1,4 @@ -import { Matcher, render, waitFor } from '@testing-library/react'; +import { Matcher, render, waitFor, screen } from '@testing-library/react'; import { Provider } from 'react-redux'; import { BackendSrv, locationService, setBackendSrv, setDataSourceSrv } from '@grafana/runtime'; import { configureStore } from 'app/store/configureStore'; @@ -249,6 +249,9 @@ describe('RuleEditor', () => { const folderInput = await ui.inputs.folder.find(); await clickSelectOption(folderInput, 'Folder A'); + const groupInput = screen.getByRole('textbox', { name: /^Group/ }); + userEvent.type(groupInput, 'my group'); + userEvent.type(ui.inputs.annotationValue(0).get(), 'some summary'); userEvent.type(ui.inputs.annotationValue(1).get(), 'some description'); @@ -268,7 +271,7 @@ describe('RuleEditor', () => { 'Folder A', { interval: '1m', - name: 'my great new rule', + name: 'my group', rules: [ { annotations: { description: 'some description', summary: 'some summary' }, diff --git a/public/app/features/alerting/unified/RuleList.test.tsx b/public/app/features/alerting/unified/RuleList.test.tsx index 1e55be07468..72cdcc1a3a8 100644 --- a/public/app/features/alerting/unified/RuleList.test.tsx +++ b/public/app/features/alerting/unified/RuleList.test.tsx @@ -192,10 +192,10 @@ describe('RuleList', () => { expect(groups).toHaveLength(5); expect(groups[0]).toHaveTextContent('foofolder'); - expect(groups[1]).toHaveTextContent('default > group-1'); - expect(groups[2]).toHaveTextContent('default > group-1'); - expect(groups[3]).toHaveTextContent('default > group-2'); - expect(groups[4]).toHaveTextContent('lokins > group-1'); + expect(groups[1]).toHaveTextContent('default group-1'); + expect(groups[2]).toHaveTextContent('default group-1'); + expect(groups[3]).toHaveTextContent('default group-2'); + expect(groups[4]).toHaveTextContent('lokins group-1'); const errors = await ui.cloudRulesSourceErrors.find(); diff --git a/public/app/features/alerting/unified/components/RuleLocation.tsx b/public/app/features/alerting/unified/components/RuleLocation.tsx new file mode 100644 index 00000000000..c1b176e231b --- /dev/null +++ b/public/app/features/alerting/unified/components/RuleLocation.tsx @@ -0,0 +1,21 @@ +import { Icon } from '@grafana/ui'; +import React, { FC } from 'react'; + +interface RuleLocationProps { + namespace: string; + group?: string; +} + +const RuleLocation: FC = ({ namespace, group }) => { + if (!group) { + return <>{namespace}; + } + + return ( + <> + {namespace} {group} + + ); +}; + +export { RuleLocation }; diff --git a/public/app/features/alerting/unified/components/rule-editor/AlertTypeStep.tsx b/public/app/features/alerting/unified/components/rule-editor/AlertTypeStep.tsx index c0ebdaa73bf..5a926a0a3f0 100644 --- a/public/app/features/alerting/unified/components/rule-editor/AlertTypeStep.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/AlertTypeStep.tsx @@ -1,6 +1,6 @@ import React, { FC } from 'react'; import { DataSourceInstanceSettings, GrafanaTheme2 } from '@grafana/data'; -import { Field, Input, InputControl, useStyles2 } from '@grafana/ui'; +import { Field, Icon, Input, InputControl, Label, Tooltip, useStyles2 } from '@grafana/ui'; import { css } from '@emotion/css'; import { RuleEditorSection } from './RuleEditorSection'; import { useFormContext } from 'react-hook-form'; @@ -12,6 +12,7 @@ import { checkForPathSeparator } from './util'; import { RuleTypePicker } from './rule-types/RuleTypePicker'; import { contextSrv } from 'app/core/services/context_srv'; import { AccessControlAction } from 'app/types'; +import { Stack } from '@grafana/experimental'; interface Props { editingExistingRule: boolean; @@ -120,26 +121,60 @@ export const AlertTypeStep: FC = ({ editingExistingRule }) => { dataSourceName && } {ruleFormType === RuleFormType.grafana && ( - - ( - - )} - name="folder" - rules={{ - required: { value: true, message: 'Please select a folder' }, - validate: { - pathSeparator: (folder: Folder) => checkForPathSeparator(folder.title), - }, - }} - /> - +
+ + + Folder + + Each folder has unique folder permission. When you store multiple rules in a folder, the folder + access permissions get assigned to the rules. +
+ } + > + + + + + } + className={styles.formInput} + error={errors.folder?.message} + invalid={!!errors.folder?.message} + data-testid="folder-picker" + > + ( + + )} + name="folder" + rules={{ + required: { value: true, message: 'Please select a folder' }, + validate: { + pathSeparator: (folder: Folder) => checkForPathSeparator(folder.title), + }, + }} + /> +
+ + + + )} ); @@ -172,5 +207,6 @@ const getStyles = (theme: GrafanaTheme2) => ({ display: flex; flex-direction: row; justify-content: flex-start; + align-items: flex-end; `, }); diff --git a/public/app/features/alerting/unified/components/rule-editor/GrafanaConditionsStep.tsx b/public/app/features/alerting/unified/components/rule-editor/GrafanaConditionsStep.tsx index cbde71df334..2d6b637eddf 100644 --- a/public/app/features/alerting/unified/components/rule-editor/GrafanaConditionsStep.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/GrafanaConditionsStep.tsx @@ -67,10 +67,8 @@ export const GrafanaConditionsStep: FC = () => { Evaluate every diff --git a/public/app/features/alerting/unified/components/rules/GrafanaRules.tsx b/public/app/features/alerting/unified/components/rules/GrafanaRules.tsx index eb4e4262f16..ab37aecab6e 100644 --- a/public/app/features/alerting/unified/components/rules/GrafanaRules.tsx +++ b/public/app/features/alerting/unified/components/rules/GrafanaRules.tsx @@ -7,6 +7,8 @@ import { RulesGroup } from './RulesGroup'; import { GRAFANA_RULES_SOURCE_NAME } from '../../utils/datasource'; import { CombinedRuleNamespace } from 'app/types/unified-alerting'; import { initialAsyncRequestState } from '../../utils/redux'; +import { useQueryParams } from 'app/core/hooks/useQueryParams'; +import { flattenGrafanaManagedRules } from '../../hooks/useCombinedRuleNamespaces'; interface Props { namespaces: CombinedRuleNamespace[]; @@ -15,10 +17,15 @@ interface Props { export const GrafanaRules: FC = ({ namespaces, expandAll }) => { const styles = useStyles(getStyles); + const [queryParams] = useQueryParams(); + const { loading } = useUnifiedAlertingSelector( (state) => state.promRules[GRAFANA_RULES_SOURCE_NAME] || initialAsyncRequestState ); + const wantsGroupedView = queryParams['view'] === 'grouped'; + const namespacesFormat = wantsGroupedView ? namespaces : flattenGrafanaManagedRules(namespaces); + return (
@@ -26,7 +33,7 @@ export const GrafanaRules: FC = ({ namespaces, expandAll }) => { {loading ? :
}
- {namespaces?.map((namespace) => + {namespacesFormat?.map((namespace) => namespace.groups.map((group) => ( = ({ namespaces, expandAll }) => { /> )) )} - {namespaces?.length === 0 &&

No rules found.

} + {namespacesFormat?.length === 0 &&

No rules found.

}
); }; diff --git a/public/app/features/alerting/unified/components/rules/RuleListGroupView.test.tsx b/public/app/features/alerting/unified/components/rules/RuleListGroupView.test.tsx index e7d2192e5d8..73a3983712b 100644 --- a/public/app/features/alerting/unified/components/rules/RuleListGroupView.test.tsx +++ b/public/app/features/alerting/unified/components/rules/RuleListGroupView.test.tsx @@ -1,3 +1,4 @@ +import { locationService } from '@grafana/runtime'; import { render } from '@testing-library/react'; import { contextSrv } from 'app/core/services/context_srv'; import { configureStore } from 'app/store/configureStore'; @@ -5,6 +6,7 @@ import { AccessControlAction } from 'app/types'; import { CombinedRuleNamespace } from 'app/types/unified-alerting'; import React from 'react'; import { Provider } from 'react-redux'; +import { Router } from 'react-router-dom'; import { byRole } from 'testing-library-selector'; import { mockCombinedRule, mockDataSource } from '../../mocks'; import { GRAFANA_RULES_SOURCE_NAME } from '../../utils/datasource'; @@ -76,7 +78,9 @@ function renderRuleList(namespaces: CombinedRuleNamespace[]) { render( - + + + ); } diff --git a/public/app/features/alerting/unified/components/rules/RulesFilter.tsx b/public/app/features/alerting/unified/components/rules/RulesFilter.tsx index e68188b4268..f0f38384a31 100644 --- a/public/app/features/alerting/unified/components/rules/RulesFilter.tsx +++ b/public/app/features/alerting/unified/components/rules/RulesFilter.tsx @@ -12,10 +12,15 @@ import { alertStateToReadable } from '../../utils/rules'; import { Stack } from '@grafana/experimental'; const ViewOptions: SelectableValue[] = [ + { + icon: 'list-ul', + label: 'List', + value: 'list', + }, { icon: 'folder', - label: 'Groups', - value: 'group', + label: 'Grouped', + value: 'grouped', }, { icon: 'heart-rate', @@ -147,7 +152,7 @@ const RulesFilter = () => { diff --git a/public/app/features/alerting/unified/components/rules/RulesGroup.tsx b/public/app/features/alerting/unified/components/rules/RulesGroup.tsx index ef668398c0c..b8c0c442d59 100644 --- a/public/app/features/alerting/unified/components/rules/RulesGroup.tsx +++ b/public/app/features/alerting/unified/components/rules/RulesGroup.tsx @@ -14,6 +14,7 @@ import { deleteRulesGroupAction } from '../../state/actions'; import { GRAFANA_RULES_SOURCE_NAME, isCloudRulesSource } from '../../utils/datasource'; import { isFederatedRuleGroup, isGrafanaRulerRule } from '../../utils/rules'; import { CollapseToggle } from '../CollapseToggle'; +import { RuleLocation } from '../RuleLocation'; import { ActionIcon } from './ActionIcon'; import { EditCloudGroupModal } from './EditCloudGroupModal'; import { RulesTable } from './RulesTable'; @@ -118,7 +119,13 @@ export const RulesGroup: FC = React.memo(({ group, namespace, expandAll } ); } - const groupName = isCloudRulesSource(rulesSource) ? `${namespace.name} > ${group.name}` : namespace.name; + // ungrouped rules are rules that are in the "default" group name + const isUngrouped = group.name === 'default'; + const groupName = isUngrouped ? ( + + ) : ( + + ); return (
diff --git a/public/app/features/alerting/unified/components/rules/RulesTable.tsx b/public/app/features/alerting/unified/components/rules/RulesTable.tsx index 221d238b91d..f638d258fcf 100644 --- a/public/app/features/alerting/unified/components/rules/RulesTable.tsx +++ b/public/app/features/alerting/unified/components/rules/RulesTable.tsx @@ -3,7 +3,6 @@ import { useStyles2 } from '@grafana/ui'; import React, { FC, useMemo } from 'react'; import { css, cx } from '@emotion/css'; import { RuleDetails } from './RuleDetails'; -import { isCloudRulesSource } from '../../utils/datasource'; import { useHasRuler } from '../../hooks/useHasRuler'; import { CombinedRule } from 'app/types/unified-alerting'; import { Annotation } from '../../utils/constants'; @@ -11,6 +10,7 @@ import { RuleState } from './RuleState'; import { RuleHealth } from './RuleHealth'; import { DynamicTable, DynamicTableColumnProps, DynamicTableItemProps } from '../DynamicTable'; import { DynamicTableWithGuidelines } from '../DynamicTableWithGuidelines'; +import { RuleLocation } from '../RuleLocation'; type RuleTableColumnProps = DynamicTableColumnProps; type RuleTableItemProps = DynamicTableItemProps; @@ -137,8 +137,15 @@ function useColumns(showSummaryColumn: boolean, showGroupColumn: boolean) { // eslint-disable-next-line react/display-name renderCell: ({ data: rule }) => { const { namespace, group } = rule; - const { rulesSource } = namespace; - return isCloudRulesSource(rulesSource) ? `${namespace.name} > ${group.name}` : namespace.name; + // ungrouped rules are rules that are in the "default" group name + const isUngrouped = group.name === 'default'; + const groupName = isUngrouped ? ( + + ) : ( + + ); + + return groupName; }, size: 5, }); diff --git a/public/app/features/alerting/unified/hooks/useCombinedRuleNamespaces.test.ts b/public/app/features/alerting/unified/hooks/useCombinedRuleNamespaces.test.ts new file mode 100644 index 00000000000..bbd6fb105f6 --- /dev/null +++ b/public/app/features/alerting/unified/hooks/useCombinedRuleNamespaces.test.ts @@ -0,0 +1,57 @@ +import { CombinedRuleGroup, CombinedRuleNamespace } from 'app/types/unified-alerting'; +import { sortRulesByName, flattenGrafanaManagedRules } from './useCombinedRuleNamespaces'; + +describe('flattenGrafanaManagedRules', () => { + it('should properly transform grafana managed namespaces', () => { + // the rules from both ungrouped groups should go in the default group + const ungroupedGroup1 = { + name: 'my-rule', + rules: [{ name: 'my-rule' }], + } as CombinedRuleGroup; + + const ungroupedGroup2 = { + name: 'another-rule', + rules: [{ name: 'another-rule' }], + } as CombinedRuleGroup; + + // the rules from both these groups should go in their own group name + const group1 = { + name: 'group1', + rules: [{ name: 'rule-1' }, { name: 'rule-2' }], + } as CombinedRuleGroup; + + const group2 = { + name: 'group2', + rules: [{ name: 'rule-1' }, { name: 'rule-2' }], + } as CombinedRuleGroup; + + const namespace1 = { + rulesSource: 'grafana', + name: 'ns1', + groups: [ungroupedGroup1, ungroupedGroup2, group1, group2], + }; + + const namespace2 = { + rulesSource: 'grafana', + name: 'ns2', + groups: [ungroupedGroup1], + }; + + const input = [namespace1, namespace2] as CombinedRuleNamespace[]; + const [ns1, ns2] = flattenGrafanaManagedRules(input); + + expect(ns1.groups).toEqual([ + { + name: 'default', + rules: sortRulesByName([...ungroupedGroup1.rules, ...ungroupedGroup2.rules, ...group1.rules, ...group2.rules]), + }, + ]); + + expect(ns2.groups).toEqual([ + { + name: 'default', + rules: ungroupedGroup1.rules, + }, + ]); + }); +}); diff --git a/public/app/features/alerting/unified/hooks/useCombinedRuleNamespaces.ts b/public/app/features/alerting/unified/hooks/useCombinedRuleNamespaces.ts index 259ff2af8c3..8b7afc403f5 100644 --- a/public/app/features/alerting/unified/hooks/useCombinedRuleNamespaces.ts +++ b/public/app/features/alerting/unified/hooks/useCombinedRuleNamespaces.ts @@ -81,17 +81,7 @@ export function useCombinedRuleNamespaces(rulesSourceName?: string): CombinedRul }); const result = Object.values(namespaces); - if (isGrafanaRulesSource(rulesSource)) { - // merge all groups in case of grafana managed, essentially treating namespaces (folders) as gorups - result.forEach((namespace) => { - namespace.groups = [ - { - name: 'default', - rules: namespace.groups.flatMap((g) => g.rules).sort((a, b) => a.name.localeCompare(b.name)), - }, - ]; - }); - } + cache.current[rulesSourceName] = { promRules, rulerRules, result }; return result; }) @@ -100,6 +90,28 @@ export function useCombinedRuleNamespaces(rulesSourceName?: string): CombinedRul ); } +// merge all groups in case of grafana managed, essentially treating namespaces (folders) as groups +export function flattenGrafanaManagedRules(namespaces: CombinedRuleNamespace[]) { + return namespaces.map((namespace) => { + const newNamespace: CombinedRuleNamespace = { + ...namespace, + groups: [], + }; + + // add default group with ungrouped rules + newNamespace.groups.push({ + name: 'default', + rules: sortRulesByName(namespace.groups.flatMap((group) => group.rules)), + }); + + return newNamespace; + }); +} + +export function sortRulesByName(rules: CombinedRule[]) { + return rules.sort((a, b) => a.name.localeCompare(b.name)); +} + function addRulerGroupsToCombinedNamespace(namespace: CombinedRuleNamespace, groups: RulerRuleGroupDTO[]): void { namespace.groups = groups.map((group) => { const combinedGroup: CombinedRuleGroup = { diff --git a/public/app/features/alerting/unified/state/actions.ts b/public/app/features/alerting/unified/state/actions.ts index 92df3168f92..571debd4e0b 100644 --- a/public/app/features/alerting/unified/state/actions.ts +++ b/public/app/features/alerting/unified/state/actions.ts @@ -390,8 +390,14 @@ export const saveRuleFormAction = createAsyncThunk( if (redirectOnSave) { locationService.push(redirectOnSave); } else { + // if the identifier comes up empty (this happens when Grafana managed rule moves to another namespace or group) + const stringifiedIdentifier = ruleId.stringifyIdentifier(identifier); + if (!stringifiedIdentifier) { + locationService.push('/alerting/list'); + return; + } // redirect to edit page - const newLocation = `/alerting/${encodeURIComponent(ruleId.stringifyIdentifier(identifier))}/edit`; + const newLocation = `/alerting/${encodeURIComponent(stringifiedIdentifier)}/edit`; if (locationService.getLocation().pathname !== newLocation) { locationService.replace(newLocation); } diff --git a/public/app/features/alerting/unified/types/rule-form.ts b/public/app/features/alerting/unified/types/rule-form.ts index 0ae36bb00b0..068dd2d3e2c 100644 --- a/public/app/features/alerting/unified/types/rule-form.ts +++ b/public/app/features/alerting/unified/types/rule-form.ts @@ -11,6 +11,7 @@ export interface RuleFormValues { name: string; type?: RuleFormType; dataSourceName: string | null; + group: string; labels: Array<{ key: string; value: string }>; annotations: Array<{ key: string; value: string }>; @@ -26,7 +27,6 @@ export interface RuleFormValues { // cortex / loki rules namespace: string; - group: string; forTime: number; forTimeUnit: string; expression: string; diff --git a/public/app/features/alerting/unified/utils/rule-form.ts b/public/app/features/alerting/unified/utils/rule-form.ts index c288586f1dd..36ae3b7510f 100644 --- a/public/app/features/alerting/unified/utils/rule-form.ts +++ b/public/app/features/alerting/unified/utils/rule-form.ts @@ -45,6 +45,7 @@ export const getDefaultFormValues = (): RuleFormValues => { ], dataSourceName: null, type: canCreateGrafanaRules ? RuleFormType.grafana : canCreateCloudRules ? RuleFormType.cloudAlerting : undefined, // viewers can't create prom alerts + group: '', // grafana folder: null, @@ -56,7 +57,6 @@ export const getDefaultFormValues = (): RuleFormValues => { evaluateFor: '5m', // cortex / loki - group: '', namespace: '', expression: '', forTime: 1, @@ -118,6 +118,7 @@ export function rulerRuleToFormValues(ruleWithLocation: RuleWithLocation): RuleF ...defaultFormValues, name: ga.title, type: RuleFormType.grafana, + group: group.name, evaluateFor: rule.for || '0', evaluateEvery: group.interval || defaultFormValues.evaluateEvery, noDataState: ga.no_data_state, diff --git a/public/app/features/alerting/unified/utils/rulerClient.test.ts b/public/app/features/alerting/unified/utils/rulerClient.test.ts deleted file mode 100644 index ec5771833cf..00000000000 --- a/public/app/features/alerting/unified/utils/rulerClient.test.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { RulerRuleGroupDTO } from 'app/types/unified-alerting-dto'; -import { getUniqueGroupName } from './rulerClient'; - -describe('getUniqueGroupName', () => { - it('Should return the original value when there are no duplicates', () => { - // Arrange - const originalGroupName = 'file-system-out-of-space'; - const existingGroups: RulerRuleGroupDTO[] = []; - - // Act - const groupName = getUniqueGroupName(originalGroupName, existingGroups); - - // Assert - expect(groupName).toBe(originalGroupName); - }); - - it('Should increment suffix counter until a unique name created', () => { - // Arrange - const originalGroupName = 'file-system-out-of-space'; - const existingGroups: RulerRuleGroupDTO[] = [ - { name: 'file-system-out-of-space', rules: [] }, - { name: 'file-system-out-of-space-2', rules: [] }, - ]; - - // Act - const groupName = getUniqueGroupName(originalGroupName, existingGroups); - - // Assert - expect(groupName).toBe('file-system-out-of-space-3'); - }); -}); diff --git a/public/app/features/alerting/unified/utils/rulerClient.ts b/public/app/features/alerting/unified/utils/rulerClient.ts index 89eb8e6c286..1d9c512a3dd 100644 --- a/public/app/features/alerting/unified/utils/rulerClient.ts +++ b/public/app/features/alerting/unified/utils/rulerClient.ts @@ -1,15 +1,14 @@ import { RuleIdentifier, RulerDataSourceConfig, RuleWithLocation } from 'app/types/unified-alerting'; -import { PostableRulerRuleGroupDTO, RulerGrafanaRuleDTO, RulerRuleGroupDTO } from 'app/types/unified-alerting-dto'; import { - deleteRulerRulesGroup, - fetchRulerRulesGroup, - fetchRulerRulesNamespace, - fetchRulerRules, - setRulerRuleGroup, -} from '../api/ruler'; + PostableRuleGrafanaRuleDTO, + PostableRulerRuleGroupDTO, + RulerGrafanaRuleDTO, + RulerRuleGroupDTO, +} from 'app/types/unified-alerting-dto'; +import { deleteRulerRulesGroup, fetchRulerRulesGroup, fetchRulerRules, setRulerRuleGroup } from '../api/ruler'; import { RuleFormValues } from '../types/rule-form'; import * as ruleId from '../utils/rule-id'; -import { GRAFANA_RULES_SOURCE_NAME, isGrafanaRulesSource } from './datasource'; +import { GRAFANA_RULES_SOURCE_NAME } from './datasource'; import { formValuesToRulerGrafanaRuleDTO, formValuesToRulerRuleDTO } from './rule-form'; import { isCloudRuleIdentifier, @@ -25,16 +24,6 @@ export interface RulerClient { saveGrafanaRule(values: RuleFormValues, existing?: RuleWithLocation): Promise; } -export function getUniqueGroupName(currentGroupName: string, existingGroups: RulerRuleGroupDTO[]) { - let newGroupName = currentGroupName; - let idx = 1; - while (!!existingGroups.find((g) => g.name === newGroupName)) { - newGroupName = `${currentGroupName}-${++idx}`; - } - - return newGroupName; -} - export function getRulerClient(rulerConfig: RulerDataSourceConfig): RulerClient { const findEditableRule = async (ruleIdentifier: RuleIdentifier): Promise => { if (isGrafanaRuleIdentifier(ruleIdentifier)) { @@ -90,13 +79,8 @@ export function getRulerClient(rulerConfig: RulerDataSourceConfig): RulerClient }; const deleteRule = async (ruleWithLocation: RuleWithLocation): Promise => { - const { ruleSourceName, namespace, group, rule } = ruleWithLocation; - // in case of GRAFANA, each group implicitly only has one rule. delete the group. - if (isGrafanaRulesSource(ruleSourceName)) { - await deleteRulerRulesGroup(rulerConfig, namespace, group.name); - return; - } - // in case of CLOUD + const { namespace, group, rule } = ruleWithLocation; + // it was the last rule, delete the entire group if (group.rules.length === 1) { await deleteRulerRulesGroup(rulerConfig, namespace, group.name); @@ -157,65 +141,104 @@ export function getRulerClient(rulerConfig: RulerDataSourceConfig): RulerClient } }; - const saveGrafanaRule = async (values: RuleFormValues, existing?: RuleWithLocation): Promise => { - const { folder, evaluateEvery } = values; - const formRule = formValuesToRulerGrafanaRuleDTO(values); - + const saveGrafanaRule = async (values: RuleFormValues, existingRule?: RuleWithLocation): Promise => { + const { folder, group, evaluateEvery } = values; if (!folder) { throw new Error('Folder must be specified'); } - // updating an existing rule... - if (existing) { - // refetch it to be sure we have the latest - const freshExisting = await findEditableRule(ruleId.fromRuleWithLocation(existing)); - if (!freshExisting) { - throw new Error('Rule not found.'); - } + const newRule = formValuesToRulerGrafanaRuleDTO(values); + const namespace = folder.title; + const groupSpec = { name: group, interval: evaluateEvery }; - // if same folder, repost the group with updated rule - if (freshExisting.namespace === folder.title) { - const uid = (freshExisting.rule as RulerGrafanaRuleDTO).grafana_alert.uid!; - formRule.grafana_alert.uid = uid; - await setRulerRuleGroup(rulerConfig, freshExisting.namespace, { - name: freshExisting.group.name, - interval: evaluateEvery, - rules: [formRule], - }); - return { uid, ruleSourceName: 'grafana' }; - } + if (!existingRule) { + return addRuleToNamespaceAndGroup(namespace, groupSpec, newRule); } - // if creating new rule or folder was changed, create rule in a new group - const targetFolderGroups = await fetchRulerRulesNamespace(rulerConfig, folder.title); + const sameNamespace = existingRule.namespace === namespace; + const sameGroup = existingRule.group.name === values.group; + const sameLocation = sameNamespace && sameGroup; - // set group name to rule name, but be super paranoid and check that this group does not already exist - const groupName = getUniqueGroupName(values.name, targetFolderGroups); - formRule.grafana_alert.title = groupName; + if (sameLocation) { + // we're update a rule in the same namespace and group + return updateGrafanaRule(existingRule, newRule, evaluateEvery); + } else { + // we're moving a rule to either a different group or namespace + return moveGrafanaRule(namespace, groupSpec, existingRule, newRule); + } + }; + + const addRuleToNamespaceAndGroup = async ( + namespace: string, + group: { name: string; interval: string }, + newRule: PostableRuleGrafanaRuleDTO + ): Promise => { + const existingGroup = await fetchRulerRulesGroup(rulerConfig, namespace, group.name); + if (!existingGroup) { + throw new Error(`No group found with name "${group.name}"`); + } const payload: PostableRulerRuleGroupDTO = { - name: groupName, - interval: evaluateEvery, - rules: [formRule], + name: group.name, + interval: group.interval, + rules: (existingGroup.rules ?? []).concat(newRule as RulerGrafanaRuleDTO), }; - await setRulerRuleGroup(rulerConfig, folder.title, payload); - // now refetch this group to get the uid, hah - const result = await fetchRulerRulesGroup(rulerConfig, folder.title, groupName); - const newUid = (result?.rules[0] as RulerGrafanaRuleDTO)?.grafana_alert?.uid; - if (newUid) { - // if folder has changed, delete the old one - if (existing) { - const freshExisting = await findEditableRule(ruleId.fromRuleWithLocation(existing)); - if (freshExisting && freshExisting.namespace !== folder.title) { - await deleteRule(freshExisting); - } - } + await setRulerRuleGroup(rulerConfig, namespace, payload); - return { uid: newUid, ruleSourceName: 'grafana' }; - } else { - throw new Error('Failed to fetch created rule.'); + return { uid: '', ruleSourceName: GRAFANA_RULES_SOURCE_NAME }; + }; + + // we can't move the rule in a single atomic operation so we have to + // 1. add the rule to the new group + // 2. remove the rule from the old one + const moveGrafanaRule = async ( + namespace: string, + group: { name: string; interval: string }, + existingRule: RuleWithLocation, + newRule: PostableRuleGrafanaRuleDTO + ): Promise => { + // add the new rule to the requested namespace and group + const identifier = await addRuleToNamespaceAndGroup(namespace, group, newRule); + + // remove the rule from the previous namespace and group + await deleteRule({ + ruleSourceName: existingRule.ruleSourceName, + namespace: existingRule.namespace, + group: existingRule.group, + rule: newRule as RulerGrafanaRuleDTO, + }); + + return identifier; + }; + + const updateGrafanaRule = async ( + existingRule: RuleWithLocation, + newRule: PostableRuleGrafanaRuleDTO, + interval: string + ): Promise => { + // type guard to make sure we're working with a Grafana managed rule + if (!isGrafanaRulerRule(existingRule.rule)) { + throw new Error('The rule is not a Grafana managed rule'); } + + // make sure our updated alert has the same UID as before + const uid = existingRule.rule.grafana_alert.uid; + newRule.grafana_alert.uid = uid; + + // create the new array of rules we want to send to the group + const newRules = existingRule.group.rules + .filter((rule): rule is RulerGrafanaRuleDTO => isGrafanaRulerRule(rule)) + .filter((rule) => rule.grafana_alert.uid !== uid) + .concat(newRule as RulerGrafanaRuleDTO); + + await setRulerRuleGroup(rulerConfig, existingRule.namespace, { + name: existingRule.group.name, + interval: interval, + rules: newRules, + }); + + return { uid: '', ruleSourceName: GRAFANA_RULES_SOURCE_NAME }; }; // Would be nice to somehow align checking of ruler type between different methods From c48d8d1d488e0ce5870c54eb5828660081743108 Mon Sep 17 00:00:00 2001 From: kay delaney <45561153+kaydelaney@users.noreply.github.com> Date: Wed, 20 Apr 2022 10:42:32 +0100 Subject: [PATCH 022/120] Frontend: Add notification persistence behind feature flag (#47871) --- .../src/types/featureToggles.gen.ts | 1 + .../grafana-data/src/types/legacyEvents.ts | 4 +- .../grafana-ui/src/components/Alert/Alert.tsx | 4 +- pkg/api/index.go | 6 + pkg/services/featuremgmt/registry.go | 6 + pkg/services/featuremgmt/toggles_gen.go | 4 + public/app/core/actions/index.ts | 4 +- .../AppNotifications/AppNotificationItem.tsx | 59 +++++---- .../AppNotifications/AppNotificationList.tsx | 10 +- .../StoredNotificationItem.tsx | 111 ++++++++++++++++ public/app/core/copy/appNotification.ts | 34 +++-- .../app/core/reducers/appNotification.test.ts | 49 ++++--- public/app/core/reducers/appNotification.ts | 105 +++++++++++++-- public/app/core/services/backend_srv.ts | 1 + public/app/core/specs/backend_srv.test.ts | 7 +- .../notifications/NotificationsPage.tsx | 36 +++++ .../notifications/StoredNotifications.tsx | 123 ++++++++++++++++++ public/app/features/sandbox/TestStuffPage.tsx | 22 +++- .../datasource/cloudwatch/datasource.ts | 1 + public/app/routes/routes.tsx | 6 + public/app/types/appNotifications.ts | 14 +- 21 files changed, 528 insertions(+), 79 deletions(-) create mode 100644 public/app/core/components/AppNotifications/StoredNotificationItem.tsx create mode 100644 public/app/features/notifications/NotificationsPage.tsx create mode 100644 public/app/features/notifications/StoredNotifications.tsx diff --git a/packages/grafana-data/src/types/featureToggles.gen.ts b/packages/grafana-data/src/types/featureToggles.gen.ts index 23e997e4dd6..f0d01d1dba6 100644 --- a/packages/grafana-data/src/types/featureToggles.gen.ts +++ b/packages/grafana-data/src/types/featureToggles.gen.ts @@ -54,4 +54,5 @@ export interface FeatureToggles { storageLocalUpload?: boolean; azureMonitorResourcePickerForMetrics?: boolean; explore2Dashboard?: boolean; + persistNotifications?: boolean; } diff --git a/packages/grafana-data/src/types/legacyEvents.ts b/packages/grafana-data/src/types/legacyEvents.ts index d7e09095a1f..df93d2f5f15 100644 --- a/packages/grafana-data/src/types/legacyEvents.ts +++ b/packages/grafana-data/src/types/legacyEvents.ts @@ -5,8 +5,8 @@ import { eventFactory } from '../events/eventFactory'; import { BusEventBase, BusEventWithPayload } from '../events/types'; import { DataHoverPayload } from '../events'; -export type AlertPayload = [string, string?]; -export type AlertErrorPayload = [string, (string | Error)?]; +export type AlertPayload = [string, string?, string?]; +export type AlertErrorPayload = [string, (string | Error)?, string?]; export const AppEvents = { alertSuccess: eventFactory('alert-success'), diff --git a/packages/grafana-ui/src/components/Alert/Alert.tsx b/packages/grafana-ui/src/components/Alert/Alert.tsx index c6e73b7fe2b..ddf70797e43 100644 --- a/packages/grafana-ui/src/components/Alert/Alert.tsx +++ b/packages/grafana-ui/src/components/Alert/Alert.tsx @@ -22,7 +22,7 @@ export interface Props extends HTMLAttributes { topSpacing?: number; } -function getIconFromSeverity(severity: AlertVariant): string { +export function getIconFromSeverity(severity: AlertVariant): string { switch (severity) { case 'error': case 'warning': @@ -150,7 +150,7 @@ const getStyles = ( color: ${theme.colors.text.secondary}; padding-top: ${theme.spacing(1)}; max-height: 50vh; - overflow-y: scroll; + overflow-y: auto; `, buttonWrapper: css` padding: ${theme.spacing(1)}; diff --git a/pkg/api/index.go b/pkg/api/index.go index 0d7f0412e01..f46a3c3c353 100644 --- a/pkg/api/index.go +++ b/pkg/api/index.go @@ -38,6 +38,12 @@ func (hs *HTTPServer) getProfileNode(c *models.ReqContext) *dtos.NavLink { }, } + if hs.Features.IsEnabled(featuremgmt.FlagPersistNotifications) { + children = append(children, &dtos.NavLink{ + Text: "Notifications", Id: "notifications", Url: hs.Cfg.AppSubURL + "/notifications", Icon: "bell", + }) + } + if setting.AddChangePasswordLink() { children = append(children, &dtos.NavLink{ Text: "Change password", Id: "change-password", Url: hs.Cfg.AppSubURL + "/profile/password", diff --git a/pkg/services/featuremgmt/registry.go b/pkg/services/featuremgmt/registry.go index 60b46d46b6a..2e7ce48be55 100644 --- a/pkg/services/featuremgmt/registry.go +++ b/pkg/services/featuremgmt/registry.go @@ -213,5 +213,11 @@ var ( State: FeatureStateBeta, FrontendOnly: true, }, + { + Name: "persistNotifications", + Description: "PoC Notifications page", + State: FeatureStateAlpha, + FrontendOnly: true, + }, } ) diff --git a/pkg/services/featuremgmt/toggles_gen.go b/pkg/services/featuremgmt/toggles_gen.go index 7548ed76643..8d0c9764b32 100644 --- a/pkg/services/featuremgmt/toggles_gen.go +++ b/pkg/services/featuremgmt/toggles_gen.go @@ -158,4 +158,8 @@ const ( // FlagExplore2Dashboard // Experimental Explore to Dashboard workflow FlagExplore2Dashboard = "explore2Dashboard" + + // FlagPersistNotifications + // PoC Notifications page + FlagPersistNotifications = "persistNotifications" ) diff --git a/public/app/core/actions/index.ts b/public/app/core/actions/index.ts index 4df4144e94c..88c6c68ab2e 100644 --- a/public/app/core/actions/index.ts +++ b/public/app/core/actions/index.ts @@ -1,3 +1,3 @@ -import { clearAppNotification, notifyApp } from '../reducers/appNotification'; +import { hideAppNotification, notifyApp } from '../reducers/appNotification'; import { updateNavIndex, updateConfigurationSubtitle } from '../reducers/navModel'; -export { updateNavIndex, updateConfigurationSubtitle, notifyApp, clearAppNotification }; +export { updateNavIndex, updateConfigurationSubtitle, notifyApp, hideAppNotification }; diff --git a/public/app/core/components/AppNotifications/AppNotificationItem.tsx b/public/app/core/components/AppNotifications/AppNotificationItem.tsx index c1c227f4fd4..4b309a5b775 100644 --- a/public/app/core/components/AppNotifications/AppNotificationItem.tsx +++ b/public/app/core/components/AppNotifications/AppNotificationItem.tsx @@ -1,36 +1,47 @@ -import React, { Component } from 'react'; -import { AppNotification } from 'app/types'; -import { Alert } from '@grafana/ui'; +import React from 'react'; +import { useEffectOnce } from 'react-use'; +import { css } from '@emotion/css'; +import { Alert, useStyles2 } from '@grafana/ui'; +import { GrafanaTheme2 } from '@grafana/data'; +import { AppNotification, timeoutMap } from 'app/types'; interface Props { appNotification: AppNotification; onClearNotification: (id: string) => void; } -export default class AppNotificationItem extends Component { - shouldComponentUpdate(nextProps: Props) { - return this.props.appNotification.id !== nextProps.appNotification.id; - } +export default function AppNotificationItem({ appNotification, onClearNotification }: Props) { + const styles = useStyles2(getStyles); - componentDidMount() { - const { appNotification, onClearNotification } = this.props; + useEffectOnce(() => { setTimeout(() => { onClearNotification(appNotification.id); - }, appNotification.timeout); - } + }, timeoutMap[appNotification.severity]); + }); - render() { - const { appNotification, onClearNotification } = this.props; + return ( + onClearNotification(appNotification.id)} + elevated + > +
+ {appNotification.component || appNotification.text} + {appNotification.traceId && Trace ID: {appNotification.traceId}} +
+
+ ); +} - return ( - onClearNotification(appNotification.id)} - elevated - > - {appNotification.component || appNotification.text} - - ); - } +function getStyles(theme: GrafanaTheme2) { + return { + wrapper: css({ + display: 'flex', + flexDirection: 'column', + }), + trace: css({ + fontSize: theme.typography.pxToRem(10), + }), + }; } diff --git a/public/app/core/components/AppNotifications/AppNotificationList.tsx b/public/app/core/components/AppNotifications/AppNotificationList.tsx index 4fe53b56801..d9aba49843a 100644 --- a/public/app/core/components/AppNotifications/AppNotificationList.tsx +++ b/public/app/core/components/AppNotifications/AppNotificationList.tsx @@ -1,8 +1,8 @@ import React, { PureComponent } from 'react'; import appEvents from 'app/core/app_events'; import AppNotificationItem from './AppNotificationItem'; -import { notifyApp, clearAppNotification } from 'app/core/actions'; -import { selectAll } from 'app/core/reducers/appNotification'; +import { notifyApp, hideAppNotification } from 'app/core/actions'; +import { selectVisible } from 'app/core/reducers/appNotification'; import { StoreState } from 'app/types'; import { @@ -17,12 +17,12 @@ import { VerticalGroup } from '@grafana/ui'; export interface OwnProps {} const mapStateToProps = (state: StoreState, props: OwnProps) => ({ - appNotifications: selectAll(state.appNotifications), + appNotifications: selectVisible(state.appNotifications), }); const mapDispatchToProps = { notifyApp, - clearAppNotification, + hideAppNotification, }; const connector = connect(mapStateToProps, mapDispatchToProps); @@ -39,7 +39,7 @@ export class AppNotificationListUnConnected extends PureComponent { } onClearAppNotification = (id: string) => { - this.props.clearAppNotification(id); + this.props.hideAppNotification(id); }; render() { diff --git a/public/app/core/components/AppNotifications/StoredNotificationItem.tsx b/public/app/core/components/AppNotifications/StoredNotificationItem.tsx new file mode 100644 index 00000000000..ea044c362b8 --- /dev/null +++ b/public/app/core/components/AppNotifications/StoredNotificationItem.tsx @@ -0,0 +1,111 @@ +import React, { ReactNode } from 'react'; +import { formatDistanceToNow } from 'date-fns'; +import { css } from '@emotion/css'; +import { GrafanaTheme2 } from '@grafana/data'; +import { getIconFromSeverity } from '@grafana/ui/src/components/Alert/Alert'; +import { Icon, IconButton, IconName, useTheme2 } from '@grafana/ui'; + +export type AlertVariant = 'success' | 'warning' | 'error' | 'info'; + +export interface Props { + title: string; + severity?: AlertVariant; + timestamp?: number; + traceId?: string; + children?: ReactNode; + onRemove?: (event: React.MouseEvent) => void; +} + +export const StoredNotificationItem = ({ + title, + severity = 'error', + traceId, + timestamp, + children, + onRemove, +}: Props) => { + const theme = useTheme2(); + const styles = getStyles(theme, severity); + + return ( +
+
+ +
+
{title}
+
{children}
+ {traceId && `Trace ID: ${traceId}`} +
+ +
+ {timestamp && {formatDistanceToNow(timestamp, { addSuffix: true })}} +
+ ); +}; + +const getStyles = (theme: GrafanaTheme2, severity: AlertVariant) => { + const color = theme.colors[severity]; + const borderRadius = theme.shape.borderRadius(); + + return { + wrapper: css({ + display: 'grid', + gridTemplateColumns: 'auto 1fr auto', + gridTemplateRows: 'auto 1fr auto', + gridTemplateAreas: ` + 'icon title close' + 'icon body body' + 'icon trace timestamp'`, + gap: `0 ${theme.spacing(2)}`, + background: theme.colors.background.secondary, + borderRadius: borderRadius, + }), + icon: css({ + gridArea: 'icon', + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + padding: theme.spacing(2, 3), + background: color.main, + color: color.contrastText, + borderRadius: `${borderRadius} 0 0 ${borderRadius}`, + }), + title: css({ + gridArea: 'title', + alignSelf: 'center', + fontWeight: theme.typography.fontWeightMedium, + color: theme.colors.text.primary, + }), + body: css({ + gridArea: 'body', + maxHeight: '50vh', + marginRight: theme.spacing(1), + overflowY: 'auto', + overflowWrap: 'break-word', + wordBreak: 'break-word', + color: theme.colors.text.secondary, + }), + trace: css({ + gridArea: 'trace', + justifySelf: 'start', + alignSelf: 'end', + paddingBottom: theme.spacing(1), + fontSize: theme.typography.pxToRem(10), + color: theme.colors.text.secondary, + }), + close: css({ + gridArea: 'close', + display: 'flex', + justifySelf: 'end', + padding: theme.spacing(1, 0.5), + background: 'none', + }), + timestamp: css({ + gridArea: 'timestamp', + alignSelf: 'end', + padding: theme.spacing(1), + fontSize: theme.typography.pxToRem(10), + color: theme.colors.text.secondary, + }), + }; +}; diff --git a/public/app/core/copy/appNotification.ts b/public/app/core/copy/appNotification.ts index 2c94b701653..987f7194eeb 100644 --- a/public/app/core/copy/appNotification.ts +++ b/public/app/core/copy/appNotification.ts @@ -1,5 +1,5 @@ import { useMemo } from 'react'; -import { AppNotification, AppNotificationSeverity, AppNotificationTimeout, useDispatch } from 'app/types'; +import { AppNotification, AppNotificationSeverity, useDispatch } from 'app/types'; import { getMessageFromError } from 'app/core/utils/errors'; import { v4 as uuidv4 } from 'uuid'; import { notifyApp } from '../actions'; @@ -9,7 +9,6 @@ const defaultSuccessNotification = { text: '', severity: AppNotificationSeverity.Success, icon: 'check', - timeout: AppNotificationTimeout.Success, }; const defaultWarningNotification = { @@ -17,7 +16,6 @@ const defaultWarningNotification = { text: '', severity: AppNotificationSeverity.Warning, icon: 'exclamation-triangle', - timeout: AppNotificationTimeout.Warning, }; const defaultErrorNotification = { @@ -25,19 +23,21 @@ const defaultErrorNotification = { text: '', severity: AppNotificationSeverity.Error, icon: 'exclamation-triangle', - timeout: AppNotificationTimeout.Error, }; -export const createSuccessNotification = (title: string, text = ''): AppNotification => ({ +export const createSuccessNotification = (title: string, text = '', traceId?: string): AppNotification => ({ ...defaultSuccessNotification, - title: title, - text: text, + title, + text, id: uuidv4(), + timestamp: Date.now(), + showing: true, }); export const createErrorNotification = ( title: string, text: string | Error = '', + traceId?: string, component?: React.ReactElement ): AppNotification => { return { @@ -45,15 +45,21 @@ export const createErrorNotification = ( text: getMessageFromError(text), title, id: uuidv4(), + traceId, component, + timestamp: Date.now(), + showing: true, }; }; -export const createWarningNotification = (title: string, text = ''): AppNotification => ({ +export const createWarningNotification = (title: string, text = '', traceId?: string): AppNotification => ({ ...defaultWarningNotification, - title: title, - text: text, + title, + text, + traceId, id: uuidv4(), + timestamp: Date.now(), + showing: true, }); /** Hook for showing toast notifications with varying severity (success, warning error). @@ -70,11 +76,11 @@ export function useAppNotification() { success: (title: string, text = '') => { dispatch(notifyApp(createSuccessNotification(title, text))); }, - warning: (title: string, text = '') => { - dispatch(notifyApp(createWarningNotification(title, text))); + warning: (title: string, text = '', traceId?: string) => { + dispatch(notifyApp(createWarningNotification(title, text, traceId))); }, - error: (title: string, text = '') => { - dispatch(notifyApp(createErrorNotification(title, text))); + error: (title: string, text = '', traceId?: string) => { + dispatch(notifyApp(createErrorNotification(title, text, traceId))); }, }), [dispatch] diff --git a/public/app/core/reducers/appNotification.test.ts b/public/app/core/reducers/appNotification.test.ts index edbf431ba2e..d0228683d14 100644 --- a/public/app/core/reducers/appNotification.test.ts +++ b/public/app/core/reducers/appNotification.test.ts @@ -1,6 +1,7 @@ -import { appNotificationsReducer, clearAppNotification, notifyApp } from './appNotification'; -import { AppNotificationSeverity, AppNotificationsState, AppNotificationTimeout } from 'app/types/'; +import { appNotificationsReducer, clearNotification, notifyApp } from './appNotification'; +import { AppNotificationSeverity, AppNotificationsState } from 'app/types/'; +const timestamp = 1649849468889; describe('clear alert', () => { it('should filter alert', () => { const id1 = '1767d3d9-4b99-40eb-ab46-de734a66f21d'; @@ -14,7 +15,8 @@ describe('clear alert', () => { icon: 'success', title: 'test', text: 'test alert', - timeout: AppNotificationTimeout.Success, + showing: true, + timestamp, }, [id2]: { id: id2, @@ -22,12 +24,14 @@ describe('clear alert', () => { icon: 'warning', title: 'test2', text: 'test alert fail 2', - timeout: AppNotificationTimeout.Warning, + showing: true, + timestamp, }, }, + lastRead: timestamp - 10, }; - const result = appNotificationsReducer(initialState, clearAppNotification(id2)); + const result = appNotificationsReducer(initialState, clearNotification(id2)); const expectedResult: AppNotificationsState = { byId: { @@ -37,9 +41,11 @@ describe('clear alert', () => { icon: 'success', title: 'test', text: 'test alert', - timeout: AppNotificationTimeout.Success, + showing: true, + timestamp, }, }, + lastRead: timestamp - 10, }; expect(result).toEqual(expectedResult); @@ -60,7 +66,8 @@ describe('notify', () => { icon: 'success', title: 'test', text: 'test alert', - timeout: AppNotificationTimeout.Success, + showing: true, + timestamp, }, [id2]: { id: id2, @@ -68,9 +75,11 @@ describe('notify', () => { icon: 'warning', title: 'test2', text: 'test alert fail 2', - timeout: AppNotificationTimeout.Warning, + showing: true, + timestamp, }, }, + lastRead: timestamp - 10, }; const result = appNotificationsReducer( @@ -81,7 +90,8 @@ describe('notify', () => { icon: 'info', title: 'test3', text: 'test alert info 3', - timeout: AppNotificationTimeout.Success, + showing: true, + timestamp: 1649802870373, }) ); @@ -93,7 +103,8 @@ describe('notify', () => { icon: 'success', title: 'test', text: 'test alert', - timeout: AppNotificationTimeout.Success, + timestamp, + showing: true, }, [id2]: { id: id2, @@ -101,7 +112,8 @@ describe('notify', () => { icon: 'warning', title: 'test2', text: 'test alert fail 2', - timeout: AppNotificationTimeout.Warning, + timestamp, + showing: true, }, [id3]: { id: id3, @@ -109,9 +121,11 @@ describe('notify', () => { icon: 'info', title: 'test3', text: 'test alert info 3', - timeout: AppNotificationTimeout.Success, + timestamp: 1649802870373, + showing: true, }, }, + lastRead: timestamp - 10, }; expect(result).toEqual(expectedResult); @@ -126,9 +140,11 @@ describe('notify', () => { icon: 'success', title: 'test', text: 'test alert', - timeout: AppNotificationTimeout.Success, + showing: true, + timestamp, }, }, + lastRead: timestamp - 10, }; const result = appNotificationsReducer( @@ -139,7 +155,8 @@ describe('notify', () => { icon: 'success', title: 'test', text: 'test alert', - timeout: AppNotificationTimeout.Success, + showing: true, + timestamp, }) ); @@ -151,9 +168,11 @@ describe('notify', () => { icon: 'success', title: 'test', text: 'test alert', - timeout: AppNotificationTimeout.Success, + showing: true, + timestamp, }, }, + lastRead: timestamp - 10, }; expect(result).toEqual(expectedResult); diff --git a/public/app/core/reducers/appNotification.ts b/public/app/core/reducers/appNotification.ts index 5da53d31c81..ff78a4bf14a 100644 --- a/public/app/core/reducers/appNotification.ts +++ b/public/app/core/reducers/appNotification.ts @@ -1,8 +1,14 @@ +import { config } from '@grafana/runtime'; import { createSlice, PayloadAction } from '@reduxjs/toolkit'; -import { AppNotification, AppNotificationsState } from 'app/types/'; +import { AppNotification, AppNotificationSeverity, AppNotificationsState } from 'app/types/'; + +export const STORAGE_KEY = 'notifications'; +export const NEW_NOTIFS_KEY = `${STORAGE_KEY}/lastRead`; +type StoredNotification = Omit; export const initialState: AppNotificationsState = { - byId: {}, + byId: deserializeNotifications(), + lastRead: Number.parseInt(window.localStorage.getItem(NEW_NOTIFS_KEY) ?? `${Date.now()}`, 10), }; /** @@ -16,30 +22,107 @@ const appNotificationsSlice = createSlice({ initialState, reducers: { notifyApp: (state, { payload: newAlert }: PayloadAction) => { - if (Object.values(state.byId).some((alert) => isSimilar(newAlert, alert))) { + if (Object.values(state.byId).some((alert) => isSimilar(newAlert, alert) && alert.showing)) { return; } state.byId[newAlert.id] = newAlert; + serializeNotifications(state.byId); }, - clearAppNotification: (state, { payload: alertId }: PayloadAction) => { + hideAppNotification: (state, { payload: alertId }: PayloadAction) => { + if (!(alertId in state.byId)) { + return; + } + + state.byId[alertId].showing = false; + serializeNotifications(state.byId); + }, + clearNotification: (state, { payload: alertId }: PayloadAction) => { delete state.byId[alertId]; + serializeNotifications(state.byId); + }, + clearAllNotifications: (state) => { + state.byId = {}; + serializeNotifications(state.byId); + }, + readAllNotifications: (state, { payload: timestamp }: PayloadAction) => { + state.lastRead = timestamp; }, }, }); -export const { notifyApp, clearAppNotification } = appNotificationsSlice.actions; +export const { notifyApp, hideAppNotification, clearNotification, clearAllNotifications, readAllNotifications } = + appNotificationsSlice.actions; export const appNotificationsReducer = appNotificationsSlice.reducer; -export const selectAll = (state: AppNotificationsState) => Object.values(state.byId); +// Selectors + +export const selectLastReadTimestamp = (state: AppNotificationsState) => state.lastRead; +export const selectAll = (state: AppNotificationsState) => + Object.values(state.byId).sort((a, b) => b.timestamp - a.timestamp); +export const selectWarningsAndErrors = (state: AppNotificationsState) => selectAll(state).filter(isAtLeastWarning); +export const selectVisible = (state: AppNotificationsState) => Object.values(state.byId).filter((n) => n.showing); + +// Helper functions function isSimilar(a: AppNotification, b: AppNotification): boolean { + return a.icon === b.icon && a.severity === b.severity && a.text === b.text && a.title === b.title; +} + +function isAtLeastWarning(notif: AppNotification) { + return notif.severity === AppNotificationSeverity.Warning || notif.severity === AppNotificationSeverity.Error; +} + +function isStoredNotification(obj: any): obj is StoredNotification { return ( - a.icon === b.icon && - a.severity === b.severity && - a.text === b.text && - a.title === b.title && - a.component === b.component + typeof obj.id === 'string' && + typeof obj.icon === 'string' && + typeof obj.title === 'string' && + typeof obj.text === 'string' ); } + +// (De)serialization + +export function deserializeNotifications(): Record { + if (!config.featureToggles?.persistNotifications) { + return {}; + } + + const storedNotifsRaw = window.localStorage.getItem(STORAGE_KEY); + if (!storedNotifsRaw) { + return {}; + } + + const parsed = JSON.parse(storedNotifsRaw); + if (!Object.values(parsed).every((v) => isStoredNotification(v))) { + return {}; + } + + return parsed; +} + +function serializeNotifications(notifs: Record) { + if (!config.featureToggles?.persistNotifications) { + return; + } + + const reducedNotifs = Object.values(notifs) + .filter(isAtLeastWarning) + .reduce>((prev, cur) => { + prev[cur.id] = { + id: cur.id, + severity: cur.severity, + icon: cur.icon, + title: cur.title, + text: cur.text, + traceId: cur.traceId, + timestamp: cur.timestamp, + showing: cur.showing, + }; + + return prev; + }, {}); + window.localStorage.setItem(STORAGE_KEY, JSON.stringify(reducedNotifs)); +} diff --git a/public/app/core/services/backend_srv.ts b/public/app/core/services/backend_srv.ts index 72e7c92b993..6da5e10f6d2 100644 --- a/public/app/core/services/backend_srv.ts +++ b/public/app/core/services/backend_srv.ts @@ -310,6 +310,7 @@ export class BackendSrv implements BackendService { this.dependencies.appEvents.emit(err.status < 500 ? AppEvents.alertWarning : AppEvents.alertError, [ message, description, + err.data.traceID, ]); } diff --git a/public/app/core/specs/backend_srv.test.ts b/public/app/core/specs/backend_srv.test.ts index c66a4acd70e..5176f4959d0 100644 --- a/public/app/core/specs/backend_srv.test.ts +++ b/public/app/core/specs/backend_srv.test.ts @@ -264,10 +264,15 @@ describe('backendSrv', () => { data: { message: 'Something failed', error: 'Error', + traceID: 'bogus-trace-id', }, } as FetchError ); - expect(appEventsMock.emit).toHaveBeenCalledWith(AppEvents.alertError, ['Something failed', '']); + expect(appEventsMock.emit).toHaveBeenCalledWith(AppEvents.alertError, [ + 'Something failed', + '', + 'bogus-trace-id', + ]); }); }); }); diff --git a/public/app/features/notifications/NotificationsPage.tsx b/public/app/features/notifications/NotificationsPage.tsx new file mode 100644 index 00000000000..e2e5c49338d --- /dev/null +++ b/public/app/features/notifications/NotificationsPage.tsx @@ -0,0 +1,36 @@ +import React from 'react'; +import { connect, ConnectedProps } from 'react-redux'; + +import { config } from '@grafana/runtime'; + +import { GrafanaRouteComponentProps } from '../../core/navigation/types'; +import { StoreState } from '../../types'; +import { getNavModel } from '../../core/selectors/navModel'; +import Page from '../../core/components/Page/Page'; +import { StoredNotifications } from './StoredNotifications'; + +const mapStateToProps = (state: StoreState) => ({ + navModel: getNavModel(state.navIndex, 'notifications'), +}); + +const connector = connect(mapStateToProps, undefined); + +interface OwnProps extends GrafanaRouteComponentProps {} + +type Props = OwnProps & ConnectedProps; + +export const NotificationsPage = ({ navModel }: Props) => { + if (!config.featureToggles.persistNotifications) { + return null; + } + + return ( + + + + + + ); +}; + +export default connect(mapStateToProps)(NotificationsPage); diff --git a/public/app/features/notifications/StoredNotifications.tsx b/public/app/features/notifications/StoredNotifications.tsx new file mode 100644 index 00000000000..1fa99b3b903 --- /dev/null +++ b/public/app/features/notifications/StoredNotifications.tsx @@ -0,0 +1,123 @@ +import React, { useRef } from 'react'; +import { useEffectOnce } from 'react-use'; +import { css, cx } from '@emotion/css'; +import { GrafanaTheme2 } from '@grafana/data'; +import { Button, Icon, useStyles2 } from '@grafana/ui'; +import { useDispatch, useSelector } from 'app/types'; +import { + clearAllNotifications, + clearNotification, + readAllNotifications, + selectWarningsAndErrors, + selectLastReadTimestamp, +} from 'app/core/reducers/appNotification'; +import { StoredNotificationItem } from 'app/core/components/AppNotifications/StoredNotificationItem'; + +export function StoredNotifications() { + const dispatch = useDispatch(); + const notifications = useSelector((state) => selectWarningsAndErrors(state.appNotifications)); + const lastReadTimestamp = useRef(useSelector((state) => selectLastReadTimestamp(state.appNotifications))); + const styles = useStyles2(getStyles); + + useEffectOnce(() => { + dispatch(readAllNotifications(Date.now())); + }); + + const onClearNotification = (id: string) => { + dispatch(clearNotification(id)); + }; + + const clearAllNotifs = () => { + dispatch(clearAllNotifications()); + }; + + if (notifications.length === 0) { + return ( +
+ + Notifications you have received will appear here. +
+ ); + } + + return ( +
+ +
    + {notifications.map((notif) => ( +
  • lastReadTimestamp.current })} + > + onClearNotification(notif.id)} + timestamp={notif.timestamp} + traceId={notif.traceId} + > + {notif.text} + +
  • + ))} +
+
+ ); +} + +function getStyles(theme: GrafanaTheme2) { + return { + smallText: css({ + fontSize: theme.typography.pxToRem(10), + color: theme.colors.text.secondary, + }), + side: css({ + display: 'flex', + flexDirection: 'column', + padding: '3px 6px', + paddingTop: theme.spacing(1), + alignItems: 'flex-end', + justifyContent: 'space-between', + flexShrink: 0, + }), + list: css({ + display: 'flex', + flexDirection: 'column', + gap: theme.spacing(1), + }), + listItem: css({ + listStyle: 'none', + gap: theme.spacing(1), + alignItems: 'center', + position: 'relative', + }), + newItem: css({ + '&::before': { + content: '""', + height: '100%', + position: 'absolute', + left: '-7px', + top: 0, + background: theme.colors.gradients.brandVertical, + width: theme.spacing(0.5), + borderRadius: theme.shape.borderRadius(1), + }, + }), + noNotifsWrapper: css({ + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + gap: theme.spacing(1), + }), + wrapper: css({ + display: 'flex', + flexDirection: 'column', + gap: theme.spacing(2), + }), + clearAll: css({ + alignSelf: 'flex-end', + }), + }; +} diff --git a/public/app/features/sandbox/TestStuffPage.tsx b/public/app/features/sandbox/TestStuffPage.tsx index 360402b78dd..7da9e64ac90 100644 --- a/public/app/features/sandbox/TestStuffPage.tsx +++ b/public/app/features/sandbox/TestStuffPage.tsx @@ -6,7 +6,7 @@ import { NavModelItem, PanelData, } from '@grafana/data'; -import { Table } from '@grafana/ui'; +import { Button, Table } from '@grafana/ui'; import { config } from 'app/core/config'; import React, { FC, useMemo, useState } from 'react'; import { useObservable } from 'react-use'; @@ -16,6 +16,7 @@ import { QueryGroupOptions } from 'app/types'; import Page from '../../core/components/Page/Page'; import AutoSizer from 'react-virtualized-auto-sizer'; import { PanelRenderer } from '../panel/components/PanelRenderer'; +import { useAppNotification } from 'app/core/copy/appNotification'; interface State { queryRunner: PanelQueryRunner; @@ -58,6 +59,8 @@ export const TestStuffPage: FC = () => { url: 'sandbox/test', }; + const notifyApp = useAppNotification(); + return ( @@ -90,6 +93,23 @@ export const TestStuffPage: FC = () => { onOptionsChange={onOptionsChange} />
+
+ + + +
); diff --git a/public/app/plugins/datasource/cloudwatch/datasource.ts b/public/app/plugins/datasource/cloudwatch/datasource.ts index f1ae76f8aef..059377a8c17 100644 --- a/public/app/plugins/datasource/cloudwatch/datasource.ts +++ b/public/app/plugins/datasource/cloudwatch/datasource.ts @@ -73,6 +73,7 @@ const displayAlert = (datasourceName: string, region: string) => createErrorNotification( `CloudWatch request limit reached in ${region} for data source ${datasourceName}`, '', + undefined, React.createElement(ThrottlingErrorMessage, { region }, null) ) ) diff --git a/public/app/routes/routes.tsx b/public/app/routes/routes.tsx index b749467036d..b2e353f71b4 100644 --- a/public/app/routes/routes.tsx +++ b/public/app/routes/routes.tsx @@ -418,6 +418,12 @@ export function getAppRoutes(): RouteDescriptor[] { () => import(/* webpackChunkName: "LibraryPanelsPage"*/ 'app/features/library-panels/LibraryPanelsPage') ), }, + { + path: '/notifications', + component: SafeDynamicImport( + () => import(/* webpackChunkName: "NotificationsPage"*/ 'app/features/notifications/NotificationsPage') + ), + }, ...getPluginCatalogRoutes(), ...getLiveRoutes(), ...getAlertingRoutes(), diff --git a/public/app/types/appNotifications.ts b/public/app/types/appNotifications.ts index 7976b447986..a3a7ea2aed7 100644 --- a/public/app/types/appNotifications.ts +++ b/public/app/types/appNotifications.ts @@ -4,8 +4,10 @@ export interface AppNotification { icon: string; title: string; text: string; + traceId?: string; component?: React.ReactElement; - timeout: AppNotificationTimeout; + showing: boolean; + timestamp: number; } export enum AppNotificationSeverity { @@ -16,11 +18,19 @@ export enum AppNotificationSeverity { } export enum AppNotificationTimeout { - Warning = 5000, Success = 3000, + Warning = 5000, Error = 7000, } +export const timeoutMap = { + [AppNotificationSeverity.Success]: AppNotificationTimeout.Success, + [AppNotificationSeverity.Warning]: AppNotificationTimeout.Warning, + [AppNotificationSeverity.Error]: AppNotificationTimeout.Error, + [AppNotificationSeverity.Info]: AppNotificationTimeout.Success, +}; + export interface AppNotificationsState { byId: Record; + lastRead: number; } From 8ae5dd74e617fcb8442514a1afa3229a5d938334 Mon Sep 17 00:00:00 2001 From: kay delaney <45561153+kaydelaney@users.noreply.github.com> Date: Wed, 20 Apr 2022 10:56:19 +0100 Subject: [PATCH 023/120] Dashboards: Defer loading of plugin exports until panel is visible (#47361) --- .../containers/DashboardPage.test.tsx | 6 +++- .../dashboard/dashgrid/DashboardPanel.tsx | 33 ++++++++----------- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/public/app/features/dashboard/containers/DashboardPage.test.tsx b/public/app/features/dashboard/containers/DashboardPage.test.tsx index 4c68581de51..c6b90437dc0 100644 --- a/public/app/features/dashboard/containers/DashboardPage.test.tsx +++ b/public/app/features/dashboard/containers/DashboardPage.test.tsx @@ -1,5 +1,6 @@ import React from 'react'; import { Provider } from 'react-redux'; +import { useEffectOnce } from 'react-use'; import { render, screen } from '@testing-library/react'; import { Props, UnthemedDashboardPage } from './DashboardPage'; import { Props as LazyLoaderProps } from '../dashgrid/LazyLoader'; @@ -17,7 +18,10 @@ import { AutoSizerProps } from 'react-virtualized-auto-sizer'; import { setDashboardSrv } from '../services/DashboardSrv'; jest.mock('app/features/dashboard/dashgrid/LazyLoader', () => { - const LazyLoader = ({ children }: Pick) => { + const LazyLoader = ({ children, onLoad }: Pick) => { + useEffectOnce(() => { + onLoad?.(); + }); return <>{typeof children === 'function' ? children({ isInView: true }) : children}; }; return { LazyLoader }; diff --git a/public/app/features/dashboard/dashgrid/DashboardPanel.tsx b/public/app/features/dashboard/dashgrid/DashboardPanel.tsx index 0401ecf9397..3783545ae69 100644 --- a/public/app/features/dashboard/dashgrid/DashboardPanel.tsx +++ b/public/app/features/dashboard/dashgrid/DashboardPanel.tsx @@ -4,7 +4,6 @@ import { PanelChrome } from './PanelChrome'; import { PanelChromeAngular } from './PanelChromeAngular'; import { DashboardModel, PanelModel } from '../state'; import { StoreState } from 'app/types'; -import { PanelPlugin } from '@grafana/data'; import { setPanelInstanceState } from '../../panel/state/reducers'; import { initPanelState } from '../../panel/state/actions'; import { LazyLoader } from './LazyLoader'; @@ -48,8 +47,8 @@ export class DashboardPanelUnconnected extends PureComponent { componentDidMount() { this.props.panel.isInView = !this.props.lazy; - if (!this.props.plugin) { - this.props.initPanelState(this.props.panel); + if (!this.props.lazy) { + this.onPanelLoad(); } } @@ -61,11 +60,18 @@ export class DashboardPanelUnconnected extends PureComponent { this.props.panel.isInView = v; }; - renderPanel(plugin: PanelPlugin) { - const { dashboard, panel, isViewing, isEditing, width, height, lazy } = this.props; + onPanelLoad = () => { + if (!this.props.plugin) { + this.props.initPanelState(this.props.panel); + } + }; + + render() { + const { dashboard, panel, isViewing, isEditing, width, height, lazy, plugin } = this.props; const renderPanelChrome = (isInView: boolean) => - plugin.angularPanelCtrl ? ( + plugin && + (plugin.angularPanelCtrl ? ( { height={height} onInstanceStateChange={this.onInstanceStateChange} /> - ); + )); return lazy ? ( - + {({ isInView }) => renderPanelChrome(isInView)} ) : ( renderPanelChrome(true) ); } - - render() { - const { plugin } = this.props; - - // If we have not loaded plugin exports yet, wait - if (!plugin) { - return null; - } - - return this.renderPanel(plugin); - } } export const DashboardPanel = connector(DashboardPanelUnconnected); From 8b4b57a6c6476d45a721610aa69635935cc47b16 Mon Sep 17 00:00:00 2001 From: Ashley Harrison Date: Wed, 20 Apr 2022 11:05:37 +0100 Subject: [PATCH 024/120] Don't set autofocus on logarithmic base select (#47927) --- packages/grafana-ui/src/options/builder/axis.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/grafana-ui/src/options/builder/axis.tsx b/packages/grafana-ui/src/options/builder/axis.tsx index 17ea669656e..5a65beceaef 100644 --- a/packages/grafana-ui/src/options/builder/axis.tsx +++ b/packages/grafana-ui/src/options/builder/axis.tsx @@ -143,7 +143,6 @@ const ScaleDistributionEditor: React.FC Date: Wed, 20 Apr 2022 13:33:59 +0200 Subject: [PATCH 025/120] Prometheus: Remove running of query on raw query toggle (#47938) --- .../querybuilder/components/PromQueryEditorSelector.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryEditorSelector.tsx b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryEditorSelector.tsx index 9bd94e3761d..e58615f536d 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryEditorSelector.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryEditorSelector.tsx @@ -46,7 +46,6 @@ export const PromQueryEditorSelector = React.memo((props) const onQueryPreviewChange = (event: SyntheticEvent) => { const isEnabled = event.currentTarget.checked; onChange({ ...query, rawQuery: isEnabled }); - onRunQuery(); }; const onChangeInternal = (query: PromQuery) => { From e8fc6637ec900ea468d93edca7055050d7d0bba5 Mon Sep 17 00:00:00 2001 From: Ashley Harrison Date: Wed, 20 Apr 2022 12:47:50 +0100 Subject: [PATCH 026/120] Wrap individual meta items in zIndex: 0 (#47935) --- .../grafana-ui/src/components/Card/Card.tsx | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/packages/grafana-ui/src/components/Card/Card.tsx b/packages/grafana-ui/src/components/Card/Card.tsx index 996339811c8..427a82ddac0 100644 --- a/packages/grafana-ui/src/components/Card/Card.tsx +++ b/packages/grafana-ui/src/components/Card/Card.tsx @@ -232,12 +232,17 @@ const Meta = memo(({ children, className, separator = '|' }: ChildProps & { sepa const styles = useStyles2(getMetaStyles); let meta = children; + const filtered = React.Children.toArray(children).filter(Boolean); + if (!filtered.length) { + return null; + } + meta = filtered.map((element, i) => ( +
+ {element} +
+ )); // Join meta data elements by separator - if (Array.isArray(children) && separator) { - const filtered = React.Children.toArray(children).filter(Boolean); - if (!filtered.length) { - return null; - } + if (filtered.length > 1 && separator) { meta = filtered.reduce((prev, curr, i) => [ prev, @@ -261,6 +266,9 @@ const getMetaStyles = (theme: GrafanaTheme2) => ({ margin: theme.spacing(0.5, 0, 0), lineHeight: theme.typography.bodySmall.lineHeight, overflowWrap: 'anywhere', + }), + metadataItem: css({ + // Needed to allow for clickable children in metadata zIndex: 0, }), separator: css({ From 79c06fdddc9ddfa03ee17ef83165e1efef09e6ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Farkas?= Date: Wed, 20 Apr 2022 13:52:15 +0200 Subject: [PATCH 027/120] Loki: add backend-forward mode to queries, update log-row-context (#47726) * loki: add helper function to sort dataframe by time * loki: add direction-attribute to queries * loki: make log-row-context code backward-compatible * better comment Co-authored-by: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com> * fixed test * simplified code Co-authored-by: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com> --- pkg/tsdb/loki/api.go | 2 + pkg/tsdb/loki/framing_test.go | 8 +- pkg/tsdb/loki/loki.go | 1 + pkg/tsdb/loki/parse_query.go | 21 +++ pkg/tsdb/loki/types.go | 8 ++ .../datasource/loki/datasource.test.ts | 10 +- .../app/plugins/datasource/loki/datasource.ts | 120 +++++++++++------- .../loki/result_transformer.test.ts | 4 +- .../datasource/loki/result_transformer.ts | 20 +-- .../datasource/loki/sortDataFrame.test.ts | 52 ++++++++ .../plugins/datasource/loki/sortDataFrame.ts | 70 ++++++++++ public/app/plugins/datasource/loki/types.ts | 6 + 12 files changed, 250 insertions(+), 72 deletions(-) create mode 100644 public/app/plugins/datasource/loki/sortDataFrame.test.ts create mode 100644 public/app/plugins/datasource/loki/sortDataFrame.ts diff --git a/pkg/tsdb/loki/api.go b/pkg/tsdb/loki/api.go index 08e3b1eb8c5..87e340dfc8c 100644 --- a/pkg/tsdb/loki/api.go +++ b/pkg/tsdb/loki/api.go @@ -29,6 +29,8 @@ func makeRequest(ctx context.Context, lokiDsUrl string, query lokiQuery) (*http. qs := url.Values{} qs.Set("query", query.Expr) + qs.Set("direction", string(query.Direction)) + // MaxLines defaults to zero when not received, // and Loki does not like limit=0, even when it is not needed // (for example for metric queries), so we diff --git a/pkg/tsdb/loki/framing_test.go b/pkg/tsdb/loki/framing_test.go index 696cc5d3fb6..8525a7f0673 100644 --- a/pkg/tsdb/loki/framing_test.go +++ b/pkg/tsdb/loki/framing_test.go @@ -22,9 +22,9 @@ import ( // but i wanted to test for all of them, to be sure. func TestSuccessResponse(t *testing.T) { - matrixQuery := lokiQuery{Expr: "up(ALERTS)", Step: time.Second * 42, QueryType: QueryTypeRange} - vectorQuery := lokiQuery{Expr: "query1", QueryType: QueryTypeInstant} - streamsQuery := lokiQuery{Expr: "query1", QueryType: QueryTypeRange} + matrixQuery := lokiQuery{Expr: "up(ALERTS)", Step: time.Second * 42, QueryType: QueryTypeRange, Direction: DirectionBackward} + vectorQuery := lokiQuery{Expr: "query1", QueryType: QueryTypeInstant, Direction: DirectionBackward} + streamsQuery := lokiQuery{Expr: "query1", QueryType: QueryTypeRange, Direction: DirectionBackward} tt := []struct { name string @@ -119,7 +119,7 @@ func TestErrorResponse(t *testing.T) { for _, test := range tt { t.Run(test.name, func(t *testing.T) { - frames, err := runQuery(context.Background(), makeMockedAPI(400, test.contentType, test.body), &lokiQuery{QueryType: QueryTypeRange}) + frames, err := runQuery(context.Background(), makeMockedAPI(400, test.contentType, test.body), &lokiQuery{QueryType: QueryTypeRange, Direction: DirectionBackward}) require.Len(t, frames, 0) require.Error(t, err) diff --git a/pkg/tsdb/loki/loki.go b/pkg/tsdb/loki/loki.go index 59cc30eb7e1..e2112d33623 100644 --- a/pkg/tsdb/loki/loki.go +++ b/pkg/tsdb/loki/loki.go @@ -53,6 +53,7 @@ type datasourceInfo struct { type QueryJSONModel struct { QueryType string `json:"queryType"` Expr string `json:"expr"` + Direction string `json:"direction"` LegendFormat string `json:"legendFormat"` Interval string `json:"interval"` IntervalMS int `json:"intervalMS"` diff --git a/pkg/tsdb/loki/parse_query.go b/pkg/tsdb/loki/parse_query.go index d62802e5f06..80f0c0cbc27 100644 --- a/pkg/tsdb/loki/parse_query.go +++ b/pkg/tsdb/loki/parse_query.go @@ -67,6 +67,21 @@ func parseQueryType(jsonValue string) (QueryType, error) { } } +func parseDirection(jsonValue string) (Direction, error) { + switch jsonValue { + case "backward": + return DirectionBackward, nil + case "forward": + return DirectionForward, nil + case "": + // there are older queries stored in alerting that did not have queryDirection, + // we default to "backward" + return DirectionBackward, nil + default: + return DirectionBackward, fmt.Errorf("invalid queryDirection: %s", jsonValue) + } +} + func parseQuery(queryContext *backend.QueryDataRequest) ([]*lokiQuery, error) { qs := []*lokiQuery{} for _, query := range queryContext.Queries { @@ -95,9 +110,15 @@ func parseQuery(queryContext *backend.QueryDataRequest) ([]*lokiQuery, error) { return nil, err } + direction, err := parseDirection(model.Direction) + if err != nil { + return nil, err + } + qs = append(qs, &lokiQuery{ Expr: expr, QueryType: queryType, + Direction: direction, Step: step, MaxLines: model.MaxLines, LegendFormat: model.LegendFormat, diff --git a/pkg/tsdb/loki/types.go b/pkg/tsdb/loki/types.go index 309d2ef8246..9d5fcead26d 100644 --- a/pkg/tsdb/loki/types.go +++ b/pkg/tsdb/loki/types.go @@ -9,9 +9,17 @@ const ( QueryTypeInstant QueryType = "instant" ) +type Direction string + +const ( + DirectionBackward Direction = "backward" + DirectionForward Direction = "forward" +) + type lokiQuery struct { Expr string QueryType QueryType + Direction Direction Step time.Duration MaxLines int LegendFormat string diff --git a/public/app/plugins/datasource/loki/datasource.test.ts b/public/app/plugins/datasource/loki/datasource.test.ts index e7f84a0a51f..38ebf6cedfd 100644 --- a/public/app/plugins/datasource/loki/datasource.test.ts +++ b/public/app/plugins/datasource/loki/datasource.test.ts @@ -943,9 +943,9 @@ describe('LokiDatasource', () => { dataFrame: new MutableDataFrame({ fields: [ { - name: 'tsNs', - type: FieldType.string, - values: ['0'], + name: 'ts', + type: FieldType.time, + values: [0], }, ], }), @@ -957,8 +957,8 @@ describe('LokiDatasource', () => { jest.spyOn(ds.languageProvider, 'getLabelKeys').mockImplementation(() => ['bar']); const contextQuery = ds.prepareLogRowContextQueryTarget(row, 10, 'BACKWARD'); - expect(contextQuery.expr).toContain('baz'); - expect(contextQuery.expr).not.toContain('uniqueParsedLabel'); + expect(contextQuery.query.expr).toContain('baz'); + expect(contextQuery.query.expr).not.toContain('uniqueParsedLabel'); }); }); diff --git a/public/app/plugins/datasource/loki/datasource.ts b/public/app/plugins/datasource/loki/datasource.ts index 9de4a813dbc..476a1b95a17 100644 --- a/public/app/plugins/datasource/loki/datasource.ts +++ b/public/app/plugins/datasource/loki/datasource.ts @@ -33,24 +33,21 @@ import { ScopedVars, TimeRange, rangeUtil, + toUtc, } from '@grafana/data'; import { BackendSrvRequest, FetchError, getBackendSrv, config, DataSourceWithBackend } from '@grafana/runtime'; import { getTemplateSrv, TemplateSrv } from 'app/features/templating/template_srv'; import { addLabelToQuery } from './add_label_to_query'; import { getTimeSrv, TimeSrv } from 'app/features/dashboard/services/TimeSrv'; import { convertToWebSocketUrl } from 'app/core/utils/explore'; -import { - lokiResultsToTableModel, - lokiStreamsToDataFrames, - lokiStreamsToRawDataFrame, - processRangeQueryResponse, -} from './result_transformer'; +import { lokiResultsToTableModel, lokiStreamsToDataFrames, processRangeQueryResponse } from './result_transformer'; import { transformBackendResult } from './backendResultTransformer'; import { addParsedLabelToQuery, getNormalizedLokiQuery, queryHasPipeParser } from './query_utils'; import { LokiOptions, LokiQuery, + LokiQueryDirection, LokiQueryType, LokiRangeQueryRequest, LokiResultType, @@ -65,6 +62,7 @@ import { DEFAULT_RESOLUTION } from './components/LokiOptionFields'; import { queryLogsVolume } from 'app/core/logs_model'; import { doLokiChannelStream } from './streaming'; import { renderLegendFormat } from '../prometheus/legend'; +import { sortDataFrameByTime } from './sortDataFrame'; export type RangeQueryOptions = DataQueryRequest | AnnotationQueryRequest; export const DEFAULT_MAX_LINES = 1000; @@ -75,7 +73,6 @@ const RANGE_QUERY_ENDPOINT = `${LOKI_ENDPOINT}/query_range`; const INSTANT_QUERY_ENDPOINT = `${LOKI_ENDPOINT}/query`; const DEFAULT_QUERY_PARAMS: Partial = { - direction: 'BACKWARD', limit: DEFAULT_MAX_LINES, query: '', }; @@ -252,6 +249,7 @@ export class LokiDatasource query: target.expr, time: `${timeNs + (1e9 - (timeNs % 1e9))}`, limit: Math.min(queryLimit || Infinity, this.maxLines), + direction: target.direction === LokiQueryDirection.Forward ? 'FORWARD' : 'BACKWARD', }; /** Used only for results of metrics instant queries */ @@ -311,6 +309,7 @@ export class LokiDatasource ...range, query, limit, + direction: target.direction === LokiQueryDirection.Forward ? 'FORWARD' : 'BACKWARD', }; } @@ -554,15 +553,29 @@ export class LokiDatasource } getLogRowContext = (row: LogRowModel, options?: RowContextOptions): Promise<{ data: DataFrame[] }> => { - const target = this.prepareLogRowContextQueryTarget( - row, - (options && options.limit) || 10, - (options && options.direction) || 'BACKWARD' - ); + const direction = (options && options.direction) || 'BACKWARD'; + const limit = (options && options.limit) || 10; + const { query, range } = this.prepareLogRowContextQueryTarget(row, limit, direction); + + const sortResults = (result: DataQueryResponse): DataQueryResponse => { + return { + ...result, + data: result.data.map((frame: DataFrame) => { + const timestampFieldIndex = frame.fields.findIndex((field) => field.type === FieldType.time); + if (timestampFieldIndex === -1) { + return frame; + } + + return sortDataFrameByTime(frame, 'DESCENDING'); + }), + }; + }; + + // this can only be called from explore currently + const app = CoreApp.Explore; - const reverse = options && options.direction === 'FORWARD'; return lastValueFrom( - this._request(RANGE_QUERY_ENDPOINT, target).pipe( + this.query(makeRequest(query, range, app, `log-row-context-query-${direction}`)).pipe( catchError((err) => { const error: DataQueryError = { message: 'Error during context query. Please check JS console logs.', @@ -571,18 +584,18 @@ export class LokiDatasource }; throw error; }), - switchMap((res) => - of({ - data: res.data ? [lokiStreamsToRawDataFrame(res.data.data.result, reverse)] : [], - }) - ) + switchMap((res) => of(sortResults(res))) ) ); }; - prepareLogRowContextQueryTarget = (row: LogRowModel, limit: number, direction: 'BACKWARD' | 'FORWARD') => { + prepareLogRowContextQueryTarget = ( + row: LogRowModel, + limit: number, + direction: 'BACKWARD' | 'FORWARD' + ): { query: LokiQuery; range: TimeRange } => { const labels = this.languageProvider.getLabelKeys(); - const query = Object.keys(row.labels) + const expr = Object.keys(row.labels) .map((label: string) => { if (labels.includes(label)) { // escape backslashes in label as users can't escape them by themselves @@ -595,36 +608,49 @@ export class LokiDatasource .join(','); const contextTimeBuffer = 2 * 60 * 60 * 1000; // 2h buffer - const commonTargetOptions = { - limit, - query: `{${query}}`, - expr: `{${query}}`, - direction, + + const queryDirection = direction === 'FORWARD' ? LokiQueryDirection.Forward : LokiQueryDirection.Backward; + + const query: LokiQuery = { + expr: `{${expr}}`, + queryType: LokiQueryType.Range, + refId: '', + maxLines: limit, + direction: queryDirection, }; const fieldCache = new FieldCache(row.dataFrame); - const nsField = fieldCache.getFieldByName('tsNs')!; - const nsTimestamp = nsField.values.get(row.rowIndex); - - if (direction === 'BACKWARD') { - return { - ...commonTargetOptions, - // convert to ns, we loose some precision here but it is not that important at the far points of the context - start: row.timeEpochMs - contextTimeBuffer + '000000', - end: nsTimestamp, - direction, - }; - } else { - return { - ...commonTargetOptions, - // start param in Loki API is inclusive so we'll have to filter out the row that this request is based from - // and any other that were logged in the same ns but before the row. Right now these rows will be lost - // because the are before but came it he response that should return only rows after. - start: nsTimestamp, - // convert to ns, we loose some precision here but it is not that important at the far points of the context - end: row.timeEpochMs + contextTimeBuffer + '000000', - }; + const tsField = fieldCache.getFirstFieldOfType(FieldType.time); + if (tsField === undefined) { + throw new Error('loki: dataframe missing time-field, should never happen'); } + const tsValue = tsField.values.get(row.rowIndex); + const timestamp = toUtc(tsValue); + + const range = + queryDirection === LokiQueryDirection.Forward + ? { + // start param in Loki API is inclusive so we'll have to filter out the row that this request is based from + // and any other that were logged in the same ns but before the row. Right now these rows will be lost + // because the are before but came it he response that should return only rows after. + from: timestamp, + // convert to ns, we loose some precision here but it is not that important at the far points of the context + to: toUtc(row.timeEpochMs + contextTimeBuffer), + } + : { + // convert to ns, we loose some precision here but it is not that important at the far points of the context + from: toUtc(row.timeEpochMs - contextTimeBuffer), + to: timestamp, + }; + + return { + query, + range: { + from: range.from, + to: range.to, + raw: range, + }, + }; }; testDatasource() { diff --git a/public/app/plugins/datasource/loki/result_transformer.test.ts b/public/app/plugins/datasource/loki/result_transformer.test.ts index db35da689a6..c43d3f99b0d 100644 --- a/public/app/plugins/datasource/loki/result_transformer.test.ts +++ b/public/app/plugins/datasource/loki/result_transformer.test.ts @@ -112,7 +112,7 @@ describe('loki result transformer', () => { }); it('should append refId to the unique ids if refId is provided', () => { - const data = ResultTransformer.lokiStreamsToRawDataFrame(streamResult, false, 'B'); + const data = ResultTransformer.lokiStreamsToRawDataFrame(streamResult, 'B'); expect(data.fields[4].values.get(0)).toEqual('4b79cb43-81ce-52f7-b1e9-a207fff144dc_B'); expect(data.fields[4].values.get(1)).toEqual('73d144f6-57f2-5a45-a49c-eb998e2006b1_B'); }); @@ -121,7 +121,7 @@ describe('loki result transformer', () => { describe('lokiStreamsToDataFrames', () => { it('should enhance data frames', () => { jest.spyOn(ResultTransformer, 'enhanceDataFrame'); - const dataFrames = ResultTransformer.lokiStreamsToDataFrames(lokiResponse, { refId: 'B' }, 500, { + const dataFrames = ResultTransformer.lokiStreamsToDataFrames(lokiResponse, { refId: 'B', expr: '' }, 500, { derivedFields: [ { matcherRegex: 'trace=(w+)', diff --git a/public/app/plugins/datasource/loki/result_transformer.ts b/public/app/plugins/datasource/loki/result_transformer.ts index c71fdf9bc86..38df63a95f1 100644 --- a/public/app/plugins/datasource/loki/result_transformer.ts +++ b/public/app/plugins/datasource/loki/result_transformer.ts @@ -45,7 +45,7 @@ const UUID_NAMESPACE = '6ec946da-0f49-47a8-983a-1d76d17e7c92'; /** * Transforms LokiStreamResult structure into a dataFrame. Used when doing standard queries */ -export function lokiStreamsToRawDataFrame(streams: LokiStreamResult[], reverse?: boolean, refId?: string): DataFrame { +export function lokiStreamsToRawDataFrame(streams: LokiStreamResult[], refId?: string): DataFrame { const labels = new ArrayVector<{}>([]); const times = new ArrayVector([]); const timesNs = new ArrayVector([]); @@ -72,11 +72,11 @@ export function lokiStreamsToRawDataFrame(streams: LokiStreamResult[], reverse?: } } - return constructDataFrame(times, timesNs, lines, uids, labels, reverse, refId); + return constructDataFrame(times, timesNs, lines, uids, labels, refId); } /** - * Constructs dataFrame with supplied fields and other data. Also makes sure it is properly reversed if needed. + * Constructs dataFrame with supplied fields and other data. */ function constructDataFrame( times: ArrayVector, @@ -84,7 +84,6 @@ function constructDataFrame( lines: ArrayVector, uids: ArrayVector, labels: ArrayVector<{}>, - reverse?: boolean, refId?: string ) { const dataFrame = { @@ -99,12 +98,6 @@ function constructDataFrame( length: times.length, }; - if (reverse) { - const mutableDataFrame = new MutableDataFrame(dataFrame); - mutableDataFrame.reverse(); - return mutableDataFrame; - } - return dataFrame; } @@ -330,10 +323,9 @@ function lokiStatsToMetaStat(stats: LokiStats | undefined): QueryResultMetaStat[ export function lokiStreamsToDataFrames( response: LokiStreamResponse, - target: { refId: string; expr?: string }, + target: LokiQuery, limit: number, - config: LokiOptions, - reverse = false + config: LokiOptions ): DataFrame[] { const data = limit > 0 ? response.data.result : []; const stats: QueryResultMetaStat[] = lokiStatsToMetaStat(response.data.stats); @@ -350,7 +342,7 @@ export function lokiStreamsToDataFrames( preferredVisualisationType: 'logs', }; - const dataFrame = lokiStreamsToRawDataFrame(data, reverse, target.refId); + const dataFrame = lokiStreamsToRawDataFrame(data, target.refId); enhanceDataFrame(dataFrame, config); if (meta.custom && dataFrame.fields.some((f) => f.labels && Object.keys(f.labels).some((l) => l === '__error__'))) { diff --git a/public/app/plugins/datasource/loki/sortDataFrame.test.ts b/public/app/plugins/datasource/loki/sortDataFrame.test.ts new file mode 100644 index 00000000000..19b35cd7dc3 --- /dev/null +++ b/public/app/plugins/datasource/loki/sortDataFrame.test.ts @@ -0,0 +1,52 @@ +import { ArrayVector, DataFrame, FieldType } from '@grafana/data'; +import { sortDataFrameByTime } from './sortDataFrame'; + +const inputFrame: DataFrame = { + refId: 'A', + fields: [ + { + name: 'time', + type: FieldType.time, + config: {}, + values: new ArrayVector([1005, 1001, 1004, 1002, 1003]), + }, + { + name: 'value', + type: FieldType.string, + config: {}, + values: new ArrayVector(['line5', 'line1', 'line4', 'line2', 'line3']), + }, + { + name: 'tsNs', + type: FieldType.time, + config: {}, + values: new ArrayVector([`1005000000`, `1001000000`, `1004000000`, `1002000000`, `1003000000`]), + }, + ], + length: 5, +}; + +describe('loki sortDataFrame', () => { + it('sorts a dataframe ascending', () => { + const sortedFrame = sortDataFrameByTime(inputFrame, 'ASCENDING'); + expect(sortedFrame.length).toBe(5); + const timeValues = sortedFrame.fields[0].values.toArray(); + const lineValues = sortedFrame.fields[1].values.toArray(); + const tsNsValues = sortedFrame.fields[2].values.toArray(); + + expect(timeValues).toStrictEqual([1001, 1002, 1003, 1004, 1005]); + expect(lineValues).toStrictEqual(['line1', 'line2', 'line3', 'line4', 'line5']); + expect(tsNsValues).toStrictEqual([`1001000000`, `1002000000`, `1003000000`, `1004000000`, `1005000000`]); + }); + it('sorts a dataframe descending', () => { + const sortedFrame = sortDataFrameByTime(inputFrame, 'DESCENDING'); + expect(sortedFrame.length).toBe(5); + const timeValues = sortedFrame.fields[0].values.toArray(); + const lineValues = sortedFrame.fields[1].values.toArray(); + const tsNsValues = sortedFrame.fields[2].values.toArray(); + + expect(timeValues).toStrictEqual([1005, 1004, 1003, 1002, 1001]); + expect(lineValues).toStrictEqual(['line5', 'line4', 'line3', 'line2', 'line1']); + expect(tsNsValues).toStrictEqual([`1005000000`, `1004000000`, `1003000000`, `1002000000`, `1001000000`]); + }); +}); diff --git a/public/app/plugins/datasource/loki/sortDataFrame.ts b/public/app/plugins/datasource/loki/sortDataFrame.ts new file mode 100644 index 00000000000..c524de61160 --- /dev/null +++ b/public/app/plugins/datasource/loki/sortDataFrame.ts @@ -0,0 +1,70 @@ +import { DataFrame, Field, SortedVector } from '@grafana/data'; + +type SortDirection = 'ASCENDING' | 'DESCENDING'; + +// creates the `index` for the sorting. +// this is needed by the `SortedVector`. +// the index is an array of numbers, and it defines an order. +// at every slot in the index the values is the position of +// the sorted item. +// for example, an index of [3,1,2] means that +// in the dataframe, that has 3 rows, after sorting: +// - the third row will become the first +// - the first row will become the second +// - the second row will become the third +function makeIndex(field: Field, dir: SortDirection): number[] { + const fieldValues: string[] = field.values.toArray(); + + // we first build an array which is [0,1,2,3....] + const index = Array(fieldValues.length); + for (let i = 0; i < index.length; i++) { + index[i] = i; + } + + const isAsc = dir === 'ASCENDING'; + + index.sort((a: number, b: number): number => { + // we need to answer this question: + // in the field-used-for-sorting, how would we compare value-at-index-a to value-at-index-b? + const valA = fieldValues[a]; + const valB = fieldValues[b]; + if (valA < valB) { + return isAsc ? -1 : 1; + } + + if (valA > valB) { + return isAsc ? 1 : -1; + } + + return 0; + }); + + return index; +} + +// sort a dataframe that is in the Loki format ascending or descending, +// based on the nanosecond-timestamp +export function sortDataFrameByTime(frame: DataFrame, dir: SortDirection): DataFrame { + const { fields, ...rest } = frame; + + // we use the approach used in @grafana/data/sortDataframe. + // we cannot use it directly, because our tsNs field has a type=time, + // so we have to build the `index` manually. + + const tsNsField = fields.find((field) => field.name === 'tsNs'); + if (tsNsField === undefined) { + throw new Error('missing nanosecond-timestamp field. should never happen'); + } + + const index = makeIndex(tsNsField, dir); + + return { + ...rest, + fields: fields.map((field) => ({ + ...field, + values: new SortedVector(field.values, index), + })), + }; + + return frame; +} diff --git a/public/app/plugins/datasource/loki/types.ts b/public/app/plugins/datasource/loki/types.ts index 1563669632c..59d0456cddd 100644 --- a/public/app/plugins/datasource/loki/types.ts +++ b/public/app/plugins/datasource/loki/types.ts @@ -29,9 +29,15 @@ export enum LokiQueryType { Stream = 'stream', } +export enum LokiQueryDirection { + Backward = 'backward', + Forward = 'forward', +} + export interface LokiQuery extends DataQuery { queryType?: LokiQueryType; expr: string; + direction?: LokiQueryDirection; legendFormat?: string; maxLines?: number; resolution?: number; From 01c22ee366cb1ea2225da6bc14203d3084ea430a Mon Sep 17 00:00:00 2001 From: Kevin Yu Date: Wed, 20 Apr 2022 05:00:39 -0700 Subject: [PATCH 028/120] Azure Monitor: Migrate metrics queries to use a resource URI (#47696) * migrate old query to new query * remove new prefixed data fetchers * fix lint * add test cases for v7 and v8 query versions * add mock ids in test * add clarifying comment * add types for azure monitor api data fetchers * add additional comment to explain the types --- .../__mocks__/datasource.ts | 14 +- .../azure_monitor_datasource.test.ts | 129 +++++++------ .../azure_monitor/azure_monitor_datasource.ts | 102 +++------- .../azure_monitor/url_builder.test.ts | 180 ++++++++---------- .../azure_monitor/url_builder.ts | 61 +++--- .../MetricsQueryEditor.test.tsx | 2 +- .../MetricsQueryEditor/dataHooks.test.ts | 4 +- .../MetricsQueryEditor/dataHooks.ts | 17 +- .../MetricsQueryEditor.test.tsx | 2 +- .../NewMetricsQueryEditor/dataHooks.test.ts | 4 +- .../NewMetricsQueryEditor/dataHooks.ts | 6 +- .../datasource.ts | 43 ----- .../types/types.ts | 47 +++++ .../utils/migrateQuery.test.ts | 81 +++++++- .../utils/migrateQuery.ts | 31 ++- .../variables.test.ts | 20 +- .../variables.ts | 15 +- 17 files changed, 395 insertions(+), 363 deletions(-) diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/__mocks__/datasource.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/__mocks__/datasource.ts index 1793aa8a397..b8a37e18fc2 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/__mocks__/datasource.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/__mocks__/datasource.ts @@ -16,9 +16,9 @@ export default function createMockDatasource(overrides?: DeepPartial }, getSubscriptions: jest.fn().mockResolvedValueOnce([]), defaultSubscriptionId: 'subscriptionId', - newGetMetricNamespaces: jest.fn().mockResolvedValueOnce([]), - newGetMetricNames: jest.fn().mockResolvedValueOnce([]), - newGetMetricMetadata: jest.fn().mockResolvedValueOnce({ + getMetricNamespaces: jest.fn().mockResolvedValueOnce([]), + getMetricNames: jest.fn().mockResolvedValueOnce([]), + getMetricMetadata: jest.fn().mockResolvedValueOnce({ primaryAggType: 'Average', supportedAggTypes: ['Average', 'Maximum', 'Minimum'], supportedTimeGrains: [], @@ -31,14 +31,6 @@ export default function createMockDatasource(overrides?: DeepPartial getResourceGroups: jest.fn().mockResolvedValueOnce([]), getMetricDefinitions: jest.fn().mockResolvedValueOnce([]), getResourceNames: jest.fn().mockResolvedValueOnce([]), - getMetricNamespaces: jest.fn().mockResolvedValueOnce([]), - getMetricNames: jest.fn().mockResolvedValueOnce([]), - getMetricMetadata: jest.fn().mockResolvedValueOnce({ - primaryAggType: 'Average', - supportedAggTypes: ['Average', 'Maximum', 'Minimum'], - supportedTimeGrains: [], - dimensions: [], - }), azureLogAnalyticsDatasource: { getKustoSchema: () => Promise.resolve(), diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_datasource.test.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_datasource.test.ts index a6cbb496067..96e1baa2cd9 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_datasource.test.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_datasource.test.ts @@ -26,7 +26,7 @@ describe('AzureMonitorDatasource', () => { ctx.instanceSettings = { name: 'test', url: 'http://azuremonitor.com', - jsonData: { subscriptionId: '9935389e-9122-4ef9-95f9-1513dd24753f', cloudName: 'azuremonitor' }, + jsonData: { subscriptionId: 'mock-subscription-id', cloudName: 'azuremonitor' }, } as unknown as DataSourceInstanceSettings; ctx.ds = new AzureMonitorDatasource(ctx.instanceSettings); }); @@ -76,11 +76,11 @@ describe('AzureMonitorDatasource', () => { }); }); - describe('When performing newGetMetricNamespaces', () => { + describe('When performing getMetricNamespaces', () => { const response = { value: [ { - id: '/subscriptions/9935389e-9122-4ef9-95f9-1513dd24753f/resourceGroups/nodeapp/providers/microsoft.insights/components/resource1/providers/microsoft.insights/metricNamespaces/Azure.ApplicationInsights', + id: '/subscriptions/mock-subscription-id/resourceGroups/nodeapp/providers/microsoft.insights/components/resource1/providers/microsoft.insights/metricNamespaces/Azure.ApplicationInsights', name: 'Azure.ApplicationInsights', type: 'Microsoft.Insights/metricNamespaces', classification: 'Custom', @@ -89,7 +89,7 @@ describe('AzureMonitorDatasource', () => { }, }, { - id: '/subscriptions/9935389e-9122-4ef9-95f9-1513dd24753f/resourceGroups/nodeapp/providers/microsoft.insights/components/resource1/providers/microsoft.insights/metricNamespaces/microsoft.insights-components', + id: '/subscriptions/mock-subscription-id/resourceGroups/nodeapp/providers/microsoft.insights/components/resource1/providers/microsoft.insights/metricNamespaces/microsoft.insights-components', name: 'microsoft.insights-components', type: 'Microsoft.Insights/metricNamespaces', classification: 'Platform', @@ -102,7 +102,7 @@ describe('AzureMonitorDatasource', () => { beforeEach(() => { ctx.ds.azureMonitorDatasource.getResource = jest.fn().mockImplementation((path: string) => { - const basePath = 'azuremonitor/subscriptions/9935389e-9122-4ef9-95f9-1513dd24753f/resourceGroups/nodeapp'; + const basePath = 'azuremonitor/subscriptions/mock-subscription-id/resourceGroups/nodeapp'; const expected = basePath + '/providers/microsoft.insights/components/resource1' + @@ -114,9 +114,10 @@ describe('AzureMonitorDatasource', () => { it('should return list of Metric Namspaces', () => { return ctx.ds.azureMonitorDatasource - .newGetMetricNamespaces( - '/subscriptions/9935389e-9122-4ef9-95f9-1513dd24753f/resourceGroups/nodeapp/providers/microsoft.insights/components/resource1' - ) + .getMetricNamespaces({ + resourceUri: + '/subscriptions/mock-subscription-id/resourceGroups/nodeapp/providers/microsoft.insights/components/resource1', + }) .then((results: Array<{ text: string; value: string }>) => { expect(results.length).toEqual(2); expect(results[0].text).toEqual('Azure.ApplicationInsights'); @@ -127,7 +128,7 @@ describe('AzureMonitorDatasource', () => { }); }); - describe('When performing newGetMetricNames', () => { + describe('When performing getMetricNames', () => { const response = { value: [ { @@ -165,7 +166,7 @@ describe('AzureMonitorDatasource', () => { beforeEach(() => { ctx.ds.azureMonitorDatasource.getResource = jest.fn().mockImplementation((path: string) => { - const basePath = 'azuremonitor/subscriptions/9935389e-9122-4ef9-95f9-1513dd24753f/resourceGroups/nodeapp'; + const basePath = 'azuremonitor/subscriptions/mock-subscription-id/resourceGroups/nodeapp'; const expected = basePath + '/providers/microsoft.insights/components/resource1' + @@ -177,10 +178,11 @@ describe('AzureMonitorDatasource', () => { it('should return list of Metric Definitions', () => { return ctx.ds.azureMonitorDatasource - .newGetMetricNames( - '/subscriptions/9935389e-9122-4ef9-95f9-1513dd24753f/resourceGroups/nodeapp/providers/microsoft.insights/components/resource1', - 'default' - ) + .getMetricNames({ + resourceUri: + '/subscriptions/mock-subscription-id/resourceGroups/nodeapp/providers/microsoft.insights/components/resource1', + metricNamespace: 'default', + }) .then((results: Array<{ text: string; value: string }>) => { expect(results.length).toEqual(2); expect(results[0].text).toEqual('Used capacity'); @@ -191,7 +193,7 @@ describe('AzureMonitorDatasource', () => { }); }); - describe('When performing newGetMetricMetadata', () => { + describe('When performing getMetricMetadata', () => { const response = { value: [ { @@ -229,7 +231,7 @@ describe('AzureMonitorDatasource', () => { beforeEach(() => { ctx.ds.azureMonitorDatasource.getResource = jest.fn().mockImplementation((path: string) => { - const basePath = 'azuremonitor/subscriptions/9935389e-9122-4ef9-95f9-1513dd24753f/resourceGroups/nodeapp'; + const basePath = 'azuremonitor/subscriptions/mock-subscription-id/resourceGroups/nodeapp'; const expected = basePath + '/providers/microsoft.insights/components/resource1' + @@ -241,11 +243,12 @@ describe('AzureMonitorDatasource', () => { it('should return Aggregation metadata for a Metric', () => { return ctx.ds.azureMonitorDatasource - .newGetMetricMetadata( - '/subscriptions/9935389e-9122-4ef9-95f9-1513dd24753f/resourceGroups/nodeapp/providers/microsoft.insights/components/resource1', - 'default', - 'UsedCapacity' - ) + .getMetricMetadata({ + resourceUri: + '/subscriptions/mock-subscription-id/resourceGroups/nodeapp/providers/microsoft.insights/components/resource1', + metricNamespace: 'default', + metricName: 'UsedCapacity', + }) .then((results) => { expect(results.primaryAggType).toEqual('Total'); expect(results.supportedAggTypes.length).toEqual(6); @@ -342,7 +345,7 @@ describe('AzureMonitorDatasource', () => { beforeEach(() => { ctx.ds.azureMonitorDatasource.getResource = jest.fn().mockImplementation((path: string) => { - const basePath = 'azuremonitor/subscriptions/9935389e-9122-4ef9-95f9-1513dd24753f/resourceGroups'; + const basePath = 'azuremonitor/subscriptions/mock-subscription-id/resourceGroups'; expect(path).toBe(basePath + '/nodesapp/resources?api-version=2021-04-01'); return Promise.resolve(response); }); @@ -350,7 +353,7 @@ describe('AzureMonitorDatasource', () => { it('should return list of Metric Definitions with no duplicates and no unsupported namespaces', () => { return ctx.ds - .getMetricDefinitions('9935389e-9122-4ef9-95f9-1513dd24753f', 'nodesapp') + .getMetricDefinitions('mock-subscription-id', 'nodesapp') .then((results: Array<{ text: string; value: string }>) => { expect(results.length).toEqual(7); expect(results[0].text).toEqual('Network interface'); @@ -372,12 +375,12 @@ describe('AzureMonitorDatasource', () => { }); describe('When performing getResourceNames', () => { - let subscription = '9935389e-9122-4ef9-95f9-1513dd24753f'; + let subscription = 'mock-subscription-id'; let resourceGroup = 'nodeapp'; let metricDefinition = 'microsoft.insights/components'; beforeEach(() => { - subscription = '9935389e-9122-4ef9-95f9-1513dd24753f'; + subscription = 'mock-subscription-id'; resourceGroup = 'nodeapp'; metricDefinition = 'microsoft.insights/components'; }); @@ -552,7 +555,7 @@ describe('AzureMonitorDatasource', () => { beforeEach(() => { ctx.ds.azureMonitorDatasource.getResource = jest.fn().mockImplementation((path: string) => { - const basePath = 'azuremonitor/subscriptions/9935389e-9122-4ef9-95f9-1513dd24753f/resourceGroups/nodeapp'; + const basePath = 'azuremonitor/subscriptions/mock-subscription-id/resourceGroups/nodeapp'; const expected = basePath + '/providers/microsoft.insights/components/resource1' + @@ -563,14 +566,14 @@ describe('AzureMonitorDatasource', () => { }); it('should return list of Metric Definitions', () => { - return ctx.ds - .getMetricNames( - '9935389e-9122-4ef9-95f9-1513dd24753f', - 'nodeapp', - 'microsoft.insights/components', - 'resource1', - 'default' - ) + return ctx.ds.azureMonitorDatasource + .getMetricNames({ + subscription: 'mock-subscription-id', + resourceGroup: 'nodeapp', + metricDefinition: 'microsoft.insights/components', + resourceName: 'resource1', + metricNamespace: 'default', + }) .then((results: Array<{ text: string; value: string }>) => { expect(results.length).toEqual(2); expect(results[0].text).toEqual('Used capacity'); @@ -619,7 +622,7 @@ describe('AzureMonitorDatasource', () => { beforeEach(() => { ctx.ds.azureMonitorDatasource.getResource = jest.fn().mockImplementation((path: string) => { - const basePath = 'azuremonitor/subscriptions/9935389e-9122-4ef9-95f9-1513dd24753f/resourceGroups/nodeapp'; + const basePath = 'azuremonitor/subscriptions/mock-subscription-id/resourceGroups/nodeapp'; const expected = basePath + '/providers/microsoft.insights/components/resource1' + @@ -630,15 +633,15 @@ describe('AzureMonitorDatasource', () => { }); it('should return Aggregation metadata for a Metric', () => { - return ctx.ds - .getMetricMetadata( - '9935389e-9122-4ef9-95f9-1513dd24753f', - 'nodeapp', - 'microsoft.insights/components', - 'resource1', - 'default', - 'UsedCapacity' - ) + return ctx.ds.azureMonitorDatasource + .getMetricMetadata({ + subscription: 'mock-subscription-id', + resourceGroup: 'nodeapp', + metricDefinition: 'microsoft.insights/components', + resourceName: 'resource1', + metricNamespace: 'default', + metricName: 'UsedCapacity', + }) .then((results) => { expect(results.primaryAggType).toEqual('Total'); expect(results.supportedAggTypes.length).toEqual(6); @@ -688,7 +691,7 @@ describe('AzureMonitorDatasource', () => { beforeEach(() => { ctx.ds.azureMonitorDatasource.getResource = jest.fn().mockImplementation((path: string) => { - const basePath = 'azuremonitor/subscriptions/9935389e-9122-4ef9-95f9-1513dd24753f/resourceGroups/nodeapp'; + const basePath = 'azuremonitor/subscriptions/mock-subscription-id/resourceGroups/nodeapp'; const expected = basePath + '/providers/microsoft.insights/components/resource1' + @@ -699,15 +702,15 @@ describe('AzureMonitorDatasource', () => { }); it('should return dimensions for a Metric that has dimensions', () => { - return ctx.ds - .getMetricMetadata( - '9935389e-9122-4ef9-95f9-1513dd24753f', - 'nodeapp', - 'microsoft.insights/components', - 'resource1', - 'default', - 'Transactions' - ) + return ctx.ds.azureMonitorDatasource + .getMetricMetadata({ + subscription: 'mock-subscription-id', + resourceGroup: 'nodeapp', + metricDefinition: 'microsoft.insights/components', + resourceName: 'resource1', + metricNamespace: 'default', + metricName: 'Transactions', + }) .then((results: any) => { expect(results.dimensions).toMatchInlineSnapshot(` Array [ @@ -759,15 +762,15 @@ describe('AzureMonitorDatasource', () => { }); it('should return an empty array for a Metric that does not have dimensions', () => { - return ctx.ds - .getMetricMetadata( - '9935389e-9122-4ef9-95f9-1513dd24753f', - 'nodeapp', - 'microsoft.insights/components', - 'resource1', - 'default', - 'FreeCapacity' - ) + return ctx.ds.azureMonitorDatasource + .getMetricMetadata({ + subscription: 'mock-subscription-id', + resourceGroup: 'nodeapp', + metricDefinition: 'microsoft.insights/components', + resourceName: 'resource1', + metricNamespace: 'default', + metricName: 'FreeCapacity', + }) .then((results: any) => { expect(results.dimensions.length).toEqual(0); }); diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_datasource.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_datasource.ts index b302061d483..8e257114e0b 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_datasource.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_datasource.ts @@ -16,6 +16,9 @@ import { AzureMonitorResourceGroupsResponse, AzureQueryType, DatasourceValidationResult, + GetMetricNamespacesQuery, + GetMetricNamesQuery, + GetMetricMetadataQuery, } from '../types'; import { routeNames } from '../utils/common'; import ResponseParser from './response_parser'; @@ -236,102 +239,35 @@ export default class AzureMonitorDatasource extends DataSourceWithBackend { - return ResponseParser.parseResponseValues(result, 'name', 'properties.metricNamespaceName'); - }); - } - - newGetMetricNamespaces(resourceUri: string) { - const templateSrv = getTemplateSrv(); - const url = UrlBuilder.newBuildAzureMonitorGetMetricNamespacesUrl( - this.resourcePath, - templateSrv.replace(resourceUri), - this.apiPreviewVersion - ); - return this.getResource(url).then((result: AzureMonitorMetricNamespacesResponse) => { return ResponseParser.parseResponseValues(result, 'name', 'properties.metricNamespaceName'); }); } - getMetricNames( - subscriptionId: string, - resourceGroup: string, - metricDefinition: string, - resourceName: string, - metricNamespace: string - ) { + getMetricNames(query: GetMetricNamesQuery) { const url = UrlBuilder.buildAzureMonitorGetMetricNamesUrl( this.resourcePath, - subscriptionId, - resourceGroup, - metricDefinition, - resourceName, - metricNamespace, - this.apiVersion + this.apiVersion, + this.replaceTemplateVariables(query) ); - - return this.getResource(url).then((result: any) => { - return ResponseParser.parseResponseValues(result, 'name.localizedValue', 'name.value'); - }); - } - - newGetMetricNames(resourceUri: string, metricNamespace: string) { - const templateSrv = getTemplateSrv(); - const url = UrlBuilder.newBuildAzureMonitorGetMetricNamesUrl( - this.resourcePath, - templateSrv.replace(resourceUri), - templateSrv.replace(metricNamespace), - this.apiVersion - ); - return this.getResource(url).then((result: AzureMonitorMetricNamesResponse) => { return ResponseParser.parseResponseValues(result, 'name.localizedValue', 'name.value'); }); } - getMetricMetadata( - subscriptionId: string, - resourceGroup: string, - metricDefinition: string, - resourceName: string, - metricNamespace: string, - metricName: string - ) { + getMetricMetadata(query: GetMetricMetadataQuery) { + const { metricName } = query; const url = UrlBuilder.buildAzureMonitorGetMetricNamesUrl( this.resourcePath, - subscriptionId, - resourceGroup, - metricDefinition, - resourceName, - metricNamespace, - this.apiVersion + this.apiVersion, + this.replaceTemplateVariables(query) ); - - return this.getResource(url).then((result: any) => { - return ResponseParser.parseMetadata(result, metricName); - }); - } - - newGetMetricMetadata(resourceUri: string, metricNamespace: string, metricName: string) { - const templateSrv = getTemplateSrv(); - const url = UrlBuilder.newBuildAzureMonitorGetMetricNamesUrl( - this.resourcePath, - templateSrv.replace(resourceUri), - templateSrv.replace(metricNamespace), - this.apiVersion - ); - return this.getResource(url).then((result: AzureMonitorMetricsMetadataResponse) => { return ResponseParser.parseMetadata(result, metricName); }); @@ -398,4 +334,16 @@ export default class AzureMonitorDatasource extends DataSourceWithBackend 0; } + + private replaceTemplateVariables(query: T) { + const templateSrv = getTemplateSrv(); + + const workingQuery: { [K in keyof T]: string } = { ...query }; + const keys = Object.keys(query) as Array; + keys.forEach((key) => { + workingQuery[key] = templateSrv.replace(workingQuery[key]); + }); + + return workingQuery; + } } diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/url_builder.test.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/url_builder.test.ts index 4aa8b984548..ed61968eed7 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/url_builder.test.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/url_builder.test.ts @@ -1,13 +1,19 @@ import UrlBuilder from './url_builder'; describe('AzureMonitorUrlBuilder', () => { + describe('buildResourceUri', () => { + it('builds a resource uri when the required properties are provided', () => { + expect(UrlBuilder.buildResourceUri('sub', 'group', 'Microsoft.NetApp/netAppAccounts', 'name')).toEqual( + '/subscriptions/sub/resourceGroups/group/providers/Microsoft.NetApp/netAppAccounts/name' + ); + }); + }); + describe('when a resource uri is provided', () => { it('builds a getMetricNamesnamespace url', () => { - const url = UrlBuilder.newBuildAzureMonitorGetMetricNamespacesUrl( - '', - '/subscriptions/sub/resource-uri/resource', - '2017-05-01-preview' - ); + const url = UrlBuilder.buildAzureMonitorGetMetricNamespacesUrl('', '2017-05-01-preview', { + resourceUri: '/subscriptions/sub/resource-uri/resource', + }); expect(url).toBe( '/subscriptions/sub/resource-uri/resource/providers/microsoft.insights/metricNamespaces?api-version=2017-05-01-preview' ); @@ -16,12 +22,10 @@ describe('AzureMonitorUrlBuilder', () => { describe('when a resource uri and metric namespace is provided', () => { it('builds a getMetricNames url', () => { - const url = UrlBuilder.newBuildAzureMonitorGetMetricNamesUrl( - '', - '/subscriptions/sub/resource-uri/resource', - 'Microsoft.Sql/servers', - '2017-05-01-preview' - ); + const url = UrlBuilder.buildAzureMonitorGetMetricNamesUrl('', '2017-05-01-preview', { + resourceUri: '/subscriptions/sub/resource-uri/resource', + metricNamespace: 'Microsoft.Sql/servers', + }); expect(url).toBe( '/subscriptions/sub/resource-uri/resource/providers/microsoft.insights/metricdefinitions?api-version=2017-05-01-preview&metricnamespace=Microsoft.Sql%2Fservers' ); @@ -31,14 +35,12 @@ describe('AzureMonitorUrlBuilder', () => { describe('Legacy query object', () => { describe('when metric definition is Microsoft.NetApp/netAppAccounts/capacityPools/volumes', () => { it('should build the getMetricNamespaces url in the even longer format', () => { - const url = UrlBuilder.buildAzureMonitorGetMetricNamespacesUrl( - '', - 'sub1', - 'rg', - 'Microsoft.NetApp/netAppAccounts/capacityPools/volumes', - 'rn1/rn2/rn3', - '2017-05-01-preview' - ); + const url = UrlBuilder.buildAzureMonitorGetMetricNamespacesUrl('', '2017-05-01-preview', { + subscription: 'sub1', + resourceGroup: 'rg', + metricDefinition: 'Microsoft.NetApp/netAppAccounts/capacityPools/volumes', + resourceName: 'rn1/rn2/rn3', + }); expect(url).toBe( '/subscriptions/sub1/resourceGroups/rg/providers/Microsoft.NetApp/netAppAccounts/rn1/capacityPools/rn2/volumes/rn3/' + 'providers/microsoft.insights/metricNamespaces?api-version=2017-05-01-preview' @@ -48,14 +50,12 @@ describe('AzureMonitorUrlBuilder', () => { describe('when metric definition is Microsoft.Sql/servers/databases', () => { it('should build the getMetricNamespaces url in the longer format', () => { - const url = UrlBuilder.buildAzureMonitorGetMetricNamespacesUrl( - '', - 'sub1', - 'rg', - 'Microsoft.Sql/servers/databases', - 'rn1/rn2', - '2017-05-01-preview' - ); + const url = UrlBuilder.buildAzureMonitorGetMetricNamespacesUrl('', '2017-05-01-preview', { + subscription: 'sub1', + resourceGroup: 'rg', + metricDefinition: 'Microsoft.Sql/servers/databases', + resourceName: 'rn1/rn2', + }); expect(url).toBe( '/subscriptions/sub1/resourceGroups/rg/providers/Microsoft.Sql/servers/rn1/databases/rn2/' + 'providers/microsoft.insights/metricNamespaces?api-version=2017-05-01-preview' @@ -65,14 +65,12 @@ describe('AzureMonitorUrlBuilder', () => { describe('when metric definition is Microsoft.Sql/servers', () => { it('should build the getMetricNamespaces url in the shorter format', () => { - const url = UrlBuilder.buildAzureMonitorGetMetricNamespacesUrl( - '', - 'sub1', - 'rg', - 'Microsoft.Sql/servers', - 'rn', - '2017-05-01-preview' - ); + const url = UrlBuilder.buildAzureMonitorGetMetricNamespacesUrl('', '2017-05-01-preview', { + subscription: 'sub1', + resourceGroup: 'rg', + metricDefinition: 'Microsoft.Sql/servers', + resourceName: 'rn', + }); expect(url).toBe( '/subscriptions/sub1/resourceGroups/rg/providers/Microsoft.Sql/servers/rn/' + 'providers/microsoft.insights/metricNamespaces?api-version=2017-05-01-preview' @@ -82,15 +80,13 @@ describe('AzureMonitorUrlBuilder', () => { describe('when metric definition is Microsoft.NetApp/netAppAccounts/capacityPools/volumes and the metricNamespace is default', () => { it('should build the getMetricNames url in the even longer format', () => { - const url = UrlBuilder.buildAzureMonitorGetMetricNamesUrl( - '', - 'sub1', - 'rg', - 'Microsoft.NetApp/netAppAccounts/capacityPools/volumes', - 'rn1/rn2/rn3', - 'default', - '2017-05-01-preview' - ); + const url = UrlBuilder.buildAzureMonitorGetMetricNamesUrl('', '2017-05-01-preview', { + subscription: 'sub1', + resourceGroup: 'rg', + metricDefinition: 'Microsoft.NetApp/netAppAccounts/capacityPools/volumes', + resourceName: 'rn1/rn2/rn3', + metricNamespace: 'default', + }); expect(url).toBe( '/subscriptions/sub1/resourceGroups/rg/providers/Microsoft.NetApp/netAppAccounts/rn1/capacityPools/rn2/volumes/rn3/' + 'providers/microsoft.insights/metricdefinitions?api-version=2017-05-01-preview&metricnamespace=default' @@ -100,15 +96,13 @@ describe('AzureMonitorUrlBuilder', () => { describe('when metric definition is Microsoft.Sql/servers/databases and the metricNamespace is default', () => { it('should build the getMetricNames url in the longer format', () => { - const url = UrlBuilder.buildAzureMonitorGetMetricNamesUrl( - '', - 'sub1', - 'rg', - 'Microsoft.Sql/servers/databases', - 'rn1/rn2', - 'default', - '2017-05-01-preview' - ); + const url = UrlBuilder.buildAzureMonitorGetMetricNamesUrl('', '2017-05-01-preview', { + subscription: 'sub1', + resourceGroup: 'rg', + metricDefinition: 'Microsoft.Sql/servers/databases', + resourceName: 'rn1/rn2', + metricNamespace: 'default', + }); expect(url).toBe( '/subscriptions/sub1/resourceGroups/rg/providers/Microsoft.Sql/servers/rn1/databases/rn2/' + 'providers/microsoft.insights/metricdefinitions?api-version=2017-05-01-preview&metricnamespace=default' @@ -118,15 +112,13 @@ describe('AzureMonitorUrlBuilder', () => { describe('when metric definition is Microsoft.Sql/servers and the metricNamespace is default', () => { it('should build the getMetricNames url in the shorter format', () => { - const url = UrlBuilder.buildAzureMonitorGetMetricNamesUrl( - '', - 'sub1', - 'rg', - 'Microsoft.Sql/servers', - 'rn', - 'default', - '2017-05-01-preview' - ); + const url = UrlBuilder.buildAzureMonitorGetMetricNamesUrl('', '2017-05-01-preview', { + subscription: 'sub1', + resourceGroup: 'rg', + metricDefinition: 'Microsoft.Sql/servers', + resourceName: 'rn', + metricNamespace: 'default', + }); expect(url).toBe( '/subscriptions/sub1/resourceGroups/rg/providers/Microsoft.Sql/servers/rn/' + 'providers/microsoft.insights/metricdefinitions?api-version=2017-05-01-preview&metricnamespace=default' @@ -136,15 +128,13 @@ describe('AzureMonitorUrlBuilder', () => { describe('when metric definition is Microsoft.Storage/storageAccounts/blobServices and the metricNamespace is default', () => { it('should build the getMetricNames url in the longer format', () => { - const url = UrlBuilder.buildAzureMonitorGetMetricNamesUrl( - '', - 'sub1', - 'rg', - 'Microsoft.Storage/storageAccounts/blobServices', - 'rn1/default', - 'default', - '2017-05-01-preview' - ); + const url = UrlBuilder.buildAzureMonitorGetMetricNamesUrl('', '2017-05-01-preview', { + subscription: 'sub1', + resourceGroup: 'rg', + metricDefinition: 'Microsoft.Storage/storageAccounts/blobServices', + resourceName: 'rn1/default', + metricNamespace: 'default', + }); expect(url).toBe( '/subscriptions/sub1/resourceGroups/rg/providers/Microsoft.Storage/storageAccounts/rn1/blobServices/default/' + 'providers/microsoft.insights/metricdefinitions?api-version=2017-05-01-preview&metricnamespace=default' @@ -154,15 +144,13 @@ describe('AzureMonitorUrlBuilder', () => { describe('when metric definition is Microsoft.Storage/storageAccounts/fileServices and the metricNamespace is default', () => { it('should build the getMetricNames url in the longer format', () => { - const url = UrlBuilder.buildAzureMonitorGetMetricNamesUrl( - '', - 'sub1', - 'rg', - 'Microsoft.Storage/storageAccounts/fileServices', - 'rn1/default', - 'default', - '2017-05-01-preview' - ); + const url = UrlBuilder.buildAzureMonitorGetMetricNamesUrl('', '2017-05-01-preview', { + subscription: 'sub1', + resourceGroup: 'rg', + metricDefinition: 'Microsoft.Storage/storageAccounts/fileServices', + resourceName: 'rn1/default', + metricNamespace: 'default', + }); expect(url).toBe( '/subscriptions/sub1/resourceGroups/rg/providers/Microsoft.Storage/storageAccounts/rn1/fileServices/default/' + 'providers/microsoft.insights/metricdefinitions?api-version=2017-05-01-preview&metricnamespace=default' @@ -172,15 +160,13 @@ describe('AzureMonitorUrlBuilder', () => { describe('when metric definition is Microsoft.Storage/storageAccounts/tableServices and the metricNamespace is default', () => { it('should build the getMetricNames url in the longer format', () => { - const url = UrlBuilder.buildAzureMonitorGetMetricNamesUrl( - '', - 'sub1', - 'rg', - 'Microsoft.Storage/storageAccounts/tableServices', - 'rn1/default', - 'default', - '2017-05-01-preview' - ); + const url = UrlBuilder.buildAzureMonitorGetMetricNamesUrl('', '2017-05-01-preview', { + subscription: 'sub1', + resourceGroup: 'rg', + metricDefinition: 'Microsoft.Storage/storageAccounts/tableServices', + resourceName: 'rn1/default', + metricNamespace: 'default', + }); expect(url).toBe( '/subscriptions/sub1/resourceGroups/rg/providers/Microsoft.Storage/storageAccounts/rn1/tableServices/default/' + 'providers/microsoft.insights/metricdefinitions?api-version=2017-05-01-preview&metricnamespace=default' @@ -190,15 +176,13 @@ describe('AzureMonitorUrlBuilder', () => { describe('when metric definition is Microsoft.Storage/storageAccounts/queueServices and the metricNamespace is default', () => { it('should build the getMetricNames url in the longer format', () => { - const url = UrlBuilder.buildAzureMonitorGetMetricNamesUrl( - '', - 'sub1', - 'rg', - 'Microsoft.Storage/storageAccounts/queueServices', - 'rn1/default', - 'default', - '2017-05-01-preview' - ); + const url = UrlBuilder.buildAzureMonitorGetMetricNamesUrl('', '2017-05-01-preview', { + subscription: 'sub1', + resourceGroup: 'rg', + metricDefinition: 'Microsoft.Storage/storageAccounts/queueServices', + resourceName: 'rn1/default', + metricNamespace: 'default', + }); expect(url).toBe( '/subscriptions/sub1/resourceGroups/rg/providers/Microsoft.Storage/storageAccounts/rn1/queueServices/default/' + 'providers/microsoft.insights/metricdefinitions?api-version=2017-05-01-preview&metricnamespace=default' diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/url_builder.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/url_builder.ts index 1d18c89a09d..7684a543e07 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/url_builder.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/url_builder.ts @@ -1,58 +1,47 @@ +import { GetMetricNamespacesQuery, GetMetricNamesQuery } from '../types'; + export default class UrlBuilder { - static buildAzureMonitorGetMetricNamespacesUrl( - baseUrl: string, + static buildResourceUri( subscriptionId: string, resourceGroup: string, metricDefinition: string, - resourceName: string, - apiVersion: string + resourceName: string ) { const metricDefinitionArray = metricDefinition.split('/'); const resourceNameArray = resourceName.split('/'); const provider = metricDefinitionArray.shift(); - const urlArray = [baseUrl, 'subscriptions', subscriptionId, 'resourceGroups', resourceGroup, 'providers', provider]; + const urlArray = ['/subscriptions', subscriptionId, 'resourceGroups', resourceGroup, 'providers', provider]; for (const i in metricDefinitionArray) { urlArray.push(metricDefinitionArray[i]); urlArray.push(resourceNameArray[i]); } - const urlPrefix = urlArray.join('/'); - return `${urlPrefix}/providers/microsoft.insights/metricNamespaces?api-version=${apiVersion}`; + return urlArray.join('/'); } - static buildAzureMonitorGetMetricNamesUrl( - baseUrl: string, - subscriptionId: string, - resourceGroup: string, - metricDefinition: string, - resourceName: string, - metricNamespace: string, - apiVersion: string - ) { - const metricDefinitionArray = metricDefinition.split('/'); - const resourceNameArray = resourceName.split('/'); - const provider = metricDefinitionArray.shift(); - const urlArray = [baseUrl, 'subscriptions', subscriptionId, 'resourceGroups', resourceGroup, 'providers', provider]; - for (const i in metricDefinitionArray) { - urlArray.push(metricDefinitionArray[i]); - urlArray.push(resourceNameArray[i]); + static buildAzureMonitorGetMetricNamespacesUrl(baseUrl: string, apiVersion: string, query: GetMetricNamespacesQuery) { + let resourceUri: string; + + if ('resourceUri' in query) { + resourceUri = query.resourceUri; + } else { + const { subscription, resourceGroup, metricDefinition, resourceName } = query; + resourceUri = UrlBuilder.buildResourceUri(subscription, resourceGroup, metricDefinition, resourceName); } - const urlPrefix = urlArray.join('/'); - return ( - `${urlPrefix}/providers/microsoft.insights/metricdefinitions?api-version=${apiVersion}` + - `&metricnamespace=${encodeURIComponent(metricNamespace)}` - ); - } - static newBuildAzureMonitorGetMetricNamespacesUrl(baseUrl: string, resourceUri: string, apiVersion: string) { return `${baseUrl}${resourceUri}/providers/microsoft.insights/metricNamespaces?api-version=${apiVersion}`; } - static newBuildAzureMonitorGetMetricNamesUrl( - baseUrl: string, - resourceUri: string, - metricNamespace: string, - apiVersion: string - ) { + static buildAzureMonitorGetMetricNamesUrl(baseUrl: string, apiVersion: string, query: GetMetricNamesQuery) { + let resourceUri: string; + const { metricNamespace } = query; + + if ('resourceUri' in query) { + resourceUri = query.resourceUri; + } else { + const { subscription, resourceGroup, metricDefinition, resourceName } = query; + resourceUri = UrlBuilder.buildResourceUri(subscription, resourceGroup, metricDefinition, resourceName); + } + return ( `${baseUrl}${resourceUri}/providers/microsoft.insights/metricdefinitions?api-version=${apiVersion}` + `&metricnamespace=${encodeURIComponent(metricNamespace)}` diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/MetricsQueryEditor.test.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/MetricsQueryEditor.test.tsx index 0d013ea943c..76f0c7e8f9c 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/MetricsQueryEditor.test.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/MetricsQueryEditor.test.tsx @@ -79,7 +79,7 @@ describe('Azure Monitor QueryEditor', () => { const mockDatasource = createMockDatasource(); const onChange = jest.fn(); const mockQuery = createMockQuery(); - mockDatasource.getMetricNames = jest.fn().mockResolvedValue([ + mockDatasource.azureMonitorDatasource.getMetricNames = jest.fn().mockResolvedValue([ { value: 'metric-a', text: 'Metric A', diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/dataHooks.test.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/dataHooks.test.ts index 2b25f47ad2c..97a50e4bb6a 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/dataHooks.test.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/dataHooks.test.ts @@ -247,11 +247,11 @@ describe('AzureMonitor: metrics dataHooks', () => { .fn() .mockResolvedValue([opt('Web server', 'web-server'), opt('Job server', 'job-server')]); - datasource.getMetricNames = jest + datasource.azureMonitorDatasource.getMetricNames = jest .fn() .mockResolvedValue([opt('Percentage CPU', 'percentage-cpu'), opt('Free memory', 'free-memory')]); - datasource.getMetricNamespaces = jest + datasource.azureMonitorDatasource.getMetricNamespaces = jest .fn() .mockResolvedValue([opt('Compute Virtual Machine', 'azure/vmc'), opt('Database NS', 'azure/dbns')]); }); diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/dataHooks.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/dataHooks.ts index c340e9929bb..76259355994 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/dataHooks.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/dataHooks.ts @@ -153,7 +153,12 @@ export const useMetricNamespaces: DataHook = (query, datasource, onChange, setEr return; } - const results = await datasource.getMetricNamespaces(subscription, resourceGroup, metricDefinition, resourceName); + const results = await datasource.azureMonitorDatasource.getMetricNamespaces({ + subscription, + resourceGroup, + metricDefinition, + resourceName, + }); const options = formatOptions(results, metricNamespace); // Do some cleanup of the query state if need be @@ -180,13 +185,13 @@ export const useMetricNames: DataHook = (query, datasource, onChange, setError) return; } - const results = await datasource.getMetricNames( + const results = await datasource.azureMonitorDatasource.getMetricNames({ subscription, resourceGroup, metricDefinition, resourceName, - metricNamespace - ); + metricNamespace, + }); const options = formatOptions(results, metricName); @@ -217,8 +222,8 @@ export const useMetricMetadata = (query: AzureMonitorQuery, datasource: Datasour return; } - datasource - .getMetricMetadata(subscription, resourceGroup, metricDefinition, resourceName, metricNamespace, metricName) + datasource.azureMonitorDatasource + .getMetricMetadata({ subscription, resourceGroup, metricDefinition, resourceName, metricNamespace, metricName }) .then((metadata) => { // TODO: Move the aggregationTypes and timeGrain defaults into `getMetricMetadata` const aggregations = (metadata.supportedAggTypes || [metadata.primaryAggType]).map((v) => ({ diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/NewMetricsQueryEditor/MetricsQueryEditor.test.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/NewMetricsQueryEditor/MetricsQueryEditor.test.tsx index 792d3b76123..6b7347e2d71 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/NewMetricsQueryEditor/MetricsQueryEditor.test.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/NewMetricsQueryEditor/MetricsQueryEditor.test.tsx @@ -160,7 +160,7 @@ describe('MetricsQueryEditor', () => { const mockDatasource = createMockDatasource({ resourcePickerData }); const onChange = jest.fn(); const mockQuery = createMockQuery(); - mockDatasource.azureMonitorDatasource.newGetMetricNames = jest.fn().mockResolvedValue([ + mockDatasource.azureMonitorDatasource.getMetricNames = jest.fn().mockResolvedValue([ { value: 'metric-a', text: 'Metric A', diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/NewMetricsQueryEditor/dataHooks.test.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/NewMetricsQueryEditor/dataHooks.test.ts index 7a784885c91..b50d71a24af 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/NewMetricsQueryEditor/dataHooks.test.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/NewMetricsQueryEditor/dataHooks.test.ts @@ -130,11 +130,11 @@ describe('AzureMonitor: metrics dataHooks', () => { .fn() .mockResolvedValue([opt('Web server', 'web-server'), opt('Job server', 'job-server')]); - datasource.azureMonitorDatasource.newGetMetricNames = jest + datasource.azureMonitorDatasource.getMetricNames = jest .fn() .mockResolvedValue([opt('Percentage CPU', 'percentage-cpu'), opt('Free memory', 'free-memory')]); - datasource.azureMonitorDatasource.newGetMetricNamespaces = jest + datasource.azureMonitorDatasource.getMetricNamespaces = jest .fn() .mockResolvedValue([opt('Compute Virtual Machine', 'azure/vmc'), opt('Database NS', 'azure/dbns')]); }); diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/NewMetricsQueryEditor/dataHooks.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/NewMetricsQueryEditor/dataHooks.ts index a8c11ebd38b..e66a83b49e0 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/NewMetricsQueryEditor/dataHooks.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/NewMetricsQueryEditor/dataHooks.ts @@ -29,7 +29,7 @@ export const useMetricNamespaces: DataHook = (query, datasource, onChange, setEr return; } - const results = await datasource.azureMonitorDatasource.newGetMetricNamespaces(resourceUri); + const results = await datasource.azureMonitorDatasource.getMetricNamespaces({ resourceUri }); const options = formatOptions(results, metricNamespace); // Do some cleanup of the query state if need be @@ -55,7 +55,7 @@ export const useMetricNames: DataHook = (query, datasource, onChange, setError) return; } - const results = await datasource.azureMonitorDatasource.newGetMetricNames(resourceUri, metricNamespace); + const results = await datasource.azureMonitorDatasource.getMetricNames({ resourceUri, metricNamespace }); const options = formatOptions(results, metricName); return options; @@ -87,7 +87,7 @@ export const useMetricMetadata = (query: AzureMonitorQuery, datasource: Datasour } datasource.azureMonitorDatasource - .newGetMetricMetadata(resourceUri, metricNamespace, metricName) + .getMetricMetadata({ resourceUri, metricNamespace, metricName }) .then((metadata) => { // TODO: Move the aggregationTypes and timeGrain defaults into `getMetricMetadata` const aggregations = (metadata.supportedAggTypes || [metadata.primaryAggType]).map((v) => ({ diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/datasource.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/datasource.ts index 42997fb09f8..2f9e008fca6 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/datasource.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/datasource.ts @@ -218,49 +218,6 @@ export default class Datasource extends DataSourceApi //the table to query (e.g. Usage, Heartbeat, Perf)\n| where $__timeFilter(TimeGenerated) //this is a macro used to show the full chart’s time range, choose the datetime column here\n| summarize count() by , bin(TimeGenerated, $__interval) //change “group by column” to a column in your table, such as “Computer”. The $__interval macro is used to auto-select the time grain. Can also use 1h, 5m etc.\n| order by TimeGenerated asc', + resultFormat: 'time_series', + workspace: 'mock-workspace-id', + }, + azureMonitor: { + aggregation: 'Average', + allowedTimeGrainsMs: [60000, 300000, 900000, 1800000, 3600000, 21600000, 43200000, 86400000], + dimensionFilters: [{ dimension: 'dependency/success', filter: '', operator: 'eq' }], + metricDefinition: 'microsoft.insights/components', + metricName: 'dependencies/duration', + metricNamespace: 'microsoft.insights/components', + resourceGroup: 'cloud-datasources', + resourceName: 'AppInsightsTestData', + timeGrain: 'auto', + top: '10', + }, + insightsAnalytics: { + query: '', + resultFormat: 'time_series', + }, + queryType: AzureQueryType.AzureMonitor, + refId: 'A', + subscription: '44693801-6ee6-49de-9b2d-9106972f9572', +}; + +const azureMonitorQueryV8 = { + azureMonitor: { + aggregation: 'Average', + dimensionFilters: [], + metricDefinition: 'microsoft.insights/components', + metricName: 'dependencies/duration', + metricNamespace: 'microsoft.insights/components', + resourceGroup: 'cloud-datasources', + resourceName: 'AppInsightsTestData', + timeGrain: 'auto', + }, + datasource: { + type: 'grafana-azure-monitor-datasource', + uid: 'sD-ZuB87k', + }, + queryType: AzureQueryType.AzureMonitor, + refId: 'A', + subscription: '44693801-6ee6-49de-9b2d-9106972f9572', +}; + const modernMetricsQuery: AzureMonitorQuery = { appInsights: { dimension: [], metricName: 'select', timeGrain: 'auto' }, azureLogAnalytics: { query: '//change this example to create your own time series query\n //the table to query (e.g. Usage, Heartbeat, Perf)\n| where $__timeFilter(TimeGenerated) //this is a macro used to show the full chart’s time range, choose the datetime column here\n| summarize count() by , bin(TimeGenerated, $__interval) //change “group by column” to a column in your table, such as “Computer”. The $__interval macro is used to auto-select the time grain. Can also use 1h, 5m etc.\n| order by TimeGenerated asc', resultFormat: 'time_series', - workspace: 'e3fe4fde-ad5e-4d60-9974-e2f3562ffdf2', + workspace: 'mock-workspace-id', }, azureMonitor: { aggregation: 'Average', @@ -19,6 +68,8 @@ const modernMetricsQuery: AzureMonitorQuery = { metricNamespace: 'microsoft.insights/components', resourceGroup: 'cloud-datasources', resourceName: 'AppInsightsTestData', + resourceUri: + '/subscriptions/44693801-6ee6-49de-9b2d-9106972f9572/resourceGroups/cloud-datasources/providers/microsoft.insights/components/AppInsightsTestData', timeGrain: 'PT5M', top: '10', }, @@ -37,4 +88,32 @@ describe('AzureMonitor: migrateQuery', () => { // MUST use .toBe because we want to assert that the identity of unmigrated queries remains the same expect(modernMetricsQuery).toBe(result); }); + + describe('migrating from a v7 query to the latest query version', () => { + it('should build a resource uri', () => { + const result = migrateQuery(azureMonitorQueryV7); + expect(result).toMatchObject( + expect.objectContaining({ + azureMonitor: expect.objectContaining({ + resourceUri: + '/subscriptions/44693801-6ee6-49de-9b2d-9106972f9572/resourceGroups/cloud-datasources/providers/microsoft.insights/components/AppInsightsTestData', + }), + }) + ); + }); + }); + + describe('migrating from a v8 query to the latest query version', () => { + it('should build a resource uri', () => { + const result = migrateQuery(azureMonitorQueryV8); + expect(result).toMatchObject( + expect.objectContaining({ + azureMonitor: expect.objectContaining({ + resourceUri: + '/subscriptions/44693801-6ee6-49de-9b2d-9106972f9572/resourceGroups/cloud-datasources/providers/microsoft.insights/components/AppInsightsTestData', + }), + }) + ); + }); + }); }); diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/migrateQuery.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/migrateQuery.ts index 3a9043718e0..78e55d70bf2 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/migrateQuery.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/migrateQuery.ts @@ -4,6 +4,7 @@ import { setTimeGrain as setMetricsTimeGrain, } from '../components/MetricsQueryEditor/setQueryValue'; import TimegrainConverter from '../time_grain_converter'; +import UrlBuilder from '../azure_monitor/url_builder'; import { AzureMonitorQuery, AzureQueryType, DeprecatedAzureQueryType } from '../types'; const OLD_DEFAULT_DROPDOWN_VALUE = 'select'; @@ -21,6 +22,7 @@ export default function migrateQuery(query: AzureMonitorQuery): AzureMonitorQuer workingQuery = migrateToDefaultNamespace(workingQuery); workingQuery = migrateApplicationInsightsDimensions(workingQuery); workingQuery = migrateMetricsDimensionFilters(workingQuery); + workingQuery = migrateResourceUri(workingQuery); return workingQuery; } @@ -121,7 +123,6 @@ function migrateApplicationInsightsDimensions(query: AzureMonitorQuery): AzureMo return query; } -// Exported because its also used directly in the datasource.ts for some reason function migrateMetricsDimensionFilters(query: AzureMonitorQuery): AzureMonitorQuery { let workingQuery = query; @@ -133,6 +134,33 @@ function migrateMetricsDimensionFilters(query: AzureMonitorQuery): AzureMonitorQ return workingQuery; } +// Azure Monitor metric queries prior to Grafana version 9 did not include a `resourceUri`. +// The resourceUri was previously constructed with the subscription id, resource group, +// metric definition (a.k.a. resource type), and the resource name. +function migrateResourceUri(query: AzureMonitorQuery): AzureMonitorQuery { + const azureMonitorQuery = query.azureMonitor; + + if (!azureMonitorQuery || azureMonitorQuery.resourceUri) { + return query; + } + + const { subscription } = query; + const { resourceGroup, metricDefinition, resourceName } = azureMonitorQuery; + if (!(subscription && resourceGroup && metricDefinition && resourceName)) { + return query; + } + + const resourceUri = UrlBuilder.buildResourceUri(subscription, resourceGroup, metricDefinition, resourceName); + + return { + ...query, + azureMonitor: { + ...azureMonitorQuery, + resourceUri, + }, + }; +} + // datasource.ts also contains some migrations, which have been moved to here. Unsure whether // they should also do all the other migrations... export function datasourceMigrations(query: AzureMonitorQuery): AzureMonitorQuery { @@ -159,6 +187,7 @@ export function datasourceMigrations(query: AzureMonitorQuery): AzureMonitorQuer if (workingQuery.queryType === AzureQueryType.AzureMonitor && workingQuery.azureMonitor) { workingQuery = migrateMetricsDimensionFilters(workingQuery); + workingQuery = migrateResourceUri(workingQuery); } return workingQuery; diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/variables.test.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/variables.test.ts index e7f5ef9779e..82c6a566e37 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/variables.test.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/variables.test.ts @@ -270,7 +270,9 @@ describe('VariableSupport', () => { azureLogAnalyticsDatasource: { defaultSubscriptionId: 'defaultSubscriptionId', }, - getMetricNamespaces: jest.fn().mockResolvedValueOnce(expectedResults), + azureMonitorDatasource: { + getMetricNamespaces: jest.fn().mockResolvedValueOnce(expectedResults), + }, }) ); const mockRequest = { @@ -296,7 +298,9 @@ describe('VariableSupport', () => { const expectedResults = ['test']; const variableSupport = new VariableSupport( createMockDatasource({ - getMetricNamespaces: jest.fn().mockResolvedValueOnce(expectedResults), + azureMonitorDatasource: { + getMetricNamespaces: jest.fn().mockResolvedValueOnce(expectedResults), + }, }) ); const mockRequest = { @@ -325,7 +329,9 @@ describe('VariableSupport', () => { azureLogAnalyticsDatasource: { defaultSubscriptionId: 'defaultSubscriptionId', }, - getMetricNames: jest.fn().mockResolvedValueOnce(expectedResults), + azureMonitorDatasource: { + getMetricNames: jest.fn().mockResolvedValueOnce(expectedResults), + }, }) ); const mockRequest = { @@ -351,7 +357,9 @@ describe('VariableSupport', () => { const expectedResults = ['test']; const variableSupport = new VariableSupport( createMockDatasource({ - getMetricNames: jest.fn().mockResolvedValueOnce(expectedResults), + azureMonitorDatasource: { + getMetricNames: jest.fn().mockResolvedValueOnce(expectedResults), + }, }) ); const mockRequest = { @@ -478,7 +486,9 @@ describe('VariableSupport', () => { azureLogAnalyticsDatasource: { defaultSubscriptionId: 'defaultSubscriptionId', }, - getMetricNames: jest.fn().mockResolvedValueOnce([]), + azureMonitorDatasource: { + getMetricNames: jest.fn().mockResolvedValueOnce([]), + }, }) ); const mockRequest = { diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/variables.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/variables.ts index 6c70fa479ab..abe9901a3df 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/variables.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/variables.ts @@ -81,22 +81,11 @@ export class VariableSupport extends CustomVariableSupport Date: Wed, 20 Apr 2022 14:01:01 +0200 Subject: [PATCH 029/120] Prometheus/Loki: Fixes the query type option when multiple queries present (#47846) --- .../querybuilder/components/LokiQueryBuilderOptions.tsx | 7 +------ .../querybuilder/components/PromQueryBuilderOptions.tsx | 7 +------ 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderOptions.tsx b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderOptions.tsx index 0aac629b32e..92b1501f740 100644 --- a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderOptions.tsx +++ b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderOptions.tsx @@ -58,12 +58,7 @@ export const LokiQueryBuilderOptions = React.memo(({ query, onChange, onR /> - + {showMaxLines && ( diff --git a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilderOptions.tsx b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilderOptions.tsx index 432d2516f65..74d1067fedb 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilderOptions.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilderOptions.tsx @@ -75,12 +75,7 @@ export const PromQueryBuilderOptions = React.memo(({ query, app, onChange + { expect(input).toBeInTheDocument(); // we open the menu - userEvent.click(input); + await userEvent.click(input); expect(screen.getByText('Option 1')).toBeInTheDocument(); // we type in the input 'Option 2', which should prompt an option creation - userEvent.type(input, 'Option 2'); + await userEvent.type(input, 'Option 2'); const creatableOption = screen.getByLabelText('Select option'); expect(creatableOption).toHaveTextContent('Create: Option 2'); // we click on the creatable option to trigger its creation - userEvent.click(creatableOption); + await userEvent.click(creatableOption); // Forcing a rerender rerender(); // we open the menu again - userEvent.click(input); + await userEvent.click(input); // the created option should be available expect(screen.getByText('Option 2')).toBeInTheDocument(); }); - it('Should handle onChange properly', () => { + it('Should handle onChange properly', async () => { const onChange = jest.fn(); const MyComp = () => ( @@ -67,28 +67,28 @@ describe('useCreatableSelectPersistedBehaviour', () => { expect(input).toBeInTheDocument(); // we open the menu - userEvent.click(input); + await userEvent.click(input); const option1 = screen.getByText('Option 1'); expect(option1).toBeInTheDocument(); // Should call onChange when selecting an already existing option - userEvent.click(option1); + await userEvent.click(option1); expect(onChange).toHaveBeenLastCalledWith( { value: 'Option 1', label: 'Option 1' }, { action: 'select-option', name: undefined, option: undefined } ); - userEvent.click(input); + await userEvent.click(input); // we type in the input 'Option 2', which should prompt an option creation - userEvent.type(input, 'Option 2'); - userEvent.click(screen.getByLabelText('Select option')); + await userEvent.type(input, 'Option 2'); + await userEvent.click(screen.getByLabelText('Select option')); expect(onChange).toHaveBeenLastCalledWith({ value: 'Option 2' }); }); - it('Should create an option for value if value is not in options', () => { + it('Should create an option for value if value is not in options', async () => { const MyComp = (_: { force?: boolean }) => (
onEdit(idx)}> - {annotation.datasource?.uid} + {dataSourceSrv.getInstanceSettings(annotation.datasource)?.name || annotation.datasource?.uid} {idx !== 0 && ( diff --git a/public/app/features/dashboard/components/DashboardSettings/AnnotationsSettings.test.tsx b/public/app/features/dashboard/components/DashboardSettings/AnnotationsSettings.test.tsx index bdd4a660c37..8cd6ad86b25 100644 --- a/public/app/features/dashboard/components/DashboardSettings/AnnotationsSettings.test.tsx +++ b/public/app/features/dashboard/components/DashboardSettings/AnnotationsSettings.test.tsx @@ -15,7 +15,7 @@ describe('AnnotationsSettings', () => { grafana: mockDataSource( { name: 'Grafana', - uid: 'Grafana', + uid: 'uid1', type: 'grafana', isDefault: true, }, @@ -24,7 +24,7 @@ describe('AnnotationsSettings', () => { Testdata: mockDataSource( { name: 'Testdata', - uid: 'Testdata', + uid: 'uid2', type: 'testdata', isDefault: true, }, @@ -33,7 +33,7 @@ describe('AnnotationsSettings', () => { Prometheus: mockDataSource( { name: 'Prometheus', - uid: 'Prometheus', + uid: 'uid3', type: 'prometheus', }, { annotations: true } @@ -63,7 +63,7 @@ describe('AnnotationsSettings', () => { list: [ { builtIn: 1, - datasource: { uid: 'Grafana', type: 'grafana' }, + datasource: { uid: 'uid1', type: 'grafana' }, enable: true, hide: true, iconColor: 'rgba(0, 211, 255, 1)', @@ -120,12 +120,12 @@ describe('AnnotationsSettings', () => { ).toBeInTheDocument(); }); - test('it renders a sortable table of annotations', async () => { + test('it renders the anotation names or uid if annotation doesnt exist', async () => { const annotationsList = [ ...dashboard.annotations.list, { builtIn: 0, - datasource: { uid: 'Prometheus', type: 'prometheus' }, + datasource: { uid: 'uid3', type: 'prometheus' }, enable: true, hide: true, iconColor: 'rgba(0, 211, 255, 1)', @@ -134,7 +134,41 @@ describe('AnnotationsSettings', () => { }, { builtIn: 0, - datasource: { uid: 'Prometheus', type: 'prometheus' }, + datasource: { uid: 'deletedAnnotationId', type: 'prometheus' }, + enable: true, + hide: true, + iconColor: 'rgba(0, 211, 255, 1)', + name: 'Annotation 2', + type: 'dashboard', + }, + ]; + const dashboardWithAnnotations = { + ...dashboard, + annotations: { + list: [...annotationsList], + }, + }; + render(); + // Check that we have the correct annotations + expect(screen.queryByText(/prometheus/i)).toBeInTheDocument(); + expect(screen.queryByText(/deletedAnnotationId/i)).toBeInTheDocument(); + }); + + test('it renders a sortable table of annotations', async () => { + const annotationsList = [ + ...dashboard.annotations.list, + { + builtIn: 0, + datasource: { uid: 'uid3', type: 'prometheus' }, + enable: true, + hide: true, + iconColor: 'rgba(0, 211, 255, 1)', + name: 'Annotation 2', + type: 'dashboard', + }, + { + builtIn: 0, + datasource: { uid: 'uid3', type: 'prometheus' }, enable: true, hide: true, iconColor: 'rgba(0, 211, 255, 1)', From 9595b56f0ddf019cf9e49382ffdd8987151f2520 Mon Sep 17 00:00:00 2001 From: Ashley Harrison Date: Thu, 21 Apr 2022 17:44:06 +0100 Subject: [PATCH 076/120] Chore: fix flakey frontend test (#48071) * remove unnecessary rerender * removed unused act import --- .../variables/inspect/VariablesUnknownTable.test.tsx | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/public/app/features/variables/inspect/VariablesUnknownTable.test.tsx b/public/app/features/variables/inspect/VariablesUnknownTable.test.tsx index be9a286e80f..bb0cad35a6e 100644 --- a/public/app/features/variables/inspect/VariablesUnknownTable.test.tsx +++ b/public/app/features/variables/inspect/VariablesUnknownTable.test.tsx @@ -1,6 +1,6 @@ import React from 'react'; import * as runtime from '@grafana/runtime'; -import { act, render, screen, waitFor } from '@testing-library/react'; +import { render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { VariablesUnknownTable, VariablesUnknownTableProps } from './VariablesUnknownTable'; @@ -107,19 +107,12 @@ describe('VariablesUnknownTable', () => { it('then it should report slow expansion', async () => { const variable = customBuilder().withId('Renamed Variable').withName('Renamed Variable').build(); const usages = [{ variable, nodes: [], edges: [], showGraph: false }]; - const { reportInteractionSpy, rerender } = await getTestContext({}, usages); + const { reportInteractionSpy } = await getTestContext({}, usages); const dateNowStart = 1000; const dateNowStop = 2000; Date.now = jest.fn().mockReturnValueOnce(dateNowStart).mockReturnValue(dateNowStop); await userEvent.click(screen.getByRole('heading', { name: /renamed or missing variables/i })); - const props: VariablesUnknownTableProps = { - variables: [], - dashboard: null, - }; - await act(async () => { - rerender(); - }); // make sure we report the interaction for slow expansion await waitFor(() => expect(reportInteractionSpy).toHaveBeenCalledTimes(2)); From d66fc6ed1a2ac0391ab9d70a6dd7cf8eed50af0e Mon Sep 17 00:00:00 2001 From: George Robinson Date: Thu, 21 Apr 2022 17:59:22 +0100 Subject: [PATCH 077/120] Alerting: Add GetRuleGroups to RuleStore (#48036) This commit adds a new method GetRuleGroups to RuleStore which returns the set of rule groups across all organizations. --- pkg/services/ngalert/models/alert_rule.go | 7 +++++++ pkg/services/ngalert/store/alert_rule.go | 13 +++++++++++++ pkg/services/ngalert/store/testing.go | 20 ++++++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/pkg/services/ngalert/models/alert_rule.go b/pkg/services/ngalert/models/alert_rule.go index 8da7640f363..e395f1f220f 100644 --- a/pkg/services/ngalert/models/alert_rule.go +++ b/pkg/services/ngalert/models/alert_rule.go @@ -265,7 +265,14 @@ type GetAlertRulesQuery struct { Result []*AlertRule } +// ListRuleGroupsQuery is the query for listing unique rule groups +// across all organizations +type ListRuleGroupsQuery struct { + Result []string +} + // ListOrgRuleGroupsQuery is the query for listing unique rule groups +// for an organization type ListOrgRuleGroupsQuery struct { OrgID int64 NamespaceUIDs []string diff --git a/pkg/services/ngalert/store/alert_rule.go b/pkg/services/ngalert/store/alert_rule.go index ff1df1709ce..3d4822128a6 100644 --- a/pkg/services/ngalert/store/alert_rule.go +++ b/pkg/services/ngalert/store/alert_rule.go @@ -39,6 +39,8 @@ type RuleStore interface { GetAlertRuleByUID(ctx context.Context, query *ngmodels.GetAlertRuleByUIDQuery) error GetAlertRulesForScheduling(ctx context.Context, query *ngmodels.ListAlertRulesQuery) error GetOrgAlertRules(ctx context.Context, query *ngmodels.ListAlertRulesQuery) error + // GetRuleGroups returns the unique rule groups across all organizations. + GetRuleGroups(ctx context.Context, query *ngmodels.ListRuleGroupsQuery) error GetAlertRules(ctx context.Context, query *ngmodels.GetAlertRulesQuery) error GetUserVisibleNamespaces(context.Context, int64, *models.SignedInUser) (map[string]*models.Folder, error) GetNamespaceByTitle(context.Context, string, int64, *models.SignedInUser, bool) (*models.Folder, error) @@ -261,6 +263,17 @@ func (st DBstore) GetOrgAlertRules(ctx context.Context, query *ngmodels.ListAler }) } +func (st DBstore) GetRuleGroups(ctx context.Context, query *ngmodels.ListRuleGroupsQuery) error { + return st.SQLStore.WithDbSession(ctx, func(sess *sqlstore.DBSession) error { + ruleGroups := make([]string, 0) + if err := sess.Table("alert_rule").Distinct("rule_group").Find(&ruleGroups); err != nil { + return err + } + query.Result = ruleGroups + return nil + }) +} + // GetAlertRules is a handler for retrieving rule group alert rules of specific organisation. func (st DBstore) GetAlertRules(ctx context.Context, query *ngmodels.GetAlertRulesQuery) error { return st.SQLStore.WithDbSession(ctx, func(sess *sqlstore.DBSession) error { diff --git a/pkg/services/ngalert/store/testing.go b/pkg/services/ngalert/store/testing.go index 0c69fd5f522..4a340037ced 100644 --- a/pkg/services/ngalert/store/testing.go +++ b/pkg/services/ngalert/store/testing.go @@ -178,6 +178,26 @@ func (f *FakeRuleStore) GetOrgAlertRules(_ context.Context, q *models.ListAlertR q.Result = rules return nil } + +func (f *FakeRuleStore) GetRuleGroups(_ context.Context, q *models.ListRuleGroupsQuery) error { + f.mtx.Lock() + defer f.mtx.Unlock() + f.RecordedOps = append(f.RecordedOps, *q) + + m := make(map[string]struct{}) + for _, rules := range f.Rules { + for _, rule := range rules { + m[rule.RuleGroup] = struct{}{} + } + } + + for s := range m { + q.Result = append(q.Result, s) + } + + return nil +} + func (f *FakeRuleStore) GetAlertRules(_ context.Context, q *models.GetAlertRulesQuery) error { f.mtx.Lock() defer f.mtx.Unlock() From 8e606dd751b5348e928665605dcf6c45a9d29de4 Mon Sep 17 00:00:00 2001 From: Kat Yang <69819079+yangkb09@users.noreply.github.com> Date: Thu, 21 Apr 2022 13:20:18 -0400 Subject: [PATCH 078/120] Chore: Remove x from session (#48074) --- pkg/services/sqlstore/alert_notification.go | 10 +++++----- pkg/services/sqlstore/session.go | 4 ++-- pkg/services/sqlstore/tags_test.go | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/pkg/services/sqlstore/alert_notification.go b/pkg/services/sqlstore/alert_notification.go index c8c515e81ee..ee780c53a44 100644 --- a/pkg/services/sqlstore/alert_notification.go +++ b/pkg/services/sqlstore/alert_notification.go @@ -54,7 +54,7 @@ func (ss *SQLStore) DeleteAlertNotification(ctx context.Context, cmd *models.Del func (ss *SQLStore) DeleteAlertNotificationWithUid(ctx context.Context, cmd *models.DeleteAlertNotificationWithUidCommand) error { existingNotification := &models.GetAlertNotificationsWithUidQuery{OrgId: cmd.OrgId, Uid: cmd.Uid} - if err := getAlertNotificationWithUidInternal(ctx, existingNotification, newSession(ctx)); err != nil { + if err := getAlertNotificationWithUidInternal(ctx, existingNotification, ss.newSession(ctx)); err != nil { return err } @@ -75,7 +75,7 @@ func (ss *SQLStore) DeleteAlertNotificationWithUid(ctx context.Context, cmd *mod } func (ss *SQLStore) GetAlertNotifications(ctx context.Context, query *models.GetAlertNotificationsQuery) error { - return getAlertNotificationInternal(ctx, query, newSession(ctx)) + return getAlertNotificationInternal(ctx, query, ss.newSession(ctx)) } func (ss *SQLStore) GetAlertNotificationUidWithId(ctx context.Context, query *models.GetAlertNotificationUidQuery) error { @@ -86,7 +86,7 @@ func (ss *SQLStore) GetAlertNotificationUidWithId(ctx context.Context, query *mo return nil } - err := getAlertNotificationUidInternal(ctx, query, newSession(ctx)) + err := getAlertNotificationUidInternal(ctx, query, ss.newSession(ctx)) if err != nil { return err } @@ -101,7 +101,7 @@ func newAlertNotificationUidCacheKey(orgID, notificationId int64) string { } func (ss *SQLStore) GetAlertNotificationsWithUid(ctx context.Context, query *models.GetAlertNotificationsWithUidQuery) error { - return getAlertNotificationWithUidInternal(ctx, query, newSession(ctx)) + return getAlertNotificationWithUidInternal(ctx, query, ss.newSession(ctx)) } func (ss *SQLStore) GetAllAlertNotifications(ctx context.Context, query *models.GetAllAlertNotificationsQuery) error { @@ -440,7 +440,7 @@ func (ss *SQLStore) UpdateAlertNotification(ctx context.Context, cmd *models.Upd func (ss *SQLStore) UpdateAlertNotificationWithUid(ctx context.Context, cmd *models.UpdateAlertNotificationWithUidCommand) error { getAlertNotificationWithUidQuery := &models.GetAlertNotificationsWithUidQuery{OrgId: cmd.OrgId, Uid: cmd.Uid} - if err := getAlertNotificationWithUidInternal(ctx, getAlertNotificationWithUidQuery, newSession(ctx)); err != nil { + if err := getAlertNotificationWithUidInternal(ctx, getAlertNotificationWithUidQuery, ss.newSession(ctx)); err != nil { return err } diff --git a/pkg/services/sqlstore/session.go b/pkg/services/sqlstore/session.go index dfa7c5fbe0a..556b936d4d1 100644 --- a/pkg/services/sqlstore/session.go +++ b/pkg/services/sqlstore/session.go @@ -30,8 +30,8 @@ func (ss *SQLStore) NewSession(ctx context.Context) *DBSession { return sess } -func newSession(ctx context.Context) *DBSession { - sess := &DBSession{Session: x.NewSession()} +func (ss *SQLStore) newSession(ctx context.Context) *DBSession { + sess := &DBSession{Session: ss.engine.NewSession()} sess.Session = sess.Session.Context(ctx) return sess diff --git a/pkg/services/sqlstore/tags_test.go b/pkg/services/sqlstore/tags_test.go index f1b986ded62..6fceef6308c 100644 --- a/pkg/services/sqlstore/tags_test.go +++ b/pkg/services/sqlstore/tags_test.go @@ -13,7 +13,7 @@ import ( ) func TestSavingTags(t *testing.T) { - InitTestDB(t) + ss := InitTestDB(t) tagPairs := []*models.Tag{ {Key: "outage"}, @@ -21,7 +21,7 @@ func TestSavingTags(t *testing.T) { {Key: "server", Value: "server-1"}, {Key: "error"}, } - tags, err := EnsureTagsExist(newSession(context.Background()), tagPairs) + tags, err := EnsureTagsExist(ss.newSession(context.Background()), tagPairs) require.Nil(t, err) require.Equal(t, 4, len(tags)) From 6910da62219ce1df8ba5166bb11419c300acd537 Mon Sep 17 00:00:00 2001 From: owensmallwood Date: Thu, 21 Apr 2022 11:23:54 -0600 Subject: [PATCH 079/120] upgrades sentry-go to 0.13.0 and replaces gin with v1.7.7 due to CVE https://github.com/advisories/GHSA-h395-qcrw-5vmq (#48000) --- go.mod | 9 ++++++--- go.sum | 29 ++++++++++------------------- 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/go.mod b/go.mod index 5b6284b0044..deb77271dfe 100644 --- a/go.mod +++ b/go.mod @@ -33,7 +33,7 @@ require ( github.com/dop251/goja v0.0.0-20210804101310-32956a348b49 github.com/fatih/color v1.13.0 github.com/gchaincl/sqlhooks v1.3.0 - github.com/getsentry/sentry-go v0.10.0 + github.com/getsentry/sentry-go v0.13.0 github.com/go-kit/kit v0.11.0 // indirect github.com/go-openapi/strfmt v0.20.2 github.com/go-redis/redis/v8 v8.11.4 @@ -216,7 +216,7 @@ require ( github.com/prometheus/procfs v0.7.3 // indirect github.com/protocolbuffers/txtpbfmt v0.0.0-20201118171849-f6a6b3f636fc // indirect github.com/rainycape/unidecode v0.0.0-20150907023854-cb7f23ec59be // indirect - github.com/rs/cors v1.8.0 // indirect + github.com/rs/cors v1.8.2 // indirect github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect github.com/segmentio/encoding v0.3.2 github.com/sercand/kuberesolver v2.4.0+incompatible // indirect @@ -276,13 +276,14 @@ require ( github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 // indirect github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/golang-jwt/jwt v3.2.1+incompatible // indirect + github.com/golang-jwt/jwt v3.2.2+incompatible // indirect github.com/imdario/mergo v0.3.12 // indirect github.com/klauspost/compress v1.15.1 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/opencontainers/image-spec v1.0.2 // indirect github.com/pierrec/lz4/v4 v4.1.8 // indirect github.com/segmentio/asm v1.1.1 // indirect + github.com/yudai/pp v2.0.1+incompatible // indirect ) // Use fork of crewjam/saml with fixes for some issues until changes get merged into upstream @@ -292,6 +293,8 @@ replace github.com/apache/thrift => github.com/apache/thrift v0.14.1 replace github.com/hashicorp/consul => github.com/hashicorp/consul v1.10.2 +replace github.com/gin-gonic/gin => github.com/gin-gonic/gin v1.7.7 + // Upgraded to fix CVE-2020-26066. This can be removed when go.opentelemetry.io/collector and github.com/influxdata/telegraf are upgraded // github.com/tidwall/match v1.0.1 should not be used. replace github.com/tidwall/match => github.com/tidwall/match v1.1.1 diff --git a/go.sum b/go.sum index 03d4fa7fdff..526466f2ed7 100644 --- a/go.sum +++ b/go.sum @@ -849,7 +849,6 @@ github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLi github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb/go.mod h1:bH6Xx7IW64qjjJq8M2u4dxNaBiDfKK+z/3eGDpXEQhc= -github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= @@ -892,18 +891,14 @@ github.com/getkin/kin-openapi v0.91.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSy github.com/getkin/kin-openapi v0.94.0 h1:bAxg2vxgnHHHoeefVdmGbR+oxtJlcv5HsJJa3qmAHuo= github.com/getkin/kin-openapi v0.94.0/go.mod h1:LWZfzOd7PRy8GJ1dJ6mCU6tNdSfOwRac1BUPam4aw6Q= github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= -github.com/getsentry/sentry-go v0.10.0 h1:6gwY+66NHKqyZrdi6O2jGdo7wGdo9b3B69E01NFgT5g= -github.com/getsentry/sentry-go v0.10.0/go.mod h1:kELm/9iCblqUYh+ZRML7PNdCvEuw24wBvJPYyi86cws= +github.com/getsentry/sentry-go v0.13.0 h1:20dgTiUSfxRB/EhMPtxcL9ZEbM1ZdR+W/7f7NWD+xWo= +github.com/getsentry/sentry-go v0.13.0/go.mod h1:EOsfu5ZdvKPfeHYV6pTVQnsjfp30+XA7//UooKNumH0= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 h1:Mn26/9ZMNWSw9C9ERFA1PUxfmGpolnw2v0bKOREu5ew= github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32/go.mod h1:GIjDIg/heH5DOkXY3YJ/wNhfHsQHoXGjl8G8amsYQ1I= -github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= -github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmCsR2Do= -github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= -github.com/gin-gonic/gin v1.7.3/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY= +github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U= github.com/glinton/ping v0.1.4-0.20200311211934-5ac87da8cd96/go.mod h1:uY+1eqFUyotrQxF1wYFNtMeHp/swbYRsoGzfcPZ8x3o= github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= @@ -1079,11 +1074,8 @@ github.com/go-openapi/validate v0.20.2/go.mod h1:e7OJoKNgd0twXZwIn0A43tHbvIcr/rZ github.com/go-pdf/fpdf v0.5.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= github.com/go-pdf/fpdf v0.6.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= -github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= -github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg= github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= @@ -1174,8 +1166,9 @@ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69 github.com/gogo/status v1.0.3/go.mod h1:SavQ51ycCLnc7dGyJxp8YAmudx8xqiVrRf+6IXRsugc= github.com/gogo/status v1.1.0 h1:+eIkrewn5q6b30y+g/BJINVVdi2xH7je5MPJ3ZPK3JA= github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= -github.com/golang-jwt/jwt v3.2.1+incompatible h1:73Z+4BJcrTC+KczS6WvTPvRGOp1WmfEP4Q1lOd9Z/+c= github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-jwt/jwt/v4 v4.4.1 h1:pC5DB52sCeK48Wlb9oPcdhnjkz1TKt1D/P7WKJ0kUcQ= @@ -1733,7 +1726,6 @@ github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E github.com/jung-kurt/gofpdf v1.16.2 h1:jgbatWHfRlPYiK85qgevsZTHviWXKwB1TTiKdz5PtRc= github.com/jung-kurt/gofpdf v1.16.2/go.mod h1:1hl7y57EsiPAkLbOwzpzqgx1A30nQCk/YmFV8S2vmK0= github.com/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef/go.mod h1:Ct9fl0F6iIOGgxJ5npU/IUOhOhqlVrGjyIZc8/MagT0= -github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= github.com/kardianos/service v1.0.0/go.mod h1:8CzDhVuCuugtsHyZoTvsOBuvonN/UDBvl0kH+BUxvbo= github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= @@ -1795,8 +1787,8 @@ github.com/kylelemons/godebug v0.0.0-20160406211939-eadb3ce320cb/go.mod h1:B69LE github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg= +github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/laher/mergefs v0.1.1 h1:nV2bTS57vrmbMxeR6uvJpI8LyGl3QHj4bLBZO3aUV58= github.com/laher/mergefs v0.1.1/go.mod h1:FSY1hYy94on4Tz60waRMGdO1awwS23BacqJlqf9lJ9Q= @@ -1805,7 +1797,6 @@ github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtB github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw= github.com/leanovate/gopter v0.2.4/go.mod h1:gNcbPWNEWRe4lm+bycKqxUYoH5uoVje5SkOJ3uoLer8= github.com/leesper/go_rng v0.0.0-20190531154944-a612b043e353/go.mod h1:N0SVk0uhy+E1PZ3C9ctsPRlvOPAFPkCNlcPBDkt0N3U= -github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/leodido/ragel-machinery v0.0.0-20181214104525-299bdde78165/go.mod h1:WZxr2/6a/Ar9bMDc2rN/LJrE/hF6bXE4LPyDSIxwAfg= github.com/leoluk/perflib_exporter v0.1.0/go.mod h1:rpV0lYj7lemdTm31t7zpCqYqPnw7xs86f+BaaNBVYFM= @@ -1870,6 +1861,7 @@ github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= @@ -2337,8 +2329,9 @@ github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUA github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= -github.com/rs/cors v1.8.0 h1:P2KMzcFwrPoSjkF1WLRPsp3UMLyql8L4v9hQpVeK5so= github.com/rs/cors v1.8.0/go.mod h1:EBwu+T5AvHOcXwvZIkQFjUN6s8Czyqw12GL/Y0tUyRM= +github.com/rs/cors v1.8.2 h1:KCooALfAYGs415Cwu5ABvv9n9509fSiG5SQJn/AQo4U= +github.com/rs/cors v1.8.2/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.4.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= @@ -2974,6 +2967,7 @@ golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210903162142-ad29c8ab022f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211020060615-d418f374d309/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -3617,9 +3611,6 @@ gopkg.in/fsnotify/fsnotify.v1 v1.4.7 h1:XNNYLJHt73EyYiCZi6+xjupS9CpvmiDgjPTAjrBl gopkg.in/fsnotify/fsnotify.v1 v1.4.7/go.mod h1:Fyux9zXlo4rWoMSIzpn9fDAYjalPqJ/K1qJ27s+7ltE= gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= -gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= -gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= -gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= gopkg.in/gorethink/gorethink.v3 v3.0.5/go.mod h1:+3yIIHJUGMBK+wyPH+iN5TP+88ikFDfZdqTlK3Y9q8I= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= From 4fbc481d1f7df27939647f583093aabf5e5d4fbb Mon Sep 17 00:00:00 2001 From: Alexander Kubyshkin Date: Thu, 21 Apr 2022 20:49:52 +0300 Subject: [PATCH 080/120] =?UTF-8?q?Fix=20Date=20picker=20content=20when=20?= =?UTF-8?q?pane=20is=20splitted=20(#46900).=20Show=20narrow(m=E2=80=A6=20(?= =?UTF-8?q?#47206)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix Date picker content when pane is splitted (#46900). Show narrow(mobile) content version. * Change from boolean to value override and use it in calendar styles. Change calendar modal to be in center of screen. * Be sure width division only happens on split view Co-authored-by: Kristina Durivage --- .../DateTimePickers/TimeRangePicker.tsx | 3 +++ .../TimeRangePicker/TimePickerCalendar.tsx | 1 - .../TimeRangePicker/TimePickerContent.tsx | 21 +++++++------------ .../features/explore/ExploreTimeControls.tsx | 1 + 4 files changed, 11 insertions(+), 15 deletions(-) diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.tsx index 167cc9d4e6a..449e905e3e1 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.tsx @@ -45,6 +45,7 @@ export interface TimeRangePickerProps extends Themeable { onZoom: () => void; history?: TimeRange[]; hideQuickRanges?: boolean; + widthOverride?: number; } export interface State { @@ -68,6 +69,7 @@ export function UnthemedTimeRangePicker(props: TimeRangePickerProps): ReactEleme onChangeTimeZone, onChangeFiscalYearStartMonth, hideQuickRanges, + widthOverride, } = props; const onChange = (timeRange: TimeRange) => { @@ -129,6 +131,7 @@ export function UnthemedTimeRangePicker(props: TimeRangePickerProps): ReactEleme quickOptions={quickOptions} history={history} showHistory + widthOverride={widthOverride} onChangeTimeZone={onChangeTimeZone} onChangeFiscalYearStartMonth={onChangeFiscalYearStartMonth} hideQuickRanges={hideQuickRanges} diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerCalendar.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerCalendar.tsx index 1f0e4c0e3ac..27ecce05cd9 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerCalendar.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerCalendar.tsx @@ -37,7 +37,6 @@ export const getStyles = (theme: GrafanaTheme2, isReversed = false) => { modal: css` position: fixed; top: 20%; - left: 25%; width: 100%; z-index: ${theme.zIndex.modal}; `, diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerContent.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerContent.tsx index 244578d35fe..f3a3dd0d406 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerContent.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerContent.tsx @@ -1,7 +1,6 @@ import { GrafanaTheme2, isDateTime, rangeUtil, RawTimeRange, TimeOption, TimeRange, TimeZone } from '@grafana/data'; import { css, cx } from '@emotion/css'; import React, { memo, useMemo, useState } from 'react'; -import { useMedia } from 'react-use'; import { stylesFactory, useTheme2 } from '../../../themes'; import { CustomScrollbar } from '../../CustomScrollbar/CustomScrollbar'; import { Icon } from '../../Icon/Icon'; @@ -29,6 +28,7 @@ interface Props { /** Reverse the order of relative and absolute range pickers. Used to left align the picker in forms */ isReversed?: boolean; hideQuickRanges?: boolean; + widthOverride?: number; } export interface PropsWithScreenSize extends Props { @@ -60,7 +60,7 @@ export const TimePickerContentWithScreenSize: React.FC = (p const isContainerTall = (isFullscreen && showHistory) || (!isFullscreen && ((showHistory && !isHistoryEmpty) || !hideQuickRanges)); const theme = useTheme2(); - const styles = getStyles(theme, isReversed, hideQuickRanges, isContainerTall); + const styles = getStyles(theme, isReversed, hideQuickRanges, isContainerTall, isFullscreen); const historyOptions = mapToHistoryOptions(history, timeZone); const timeOption = useTimeOption(value.raw, quickOptions); const [searchTerm, setSearchQuery] = useState(''); @@ -112,9 +112,9 @@ export const TimePickerContentWithScreenSize: React.FC = (p }; export const TimePickerContent: React.FC = (props) => { + const { widthOverride } = props; const theme = useTheme2(); - const isFullscreen = useMedia(`(min-width: ${theme.breakpoints.values.lg}px)`); - + const isFullscreen = (widthOverride || window.innerWidth) >= theme.breakpoints.values.lg; return ; }; @@ -251,22 +251,18 @@ const useTimeOption = (raw: RawTimeRange, quickOptions: TimeOption[]): TimeOptio }, [raw, quickOptions]); }; -const getStyles = stylesFactory((theme: GrafanaTheme2, isReversed, hideQuickRanges, isContainerTall) => { +const getStyles = stylesFactory((theme: GrafanaTheme2, isReversed, hideQuickRanges, isContainerTall, isFullscreen) => { return { container: css` background: ${theme.colors.background.primary}; box-shadow: ${theme.shadows.z3}; position: absolute; z-index: ${theme.zIndex.dropdown}; - width: 546px; + width: ${isFullscreen ? '546px' : '262px'}; top: 116%; border-radius: 2px; border: 1px solid ${theme.colors.border.weak}; ${isReversed ? 'left' : 'right'}: 0; - - @media only screen and (max-width: ${theme.breakpoints.values.lg}px) { - width: 262px; - } `, body: css` display: flex; @@ -282,13 +278,10 @@ const getStyles = stylesFactory((theme: GrafanaTheme2, isReversed, hideQuickRang order: ${isReversed ? 1 : 0}; `, rightSide: css` - width: 40% !important; + width: ${isFullscreen ? '40%' : '100%'}; !important; border-right: ${isReversed ? `1px solid ${theme.colors.border.weak}` : 'none'}; display: flex; flex-direction: column; - @media only screen and (max-width: ${theme.breakpoints.values.lg}px) { - width: 100% !important; - } `, timeRangeFilter: css` padding: ${theme.spacing(1)}; diff --git a/public/app/features/explore/ExploreTimeControls.tsx b/public/app/features/explore/ExploreTimeControls.tsx index ed8b5a2ba66..2047149cc3d 100644 --- a/public/app/features/explore/ExploreTimeControls.tsx +++ b/public/app/features/explore/ExploreTimeControls.tsx @@ -92,6 +92,7 @@ export class ExploreTimeControls extends Component { {...timePickerCommonProps} timeSyncButton={timeSyncButton} isSynced={syncedTimes} + widthOverride={splitted ? window.innerWidth / 2 : undefined} onChange={this.onChangeTimePicker} onChangeTimeZone={onChangeTimeZone} onChangeFiscalYearStartMonth={onChangeFiscalYearStartMonth} From 53a6c0210dc1401b1dafb5dbd411163f88b154ae Mon Sep 17 00:00:00 2001 From: Yuriy Tseretyan Date: Thu, 21 Apr 2022 14:58:05 -0400 Subject: [PATCH 081/120] Alerting: tests for ticker (#47986) --- pkg/services/alerting/ticker_test.go | 236 +++++++++++++-------------- 1 file changed, 117 insertions(+), 119 deletions(-) diff --git a/pkg/services/alerting/ticker_test.go b/pkg/services/alerting/ticker_test.go index bb679750a51..0db3c6b777f 100644 --- a/pkg/services/alerting/ticker_test.go +++ b/pkg/services/alerting/ticker_test.go @@ -1,121 +1,119 @@ package alerting -// import ( -// "testing" -// "time" -// -// "github.com/benbjohnson/clock" -// ) -// -// func inspectTick(tick time.Time, last time.Time, offset time.Duration, t *testing.T) { -// if !tick.Equal(last.Add(time.Duration(1) * time.Second)) { -// t.Fatalf("expected a tick 1 second more than prev, %s. got: %s", last, tick) -// } -// } -// -// returns the new last tick seen -// func assertAdvanceUntil(ticker *Ticker, last, desiredLast time.Time, offset, wait time.Duration, t *testing.T) time.Time { -// for { -// select { -// case tick := <-ticker.C: -// inspectTick(tick, last, offset, t) -// last = tick -// case <-time.NewTimer(wait).C: -// if last.Before(desiredLast) { -// t.Fatalf("waited %s for ticker to advance to %s, but only went up to %s", wait, desiredLast, last) -// } -// if last.After(desiredLast) { -// t.Fatalf("timer advanced too far. should only have gone up to %s, but it went up to %s", desiredLast, last) -// } -// return last -// } -// } -// } -// -// func assertNoAdvance(ticker *Ticker, desiredLast time.Time, wait time.Duration, t *testing.T) { -// for { -// select { -// case tick := <-ticker.C: -// t.Fatalf("timer should have stayed at %s, instead it advanced to %s", desiredLast, tick) -// case <-time.NewTimer(wait).C: -// return -// } -// } -// } -// -// func TestTickerRetro1Hour(t *testing.T) { -// offset := time.Duration(10) * time.Second -// last := time.Unix(0, 0) -// mock := clock.NewMock() -// mock.Add(time.Duration(1) * time.Hour) -// desiredLast := mock.Now().Add(-offset) -// ticker := NewTicker(last, offset, mock) -// -// last = assertAdvanceUntil(ticker, last, desiredLast, offset, time.Duration(10)*time.Millisecond, t) -// assertNoAdvance(ticker, last, time.Duration(500)*time.Millisecond, t) -// -// } -// -// func TestAdvanceWithUpdateOffset(t *testing.T) { -// offset := time.Duration(10) * time.Second -// last := time.Unix(0, 0) -// mock := clock.NewMock() -// mock.Add(time.Duration(1) * time.Hour) -// desiredLast := mock.Now().Add(-offset) -// ticker := NewTicker(last, offset, mock) -// -// last = assertAdvanceUntil(ticker, last, desiredLast, offset, time.Duration(10)*time.Millisecond, t) -// assertNoAdvance(ticker, last, time.Duration(500)*time.Millisecond, t) -// -// // lowering offset should see a few more ticks -// offset = time.Duration(5) * time.Second -// ticker.updateOffset(offset) -// desiredLast = mock.Now().Add(-offset) -// last = assertAdvanceUntil(ticker, last, desiredLast, offset, time.Duration(9)*time.Millisecond, t) -// assertNoAdvance(ticker, last, time.Duration(500)*time.Millisecond, t) -// -// // advancing clock should see even more ticks -// mock.Add(time.Duration(1) * time.Hour) -// desiredLast = mock.Now().Add(-offset) -// last = assertAdvanceUntil(ticker, last, desiredLast, offset, time.Duration(8)*time.Millisecond, t) -// assertNoAdvance(ticker, last, time.Duration(500)*time.Millisecond, t) -// -// } -// -// func getCase(lastSeconds, offsetSeconds int) (time.Time, time.Duration) { -// last := time.Unix(int64(lastSeconds), 0) -// offset := time.Duration(offsetSeconds) * time.Second -// return last, offset -// } -// -// func TestTickerNoAdvance(t *testing.T) { -// -// // it's 00:01:00 now. what are some cases where we don't want the ticker to advance? -// mock := clock.NewMock() -// mock.Add(time.Duration(60) * time.Second) -// -// type Case struct { -// last int -// offset int -// } -// -// // note that some cases add up to now, others go into the future -// cases := []Case{ -// {50, 10}, -// {50, 30}, -// {59, 1}, -// {59, 10}, -// {59, 30}, -// {60, 1}, -// {60, 10}, -// {60, 30}, -// {90, 1}, -// {90, 10}, -// {90, 30}, -// } -// for _, c := range cases { -// last, offset := getCase(c.last, c.offset) -// ticker := NewTicker(last, offset, mock) -// assertNoAdvance(ticker, last, time.Duration(500)*time.Millisecond, t) -// } -// } +import ( + "context" + "fmt" + "math/rand" + "sync" + "testing" + "time" + + "github.com/benbjohnson/clock" + "github.com/stretchr/testify/require" +) + +func TestTicker(t *testing.T) { + readChanOrFail := func(t *testing.T, ctx context.Context, c chan time.Time) time.Time { + t.Helper() + select { + case tick := <-c: + return tick + case <-ctx.Done(): + require.Failf(t, fmt.Sprintf("%v", ctx.Err()), "timeout reading the channel") + default: + require.Failf(t, "channel is empty but it should have a tick", "") + } + return time.Time{} + } + t.Run("should not drop ticks", func(t *testing.T) { + clk := clock.NewMock() + intervalSec := rand.Int63n(100) + 10 + interval := time.Duration(intervalSec) * time.Second + last := clk.Now() + ticker := NewTicker(last, 0, clk, intervalSec) + + ticks := rand.Intn(9) + 1 + jitter := rand.Int63n(int64(interval) - 1) + + clk.Add(time.Duration(ticks)*interval + time.Duration(jitter)) + + w := sync.WaitGroup{} + w.Add(1) + regTicks := make([]time.Time, 0, ticks) + go func() { + for timestamp := range ticker.C { + regTicks = append(regTicks, timestamp) + if len(regTicks) == ticks { + w.Done() + } + } + }() + w.Wait() + + require.Len(t, regTicks, ticks) + + t.Run("ticks should monotonically increase", func(t *testing.T) { + for i := 1; i < len(regTicks); i++ { + previous := regTicks[i-1] + current := regTicks[i] + require.Equal(t, interval, current.Sub(previous)) + } + }) + }) + + t.Run("should not put anything to channel until it's time", func(t *testing.T) { + clk := clock.NewMock() + intervalSec := rand.Int63n(9) + 1 + interval := time.Duration(intervalSec) * time.Second + last := clk.Now() + ticker := NewTicker(last, 0, clk, intervalSec) + expectedTick := clk.Now().Add(interval) + for { + require.Empty(t, ticker.C) + clk.Add(time.Duration(rand.Int31n(500)+100) * time.Millisecond) + if clk.Now().After(expectedTick) { + break + } + } + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + t.Cleanup(func() { + cancel() + }) + actual := readChanOrFail(t, ctx, ticker.C) + require.Equal(t, expectedTick, actual) + }) + + t.Run("should put the tick in the channel immediately if it is behind", func(t *testing.T) { + clk := clock.NewMock() + intervalSec := rand.Int63n(9) + 1 + interval := time.Duration(intervalSec) * time.Second + last := clk.Now() + ticker := NewTicker(last, 0, clk, intervalSec) + + // We can expect the first tick to be at a consistent interval. Take a snapshot of the clock now, before we advance it. + expectedTick := clk.Now().Add(interval) + + require.Empty(t, ticker.C) + + clk.Add(interval) // advance the clock by the interval to make the ticker tick the first time. + clk.Add(interval) // advance the clock by the interval to make the ticker tick the second time. + + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + t.Cleanup(func() { + cancel() + }) + + // Irregardless of wall time, the first tick should be initial clock + interval. + actual1 := readChanOrFail(t, ctx, ticker.C) + require.Equal(t, expectedTick, actual1) + + var actual2 time.Time + require.Eventually(t, func() bool { + actual2 = readChanOrFail(t, ctx, ticker.C) + return true + }, time.Second, 10*time.Millisecond) + + // Similarly, the second tick should be last tick + interval irregardless of wall time. + require.Equal(t, expectedTick.Add(interval), actual2) + }) +} From 9f0b6a57547988ee8665785e3b3f0381534db2a4 Mon Sep 17 00:00:00 2001 From: Artur Wierzbicki Date: Thu, 21 Apr 2022 23:27:43 +0400 Subject: [PATCH 082/120] Storage: refactor filtering, improve performance (#47403) * Storage: refactor filtering, improve performance * added a comment to `newpathfilter` * after merge fixes --- go.mod | 1 + go.sum | 1 + pkg/infra/filestorage/api.go | 66 +---- pkg/infra/filestorage/cdk_blob_filestorage.go | 6 +- pkg/infra/filestorage/db_filestorage.go | 40 +-- pkg/infra/filestorage/filter.go | 249 ++++++++++++++++++ pkg/infra/filestorage/filter_test.go | 135 ++++++++++ pkg/infra/filestorage/fs_integration_test.go | 63 +++-- pkg/infra/filestorage/test_utils.go | 2 +- pkg/infra/filestorage/wrapper.go | 147 ++++------- pkg/infra/filestorage/wrapper_test.go | 151 ----------- pkg/services/store/storage_disk.go | 2 +- 12 files changed, 483 insertions(+), 380 deletions(-) create mode 100644 pkg/infra/filestorage/filter.go create mode 100644 pkg/infra/filestorage/filter_test.go diff --git a/go.mod b/go.mod index deb77271dfe..521db1c19a0 100644 --- a/go.mod +++ b/go.mod @@ -246,6 +246,7 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.13.2 github.com/Azure/azure-sdk-for-go/sdk/keyvault/azkeys v0.4.0 github.com/Azure/go-autorest/autorest/adal v0.9.17 + github.com/armon/go-radix v1.0.0 github.com/golang-migrate/migrate/v4 v4.7.0 github.com/grafana/dskit v0.0.0-20211011144203-3a88ec0b675f github.com/grafana/thema v0.0.0-20220413232647-fc54c169b508 diff --git a/go.sum b/go.sum index 526466f2ed7..071e5682a5b 100644 --- a/go.sum +++ b/go.sum @@ -347,6 +347,7 @@ github.com/armon/go-metrics v0.3.8/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4 github.com/armon/go-metrics v0.3.10 h1:FR+drcQStOe+32sYyJYyZ7FIdgoGGBnwLl+flodp8Uo= github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= diff --git a/pkg/infra/filestorage/api.go b/pkg/infra/filestorage/api.go index 93515f2c30e..0a1712e8657 100644 --- a/pkg/infra/filestorage/api.go +++ b/pkg/infra/filestorage/api.go @@ -60,13 +60,6 @@ type UpsertFileCommand struct { Properties map[string]string } -type PathFilters struct { - allowedPrefixes []string - disallowedPrefixes []string - allowedPaths []string - disallowedPaths []string -} - func toLower(list []string) []string { if list == nil { return nil @@ -78,63 +71,6 @@ func toLower(list []string) []string { return lower } -func allowAllPathFilters() *PathFilters { - return NewPathFilters(nil, nil, nil, nil) -} - -//nolint:deadcode,unused -func denyAllPathFilters() *PathFilters { - return NewPathFilters([]string{}, []string{}, nil, nil) -} - -func NewPathFilters(allowedPrefixes []string, allowedPaths []string, disallowedPrefixes []string, disallowedPaths []string) *PathFilters { - return &PathFilters{ - allowedPrefixes: toLower(allowedPrefixes), - allowedPaths: toLower(allowedPaths), - disallowedPaths: toLower(disallowedPaths), - disallowedPrefixes: toLower(disallowedPrefixes), - } -} - -func (f *PathFilters) isDenyAll() bool { - return f.allowedPaths != nil && f.allowedPrefixes != nil && (len(f.allowedPaths)+len(f.allowedPrefixes) == 0) -} - -func (f *PathFilters) IsAllowed(path string) bool { - if f == nil { - return true - } - - path = strings.ToLower(path) - for i := range f.disallowedPaths { - if f.disallowedPaths[i] == path { - return false - } - } - - for i := range f.disallowedPrefixes { - if strings.HasPrefix(path, f.disallowedPrefixes[i]) { - return false - } - } - - if f.allowedPrefixes == nil && f.allowedPaths == nil { - return true - } - - for i := range f.allowedPaths { - if f.allowedPaths[i] == path { - return true - } - } - for i := range f.allowedPrefixes { - if strings.HasPrefix(path, f.allowedPrefixes[i]) { - return true - } - } - return false -} - type ListResponse struct { Files []*File HasMore bool @@ -146,7 +82,7 @@ type ListOptions struct { WithFiles bool WithFolders bool WithContents bool - *PathFilters + Filter PathFilter } type FileStorage interface { diff --git a/pkg/infra/filestorage/cdk_blob_filestorage.go b/pkg/infra/filestorage/cdk_blob_filestorage.go index 53f165fac9a..988b8749497 100644 --- a/pkg/infra/filestorage/cdk_blob_filestorage.go +++ b/pkg/infra/filestorage/cdk_blob_filestorage.go @@ -24,11 +24,11 @@ type cdkBlobStorage struct { bucket *blob.Bucket } -func NewCdkBlobStorage(log log.Logger, bucket *blob.Bucket, rootFolder string, pathFilters *PathFilters) FileStorage { +func NewCdkBlobStorage(log log.Logger, bucket *blob.Bucket, rootFolder string, filter PathFilter) FileStorage { return newWrapper(log, &cdkBlobStorage{ log: log, bucket: bucket, - }, pathFilters, rootFolder) + }, filter, rootFolder) } func (c cdkBlobStorage) Get(ctx context.Context, filePath string) (*File, error) { @@ -266,7 +266,7 @@ func (c cdkBlobStorage) list(ctx context.Context, folderPath string, paging *Pag path := obj.Key lowerPath := strings.ToLower(path) - allowed := options.IsAllowed(lowerPath) + allowed := options.Filter.IsAllowed(lowerPath) if obj.IsDir && recursive && !visitedFolders[lowerPath] { iterators = append([]*blob.ListIterator{c.bucket.List(&blob.ListOptions{ diff --git a/pkg/infra/filestorage/db_filestorage.go b/pkg/infra/filestorage/db_filestorage.go index ae4db90b713..3d826af9095 100644 --- a/pkg/infra/filestorage/db_filestorage.go +++ b/pkg/infra/filestorage/db_filestorage.go @@ -31,11 +31,11 @@ type dbFileStorage struct { log log.Logger } -func NewDbStorage(log log.Logger, db *sqlstore.SQLStore, pathFilters *PathFilters, rootFolder string) FileStorage { +func NewDbStorage(log log.Logger, db *sqlstore.SQLStore, filter PathFilter, rootFolder string) FileStorage { return newWrapper(log, &dbFileStorage{ log: log, db: db, - }, pathFilters, rootFolder) + }, filter, rootFolder) } func (s dbFileStorage) getProperties(sess *sqlstore.DBSession, lowerCasePaths []string) (map[string]map[string]string, error) { @@ -268,40 +268,8 @@ func (s dbFileStorage) List(ctx context.Context, folderPath string, paging *Pagi sess.Where("path LIKE ?", "%/") } - if len(options.PathFilters.allowedPrefixes)+len(options.PathFilters.allowedPaths) > 0 { - queries := make([]string, 0) - args := make([]interface{}, 0) - for _, prefix := range options.PathFilters.allowedPrefixes { - queries = append(queries, "LOWER(path) LIKE ?") - args = append(args, prefix+"%") - } - - for _, path := range options.PathFilters.allowedPaths { - queries = append(queries, "LOWER(path) = ?") - args = append(args, path) - } - sess.Where(strings.Join(queries, " OR "), args...) - } - - if options.PathFilters.disallowedPrefixes != nil && len(options.PathFilters.disallowedPrefixes) > 0 { - queries := make([]string, 0) - args := make([]interface{}, 0) - for _, prefix := range options.PathFilters.disallowedPrefixes { - queries = append(queries, "LOWER(path) NOT LIKE ?") - args = append(args, prefix+"%") - } - sess.Where(strings.Join(queries, " AND "), args...) - } - - if options.PathFilters.disallowedPaths != nil && len(options.PathFilters.disallowedPaths) > 0 { - queries := make([]string, 0) - args := make([]interface{}, 0) - for _, path := range options.PathFilters.disallowedPaths { - queries = append(queries, "LOWER(path) != ?") - args = append(args, path) - } - sess.Where(strings.Join(queries, " AND "), args...) - } + sqlFilter := options.Filter.asSQLFilter() + sess.Where(sqlFilter.Where, sqlFilter.Args...) sess.OrderBy("path") diff --git a/pkg/infra/filestorage/filter.go b/pkg/infra/filestorage/filter.go new file mode 100644 index 00000000000..ce6ec130ad2 --- /dev/null +++ b/pkg/infra/filestorage/filter.go @@ -0,0 +1,249 @@ +package filestorage + +import ( + "strings" + + "github.com/armon/go-radix" + "github.com/grafana/grafana/pkg/services/accesscontrol" +) + +type treeValue string + +const ( + treeValueDisallowedPath treeValue = "!" + treeValueDisallowedPrefix treeValue = "!*" + treeValueAllowedPath treeValue = "" + treeValueAllowedPrefix treeValue = "*" +) + +type PathFilter interface { + IsAllowed(path string) bool + ToString() string + + asSQLFilter() accesscontrol.SQLFilter +} + +// NewPathFilter factory function for a tree-based PathFilter +// `nil` and empty arrays are treated in a different way. The PathFilter will not perform checks associated with a `nil` array, examples: +// - `allowedPrefixes` & `allowedPaths` are nil -> all paths are allowed (unless included in `disallowedX` arrays) +// - `allowedPrefixes` & `allowedPaths` are both empty -> no paths are allowed, regardless of what is inside `disallowedX` arrays +// - `allowedPrefixes` is nil, `allowedPaths` is not nil. -> only paths specified in `allowedPaths` are allowed (unless included in `disallowedX` arrays) +func NewPathFilter(allowedPrefixes []string, allowedPaths []string, disallowedPrefixes []string, disallowedPaths []string) PathFilter { + if allowedPrefixes != nil && allowedPaths != nil && (len(allowedPrefixes)+len(allowedPaths) == 0) { + return NewDenyAllPathFilter() + } + + if allowedPaths == nil && allowedPrefixes == nil && (len(disallowedPaths)+len(disallowedPrefixes) == 0) { + return NewAllowAllPathFilter() + } + + return &radixTreePathFilter{ + tree: createRadixTree(toLower(allowedPrefixes), toLower(allowedPaths), toLower(disallowedPrefixes), toLower(disallowedPaths)), + } +} + +func NewAllowAllPathFilter() PathFilter { + return &radixTreePathFilter{ + tree: createRadixTree([]string{Delimiter}, nil, nil, nil), + } +} + +func NewDenyAllPathFilter() PathFilter { + return &radixTreePathFilter{ + tree: createRadixTree(nil, nil, []string{Delimiter}, nil), + } +} + +type radixTreePathFilter struct { + tree *radix.Tree +} + +func (r *radixTreePathFilter) asSQLFilter() accesscontrol.SQLFilter { + denyConditions := make([]string, 0) + denyArgs := make([]interface{}, 0) + + allowConditions := make([]string, 0) + allowArgs := make([]interface{}, 0) + + r.tree.Walk(func(path string, v interface{}) bool { + switch v.(treeValue) { + case treeValueAllowedPrefix: + allowConditions = append(allowConditions, "LOWER(PATH) LIKE ?") + allowArgs = append(allowArgs, path+"%") + case treeValueAllowedPath: + allowConditions = append(allowConditions, "LOWER(PATH) = ?") + allowArgs = append(allowArgs, path) + case treeValueDisallowedPrefix: + denyConditions = append(denyConditions, "LOWER(PATH) NOT LIKE ? ") + denyArgs = append(denyArgs, path+"%") + case treeValueDisallowedPath: + denyConditions = append(denyConditions, "LOWER(PATH) != ?") + denyArgs = append(denyArgs, path) + } + return false + }) + + if len(denyConditions)+len(allowConditions) == 0 { + return accesscontrol.SQLFilter{Where: "1 = 1", Args: nil} + } + + allowQuery := strings.Join(allowConditions, " OR ") + denyQuery := strings.Join(denyConditions, " AND ") + + if len(allowConditions) == 0 { + return accesscontrol.SQLFilter{ + Where: denyQuery, + Args: denyArgs, + } + } + + if len(denyConditions) == 0 { + return accesscontrol.SQLFilter{ + Where: allowQuery, + Args: allowArgs, + } + } + + return accesscontrol.SQLFilter{ + Where: "(" + allowQuery + ") AND ( " + denyQuery + " )", + Args: append(allowArgs, denyArgs...), + } +} + +func (r *radixTreePathFilter) ToString() string { + builder := strings.Builder{} + r.tree.Walk(func(s string, v interface{}) bool { + if builder.Len() != 0 { + builder.WriteString("\n") + } + switch v.(treeValue) { + case treeValueAllowedPrefix: + builder.WriteString(s) + builder.WriteString("*") + case treeValueAllowedPath: + builder.WriteString(s) + case treeValueDisallowedPrefix: + builder.WriteString("!") + builder.WriteString(s) + builder.WriteString("*") + case treeValueDisallowedPath: + builder.WriteString("!") + builder.WriteString(s) + } + return false + }) + return builder.String() +} + +func (r *radixTreePathFilter) IsAllowed(path string) bool { + path = strings.ToLower(path) + + allowed := false + denied := false + r.tree.WalkPath(path, func(s string, v interface{}) bool { + if v == treeValueDisallowedPrefix || (s == path && v == treeValueDisallowedPath) { + denied = true + return true + } + + if v == treeValueAllowedPrefix || (s == path && v == treeValueAllowedPath) { + allowed = true + // have to keep traversing to look for explicit denies + } + return false + }) + + if denied { + return false + } + + return allowed +} + +func createRadixTree(allowedPrefixes []string, allowedPaths []string, disallowedPrefixes []string, disallowedPaths []string) *radix.Tree { + tree := radix.New() + for _, disallowedPrefix := range disallowedPrefixes { + tree.Insert(disallowedPrefix, treeValueDisallowedPrefix) + } + + for _, disallowedPath := range disallowedPaths { + tree.Insert(disallowedPath, treeValueDisallowedPath) + } + + for _, allowedPath := range allowedPaths { + isDenied := false + tree.WalkPath(allowedPath, func(s string, v interface{}) bool { + if v == treeValueDisallowedPrefix || s == allowedPath { + isDenied = true + return true + } + return false + }) + + if !isDenied { + tree.Insert(allowedPath, treeValueAllowedPath) + } + } + + for _, allowedPrefix := range allowedPrefixes { + isDenied := false + tree.WalkPath(allowedPrefix, func(s string, v interface{}) bool { + if v == treeValueDisallowedPrefix { + isDenied = true + return true + } + return false + }) + + if !isDenied { + tree.Insert(allowedPrefix, treeValueAllowedPrefix) + } + } + + return tree +} + +type allOfPathFilter struct { + filters []PathFilter +} + +func (m allOfPathFilter) IsAllowed(path string) bool { + for _, filter := range m.filters { + isAllowed := filter.IsAllowed(path) + if !isAllowed { + return false + } + } + return true +} + +func (m allOfPathFilter) ToString() string { + s := strings.Builder{} + for _, filter := range m.filters { + if s.Len() != 0 { + s.WriteString("\n\nAND\n") + } + s.WriteString(filter.ToString()) + } + return s.String() +} + +func (m allOfPathFilter) asSQLFilter() accesscontrol.SQLFilter { + queries := make([]string, 0) + + args := make([]interface{}, 0) + for _, filter := range m.filters { + sqlFilter := filter.asSQLFilter() + queries = append(queries, "("+sqlFilter.Where+")") + args = append(args, sqlFilter.Args...) + } + + return accesscontrol.SQLFilter{ + Where: "(" + strings.Join(queries, " AND ") + ")", + Args: args, + } +} + +func newAndPathFilter(filters ...PathFilter) PathFilter { + return &allOfPathFilter{filters: filters} +} diff --git a/pkg/infra/filestorage/filter_test.go b/pkg/infra/filestorage/filter_test.go new file mode 100644 index 00000000000..20f69c48870 --- /dev/null +++ b/pkg/infra/filestorage/filter_test.go @@ -0,0 +1,135 @@ +package filestorage + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestAuth(t *testing.T) { + var tests = []struct { + name string + filter PathFilter + expectedDeny []string + expectedAllow []string + }{ + { + name: "can not access anything without an allow rule (deny by default)", + filter: NewPathFilter([]string{"/b"}, nil, nil, nil), + expectedDeny: []string{ + "/a/b.jpg", + "/a/", + "/c", + "/", + }, + expectedAllow: []string{ + "/b/", + "/b/a.jpg", + }, + }, + { + name: "can access any path with / prefix and no denies", + filter: NewPathFilter([]string{"/"}, nil, nil, nil), + expectedAllow: []string{ + "/a/b/c/d/e.jpg", + }, + }, + { + name: "can not access paths which are explicitly denied", + filter: NewPathFilter([]string{"/"}, nil, []string{"/x/"}, []string{"/a/b/c/d/e.jpg"}), + expectedDeny: []string{ + "/a/b/c/d/e.jpg", + "/x/", + "/x/a.jpg", + "/x/a/b.jpg", + }, + expectedAllow: []string{ + "/a/b/c/d/x.jpg", + "/a/b/c/d/", + }, + }, + { + name: "can not access paths with denied prefixes - parent folder", + filter: NewPathFilter([]string{"/"}, nil, []string{"/a/b/c/"}, []string{"/a/b/c/d/e.jpg"}), + expectedDeny: []string{ + "/a/b/c/d/e.jpg", + }, + expectedAllow: []string{ + "/a/b/x/d/e.jpg", + }, + }, + { + name: "can not access paths with denied prefixes - root folder", + filter: NewPathFilter([]string{"/"}, nil, []string{"/"}, nil), + expectedDeny: []string{ + "/a/b/c/d/e.jpg", + "/", + "/a.jpg", + }, + }, + { + name: "can not access paths with denied prefixes - same folder", + filter: NewPathFilter([]string{"/"}, nil, []string{"/a/b/c/d/e"}, nil), + expectedDeny: []string{ + "/a/b/c/d/e.jpg", + }, + }, + { + name: "can not access paths with denied prefixes - parent folder with a dot", + filter: NewPathFilter([]string{"/"}, nil, []string{"/a/b/c/d."}, nil), + expectedDeny: []string{ + "/a/b/c/d.e/f.jpg", + }, + expectedAllow: []string{ + "/a/b/c/e.jpg", + }, + }, + { + name: "can not access paths with denied prefixes even if path is explicitly allowed - deny takes priority", + filter: NewPathFilter([]string{"/"}, []string{"/a/b/c/d/f.jpg"}, []string{"/a/"}, nil), + expectedDeny: []string{ + "/a/b/c/d/f.jpg", + }, + }, + { + name: "multiple rules", + filter: NewPathFilter( + []string{"/gitB/", "/s3/folder/", "/gitC/"}, + []string{"/gitA/dashboard2.json"}, + []string{"/s3/folder/nested/"}, + []string{"/gitC/nestedC/"}, + ), + expectedAllow: []string{ + "/gitA/dashboard2.json", + "/gitB/", + "/gitB/nested/", + "/gitB/nested/dashboard.json", + "/gitB/nested2/dashboard2.json", + "/gitC/", + "/gitC/nestedC/dashboardC.json", + "/s3/folder/", + "/s3/folder/file.jpg", + "/s3/folder/nested2/file.jpg", + }, + expectedDeny: []string{ + "/gitA/dashboard.json", // not explicitly allowed + "/s3/folder/nested/dashboard.json", // denied with '/s3/folder/nested/' prefix + "/s3/nestedC/", // not explicitly allowed + "/s3/anyFile.jpg", // not explicitly allowed + "/s3/", // not explicitly allowed + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + for _, expectedAllow := range tt.expectedAllow { + require.Truef(t, tt.filter.IsAllowed(expectedAllow), "expected access to %s", expectedAllow) + } + + for _, expectedDeny := range tt.expectedDeny { + require.Falsef(t, tt.filter.IsAllowed(expectedDeny), "expected no access to %s", expectedDeny) + } + }) + } +} diff --git a/pkg/infra/filestorage/fs_integration_test.go b/pkg/infra/filestorage/fs_integration_test.go index 1a756545a2c..db93761e5d8 100644 --- a/pkg/infra/filestorage/fs_integration_test.go +++ b/pkg/infra/filestorage/fs_integration_test.go @@ -95,7 +95,6 @@ func runTests(createCases func() []fsTestCase, t *testing.T) { setupLocalFsNestedPath := func() { commonSetup() tmpDir, err := ioutil.TempDir("", "") - tempDir = tmpDir if err != nil { t.Fatal(err) } @@ -318,6 +317,13 @@ func TestFsStorage(t *testing.T) { Properties: map[string]string{"prop1": "val1"}, }, }, + cmdUpsert{ + cmd: UpsertFileCommand{ + Path: "/dashboards/dashboards/file-inner.jpg", + Contents: emptyContents, + Properties: map[string]string{"prop1": "val1"}, + }, + }, queryListFiles{ input: queryListFilesInput{path: "/folder1/file-inner.jp", options: &ListOptions{Recursive: true}}, list: checks(listSize(0), listHasMore(false), listLastPath("")), @@ -355,6 +361,13 @@ func TestFsStorage(t *testing.T) { checks(fPath("/folder1/file-inner.jpg"), fName("file-inner.jpg"), fProperties(map[string]string{"prop1": "val1"})), }, }, + queryListFiles{ + input: queryListFilesInput{path: "/dashboards/dashboards/file-inner.jpg", options: &ListOptions{Recursive: true, WithFiles: true}}, + list: checks(listSize(1), listHasMore(false), listLastPath("/dashboards/dashboards/file-inner.jpg")), + files: [][]interface{}{ + checks(fPath("/dashboards/dashboards/file-inner.jpg"), fName("file-inner.jpg")), + }, + }, queryListFiles{ input: queryListFilesInput{path: "/folder1/file-inner.jpg", options: &ListOptions{Recursive: true, WithFolders: true, WithFiles: true}}, list: checks(listSize(1), listHasMore(false), listLastPath("/folder1/file-inner.jpg")), @@ -380,23 +393,23 @@ func TestFsStorage(t *testing.T) { }, }, queryListFiles{ - input: queryListFilesInput{path: "/folder1", options: &ListOptions{Recursive: true, PathFilters: &PathFilters{allowedPrefixes: []string{"/folder2"}}}}, + input: queryListFilesInput{path: "/folder1", options: &ListOptions{Recursive: true, Filter: NewPathFilter([]string{"/folder2"}, nil, nil, nil)}}, list: checks(listSize(0), listHasMore(false), listLastPath("")), }, queryListFiles{ - input: queryListFilesInput{path: "/folder1", options: &ListOptions{Recursive: true, WithFiles: true, WithFolders: true, PathFilters: &PathFilters{allowedPrefixes: []string{"/folder2"}}}}, + input: queryListFilesInput{path: "/folder1", options: &ListOptions{Recursive: true, WithFiles: true, WithFolders: true, Filter: NewPathFilter([]string{"/folder2"}, nil, nil, nil)}}, list: checks(listSize(0), listHasMore(false), listLastPath("")), files: [][]interface{}{}, }, queryListFiles{ - input: queryListFilesInput{path: "/folder1", options: &ListOptions{Recursive: true, PathFilters: &PathFilters{allowedPrefixes: []string{"/folder1/folder"}}}}, + input: queryListFilesInput{path: "/folder1", options: &ListOptions{Recursive: true, Filter: NewPathFilter([]string{"/folder1/folder"}, nil, nil, nil)}}, list: checks(listSize(1), listHasMore(false)), files: [][]interface{}{ checks(fPath("/folder1/folder2/file.jpg")), }, }, queryListFiles{ - input: queryListFilesInput{path: "/folder1", options: &ListOptions{Recursive: true, WithFiles: true, WithFolders: true, PathFilters: &PathFilters{allowedPrefixes: []string{"/folder1/folder"}}}}, + input: queryListFilesInput{path: "/folder1", options: &ListOptions{Recursive: true, WithFiles: true, WithFolders: true, Filter: NewPathFilter([]string{"/folder1/folder"}, nil, nil, nil)}}, list: checks(listSize(2), listHasMore(false)), files: [][]interface{}{ checks(fPath("/folder1/folder2"), fMimeType("directory")), @@ -1151,7 +1164,7 @@ func TestFsStorage(t *testing.T) { } createPathFiltersCases := func() []fsTestCase { - pathFilters := NewPathFilters( + pathFilters := NewPathFilter( []string{"/gitB/", "/s3/folder/", "/gitC/"}, []string{"/gitA/dashboard2.json"}, []string{"/s3/folder/nested/"}, @@ -1205,22 +1218,22 @@ func TestFsStorage(t *testing.T) { }, queryListFiles{ input: queryListFilesInput{path: "/", options: &ListOptions{ - Recursive: true, - PathFilters: allowAllPathFilters(), + Recursive: true, + Filter: NewAllowAllPathFilter(), }}, list: checks(listSize(7)), }, queryListFiles{ input: queryListFilesInput{path: "/", options: &ListOptions{ - Recursive: true, - PathFilters: denyAllPathFilters(), + Recursive: true, + Filter: NewDenyAllPathFilter(), }}, list: checks(listSize(0)), }, queryListFiles{ input: queryListFilesInput{path: "/", options: &ListOptions{ - Recursive: true, - PathFilters: pathFilters, + Recursive: true, + Filter: pathFilters, }}, list: checks(listSize(5), listHasMore(false), listLastPath("/s3/folder/dashboard.json")), files: [][]interface{}{ @@ -1236,7 +1249,7 @@ func TestFsStorage(t *testing.T) { queryListFiles{ input: queryListFilesInput{path: "/", options: &ListOptions{ Recursive: true, - PathFilters: pathFilters, + Filter: pathFilters, WithFiles: true, WithFolders: true, }}, @@ -1260,8 +1273,8 @@ func TestFsStorage(t *testing.T) { }, queryListFolders{ input: queryListFoldersInput{path: "/", options: &ListOptions{ - Recursive: true, - PathFilters: pathFilters, + Recursive: true, + Filter: pathFilters, }}, checks: [][]interface{}{ // /gitA is missing due to the lack of explicit allow @@ -1277,8 +1290,8 @@ func TestFsStorage(t *testing.T) { }, queryListFiles{ input: queryListFilesInput{path: "/gitA", options: &ListOptions{ - Recursive: false, - PathFilters: pathFilters, + Recursive: false, + Filter: pathFilters, }}, list: checks(listSize(1), listHasMore(false), listLastPath("/gitA/dashboard2.json")), files: [][]interface{}{ @@ -1287,23 +1300,23 @@ func TestFsStorage(t *testing.T) { }, queryListFolders{ input: queryListFoldersInput{path: "/gitA", options: &ListOptions{ - Recursive: false, - PathFilters: pathFilters, + Recursive: false, + Filter: pathFilters, }}, checks: [][]interface{}{}, }, queryListFiles{ input: queryListFilesInput{path: "/gitC", options: &ListOptions{ - Recursive: false, - PathFilters: pathFilters, + Recursive: false, + Filter: pathFilters, }}, list: checks(listSize(0), listHasMore(false), listLastPath("")), files: [][]interface{}{}, }, queryListFiles{ input: queryListFilesInput{path: "/gitC/nestedC", options: &ListOptions{ - Recursive: false, - PathFilters: pathFilters, + Recursive: false, + Filter: pathFilters, }}, list: checks(listSize(1), listHasMore(false), listLastPath("/gitC/nestedC/dashboardC.json")), files: [][]interface{}{ @@ -1312,8 +1325,8 @@ func TestFsStorage(t *testing.T) { }, queryListFolders{ input: queryListFoldersInput{path: "/gitC", options: &ListOptions{ - Recursive: false, - PathFilters: pathFilters, + Recursive: false, + Filter: pathFilters, }}, checks: [][]interface{}{}, }, diff --git a/pkg/infra/filestorage/test_utils.go b/pkg/infra/filestorage/test_utils.go index 695a774a68e..a8e52ad02ec 100644 --- a/pkg/infra/filestorage/test_utils.go +++ b/pkg/infra/filestorage/test_utils.go @@ -313,7 +313,7 @@ func handleQuery(t *testing.T, ctx context.Context, query interface{}, queryName WithFiles: false, WithFolders: true, WithContents: false, - PathFilters: nil, + Filter: nil, } } else { opts.WithFolders = true diff --git a/pkg/infra/filestorage/wrapper.go b/pkg/infra/filestorage/wrapper.go index b9718f6a0ed..978777f3e7e 100644 --- a/pkg/infra/filestorage/wrapper.go +++ b/pkg/infra/filestorage/wrapper.go @@ -9,6 +9,7 @@ import ( "strings" "github.com/grafana/grafana/pkg/infra/log" + "github.com/grafana/grafana/pkg/services/accesscontrol" ) var ( @@ -17,102 +18,54 @@ var ( ) type wrapper struct { - log log.Logger - wrapped FileStorage - pathFilters *PathFilters - rootFolder string + log log.Logger + wrapped FileStorage + filter PathFilter + rootFolder string } -func addRootFolderToFilters(pathFilters *PathFilters, rootFolder string) *PathFilters { - if pathFilters == nil { - return pathFilters - } - - for i := range pathFilters.disallowedPaths { - pathFilters.disallowedPaths[i] = rootFolder + strings.TrimPrefix(pathFilters.disallowedPaths[i], Delimiter) - } - for i := range pathFilters.disallowedPrefixes { - pathFilters.disallowedPrefixes[i] = rootFolder + strings.TrimPrefix(pathFilters.disallowedPrefixes[i], Delimiter) - } - for i := range pathFilters.allowedPaths { - pathFilters.allowedPaths[i] = rootFolder + strings.TrimPrefix(pathFilters.allowedPaths[i], Delimiter) - } - for i := range pathFilters.allowedPrefixes { - pathFilters.allowedPrefixes[i] = rootFolder + strings.TrimPrefix(pathFilters.allowedPrefixes[i], Delimiter) - } - - return pathFilters +func wrapPathFilter(filter PathFilter, rootFolder string) PathFilter { + return &wrappedPathFilter{filter: filter, rootFolder: rootFolder} } -func copyPathFilters(p *PathFilters) *PathFilters { - if p == nil { - return nil - } - - return NewPathFilters(p.allowedPrefixes, p.allowedPaths, p.disallowedPrefixes, p.disallowedPaths) +type wrappedPathFilter struct { + rootFolder string + filter PathFilter } -func addPathFilters(base *PathFilters, new *PathFilters) *PathFilters { - if new == nil { - return base - } +func (w wrappedPathFilter) IsAllowed(path string) bool { + pathWithReplacedRoot := Delimiter + strings.TrimPrefix(path, w.rootFolder) + return w.filter.IsAllowed(pathWithReplacedRoot) +} - if new.allowedPrefixes != nil { - if base.allowedPrefixes != nil { - base.allowedPrefixes = append(base.allowedPrefixes, new.allowedPrefixes...) - } else { - copiedPrefixes := make([]string, len(new.allowedPrefixes)) - copy(copiedPrefixes, new.allowedPrefixes) - base.allowedPrefixes = copiedPrefixes +func (w wrappedPathFilter) ToString() string { + return w.filter.ToString() +} + +func (w wrappedPathFilter) asSQLFilter() accesscontrol.SQLFilter { + sqlFilter := w.filter.asSQLFilter() + for i := range sqlFilter.Args { + if path, ok := sqlFilter.Args[i].(string); ok { + sqlFilter.Args[i] = w.rootFolder + strings.TrimPrefix(path, Delimiter) } } - if new.allowedPaths != nil { - if base.allowedPaths != nil { - base.allowedPaths = append(base.allowedPaths, new.allowedPaths...) - } else { - copiedPaths := make([]string, len(new.allowedPaths)) - copy(copiedPaths, new.allowedPaths) - base.allowedPaths = copiedPaths - } - } - - if new.disallowedPrefixes != nil { - if base.disallowedPrefixes != nil { - base.disallowedPrefixes = append(base.disallowedPrefixes, new.disallowedPrefixes...) - } else { - copiedPrefixes := make([]string, len(new.disallowedPrefixes)) - copy(copiedPrefixes, new.disallowedPrefixes) - base.disallowedPrefixes = copiedPrefixes - } - } - - if new.disallowedPaths != nil { - if base.disallowedPaths != nil { - base.disallowedPaths = append(base.disallowedPaths, new.disallowedPaths...) - } else { - copiedPaths := make([]string, len(new.disallowedPaths)) - copy(copiedPaths, new.disallowedPaths) - base.disallowedPaths = copiedPaths - } - } - - return base + return sqlFilter } -func newWrapper(log log.Logger, wrapped FileStorage, pathFilters *PathFilters, rootFolder string) FileStorage { - var rootedPathFilters *PathFilters - if pathFilters != nil { - rootedPathFilters = addRootFolderToFilters(copyPathFilters(pathFilters), rootFolder) +func newWrapper(log log.Logger, wrapped FileStorage, pathFilter PathFilter, rootFolder string) FileStorage { + var wrappedPathFilter PathFilter + if pathFilter != nil { + wrappedPathFilter = wrapPathFilter(pathFilter, rootFolder) } else { - rootedPathFilters = allowAllPathFilters() + wrappedPathFilter = wrapPathFilter(NewAllowAllPathFilter(), rootFolder) } return &wrapper{ - log: log, - wrapped: wrapped, - pathFilters: rootedPathFilters, - rootFolder: rootFolder, + log: log, + wrapped: wrapped, + filter: wrappedPathFilter, + rootFolder: rootFolder, } } @@ -198,7 +151,7 @@ func (b wrapper) Get(ctx context.Context, path string) (*File, error) { } rootedPath := b.addRoot(path) - if !b.pathFilters.IsAllowed(rootedPath) { + if !b.filter.IsAllowed(rootedPath) { return nil, nil } @@ -212,13 +165,14 @@ func (b wrapper) Get(ctx context.Context, path string) (*File, error) { } return file, err } + func (b wrapper) Delete(ctx context.Context, path string) error { if err := b.validatePath(path); err != nil { return err } rootedPath := b.addRoot(path) - if !b.pathFilters.IsAllowed(rootedPath) { + if !b.filter.IsAllowed(rootedPath) { return nil } @@ -242,7 +196,7 @@ func (b wrapper) Upsert(ctx context.Context, file *UpsertFileCommand) error { } rootedPath := b.addRoot(file.Path) - if !b.pathFilters.IsAllowed(rootedPath) { + if !b.filter.IsAllowed(rootedPath) { return nil } @@ -284,7 +238,7 @@ func (b wrapper) listOptionsWithDefaults(options *ListOptions) *ListOptions { if options == nil { return &ListOptions{ Recursive: false, - PathFilters: b.pathFilters, + Filter: b.filter, WithFiles: true, WithFolders: false, WithContents: false, @@ -295,20 +249,25 @@ func (b wrapper) listOptionsWithDefaults(options *ListOptions) *ListOptions { if !options.WithFiles && !options.WithFolders { withFiles = true } - if options.PathFilters == nil { + if b.filter == nil { return &ListOptions{ Recursive: options.Recursive, - PathFilters: b.pathFilters, + Filter: b.filter, WithFiles: withFiles, WithFolders: options.WithFolders, WithContents: options.WithContents, } } - rootedFilters := addRootFolderToFilters(copyPathFilters(options.PathFilters), b.rootFolder) + var filter PathFilter + if options.Filter != nil { + filter = newAndPathFilter(b.filter, wrapPathFilter(options.Filter, b.rootFolder)) + } else { + filter = b.filter + } return &ListOptions{ Recursive: options.Recursive, - PathFilters: addPathFilters(rootedFilters, b.pathFilters), + Filter: filter, WithFiles: withFiles, WithFolders: options.WithFolders, WithContents: options.WithContents, @@ -321,7 +280,7 @@ func (b wrapper) CreateFolder(ctx context.Context, path string) error { } rootedPath := b.addRoot(path) - if !b.pathFilters.IsAllowed(rootedPath) { + if !b.filter.IsAllowed(rootedPath) { return nil } @@ -334,7 +293,7 @@ func (b wrapper) DeleteFolder(ctx context.Context, path string) error { } rootedPath := b.addRoot(path) - if !b.pathFilters.IsAllowed(rootedPath) { + if !b.filter.IsAllowed(rootedPath) { return nil } @@ -356,13 +315,6 @@ func (b wrapper) List(ctx context.Context, folderPath string, paging *Paging, op } options = b.listOptionsWithDefaults(options) - if (!options.WithFiles && !options.WithFolders) || options.isDenyAll() { - return &ListResponse{ - Files: []*File{}, - HasMore: false, - LastPath: "", - }, nil - } var fileChan = make(chan *File) fileRetrievalCtx, cancelFileGet := context.WithCancel(ctx) @@ -397,7 +349,6 @@ func (b wrapper) List(ctx context.Context, folderPath string, paging *Paging, op file := <-fileChan if file != nil { - file.FileMetadata.FullPath = b.removeRoot(file.FileMetadata.FullPath) var contents []byte if options.WithContents { contents = file.Contents diff --git a/pkg/infra/filestorage/wrapper_test.go b/pkg/infra/filestorage/wrapper_test.go index aeee9662c12..0fd9d55f085 100644 --- a/pkg/infra/filestorage/wrapper_test.go +++ b/pkg/infra/filestorage/wrapper_test.go @@ -7,157 +7,6 @@ import ( "github.com/stretchr/testify/require" ) -func TestWrapper_addRootFolderToFilters(t *testing.T) { - t.Run("should return null if passed filters are null", func(t *testing.T) { - require.Nil(t, addRootFolderToFilters(nil, "root")) - }) - - t.Run("should not allocate empty arrays in place of nil arrays", func(t *testing.T) { - filters := NewPathFilters(nil, nil, nil, nil) - rootedFilters := addRootFolderToFilters(filters, "root") - require.NotNil(t, rootedFilters) - require.Nil(t, rootedFilters.disallowedPrefixes) - require.Nil(t, rootedFilters.disallowedPaths) - require.Nil(t, rootedFilters.allowedPrefixes) - require.Nil(t, rootedFilters.allowedPaths) - }) - - t.Run("should preserve empty arrays", func(t *testing.T) { - filters := NewPathFilters([]string{}, []string{}, nil, nil) - rootedFilters := addRootFolderToFilters(filters, "root") - require.NotNil(t, rootedFilters) - require.Nil(t, rootedFilters.disallowedPrefixes) - require.Nil(t, rootedFilters.disallowedPaths) - require.NotNil(t, rootedFilters.allowedPrefixes) - require.Equal(t, []string{}, rootedFilters.allowedPrefixes) - - require.NotNil(t, rootedFilters.allowedPaths) - require.Equal(t, []string{}, rootedFilters.allowedPaths) - }) - - t.Run("should mutate arrays rather than reallocate", func(t *testing.T) { - filters := NewPathFilters([]string{"/abc", "/abc2"}, nil, nil, []string{"/abc/", "/abc2/"}) - originalAllowedPrefixes := filters.allowedPrefixes - originalDisallowedPaths := filters.disallowedPaths - - rootedFilters := addRootFolderToFilters(filters, "root/") - require.NotNil(t, rootedFilters) - require.Nil(t, rootedFilters.allowedPaths) - require.Nil(t, rootedFilters.disallowedPrefixes) - - expectedAllowedPrefixes := []string{"root/abc", "root/abc2"} - expectedDisallowedPaths := []string{"root/abc/", "root/abc2/"} - require.Equal(t, expectedAllowedPrefixes, rootedFilters.allowedPrefixes) - require.Equal(t, expectedDisallowedPaths, rootedFilters.disallowedPaths) - - require.Equal(t, expectedAllowedPrefixes, originalAllowedPrefixes) - require.Equal(t, expectedDisallowedPaths, originalDisallowedPaths) - }) -} - -func TestWrapper_copyPathFilters(t *testing.T) { - t.Run("should return null if passed pathFilters are null", func(t *testing.T) { - require.Nil(t, copyPathFilters(nil)) - }) - - t.Run("should not allocate empty arrays in place of nil arrays", func(t *testing.T) { - copiedFilters := copyPathFilters(NewPathFilters(nil, nil, nil, nil)) - require.NotNil(t, copiedFilters) - require.Nil(t, copiedFilters.disallowedPrefixes) - require.Nil(t, copiedFilters.disallowedPaths) - require.Nil(t, copiedFilters.allowedPrefixes) - require.Nil(t, copiedFilters.allowedPaths) - }) - - t.Run("should preserve empty arrays", func(t *testing.T) { - copiedFilters := copyPathFilters(NewPathFilters([]string{}, []string{}, nil, nil)) - require.NotNil(t, copiedFilters) - require.Nil(t, copiedFilters.disallowedPrefixes) - require.Nil(t, copiedFilters.disallowedPaths) - require.NotNil(t, copiedFilters.allowedPrefixes) - require.Equal(t, []string{}, copiedFilters.allowedPrefixes) - - require.NotNil(t, copiedFilters.allowedPaths) - require.Equal(t, []string{}, copiedFilters.allowedPaths) - }) - - t.Run("should new pointer with new slices", func(t *testing.T) { - filters := NewPathFilters([]string{"/abc", "/abc2"}, nil, nil, []string{"/abc/", "/abc2/"}) - - copiedFilters := copyPathFilters(filters) - - require.NotSame(t, filters, copiedFilters) - - require.Equal(t, filters.allowedPrefixes, copiedFilters.allowedPrefixes) - require.Equal(t, filters.allowedPaths, copiedFilters.allowedPaths) - require.Equal(t, filters.disallowedPrefixes, copiedFilters.disallowedPrefixes) - require.Equal(t, filters.disallowedPaths, copiedFilters.disallowedPaths) - - copiedFilters.disallowedPaths[0] = "changed" - require.Equal(t, []string{"/abc/", "/abc2/"}, filters.disallowedPaths) - require.Equal(t, []string{"changed", "/abc2/"}, copiedFilters.disallowedPaths) - require.NotEqual(t, filters.disallowedPaths, copiedFilters.disallowedPaths) - }) -} - -func TestWrapper_addPathFilters(t *testing.T) { - t.Run("should return pointer to the first argument", func(t *testing.T) { - base := NewPathFilters(nil, nil, nil, nil) - toAdd := NewPathFilters([]string{"abc"}, []string{"abc2"}, []string{"abc3"}, []string{"abc4"}) - require.Same(t, base, addPathFilters(base, toAdd)) - }) - - testcases := []struct { - base *PathFilters - toAdd *PathFilters - expected *PathFilters - }{ - { - base: NewPathFilters(nil, nil, nil, nil), - toAdd: NewPathFilters([]string{"abc"}, []string{"abc2"}, []string{"abc3"}, []string{"abc4"}), - expected: NewPathFilters([]string{"abc"}, []string{"abc2"}, []string{"abc3"}, []string{"abc4"}), - }, - { - base: NewPathFilters([]string{"abc"}, []string{"abc2"}, []string{"abc3"}, []string{"abc4"}), - toAdd: NewPathFilters(nil, nil, nil, nil), - expected: NewPathFilters([]string{"abc"}, []string{"abc2"}, []string{"abc3"}, []string{"abc4"}), - }, - { - base: NewPathFilters([]string{"abc"}, []string{"abc2"}, []string{"abc3"}, []string{"abc4"}), - toAdd: NewPathFilters([]string{"abc"}, []string{"abc2"}, []string{"abc3"}, []string{"abc4"}), - expected: NewPathFilters([]string{"abc", "abc"}, []string{"abc2", "abc2"}, []string{"abc3", "abc3"}, []string{"abc4", "abc4"}), - }, - { - base: NewPathFilters([]string{"abc"}, []string{}, nil, []string{"abc4"}), - toAdd: NewPathFilters([]string{"abc"}, []string{"abc2", "abc22", "abc222"}, []string{"abc3"}, []string{"abc4"}), - expected: NewPathFilters([]string{"abc", "abc"}, []string{"abc2", "abc22", "abc222"}, []string{"abc3"}, []string{"abc4", "abc4"}), - }, - } - - for _, tt := range testcases { - require.Equal(t, tt.expected, addPathFilters(tt.base, tt.toAdd)) - } - - t.Run("should not reuse arrays allocations from the second arg", func(t *testing.T) { - base := NewPathFilters(nil, []string{}, nil, nil) - toAdd := NewPathFilters([]string{"abc"}, []string{"abc2"}, []string{"abc3"}, []string{"abc4"}) - - _ = addPathFilters(base, toAdd) - - require.Equal(t, toAdd.allowedPaths, base.allowedPaths) - base.allowedPaths[0] = "mutated" - require.Equal(t, []string{"mutated"}, base.allowedPaths) - require.Equal(t, []string{"abc2"}, toAdd.allowedPaths) - require.NotEqual(t, toAdd.allowedPaths, base.allowedPaths) - - require.Equal(t, toAdd.allowedPrefixes, base.allowedPrefixes) - base.allowedPrefixes[0] = "mutated2" - require.Equal(t, []string{"mutated2"}, base.allowedPrefixes) - require.Equal(t, []string{"abc"}, toAdd.allowedPrefixes) - require.NotEqual(t, toAdd.allowedPrefixes, base.allowedPrefixes) - }) -} - func TestFilestorage_getParentFolderPath(t *testing.T) { var tests = []struct { name string diff --git a/pkg/services/store/storage_disk.go b/pkg/services/store/storage_disk.go index 143a80b5e28..78955451da7 100644 --- a/pkg/services/store/storage_disk.go +++ b/pkg/services/store/storage_disk.go @@ -57,7 +57,7 @@ func newDiskStorage(prefix string, name string, cfg *StorageLocalDiskConfig) *ro } else { s.store = filestorage.NewCdkBlobStorage(grafanaStorageLogger, bucket, "", - filestorage.NewPathFilters(cfg.Roots, nil, nil, nil)) + filestorage.NewPathFilter(cfg.Roots, nil, nil, nil)) meta.Ready = true // exists! } From 75d528d7bdcbf2a9b9a0d087a1239fbafe24ba1a Mon Sep 17 00:00:00 2001 From: achatterjee-grafana <70489351+achatterjee-grafana@users.noreply.github.com> Date: Thu, 21 Apr 2022 17:03:58 -0400 Subject: [PATCH 083/120] Docs: resize images in what's news 8.5 (#48082) * Updated image size. * Few more resizing. Also, added link for signup for beta testing (nav bar). * Few minor tweaks * Fixed a typo --- docs/sources/whatsnew/whats-new-in-v8-5.md | 24 +++++++++++----------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/sources/whatsnew/whats-new-in-v8-5.md b/docs/sources/whatsnew/whats-new-in-v8-5.md index ffef79705ea..e1ae48e525a 100644 --- a/docs/sources/whatsnew/whats-new-in-v8-5.md +++ b/docs/sources/whatsnew/whats-new-in-v8-5.md @@ -22,11 +22,11 @@ It’s been tricky to work with more than a small number of Grafana-managed aler Choose useful group names, and move alert rules between groups. -{{< figure src="/static/img/docs/alerting/unified/rule-grouping-8-5.png" max-width="38000px" caption="Rule group" >}} +{{< figure src="/static/img/docs/alerting/unified/rule-grouping-8-5.png" max-width="400px" caption="Rule group" >}} Rules in a group are evaluated together, so you can also set the interval for the entire group. -{{< figure src="/static/img/docs/alerting/unified/rule-grouping-details-8-5.png" max-width="38000px" caption="Rule group details" >}} +{{< figure src="/static/img/docs/alerting/unified/rule-grouping-details-8-5.png" max-width="350px" caption="Rule group details" >}} ## Analytics @@ -36,11 +36,11 @@ When enabled, a check runs every 10 minutes. It will notify, via the UI, when a Plugin update available: -{{< figure src="/static/img/docs/analytics/github-plugin-update-available-8-5.png" max-width="1200px" caption="Plugin-available" >}} +{{< figure src="/static/img/docs/analytics/github-plugin-update-available-8-5.png" max-width="450px" caption="Grafana-update-available" >}} Grafana update available: -{{< figure src="/static/img/docs/analytics/github-plugin-version-8-5.png" max-width="1200px" caption="Grafana-update-available" >}} +{{< figure src="/static/img/docs/analytics/github-plugin-version-8-5.png" max-width="450px" caption="Grafana-update-available" >}} ## Dashboard Panels @@ -50,9 +50,9 @@ In addition to RSS feeds, the News panel now supports Atom feeds, allowing you t The Bar gauge panel now supports scrolling to support displaying large datasets while maintaining the readability of labels. You can set a min width or height for the bars (depending on the chart’s orientation), allowing the content to overflow in the container and become scrollable. -{{< figure src="/static/img/docs/bar-gauge-panel/vertical-view-8-5.png" max-width="1200px" caption="Vertical view" >}} +{{< figure src="/static/img/docs/bar-gauge-panel/vertical-view-8-5.png" max-width="400px" caption="Vertical view" >}} -{{< figure src="/static/img/docs/bar-gauge-panel/horizontal-view-8-5.png" max-width="1200px" caption="Horizontal view" >}} +{{< figure src="/static/img/docs/bar-gauge-panel/horizontal-view-8-5.png" max-width="400px" caption="Horizontal view" >}} ## Transformations @@ -69,23 +69,23 @@ A new transformation is available that helps you structure data in a matrix form Available by switching on the ‘newNavigation’ feature toggle. You can expand the navigation bar for a better overview of Grafana’s features and installed integrations. This feature is currently in a beta version and we would appreciate your feedback. Sign up for a call with the Grafana team - it only takes 30 minutes, and you'll receive a $40 USD gift card as a token of appreciation for your time. -US, UK, Canada, Australia, France, Germany, or South Africa: sign up here -Everywhere else in the world: sign up here +US, UK, Canada, Australia, France, Germany, or South Africa: sign up [here](https://www.userinterviews.com/projects/Hz3DyNNwWA/apply); +Everywhere else in the world: sign up [here](https://www.userinterviews.com/projects/Hz3DyNNwWA/apply). -{{< figure src="/static/img/docs/navigation/new-navigation-8-5.png" max-width="1200px" caption="New nav panel" >}} +{{< figure src="/static/img/docs/navigation/new-navigation-8-5.png" max-width="400px" caption="New nav panel" >}} ## Notifications list for error alerts (Beta) Available by switching on the ‘persistNotifications’ feature toggle. In order to support debugging issues in Grafana, error alerts that appear when viewing a dashboard now include a trace ID, and these alerts can be accessed under Profile / Notifications. -{{< figure src="/static/img/docs/navigation/nav-profile-notification-8-5.png" max-width="1200px" caption="Alert error list" >}} +{{< figure src="/static/img/docs/navigation/nav-profile-notification-8-5.png" max-width="200px" caption="New nav panel" >}} ## Service accounts (beta) Service accounts are a major evolution for machine access within Grafana. You can create multiple API tokens per service account with independent expiration dates, and temporarily disable a service account without deleting it. These benefits make Service Accounts a more flexible way for Terraform and other apps to authenticate with Grafana. Service accounts also work with [fine-grained access control](https://grafana.com/docs/grafana/latest/enterprise/access-control/) in [Grafana Enterprise](https://grafana.com/docs/grafana/latest/enterprise/): you can improve security by granting service accounts specific roles to limit the functions they can perform. Service accounts are available in beta; you can try them out by enabling the `service-accounts` [feature toggle](https://grafana.com/docs/grafana/latest/administration/service-accounts/enable-service-accounts) or, if you use Grafana Cloud, [reaching out to our support team](https://grafana.com/orgs/raintank/tickets#) for early access. Learn more about Service Accounts in our [docs](https://grafana.com/docs/grafana/latest/administration/service-accounts). -{{< figure src="/static/img/docs/service-accounts/configure-8-5.png" max-width="1200px" caption="Configure service accounts" >}} +{{< figure src="/static/img/docs/service-accounts/configure-8-5.png" max-width="400px" caption="Configure service accounts" >}} ## Observability @@ -123,4 +123,4 @@ You can already keep secrets in Grafana’s database (like data source credentia Reports are a great way to share Grafana dashboards by email with users who don’t regularly sign in to Grafana. In 8.5, we’ve revamped the Report authoring UI to make it quicker and easier for you to create reports. View report details at a glance in list view, consider one configuration step at a time, and save reports for later. Also, Grafana will now emit a log every time a report is sent, so you can confirm its status or learn about send errors. Learn more about Reporting in our [docs](https://grafana.com/docs/grafana/latest/enterprise/reporting/). -{{< figure src="/static/img/docs/enterprise/report-new-report-8-5.png" max-width="1200px" caption="New report" >}} +{{< figure src="/static/img/docs/enterprise/report-new-report-8-5.png" max-width="350px" caption="New report" >}} From 3e7db088acd1da32ea489b0756cdf4e15ec2da69 Mon Sep 17 00:00:00 2001 From: Kristina Date: Thu, 21 Apr 2022 16:50:34 -0500 Subject: [PATCH 084/120] Command Palette Scaffolding + Explore (#47445) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add feature flag and scaffodling * start adding actions * WIP * move action files * Start adding styles * Fix implementation based on feedback * Add more hackathon code back to command palette * Cleanup * Cleanup unused service files for simple MVP pass * Move type def to library * WIP * Move provider to proper place to pick up other routes’ actions * Build actions off navbar, add explore actions * Work around undefined typescript stuff * Fix based on feedback * close palette on ESC * Fix based on PR feedback pt 1 * Move styles to classes * Move another inline style to a class * Enable command palette by default * change around async hook structure * Add simple feature tracking * Code cleanup, and be sure the command is accurate * Change to only render if there are actions, and only add actions once past login --- conf/defaults.ini | 3 + package.json | 1 + .../src/types/featureToggles.gen.ts | 1 + pkg/services/featuremgmt/registry.go | 5 + pkg/services/featuremgmt/toggles_gen.go | 4 + public/app/AppWrapper.tsx | 62 ++++--- .../commandPalette/CommandPalette.tsx | 146 +++++++++++++++++ .../features/commandPalette/ResultItem.tsx | 123 ++++++++++++++ .../actions/dashboard.nav.actions.ts | 24 +++ .../actions/global.static.actions.ts | 152 ++++++++++++++++++ .../app/features/explore/ExploreActions.tsx | 94 +++++++++++ public/app/features/explore/Wrapper.tsx | 2 + yarn.lock | 83 ++++++++++ 13 files changed, 676 insertions(+), 24 deletions(-) create mode 100644 public/app/features/commandPalette/CommandPalette.tsx create mode 100644 public/app/features/commandPalette/ResultItem.tsx create mode 100644 public/app/features/commandPalette/actions/dashboard.nav.actions.ts create mode 100644 public/app/features/commandPalette/actions/global.static.actions.ts create mode 100644 public/app/features/explore/ExploreActions.tsx diff --git a/conf/defaults.ini b/conf/defaults.ini index 904719d5620..4bb5376c233 100644 --- a/conf/defaults.ini +++ b/conf/defaults.ini @@ -1140,6 +1140,9 @@ promQueryBuilder = true # Experimental Explore to Dashboard workflow explore2Dashboard = true +# Experimental Command Palette +commandPalette = true + # feature1 = true # feature2 = false diff --git a/package.json b/package.json index d23dfb7b501..3dcbc26e117 100644 --- a/package.json +++ b/package.json @@ -319,6 +319,7 @@ "js-yaml": "^4.1.0", "json-source-map": "0.6.1", "jsurl": "^0.1.5", + "kbar": "^0.1.0-beta.30", "lezer-promql": "0.22.0", "lodash": "4.17.21", "logfmt": "^1.3.2", diff --git a/packages/grafana-data/src/types/featureToggles.gen.ts b/packages/grafana-data/src/types/featureToggles.gen.ts index c222161310a..e5b4cb3e532 100644 --- a/packages/grafana-data/src/types/featureToggles.gen.ts +++ b/packages/grafana-data/src/types/featureToggles.gen.ts @@ -55,4 +55,5 @@ export interface FeatureToggles { azureMonitorResourcePickerForMetrics?: boolean; explore2Dashboard?: boolean; persistNotifications?: boolean; + commandPalette?: boolean; } diff --git a/pkg/services/featuremgmt/registry.go b/pkg/services/featuremgmt/registry.go index 668426522bf..6c18fb2a947 100644 --- a/pkg/services/featuremgmt/registry.go +++ b/pkg/services/featuremgmt/registry.go @@ -219,5 +219,10 @@ var ( State: FeatureStateAlpha, FrontendOnly: true, }, + { + Name: "commandPalette", + Description: "Enable command palette", + State: FeatureStateAlpha, + }, } ) diff --git a/pkg/services/featuremgmt/toggles_gen.go b/pkg/services/featuremgmt/toggles_gen.go index 9d92cc4cf21..0d762f26555 100644 --- a/pkg/services/featuremgmt/toggles_gen.go +++ b/pkg/services/featuremgmt/toggles_gen.go @@ -162,4 +162,8 @@ const ( // FlagPersistNotifications // PoC Notifications page FlagPersistNotifications = "persistNotifications" + + // FlagCommandPalette + // Enable command palette + FlagCommandPalette = "commandPalette" ) diff --git a/public/app/AppWrapper.tsx b/public/app/AppWrapper.tsx index 73a370a25dc..f31867db17f 100644 --- a/public/app/AppWrapper.tsx +++ b/public/app/AppWrapper.tsx @@ -1,6 +1,6 @@ import React, { ComponentType } from 'react'; import { Router, Route, Redirect, Switch } from 'react-router-dom'; -import { config, locationService, navigationLogger } from '@grafana/runtime'; +import { config, locationService, navigationLogger, reportInteraction } from '@grafana/runtime'; import { Provider } from 'react-redux'; import { store } from 'app/store/store'; import { ErrorBoundaryAlert, GlobalStyles, ModalRoot, ModalsProvider, PortalContainer } from '@grafana/ui'; @@ -15,6 +15,8 @@ import { GrafanaRoute } from './core/navigation/GrafanaRoute'; import { AppNotificationList } from './core/components/AppNotifications/AppNotificationList'; import { SearchWrapper } from 'app/features/search'; import { LiveConnectionWarning } from './features/live/LiveConnectionWarning'; +import { Action, KBarProvider } from 'kbar'; +import { CommandPalette } from './features/commandPalette/CommandPalette'; import { I18nProvider } from './core/localisation'; import { AngularRoot } from './angular/AngularRoot'; import { loadAndInitAngularIfEnabled } from './angular/loadAndInitAngularIfEnabled'; @@ -85,36 +87,48 @@ export class AppWrapper extends React.Component { + reportInteraction('commandPalette_action_selected', { + actionId: action.id, + }); + }; + return ( - - -
- - {ready && <>{newNavigationEnabled ? : }} -
- {pageBanners.map((Banner, index) => ( - - ))} + + + + {config.featureToggles.commandPalette && } +
+ + {ready && <>{newNavigationEnabled ? : }} +
+ {pageBanners.map((Banner, index) => ( + + ))} - - - - {ready && this.renderRoutes()} - {bodyRenderHooks.map((Hook, index) => ( - - ))} -
-
-
- - - -
+ + + + {ready && this.renderRoutes()} + {bodyRenderHooks.map((Hook, index) => ( + + ))} +
+
+
+ + + +
+
diff --git a/public/app/features/commandPalette/CommandPalette.tsx b/public/app/features/commandPalette/CommandPalette.tsx new file mode 100644 index 00000000000..4cdcc4c069d --- /dev/null +++ b/public/app/features/commandPalette/CommandPalette.tsx @@ -0,0 +1,146 @@ +import React, { useEffect, useState } from 'react'; +import { + KBarAnimator, + KBarPortal, + KBarPositioner, + KBarResults, + KBarSearch, + useMatches, + Action, + VisualState, + useRegisterActions, + useKBar, +} from 'kbar'; +import { useStyles2 } from '@grafana/ui'; +import { GrafanaTheme2 } from '@grafana/data'; +import { ResultItem } from './ResultItem'; +import getGlobalActions from './actions/global.static.actions'; +import getDashboardNavActions from './actions/dashboard.nav.actions'; +import { useSelector } from 'react-redux'; +import { StoreState } from 'app/types'; +import { css } from '@emotion/css'; +import { keybindingSrv } from '../../core/services/keybindingSrv'; +import { reportInteraction, locationService } from '@grafana/runtime'; + +/** + * Wrap all the components from KBar here. + * @constructor + */ + +export const CommandPalette = () => { + const styles = useStyles2(getSearchStyles); + const [actions, setActions] = useState([]); + const { notHidden, query, showing } = useKBar((state) => ({ + notHidden: state.visualState !== VisualState.hidden, + showing: state.visualState === VisualState.showing, + })); + const isNotLogin = locationService.getLocation().pathname !== '/login'; + + const { navBarTree } = useSelector((state: StoreState) => { + return { + navBarTree: state.navBarTree, + }; + }); + + keybindingSrv.bind('esc', () => { + if (notHidden) { + query.setVisualState(VisualState.animatingOut); + } + }); + + useEffect(() => { + (async () => { + if (isNotLogin) { + const staticActions = getGlobalActions(navBarTree); + const dashAct = await getDashboardNavActions('go/dashboard'); + setActions([...staticActions, ...dashAct]); + } + })(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [isNotLogin]); + + useEffect(() => { + if (showing) { + reportInteraction('commandPalette_opened'); + } + }, [showing]); + + useRegisterActions(actions, [actions]); + + return actions.length > 0 ? ( + + + + + + + + + ) : null; +}; + +const RenderResults = () => { + const { results, rootActionId } = useMatches(); + const styles = useStyles2(getSearchStyles); + + return ( +
+ + typeof item === 'string' ? ( +
{item}
+ ) : ( + + ) + } + /> +
+ ); +}; + +const getSearchStyles = (theme: GrafanaTheme2) => ({ + positioner: css({ + zIndex: theme.zIndex.portal, + marginTop: '0px', + '&::before': { + content: '""', + position: 'fixed', + top: 0, + right: 0, + bottom: 0, + left: 0, + background: theme.components.overlay.background, + backdropFilter: 'blur(1px)', + }, + }), + animator: css({ + maxWidth: theme.breakpoints.values.sm, // supposed to be 600... + width: '100%', + background: theme.colors.background.canvas, + color: theme.colors.text.primary, + borderRadius: theme.shape.borderRadius(4), + overflow: 'hidden', + boxShadow: theme.shadows.z3, + }), + search: css({ + padding: theme.spacing(2, 3), + fontSize: theme.typography.fontSize, + width: '100%', + boxSizing: 'border-box', + outline: 'none', + border: 'none', + background: theme.colors.background.canvas, + color: theme.colors.text.primary, + borderBottom: `1px solid ${theme.colors.border.weak}`, + }), + sectionHeader: css({ + padding: theme.spacing(1, 2), + fontSize: theme.typography.h6.fontSize, + fontWeight: theme.typography.body.fontWeight, + color: theme.colors.text.secondary, + }), + resultsContainer: css({ + padding: theme.spacing(2, 0), + }), +}); diff --git a/public/app/features/commandPalette/ResultItem.tsx b/public/app/features/commandPalette/ResultItem.tsx new file mode 100644 index 00000000000..2b876a74f48 --- /dev/null +++ b/public/app/features/commandPalette/ResultItem.tsx @@ -0,0 +1,123 @@ +import React from 'react'; +import { ActionId, ActionImpl } from 'kbar'; +import { useTheme2 } from '@grafana/ui'; +import { GrafanaTheme2 } from '@grafana/data'; +import { css } from '@emotion/css'; + +export const ResultItem = React.forwardRef( + ( + { + action, + active, + currentRootActionId, + }: { + action: ActionImpl; + active: boolean; + currentRootActionId: ActionId; + }, + ref: React.Ref + ) => { + const ancestors = React.useMemo(() => { + if (!currentRootActionId) { + return action.ancestors; + } + + const index = action.ancestors.findIndex((ancestor) => ancestor.id === currentRootActionId); + // +1 removes the currentRootAction; e.g. + // if we are on the "Set theme" parent action, + // the UI should not display "Set theme… > Dark" + // but rather just "Dark" + return action.ancestors.slice(index + 1); + }, [action.ancestors, currentRootActionId]); + + const theme = useTheme2(); + const styles = getResultItemStyles(theme, active); + + return ( +
+
+ {action.icon} +
+
+ {ancestors.length > 0 && + ancestors.map((ancestor) => ( + + {ancestor.name} + › + + ))} + {action.name} +
+
+ {action.subtitle && {action.subtitle}} +
+ {action.shortcut?.length ? ( +
+ {action.shortcut.map((sc) => ( + + {sc} + + ))} +
+ ) : null} +
+ ); + } +); +ResultItem.displayName = 'ResultItem'; + +const getResultItemStyles = (theme: GrafanaTheme2, isActive: boolean) => { + const textColor = isActive ? theme.colors.text.maxContrast : theme.colors.text.primary; + const rowBackgroundColor = isActive ? theme.colors.background.primary : 'transparent'; + const shortcutBackgroundColor = isActive ? theme.colors.background.secondary : theme.colors.background.primary; + return { + row: css({ + color: textColor, + padding: theme.spacing(1, 2), + background: rowBackgroundColor, + display: 'flex', + alightItems: 'center', + justifyContent: 'space-between', + cursor: 'pointer', + '&:before': { + display: isActive ? 'block' : 'none', + content: '" "', + position: 'absolute', + left: 0, + top: 0, + bottom: 0, + width: theme.spacing(0.5), + borderRadius: theme.shape.borderRadius(1), + backgroundImage: theme.colors.gradients.brandVertical, + }, + }), + actionContainer: css({ + display: 'flex', + gap: theme.spacing(2), + alignitems: 'center', + fontsize: theme.typography.fontSize, + }), + textContainer: css({ + display: 'flex', + flexDirection: 'column', + }), + shortcut: css({ + padding: theme.spacing(0, 1), + background: shortcutBackgroundColor, + borderRadius: theme.shape.borderRadius(), + fontsize: theme.typography.fontSize, + }), + breadcrumbAncestor: css({ + opacity: 0.5, + marginRight: theme.spacing(1), + }), + subtitleText: css({ + fontSize: theme.typography.fontSize - 2, + }), + shortcutContainer: css({ + display: 'grid', + gridAutoFlow: 'column', + gap: theme.spacing(1), + }), + }; +}; diff --git a/public/app/features/commandPalette/actions/dashboard.nav.actions.ts b/public/app/features/commandPalette/actions/dashboard.nav.actions.ts new file mode 100644 index 00000000000..38ca11e3eb8 --- /dev/null +++ b/public/app/features/commandPalette/actions/dashboard.nav.actions.ts @@ -0,0 +1,24 @@ +import { locationService, getBackendSrv } from '@grafana/runtime'; +import { Action } from 'kbar'; + +async function getDashboardNav(parentId: string): Promise { + const data: Array<{ type: string; title: string; url: string }> = await getBackendSrv().get('/api/search'); + + const goToDashboardActions: Action[] = data + .filter((item) => item.type === 'dash-db') + .map((item) => ({ + parent: parentId, + id: `go/dashboard/${item.url}`, + name: `Go to dashboard ${item.title}`, + perform: () => { + locationService.push(item.url); + }, + })); + + return goToDashboardActions; +} + +export default async (parentId: string) => { + const dashboardNav = await getDashboardNav(parentId); + return dashboardNav; +}; diff --git a/public/app/features/commandPalette/actions/global.static.actions.ts b/public/app/features/commandPalette/actions/global.static.actions.ts new file mode 100644 index 00000000000..c94f3c11c4a --- /dev/null +++ b/public/app/features/commandPalette/actions/global.static.actions.ts @@ -0,0 +1,152 @@ +import { locationService } from '@grafana/runtime'; +import { NavModelItem } from '@grafana/data'; +import { Action, Priority } from 'kbar'; + +export default (navBarTree: NavModelItem[]) => { + const globalActions: Action[] = [ + { + id: 'go/search', + name: 'Go to dashboard search', + keywords: 'navigate', + perform: () => locationService.push('?search=open'), + section: 'Navigation', + shortcut: ['s', 'o'], + }, + { + id: 'go/dashboard', + name: 'Go to dashboard...', + keywords: 'navigate', + section: 'Navigation', + priority: Priority.NORMAL, + }, + { + id: 'preferences/theme', + name: 'Change theme...', + keywords: 'interface color dark light', + section: 'Preferences', + }, + { + id: 'preferences/dark-theme', + name: 'Dark', + keywords: 'dark theme', + section: '', + perform: () => { + locationService.push({ search: '?theme=dark' }); + location.reload(); + }, + parent: 'preferences/theme', + }, + { + id: 'preferences/light-theme', + name: 'Light', + keywords: 'light theme', + section: '', + perform: () => { + locationService.push({ search: '?theme=light' }); + location.reload(); + }, + parent: 'preferences/theme', + }, + ]; + + // this maps actions to navbar by URL items for showing/hiding + // actions is an array for multiple child actions that would be under one navbar item + const navBarActionMap = [ + { + url: '/dashboard/new', + actions: [ + { + id: 'management/create-folder', + name: 'Create folder', + keywords: 'new add', + perform: () => locationService.push('/dashboards/folder/new'), + section: 'Management', + }, + { + id: 'management/create-dashboard', + name: 'Create dashboard', + keywords: 'new add', + perform: () => locationService.push('/dashboard/new'), + section: 'Management', + }, + ], + }, + { + url: '/', + actions: [ + { + id: 'go/home', + name: 'Go to home', + keywords: 'navigate', + perform: () => locationService.push('/'), + section: 'Navigation', + shortcut: ['g', 'h'], + priority: Priority.HIGH, + }, + ], + }, + { + url: '/explore', + actions: [ + { + id: 'go/explore', + name: 'Go to explore', + keywords: 'navigate', + perform: () => locationService.push('/explore'), + section: 'Navigation', + priority: Priority.NORMAL, + }, + ], + }, + { + url: '/alerting', + actions: [ + { + id: 'go/alerting', + name: 'Go to alerting', + keywords: 'navigate notification', + perform: () => locationService.push('/alerting'), + section: 'Navigation', + priority: Priority.NORMAL, + }, + ], + }, + { + url: '/profile', + actions: [ + { + id: 'go/profile', + name: 'Go to profile', + keywords: 'navigate preferences', + perform: () => locationService.push('/profile'), + section: 'Navigation', + shortcut: ['g', 'p'], + priority: Priority.LOW, + }, + ], + }, + { + url: '/datasources', + actions: [ + { + id: 'go/configuration', + name: 'Go to data sources configuration', + keywords: 'navigate settings ds', + perform: () => locationService.push('/datasources'), + section: 'Navigation', + }, + ], + }, + ]; + + const navBarActions: Action[] = []; + + navBarActionMap.forEach((navBarAction) => { + const navBarItem = navBarTree.find((navBarItem) => navBarItem.url === navBarAction.url); + if (navBarItem && !navBarItem.hideFromNavbar) { + navBarActions.push(...navBarAction.actions); + } + }); + + return [...globalActions, ...navBarActions]; +}; diff --git a/public/app/features/explore/ExploreActions.tsx b/public/app/features/explore/ExploreActions.tsx new file mode 100644 index 00000000000..ac1b95e101e --- /dev/null +++ b/public/app/features/explore/ExploreActions.tsx @@ -0,0 +1,94 @@ +import { FC, useEffect, useState } from 'react'; +import { useRegisterActions, useKBar, Action, Priority } from 'kbar'; +import { useDispatch, useSelector } from 'react-redux'; +import { ExploreId } from 'app/types'; +import { splitOpen, splitClose } from './state/main'; +import { isSplit } from './state/selectors'; +import { runQueries } from './state/query'; + +interface Props { + exploreIdLeft: ExploreId; + exploreIdRight?: ExploreId; +} + +export const ExploreActions: FC = ({ exploreIdLeft, exploreIdRight }: Props) => { + const [actions, setActions] = useState([]); + const { query } = useKBar(); + const dispatch = useDispatch(); + const splitted = useSelector(isSplit); + + useEffect(() => { + const exploreSection = { + name: 'Explore', + priority: Priority.HIGH + 1, + }; + + const actionsArr: Action[] = []; + + if (splitted) { + actionsArr.push({ + id: 'explore/run-query-left', + name: 'Run Query (Left)', + keywords: 'query left', + perform: () => { + dispatch(runQueries(exploreIdLeft)); + }, + section: exploreSection, + }); + if (exploreIdRight) { + // we should always have the right exploreId if split + actionsArr.push({ + id: 'explore/run-query-right', + name: 'Run Query (Right)', + keywords: 'query right', + perform: () => { + dispatch(runQueries(exploreIdRight)); + }, + section: exploreSection, + }); + actionsArr.push({ + id: 'explore/split-view-close-left', + name: 'Close split view left', + keywords: 'split', + perform: () => { + dispatch(splitClose(exploreIdLeft)); + }, + section: exploreSection, + }); + actionsArr.push({ + id: 'explore/split-view-close-right', + name: 'Close split view right', + keywords: 'split', + perform: () => { + dispatch(splitClose(exploreIdRight)); + }, + section: exploreSection, + }); + } + } else { + actionsArr.push({ + id: 'explore/run-query', + name: 'Run Query', + keywords: 'query', + perform: () => { + dispatch(runQueries(exploreIdLeft)); + }, + section: exploreSection, + }); + actionsArr.push({ + id: 'explore/split-view-open', + name: 'Open split view', + keywords: 'split', + perform: () => { + dispatch(splitOpen()); + }, + section: exploreSection, + }); + } + setActions(actionsArr); + }, [exploreIdLeft, exploreIdRight, splitted, query, dispatch]); + + useRegisterActions(!query ? [] : actions, [actions, query]); + + return null; +}; diff --git a/public/app/features/explore/Wrapper.tsx b/public/app/features/explore/Wrapper.tsx index 4f2d5439ea4..e1591752591 100644 --- a/public/app/features/explore/Wrapper.tsx +++ b/public/app/features/explore/Wrapper.tsx @@ -6,6 +6,7 @@ import { lastSavedUrl, resetExploreAction, richHistoryUpdatedAction } from './st import { ExplorePaneContainer } from './ExplorePaneContainer'; import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; import { Branding } from '../../core/components/Branding/Branding'; +import { ExploreActions } from './ExploreActions'; import { getNavModel } from '../../core/selectors/navModel'; import { StoreState } from 'app/types'; @@ -69,6 +70,7 @@ class WrapperUnconnected extends PureComponent { return (
+
diff --git a/yarn.lock b/yarn.lock index ef51e3b4ee0..294116d626f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6881,6 +6881,40 @@ __metadata: languageName: node linkType: hard +"@reach/observe-rect@npm:^1.1.0": + version: 1.2.0 + resolution: "@reach/observe-rect@npm:1.2.0" + checksum: 7dd903eeaad0e22c6d973bd26265d91eadba56ab5134701ceb3e85214db75339fae94aa7e8b88a65e8daa64bc7cf1b915d4ffcdfd324466b561dc6adc3c6e070 + languageName: node + linkType: hard + +"@reach/portal@npm:^0.16.0": + version: 0.16.2 + resolution: "@reach/portal@npm:0.16.2" + dependencies: + "@reach/utils": 0.16.0 + tiny-warning: ^1.0.3 + tslib: ^2.3.0 + peerDependencies: + react: ^16.8.0 || 17.x + react-dom: ^16.8.0 || 17.x + checksum: 7413dcd169cfb9854dd0d3a01f811ec19ef170558fcbd00118d676fc02c197d1c0bce1d1357508879d4775169561d103e13a8e4d74cc677eb0037cc7b04f7a1e + languageName: node + linkType: hard + +"@reach/utils@npm:0.16.0": + version: 0.16.0 + resolution: "@reach/utils@npm:0.16.0" + dependencies: + tiny-warning: ^1.0.3 + tslib: ^2.3.0 + peerDependencies: + react: ^16.8.0 || 17.x + react-dom: ^16.8.0 || 17.x + checksum: 36bc0eb41a71798eb6186b23de265ba709e51dae5bf214fb8505c66bb3f2e6a41bb2401457350436ba89ca9e3a50f93a04fe7c33d15648ce11e568a85622d770 + languageName: node + linkType: hard + "@react-aria/button@npm:3.4.3": version: 3.4.3 resolution: "@react-aria/button@npm:3.4.3" @@ -15087,6 +15121,13 @@ __metadata: languageName: node linkType: hard +"command-score@npm:^0.1.2": + version: 0.1.2 + resolution: "command-score@npm:0.1.2" + checksum: b733fd552d7e569070da3d474b1ed5f54785fdf3dd61670002e0a00b2eff1a547c2b6d3af3683c012f4f39c6455f9e7ee5e9997a79c08048ec37ec2195d3df08 + languageName: node + linkType: hard + "commander@npm:*, commander@npm:8.3.0, commander@npm:^8.0.0, commander@npm:^8.1.0, commander@npm:^8.3.0": version: 8.3.0 resolution: "commander@npm:8.3.0" @@ -18998,6 +19039,13 @@ __metadata: languageName: node linkType: hard +"fast-equals@npm:^2.0.3": + version: 2.0.4 + resolution: "fast-equals@npm:2.0.4" + checksum: 1aac8a2e16b33e5e402bb5cd46be65f1ca331903c2c44e3bd75324e8472ee04f0acdbc6889e45fc28f9707ca3964f2a86789b32305d4d8b85dc97f61e446ef4b + languageName: node + linkType: hard + "fast-glob@npm:^2.2.6": version: 2.2.7 resolution: "fast-glob@npm:2.2.7" @@ -20585,6 +20633,7 @@ __metadata: js-yaml: ^4.1.0 json-source-map: 0.6.1 jsurl: ^0.1.5 + kbar: ^0.1.0-beta.30 lerna: ^4.0.0 lezer-promql: 0.22.0 lint-staged: 12.3.7 @@ -24493,6 +24542,22 @@ __metadata: languageName: node linkType: hard +"kbar@npm:^0.1.0-beta.30": + version: 0.1.0-beta.33 + resolution: "kbar@npm:0.1.0-beta.33" + dependencies: + "@reach/portal": ^0.16.0 + command-score: ^0.1.2 + fast-equals: ^2.0.3 + react-virtual: ^2.8.2 + tiny-invariant: ^1.2.0 + peerDependencies: + react: ^16.0.0 || ^17.0.0 + react-dom: ^16.0.0 || ^17.0.0 + checksum: 545720900a046501157f8aab9530f62dec356438b85f728968fdc08192cc65afd903cd27e3a0c0f92a74ad6d15d808f5eb12c8b6a801cf881208e3dc2594eb8b + languageName: node + linkType: hard + "keycharm@npm:^0.2.0": version: 0.2.0 resolution: "keycharm@npm:0.2.0" @@ -31317,6 +31382,17 @@ __metadata: languageName: node linkType: hard +"react-virtual@npm:^2.8.2": + version: 2.10.4 + resolution: "react-virtual@npm:2.10.4" + dependencies: + "@reach/observe-rect": ^1.1.0 + peerDependencies: + react: ^16.6.3 || ^17.0.0 + checksum: 1bebc741b01057829a7d7f29256114caecf0597d41b187cb41e75af77f24a87c780bc1a81ec11205b78ee2e9c801fc5e36b20a9e1ab7ddc70a18dd95417795f8 + languageName: node + linkType: hard + "react-virtualized-auto-sizer@npm:1.0.6": version: 1.0.6 resolution: "react-virtualized-auto-sizer@npm:1.0.6" @@ -34919,6 +34995,13 @@ __metadata: languageName: node linkType: hard +"tiny-invariant@npm:^1.2.0": + version: 1.2.0 + resolution: "tiny-invariant@npm:1.2.0" + checksum: e09a718a7c4a499ba592cdac61f015d87427a0867ca07f50c11fd9b623f90cdba18937b515d4a5e4f43dac92370498d7bdaee0d0e7a377a61095e02c4a92eade + languageName: node + linkType: hard + "tiny-warning@npm:^0.0.3": version: 0.0.3 resolution: "tiny-warning@npm:0.0.3" From 87dc1bfc884ef19ebdc67651273eb0e3d03f6dd1 Mon Sep 17 00:00:00 2001 From: Artur Wierzbicki Date: Fri, 22 Apr 2022 08:23:30 +0400 Subject: [PATCH 085/120] Chore: enforce feature naming convention (#48053) * enforce feature naming convention * fix link * add comment * fix lint * move the feature name check test to toggles_gen_test --- pkg/services/featuremgmt/strcase/camel.go | 92 ++++++++++++++++++++ pkg/services/featuremgmt/toggles_gen_test.go | 52 ++++++++--- 2 files changed, 134 insertions(+), 10 deletions(-) create mode 100644 pkg/services/featuremgmt/strcase/camel.go diff --git a/pkg/services/featuremgmt/strcase/camel.go b/pkg/services/featuremgmt/strcase/camel.go new file mode 100644 index 00000000000..4e355df5975 --- /dev/null +++ b/pkg/services/featuremgmt/strcase/camel.go @@ -0,0 +1,92 @@ +// https://github.com/iancoleman/strcase/blob/master/camel.go +// https://github.com/iancoleman/strcase/blob/master/acronyms.go + +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 Ian Coleman + * Copyright (c) 2018 Ma_124, + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, Subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or Substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package strcase + +import ( + "strings" +) + +var uppercaseAcronym = map[string]string{ + "ID": "id", +} + +// ConfigureAcronym allows you to add additional words which will be considered acronyms +func ConfigureAcronym(key, val string) { + uppercaseAcronym[key] = val +} + +// Converts a string to CamelCase +func toCamelInitCase(s string, initCase bool) string { + s = strings.TrimSpace(s) + if s == "" { + return s + } + if a, ok := uppercaseAcronym[s]; ok { + s = a + } + + n := strings.Builder{} + n.Grow(len(s)) + capNext := initCase + for i, v := range []byte(s) { + vIsCap := v >= 'A' && v <= 'Z' + vIsLow := v >= 'a' && v <= 'z' + if capNext { + if vIsLow { + v += 'A' + v -= 'a' + } + } else if i == 0 { + if vIsCap { + v += 'a' + v -= 'A' + } + } + if vIsCap || vIsLow { + n.WriteByte(v) + capNext = false + } else if vIsNum := v >= '0' && v <= '9'; vIsNum { + n.WriteByte(v) + capNext = true + } else { + capNext = v == '_' || v == ' ' || v == '-' || v == '.' + } + } + return n.String() +} + +// ToCamel converts a string to CamelCase +func ToCamel(s string) string { + return toCamelInitCase(s, true) +} + +// ToLowerCamel converts a string to lowerCamelCase +func ToLowerCamel(s string) string { + return toCamelInitCase(s, false) +} diff --git a/pkg/services/featuremgmt/toggles_gen_test.go b/pkg/services/featuremgmt/toggles_gen_test.go index 27c3f05a753..8bc082537e7 100644 --- a/pkg/services/featuremgmt/toggles_gen_test.go +++ b/pkg/services/featuremgmt/toggles_gen_test.go @@ -12,20 +12,52 @@ import ( "unicode" "github.com/google/go-cmp/cmp" + "github.com/grafana/grafana/pkg/services/featuremgmt/strcase" + "github.com/stretchr/testify/require" ) func TestFeatureToggleFiles(t *testing.T) { - // Typescript files - verifyAndGenerateFile(t, - "../../../packages/grafana-data/src/types/featureToggles.gen.ts", - generateTypeScript(), - ) + legacyNames := map[string]bool{ + "httpclientprovider_azure_auth": true, + "service-accounts": true, + "database_metrics": true, + "live-config": true, + "live-pipeline": true, + "live-service-web-worker": true, + "accesscontrol-builtins": true, + "prometheus_azure_auth": true, + "disable_http_request_histogram": true, + } - // Golang files - verifyAndGenerateFile(t, - "toggles_gen.go", - generateRegistry(t), - ) + t.Run("verify files", func(t *testing.T) { + // Typescript files + verifyAndGenerateFile(t, + "../../../packages/grafana-data/src/types/featureToggles.gen.ts", + generateTypeScript(), + ) + + // Golang files + verifyAndGenerateFile(t, + "toggles_gen.go", + generateRegistry(t), + ) + }) + + t.Run("check feature naming convention", func(t *testing.T) { + invalidNames := make([]string, 0) + for _, f := range standardFeatureFlags { + if legacyNames[f.Name] { + continue + } + + if f.Name != strcase.ToLowerCamel(f.Name) { + invalidNames = append(invalidNames, f.Name) + } + } + + require.Empty(t, invalidNames, "%s feature names should be camel cased", invalidNames) + // acronyms can be configured as needed via `ConfigureAcronym` function from `./strcase/camel.go` + }) } func verifyAndGenerateFile(t *testing.T, fpath string, gen string) { From f2814046d1ef68ebb0cc894deb7c37ea9ccb7076 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Farkas?= Date: Fri, 22 Apr 2022 08:43:33 +0200 Subject: [PATCH 086/120] loki: logrowcontext: explicitly name fields (#48043) --- .../app/plugins/datasource/loki/datasource.ts | 49 +++++++++++++++---- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/public/app/plugins/datasource/loki/datasource.ts b/public/app/plugins/datasource/loki/datasource.ts index 476a1b95a17..96a2357254b 100644 --- a/public/app/plugins/datasource/loki/datasource.ts +++ b/public/app/plugins/datasource/loki/datasource.ts @@ -557,17 +557,46 @@ export class LokiDatasource const limit = (options && options.limit) || 10; const { query, range } = this.prepareLogRowContextQueryTarget(row, limit, direction); - const sortResults = (result: DataQueryResponse): DataQueryResponse => { + const processDataFrame = (frame: DataFrame): DataFrame => { + // log-row-context requires specific field-names to work, so we set them here: "ts", "line", "id" + const cache = new FieldCache(frame); + const timestampField = cache.getFirstFieldOfType(FieldType.time); + const lineField = cache.getFirstFieldOfType(FieldType.string); + const idField = cache.getFieldByName('id'); + + if (timestampField === undefined || lineField === undefined || idField === undefined) { + // this should never really happen, but i want to keep typescript happy + return { ...frame, fields: [] }; + } + + return { + ...frame, + fields: [ + { + ...timestampField, + name: 'ts', + }, + { + ...lineField, + name: 'line', + }, + { + ...idField, + name: 'id', + }, + ], + }; + }; + + const processResults = (result: DataQueryResponse): DataQueryResponse => { + const frames: DataFrame[] = result.data; + const processedFrames = frames + .map((frame) => sortDataFrameByTime(frame, 'DESCENDING')) + .map((frame) => processDataFrame(frame)); // rename fields if needed + return { ...result, - data: result.data.map((frame: DataFrame) => { - const timestampFieldIndex = frame.fields.findIndex((field) => field.type === FieldType.time); - if (timestampFieldIndex === -1) { - return frame; - } - - return sortDataFrameByTime(frame, 'DESCENDING'); - }), + data: processedFrames, }; }; @@ -584,7 +613,7 @@ export class LokiDatasource }; throw error; }), - switchMap((res) => of(sortResults(res))) + switchMap((res) => of(processResults(res))) ) ); }; From 6899f23a22d15b9025e6dc81736d5facc8958868 Mon Sep 17 00:00:00 2001 From: Giordano Ricci Date: Fri, 22 Apr 2022 09:03:24 +0100 Subject: [PATCH 087/120] Explore: prevent direct access to explore if disabled via feature toggle (#47714) * Explore: prevent explore route to be registered if explore is disabled * add feature toggle page --- .../features/explore/FeatureTogglePage.tsx | 30 +++++++++++++++++++ public/app/routes/routes.tsx | 6 +++- 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 public/app/features/explore/FeatureTogglePage.tsx diff --git a/public/app/features/explore/FeatureTogglePage.tsx b/public/app/features/explore/FeatureTogglePage.tsx new file mode 100644 index 00000000000..71ad80801c6 --- /dev/null +++ b/public/app/features/explore/FeatureTogglePage.tsx @@ -0,0 +1,30 @@ +import React from 'react'; +import Page from 'app/core/components/Page/Page'; +import { css } from '@emotion/css'; +import { useStyles2 } from '@grafana/ui'; +import { GrafanaTheme2 } from '@grafana/data'; + +export default function FeatureTogglePage() { + const styles = useStyles2( + (theme: GrafanaTheme2) => + css` + margin-top: ${theme.spacing(2)}; + ` + ); + + return ( + + +

Explore is disabled

+ To enable Explore, enable it in the Grafana config: +
+
+            {`[explore]
+enable = true
+`}
+          
+
+
+
+ ); +} diff --git a/public/app/routes/routes.tsx b/public/app/routes/routes.tsx index b2e353f71b4..9186b51d2d6 100644 --- a/public/app/routes/routes.tsx +++ b/public/app/routes/routes.tsx @@ -161,7 +161,11 @@ export function getAppRoutes(): RouteDescriptor[] { () => (config.viewersCanEdit ? [] : ['Editor', 'Admin']), [AccessControlAction.DataSourcesExplore] ), - component: SafeDynamicImport(() => import(/* webpackChunkName: "explore" */ 'app/features/explore/Wrapper')), + component: SafeDynamicImport(() => + config.exploreEnabled + ? import(/* webpackChunkName: "explore" */ 'app/features/explore/Wrapper') + : import(/* webpackChunkName: "explore-feature-toggle-page" */ 'app/features/explore/FeatureTogglePage') + ), }, { path: '/a/:pluginId/', From 28665a869b443800b7242fd47b1730e25997dc49 Mon Sep 17 00:00:00 2001 From: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com> Date: Fri, 22 Apr 2022 10:46:16 +0200 Subject: [PATCH 088/120] Prometheus: Add report interaction for editor modes (#47940) * Prometheus: Add report interaction for editor modes * Add new query * Fix test * Update public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryEditorSelector.tsx * Add app to feature tracking * Update --- .../components/PromQueryEditorSelector.test.tsx | 7 +++++++ .../components/PromQueryEditorSelector.tsx | 14 +++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryEditorSelector.test.tsx b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryEditorSelector.test.tsx index b2b64c7f516..e754eafebbd 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryEditorSelector.test.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryEditorSelector.test.tsx @@ -18,6 +18,13 @@ jest.mock('../../components/monaco-query-field/MonacoQueryFieldWrapper', () => { }; }); +jest.mock('@grafana/runtime', () => { + return { + ...jest.requireActual('@grafana/runtime'), + reportInteraction: jest.fn(), + }; +}); + const defaultQuery = { refId: 'A', expr: 'metric{label1="foo", label2="bar"}', diff --git a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryEditorSelector.tsx b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryEditorSelector.tsx index e58615f536d..7261e2d8ae4 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryEditorSelector.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryEditorSelector.tsx @@ -1,5 +1,6 @@ import React, { SyntheticEvent, useCallback, useEffect, useState } from 'react'; import { LoadingState } from '@grafana/data'; +import { reportInteraction } from '@grafana/runtime'; import { EditorHeader, EditorRows, FlexItem, InlineSelect, Space } from '@grafana/experimental'; import { Button, ConfirmModal } from '@grafana/ui'; import { PromQueryEditorProps } from '../../components/types'; @@ -17,15 +18,22 @@ import { PromQuery } from '../../types'; import { FeedbackLink } from '../shared/FeedbackLink'; export const PromQueryEditorSelector = React.memo((props) => { - const { onChange, onRunQuery, data } = props; + const { onChange, onRunQuery, data, app } = props; const [parseModalOpen, setParseModalOpen] = useState(false); const [dataIsStale, setDataIsStale] = useState(false); - const query = getQueryWithDefaults(props.query, props.app); + const query = getQueryWithDefaults(props.query, app); const editorMode = query.editorMode!; const onEditorModeChange = useCallback( (newMetricEditorMode: QueryEditorMode) => { + reportInteraction('user_grafana_prometheus_editor_mode_clicked', { + newEditor: newMetricEditorMode, + previousEditor: query.editorMode ?? '', + newQuery: !query.expr, + app: app ?? '', + }); + if (newMetricEditorMode === QueryEditorMode.Builder) { const result = buildVisualQueryFromString(query.expr || ''); // If there are errors, give user a chance to decide if they want to go to builder as that can loose some data. @@ -36,7 +44,7 @@ export const PromQueryEditorSelector = React.memo((props) } changeEditorMode(query, newMetricEditorMode, onChange); }, - [onChange, query] + [onChange, query, app] ); useEffect(() => { From 11bc5e1a0698ed813560f960b534e390d8e04528 Mon Sep 17 00:00:00 2001 From: Ashley Harrison Date: Fri, 22 Apr 2022 10:38:47 +0100 Subject: [PATCH 089/120] Navigation: Prevent chevron overlaying navbar menus (#47988) * Attach nav item menus to a portal that's a sibling of the chevron to prevent incorrect stacking * Make sure hover menus size correctly * refactor into separate component * Fix focus behaviour * fix test again... --- .../components/NavBar/Next/NavBarItemMenu.tsx | 3 --- .../NavBar/Next/NavBarItemMenuTrigger.tsx | 5 ++-- .../components/NavBar/Next/NavBarMenuItem.tsx | 1 + .../NavBar/Next/NavBarMenuPortalContainer.tsx | 26 +++++++++++++++++++ .../components/NavBar/Next/NavBarNext.tsx | 3 +++ .../components/NavBar/Next/NavBarToggle.tsx | 2 +- .../inspect/VariablesUnknownTable.test.tsx | 7 +++-- 7 files changed, 37 insertions(+), 10 deletions(-) create mode 100644 public/app/core/components/NavBar/Next/NavBarMenuPortalContainer.tsx diff --git a/public/app/core/components/NavBar/Next/NavBarItemMenu.tsx b/public/app/core/components/NavBar/Next/NavBarItemMenu.tsx index 9b9695a8f97..6b902ea6f03 100644 --- a/public/app/core/components/NavBar/Next/NavBarItemMenu.tsx +++ b/public/app/core/components/NavBar/Next/NavBarItemMenu.tsx @@ -78,14 +78,11 @@ function getStyles(theme: GrafanaTheme2, reverseDirection?: boolean) { menu: css` background-color: ${theme.colors.background.primary}; border: 1px solid ${theme.components.panel.borderColor}; - bottom: ${reverseDirection ? 0 : 'auto'}; box-shadow: ${theme.shadows.z3}; display: flex; flex-direction: column; - left: 100%; list-style: none; min-width: 140px; - top: ${reverseDirection ? 'auto' : 0}; transition: ${theme.transitions.create('opacity')}; z-index: ${theme.zIndex.sidemenu}; `, diff --git a/public/app/core/components/NavBar/Next/NavBarItemMenuTrigger.tsx b/public/app/core/components/NavBar/Next/NavBarItemMenuTrigger.tsx index 1d2e94978e5..30e44e6d463 100644 --- a/public/app/core/components/NavBar/Next/NavBarItemMenuTrigger.tsx +++ b/public/app/core/components/NavBar/Next/NavBarItemMenuTrigger.tsx @@ -1,6 +1,6 @@ import React, { ReactElement, useEffect, useState } from 'react'; import { css, cx } from '@emotion/css'; -import { getPortalContainer, Icon, IconName, Link, useTheme2 } from '@grafana/ui'; +import { Icon, IconName, Link, useTheme2 } from '@grafana/ui'; import { GrafanaTheme2, NavModelItem } from '@grafana/data'; import { MenuTriggerProps } from '@react-types/menu'; import { useMenuTriggerState } from '@react-stately/menu'; @@ -14,6 +14,7 @@ import { FocusScope } from '@react-aria/focus'; import { NavBarItemMenuContext, useNavBarContext } from '../context'; import { NavFeatureHighlight } from '../NavFeatureHighlight'; import { reportExperimentView } from '@grafana/runtime'; +import { getNavMenuPortalContainer } from './NavBarMenuPortalContainer'; export interface NavBarItemMenuTriggerProps extends MenuTriggerProps { children: ReactElement; @@ -185,7 +186,7 @@ export function NavBarItemMenuTrigger(props: NavBarItemMenuTriggerProps): ReactE
{element} {state.isOpen && ( - + document.getElementById(NAV_MENU_PORTAL_CONTAINER_ID) ?? document.body; + +export const NavBarMenuPortalContainer = () => { + const theme = useTheme2(); + const styles = getStyles(theme); + return
; +}; + +NavBarMenuPortalContainer.displayName = 'NavBarMenuPortalContainer'; + +const getStyles = (theme: GrafanaTheme2) => ({ + menuPortalContainer: css({ + left: 0, + position: 'fixed', + right: 0, + top: 0, + zIndex: theme.zIndex.sidemenu, + }), +}); diff --git a/public/app/core/components/NavBar/Next/NavBarNext.tsx b/public/app/core/components/NavBar/Next/NavBarNext.tsx index a2a07fbac5e..0612dc02d13 100644 --- a/public/app/core/components/NavBar/Next/NavBarNext.tsx +++ b/public/app/core/components/NavBar/Next/NavBarNext.tsx @@ -16,6 +16,7 @@ import { NavBarItemWithoutMenu } from './NavBarItemWithoutMenu'; import { FocusScope } from '@react-aria/focus'; import { NavBarContext } from '../context'; import { NavBarToggle } from './NavBarToggle'; +import { NavBarMenuPortalContainer } from './NavBarMenuPortalContainer'; const onOpenSearch = () => { locationService.partial({ search: 'open' }); @@ -85,6 +86,8 @@ export const NavBarNext = React.memo(() => { onClick={() => setMenuOpen(!menuOpen)} /> + +
    ({ border: `1px solid ${theme.colors.border.weak}`, borderRadius: '50%', marginRight: 0, - zIndex: theme.zIndex.sidemenu, + zIndex: theme.zIndex.sidemenu + 1, [theme.breakpoints.down('md')]: { display: 'none', diff --git a/public/app/features/variables/inspect/VariablesUnknownTable.test.tsx b/public/app/features/variables/inspect/VariablesUnknownTable.test.tsx index bb0cad35a6e..231bc03134c 100644 --- a/public/app/features/variables/inspect/VariablesUnknownTable.test.tsx +++ b/public/app/features/variables/inspect/VariablesUnknownTable.test.tsx @@ -115,10 +115,9 @@ describe('VariablesUnknownTable', () => { await userEvent.click(screen.getByRole('heading', { name: /renamed or missing variables/i })); // make sure we report the interaction for slow expansion - await waitFor(() => expect(reportInteractionSpy).toHaveBeenCalledTimes(2)); - expect(reportInteractionSpy.mock.calls[0][0]).toEqual('Unknown variables section expanded'); - expect(reportInteractionSpy.mock.calls[1][0]).toEqual('Slow unknown variables expansion'); - expect(reportInteractionSpy.mock.calls[1][1]).toEqual({ elapsed: 1000 }); + await waitFor(() => + expect(reportInteractionSpy).toHaveBeenCalledWith('Slow unknown variables expansion', { elapsed: 1000 }) + ); }); }); }); From 3606527359f4ce71091cce084d7c22364f1484fc Mon Sep 17 00:00:00 2001 From: kay delaney <45561153+kaydelaney@users.noreply.github.com> Date: Fri, 22 Apr 2022 10:57:02 +0100 Subject: [PATCH 090/120] Templating: Expose more informative action names for keyed actions (#48076) --- .../features/variables/editor/actions.test.ts | 11 +++++++++-- .../variables/state/keyedVariablesReducer.ts | 18 +++++++++++++++--- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/public/app/features/variables/editor/actions.test.ts b/public/app/features/variables/editor/actions.test.ts index 755259d977f..d421d852f66 100644 --- a/public/app/features/variables/editor/actions.test.ts +++ b/public/app/features/variables/editor/actions.test.ts @@ -56,8 +56,15 @@ describe('switchToListMode', () => { const mockDispatch = jest.fn(); switchToListMode(null)(mockDispatch, mockGetState, undefined); + const keyedAction = { + type: expect.any(String), + payload: { + key: 'null', + action: expect.any(Object), + }, + }; expect(mockDispatch).toHaveBeenCalledTimes(2); - expect(mockDispatch.mock.calls[0][0]).toEqual(toKeyedAction('null', expect.any(Object))); - expect(mockDispatch.mock.calls[1][0]).toEqual(toKeyedAction('null', expect.any(Object))); + expect(mockDispatch.mock.calls[0][0]).toMatchObject(keyedAction); + expect(mockDispatch.mock.calls[1][0]).toMatchObject(keyedAction); }); }); diff --git a/public/app/features/variables/state/keyedVariablesReducer.ts b/public/app/features/variables/state/keyedVariablesReducer.ts index c3fd48ed5c6..56f4aee6b82 100644 --- a/public/app/features/variables/state/keyedVariablesReducer.ts +++ b/public/app/features/variables/state/keyedVariablesReducer.ts @@ -1,5 +1,5 @@ import { AnyAction } from 'redux'; -import { createAction, PayloadAction } from '@reduxjs/toolkit'; +import { PayloadAction } from '@reduxjs/toolkit'; import { getTemplatingReducers, TemplatingState } from './reducers'; import { variablesInitTransaction } from './transactionReducer'; import { toStateKey } from '../utils'; @@ -16,15 +16,27 @@ export interface KeyedAction { action: PayloadAction; } -const keyedAction = createAction('templating/keyedAction'); +const keyedAction = (payload: KeyedAction) => ({ + type: `templating/keyed/${payload.action.type.replace(/^templating\//, '')}`, + payload, +}); export function toKeyedAction(key: string, action: PayloadAction): PayloadAction { const keyAsString = toStateKey(key); return keyedAction({ key: keyAsString, action }); } +const isKeyedAction = (action: AnyAction): action is PayloadAction => { + return ( + typeof action.type === 'string' && + action.type.startsWith('templating/keyed') && + 'payload' in action && + typeof action.payload.key === 'string' + ); +}; + export function keyedVariablesReducer(state = initialKeyedVariablesState, outerAction: AnyAction): KeyedVariablesState { - if (keyedAction.match(outerAction)) { + if (isKeyedAction(outerAction)) { const { key, action } = outerAction.payload; const stringKey = toStateKey(key); const lastKey = variablesInitTransaction.match(action) ? stringKey : state.lastKey; From a34da3e2482b7a9914eedab8bcba1ad194e81ae0 Mon Sep 17 00:00:00 2001 From: Ashley Harrison Date: Fri, 22 Apr 2022 11:04:04 +0100 Subject: [PATCH 091/120] Navigation: Implement scrolling navbar + fix clickable area of grafana logo (#48045) * Attach nav item menus to a portal that's a sibling of the chevron to prevent incorrect stacking * add scrollbar to navbar * Make clickable area of grafana logo full size * hide vertical track as well * prettier... --- .../components/NavBar/Next/NavBarMenu.tsx | 2 +- .../components/NavBar/Next/NavBarNext.tsx | 64 ++++++++++++------- public/app/core/components/NavBar/utils.ts | 3 + 3 files changed, 46 insertions(+), 23 deletions(-) diff --git a/public/app/core/components/NavBar/Next/NavBarMenu.tsx b/public/app/core/components/NavBar/Next/NavBarMenu.tsx index 00e40a6e5f1..2a6cebd020e 100644 --- a/public/app/core/components/NavBar/Next/NavBarMenu.tsx +++ b/public/app/core/components/NavBar/Next/NavBarMenu.tsx @@ -391,7 +391,7 @@ const getCollapsibleStyles = (theme: GrafanaTheme2) => ({ position: 'relative', display: 'grid', gridAutoFlow: 'column', - gridTemplateColumns: '56px auto', + gridTemplateColumns: `${theme.spacing(7)} auto`, }), collapsibleMenuItem: css({ height: theme.spacing(6), diff --git a/public/app/core/components/NavBar/Next/NavBarNext.tsx b/public/app/core/components/NavBar/Next/NavBarNext.tsx index 0612dc02d13..11961c6d8eb 100644 --- a/public/app/core/components/NavBar/Next/NavBarNext.tsx +++ b/public/app/core/components/NavBar/Next/NavBarNext.tsx @@ -3,7 +3,7 @@ import { useLocation } from 'react-router-dom'; import { css, cx } from '@emotion/css'; import { cloneDeep } from 'lodash'; import { GrafanaTheme2, NavModelItem, NavSection } from '@grafana/data'; -import { Icon, IconName, useTheme2 } from '@grafana/ui'; +import { CustomScrollbar, Icon, IconName, useTheme2 } from '@grafana/ui'; import { config, locationService } from '@grafana/runtime'; import { getKioskMode } from 'app/core/navigation/kiosk'; import { KioskMode, StoreState } from 'app/types'; @@ -13,10 +13,10 @@ import { NavBarMenu } from './NavBarMenu'; import NavBarItem from './NavBarItem'; import { useSelector } from 'react-redux'; import { NavBarItemWithoutMenu } from './NavBarItemWithoutMenu'; -import { FocusScope } from '@react-aria/focus'; import { NavBarContext } from '../context'; import { NavBarToggle } from './NavBarToggle'; import { NavBarMenuPortalContainer } from './NavBarMenuPortalContainer'; +import { FocusScope } from '@react-aria/focus'; const onOpenSearch = () => { locationService.partial({ search: 'open' }); @@ -90,6 +90,7 @@ export const NavBarNext = React.memo(() => {
      { > - - - - {coreItems.map((link, index) => ( - - {link.icon && } - {link.img && {`${link.text}} + + + - ))} - {pluginItems.length > 0 && - pluginItems.map((link, index) => ( - + {coreItems.map((link, index) => ( + {link.icon && } {link.img && {`${link.text}} ))} + {pluginItems.length > 0 && + pluginItems.map((link, index) => ( + + {link.icon && } + {link.img && {`${link.text}} + + ))} + + {configItems.map((link, index) => ( ({ zIndex: theme.zIndex.sidemenu, padding: `${theme.spacing(1)} 0`, position: 'relative', - width: theme.spacing(7), + width: `calc(${theme.spacing(7)} + 1px)`, borderRight: `1px solid ${theme.colors.border.weak}`, [theme.breakpoints.down('md')]: { @@ -207,13 +215,22 @@ const getStyles = (theme: GrafanaTheme2) => ({ }, }), grafanaLogo: css({ + alignItems: 'stretch', + display: 'flex', + flexShrink: 0, + justifyContent: 'stretch', + }), + grafanaLogoInner: css({ alignItems: 'center', display: 'flex', - img: { - height: theme.spacing(3), - width: theme.spacing(3), - }, + height: '100%', justifyContent: 'center', + width: '100%', + + '> div': { + height: 'auto', + width: 'auto', + }, }), search: css({ display: 'none', @@ -244,4 +261,7 @@ const getStyles = (theme: GrafanaTheme2) => ({ right: '0px', transform: `translateX(50%)`, }), + menuPortalContainer: css({ + zIndex: theme.zIndex.sidemenu, + }), }); diff --git a/public/app/core/components/NavBar/utils.ts b/public/app/core/components/NavBar/utils.ts index 80b8bca775f..21bc5add093 100644 --- a/public/app/core/components/NavBar/utils.ts +++ b/public/app/core/components/NavBar/utils.ts @@ -8,6 +8,9 @@ import { getFooterLinks } from '../Footer/Footer'; import { HelpModal } from '../help/HelpModal'; export const SEARCH_ITEM_ID = 'search'; +export const NAV_MENU_PORTAL_CONTAINER_ID = 'navbar-menu-portal-container'; + +export const getNavMenuPortalContainer = () => document.getElementById(NAV_MENU_PORTAL_CONTAINER_ID) ?? document.body; export const getForcedLoginUrl = (url: string) => { const queryParams = new URLSearchParams(url.split('?')[1]); From 5f83fc3c61483e66e0e1f14f639b67ca3d9facd0 Mon Sep 17 00:00:00 2001 From: Ashley Harrison Date: Fri, 22 Apr 2022 11:04:23 +0100 Subject: [PATCH 092/120] Navigation: Use correct component for custom branding (#48101) * Use correct component for whitelabelling * extract logic into reusable function --- .../components/NavBar/Next/NavBarMenu.tsx | 25 +++++++++++-------- .../components/NavBar/Next/NavBarNext.tsx | 3 ++- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/public/app/core/components/NavBar/Next/NavBarMenu.tsx b/public/app/core/components/NavBar/Next/NavBarMenu.tsx index 2a6cebd020e..c6e5cefd2b4 100644 --- a/public/app/core/components/NavBar/Next/NavBarMenu.tsx +++ b/public/app/core/components/NavBar/Next/NavBarMenu.tsx @@ -5,6 +5,7 @@ import { CollapsableSection, CustomScrollbar, Icon, IconButton, IconName, useSty import { FocusScope } from '@react-aria/focus'; import { useDialog } from '@react-aria/dialog'; import { OverlayContainer, useOverlay } from '@react-aria/overlays'; +import { Branding } from 'app/core/components/Branding/Branding'; import { css, cx } from '@emotion/css'; import { NavBarMenuItem } from './NavBarMenuItem'; import { NavBarItemWithoutMenu } from './NavBarItemWithoutMenu'; @@ -266,12 +267,7 @@ function NavItem({ isActive={link === activeItem} >
      -
      - {link.icon && } - {link.img && ( - {`${link.text} - )} -
      +
      {getLinkIcon(link)}
      {link.text}
      @@ -362,10 +358,7 @@ function CollapsibleNavItem({ className={styles.collapsibleMenuItem} elClassName={styles.collapsibleIcon} > - {link.img && ( - {`${link.text} - )} - {link.icon && } + {getLinkIcon(link)}
      ({ function linkHasChildren(link: NavModelItem): link is NavModelItem & { children: NavModelItem[] } { return Boolean(link.children && link.children.length > 0); } + +function getLinkIcon(link: NavModelItem) { + if (link.id === 'home') { + return ; + } else if (link.icon) { + return ; + } else if (link.img) { + return {`${link.text}; + } else { + return null; + } +} diff --git a/public/app/core/components/NavBar/Next/NavBarNext.tsx b/public/app/core/components/NavBar/Next/NavBarNext.tsx index 11961c6d8eb..3a9410d8e15 100644 --- a/public/app/core/components/NavBar/Next/NavBarNext.tsx +++ b/public/app/core/components/NavBar/Next/NavBarNext.tsx @@ -6,6 +6,7 @@ import { GrafanaTheme2, NavModelItem, NavSection } from '@grafana/data'; import { CustomScrollbar, Icon, IconName, useTheme2 } from '@grafana/ui'; import { config, locationService } from '@grafana/runtime'; import { getKioskMode } from 'app/core/navigation/kiosk'; +import { Branding } from 'app/core/components/Branding/Branding'; import { KioskMode, StoreState } from 'app/types'; import { enrichConfigItems, getActiveItem, isMatchOrChildMatch, isSearchActive, SEARCH_ITEM_ID } from '../utils'; import { OrgSwitcher } from '../../OrgSwitcher'; @@ -96,7 +97,7 @@ export const NavBarNext = React.memo(() => { className={styles.grafanaLogo} url={homeItem.url} > - + From 2713de2bd1714ec2bda457b95b7b534630d07bc3 Mon Sep 17 00:00:00 2001 From: Gilles De Mey Date: Fri, 22 Apr 2022 14:29:36 +0200 Subject: [PATCH 093/120] Alerting: fix alert creation interval layout bug (#48112) --- .../components/rule-editor/GrafanaConditionsStep.tsx | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/public/app/features/alerting/unified/components/rule-editor/GrafanaConditionsStep.tsx b/public/app/features/alerting/unified/components/rule-editor/GrafanaConditionsStep.tsx index 2d6b637eddf..782b18d8887 100644 --- a/public/app/features/alerting/unified/components/rule-editor/GrafanaConditionsStep.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/GrafanaConditionsStep.tsx @@ -57,7 +57,10 @@ export const GrafanaConditionsStep: FC = () => { return ( - +
      { > Evaluate every - - - + Date: Fri, 22 Apr 2022 09:56:25 -0300 Subject: [PATCH 094/120] Toolkit: Bump axios from 0.21.2 to 0.26.1 (#47904) --- packages/grafana-toolkit/package.json | 2 +- yarn.lock | 35 +++++---------------------- 2 files changed, 7 insertions(+), 30 deletions(-) diff --git a/packages/grafana-toolkit/package.json b/packages/grafana-toolkit/package.json index 467a23cf417..276107db1f7 100644 --- a/packages/grafana-toolkit/package.json +++ b/packages/grafana-toolkit/package.json @@ -49,7 +49,7 @@ "@types/webpack": "4.41.7", "@typescript-eslint/eslint-plugin": "4.28.0", "@typescript-eslint/parser": "4.28.0", - "axios": "0.21.2", + "axios": "0.26.1", "babel-jest": "26.6.3", "babel-loader": "8.2.2", "babel-plugin-angularjs-annotate": "0.10.0", diff --git a/yarn.lock b/yarn.lock index 294116d626f..dae71d7cb2a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4277,7 +4277,7 @@ __metadata: "@types/webpack": 4.41.7 "@typescript-eslint/eslint-plugin": 4.28.0 "@typescript-eslint/parser": 4.28.0 - axios: 0.21.2 + axios: 0.26.1 babel-jest: 26.6.3 babel-loader: 8.2.2 babel-plugin-angularjs-annotate: 0.10.0 @@ -13169,15 +13169,6 @@ __metadata: languageName: node linkType: hard -"axios@npm:0.21.2": - version: 0.21.2 - resolution: "axios@npm:0.21.2" - dependencies: - follow-redirects: ^1.14.0 - checksum: 41299c21f77323e7c56ea49d2d5ed25407d24bb145a4ce3441a8db17359ae56554f9495dca6e15d343a9530e106212a684c75a4db3bedfbe19f6414a8d94378e - languageName: node - linkType: hard - "axios@npm:0.26.1": version: 0.26.1 resolution: "axios@npm:0.26.1" @@ -14414,24 +14405,10 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30000981, caniuse-lite@npm:^1.0.30001109, caniuse-lite@npm:^1.0.30001271": - version: 1.0.30001271 - resolution: "caniuse-lite@npm:1.0.30001271" - checksum: 0271e234e17c588fa203a34523f90c5a21ab62f41a2c3acabe96f0251593ac92f192cadd7a3dcbcf49bb28de4f57ca274d775c75700c3f38e9c42028d3becb0f - languageName: node - linkType: hard - -"caniuse-lite@npm:^1.0.30001286": - version: 1.0.30001297 - resolution: "caniuse-lite@npm:1.0.30001297" - checksum: 4f0d298cf32c050aa1d8a7bb33ef6ff5f289e6dd6dad48b364bc2db91e03b5f0089ffa9950d6228dbd43446695cecd1990601b432a8d03c1d5b2e945cb67bade - languageName: node - linkType: hard - -"caniuse-lite@npm:^1.0.30001317": - version: 1.0.30001319 - resolution: "caniuse-lite@npm:1.0.30001319" - checksum: 1c03cc4ca019c410d197b76604cd8605077ef124906f3debd3f026568e01a1aa3888cdfcb0d23c0786115b0b3f790486f2aa8e0cce361d3dcc5c92ff3611f73e +"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30000981, caniuse-lite@npm:^1.0.30001109, caniuse-lite@npm:^1.0.30001271, caniuse-lite@npm:^1.0.30001286, caniuse-lite@npm:^1.0.30001317": + version: 1.0.30001332 + resolution: "caniuse-lite@npm:1.0.30001332" + checksum: e54182ea42ab3d2ff1440f9a6480292f7ab23c00c188df7ad65586312e4da567e8bedd5cb5fb8f0ff4193dc027a54e17e0b3c0b6db5d5a3fb61c7726ff9c45b3 languageName: node linkType: hard @@ -19425,7 +19402,7 @@ __metadata: languageName: node linkType: hard -"follow-redirects@npm:^1.0.0, follow-redirects@npm:^1.14.0": +"follow-redirects@npm:^1.0.0": version: 1.14.4 resolution: "follow-redirects@npm:1.14.4" peerDependenciesMeta: From 147a1600e7905c4cd30a462ea67aee4e52a921d6 Mon Sep 17 00:00:00 2001 From: Alexandre de Verteuil Date: Fri, 22 Apr 2022 09:15:31 -0400 Subject: [PATCH 095/120] Syntax fix in whats-new-in-v8-5.md (#48111) --- docs/sources/whatsnew/whats-new-in-v8-5.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sources/whatsnew/whats-new-in-v8-5.md b/docs/sources/whatsnew/whats-new-in-v8-5.md index e1ae48e525a..997091d850e 100644 --- a/docs/sources/whatsnew/whats-new-in-v8-5.md +++ b/docs/sources/whatsnew/whats-new-in-v8-5.md @@ -58,7 +58,7 @@ The Bar gauge panel now supports scrolling to support displaying large datasets ### Template variable substitution -We’ve added support to substitute template variables to transformations. This allows dashboards to be more interactive with transformations when a user inputs calculations and $**interval and $**interval_ms. +We’ve added support to substitute template variables to transformations. This allows dashboards to be more interactive with transformations when a user inputs calculations and `$__interval` and `$__interval_ms`. ### Grouping to matrix From 3c6e0e8ef85048af952367751e478c08342e17b4 Mon Sep 17 00:00:00 2001 From: Josh Hunt Date: Fri, 22 Apr 2022 14:33:13 +0100 Subject: [PATCH 096/120] Chore: ESlint import order (#44959) * Add and configure eslint-plugin-import * Fix the lint:ts npm command * Autofix + prettier all the files * Manually fix remaining files * Move jquery code in jest-setup to external file to safely reorder imports * Resolve issue caused by circular dependencies within Prometheus * Update .betterer.results * Fix missing // @ts-ignore * ignore iconBundle.ts * Fix missing // @ts-ignore --- .betterer.results | 538 +++++++++--------- .eslintignore | 3 + .eslintrc | 16 +- .../dashboard-time-zone.spec.ts | 3 +- e2e/panels-suite/panelEdit_queries.spec.ts | 1 + e2e/smoke-tests-suite/1-smoketests.spec.ts | 1 + e2e/verify/specs/smoketests.spec.ts | 1 + package.json | 3 +- packages/grafana-data/rollup.config.ts | 6 +- .../src/dataframe/ArrayDataFrame.test.ts | 3 +- .../src/dataframe/ArrayDataFrame.ts | 7 +- .../src/dataframe/CircularDataFrame.ts | 3 +- .../src/dataframe/DataFrameJSON.test.ts | 1 + .../src/dataframe/DataFrameJSON.ts | 1 + .../src/dataframe/DataFrameView.test.ts | 5 +- .../src/dataframe/DataFrameView.ts | 2 +- .../src/dataframe/FieldCache.test.ts | 3 +- .../src/dataframe/MutableDataFrame.test.ts | 1 + .../src/dataframe/MutableDataFrame.ts | 10 +- .../grafana-data/src/dataframe/dimensions.ts | 2 +- .../src/dataframe/frameComparisons.test.ts | 1 + .../src/dataframe/processDataFrame.test.ts | 10 +- .../src/dataframe/processDataFrame.ts | 11 +- .../grafana-data/src/dataframe/utils.test.ts | 3 +- packages/grafana-data/src/dataframe/utils.ts | 1 + .../src/datetime/datemath.test.ts | 2 +- .../grafana-data/src/datetime/datemath.ts | 4 +- .../grafana-data/src/datetime/durationutil.ts | 2 +- .../grafana-data/src/datetime/formatter.ts | 6 +- .../src/datetime/moment_wrapper.ts | 3 +- .../grafana-data/src/datetime/parser.test.ts | 2 +- packages/grafana-data/src/datetime/parser.ts | 5 +- .../src/datetime/rangeutil.test.ts | 4 +- .../grafana-data/src/datetime/rangeutil.ts | 2 +- .../src/datetime/timezones.test.ts | 2 +- .../grafana-data/src/datetime/timezones.ts | 4 +- .../grafana-data/src/events/EventBus.test.ts | 4 +- packages/grafana-data/src/events/EventBus.ts | 1 + packages/grafana-data/src/events/common.ts | 1 + .../src/field/FieldConfigOptionsRegistry.tsx | 2 +- .../src/field/displayProcessor.test.ts | 9 +- .../src/field/displayProcessor.ts | 15 +- .../grafana-data/src/field/fieldColor.test.ts | 1 + packages/grafana-data/src/field/fieldColor.ts | 10 +- .../grafana-data/src/field/fieldComparers.ts | 5 +- .../src/field/fieldDisplay.test.ts | 8 +- .../grafana-data/src/field/fieldDisplay.ts | 15 +- .../src/field/fieldOverrides.test.ts | 27 +- .../grafana-data/src/field/fieldOverrides.ts | 24 +- .../grafana-data/src/field/fieldState.test.ts | 5 +- .../field/getFieldDisplayValuesProxy.test.tsx | 5 +- .../src/field/getFieldDisplayValuesProxy.ts | 2 + packages/grafana-data/src/field/scale.test.ts | 9 +- packages/grafana-data/src/field/scale.ts | 2 + .../standardFieldConfigEditorRegistry.ts | 8 +- .../src/field/templateProxies.test.ts | 3 +- .../grafana-data/src/field/templateProxies.ts | 3 +- .../grafana-data/src/field/thresholds.test.ts | 5 +- packages/grafana-data/src/geo/layer.ts | 11 +- .../src/panel/PanelPlugin.test.tsx | 8 +- .../grafana-data/src/panel/PanelPlugin.ts | 10 +- .../src/panel/registryFactories.ts | 1 + packages/grafana-data/src/text/markdown.ts | 1 + packages/grafana-data/src/text/sanitize.ts | 2 +- .../grafana-data/src/themes/createColors.ts | 1 + .../grafana-data/src/themes/createTheme.ts | 4 +- .../grafana-data/src/themes/createV1Theme.ts | 1 + .../src/themes/createVisualizationColors.ts | 1 + packages/grafana-data/src/themes/types.ts | 5 +- .../src/transformations/fieldReducer.test.ts | 8 +- .../src/transformations/matchers.ts | 13 +- .../matchers/fieldTypeMatcher.test.ts | 3 +- .../matchers/fieldTypeMatcher.ts | 3 +- .../transformations/matchers/matchers.test.ts | 1 + .../matchers/nameMatcher.test.ts | 5 +- .../transformations/matchers/nameMatcher.ts | 9 +- .../matchers/predicates.test.ts | 3 +- .../transformations/matchers/predicates.ts | 5 +- .../transformations/matchers/refIdMatcher.ts | 7 +- .../matchers/simpleFieldMatcher.ts | 3 +- .../matchers/valueMatchers/equalMatchers.ts | 1 + .../matchers/valueMatchers/nullMatchers.ts | 1 + .../matchers/valueMatchers/numericMatchers.ts | 1 + .../matchers/valueMatchers/rangeMatchers.ts | 1 + .../matchers/valueMatchers/regexMatchers.ts | 1 + .../standardTransformersRegistry.ts | 1 + .../transformDataFrame.test.ts | 13 +- .../src/transformations/transformDataFrame.ts | 1 + .../src/transformations/transformers.ts | 26 +- .../transformers/calculateField.test.ts | 17 +- .../transformers/calculateField.ts | 17 +- .../transformers/concat.test.ts | 1 + .../transformations/transformers/concat.ts | 5 +- .../transformers/convertFieldType.test.ts | 1 + .../transformers/convertFieldType.ts | 7 +- .../transformers/ensureColumns.test.ts | 3 +- .../transformers/ensureColumns.ts | 12 +- .../transformers/filter.test.ts | 9 +- .../transformations/transformers/filter.ts | 5 +- .../transformers/filterByName.test.ts | 7 +- .../transformers/filterByName.ts | 5 +- .../transformers/filterByRefId.test.ts | 5 +- .../transformers/filterByRefId.ts | 5 +- .../transformers/filterByValue.test.ts | 13 +- .../transformers/filterByValue.ts | 11 +- .../transformers/groupBy.test.ts | 12 +- .../transformations/transformers/groupBy.ts | 9 +- .../transformers/groupingToMatrix.test.ts | 4 +- .../transformers/groupingToMatrix.ts | 5 +- .../transformers/histogram.test.ts | 1 + .../transformations/transformers/histogram.ts | 11 +- .../transformers/joinDataFrames.test.ts | 1 + .../transformers/joinDataFrames.ts | 2 +- .../transformers/labelsToFields.test.ts | 9 +- .../transformers/labelsToFields.ts | 7 +- .../transformers/merge.test.ts | 9 +- .../src/transformations/transformers/merge.ts | 11 +- .../src/transformations/transformers/noop.ts | 3 +- .../transformers/order.test.ts | 4 +- .../src/transformations/transformers/order.ts | 10 +- .../transformers/organize.test.ts | 4 +- .../transformations/transformers/organize.ts | 5 +- .../transformers/reduce.test.ts | 19 +- .../transformations/transformers/reduce.ts | 17 +- .../transformers/rename.test.ts | 4 +- .../transformations/transformers/rename.ts | 10 +- .../transformers/renameByRegex.test.ts | 4 +- .../transformers/renameByRegex.ts | 8 +- .../transformers/seriesToColumns.test.ts | 4 +- .../transformers/seriesToColumns.ts | 5 +- .../transformers/seriesToRows.test.ts | 9 +- .../transformers/seriesToRows.ts | 11 +- .../transformers/sortBy.test.ts | 8 +- .../transformations/transformers/sortBy.ts | 9 +- .../src/types/OptionsUIRegistryBuilder.ts | 4 +- .../grafana-data/src/types/annotations.ts | 4 +- packages/grafana-data/src/types/app.ts | 1 + packages/grafana-data/src/types/config.ts | 10 +- packages/grafana-data/src/types/data.ts | 9 +- packages/grafana-data/src/types/dataFrame.ts | 10 +- packages/grafana-data/src/types/dataLink.ts | 4 +- packages/grafana-data/src/types/datasource.ts | 21 +- .../grafana-data/src/types/fieldOverrides.ts | 8 +- packages/grafana-data/src/types/graph.ts | 2 +- .../grafana-data/src/types/legacyEvents.ts | 9 +- packages/grafana-data/src/types/logs.ts | 2 +- packages/grafana-data/src/types/logsVolume.ts | 5 +- packages/grafana-data/src/types/panel.ts | 22 +- packages/grafana-data/src/types/plugin.ts | 1 + .../grafana-data/src/types/queryRunner.ts | 5 +- .../grafana-data/src/types/transformations.ts | 3 +- packages/grafana-data/src/types/variables.ts | 2 +- .../src/utils/OptionsUIBuilders.ts | 6 +- .../grafana-data/src/utils/Registry.test.ts | 3 +- .../grafana-data/src/utils/arrayUtils.test.ts | 1 + packages/grafana-data/src/utils/csv.test.ts | 7 +- packages/grafana-data/src/utils/csv.ts | 6 +- .../grafana-data/src/utils/dataLinks.test.ts | 3 +- packages/grafana-data/src/utils/dataLinks.ts | 1 + packages/grafana-data/src/utils/datasource.ts | 1 + .../grafana-data/src/utils/fieldParser.ts | 2 +- .../grafana-data/src/utils/flotPairs.test.ts | 5 +- packages/grafana-data/src/utils/flotPairs.ts | 2 +- .../grafana-data/src/utils/labels.test.ts | 3 +- packages/grafana-data/src/utils/location.ts | 6 +- packages/grafana-data/src/utils/logs.test.ts | 3 +- packages/grafana-data/src/utils/logs.ts | 2 +- .../src/utils/namedColorsPalette.test.ts | 3 +- .../grafana-data/src/utils/series.test.ts | 3 +- .../src/utils/valueMappings.test.ts | 3 +- .../grafana-data/src/utils/valueMappings.ts | 4 +- .../src/valueFormats/arithmeticFormatters.ts | 3 +- .../src/valueFormats/categories.ts | 20 +- .../valueFormats/dateTimeFormatters.test.ts | 3 +- .../src/valueFormats/dateTimeFormatters.ts | 6 +- .../src/valueFormats/symbolFormatters.ts | 3 +- .../src/valueFormats/valueFormats.test.ts | 7 +- .../src/valueFormats/valueFormats.ts | 5 +- .../src/vector/AppendedVectors.test.ts | 2 +- .../src/vector/AppendedVectors.ts | 1 + .../grafana-data/src/vector/ArrayVector.ts | 1 + .../grafana-data/src/vector/AsNumberVector.ts | 1 + .../src/vector/BinaryOperationVector.test.ts | 3 +- .../src/vector/BinaryOperationVector.ts | 3 +- .../grafana-data/src/vector/CircularVector.ts | 3 +- .../src/vector/FormattedVector.ts | 3 +- .../src/vector/FunctionalVector.ts | 3 +- .../grafana-data/src/vector/IndexVector.ts | 1 + packages/grafana-data/src/vector/RowVector.ts | 1 + .../grafana-data/src/vector/SortedVector.ts | 1 + .../src/selectors/index.ts | 5 +- packages/grafana-e2e/cli.js | 4 +- .../plugins/benchmark/CDPDataCollector.ts | 4 +- .../cypress/plugins/benchmark/formatting.ts | 3 +- .../cypress/plugins/benchmark/index.ts | 7 +- packages/grafana-e2e/cypress/plugins/index.js | 2 +- .../cypress/plugins/readProvisions.js | 2 +- .../cypress/plugins/typescriptPreprocessor.js | 2 +- packages/grafana-e2e/rollup.config.ts | 2 +- .../grafana-e2e/src/flows/addDashboard.ts | 8 +- .../grafana-e2e/src/flows/addDataSource.ts | 6 +- packages/grafana-e2e/src/flows/addPanel.ts | 6 +- .../grafana-e2e/src/flows/configurePanel.ts | 1 + .../grafana-e2e/src/flows/importDashboard.ts | 3 +- .../grafana-e2e/src/flows/importDashboards.ts | 3 +- .../grafana-e2e/src/flows/openDashboard.ts | 1 + .../grafana-e2e/src/flows/setTimeRange.ts | 1 + packages/grafana-e2e/src/index.ts | 9 +- .../src/support/scenarioContext.ts | 2 +- packages/grafana-e2e/src/support/types.ts | 2 + packages/grafana-runtime/rollup.config.ts | 2 +- .../src/components/DataSourcePicker.test.tsx | 5 +- .../src/components/DataSourcePicker.tsx | 3 +- .../src/components/PanelDataErrorView.tsx | 1 + .../src/components/PanelRenderer.tsx | 1 + packages/grafana-runtime/src/config.ts | 1 + .../src/services/LocationService.ts | 7 +- packages/grafana-runtime/src/services/live.ts | 3 +- .../src/utils/DataSourceWithBackend.test.ts | 6 +- .../src/utils/DataSourceWithBackend.ts | 9 +- .../grafana-runtime/src/utils/analytics.ts | 4 +- packages/grafana-runtime/src/utils/plugin.ts | 4 +- .../src/utils/queryResponse.test.ts | 4 +- .../src/utils/queryResponse.ts | 2 + packages/grafana-schema/rollup.config.ts | 2 +- .../install/bin/githubRelease.js | 5 +- packages/grafana-toolkit/src/cli/index.ts | 31 +- .../src/cli/tasks/changelog.ts | 8 +- .../src/cli/tasks/cherrypick.ts | 3 +- .../src/cli/tasks/closeMilestone.ts | 3 +- .../src/cli/tasks/component.create.ts | 8 +- .../src/cli/tasks/core.start.ts | 1 + .../src/cli/tasks/nodeVersionChecker.ts | 5 +- .../src/cli/tasks/package.build.ts | 12 +- .../src/cli/tasks/plugin.build.ts | 18 +- .../src/cli/tasks/plugin.ci.ts | 22 +- .../src/cli/tasks/plugin.create.ts | 2 + .../src/cli/tasks/plugin.dev.ts | 10 +- .../src/cli/tasks/plugin.sign.ts | 4 +- .../src/cli/tasks/plugin.tests.ts | 2 +- .../src/cli/tasks/plugin.update.ts | 6 +- .../src/cli/tasks/plugin.utils.ts | 19 +- .../src/cli/tasks/plugin/bundle.managed.ts | 5 +- .../src/cli/tasks/plugin/bundle.ts | 5 +- .../src/cli/tasks/plugin/create.ts | 1 + .../src/cli/tasks/plugin/tests.ts | 3 +- .../src/cli/tasks/searchTestDataSetup.ts | 1 + .../src/cli/tasks/toolkit.build.ts | 4 +- .../grafana-toolkit/src/cli/utils/execTask.ts | 3 +- .../src/cli/utils/githubRelease.ts | 8 +- .../src/config/jest.plugin.config.ts | 2 +- .../src/config/webpack.plugin.config.test.ts | 3 +- .../src/config/webpack.plugin.config.ts | 21 +- .../src/config/webpack/loaders.ts | 1 + packages/grafana-toolkit/src/plugins/env.ts | 4 +- .../grafana-toolkit/src/plugins/manifest.ts | 5 +- packages/grafana-toolkit/src/plugins/utils.ts | 4 +- .../grafana-toolkit/src/plugins/workflow.ts | 5 +- packages/grafana-ui/rollup.config.ts | 2 +- .../src/components/Alert/Alert.story.tsx | 11 +- .../grafana-ui/src/components/Alert/Alert.tsx | 8 +- .../src/components/Badge/Badge.story.tsx | 5 +- .../grafana-ui/src/components/Badge/Badge.tsx | 12 +- .../components/BarGauge/BarGauge.story.tsx | 13 +- .../src/components/BarGauge/BarGauge.test.tsx | 4 +- .../src/components/BarGauge/BarGauge.tsx | 6 +- .../components/BigValue/BigValue.story.tsx | 11 +- .../src/components/BigValue/BigValue.test.tsx | 6 +- .../src/components/BigValue/BigValue.tsx | 4 +- .../BigValue/BigValueLayout.test.tsx | 3 +- .../components/BigValue/BigValueLayout.tsx | 12 +- .../src/components/BrowserLabel/Label.tsx | 10 +- .../src/components/Button/Button.story.tsx | 12 +- .../src/components/Button/Button.tsx | 12 +- .../src/components/Button/ButtonGroup.tsx | 6 +- .../Button/FullWidthButtonContainer.tsx | 3 +- .../components/Button/ToolbarButton.story.tsx | 9 +- .../src/components/Button/ToolbarButton.tsx | 17 +- .../components/Button/ToolbarButtonRow.tsx | 6 +- .../ButtonCascader/ButtonCascader.story.tsx | 7 +- .../ButtonCascader/ButtonCascader.tsx | 13 +- .../CallToActionCard.story.internal.tsx | 10 +- .../CallToActionCard.test.tsx | 6 +- .../CallToActionCard/CallToActionCard.tsx | 6 +- .../src/components/Card/Card.story.tsx | 10 +- .../src/components/Card/Card.test.tsx | 6 +- .../grafana-ui/src/components/Card/Card.tsx | 7 +- .../src/components/Card/CardContainer.tsx | 4 +- .../components/Cascader/Cascader.story.tsx | 7 +- .../src/components/Cascader/Cascader.test.tsx | 5 +- .../src/components/Cascader/Cascader.tsx | 18 +- .../src/components/Cascader/optionMappings.ts | 1 + .../ClickOutsideWrapper.story.tsx | 6 +- .../ClipboardButton.story.internal.tsx | 6 +- .../ClipboardButton/ClipboardButton.tsx | 1 + .../Collapse/CollapsableSection.story.tsx | 1 + .../Collapse/CollapsableSection.tsx | 10 +- .../components/Collapse/Collapse.story.tsx | 6 +- .../src/components/Collapse/Collapse.tsx | 3 +- .../src/components/ColorPicker/ColorInput.tsx | 12 +- .../ColorPicker/ColorPicker.story.tsx | 13 +- .../ColorPicker/ColorPicker.test.tsx | 1 + .../components/ColorPicker/ColorPicker.tsx | 18 +- .../ColorPicker/ColorPickerPopover.story.tsx | 6 +- .../ColorPicker/ColorPickerPopover.test.tsx | 8 +- .../ColorPicker/ColorPickerPopover.tsx | 19 +- .../components/ColorPicker/ColorSwatch.tsx | 8 +- .../ColorPicker/NamedColorsGroup.tsx | 15 +- .../ColorPicker/NamedColorsPalette.story.tsx | 6 +- .../ColorPicker/NamedColorsPalette.test.tsx | 6 +- .../ColorPicker/NamedColorsPalette.tsx | 13 +- .../ColorPicker/SeriesColorPickerPopover.tsx | 9 +- .../ColorPicker/SpectrumPalette.story.tsx | 6 +- .../ColorPicker/SpectrumPalette.tsx | 16 +- .../warnAboutColorPickerPropsDeprecation.ts | 1 + .../ConfirmButton/ConfirmButton.story.tsx | 13 +- .../ConfirmButton/ConfirmButton.test.tsx | 5 +- .../ConfirmButton/ConfirmButton.tsx | 6 +- .../components/ConfirmButton/DeleteButton.tsx | 4 +- .../ConfirmModal/ConfirmModal.story.tsx | 11 +- .../ConfirmModal/ConfirmModal.test.tsx | 2 +- .../components/ConfirmModal/ConfirmModal.tsx | 9 +- .../ContextMenu/ContextMenu.story.tsx | 8 +- .../components/ContextMenu/ContextMenu.tsx | 6 +- .../ContextMenu/WithContextMenu.tsx | 1 + .../CustomScrollbar/CustomScrollbar.test.tsx | 1 + .../CustomScrollbar/CustomScrollbar.tsx | 4 +- .../components/DataLinks/DataLinkButton.tsx | 4 +- .../components/DataLinks/DataLinkEditor.tsx | 11 +- .../components/DataLinks/DataLinkInput.tsx | 30 +- .../DataLinks/DataLinkSuggestions.tsx | 6 +- .../DataLinks/DataLinksContextMenu.test.tsx | 6 +- .../DataLinks/DataLinksContextMenu.tsx | 6 +- .../DataLinkEditorModalContent.tsx | 6 +- .../DataLinksInlineEditor.tsx | 13 +- .../DataLinksListItem.test.tsx | 3 +- .../DataLinksListItem.tsx | 6 +- .../components/DataLinks/FieldLinkList.tsx | 5 +- .../DataSourceSettings/AlertingSettings.tsx | 6 +- .../DataSourceSettings/BasicAuthSettings.tsx | 3 +- .../DataSourceSettings/CertificationKey.tsx | 5 +- .../CustomHeadersSettings.test.tsx | 5 +- .../CustomHeadersSettings.tsx | 6 +- .../DataSourceHttpSettings.story.tsx | 4 +- .../DataSourceHttpSettings.tsx | 21 +- .../DataSourceSettings/HttpProxySettings.tsx | 4 +- .../DataSourceSettings/SigV4AuthSettings.tsx | 6 +- .../DataSourceSettings/TLSAuthSettings.tsx | 11 +- .../components/DataSourceSettings/types.ts | 1 + .../DatePicker/DatePicker.story.tsx | 8 +- .../DatePicker/DatePicker.test.tsx | 3 +- .../DateTimePickers/DatePicker/DatePicker.tsx | 4 +- .../DatePickerWithInput.story.tsx | 4 +- .../DatePickerWithInput.test.tsx | 6 +- .../DatePickerWithInput.tsx | 8 +- .../DateTimePicker/DateTimePicker.story.tsx | 7 +- .../DateTimePicker/DateTimePicker.test.tsx | 4 +- .../DateTimePicker/DateTimePicker.tsx | 14 +- .../RelativeTimeRangePicker.story.tsx | 4 +- .../RelativeTimeRangePicker.test.tsx | 6 +- .../RelativeTimeRangePicker.tsx | 17 +- .../DateTimePickers/TimeOfDayPicker.story.tsx | 5 +- .../DateTimePickers/TimeOfDayPicker.tsx | 8 +- .../DateTimePickers/TimeRangeInput.story.tsx | 9 +- .../DateTimePickers/TimeRangeInput.tsx | 9 +- .../DateTimePickers/TimeRangePicker.story.tsx | 10 +- .../DateTimePickers/TimeRangePicker.test.tsx | 4 +- .../DateTimePickers/TimeRangePicker.tsx | 30 +- .../TimeRangePicker/CalendarBody.tsx | 13 +- .../TimeRangePicker/CalendarFooter.tsx | 7 +- .../TimeRangePicker/CalendarHeader.tsx | 17 +- .../TimeRangePicker/TimePickerCalendar.tsx | 13 +- .../TimePickerContent.test.tsx | 4 +- .../TimeRangePicker/TimePickerContent.tsx | 15 +- .../TimeRangePicker/TimePickerFooter.tsx | 16 +- .../TimeRangePicker/TimePickerTitle.tsx | 4 +- .../TimeRangePicker/TimeRangeForm.test.tsx | 6 +- .../TimeRangePicker/TimeRangeForm.tsx | 5 +- .../TimeRangePicker/TimeRangeList.tsx | 7 +- .../TimeRangePicker/TimeRangeOption.tsx | 6 +- .../DateTimePickers/TimeZonePicker.story.tsx | 3 +- .../DateTimePickers/TimeZonePicker.tsx | 7 +- .../TimeZonePicker/TimeZoneDescription.tsx | 4 +- .../TimeZonePicker/TimeZoneGroup.tsx | 4 +- .../TimeZonePicker/TimeZoneOffset.tsx | 8 +- .../TimeZonePicker/TimeZoneOption.tsx | 9 +- .../TimeZonePicker/TimeZoneTitle.tsx | 4 +- .../DateTimePickers/WeekStartPicker.story.tsx | 3 +- .../DateTimePickers/WeekStartPicker.tsx | 4 +- .../src/components/Drawer/Drawer.story.tsx | 7 +- .../src/components/Drawer/Drawer.tsx | 15 +- .../Dropdown/ButtonSelect.story.internal.tsx | 11 +- .../src/components/Dropdown/ButtonSelect.tsx | 16 +- .../EmptySearchResult.story.tsx | 4 +- .../EmptySearchResult/EmptySearchResult.tsx | 6 +- .../ErrorBoundary/ErrorBoundary.story.tsx | 11 +- .../ErrorBoundary/ErrorBoundary.test.tsx | 7 +- .../ErrorBoundary/ErrorBoundary.tsx | 4 +- .../ErrorBoundary/ErrorWithStack.tsx | 8 +- .../FileDropzone/FileDropzone.story.tsx | 5 +- .../FileDropzone/FileDropzone.test.tsx | 1 + .../components/FileDropzone/FileDropzone.tsx | 5 +- .../FileDropzone/FileListItem.story.tsx | 2 + .../FileDropzone/FileListItem.test.tsx | 1 + .../components/FileDropzone/FileListItem.tsx | 5 +- .../FileUpload/FileUpload.story.tsx | 11 +- .../components/FileUpload/FileUpload.test.tsx | 3 +- .../src/components/FileUpload/FileUpload.tsx | 10 +- .../components/FilterInput/FilterInput.tsx | 2 + .../FilterPill/FilterPill.story.tsx | 9 +- .../src/components/FilterPill/FilterPill.tsx | 10 +- .../FormField/FormField.story.internal.tsx | 4 +- .../components/FormField/FormField.test.tsx | 3 +- .../src/components/FormField/FormField.tsx | 3 +- .../src/components/FormLabel/FormLabel.tsx | 5 +- .../FormattedValueDisplay.story.tsx | 4 +- .../FormattedValueDisplay.tsx | 1 + .../src/components/Forms/Checkbox.story.tsx | 6 +- .../src/components/Forms/Checkbox.tsx | 11 +- .../src/components/Forms/Field.story.tsx | 6 +- .../src/components/Forms/Field.test.tsx | 6 +- .../grafana-ui/src/components/Forms/Field.tsx | 11 +- .../src/components/Forms/FieldArray.story.tsx | 7 +- .../src/components/Forms/FieldArray.tsx | 1 + .../src/components/Forms/FieldSet.story.tsx | 7 +- .../src/components/Forms/FieldSet.tsx | 5 +- .../Forms/FieldValidationMessage.story.tsx | 3 +- .../Forms/FieldValidationMessage.tsx | 6 +- .../src/components/Forms/Form.story.tsx | 5 +- .../grafana-ui/src/components/Forms/Form.tsx | 3 +- .../components/Forms/InlineField.story.tsx | 4 +- .../src/components/Forms/InlineField.test.tsx | 6 +- .../src/components/Forms/InlineField.tsx | 11 +- .../components/Forms/InlineFieldRow.story.tsx | 6 +- .../src/components/Forms/InlineFieldRow.tsx | 6 +- .../components/Forms/InlineLabel.story.tsx | 1 + .../src/components/Forms/InlineLabel.tsx | 4 +- .../components/Forms/InlineSegmentGroup.tsx | 4 +- .../src/components/Forms/Label.story.tsx | 1 + .../grafana-ui/src/components/Forms/Label.tsx | 8 +- .../Legacy/Input/Input.story.internal.tsx | 11 +- .../Forms/Legacy/Input/Input.test.tsx | 8 +- .../components/Forms/Legacy/Input/Input.tsx | 5 +- .../Legacy/Select/IndicatorsContainer.tsx | 3 +- .../Forms/Legacy/Select/NoOptionsMessage.tsx | 1 + .../Legacy/Select/Select.story.internal.tsx | 9 +- .../components/Forms/Legacy/Select/Select.tsx | 16 +- .../Forms/Legacy/Select/SelectOption.test.tsx | 5 +- .../Forms/Legacy/Select/SelectOption.tsx | 3 +- .../Legacy/Switch/Switch.story.internal.tsx | 2 +- .../components/Forms/Legacy/Switch/Switch.tsx | 7 +- .../src/components/Forms/Legend.story.tsx | 3 +- .../src/components/Forms/Legend.tsx | 8 +- .../Forms/RadioButtonGroup/RadioButton.tsx | 12 +- .../RadioButtonGroup.story.tsx | 7 +- .../RadioButtonGroup/RadioButtonGroup.tsx | 11 +- .../src/components/Forms/commonStyles.ts | 2 + .../src/components/Forms/getFormStyles.ts | 14 +- .../src/components/Gauge/Gauge.test.tsx | 8 +- .../grafana-ui/src/components/Gauge/Gauge.tsx | 4 +- .../src/components/Graph/Graph.test.tsx | 11 +- .../grafana-ui/src/components/Graph/Graph.tsx | 11 +- .../src/components/Graph/GraphContextMenu.tsx | 13 +- .../components/Graph/GraphSeriesToggler.tsx | 5 +- .../Graph/GraphTooltip/GraphTooltip.tsx | 4 +- .../MultiModeGraphTooltip.test.tsx | 9 +- .../GraphTooltip/MultiModeGraphTooltip.tsx | 11 +- .../GraphTooltip/SingleModeGraphTooltip.tsx | 3 + .../components/Graph/GraphTooltip/types.ts | 3 +- .../Graph/GraphWithLegend.story.internal.tsx | 10 +- .../src/components/Graph/GraphWithLegend.tsx | 14 +- .../src/components/Graph/utils.test.ts | 2 + .../src/components/GraphNG/GraphNG.tsx | 19 +- .../src/components/GraphNG/hooks.ts | 6 +- .../GraphNG/nullInsertThreshold.test.ts | 1 + .../src/components/GraphNG/types.ts | 1 + .../src/components/GraphNG/utils.test.ts | 6 +- .../src/components/GraphNG/utils.ts | 7 +- .../src/components/Icon/Icon.story.tsx | 7 +- .../grafana-ui/src/components/Icon/Icon.tsx | 13 +- .../src/components/Icon/iconBundle.ts | 107 ++-- .../IconButton/IconButton.story.tsx | 10 +- .../src/components/IconButton/IconButton.tsx | 14 +- .../src/components/InfoBox/FeatureInfoBox.tsx | 7 +- .../src/components/InfoBox/InfoBox.story.tsx | 6 +- .../src/components/InfoBox/InfoBox.tsx | 8 +- .../InfoTooltip.story.internal.tsx | 3 +- .../components/InfoTooltip/InfoTooltip.tsx | 3 +- .../src/components/Input/Input.story.tsx | 11 +- .../grafana-ui/src/components/Input/Input.tsx | 12 +- .../JSONFormatter/JSONFormatter.tsx | 1 + .../json_explorer/json_explorer.ts | 4 +- .../src/components/Layout/Layout.story.tsx | 13 +- .../src/components/Layout/Layout.tsx | 4 +- .../grafana-ui/src/components/Link/Link.tsx | 3 +- .../src/components/List/AbstractList.test.tsx | 3 +- .../src/components/List/AbstractList.tsx | 3 +- .../src/components/List/InlineList.tsx | 1 + .../components/List/List.story.internal.tsx | 7 +- .../grafana-ui/src/components/List/List.tsx | 1 + .../LoadingPlaceholder.story.tsx | 4 +- .../LoadingPlaceholder/LoadingPlaceholder.tsx | 6 +- .../src/components/Logs/LogDetails.test.tsx | 3 +- .../src/components/Logs/LogDetails.tsx | 14 +- .../components/Logs/LogDetailsRow.test.tsx | 3 +- .../src/components/Logs/LogDetailsRow.tsx | 12 +- .../src/components/Logs/LogLabelStats.tsx | 5 +- .../src/components/Logs/LogLabelStatsRow.tsx | 4 +- .../src/components/Logs/LogLabels.test.tsx | 5 +- .../src/components/Logs/LogLabels.tsx | 5 +- .../components/Logs/LogMessageAnsi.test.tsx | 4 +- .../src/components/Logs/LogMessageAnsi.tsx | 4 +- .../grafana-ui/src/components/Logs/LogRow.tsx | 16 +- .../components/Logs/LogRowContext.test.tsx | 6 +- .../src/components/Logs/LogRowContext.tsx | 12 +- .../Logs/LogRowContextProvider.test.tsx | 8 +- .../components/Logs/LogRowContextProvider.tsx | 5 +- .../src/components/Logs/LogRowMessage.tsx | 20 +- .../Logs/LogRowMessageDetectedFields.tsx | 5 +- .../src/components/Logs/LogRows.test.tsx | 8 +- .../src/components/Logs/LogRows.tsx | 7 +- .../src/components/Logs/getLogRowStyles.ts | 2 + .../src/components/Logs/logParser.ts | 3 +- .../FieldNameByRegexMatcherEditor.tsx | 5 +- .../MatchersUI/FieldNameMatcherEditor.tsx | 5 +- .../components/MatchersUI/FieldNamePicker.tsx | 3 + .../MatchersUI/FieldNamesMatcherEditor.tsx | 7 +- .../MatchersUI/FieldTypeMatcherEditor.tsx | 5 +- .../MatchersUI/FieldsByFrameRefIdMatcher.tsx | 5 +- .../components/MatchersUI/fieldMatchersUI.ts | 7 +- .../src/components/MatchersUI/types.ts | 1 + .../src/components/MatchersUI/utils.ts | 2 + .../components/Menu/Menu.story.internal.tsx | 10 +- .../src/components/Menu/Menu.test.tsx | 4 +- .../grafana-ui/src/components/Menu/Menu.tsx | 5 +- .../src/components/Menu/MenuGroup.tsx | 11 +- .../src/components/Menu/MenuItem.test.tsx | 6 +- .../src/components/Menu/MenuItem.tsx | 11 +- .../src/components/Menu/SubMenu.test.tsx | 4 +- .../src/components/Menu/SubMenu.tsx | 7 +- .../src/components/Menu/hooks.test.tsx | 5 +- .../grafana-ui/src/components/Menu/hooks.ts | 1 + .../src/components/Modal/Modal.story.tsx | 14 +- .../src/components/Modal/Modal.test.tsx | 5 +- .../grafana-ui/src/components/Modal/Modal.tsx | 6 +- .../src/components/Modal/ModalHeader.tsx | 6 +- .../src/components/Modal/ModalTabContent.tsx | 1 + .../src/components/Modal/ModalTabsHeader.tsx | 5 +- .../src/components/Modal/getModalStyles.ts | 2 + .../Monaco/CodeEditor.story.internal.tsx | 8 +- .../src/components/Monaco/CodeEditor.tsx | 9 +- .../components/Monaco/ReactMonacoEditor.tsx | 6 +- .../Monaco/ReactMonacoEditorLazy.tsx | 4 +- .../grafana-ui/src/components/Monaco/theme.ts | 1 + .../grafana-ui/src/components/Monaco/types.ts | 2 +- .../grafana-ui/src/components/Monaco/utils.ts | 1 + .../src/components/OptionsUI/color.tsx | 10 +- .../src/components/OptionsUI/fieldColor.tsx | 9 +- .../src/components/OptionsUI/links.tsx | 2 + .../src/components/OptionsUI/multiSelect.tsx | 2 + .../src/components/OptionsUI/number.tsx | 2 + .../src/components/OptionsUI/select.tsx | 2 + .../src/components/OptionsUI/slider.tsx | 2 + .../src/components/OptionsUI/stats.tsx | 2 + .../src/components/OptionsUI/string.tsx | 2 + .../src/components/OptionsUI/strings.tsx | 12 +- .../src/components/OptionsUI/units.tsx | 1 + .../PageLayout/PageToolbar.story.tsx | 13 +- .../src/components/PageLayout/PageToolbar.tsx | 12 +- .../Pagination/Pagination.story.tsx | 9 +- .../components/Pagination/Pagination.test.tsx | 3 +- .../src/components/Pagination/Pagination.tsx | 3 +- .../components/PanelChrome/ErrorIndicator.tsx | 8 +- .../PanelChrome/LoadingIndicator.tsx | 6 +- .../PanelChrome/PanelChrome.story.tsx | 12 +- .../components/PanelChrome/PanelChrome.tsx | 6 +- .../components/PanelChrome/PanelContext.ts | 4 +- .../src/components/PanelChrome/index.ts | 3 +- .../PluginSignatureBadge.story.tsx | 8 +- .../PluginSignatureBadge.tsx | 2 + .../src/components/Portal/Portal.tsx | 1 + .../QueryField/QueryField.story.tsx | 4 +- .../components/QueryField/QueryField.test.tsx | 6 +- .../src/components/QueryField/QueryField.tsx | 29 +- .../RefreshPicker/RefreshPicker.story.tsx | 10 +- .../RefreshPicker/RefreshPicker.tsx | 8 +- .../SecretFormField.story.internal.tsx | 7 +- .../SecretFormField/SecretFormField.tsx | 5 +- .../SecretInput/SecretInput.story.tsx | 6 +- .../SecretInput/SecretInput.test.tsx | 3 +- .../components/SecretInput/SecretInput.tsx | 3 +- .../src/components/Segment/Segment.story.tsx | 3 +- .../src/components/Segment/Segment.tsx | 12 +- .../components/Segment/SegmentAsync.story.tsx | 3 +- .../src/components/Segment/SegmentAsync.tsx | 16 +- .../components/Segment/SegmentInput.story.tsx | 3 +- .../src/components/Segment/SegmentInput.tsx | 13 +- .../src/components/Segment/SegmentSection.tsx | 6 +- .../src/components/Segment/SegmentSelect.tsx | 4 +- .../src/components/Segment/styles.ts | 3 +- .../src/components/Select/Container.tsx | 12 +- .../components/Select/DropdownIndicator.tsx | 1 + .../components/Select/IndicatorsContainer.tsx | 3 +- .../src/components/Select/InputControl.tsx | 8 +- .../src/components/Select/MultiValue.tsx | 1 + .../src/components/Select/Select.story.tsx | 21 +- .../src/components/Select/Select.tsx | 4 +- .../src/components/Select/SelectBase.test.tsx | 6 +- .../src/components/Select/SelectBase.tsx | 21 +- .../src/components/Select/SelectContainer.tsx | 12 +- .../src/components/Select/SelectMenu.tsx | 11 +- .../components/Select/SelectOptionGroup.tsx | 6 +- .../src/components/Select/SingleValue.tsx | 16 +- .../src/components/Select/ValueContainer.tsx | 5 +- .../src/components/Select/getSelectStyles.ts | 4 +- .../src/components/Select/mockOptions.tsx | 3 +- .../components/Select/resetSelectStyles.ts | 3 +- .../grafana-ui/src/components/Select/types.ts | 3 +- .../src/components/Select/utils.test.ts | 5 +- .../grafana-ui/src/components/Select/utils.ts | 1 + .../components/SetInterval/SetInterval.tsx | 3 +- .../SingleStatBaseOptions.test.ts | 3 +- .../SingleStatShared/SingleStatBaseOptions.ts | 2 +- .../components/Slider/RangeSlider.story.tsx | 8 +- .../components/Slider/RangeSlider.test.tsx | 3 +- .../src/components/Slider/RangeSlider.tsx | 6 +- .../src/components/Slider/Slider.story.tsx | 11 +- .../src/components/Slider/Slider.test.tsx | 3 +- .../src/components/Slider/Slider.tsx | 9 +- .../src/components/Slider/styles.ts | 8 +- .../grafana-ui/src/components/Slider/types.ts | 1 + .../src/components/Sparkline/Sparkline.tsx | 9 +- .../src/components/Sparkline/utils.ts | 1 + .../src/components/Spinner/Spinner.story.tsx | 7 +- .../src/components/Spinner/Spinner.tsx | 3 +- .../StatsPicker/StatsPicker.story.tsx | 8 +- .../components/StatsPicker/StatsPicker.tsx | 5 +- .../src/components/Switch/Switch.story.tsx | 11 +- .../src/components/Switch/Switch.tsx | 4 +- .../TabbedContainer/TabbedContainer.tsx | 5 +- .../src/components/Table/BarGaugeCell.tsx | 13 +- .../src/components/Table/CellActions.tsx | 2 + .../src/components/Table/DefaultCell.tsx | 8 +- .../src/components/Table/Filter.tsx | 8 +- .../src/components/Table/FilterList.tsx | 5 +- .../src/components/Table/FilterPopup.tsx | 10 +- .../src/components/Table/FooterCell.tsx | 8 +- .../src/components/Table/FooterRow.tsx | 7 +- .../src/components/Table/GeoCell.tsx | 7 +- .../src/components/Table/HeaderRow.tsx | 9 +- .../src/components/Table/ImageCell.tsx | 2 + .../src/components/Table/JSONViewCell.tsx | 8 +- .../src/components/Table/Table.story.tsx | 15 +- .../src/components/Table/Table.test.tsx | 4 +- .../grafana-ui/src/components/Table/Table.tsx | 21 +- .../src/components/Table/TableCell.tsx | 3 +- .../Table/TableCellInspectModal.tsx | 1 + .../grafana-ui/src/components/Table/styles.ts | 2 + .../grafana-ui/src/components/Table/types.ts | 10 +- .../src/components/Table/utils.test.ts | 1 + .../grafana-ui/src/components/Table/utils.ts | 13 +- .../TableInputCSV.story.internal.tsx | 8 +- .../TableInputCSV/TableInputCSV.test.tsx | 5 +- .../TableInputCSV/TableInputCSV.tsx | 12 +- .../src/components/Tabs/Counter.tsx | 6 +- .../grafana-ui/src/components/Tabs/Tab.tsx | 10 +- .../src/components/Tabs/TabContent.tsx | 6 +- .../src/components/Tabs/Tabs.story.tsx | 11 +- .../src/components/Tabs/TabsBar.tsx | 8 +- .../src/components/Tags/Tag.story.tsx | 5 +- .../grafana-ui/src/components/Tags/Tag.tsx | 6 +- .../src/components/Tags/TagList.story.tsx | 6 +- .../src/components/Tags/TagList.tsx | 9 +- .../src/components/TagsInput/TagItem.tsx | 8 +- .../components/TagsInput/TagsInput.story.tsx | 8 +- .../components/TagsInput/TagsInput.test.tsx | 3 +- .../src/components/TagsInput/TagsInput.tsx | 11 +- .../components/TextArea/TextArea.story.tsx | 9 +- .../src/components/TextArea/TextArea.tsx | 6 +- .../components/ThemeDemos/EmotionPerfTest.tsx | 8 +- .../components/ThemeDemos/ThemeDemo.story.tsx | 1 + .../src/components/ThemeDemos/ThemeDemo.tsx | 20 +- .../src/components/TimeSeries/TimeSeries.tsx | 15 +- .../src/components/TimeSeries/utils.ts | 9 +- .../src/components/Tooltip/Popover.tsx | 8 +- .../components/Tooltip/PopoverController.tsx | 3 +- .../src/components/Tooltip/Tooltip.story.tsx | 6 +- .../src/components/Tooltip/Tooltip.test.tsx | 5 +- .../src/components/Tooltip/Tooltip.tsx | 7 +- .../Typeahead/PartialHighlighter.test.tsx | 3 +- .../Typeahead/PartialHighlighter.tsx | 1 + .../components/Typeahead/Typeahead.test.tsx | 5 +- .../src/components/Typeahead/Typeahead.tsx | 9 +- .../Typeahead/TypeaheadInfo.test.tsx | 6 +- .../components/Typeahead/TypeaheadInfo.tsx | 3 +- .../components/Typeahead/TypeaheadItem.tsx | 10 +- .../Typography/Typography.story.tsx | 2 + .../UnitPicker/UnitPicker.story.tsx | 4 +- .../src/components/UnitPicker/UnitPicker.tsx | 4 +- .../ValuePicker/ValuePicker.story.tsx | 11 +- .../components/ValuePicker/ValuePicker.tsx | 10 +- .../components/VizLayout/VizLayout.story.tsx | 6 +- .../src/components/VizLayout/VizLayout.tsx | 10 +- .../components/VizLegend/SeriesIcon.test.tsx | 3 +- .../src/components/VizLegend/SeriesIcon.tsx | 4 +- .../components/VizLegend/VizLegend.story.tsx | 12 +- .../src/components/VizLegend/VizLegend.tsx | 11 +- .../components/VizLegend/VizLegendList.tsx | 11 +- .../VizLegend/VizLegendListItem.tsx | 13 +- .../VizLegend/VizLegendSeriesIcon.tsx | 2 + .../VizLegend/VizLegendStatsList.tsx | 8 +- .../components/VizLegend/VizLegendTable.tsx | 13 +- .../VizLegend/VizLegendTableItem.tsx | 11 +- .../components/VizRepeater/VizRepeater.tsx | 2 + .../VizTooltip/SeriesTable.story.tsx | 3 +- .../src/components/VizTooltip/SeriesTable.tsx | 8 +- .../src/components/VizTooltip/VizTooltip.tsx | 13 +- .../VizTooltip/VizTooltipContainer.tsx | 9 +- packages/grafana-ui/src/components/index.ts | 21 +- .../components/transitions/FadeTransition.tsx | 3 +- .../transitions/SlideOutTransition.tsx | 3 +- .../src/components/uPlot/Plot.test.tsx | 12 +- .../grafana-ui/src/components/uPlot/Plot.tsx | 3 +- .../src/components/uPlot/PlotLegend.tsx | 9 +- .../uPlot/config/UPlotAxisBuilder.ts | 9 +- .../uPlot/config/UPlotConfigBuilder.test.ts | 5 +- .../uPlot/config/UPlotConfigBuilder.ts | 11 +- .../uPlot/config/UPlotScaleBuilder.ts | 6 +- .../uPlot/config/UPlotSeriesBuilder.ts | 5 +- .../uPlot/config/UPlotThresholds.ts | 8 +- .../components/uPlot/config/gradientFills.ts | 6 +- .../uPlot/geometries/EventsCanvas.tsx | 7 +- .../components/uPlot/geometries/XYCanvas.tsx | 2 +- .../src/components/uPlot/geometries/index.ts | 4 +- .../uPlot/plugins/KeyboardPlugin.tsx | 3 +- .../uPlot/plugins/TooltipPlugin.tsx | 2 + .../components/uPlot/plugins/ZoomPlugin.tsx | 3 +- .../grafana-ui/src/components/uPlot/types.ts | 2 + .../src/components/uPlot/utils.test.ts | 6 +- .../grafana-ui/src/components/uPlot/utils.ts | 4 +- .../grafana-ui/src/options/builder/axis.tsx | 4 +- .../src/options/builder/hideSeries.tsx | 6 +- .../src/options/builder/stacking.tsx | 6 +- .../grafana-ui/src/options/builder/text.tsx | 2 +- .../src/options/builder/tooltip.tsx | 2 +- .../src/slate-plugins/braces.test.tsx | 4 +- .../grafana-ui/src/slate-plugins/braces.ts | 3 +- .../src/slate-plugins/clear.test.tsx | 8 +- .../grafana-ui/src/slate-plugins/clear.ts | 3 +- .../grafana-ui/src/slate-plugins/clipboard.ts | 3 +- .../src/slate-plugins/indentation.ts | 5 +- .../grafana-ui/src/slate-plugins/newline.ts | 3 +- .../src/slate-plugins/runner.test.tsx | 8 +- .../grafana-ui/src/slate-plugins/runner.ts | 3 +- .../src/slate-plugins/selection_shortcuts.ts | 4 +- .../src/slate-plugins/slate-prism/index.ts | 4 +- .../src/slate-plugins/slate-prism/options.tsx | 3 +- .../src/slate-plugins/suggestions.test.tsx | 12 +- .../src/slate-plugins/suggestions.tsx | 7 +- .../src/themes/GlobalStyles/GlobalStyles.tsx | 10 +- .../themes/GlobalStyles/angularPanelStyles.ts | 1 + .../src/themes/GlobalStyles/card.ts | 1 + .../src/themes/GlobalStyles/elements.ts | 2 + .../src/themes/GlobalStyles/markdownStyles.ts | 1 + .../src/themes/GlobalStyles/page.ts | 1 + .../src/themes/ThemeContext.test.tsx | 7 +- .../grafana-ui/src/themes/ThemeContext.tsx | 5 +- .../src/themes/_variables.dark.scss.tmpl.ts | 1 + .../src/themes/_variables.light.scss.tmpl.ts | 6 +- .../src/themes/_variables.scss.tmpl.ts | 1 + packages/grafana-ui/src/themes/mixins.ts | 3 +- .../src/themes/selectThemeVariant.test.ts | 2 + packages/grafana-ui/src/types/completion.ts | 1 + packages/grafana-ui/src/types/icon.ts | 1 + packages/grafana-ui/src/utils/dataLinks.ts | 1 + packages/grafana-ui/src/utils/fuzzy.ts | 3 +- packages/grafana-ui/src/utils/index.ts | 6 +- .../grafana-ui/src/utils/searchFunctions.ts | 1 + .../grafana-ui/src/utils/standardEditors.tsx | 9 +- .../utils/storybook/DashboardStoryCanvas.tsx | 3 +- .../src/utils/storybook/StoryExample.tsx | 3 +- .../utils/storybook/ThemedDocsContainer.tsx | 3 +- .../src/utils/storybook/UseState.tsx | 2 +- .../grafana-ui/src/utils/storybook/knobs.ts | 1 + .../src/utils/storybook/withCenteredStory.tsx | 1 + .../src/utils/storybook/withPaddedStory.tsx | 1 + .../utils/storybook/withRightAlignedStory.tsx | 1 + .../utils/storybook/withStoryContainer.tsx | 5 +- .../src/utils/storybook/withTheme.tsx | 8 +- packages/grafana-ui/src/utils/table.ts | 3 +- packages/grafana-ui/src/utils/typeahead.ts | 4 +- .../utils/useDelayedSwitch.story.internal.tsx | 2 +- .../src/ScrollManager.test.js | 2 +- packages/jaeger-ui-components/src/Theme.tsx | 1 + .../SpanGraph/CanvasSpanGraph.test.js | 3 +- .../SpanGraph/CanvasSpanGraph.tsx | 13 +- .../SpanGraph/GraphTicks.test.js | 2 +- .../TracePageHeader/SpanGraph/GraphTicks.tsx | 3 +- .../SpanGraph/Scrubber.test.js | 2 +- .../TracePageHeader/SpanGraph/Scrubber.tsx | 5 +- .../SpanGraph/TickLabels.test.js | 2 +- .../TracePageHeader/SpanGraph/TickLabels.tsx | 3 +- .../SpanGraph/ViewingLayer.test.js | 6 +- .../SpanGraph/ViewingLayer.tsx | 8 +- .../TracePageHeader/SpanGraph/index.test.js | 12 +- .../src/TracePageHeader/SpanGraph/index.tsx | 9 +- .../TracePageHeader/TracePageHeader.test.js | 7 +- .../src/TracePageHeader/TracePageHeader.tsx | 17 +- .../TracePageSearchBar.test.js | 8 +- .../TracePageHeader/TracePageSearchBar.tsx | 13 +- .../ListView/index.test.js | 5 +- .../TraceTimelineViewer/ListView/index.tsx | 3 +- .../ReferencesButton.test.js | 8 +- .../TraceTimelineViewer/ReferencesButton.tsx | 3 +- .../src/TraceTimelineViewer/SpanBar.test.js | 3 +- .../src/TraceTimelineViewer/SpanBar.tsx | 9 +- .../TraceTimelineViewer/SpanBarRow.test.js | 4 +- .../src/TraceTimelineViewer/SpanBarRow.tsx | 24 +- .../SpanDetail/AccordianKeyValues.test.js | 2 +- .../SpanDetail/AccordianKeyValues.tsx | 18 +- .../SpanDetail/AccordianLogs.test.js | 2 +- .../SpanDetail/AccordianLogs.tsx | 12 +- .../SpanDetail/AccordianReferences.test.js | 6 +- .../SpanDetail/AccordianReferences.tsx | 16 +- .../SpanDetail/AccordianText.test.js | 3 +- .../SpanDetail/AccordianText.tsx | 14 +- .../SpanDetail/KeyValuesTable.test.js | 4 +- .../SpanDetail/KeyValuesTable.tsx | 11 +- .../SpanDetail/TextList.test.js | 3 +- .../SpanDetail/TextList.tsx | 3 +- .../SpanDetail/index.test.js | 12 +- .../TraceTimelineViewer/SpanDetail/index.tsx | 24 +- .../TraceTimelineViewer/SpanDetailRow.test.js | 5 +- .../src/TraceTimelineViewer/SpanDetailRow.tsx | 15 +- .../SpanTreeOffset.test.js | 4 +- .../TraceTimelineViewer/SpanTreeOffset.tsx | 11 +- .../src/TraceTimelineViewer/Ticks.test.js | 2 +- .../src/TraceTimelineViewer/Ticks.tsx | 10 +- .../TimelineCollapser.test.js | 2 +- .../TimelineHeaderRow/TimelineCollapser.tsx | 3 +- .../TimelineColumnResizer.test.js | 4 +- .../TimelineColumnResizer.tsx | 3 +- .../TimelineHeaderRow.test.js | 9 +- .../TimelineHeaderRow/TimelineHeaderRow.tsx | 16 +- .../TimelineViewingLayer.test.js | 4 +- .../TimelineViewingLayer.tsx | 6 +- .../src/TraceTimelineViewer/TimelineRow.tsx | 4 +- .../VirtualizedTraceView.test.js | 9 +- .../VirtualizedTraceView.tsx | 21 +- .../src/TraceTimelineViewer/index.test.js | 7 +- .../src/TraceTimelineViewer/index.tsx | 18 +- .../src/TraceTimelineViewer/utils.test.js | 4 +- .../src/common/BreakableText.tsx | 3 +- .../src/common/CopyIcon.test.js | 6 +- .../src/common/CopyIcon.tsx | 3 +- .../src/common/Divider.tsx | 6 +- .../src/common/ExternalLinks.tsx | 1 + .../src/common/LabeledList.tsx | 6 +- .../src/common/NewWindowIcon.test.js | 2 +- .../src/common/NewWindowIcon.tsx | 7 +- .../src/common/Popover.tsx | 1 + .../src/common/TraceName.tsx | 8 +- .../src/common/UiFindInput.test.js | 3 +- .../src/common/UiFindInput.tsx | 3 +- .../src/keyboard-shortcuts.tsx | 2 +- .../src/model/link-patterns.tsx | 6 +- .../src/model/transform-trace-data.tsx | 3 +- .../src/scroll-page.test.js | 2 +- .../src/selectors/process.test.js | 3 +- .../src/selectors/span.js | 2 +- .../src/selectors/span.test.js | 3 +- .../src/selectors/trace.js | 9 +- .../src/selectors/trace.test.js | 7 +- .../src/types/TDdgState.tsx | 3 +- .../src/types/TTraceTimeline.tsx | 1 + .../jaeger-ui-components/src/types/links.ts | 3 +- .../src/url/ReferenceLink.test.js | 2 +- .../src/url/ReferenceLink.tsx | 2 + .../DraggableManager/DraggableManager.tsx | 3 +- .../DraggableManager/demo/DividerDemo.tsx | 2 +- .../demo/DraggableManagerDemo.tsx | 3 +- .../src/utils/DraggableManager/types.tsx | 3 +- .../src/utils/color-generator.test.js | 3 +- .../src/utils/color-generator.tsx | 1 + .../jaeger-ui-components/src/utils/date.tsx | 2 +- .../src/utils/filter-spans.tsx | 2 +- .../src/InputConfigEditor.tsx | 6 +- .../src/InputDatasource.test.ts | 4 +- .../input-datasource/src/InputQueryEditor.tsx | 7 +- .../internal/input-datasource/src/module.ts | 5 +- public/app/AppWrapper.tsx | 40 +- public/app/angular/AngularApp.ts | 24 +- .../angular/AngularLocationWrapper.test.ts | 3 +- public/app/angular/AngularLocationWrapper.ts | 2 +- public/app/angular/GrafanaCtrl.ts | 30 +- public/app/angular/angular_wrappers.ts | 25 +- public/app/angular/array_join.ts | 1 + .../app/angular/bridgeReactAngularRouting.ts | 8 +- .../components/form_dropdown/form_dropdown.ts | 5 +- public/app/angular/components/info_popover.ts | 3 +- public/app/angular/components/jsontree.ts | 2 +- .../angular/components/plugin_component.ts | 8 +- .../angular/components/query_part_editor.ts | 4 +- public/app/angular/components/scroll.ts | 3 +- .../components/sql_part/sql_part_editor.ts | 3 +- public/app/angular/diff-view.ts | 4 +- public/app/angular/dropdown_typeahead.ts | 3 +- public/app/angular/filters/filters.ts | 8 +- public/app/angular/jquery_extended.ts | 2 +- public/app/angular/metric_segment.ts | 6 +- public/app/angular/misc.ts | 1 + public/app/angular/ng_model_on_blur.ts | 3 +- .../app/angular/panel/metrics_panel_ctrl.ts | 10 +- public/app/angular/panel/panel_ctrl.ts | 10 +- public/app/angular/panel/panel_directive.ts | 13 +- public/app/angular/panel/query_ctrl.ts | 2 +- .../panel/specs/metrics_panel_ctrl.test.ts | 1 + public/app/angular/promiseToDigest.test.ts | 1 + public/app/angular/rebuild_on_change.ts | 1 + public/app/angular/registerComponents.ts | 3 +- public/app/angular/services/AngularLoader.ts | 2 +- public/app/angular/services/UtilSrv.ts | 5 +- .../app/angular/services/annotations_srv.ts | 2 +- .../angular/services/dynamic_directive_srv.ts | 1 + public/app/angular/services/nav_model_srv.ts | 2 +- public/app/angular/services/ng_react.ts | 2 +- public/app/angular/services/popover_srv.ts | 3 +- public/app/angular/services/segment_srv.ts | 1 + public/app/angular/services/timer.ts | 5 +- public/app/angular/tags.ts | 4 +- public/app/app.ts | 72 +-- .../AccessControl/AddPermission.tsx | 8 +- .../AccessControl/PermissionList.tsx | 3 +- .../AccessControl/PermissionListItem.tsx | 4 +- .../components/AccessControl/Permissions.tsx | 5 +- .../AppNotifications/AppNotificationItem.tsx | 5 +- .../AppNotifications/AppNotificationList.tsx | 12 +- .../StoredNotificationItem.tsx | 7 +- .../app/core/components/Branding/Branding.tsx | 5 +- public/app/core/components/CardButton.tsx | 3 +- .../components/CloseButton/CloseButton.tsx | 5 +- .../core/components/ColorScale/ColorScale.tsx | 3 +- .../DynamicImports/ErrorLoadingChunk.tsx | 5 +- .../LoadingChunkPlaceHolder.tsx | 1 + .../DynamicImports/SafeDynamicImport.test.tsx | 3 +- .../DynamicImports/SafeDynamicImport.tsx | 6 +- .../components/EmptyListCTA/EmptyListCTA.tsx | 3 +- .../core/components/ErrorPage/ErrorPage.tsx | 4 +- .../components/FolderFilter/FolderFilter.tsx | 8 +- public/app/core/components/Footer/Footer.tsx | 1 + .../ForgottenPassword/ChangePassword.tsx | 4 +- .../ChangePasswordPage.test.tsx | 3 +- .../ForgottenPassword/ChangePasswordPage.tsx | 9 +- .../ForgottenPassword/ForgottenPassword.tsx | 7 +- .../SendResetMailPage.test.tsx | 2 +- .../ForgottenPassword/SendResetMailPage.tsx | 1 + .../core/components/Layers/AddLayerButton.tsx | 2 +- .../components/Layers/LayerDragDropList.tsx | 5 +- .../core/components/Layers/LayerName.test.tsx | 3 +- .../app/core/components/Layers/LayerName.tsx | 5 +- .../LocalStorageValueProvider.tsx | 1 + .../app/core/components/Login/LoginCtrl.tsx | 5 +- .../app/core/components/Login/LoginForm.tsx | 8 +- .../app/core/components/Login/LoginLayout.tsx | 8 +- .../core/components/Login/LoginPage.test.tsx | 5 +- .../app/core/components/Login/LoginPage.tsx | 16 +- .../components/Login/LoginServiceButtons.tsx | 9 +- .../app/core/components/Login/UserSignup.tsx | 5 +- .../core/components/NavBar/NavBar.test.tsx | 5 +- public/app/core/components/NavBar/NavBar.tsx | 15 +- .../components/NavBar/NavBarItem.test.tsx | 4 +- .../app/core/components/NavBar/NavBarItem.tsx | 23 +- .../core/components/NavBar/NavBarItemMenu.tsx | 15 +- .../components/NavBar/NavBarItemMenuItem.tsx | 11 +- .../NavBar/NavBarItemMenuTrigger.tsx | 21 +- .../NavBar/NavBarItemWithoutMenu.tsx | 4 +- .../components/NavBar/NavBarMenu.test.tsx | 6 +- .../app/core/components/NavBar/NavBarMenu.tsx | 10 +- .../components/NavBar/NavBarMenuItem.test.tsx | 3 +- .../core/components/NavBar/NavBarMenuItem.tsx | 3 +- .../core/components/NavBar/NavBarSection.tsx | 3 +- .../components/NavBar/NavFeatureHighlight.tsx | 5 +- .../components/NavBar/Next/NavBarItem.tsx | 26 +- .../components/NavBar/Next/NavBarItemMenu.tsx | 15 +- .../NavBar/Next/NavBarItemMenuTrigger.tsx | 22 +- .../NavBar/Next/NavBarItemWithoutMenu.tsx | 4 +- .../components/NavBar/Next/NavBarMenu.tsx | 19 +- .../components/NavBar/Next/NavBarMenuItem.tsx | 3 +- .../NavBar/Next/NavBarMenuPortalContainer.tsx | 3 +- .../NavBar/Next/NavBarNext.test.tsx | 5 +- .../components/NavBar/Next/NavBarNext.tsx | 39 +- .../components/NavBar/Next/NavBarToggle.tsx | 7 +- .../NavBar/navBarItem-translations.ts | 2 +- .../app/core/components/NavBar/utils.test.ts | 3 + public/app/core/components/NavBar/utils.ts | 2 + .../app/core/components/NodeGraphSettings.tsx | 3 +- public/app/core/components/OrgSwitcher.tsx | 9 +- public/app/core/components/Page/Page.tsx | 14 +- .../app/core/components/Page/PageContents.tsx | 2 +- .../PageActionBar/PageActionBar.test.tsx | 3 +- .../PageActionBar/PageActionBar.tsx | 1 + .../components/PageHeader/PageHeader.test.tsx | 5 +- .../core/components/PageHeader/PageHeader.tsx | 6 +- .../core/components/PageLoader/PageLoader.tsx | 1 + .../PanelTypeFilter/PanelTypeFilter.tsx | 9 +- .../PasswordField/PasswordField.test.tsx | 3 +- .../PasswordField/PasswordField.tsx | 2 +- .../PermissionList/AddPermission.tsx | 12 +- .../DisabledPermissionListItem.tsx | 1 + .../PermissionList/PermissionList.tsx | 6 +- .../PermissionList/PermissionListItem.tsx | 5 +- .../core/components/PluginHelp/PluginHelp.tsx | 1 + .../QueryOperationRow/OperationRowHelp.tsx | 3 +- .../QueryOperationAction.test.tsx | 5 +- .../QueryOperationAction.tsx | 5 +- .../QueryOperationRow.test.tsx | 5 +- .../QueryOperationRow/QueryOperationRow.tsx | 9 +- .../core/components/RolePicker/RolePicker.tsx | 6 +- .../components/RolePicker/RolePickerInput.tsx | 9 +- .../components/RolePicker/RolePickerMenu.tsx | 5 +- .../components/RolePicker/TeamRolePicker.tsx | 2 + .../components/RolePicker/UserRolePicker.tsx | 2 + .../components/RolePicker/ValueContainer.tsx | 5 +- .../components/Select/DashboardPicker.tsx | 7 +- .../components/Select/FolderPicker.test.tsx | 8 +- .../core/components/Select/FolderPicker.tsx | 9 +- .../components/Select/MetricSelect.test.tsx | 7 +- .../core/components/Select/MetricSelect.tsx | 4 +- .../app/core/components/Select/OrgPicker.tsx | 5 +- .../ReadonlyFolderPicker.test.tsx | 12 +- .../ReadonlyFolderPicker.tsx | 6 +- .../Select/ReadonlyFolderPicker/api.test.ts | 5 +- .../Select/ReadonlyFolderPicker/api.ts | 3 +- .../app/core/components/Select/SortPicker.tsx | 4 +- .../components/Select/TeamPicker.test.tsx | 3 +- .../app/core/components/Select/TeamPicker.tsx | 5 +- .../components/Select/UserPicker.test.tsx | 3 +- .../app/core/components/Select/UserPicker.tsx | 14 +- .../SharedPreferences/SharedPreferences.tsx | 13 +- .../components/Signup/SignupPage.test.tsx | 3 +- .../app/core/components/Signup/SignupPage.tsx | 6 +- .../core/components/Signup/VerifyEmail.tsx | 3 +- .../Signup/VerifyEmailPage.test.tsx | 4 +- .../components/Signup/VerifyEmailPage.tsx | 1 + .../SplitPaneWrapper/SplitPaneWrapper.tsx | 3 +- .../core/components/TagFilter/TagBadge.tsx | 1 + .../core/components/TagFilter/TagFilter.tsx | 9 +- .../core/components/TagFilter/TagOption.tsx | 9 +- .../core/components/TagFilter/TagValue.tsx | 1 + .../TimePicker/TimePickerWithHistory.tsx | 4 +- .../components/TraceToLogs/KeyValueInput.tsx | 3 +- .../TraceToLogs/TraceToLogsSettings.tsx | 4 +- .../app/core/components/Upgrade/ProBadge.tsx | 5 +- .../core/components/Upgrade/UpgradeBox.tsx | 5 +- .../core/components/connectWithCleanUp.tsx | 7 +- .../components/editors/DashboardPicker.tsx | 1 + .../editors/DashboardPickerByID.tsx | 5 +- .../app/core/components/editors/registry.tsx | 7 +- public/app/core/components/help/HelpModal.tsx | 3 +- .../components/modals/AngularModalProxy.tsx | 6 +- public/app/core/config.ts | 2 +- public/app/core/copy/appNotification.ts | 6 +- public/app/core/core.ts | 5 +- .../history/RichHistoryLocalStorage.test.ts | 10 +- .../core/history/RichHistoryLocalStorage.ts | 13 +- .../history/localStorageConverter.test.ts | 5 +- .../app/core/history/localStorageConverter.ts | 5 +- .../history/richHistoryLocalStorageUtils.ts | 3 +- public/app/core/hooks/useCleanup.ts | 1 + public/app/core/hooks/useNavModel.ts | 6 +- public/app/core/hooks/useQueryParams.ts | 5 +- public/app/core/localisation.tsx | 2 +- public/app/core/logs_model.test.ts | 7 +- public/app/core/logs_model.ts | 8 +- .../app/core/navigation/GrafanaRoute.test.tsx | 7 +- public/app/core/navigation/GrafanaRoute.tsx | 5 +- public/app/core/navigation/RouterDebugger.tsx | 2 + .../core/navigation/__mocks__/routeProps.ts | 3 +- public/app/core/navigation/hooks.ts | 3 +- public/app/core/navigation/kiosk.ts | 3 +- public/app/core/navigation/testRoutes.tsx | 1 + public/app/core/navigation/types.ts | 3 +- .../app/core/reducers/appNotification.test.ts | 3 +- public/app/core/reducers/appNotification.ts | 3 +- public/app/core/reducers/index.ts | 4 +- public/app/core/reducers/navBarTree.ts | 1 + public/app/core/reducers/navModel.test.ts | 6 +- public/app/core/reducers/navModel.ts | 2 +- public/app/core/reducers/root.test.ts | 11 +- public/app/core/reducers/root.ts | 30 +- public/app/core/services/FetchQueue.test.ts | 1 + .../core/services/FetchQueueWorker.test.ts | 10 +- public/app/core/services/FetchQueueWorker.ts | 4 +- public/app/core/services/ModalManager.ts | 11 +- .../app/core/services/PreferencesService.ts | 1 + .../app/core/services/ResponseQueue.test.ts | 8 +- public/app/core/services/ResponseQueue.ts | 2 + .../core/services/__mocks__/backend_srv.ts | 4 +- public/app/core/services/backend_srv.ts | 16 +- public/app/core/services/context_srv.ts | 6 +- public/app/core/services/echo/Echo.ts | 2 + public/app/core/services/echo/EchoSrv.ts | 4 +- .../echo/backends/PerformanceBackend.ts | 1 + .../analytics/ApplicationInsightsBackend.ts | 1 + .../echo/backends/analytics/GABackend.ts | 1 + .../backends/analytics/RudderstackBackend.ts | 4 +- .../backends/sentry/SentryBackend.test.ts | 15 +- .../echo/backends/sentry/SentryBackend.ts | 8 +- .../CustomEndpointTransport.test.ts | 1 + .../transports/CustomEndpointTransport.ts | 3 +- .../sentry/transports/EchoSrvTransport.ts | 5 +- .../services/echo/backends/sentry/types.ts | 3 +- public/app/core/services/echo/utils.test.ts | 1 + public/app/core/services/echo/utils.ts | 3 +- public/app/core/services/impression_srv.ts | 3 +- public/app/core/services/keybindingSrv.ts | 17 +- public/app/core/services/search_srv.ts | 6 +- public/app/core/services/toggleTheme.ts | 6 +- public/app/core/specs/OrgSwitcher.test.tsx | 8 +- public/app/core/specs/backend_srv.test.ts | 7 +- public/app/core/specs/search_srv.test.ts | 8 +- public/app/core/table_model.ts | 1 + public/app/core/time_series2.ts | 1 + public/app/core/utils/ConfigProvider.tsx | 4 +- .../app/core/utils/connectWithReduxStore.tsx | 1 + public/app/core/utils/explore.test.ts | 12 +- public/app/core/utils/explore.ts | 20 +- public/app/core/utils/fetch.ts | 3 +- public/app/core/utils/kbn.test.ts | 3 +- public/app/core/utils/query.test.ts | 1 + public/app/core/utils/richHistory.test.ts | 10 +- public/app/core/utils/richHistory.ts | 26 +- public/app/core/utils/shortLinks.ts | 6 +- .../app/features/admin/AdminEditOrgPage.tsx | 24 +- .../app/features/admin/AdminListOrgsPage.tsx | 14 +- public/app/features/admin/AdminOrgsTable.tsx | 3 +- public/app/features/admin/AdminSettings.tsx | 8 +- .../app/features/admin/CrawlerStartButton.tsx | 5 +- public/app/features/admin/CrawlerStatus.tsx | 6 +- public/app/features/admin/LicenseChrome.tsx | 5 +- public/app/features/admin/OrgRolePicker.tsx | 1 + .../app/features/admin/ServerStats.test.tsx | 3 +- public/app/features/admin/ServerStats.tsx | 11 +- public/app/features/admin/UpgradePage.tsx | 9 +- public/app/features/admin/UserAdminPage.tsx | 18 +- public/app/features/admin/UserCreatePage.tsx | 10 +- .../app/features/admin/UserLdapSyncInfo.tsx | 3 +- .../app/features/admin/UserListAdminPage.tsx | 9 +- public/app/features/admin/UserOrgs.tsx | 14 +- public/app/features/admin/UserPermissions.tsx | 3 +- public/app/features/admin/UserProfile.tsx | 7 +- public/app/features/admin/UserSessions.tsx | 9 +- .../admin/ldap/LdapConnectionStatus.tsx | 1 + public/app/features/admin/ldap/LdapPage.tsx | 15 +- .../app/features/admin/ldap/LdapSyncInfo.tsx | 1 + .../features/admin/ldap/LdapUserGroups.tsx | 1 + .../app/features/admin/ldap/LdapUserInfo.tsx | 6 +- .../admin/ldap/LdapUserMappingInfo.tsx | 1 + .../admin/ldap/LdapUserPermissions.tsx | 3 +- .../app/features/admin/ldap/LdapUserTeams.tsx | 1 + public/app/features/admin/state/actions.ts | 9 +- .../app/features/admin/state/reducers.test.ts | 4 +- public/app/features/admin/state/reducers.ts | 1 + .../app/features/alerting/AlertHowToModal.tsx | 3 +- .../features/alerting/AlertRuleItem.test.tsx | 3 +- .../app/features/alerting/AlertRuleItem.tsx | 2 + .../features/alerting/AlertRuleList.test.tsx | 17 +- .../app/features/alerting/AlertRuleList.tsx | 19 +- public/app/features/alerting/AlertTab.tsx | 19 +- public/app/features/alerting/AlertTabCtrl.ts | 25 +- .../app/features/alerting/AlertTabIndex.tsx | 1 + .../alerting/EditNotificationChannelPage.tsx | 10 +- .../features/alerting/FeatureTogglePage.tsx | 1 + .../alerting/NewNotificationChannelPage.tsx | 11 +- .../alerting/NotificationsListPage.tsx | 8 +- public/app/features/alerting/StateHistory.tsx | 6 +- .../features/alerting/TestRuleResult.test.tsx | 8 +- .../app/features/alerting/TestRuleResult.tsx | 6 +- .../alerting/components/BasicSettings.tsx | 7 +- .../alerting/components/ChannelSettings.tsx | 7 +- .../components/NotificationChannelForm.tsx | 10 +- .../components/NotificationChannelOptions.tsx | 5 +- .../components/NotificationSettings.tsx | 2 + .../alerting/components/OptionElement.tsx | 2 + .../UnifiedAlertingPromotion.test.tsx | 4 +- .../components/UnifiedAlertingPromotion.tsx | 2 +- .../getAlertingValidationMessage.test.ts | 3 +- public/app/features/alerting/routes.tsx | 8 +- public/app/features/alerting/state/actions.ts | 7 +- .../app/features/alerting/state/alertDef.ts | 1 + .../features/alerting/state/reducers.test.ts | 6 +- .../app/features/alerting/state/reducers.ts | 5 +- .../app/features/alerting/unified/Admin.tsx | 1 + .../alerting/unified/AlertGroups.test.tsx | 10 +- .../features/alerting/unified/AlertGroups.tsx | 19 +- .../unified/AlertsFolderView.test.tsx | 8 +- .../alerting/unified/AlertsFolderView.tsx | 10 +- .../alerting/unified/AmRoutes.test.tsx | 18 +- .../features/alerting/unified/AmRoutes.tsx | 15 +- .../alerting/unified/MuteTimings.test.tsx | 16 +- .../features/alerting/unified/MuteTimings.tsx | 10 +- .../alerting/unified/PanelAlertTab.tsx | 4 +- .../unified/PanelAlertTabContent.test.tsx | 28 +- .../alerting/unified/PanelAlertTabContent.tsx | 12 +- .../alerting/unified/Receivers.test.tsx | 32 +- .../features/alerting/unified/Receivers.tsx | 6 +- .../unified/RedirectToRuleViewer.test.tsx | 9 +- .../alerting/unified/RedirectToRuleViewer.tsx | 12 +- .../alerting/unified/RuleEditor.test.tsx | 31 +- .../features/alerting/unified/RuleEditor.tsx | 8 +- .../alerting/unified/RuleList.test.tsx | 22 +- .../features/alerting/unified/RuleList.tsx | 10 +- .../alerting/unified/RuleViewer.test.tsx | 12 +- .../features/alerting/unified/RuleViewer.tsx | 7 +- .../alerting/unified/Silences.test.tsx | 24 +- .../features/alerting/unified/Silences.tsx | 15 +- .../alerting/unified/api/alertmanager.ts | 6 +- .../alerting/unified/api/annotations.test.ts | 3 +- .../alerting/unified/api/buildInfo.test.ts | 4 +- .../alerting/unified/api/buildInfo.ts | 5 +- .../features/alerting/unified/api/preview.ts | 6 +- .../alerting/unified/api/prometheus.ts | 3 +- .../alerting/unified/api/ruler.test.ts | 2 + .../features/alerting/unified/api/ruler.ts | 10 +- .../unified/components/AlertLabel.tsx | 7 +- .../unified/components/AlertLabels.tsx | 1 + .../unified/components/AlertManagerPicker.tsx | 12 +- .../components/AlertingPageWrapper.tsx | 3 +- .../components/AnnotationDetailsField.tsx | 11 +- .../alerting/unified/components/Authorize.tsx | 3 +- .../components/CollapseToggle.test.tsx | 1 + .../unified/components/CollapseToggle.tsx | 3 +- .../unified/components/DetailsField.tsx | 3 +- .../unified/components/DynamicTable.tsx | 3 +- .../components/DynamicTableWithGuidelines.tsx | 4 +- .../alerting/unified/components/EmptyArea.tsx | 3 +- .../unified/components/EmptyAreaWithCTA.tsx | 4 +- .../unified/components/Expression.tsx | 15 +- .../components/PanelPluginsButtonGroup.tsx | 4 +- .../unified/components/RuleLocation.tsx | 3 +- .../unified/components/StateColoredText.tsx | 5 +- .../alerting/unified/components/StateTag.tsx | 5 +- .../alerting/unified/components/TimeToNow.tsx | 3 +- .../alerting/unified/components/Well.tsx | 5 +- .../components/admin/AddAlertManagerModal.tsx | 3 +- .../admin/AlertmanagerConfig.test.tsx | 37 +- .../components/admin/AlertmanagerConfig.tsx | 12 +- .../admin/ExternalAlertmanagers.tsx | 11 +- .../components/alert-groups/AlertDetails.tsx | 4 +- .../components/alert-groups/AlertGroup.tsx | 9 +- .../alert-groups/AlertGroupAlertsTable.tsx | 15 +- .../alert-groups/AlertGroupFilter.tsx | 15 +- .../alert-groups/AlertGroupHeader.tsx | 10 +- .../alert-groups/AlertStateFilter.tsx | 9 +- .../components/alert-groups/GroupBy.tsx | 7 +- .../components/alert-groups/MatcherFilter.tsx | 7 +- .../components/amroutes/AmRootRoute.tsx | 12 +- .../components/amroutes/AmRootRouteForm.tsx | 5 +- .../components/amroutes/AmRootRouteRead.tsx | 3 + .../amroutes/AmRoutesExpandedForm.tsx | 9 +- .../amroutes/AmRoutesExpandedRead.tsx | 15 +- .../components/amroutes/AmRoutesTable.test.ts | 2 + .../components/amroutes/AmRoutesTable.tsx | 15 +- .../components/amroutes/AmSpecificRouting.tsx | 15 +- .../components/amroutes/MuteTimingForm.tsx | 25 +- .../amroutes/MuteTimingTimeInterval.tsx | 9 +- .../amroutes/MuteTimingTimeRange.tsx | 8 +- .../components/amroutes/MuteTimingsTable.tsx | 18 +- .../unified/components/amroutes/formStyles.ts | 1 + .../unified/components/amroutes/gridStyles.ts | 1 + .../NewRuleFromPanelButton.tsx | 10 +- .../components/receivers/EditReceiverView.tsx | 5 +- .../components/receivers/EditTemplateView.tsx | 4 +- .../components/receivers/GlobalConfigForm.tsx | 23 +- .../components/receivers/NewReceiverView.tsx | 5 +- .../components/receivers/NewTemplateView.tsx | 4 +- .../receivers/ReceiversAndTemplatesView.tsx | 5 +- .../components/receivers/ReceiversSection.tsx | 5 +- .../receivers/ReceiversTable.test.tsx | 17 +- .../components/receivers/ReceiversTable.tsx | 27 +- .../components/receivers/TemplateForm.tsx | 8 +- .../components/receivers/TemplatesTable.tsx | 19 +- .../receivers/form/ChannelOptions.tsx | 9 +- .../receivers/form/ChannelSubForm.tsx | 13 +- .../form/CloudCommonChannelSettings.tsx | 6 +- .../receivers/form/CloudReceiverForm.tsx | 7 +- .../receivers/form/CollapsibleSection.tsx | 4 +- .../form/GrafanaCommonChannelSettings.tsx | 6 +- .../receivers/form/GrafanaReceiverForm.tsx | 7 +- .../receivers/form/ReceiverForm.tsx | 11 +- .../receivers/form/TestContactPointModal.tsx | 14 +- .../form/fields/KeyValueMapInput.tsx | 6 +- .../receivers/form/fields/OptionField.tsx | 16 +- .../form/fields/StringArrayInput.tsx | 6 +- .../form/fields/SubformArrayField.tsx | 11 +- .../receivers/form/fields/SubformField.tsx | 7 +- .../receivers/form/fields/styles.ts | 3 +- .../components/rule-editor/AlertRuleForm.tsx | 36 +- .../rule-editor/AlertTypeStep.test.tsx | 8 +- .../components/rule-editor/AlertTypeStep.tsx | 25 +- .../rule-editor/AnnotationKeyInput.tsx | 7 +- .../rule-editor/AnnotationsField.tsx | 9 +- .../rule-editor/CloudConditionsStep.tsx | 9 +- .../rule-editor/CloudRulesSourcePicker.tsx | 2 + .../components/rule-editor/ConditionField.tsx | 6 +- .../components/rule-editor/DetailsStep.tsx | 8 +- .../rule-editor/ExpressionEditor.tsx | 7 +- .../rule-editor/GrafanaAlertStatePicker.tsx | 3 +- .../GrafanaConditionEvalWarning.tsx | 6 +- .../rule-editor/GrafanaConditionsStep.tsx | 13 +- .../rule-editor/GroupAndNamespaceFields.tsx | 11 +- .../components/rule-editor/LabelsField.tsx | 7 +- .../components/rule-editor/PreviewRule.tsx | 7 +- .../rule-editor/PreviewRuleResult.tsx | 8 +- .../components/rule-editor/QueryEditor.tsx | 21 +- .../components/rule-editor/QueryRows.tsx | 12 +- .../components/rule-editor/QueryStep.tsx | 7 +- .../components/rule-editor/QueryWrapper.tsx | 11 +- .../rule-editor/RuleEditorSection.tsx | 3 +- .../rule-editor/RuleFolderPicker.tsx | 1 + .../components/rule-editor/RuleInspector.tsx | 6 +- .../components/rule-editor/SelectWIthAdd.tsx | 3 +- .../components/rule-editor/VizWrapper.tsx | 8 +- .../rule-types/DisabledTooltip.tsx | 1 + .../rule-types/GrafanaManagedAlert.tsx | 4 +- .../rule-types/MimirOrLokiAlert.tsx | 6 +- .../rule-types/MimirOrLokiRecordingRule.tsx | 6 +- .../rule-editor/rule-types/RuleType.tsx | 4 +- .../rule-editor/rule-types/RuleTypePicker.tsx | 7 +- .../components/rule-editor/util.test.ts | 3 +- .../unified/components/rule-editor/util.ts | 3 +- .../rule-viewer/RuleViewerLayout.tsx | 3 +- .../rule-viewer/RuleViewerVisualization.tsx | 10 +- .../unified/components/rules/ActionButton.tsx | 5 +- .../unified/components/rules/ActionIcon.tsx | 3 +- .../components/rules/AlertInstanceDetails.tsx | 4 +- .../rules/AlertInstanceStateFilter.tsx | 1 + .../components/rules/AlertInstancesTable.tsx | 9 +- .../components/rules/AlertStateTag.tsx | 4 +- .../unified/components/rules/CloudRules.tsx | 13 +- .../components/rules/EditCloudGroupModal.tsx | 14 +- .../unified/components/rules/GrafanaRules.tsx | 15 +- .../unified/components/rules/NoRulesCTA.tsx | 4 +- .../components/rules/RuleDetails.test.tsx | 15 +- .../unified/components/rules/RuleDetails.tsx | 5 +- .../rules/RuleDetailsActionButtons.tsx | 8 +- .../rules/RuleDetailsAnnotations.tsx | 4 +- .../rules/RuleDetailsDataSources.tsx | 4 +- .../rules/RuleDetailsExpression.tsx | 4 +- .../rules/RuleDetailsFederatedSources.tsx | 4 +- .../rules/RuleDetailsMatchingInstances.tsx | 21 +- .../unified/components/rules/RuleHealth.tsx | 3 +- .../components/rules/RuleListErrors.tsx | 6 +- .../rules/RuleListGroupView.test.tsx | 13 +- .../components/rules/RuleListGroupView.tsx | 5 +- .../components/rules/RuleListStateSection.tsx | 5 +- .../components/rules/RuleListStateView.tsx | 5 +- .../unified/components/rules/RuleState.tsx | 5 +- .../unified/components/rules/RuleStats.tsx | 6 +- .../unified/components/rules/RulesFilter.tsx | 17 +- .../components/rules/RulesGroup.test.tsx | 7 +- .../unified/components/rules/RulesGroup.tsx | 11 +- .../unified/components/rules/RulesTable.tsx | 15 +- .../unified/components/rules/StateHistory.tsx | 13 +- .../components/silences/AmAlertStateTag.tsx | 4 +- .../silences/MatchedSilencedRules.tsx | 16 +- .../unified/components/silences/Matchers.tsx | 4 +- .../components/silences/MatchersField.tsx | 10 +- .../components/silences/NoSilencesCTA.tsx | 4 +- .../components/silences/SilenceDetails.tsx | 7 +- .../components/silences/SilencePeriod.tsx | 6 +- .../components/silences/SilenceStateTag.tsx | 4 +- .../components/silences/SilenceTableRow.tsx | 20 +- .../silences/SilencedAlertsTable.tsx | 15 +- .../silences/SilencedAlertsTableRow.tsx | 7 +- .../components/silences/SilencesEditor.tsx | 35 +- .../components/silences/SilencesFilter.tsx | 16 +- .../components/silences/SilencesTable.tsx | 33 +- .../hooks/useAlertManagerSourceName.ts | 4 +- .../unified/hooks/useAlertQueriesStatus.ts | 3 +- .../alerting/unified/hooks/useCombinedRule.ts | 7 +- .../hooks/useCombinedRuleNamespaces.test.ts | 1 + .../hooks/useCombinedRuleNamespaces.ts | 5 +- .../unified/hooks/useControlledFieldArray.ts | 3 +- .../hooks/useExternalAMSelector.test.ts | 1 + .../unified/hooks/useExternalAmSelector.ts | 1 + .../unified/hooks/useFilteredAmGroups.ts | 4 +- .../unified/hooks/useFilteredRules.ts | 13 +- .../alerting/unified/hooks/useFolder.ts | 9 +- .../unified/hooks/useGroupedAlerts.ts | 7 +- .../alerting/unified/hooks/useHasRuler.ts | 5 +- .../unified/hooks/useIsRuleEditable.test.tsx | 7 +- .../unified/hooks/useIsRuleEditable.ts | 2 + .../hooks/useManagedAlertStateHistory.ts | 5 +- .../unified/hooks/useMuteTimingOptions.ts | 5 +- .../unified/hooks/usePanelCombinedRules.ts | 8 +- .../unified/hooks/useRuleSourcesWithRuler.ts | 2 + .../unified/hooks/useStateHistoryModal.tsx | 2 + .../unified/hooks/useURLSearchParams.ts | 1 + .../hooks/useUnifiedAlertingSelector.ts | 4 +- .../alerting/unified/hooks/useVizHeight.ts | 1 + public/app/features/alerting/unified/mocks.ts | 24 +- .../unified/state/AlertingQueryRunner.test.ts | 8 +- .../unified/state/AlertingQueryRunner.ts | 8 +- .../alerting/unified/state/actions.ts | 6 +- .../alerting/unified/state/reducers.ts | 2 + .../alerting/unified/styles/notifications.ts | 3 +- .../features/alerting/unified/styles/table.ts | 3 +- .../alerting/unified/types/preview.ts | 1 + .../alerting/unified/types/receiver-form.ts | 4 +- .../alerting/unified/utils/access-control.ts | 5 +- .../unified/utils/accessControlHooks.ts | 1 + .../unified/utils/alertmanager.test.ts | 1 + .../alerting/unified/utils/alertmanager.ts | 6 +- .../alerting/unified/utils/amroutes.ts | 13 +- .../alerting/unified/utils/datasource.ts | 1 + .../alerting/unified/utils/matchers.test.ts | 4 +- .../alerting/unified/utils/matchers.ts | 11 +- .../alerting/unified/utils/misc.test.ts | 4 +- .../features/alerting/unified/utils/misc.ts | 12 +- .../alerting/unified/utils/mute-timings.ts | 4 +- .../alerting/unified/utils/query.test.ts | 7 +- .../features/alerting/unified/utils/query.ts | 1 + .../alerting/unified/utils/receiver-form.ts | 4 +- .../alerting/unified/utils/receivers.ts | 3 +- .../features/alerting/unified/utils/redux.ts | 5 +- .../alerting/unified/utils/rule-form.ts | 2 + .../alerting/unified/utils/rule-id.ts | 1 + .../alerting/unified/utils/rulerClient.ts | 2 + .../features/alerting/unified/utils/rules.ts | 27 +- .../features/alerting/unified/utils/time.ts | 1 + .../alerting/unified/utils/timeRange.test.ts | 5 +- .../alerting/unified/utils/timeRange.ts | 1 + .../utils/notificationChannel.test.ts | 3 +- .../alerting/utils/notificationChannels.ts | 1 + public/app/features/annotations/api.ts | 1 + .../components/AnnotationResultMapper.tsx | 2 +- .../StandardAnnotationQueryEditor.tsx | 10 +- .../annotations/executeAnnotationQuery.ts | 6 +- .../standardAnnotationSupport.test.ts | 1 + .../annotations/standardAnnotationSupport.ts | 4 +- public/app/features/annotations/types.ts | 1 + .../features/api-keys/ApiKeysActionBar.tsx | 1 + .../api-keys/ApiKeysAddedModal.test.tsx | 5 +- .../features/api-keys/ApiKeysAddedModal.tsx | 10 +- public/app/features/api-keys/ApiKeysForm.tsx | 8 +- .../features/api-keys/ApiKeysPage.test.tsx | 19 +- public/app/features/api-keys/ApiKeysPage.tsx | 34 +- public/app/features/api-keys/ApiKeysTable.tsx | 5 +- public/app/features/api-keys/state/actions.ts | 1 + .../features/api-keys/state/reducers.test.ts | 9 +- .../features/api-keys/state/selectors.test.ts | 6 +- public/app/features/canvas/element.ts | 7 +- .../app/features/canvas/elements/button.tsx | 5 +- .../features/canvas/elements/droneFront.tsx | 9 +- .../features/canvas/elements/droneSide.tsx | 9 +- .../app/features/canvas/elements/droneTop.tsx | 9 +- public/app/features/canvas/elements/icon.tsx | 13 +- .../app/features/canvas/elements/textBox.tsx | 11 +- .../features/canvas/elements/windTurbine.tsx | 9 +- public/app/features/canvas/registry.ts | 1 + .../app/features/canvas/runtime/element.tsx | 10 +- public/app/features/canvas/runtime/group.tsx | 21 +- public/app/features/canvas/runtime/root.tsx | 1 + public/app/features/canvas/runtime/scene.tsx | 13 +- .../commandPalette/CommandPalette.tsx | 21 +- .../features/commandPalette/ResultItem.tsx | 9 +- .../actions/dashboard.nav.actions.ts | 3 +- .../actions/global.static.actions.ts | 5 +- public/app/features/comments/Comment.tsx | 7 +- .../app/features/comments/CommentManager.tsx | 3 +- public/app/features/comments/CommentView.tsx | 3 +- .../AddPanelWidget/AddPanelWidget.test.tsx | 6 +- .../AddPanelWidget/AddPanelWidget.tsx | 21 +- .../AngularEditorLoader.tsx | 1 + .../AnnotationSettingsEdit.tsx | 15 +- .../AnnotationSettingsList.tsx | 10 +- .../DashExportModal/DashboardExporter.test.ts | 13 +- .../DashExportModal/DashboardExporter.ts | 13 +- .../dashboard/components/DashNav/DashNav.tsx | 32 +- .../components/DashNav/DashNavButton.tsx | 5 +- .../DashNav/DashNavTimeControls.test.tsx | 8 +- .../DashNav/DashNavTimeControls.tsx | 15 +- .../DashboardCommentsModal.tsx | 7 +- .../DashboardLoading/DashboardFailed.tsx | 7 +- .../DashboardLoading/DashboardLoading.tsx | 7 +- .../AccessControlDashboardPermissions.tsx | 8 +- .../DashboardPermissions.tsx | 12 +- .../DashboardPrompt/DashboardPrompt.test.tsx | 3 +- .../DashboardPrompt/DashboardPrompt.tsx | 22 +- .../DashboardRow/DashboardRow.test.tsx | 6 +- .../components/DashboardRow/DashboardRow.tsx | 18 +- .../AnnotationsSettings.test.tsx | 9 +- .../DashboardSettings/AnnotationsSettings.tsx | 5 +- .../AutoRefreshIntervals.test.tsx | 6 +- .../AutoRefreshIntervals.tsx | 1 + .../DashboardSettings/DashboardSettings.tsx | 27 +- .../DashboardSettingsHeader.tsx | 1 + .../GeneralSettings.test.tsx | 10 +- .../DashboardSettings/GeneralSettings.tsx | 10 +- .../DashboardSettings/JsonEditorSettings.tsx | 6 +- .../DashboardSettings/LinksSettings.test.tsx | 6 +- .../DashboardSettings/LinksSettings.tsx | 2 + .../DashboardSettings/ListNewButton.tsx | 7 +- .../DashboardSettings/PreviewSettings.tsx | 3 +- .../DashboardSettings/TimePickerSettings.tsx | 8 +- .../VersionsSettings.test.tsx | 9 +- .../DashboardSettings/VersionsSettings.tsx | 2 + .../DeleteDashboard/DeleteDashboardButton.tsx | 5 +- .../DeleteDashboard/DeleteDashboardModal.tsx | 11 +- .../DeleteDashboard/useDashboardDelete.tsx | 3 +- .../components/Inspector/InspectContent.tsx | 14 +- .../Inspector/PanelInspectActions.tsx | 7 +- .../components/Inspector/PanelInspector.tsx | 17 +- .../dashboard/components/Inspector/hooks.ts | 9 +- .../LinksSettings/LinkSettingsEdit.tsx | 4 +- .../LinksSettings/LinkSettingsList.tsx | 4 +- .../PanelEditor/AngularPanelOptions.tsx | 16 +- .../PanelEditor/DynamicConfigValueEditor.tsx | 9 +- .../components/PanelEditor/OptionsPane.tsx | 16 +- .../PanelEditor/OptionsPaneCategory.tsx | 10 +- .../OptionsPaneCategoryDescriptor.tsx | 1 + .../PanelEditor/OptionsPaneItemDescriptor.tsx | 7 +- .../PanelEditor/OptionsPaneItemOverrides.tsx | 8 +- .../PanelEditor/OptionsPaneOptions.test.tsx | 18 +- .../PanelEditor/OptionsPaneOptions.tsx | 17 +- .../PanelEditor/OverrideCategoryTitle.tsx | 3 +- .../components/PanelEditor/PanelEditor.tsx | 54 +- .../PanelEditor/PanelEditorQueries.tsx | 10 +- .../PanelEditor/PanelEditorTableView.tsx | 15 +- .../PanelEditor/PanelEditorTabs.tsx | 17 +- .../PanelEditor/PanelNotSupported.test.tsx | 4 +- .../PanelEditor/PanelNotSupported.tsx | 7 +- .../PanelEditor/VisualizationButton.tsx | 11 +- .../PanelEditor/VisualizationSelectPane.tsx | 25 +- .../PanelEditor/getFieldOverrideElements.tsx | 14 +- .../PanelEditor/getLibraryPanelOptions.tsx | 13 +- .../PanelEditor/getPanelFrameOptions.tsx | 7 +- .../getVisualizationOptions.test.ts | 1 + .../PanelEditor/getVisualizationOptions.tsx | 16 +- .../state/OptionSearchEngine.test.ts | 1 + .../PanelEditor/state/OptionSearchEngine.ts | 2 +- .../PanelEditor/state/actions.test.ts | 10 +- .../components/PanelEditor/state/actions.ts | 9 +- .../PanelEditor/state/getOptionOverrides.ts | 4 +- .../components/PanelEditor/state/reducers.ts | 6 +- .../PanelEditor/state/selectors.test.ts | 8 +- .../components/PanelEditor/state/selectors.ts | 6 +- .../dashboard/components/PanelEditor/types.ts | 1 + .../PanelEditor/usePanelLatestData.ts | 6 +- .../components/PanelEditor/utils.test.ts | 1 + .../dashboard/components/PanelEditor/utils.ts | 7 +- .../RepeatRowSelect/RepeatRowSelect.tsx | 7 +- .../RowOptions/RowOptionsButton.tsx | 3 +- .../components/RowOptions/RowOptionsForm.tsx | 1 + .../components/RowOptions/RowOptionsModal.tsx | 5 +- .../SaveDashboard/SaveDashboardAsModal.tsx | 8 +- .../SaveDashboard/SaveDashboardButton.tsx | 4 +- .../SaveDashboard/SaveDashboardDiff.tsx | 10 +- .../SaveDashboard/SaveDashboardDrawer.tsx | 15 +- .../SaveDashboard/SaveDashboardErrorProxy.tsx | 12 +- .../SaveDashboard/SaveDashboardModal.tsx | 10 +- .../SaveDashboard/SaveDashboardProxy.tsx | 10 +- .../SaveProvisionedDashboard.tsx | 2 + .../SaveDashboard/UnsavedChangesModal.tsx | 11 +- .../forms/SaveDashboardAsForm.test.tsx | 8 +- .../forms/SaveDashboardAsForm.tsx | 6 +- .../forms/SaveDashboardForm.test.tsx | 7 +- .../SaveDashboard/forms/SaveDashboardForm.tsx | 8 +- .../forms/SaveProvisionedDashboardForm.tsx | 10 +- .../components/SaveDashboard/types.ts | 1 + .../SaveDashboard/useDashboardSave.tsx | 8 +- .../components/ShareModal/ShareEmbed.test.tsx | 7 +- .../components/ShareModal/ShareEmbed.tsx | 6 +- .../components/ShareModal/ShareExport.tsx | 16 +- .../ShareModal/ShareLibraryPanel.tsx | 2 + .../components/ShareModal/ShareLink.test.tsx | 9 +- .../components/ShareModal/ShareLink.tsx | 8 +- .../components/ShareModal/ShareModal.tsx | 10 +- .../components/ShareModal/ShareSnapshot.tsx | 9 +- .../components/ShareModal/ViewJsonModal.tsx | 5 +- .../dashboard/components/ShareModal/types.ts | 1 + .../components/ShareModal/utils.test.ts | 3 +- .../dashboard/components/ShareModal/utils.ts | 6 +- .../components/SubMenu/AnnotationPicker.tsx | 10 +- .../components/SubMenu/Annotations.tsx | 2 + .../components/SubMenu/DashboardLinks.tsx | 16 +- .../SubMenu/DashboardLinksDashboard.test.tsx | 7 +- .../SubMenu/DashboardLinksDashboard.tsx | 12 +- .../dashboard/components/SubMenu/SubMenu.tsx | 13 +- .../components/SubMenu/SubMenuItems.tsx | 4 +- .../TransformationEditor.tsx | 5 +- .../TransformationOperationRow.tsx | 13 +- .../TransformationOperationRows.tsx | 1 + .../TransformationsEditor.test.tsx | 13 +- .../TransformationsEditor.tsx | 41 +- .../components/VersionHistory/DiffGroup.tsx | 10 +- .../components/VersionHistory/DiffTitle.tsx | 10 +- .../components/VersionHistory/DiffValues.tsx | 10 +- .../components/VersionHistory/DiffViewer.tsx | 5 +- .../VersionHistory/HistorySrv.test.ts | 5 +- .../components/VersionHistory/HistorySrv.ts | 4 +- .../VersionHistory/RevertDashboardModal.tsx | 2 + .../VersionHistory/VersionHistoryButtons.tsx | 1 + .../VersionHistoryComparison.tsx | 8 +- .../VersionHistory/VersionHistoryHeader.tsx | 3 +- .../VersionHistory/VersionHistoryTable.tsx | 5 +- .../VersionHistory/useDashboardRestore.tsx | 11 +- .../containers/DashboardPage.test.tsx | 29 +- .../dashboard/containers/DashboardPage.tsx | 44 +- .../containers/SoloPanelPage.test.tsx | 11 +- .../dashboard/containers/SoloPanelPage.tsx | 8 +- .../dashboard/dashgrid/DashboardGrid.test.tsx | 6 +- .../dashboard/dashgrid/DashboardGrid.tsx | 22 +- .../dashboard/dashgrid/DashboardPanel.tsx | 13 +- .../dashboard/dashgrid/LazyLoader.tsx | 3 +- .../dashboard/dashgrid/PanelChrome.test.tsx | 10 +- .../dashboard/dashgrid/PanelChrome.tsx | 32 +- .../dashboard/dashgrid/PanelChromeAngular.tsx | 24 +- .../dashgrid/PanelHeader/PanelHeader.tsx | 15 +- .../PanelHeader/PanelHeaderCorner.test.tsx | 6 +- .../PanelHeader/PanelHeaderCorner.tsx | 11 +- .../PanelHeaderLoadingIndicator.tsx | 3 +- .../dashgrid/PanelHeader/PanelHeaderMenu.tsx | 4 +- .../PanelHeader/PanelHeaderMenuItem.tsx | 5 +- .../PanelHeader/PanelHeaderMenuProvider.tsx | 9 +- .../PanelHeader/PanelHeaderMenuTrigger.tsx | 1 + .../PanelHeader/PanelHeaderMenuWrapper.tsx | 7 +- .../PanelHeader/PanelHeaderNotice.tsx | 1 + .../PanelHeader/PanelHeaderNotices.tsx | 4 +- .../dashboard/dashgrid/PanelResizer.tsx | 2 +- .../features/dashboard/dashgrid/liveTimer.ts | 4 +- .../dashboard/services/DashboardLoaderSrv.ts | 18 +- .../dashboard/services/DashboardSrv.ts | 12 +- .../dashboard/services/TimeSrv.test.ts | 9 +- .../features/dashboard/services/TimeSrv.ts | 12 +- .../dashboard/state/DashboardMigrator.test.ts | 20 +- .../dashboard/state/DashboardMigrator.ts | 35 +- .../state/DashboardModel.refresh.test.ts | 7 +- .../state/DashboardModel.repeat.test.ts | 9 +- .../dashboard/state/DashboardModel.test.ts | 9 +- .../dashboard/state/DashboardModel.ts | 39 +- .../dashboard/state/PanelModel.test.ts | 19 +- .../features/dashboard/state/PanelModel.ts | 21 +- .../app/features/dashboard/state/actions.ts | 13 +- .../dashboard/state/analyticsProcessor.ts | 3 +- .../state/getPanelOptionsWithDefaults.test.ts | 4 +- .../state/getPanelOptionsWithDefaults.ts | 3 +- .../dashboard/state/initDashboard.test.ts | 26 +- .../features/dashboard/state/initDashboard.ts | 35 +- .../features/dashboard/state/reducers.test.ts | 5 +- .../app/features/dashboard/state/reducers.ts | 6 +- .../app/features/dashboard/state/selectors.ts | 3 +- .../features/dashboard/state/utils.test.ts | 3 +- public/app/features/dashboard/state/utils.ts | 3 +- .../dashboard/utils/getPanelMenu.test.ts | 10 +- .../features/dashboard/utils/getPanelMenu.ts | 15 +- .../dashboard/utils/loadSnapshotData.ts | 8 +- .../features/dashboard/utils/panel.test.ts | 8 +- public/app/features/dashboard/utils/panel.ts | 26 +- .../dashboard/utils/panelMerge.test.ts | 1 + .../features/dashboard/utils/panelMerge.ts | 4 +- .../datasources/DashboardsTable.test.tsx | 6 +- .../features/datasources/DashboardsTable.tsx | 4 +- .../datasources/DataSourceDashboards.test.tsx | 8 +- .../datasources/DataSourceDashboards.tsx | 22 +- .../datasources/DataSourceList.test.tsx | 6 +- .../features/datasources/DataSourcesList.tsx | 2 +- .../datasources/DataSourcesListPage.test.tsx | 3 +- .../datasources/DataSourcesListPage.tsx | 20 +- .../datasources/NewDataSourcePage.tsx | 16 +- .../settings/BasicSettings.test.tsx | 3 +- .../datasources/settings/BasicSettings.tsx | 3 +- .../datasources/settings/ButtonRow.test.tsx | 3 +- .../datasources/settings/ButtonRow.tsx | 5 +- .../datasources/settings/CloudInfoBox.tsx | 7 +- .../settings/DataSourceSettingsPage.test.tsx | 19 +- .../settings/DataSourceSettingsPage.tsx | 41 +- .../datasources/settings/PluginSettings.tsx | 3 +- .../datasources/state/actions.test.ts | 19 +- .../app/features/datasources/state/actions.ts | 8 +- .../datasources/state/buildCategories.test.ts | 6 +- .../features/datasources/state/navModel.ts | 5 +- .../datasources/state/reducers.test.ts | 11 +- .../features/datasources/state/reducers.ts | 6 +- .../features/datasources/state/selectors.ts | 1 + public/app/features/dimensions/color.ts | 1 + .../editors/ColorDimensionEditor.tsx | 6 +- .../dimensions/editors/FolderPickerTab.tsx | 10 +- .../dimensions/editors/IconSelector.tsx | 3 +- .../dimensions/editors/NumberInput.tsx | 1 + .../dimensions/editors/ResourceCards.tsx | 8 +- .../editors/ResourceDimensionEditor.tsx | 4 +- .../dimensions/editors/ResourcePicker.tsx | 14 +- .../editors/ResourcePickerPopover.tsx | 10 +- .../editors/ScalarDimensionEditor.tsx | 7 +- .../editors/ScaleDimensionEditor.tsx | 9 +- .../editors/TextDimensionEditor.tsx | 3 +- .../ThresholdsEditor.test.tsx | 6 +- .../ThresholdsEditor/ThresholdsEditor.tsx | 5 +- .../editors/ThresholdsEditor/thresholds.tsx | 2 + .../dimensions/editors/URLPickerTab.tsx | 9 +- .../ValueMappingEditRow.tsx | 10 +- .../ValueMappingsEditor.test.tsx | 6 +- .../ValueMappingsEditor.tsx | 9 +- .../ValueMappingsEditorModal.test.tsx | 6 +- .../ValueMappingsEditorModal.tsx | 10 +- public/app/features/dimensions/resource.ts | 1 + public/app/features/dimensions/scalar.test.ts | 4 +- public/app/features/dimensions/scalar.ts | 1 + public/app/features/dimensions/scale.test.ts | 1 + public/app/features/dimensions/scale.ts | 5 +- public/app/features/dimensions/text.ts | 1 + public/app/features/dimensions/utils.ts | 3 +- .../AddToDashboard/AddToDashboardModal.tsx | 23 +- .../AddToDashboard/addToDashboard.test.ts | 10 +- .../explore/AddToDashboard/index.test.tsx | 24 +- .../features/explore/AddToDashboard/index.tsx | 9 +- public/app/features/explore/ElapsedTime.tsx | 1 + .../features/explore/ErrorContainer.test.tsx | 3 +- .../app/features/explore/ErrorContainer.tsx | 1 + public/app/features/explore/Explore.test.tsx | 12 +- public/app/features/explore/Explore.tsx | 58 +- .../app/features/explore/ExploreActions.tsx | 6 +- public/app/features/explore/ExploreDrawer.tsx | 6 +- public/app/features/explore/ExploreGraph.tsx | 13 +- .../features/explore/ExploreGraphLabel.tsx | 4 +- .../features/explore/ExplorePaneContainer.tsx | 13 +- .../explore/ExploreQueryInspector.test.tsx | 4 +- .../explore/ExploreQueryInspector.tsx | 16 +- .../features/explore/ExploreTimeControls.tsx | 13 +- .../app/features/explore/ExploreToolbar.tsx | 21 +- .../features/explore/FeatureTogglePage.tsx | 7 +- public/app/features/explore/LiveLogs.test.tsx | 6 +- public/app/features/explore/LiveLogs.tsx | 4 +- .../app/features/explore/LiveTailButton.tsx | 3 +- public/app/features/explore/Logs.test.tsx | 3 +- public/app/features/explore/Logs.tsx | 12 +- public/app/features/explore/LogsContainer.tsx | 17 +- public/app/features/explore/LogsMetaRow.tsx | 2 + .../features/explore/LogsNavigation.test.tsx | 4 +- .../app/features/explore/LogsNavigation.tsx | 6 +- .../explore/LogsNavigationPages.test.tsx | 3 +- .../features/explore/LogsNavigationPages.tsx | 4 +- .../features/explore/LogsVolumePanel.test.tsx | 6 +- .../app/features/explore/LogsVolumePanel.tsx | 6 +- .../features/explore/MetaInfoText.test.tsx | 3 +- public/app/features/explore/MetaInfoText.tsx | 3 +- public/app/features/explore/NoData.tsx | 5 +- .../explore/NoDataSourceCallToAction.tsx | 4 +- .../explore/NodeGraphContainer.test.tsx | 7 +- .../features/explore/NodeGraphContainer.tsx | 17 +- .../app/features/explore/QueryRows.test.tsx | 15 +- public/app/features/explore/QueryRows.tsx | 11 +- .../explore/ResponseErrorContainer.test.tsx | 6 +- .../explore/ResponseErrorContainer.tsx | 5 +- .../explore/RichHistory/RichHistory.test.tsx | 9 +- .../explore/RichHistory/RichHistory.tsx | 17 +- .../RichHistory/RichHistoryCard.test.tsx | 10 +- .../explore/RichHistory/RichHistoryCard.tsx | 23 +- .../RichHistory/RichHistoryContainer.test.tsx | 9 +- .../RichHistory/RichHistoryContainer.tsx | 9 +- .../RichHistory/RichHistoryQueriesTab.tsx | 15 +- .../RichHistorySettingsTab.test.tsx | 3 +- .../RichHistory/RichHistorySettingsTab.tsx | 12 +- .../RichHistoryStarredTab.test.tsx | 7 +- .../RichHistory/RichHistoryStarredTab.tsx | 16 +- .../app/features/explore/RunButton.test.tsx | 8 +- public/app/features/explore/RunButton.tsx | 1 + .../explore/SecondaryActions.test.tsx | 5 +- .../app/features/explore/SecondaryActions.tsx | 3 +- .../features/explore/TableContainer.test.tsx | 6 +- .../app/features/explore/TableContainer.tsx | 10 +- public/app/features/explore/Time.tsx | 1 + .../features/explore/TimeSyncButton.test.tsx | 5 +- .../app/features/explore/TimeSyncButton.tsx | 1 + .../explore/TraceView/TraceView.test.tsx | 15 +- .../features/explore/TraceView/TraceView.tsx | 7 +- .../TraceView/TraceViewContainer.test.tsx | 17 +- .../explore/TraceView/TraceViewContainer.tsx | 14 +- .../explore/TraceView/createSpanLink.test.ts | 4 +- .../explore/TraceView/createSpanLink.tsx | 4 +- .../TraceView/useChildrenState.test.ts | 4 +- .../explore/TraceView/useChildrenState.ts | 1 + .../explore/TraceView/useDetailState.test.ts | 6 +- .../explore/TraceView/useDetailState.ts | 3 +- .../TraceView/useHoverIndentGuide.test.ts | 1 + .../explore/TraceView/useSearch.test.ts | 4 +- .../features/explore/TraceView/useSearch.ts | 1 + .../explore/TraceView/useViewRange.test.ts | 1 + .../explore/TraceView/useViewRange.ts | 1 + public/app/features/explore/Wrapper.test.tsx | 14 +- public/app/features/explore/Wrapper.tsx | 20 +- .../explore/exploreGraphStyleUtils.ts | 2 + .../features/explore/spec/helper/assert.ts | 2 + .../explore/spec/helper/interactions.ts | 7 +- .../app/features/explore/spec/helper/query.ts | 1 + .../features/explore/spec/helper/setup.tsx | 11 +- .../explore/spec/interpolation.test.tsx | 7 +- .../explore/spec/queryHistory.test.tsx | 23 +- .../features/explore/state/datasource.test.ts | 5 +- .../app/features/explore/state/datasource.ts | 5 +- .../explore/state/explorePane.test.ts | 13 +- .../app/features/explore/state/explorePane.ts | 55 +- public/app/features/explore/state/helpers.ts | 1 + public/app/features/explore/state/history.ts | 9 +- .../app/features/explore/state/main.test.ts | 13 +- public/app/features/explore/state/main.ts | 21 +- .../app/features/explore/state/query.test.ts | 44 +- public/app/features/explore/state/query.ts | 20 +- .../app/features/explore/state/time.test.ts | 14 +- public/app/features/explore/state/time.ts | 10 +- .../app/features/explore/state/utils.test.ts | 2 +- public/app/features/explore/state/utils.ts | 6 +- .../features/explore/useLiveTailControls.ts | 6 +- .../explore/utils/LogsCrossFadeTransition.tsx | 4 +- .../features/explore/utils/decorators.test.ts | 7 +- .../app/features/explore/utils/decorators.ts | 8 +- .../app/features/explore/utils/links.test.ts | 6 +- public/app/features/explore/utils/links.ts | 4 +- .../expressions/ExpressionDatasource.test.ts | 1 + .../expressions/ExpressionDatasource.ts | 8 +- .../expressions/ExpressionQueryEditor.tsx | 10 +- .../components/ClassicConditions.tsx | 5 +- .../expressions/components/Condition.tsx | 4 +- .../features/expressions/components/Math.tsx | 4 +- .../expressions/components/Reduce.tsx | 2 + .../expressions/components/Resample.tsx | 2 + public/app/features/expressions/guards.ts | 1 + public/app/features/expressions/types.ts | 1 + .../expressions/utils/expressionTypes.ts | 3 +- .../AccessControlFolderPermissions.tsx | 9 +- .../app/features/folders/FolderAlerting.tsx | 9 +- .../folders/FolderLibraryPanelsPage.tsx | 11 +- .../features/folders/FolderPermissions.tsx | 12 +- .../folders/FolderSettingsPage.test.tsx | 10 +- .../features/folders/FolderSettingsPage.tsx | 9 +- .../components/NewDashboardsFolder.tsx | 4 +- .../features/folders/state/actions.test.ts | 10 +- public/app/features/folders/state/actions.ts | 4 +- public/app/features/folders/state/navModel.ts | 1 - .../features/folders/state/reducers.test.ts | 4 +- public/app/features/folders/state/reducers.ts | 2 +- .../geo/editor/GazetteerPathEditor.tsx | 4 +- .../app/features/geo/format/geojson.test.ts | 1 + public/app/features/geo/format/geojson.ts | 3 +- public/app/features/geo/format/utils.ts | 7 +- .../features/geo/gazetteer/gazetteer.test.ts | 1 + .../app/features/geo/gazetteer/gazetteer.ts | 9 +- .../features/geo/gazetteer/worldmap.test.ts | 6 +- public/app/features/geo/gazetteer/worldmap.ts | 3 +- .../features/geo/utils/frameVectorSource.ts | 4 +- .../app/features/geo/utils/location.test.ts | 4 +- public/app/features/geo/utils/location.ts | 6 +- public/app/features/inspector/DetailText.tsx | 7 +- .../features/inspector/InspectDataOptions.tsx | 6 +- .../inspector/InspectDataTab.test.tsx | 6 +- .../app/features/inspector/InspectDataTab.tsx | 22 +- .../inspector/InspectErrorTab.test.tsx | 3 +- .../features/inspector/InspectErrorTab.tsx | 1 + .../app/features/inspector/InspectJSONTab.tsx | 6 +- .../features/inspector/InspectMetadataTab.tsx | 1 + .../features/inspector/InspectStatsTab.tsx | 4 +- .../features/inspector/InspectStatsTable.tsx | 3 +- .../app/features/inspector/QueryInspector.tsx | 23 +- public/app/features/inspector/styles.ts | 3 +- public/app/features/invites/InviteeRow.tsx | 6 +- .../features/invites/InviteesTable.test.tsx | 7 +- public/app/features/invites/InviteesTable.tsx | 2 + .../features/invites/SignupInvited.test.tsx | 8 +- public/app/features/invites/SignupInvited.tsx | 5 +- .../features/invites/state/reducers.test.ts | 9 +- public/app/features/invites/state/reducers.ts | 2 + .../app/features/invites/state/selectors.ts | 1 + .../library-panels/LibraryPanelsPage.tsx | 9 +- .../AddLibraryPanelModal.tsx | 6 +- .../ChangeLibraryPanelModal.tsx | 1 + .../DeleteLibraryPanelModal.tsx | 10 +- .../DeleteLibraryPanelModal/actions.ts | 3 +- .../DeleteLibraryPanelModal/reducer.test.ts | 4 +- .../DeleteLibraryPanelModal/reducer.ts | 7 +- .../LibraryPanelCard/LibraryPanelCard.tsx | 12 +- .../LibraryPanelInfo/LibraryPanelInfo.tsx | 8 +- .../LibraryPanelsSearch.test.tsx | 12 +- .../LibraryPanelsSearch.tsx | 19 +- .../LibraryPanelsSearch/reducer.test.ts | 1 + .../components/LibraryPanelsSearch/reducer.ts | 3 +- .../LibraryPanelsView/LibraryPanelsView.tsx | 12 +- .../components/LibraryPanelsView/actions.ts | 3 +- .../LibraryPanelsView/reducer.test.ts | 3 +- .../components/LibraryPanelsView/reducer.ts | 3 +- .../OpenLibraryPanelModal.tsx | 9 +- .../PanelLibraryOptionsGroup.tsx | 17 +- .../SaveLibraryPanelModal.tsx | 8 +- .../components/UnlinkModal/UnlinkModal.tsx | 1 + public/app/features/library-panels/guard.ts | 1 + .../app/features/library-panels/state/api.ts | 7 +- public/app/features/library-panels/styles.ts | 1 + public/app/features/library-panels/types.ts | 5 +- public/app/features/library-panels/utils.ts | 7 +- .../library-panels/utils/usePanelSave.ts | 3 +- .../features/live/LiveConnectionWarning.tsx | 5 +- .../live/centrifuge/LiveDataStream.test.ts | 13 +- .../live/centrifuge/LiveDataStream.ts | 11 +- .../app/features/live/centrifuge/channel.ts | 20 +- .../app/features/live/centrifuge/service.ts | 25 +- .../live/centrifuge/service.worker.ts | 9 +- .../live/centrifuge/serviceWorkerProxy.ts | 8 +- .../live/dashboard/DashboardChangedModal.tsx | 12 +- .../live/dashboard/dashboardWatcher.ts | 15 +- public/app/features/live/index.ts | 10 +- public/app/features/live/live.test.ts | 8 +- public/app/features/live/live.ts | 11 +- public/app/features/live/pages/AddNewRule.tsx | 6 +- .../features/live/pages/CloudAdminPage.tsx | 6 +- .../features/live/pages/FeatureTogglePage.tsx | 1 + .../features/live/pages/LiveStatusPage.tsx | 1 + .../features/live/pages/PipelineAdminPage.tsx | 6 +- .../app/features/live/pages/PipelineTable.tsx | 10 +- public/app/features/live/pages/RuleModal.tsx | 14 +- .../features/live/pages/RuleSettingsArray.tsx | 7 +- .../live/pages/RuleSettingsEditor.tsx | 2 + public/app/features/live/pages/RuleTest.tsx | 10 +- public/app/features/live/pages/utils.ts | 1 + .../manage-dashboards/DashboardImportPage.tsx | 15 +- .../manage-dashboards/SnapshotListPage.tsx | 9 +- .../components/ImportDashboardForm.tsx | 10 +- .../ImportDashboardLibraryPanelsList.tsx | 7 +- .../components/ImportDashboardOverview.tsx | 13 +- .../components/SnapshotListTable.test.tsx | 1 + .../components/SnapshotListTable.tsx | 8 +- .../manage-dashboards/state/actions.test.ts | 4 +- .../manage-dashboards/state/actions.ts | 20 +- .../manage-dashboards/state/reducers.test.ts | 6 +- .../manage-dashboards/state/reducers.ts | 2 + .../manage-dashboards/utils/validation.ts | 3 +- .../notifications/NotificationsPage.tsx | 7 +- .../notifications/StoredNotifications.tsx | 7 +- public/app/features/org/NewOrgPage.tsx | 13 +- .../app/features/org/OrgDetailsPage.test.tsx | 8 +- public/app/features/org/OrgDetailsPage.tsx | 17 +- public/app/features/org/OrgProfile.test.tsx | 3 +- public/app/features/org/OrgProfile.tsx | 1 + public/app/features/org/SelectOrgPage.tsx | 14 +- public/app/features/org/UserInviteForm.tsx | 6 +- public/app/features/org/UserInvitePage.tsx | 8 +- public/app/features/org/state/actions.test.ts | 6 +- public/app/features/org/state/actions.ts | 5 +- .../app/features/org/state/reducers.test.ts | 1 + .../components/PanelDataErrorView.test.tsx | 10 +- .../panel/components/PanelDataErrorView.tsx | 20 +- .../panel/components/PanelPluginError.tsx | 4 +- .../panel/components/PanelRenderer.tsx | 6 +- .../VizTypePicker/PanelTypeCard.tsx | 7 +- .../VisualizationSuggestionCard.tsx | 15 +- .../VisualizationSuggestions.tsx | 15 +- .../VizTypePicker/VizTypePicker.tsx | 11 +- .../VizTypePicker/VizTypePickerPlugin.tsx | 2 + .../panel/panellinks/linkSuppliers.test.ts | 6 +- .../panel/panellinks/linkSuppliers.ts | 3 +- .../app/features/panel/panellinks/link_srv.ts | 8 +- .../panel/panellinks/specs/link_srv.test.ts | 5 +- .../app/features/panel/state/actions.test.ts | 13 +- public/app/features/panel/state/actions.ts | 13 +- .../panel/state/getAllSuggestions.test.ts | 1 + public/app/features/panel/state/reducers.ts | 3 +- public/app/features/panel/state/selectors.ts | 1 + public/app/features/panel/state/utils.test.ts | 1 + .../playlist/EmptyQueryListBanner.tsx | 7 +- .../playlist/PlaylistEditPage.test.tsx | 11 +- .../features/playlist/PlaylistEditPage.tsx | 10 +- .../features/playlist/PlaylistForm.test.tsx | 6 +- public/app/features/playlist/PlaylistForm.tsx | 10 +- .../playlist/PlaylistNewPage.test.tsx | 10 +- .../app/features/playlist/PlaylistNewPage.tsx | 10 +- .../features/playlist/PlaylistPage.test.tsx | 6 +- public/app/features/playlist/PlaylistPage.tsx | 21 +- .../features/playlist/PlaylistPageList.tsx | 9 +- .../app/features/playlist/PlaylistSrv.test.ts | 6 +- public/app/features/playlist/PlaylistSrv.ts | 4 +- .../features/playlist/PlaylistStartPage.tsx | 2 + .../features/playlist/PlaylistTableRow.tsx | 8 +- public/app/features/playlist/ShareModal.tsx | 3 + public/app/features/playlist/StartModal.tsx | 4 +- public/app/features/playlist/api.ts | 5 +- public/app/features/playlist/styles.ts | 3 +- public/app/features/playlist/usePlaylist.tsx | 3 +- .../features/playlist/usePlaylistItems.tsx | 3 +- .../features/plugins/__mocks__/pluginMocks.ts | 5 +- .../plugins/admin/__mocks__/mockHelpers.ts | 8 +- .../admin/__mocks__/remotePlugin.mock.ts | 1 + public/app/features/plugins/admin/api.ts | 5 +- .../admin/components/AppConfigWrapper.tsx | 7 +- .../components/Badges/PluginDisabledBadge.tsx | 1 + .../Badges/PluginEnterpriseBadge.tsx | 9 +- .../components/Badges/PluginInstallBadge.tsx | 2 + .../Badges/PluginUpdateAvailableBadge.tsx | 4 +- .../admin/components/Badges/sharedStyles.ts | 1 + .../GetStartedWithApp.tsx | 6 +- .../GetStartedWithDataSource.tsx | 6 +- .../GetStartedWithPlugin.tsx | 5 +- .../admin/components/HorizontalGroup.tsx | 4 +- .../ExternallyManagedButton.tsx | 2 + .../InstallControls/InstallControls.tsx | 13 +- .../InstallControls/InstallControlsButton.tsx | 3 +- .../plugins/admin/components/Loader.tsx | 2 + .../plugins/admin/components/Page.tsx | 5 +- .../admin/components/PluginDashboards.tsx | 7 +- .../admin/components/PluginDetailsBody.tsx | 5 +- .../components/PluginDetailsDisabledError.tsx | 6 +- .../admin/components/PluginDetailsHeader.tsx | 14 +- .../PluginDetailsHeaderDependencies.tsx | 4 +- .../PluginDetailsHeaderSignature.tsx | 7 +- .../components/PluginDetailsSignature.tsx | 4 +- .../plugins/admin/components/PluginList.tsx | 9 +- .../admin/components/PluginListItem.test.tsx | 7 +- .../admin/components/PluginListItem.tsx | 7 +- .../components/PluginListItemBadges.test.tsx | 9 +- .../admin/components/PluginListItemBadges.tsx | 3 + .../PluginSignatureDetailsBadge.tsx | 3 +- .../admin/components/PluginTypeIcon.tsx | 3 +- .../plugins/admin/components/SearchField.tsx | 3 +- .../plugins/admin/components/VersionList.tsx | 5 +- .../features/plugins/admin/helpers.test.ts | 5 +- public/app/features/plugins/admin/helpers.ts | 5 +- .../plugins/admin/hooks/usePluginConfig.tsx | 3 +- .../admin/hooks/usePluginDetailsTabs.tsx | 4 +- .../plugins/admin/pages/Browse.test.tsx | 11 +- .../features/plugins/admin/pages/Browse.tsx | 26 +- .../plugins/admin/pages/NotEnabed.tsx | 6 +- .../admin/pages/PluginDetails.test.tsx | 23 +- .../plugins/admin/pages/PluginDetails.tsx | 22 +- public/app/features/plugins/admin/routes.ts | 1 + .../features/plugins/admin/state/actions.ts | 8 +- .../app/features/plugins/admin/state/hooks.ts | 9 +- .../features/plugins/admin/state/reducer.ts | 9 +- .../features/plugins/admin/state/selectors.ts | 3 + public/app/features/plugins/admin/types.ts | 1 + .../app/features/plugins/built_in_plugins.ts | 38 +- .../plugins/components/AppRootPage.test.tsx | 13 +- .../plugins/components/AppRootPage.tsx | 11 +- .../plugins/components/PluginStateInfo.tsx | 3 +- .../plugins/components/PluginsErrorsInfo.tsx | 6 +- public/app/features/plugins/datasource_srv.ts | 29 +- .../app/features/plugins/importPanelPlugin.ts | 4 +- .../app/features/plugins/pluginPreloader.ts | 1 + .../features/plugins/pluginSettings.test.ts | 3 +- public/app/features/plugins/pluginSettings.ts | 2 +- public/app/features/plugins/plugin_loader.ts | 48 +- .../plugins/tests/datasource_srv.test.ts | 2 +- .../plugins/tests/plugin_loader.test.ts | 2 +- public/app/features/plugins/utils.ts | 3 +- .../features/profile/ChangePasswordForm.tsx | 8 +- .../profile/ChangePasswordPage.test.tsx | 9 +- .../features/profile/ChangePasswordPage.tsx | 9 +- .../features/profile/FeatureTogglePage.tsx | 1 + .../features/profile/UserOrganizations.tsx | 7 +- .../features/profile/UserProfileEditForm.tsx | 8 +- .../profile/UserProfileEditPage.test.tsx | 12 +- .../features/profile/UserProfileEditPage.tsx | 13 +- public/app/features/profile/UserSessions.tsx | 9 +- public/app/features/profile/UserTeams.tsx | 3 +- public/app/features/profile/api.ts | 3 +- public/app/features/profile/routes.tsx | 3 +- public/app/features/profile/state/actions.ts | 5 +- .../features/profile/state/reducers.test.ts | 1 + public/app/features/profile/state/reducers.ts | 6 +- .../features/query/components/HelpToggle.tsx | 5 +- .../query/components/QueryEditorRow.test.ts | 1 + .../query/components/QueryEditorRow.tsx | 22 +- .../components/QueryEditorRowHeader.test.tsx | 6 +- .../query/components/QueryEditorRowHeader.tsx | 5 +- .../query/components/QueryEditorRows.tsx | 7 +- .../query/components/QueryErrorAlert.tsx | 3 +- .../features/query/components/QueryGroup.tsx | 43 +- .../query/components/QueryGroupOptions.tsx | 8 +- .../AlertStatesWorker.test.ts | 5 +- .../DashboardQueryRunner/AlertStatesWorker.ts | 6 +- .../AnnotationsQueryRunner.test.ts | 8 +- .../AnnotationsQueryRunner.ts | 6 +- .../AnnotationsWorker.test.ts | 14 +- .../DashboardQueryRunner/AnnotationsWorker.ts | 14 +- .../DashboardQueryRunner.test.ts | 14 +- .../DashboardQueryRunner.ts | 20 +- .../LegacyAnnotationQueryRunner.test.ts | 5 +- .../LegacyAnnotationQueryRunner.ts | 1 + .../SnapshotWorker.test.ts | 2 +- .../DashboardQueryRunner/SnapshotWorker.ts | 4 +- .../UnifiedAlertStatesWorker.test.ts | 12 +- .../UnifiedAlertStatesWorker.ts | 12 +- .../state/DashboardQueryRunner/testHelpers.ts | 4 +- .../query/state/DashboardQueryRunner/types.ts | 1 + .../query/state/DashboardQueryRunner/utils.ts | 4 +- .../query/state/PanelQueryRunner.test.ts | 7 +- .../features/query/state/PanelQueryRunner.ts | 20 +- .../app/features/query/state/QueryRunner.ts | 8 +- .../query/state/mergePanelAndDashData.test.ts | 6 +- .../query/state/mergePanelAndDashData.ts | 6 +- .../query/state/processing/canceler.ts | 3 +- .../query/state/queryAnalytics.test.ts | 6 +- .../features/query/state/queryAnalytics.ts | 3 +- .../features/query/state/runRequest.test.ts | 11 +- public/app/features/query/state/runRequest.ts | 10 +- .../query/state/updateQueries.test.ts | 1 + .../app/features/sandbox/BenchmarksPage.tsx | 3 +- public/app/features/sandbox/TestStuffPage.tsx | 16 +- .../features/search/components/ActionRow.tsx | 8 +- .../search/components/ConfirmDeleteModal.tsx | 6 +- .../search/components/DashboardActions.tsx | 1 + .../search/components/DashboardListPage.tsx | 13 +- .../components/DashboardSearch.test.tsx | 14 +- .../search/components/DashboardSearch.tsx | 13 +- .../search/components/ManageDashboards.tsx | 19 +- .../search/components/MoveToFolderModal.tsx | 10 +- .../components/PreviewsSystemRequirements.tsx | 7 +- .../features/search/components/SearchCard.tsx | 9 +- .../search/components/SearchCardExpanded.tsx | 5 +- .../search/components/SearchCheckbox.tsx | 1 + .../search/components/SearchField.tsx | 6 +- .../search/components/SearchItem.test.tsx | 6 +- .../features/search/components/SearchItem.tsx | 11 +- .../search/components/SearchResults.test.tsx | 6 +- .../search/components/SearchResults.tsx | 13 +- .../components/SearchResultsFilter.test.tsx | 7 +- .../search/components/SearchResultsFilter.tsx | 7 +- .../search/components/SearchWrapper.tsx | 5 +- .../search/components/SectionHeader.tsx | 8 +- .../search/hooks/useDashboardSearch.ts | 13 +- .../search/hooks/useManageDashboards.test.ts | 14 +- .../search/hooks/useManageDashboards.ts | 13 +- public/app/features/search/hooks/useSearch.ts | 4 +- .../features/search/hooks/useSearchQuery.ts | 6 +- .../search/hooks/useShowDashboardPreviews.ts | 6 +- public/app/features/search/loaders.ts | 1 + .../app/features/search/page/SearchPage.tsx | 22 +- .../app/features/search/page/table/Table.tsx | 8 +- .../features/search/page/table/columns.tsx | 6 +- .../search/reducers/dashboardSearch.test.ts | 3 +- .../search/reducers/dashboardSearch.ts | 1 + .../search/reducers/manageDashboards.test.ts | 5 +- .../search/reducers/manageDashboards.ts | 3 +- .../search/reducers/searchQueryReducer.ts | 1 + public/app/features/search/service/backend.ts | 9 +- .../features/search/service/minisearcher.ts | 6 +- public/app/features/search/types.ts | 2 + public/app/features/search/utils.test.ts | 4 +- public/app/features/search/utils.ts | 9 +- .../CreateServiceAccountTokenModal.tsx | 3 +- .../ServiceAccountCreatePage.tsx | 10 +- .../serviceaccounts/ServiceAccountPage.tsx | 18 +- .../serviceaccounts/ServiceAccountProfile.tsx | 8 +- .../serviceaccounts/ServiceAccountRoleRow.tsx | 10 +- .../ServiceAccountTokensTable.tsx | 13 +- .../ServiceAccountsListItem.tsx | 5 +- .../ServiceAccountsListPage.tsx | 19 +- .../features/serviceaccounts/state/actions.ts | 15 +- public/app/features/teams/CreateTeam.test.tsx | 3 +- public/app/features/teams/CreateTeam.tsx | 9 +- .../app/features/teams/TeamGroupSync.test.tsx | 6 +- public/app/features/teams/TeamGroupSync.tsx | 16 +- public/app/features/teams/TeamList.test.tsx | 15 +- public/app/features/teams/TeamList.tsx | 23 +- .../app/features/teams/TeamMemberRow.test.tsx | 11 +- public/app/features/teams/TeamMemberRow.tsx | 14 +- .../app/features/teams/TeamMembers.test.tsx | 13 +- public/app/features/teams/TeamMembers.tsx | 14 +- public/app/features/teams/TeamPages.test.tsx | 13 +- public/app/features/teams/TeamPages.tsx | 24 +- public/app/features/teams/TeamPermissions.tsx | 4 +- .../app/features/teams/TeamSettings.test.tsx | 3 +- public/app/features/teams/TeamSettings.tsx | 7 +- public/app/features/teams/state/actions.ts | 8 +- public/app/features/teams/state/navModel.ts | 6 +- .../app/features/teams/state/reducers.test.ts | 7 +- .../features/teams/state/selectors.test.ts | 8 +- public/app/features/teams/state/selectors.ts | 2 +- .../app/features/templating/formatRegistry.ts | 8 +- .../features/templating/template_srv.mock.ts | 3 +- .../features/templating/template_srv.test.ts | 16 +- .../app/features/templating/template_srv.ts | 13 +- .../FilterByValueFilterEditor.tsx | 4 +- .../FilterByValueTransformerEditor.tsx | 7 +- .../ValueMatchers/BasicMatcherEditor.tsx | 4 +- .../ValueMatchers/NoopMatcherEditor.tsx | 4 +- .../ValueMatchers/RangeMatcherEditor.tsx | 4 +- .../ValueMatchers/utils.ts | 3 +- .../ValueMatchers/valueMatchersUI.ts | 1 + .../HeatmapTransformerEditor.tsx | 6 +- .../calculateHeatmap/editor/AxisEditor.tsx | 2 + .../calculateHeatmap/editor/helper.ts | 1 + .../calculateHeatmap/heatmap.test.ts | 1 + .../transformers/calculateHeatmap/heatmap.ts | 4 +- .../ConfigFromQueryTransformerEditor.test.tsx | 6 +- .../ConfigFromQueryTransformerEditor.tsx | 7 +- .../configFromQuery/configFromQuery.test.ts | 2 + .../configFromQuery/configFromQuery.ts | 2 + .../CalculateFieldTransformerEditor.tsx | 6 +- .../editors/ConcatenateTransformerEditor.tsx | 3 +- .../ConvertFieldTypeTransformerEditor.tsx | 5 +- .../editors/FilterByNameTransformerEditor.tsx | 5 +- .../FilterByRefIdTransformerEditor.tsx | 4 +- .../editors/GroupByTransformerEditor.tsx | 7 +- .../GroupingToMatrixTransformerEditor.tsx | 2 + .../editors/HistogramTransformerEditor.tsx | 2 +- .../LabelsToFieldsTransformerEditor.tsx | 4 +- .../editors/MergeTransformerEditor.tsx | 4 +- .../OrganizeFieldsTransformerEditor.tsx | 7 +- .../editors/ReduceTransformerEditor.tsx | 4 +- .../editors/RenameByRegexTransformer.tsx | 5 +- .../SeriesToFieldsTransformerEditor.tsx | 3 +- .../editors/SeriesToRowsTransformerEditor.tsx | 1 + .../editors/SortByTransformerEditor.tsx | 4 +- .../ExtractFieldsTransformerEditor.tsx | 3 +- .../extractFields/extractFields.test.ts | 1 + .../extractFields/extractFields.ts | 6 +- .../FieldToConfigMappingEditor.test.tsx | 6 +- .../FieldToConfigMappingEditor.tsx | 6 +- .../fieldToConfigMapping.ts | 3 +- .../FieldLookupTransformerEditor.tsx | 5 +- .../lookupGazetteer/fieldLookup.test.ts | 1 + .../lookupGazetteer/fieldLookup.ts | 3 +- .../PrepareTimeSeriesEditor.tsx | 10 +- .../prepareTimeSeries.test.ts | 1 + .../prepareTimeSeries/prepareTimeSeries.ts | 3 +- .../RowsToFieldsTransformerEditor.test.tsx | 6 +- .../RowsToFieldsTransformerEditor.tsx | 5 +- .../rowsToFields/rowsToFields.test.ts | 1 + .../transformers/rowsToFields/rowsToFields.ts | 2 + .../spatial/SpatialTransformerEditor.tsx | 13 +- .../transformers/spatial/optionsHelper.tsx | 7 +- .../spatial/spatialTransformer.ts | 4 +- .../features/transformers/spatial/utils.ts | 4 +- .../transformers/standardTransformers.ts | 41 +- public/app/features/transformers/utils.ts | 3 +- .../app/features/users/TokenRevokedModal.tsx | 5 +- .../features/users/UsersActionBar.test.tsx | 5 +- public/app/features/users/UsersActionBar.tsx | 9 +- .../app/features/users/UsersListPage.test.tsx | 11 +- public/app/features/users/UsersListPage.tsx | 16 +- public/app/features/users/UsersTable.test.tsx | 10 +- public/app/features/users/UsersTable.tsx | 12 +- public/app/features/users/state/actions.ts | 8 +- .../app/features/users/state/reducers.test.ts | 3 +- public/app/features/users/state/reducers.ts | 2 +- public/app/features/variables/adapters.ts | 3 +- .../adhoc/AdHocVariableEditor.test.tsx | 6 +- .../variables/adhoc/AdHocVariableEditor.tsx | 14 +- .../features/variables/adhoc/actions.test.ts | 19 +- .../app/features/variables/adhoc/actions.ts | 21 +- .../app/features/variables/adhoc/adapter.ts | 9 +- .../adhoc/picker/AdHocFilter.test.tsx | 8 +- .../variables/adhoc/picker/AdHocFilter.tsx | 6 +- .../adhoc/picker/AdHocFilterBuilder.tsx | 4 +- .../variables/adhoc/picker/AdHocFilterKey.tsx | 6 +- .../adhoc/picker/AdHocFilterRenderer.tsx | 6 +- .../adhoc/picker/AdHocFilterValue.tsx | 6 +- .../variables/adhoc/picker/AdHocPicker.tsx | 7 +- .../adhoc/picker/OperatorSegment.tsx | 3 +- .../features/variables/adhoc/reducer.test.ts | 8 +- .../app/features/variables/adhoc/reducer.ts | 3 +- .../variables/adhoc/urlParser.test.ts | 5 +- .../app/features/variables/adhoc/urlParser.ts | 5 +- .../constant/ConstantVariableEditor.tsx | 5 +- .../variables/constant/actions.test.ts | 13 +- .../features/variables/constant/actions.ts | 8 +- .../features/variables/constant/adapter.ts | 12 +- .../variables/constant/reducer.test.ts | 5 +- .../features/variables/constant/reducer.ts | 4 +- .../variables/custom/CustomVariableEditor.tsx | 14 +- .../features/variables/custom/actions.test.ts | 13 +- .../app/features/variables/custom/actions.ts | 8 +- .../app/features/variables/custom/adapter.ts | 14 +- .../features/variables/custom/reducer.test.ts | 7 +- .../app/features/variables/custom/reducer.ts | 4 +- .../DataSourceVariableEditor.test.tsx | 7 +- .../datasource/DataSourceVariableEditor.tsx | 18 +- .../variables/datasource/actions.test.ts | 19 +- .../features/variables/datasource/actions.ts | 16 +- .../features/variables/datasource/adapter.ts | 14 +- .../variables/datasource/reducer.test.ts | 12 +- .../features/variables/datasource/reducer.ts | 5 +- .../editor/LegacyVariableQueryEditor.tsx | 8 +- .../editor/SelectionOptionsEditor.tsx | 12 +- .../editor/VariableEditorContainer.tsx | 10 +- .../variables/editor/VariableEditorEditor.tsx | 38 +- .../variables/editor/VariableEditorList.tsx | 12 +- .../editor/VariableEditorListRow.tsx | 7 +- .../variables/editor/VariableHideSelect.tsx | 1 + .../editor/VariableSectionHeader.tsx | 7 +- .../variables/editor/VariableSelectField.tsx | 7 +- .../variables/editor/VariableSwitchField.tsx | 1 + .../editor/VariableTextAreaField.tsx | 7 +- .../variables/editor/VariableTextField.tsx | 1 + .../variables/editor/VariableTypeSelect.tsx | 3 +- .../editor/VariableValuesPreview.tsx | 8 +- .../features/variables/editor/actions.test.ts | 7 +- .../app/features/variables/editor/actions.ts | 5 +- .../editor/getVariableQueryEditor.test.tsx | 3 +- .../editor/getVariableQueryEditor.tsx | 6 +- .../features/variables/editor/reducer.test.ts | 3 +- .../app/features/variables/editor/reducer.ts | 4 +- .../variables/editor/selectors.test.ts | 15 +- .../getAllVariableValuesForUrl.test.ts | 8 +- .../variables/getAllVariableValuesForUrl.ts | 1 + public/app/features/variables/guard.test.ts | 7 +- public/app/features/variables/guard.ts | 3 +- .../variables/inspect/NetworkGraph.tsx | 1 + .../variables/inspect/NetworkGraphModal.tsx | 3 +- .../inspect/VariableUsagesButton.tsx | 7 +- .../inspect/VariablesDependenciesButton.tsx | 8 +- .../inspect/VariablesUnknownButton.tsx | 4 +- .../inspect/VariablesUnknownTable.test.tsx | 8 +- .../inspect/VariablesUnknownTable.tsx | 8 +- .../variables/inspect/reducer.test.ts | 3 +- .../app/features/variables/inspect/reducer.ts | 3 +- .../features/variables/inspect/utils.test.ts | 12 +- .../app/features/variables/inspect/utils.ts | 9 +- .../interval/IntervalVariableEditor.tsx | 15 +- .../variables/interval/actions.test.ts | 30 +- .../features/variables/interval/actions.ts | 11 +- .../features/variables/interval/adapter.ts | 12 +- .../variables/interval/reducer.test.ts | 7 +- .../features/variables/interval/reducer.ts | 5 +- .../OptionsPicker/OptionPicker.test.tsx | 14 +- .../pickers/OptionsPicker/OptionsPicker.tsx | 30 +- .../pickers/OptionsPicker/actions.test.ts | 32 +- .../pickers/OptionsPicker/actions.ts | 13 +- .../pickers/OptionsPicker/reducer.test.ts | 8 +- .../pickers/OptionsPicker/reducer.ts | 7 +- .../variables/pickers/PickerRenderer.tsx | 6 +- .../pickers/shared/VariableInput.tsx | 1 + .../variables/pickers/shared/VariableLink.tsx | 7 +- .../pickers/shared/VariableOptions.tsx | 5 +- .../query/QueryVariableEditor.test.tsx | 18 +- .../variables/query/QueryVariableEditor.tsx | 28 +- .../query/QueryVariableRefreshSelect.tsx | 2 + .../query/QueryVariableSortSelect.tsx | 2 + .../query/VariableQueryRunner.test.ts | 16 +- .../variables/query/VariableQueryRunner.ts | 16 +- .../features/variables/query/actions.test.tsx | 46 +- .../app/features/variables/query/actions.ts | 20 +- .../app/features/variables/query/adapter.ts | 13 +- .../variables/query/operators.test.ts | 9 +- .../app/features/variables/query/operators.ts | 12 +- .../variables/query/queryRunners.test.ts | 9 +- .../features/variables/query/queryRunners.ts | 5 +- .../features/variables/query/reducer.test.ts | 12 +- .../app/features/variables/query/reducer.ts | 6 +- .../query/variableQueryObserver.test.ts | 4 +- .../variables/query/variableQueryObserver.ts | 1 + .../variables/shared/formatVariable.ts | 1 + .../variables/shared/multiOptions.test.ts | 1 + .../shared/testing/adHocVariableBuilder.ts | 1 + .../variables/shared/testing/builders.ts | 15 +- .../testing/datasourceVariableBuilder.ts | 3 +- .../shared/testing/intervalVariableBuilder.ts | 3 +- .../shared/testing/multiVariableBuilder.ts | 1 + .../shared/testing/optionsVariableBuilder.ts | 1 + .../shared/testing/queryVariableBuilder.ts | 2 +- .../shared/testing/textboxVariableBuilder.ts | 1 + .../shared/testing/variableBuilder.ts | 1 + .../features/variables/state/actions.test.ts | 62 +- .../app/features/variables/state/actions.ts | 94 +-- .../app/features/variables/state/helpers.ts | 13 +- .../state/initVariableTransaction.test.ts | 38 +- .../state/keyedVariablesReducer.test.ts | 7 +- .../variables/state/keyedVariablesReducer.ts | 6 +- ...igrateVariablesDatasourceNameToRef.test.ts | 12 +- .../state/onTimeRangeUpdated.test.ts | 27 +- .../variables/state/processVariable.test.ts | 23 +- .../features/variables/state/reducers.test.ts | 8 +- .../app/features/variables/state/reducers.ts | 8 +- .../app/features/variables/state/selectors.ts | 8 +- .../variables/state/setOptionFromUrl.test.ts | 13 +- .../variables/state/sharedReducer.test.ts | 22 +- .../features/variables/state/sharedReducer.ts | 7 +- .../state/templateVarsChangedInUrl.test.ts | 17 +- .../state/transactionReducer.test.ts | 3 +- .../variables/state/transactionReducer.ts | 4 +- .../state/upgradeLegacyQueries.test.ts | 12 +- .../variables/state/variablesReducer.ts | 8 +- .../app/features/variables/system/adapter.ts | 5 +- .../textbox/TextBoxVariableEditor.tsx | 7 +- .../textbox/TextBoxVariablePicker.tsx | 13 +- .../variables/textbox/actions.test.ts | 20 +- .../app/features/variables/textbox/actions.ts | 20 +- .../variables/textbox/adapter.test.ts | 3 +- .../app/features/variables/textbox/adapter.ts | 13 +- .../variables/textbox/reducer.test.ts | 8 +- .../app/features/variables/textbox/reducer.ts | 4 +- public/app/features/variables/types.ts | 1 + public/app/features/variables/utils.test.ts | 5 +- public/app/features/variables/utils.ts | 14 +- .../datasource/alertmanager/ConfigEditor.tsx | 4 +- .../datasource/alertmanager/DataSource.ts | 2 + .../plugins/datasource/alertmanager/module.ts | 1 + .../CloudMonitoringMetricFindQuery.ts | 6 +- .../components/Aggregation.test.tsx | 11 +- .../components/Aggregation.tsx | 8 +- .../cloud-monitoring/components/AliasBy.tsx | 6 +- .../cloud-monitoring/components/Alignment.tsx | 6 +- .../components/AlignmentFunction.tsx | 3 +- .../components/AlignmentPeriod.tsx | 3 +- .../components/AlignmentPeriodLabel.tsx | 2 + .../components/AnnotationQueryEditor.tsx | 4 +- .../components/CloudMonitoringCheatSheet.tsx | 6 +- .../components/ConfigEditor/ConfigEditor.tsx | 4 +- .../cloud-monitoring/components/Fields.tsx | 3 +- .../cloud-monitoring/components/GroupBy.tsx | 8 +- .../components/LabelFilter.tsx | 10 +- .../components/MQLQueryEditor.tsx | 1 + .../components/MetricQueryEditor.tsx | 7 +- .../cloud-monitoring/components/Metrics.tsx | 10 +- .../components/Preprocessor.tsx | 5 +- .../cloud-monitoring/components/Project.tsx | 8 +- .../components/QueryEditor.tsx | 7 +- .../cloud-monitoring/components/SLO/SLO.tsx | 3 +- .../components/SLO/SLOQueryEditor.tsx | 6 +- .../components/SLO/Selector.tsx | 3 +- .../components/SLO/Service.tsx | 3 +- .../components/VariableQueryEditor.test.tsx | 9 +- .../components/VariableQueryEditor.tsx | 7 +- .../components/VisualMetricQueryEditor.tsx | 6 +- .../datasource/cloud-monitoring/constants.ts | 3 +- .../datasource/cloud-monitoring/datasource.ts | 5 +- .../datasource/cloud-monitoring/functions.ts | 3 +- .../datasource/cloud-monitoring/module.ts | 8 +- .../cloud-monitoring/specs/datasource.test.ts | 13 +- .../datasource/cloud-monitoring/variables.ts | 5 +- .../__mocks__/CloudWatchDataSource.ts | 3 +- .../cloudwatch/__mocks__/monarch/Monaco.ts | 1 + .../cloudwatch/annotations_query_ctrl.ts | 1 + .../cloudwatch-sql/SQLGenerator.test.ts | 6 +- .../cloudwatch/cloudwatch-sql/SQLGenerator.ts | 3 +- .../completion/CompletionItemProvider.ts | 17 +- .../completion/statementPosition.test.ts | 8 +- .../completion/statementPosition.ts | 3 +- .../completion/tokenUtils.test.ts | 12 +- .../cloudwatch-sql/completion/tokenUtils.ts | 1 + .../cloudwatch/components/Alias.tsx | 3 +- .../components/AnnotationQueryEditor.test.tsx | 5 +- .../components/AnnotationQueryEditor.tsx | 3 + .../cloudwatch/components/CloudWatchLink.tsx | 3 +- .../components/ConfigEditor.test.tsx | 4 +- .../cloudwatch/components/ConfigEditor.tsx | 13 +- .../components/Dimensions/Dimensions.test.tsx | 7 +- .../components/Dimensions/Dimensions.tsx | 3 + .../components/Dimensions/FilterItem.tsx | 5 +- .../cloudwatch/components/Forms.tsx | 1 + .../cloudwatch/components/LogsCheatSheet.tsx | 14 +- .../cloudwatch/components/LogsQueryEditor.tsx | 6 +- .../components/LogsQueryField.test.tsx | 18 +- .../cloudwatch/components/LogsQueryField.tsx | 32 +- .../components/MathExpressionQueryField.tsx | 12 +- .../cloudwatch/components/MetaInspector.tsx | 4 +- .../MetricStatEditor.test.tsx | 7 +- .../MetricStatEditor/MetricStatEditor.tsx | 4 +- .../components/MetricsQueryEditor.test.tsx | 11 +- .../components/MetricsQueryEditor.tsx | 6 +- .../components/MetricsQueryHeader.test.tsx | 6 +- .../components/MetricsQueryHeader.tsx | 2 +- .../components/PanelQueryEditor.tsx | 7 +- .../components/QueryHeader.test.tsx | 6 +- .../cloudwatch/components/QueryHeader.tsx | 6 +- .../SQLBuilderEditor.test.tsx | 7 +- .../SQLBuilderEditor/SQLBuilderEditor.tsx | 3 + .../SQLBuilderSelectRow.test.tsx | 9 +- .../SQLBuilderEditor/SQLBuilderSelectRow.tsx | 3 + .../components/SQLBuilderEditor/SQLFilter.tsx | 3 + .../SQLBuilderEditor/SQLGroupBy.test.tsx | 6 +- .../SQLBuilderEditor/SQLGroupBy.tsx | 3 + .../SQLBuilderEditor/SQLOrderByGroup.tsx | 3 + .../components/SQLBuilderEditor/utils.ts | 3 +- .../cloudwatch/components/SQLCodeEditor.tsx | 6 +- .../VariableQueryEditor.test.tsx | 4 +- .../VariableQueryEditor.tsx | 10 +- .../VariableQueryField.tsx | 4 +- .../VariableQueryEditor/VariableTextField.tsx | 3 +- .../cloudwatch/components/XrayLinkConfig.tsx | 8 +- .../datasource/cloudwatch/datasource.test.ts | 5 +- .../datasource/cloudwatch/datasource.ts | 9 +- .../plugins/datasource/cloudwatch/hooks.ts | 10 +- .../cloudwatch/language_provider.test.ts | 12 +- .../cloudwatch/language_provider.ts | 5 +- .../completion/CompletionItemProvider.test.ts | 10 +- .../completion/CompletionItemProvider.ts | 12 +- .../completion/statementPosition.test.ts | 6 +- .../completion/statementPosition.ts | 1 + .../datasource/cloudwatch/migration.test.ts | 1 + .../datasource/cloudwatch/migrations.ts | 1 + .../plugins/datasource/cloudwatch/module.tsx | 13 +- .../monarch/CompletionItemProvider.ts | 5 +- .../cloudwatch/monarch/LinkedToken.ts | 1 + .../monarch/linkedTokenBuilder.test.ts | 10 +- .../cloudwatch/monarch/linkedTokenBuilder.ts | 2 +- .../datasource/cloudwatch/monarch/register.ts | 6 +- .../cloudwatch/specs/datasource.test.ts | 20 +- .../plugins/datasource/cloudwatch/syntax.ts | 1 + .../plugins/datasource/cloudwatch/types.ts | 2 +- .../cloudwatch/utils/datalinks.test.ts | 3 +- .../datasource/cloudwatch/utils/datalinks.ts | 5 +- .../cloudwatch/utils/logsRetry.test.ts | 7 +- .../datasource/cloudwatch/utils/logsRetry.ts | 6 +- .../datasource/cloudwatch/utils/utils.ts | 1 + .../datasource/cloudwatch/variables.test.ts | 2 +- .../datasource/cloudwatch/variables.ts | 7 +- .../dashboard/DashboardQueryEditor.test.tsx | 12 +- .../dashboard/DashboardQueryEditor.tsx | 13 +- .../dashboard/DashboardQueryRow.tsx | 5 +- .../datasource/dashboard/datasource.ts | 1 + .../plugins/datasource/dashboard/module.ts | 3 +- .../dashboard/runSharedRequest.test.ts | 3 +- .../datasource/dashboard/runSharedRequest.ts | 8 +- .../components/AddRemove.test.tsx | 3 +- .../elasticsearch/components/AddRemove.tsx | 1 + .../elasticsearch/components/IconButton.tsx | 3 +- .../elasticsearch/components/MetricPicker.tsx | 5 +- .../BucketAggregationEditor.tsx | 7 +- .../DateHistogramSettingsEditor.tsx | 17 +- .../FiltersSettingsEditor/index.tsx | 9 +- .../FiltersSettingsEditor/state/actions.ts | 1 + .../state/reducer.test.ts | 2 + .../FiltersSettingsEditor/state/reducer.ts | 2 + .../TermsSettingsEditor.test.tsx | 9 +- .../SettingsEditor/TermsSettingsEditor.tsx | 21 +- .../SettingsEditor/index.tsx | 13 +- .../BucketAggregationsEditor/index.tsx | 10 +- .../BucketAggregationsEditor/state/actions.ts | 1 + .../state/reducer.test.ts | 9 +- .../BucketAggregationsEditor/state/reducer.ts | 14 +- .../BucketAggregationsEditor/utils.ts | 6 +- .../ElasticsearchQueryContext.test.tsx | 13 +- .../QueryEditor/ElasticsearchQueryContext.tsx | 6 +- .../MetricEditor.test.tsx | 17 +- .../MetricAggregationsEditor/MetricEditor.tsx | 21 +- .../BucketScriptSettingsEditor/index.tsx | 19 +- .../state/reducer.test.ts | 2 + .../state/reducer.ts | 2 + .../MovingAverageSettingsEditor.tsx | 5 +- .../SettingsEditor/SettingField.tsx | 8 +- .../TopMetricsSettingsEditor.tsx | 12 +- .../SettingsEditor/index.test.tsx | 11 +- .../SettingsEditor/index.tsx | 25 +- .../MetricAggregationsEditor/index.tsx | 12 +- .../MetricAggregationsEditor/state/actions.ts | 1 + .../state/reducer.test.ts | 15 +- .../MetricAggregationsEditor/state/reducer.ts | 2 + .../MetricAggregationsEditor/styles.ts | 3 +- .../MetricAggregationsEditor/utils.ts | 9 +- .../components/QueryEditor/QueryEditorRow.tsx | 5 +- .../QueryEditor/SettingsEditorContainer.tsx | 6 +- .../components/QueryEditor/index.test.tsx | 6 +- .../components/QueryEditor/index.tsx | 27 +- .../components/QueryEditor/state.test.ts | 2 + .../components/QueryEditor/state.ts | 1 + ...CreatableSelectPersistedBehaviour.test.tsx | 8 +- .../useCreatableSelectPersistedBehaviour.ts | 3 +- .../configuration/ConfigEditor.test.tsx | 6 +- .../configuration/ConfigEditor.tsx | 9 +- .../elasticsearch/configuration/DataLink.tsx | 9 +- .../configuration/DataLinks.test.tsx | 10 +- .../elasticsearch/configuration/DataLinks.tsx | 7 +- .../configuration/ElasticDetails.test.tsx | 5 +- .../configuration/ElasticDetails.tsx | 9 +- .../configuration/LogsConfig.test.tsx | 3 +- .../configuration/LogsConfig.tsx | 2 + .../elasticsearch/configuration/mocks.ts | 3 +- .../elasticsearch/configuration/utils.ts | 5 +- .../elasticsearch/datasource.test.ts | 10 +- .../datasource/elasticsearch/datasource.ts | 32 +- .../elasticsearch/elastic_response.ts | 12 +- .../elasticsearch/hooks/useFields.test.tsx | 21 +- .../elasticsearch/hooks/useFields.ts | 2 + .../elasticsearch/hooks/useNextId.test.tsx | 11 +- .../elasticsearch/hooks/useNextId.ts | 3 +- .../hooks/useStatelessReducer.test.tsx | 3 +- .../hooks/useStatelessReducer.ts | 2 +- .../datasource/elasticsearch/index_pattern.ts | 1 + .../elasticsearch/language_provider.test.ts | 8 +- .../datasource/elasticsearch/module.ts | 5 +- .../datasource/elasticsearch/query_builder.ts | 4 +- .../specs/elastic_response.test.ts | 5 +- .../elasticsearch/specs/index_pattern.test.ts | 3 +- .../elasticsearch/specs/query_builder.test.ts | 1 + .../elasticsearch/test-helpers/render.tsx | 6 +- .../plugins/datasource/elasticsearch/types.ts | 1 + .../plugins/datasource/elasticsearch/utils.ts | 3 +- .../__mocks__/instanceSettings.ts | 1 + .../azure_log_analytics_datasource.test.ts | 1 + .../azure_log_analytics_datasource.ts | 8 +- .../azure_log_analytics/response_parser.ts | 3 +- .../azure_monitor/azure_monitor_datasource.ts | 4 +- .../azure_monitor/response_parser.ts | 1 + .../azure_resource_graph_datasource.test.ts | 12 +- .../azure_resource_graph_datasource.ts | 4 +- .../ArgQueryEditor/ArgQueryEditor.tsx | 7 +- .../components/ArgQueryEditor/QueryField.tsx | 4 +- .../components/AzureCredentialsForm.test.tsx | 3 +- .../components/AzureCredentialsForm.tsx | 4 +- .../components/ConfigEditor.test.tsx | 1 + .../components/ConfigEditor.tsx | 6 +- .../components/Field.tsx | 3 +- .../LogsQueryEditor/FormatAsField.tsx | 3 + .../LogsQueryEditor/LogsQueryEditor.tsx | 13 +- .../components/LogsQueryEditor/QueryField.tsx | 6 +- .../LogsQueryEditor/useMigrations.ts | 3 +- .../MetricsQueryEditor/AggregationField.tsx | 8 +- .../MetricsQueryEditor/DimensionFields.tsx | 4 +- .../MetricsQueryEditor/LegendFormatField.tsx | 4 +- .../MetricsQueryEditor/MetricNameField.tsx | 8 +- .../MetricNamespaceField.test.tsx | 8 +- .../MetricNamespaceField.tsx | 8 +- .../MetricsQueryEditor.test.tsx | 9 +- .../MetricsQueryEditor/MetricsQueryEditor.tsx | 14 +- .../ResourceGroupsField.tsx | 8 +- .../MetricsQueryEditor/ResourceNameField.tsx | 8 +- .../MetricsQueryEditor/ResourceTypeField.tsx | 8 +- .../MetricsQueryEditor/TimeGrainField.tsx | 8 +- .../MetricsQueryEditor/TopField.tsx | 4 +- .../MetricsQueryEditor/dataHooks.test.ts | 1 + .../MetricsQueryEditor/dataHooks.ts | 1 + .../components/MonitorConfig.tsx | 7 +- .../MetricsQueryEditor.test.tsx | 8 +- .../MetricsQueryEditor.tsx | 13 +- .../NewMetricsQueryEditor/dataHooks.test.ts | 1 + .../QueryEditor/QueryEditor.test.tsx | 6 +- .../components/QueryEditor/QueryEditor.tsx | 15 +- .../components/QueryEditor/QueryTypeField.tsx | 7 +- .../QueryEditor/usePreparedQuery.ts | 7 +- .../ResourceField/ResourceField.tsx | 3 +- .../components/ResourcePicker/EntryIcon.tsx | 3 +- .../ResourcePicker/NestedEntry.test.tsx | 1 + .../components/ResourcePicker/NestedEntry.tsx | 4 +- .../ResourcePicker/NestedResourceTable.tsx | 2 +- .../components/ResourcePicker/NestedRow.tsx | 3 +- .../components/ResourcePicker/NestedRows.tsx | 2 +- .../ResourcePicker/ResourcePicker.test.tsx | 4 +- .../ResourcePicker/ResourcePicker.tsx | 4 +- .../components/ResourcePicker/styles.ts | 1 + .../components/ResourcePicker/utils.ts | 1 + .../components/Space.tsx | 3 +- .../components/SubscriptionField.tsx | 2 + .../VariableEditor/VariableEditor.test.tsx | 11 +- .../VariableEditor/VariableEditor.tsx | 12 +- .../app_insights_datasource.test.ts | 5 +- .../app_insights/app_insights_datasource.ts | 4 +- .../app_insights/response_parser.ts | 1 + .../deprecated/components/AnalyticsConfig.tsx | 3 +- .../ApplicationInsightsEditor/index.tsx | 3 +- .../InsightsAnalyticsEditor/index.tsx | 3 +- .../components/InsightsConfig.test.tsx | 4 +- .../deprecated/components/InsightsConfig.tsx | 3 +- .../components/deprecated/utils.tsx | 3 +- .../datasource.ts | 7 +- .../grafanaTemplateVariableFns.ts | 4 +- .../grafanaTemplateVariables.test.ts | 2 +- .../log_analytics/querystring_builder.test.ts | 3 +- .../module.ts | 3 +- .../resourcePicker/resourcePickerData.test.ts | 3 +- .../time_grain_converter.ts | 1 + .../types/query.ts | 1 + .../types/types.ts | 1 + .../utils/common.test.ts | 1 + .../utils/common.ts | 2 + .../utils/messageFromError.test.ts | 1 + .../utils/migrateAnnotation.test.ts | 2 + .../utils/migrateAnnotation.ts | 3 +- .../utils/migrateQuery.test.ts | 1 + .../utils/migrateQuery.ts | 2 +- .../utils/useAsyncState.test.ts | 1 + .../utils/useLastError.test.ts | 1 + .../utils/useLastError.ts | 2 + .../variables.test.ts | 3 +- .../variables.ts | 3 +- .../components/AnnotationQueryEditor.test.tsx | 3 +- .../components/AnnotationQueryEditor.tsx | 7 +- .../grafana/components/QueryEditor.tsx | 6 +- .../datasource/grafana/datasource.test.ts | 2 +- .../plugins/datasource/grafana/datasource.ts | 28 +- .../app/plugins/datasource/grafana/module.ts | 3 +- .../components/AddGraphiteFunction.tsx | 9 +- .../components/FunctionEditor.test.tsx | 6 +- .../graphite/components/FunctionEditor.tsx | 11 +- .../components/FunctionEditorControls.tsx | 2 + .../components/FunctionParamEditor.tsx | 7 +- .../graphite/components/FunctionsSection.tsx | 9 +- .../components/GraphiteFunctionEditor.tsx | 15 +- .../components/GraphiteQueryEditor.tsx | 9 +- .../components/GraphiteTextEditor.tsx | 2 + .../graphite/components/MetricSegment.tsx | 16 +- .../components/MetricTankMetaInspector.tsx | 8 +- .../graphite/components/MetricsSection.tsx | 4 +- .../graphite/components/PlayButton.tsx | 2 + .../graphite/components/SeriesSection.tsx | 9 +- .../graphite/components/TagEditor.tsx | 8 +- .../graphite/components/TagsSection.tsx | 21 +- .../graphite/components/helpers.test.ts | 3 +- .../datasource/graphite/components/helpers.ts | 7 +- .../graphite/configuration/ConfigEditor.tsx | 15 +- .../configuration/MappingsConfiguration.tsx | 2 + .../graphite/configuration/MappingsHelp.tsx | 3 +- .../datasource/graphite/datasource.test.ts | 13 +- .../plugins/datasource/graphite/datasource.ts | 17 +- .../app/plugins/datasource/graphite/gfunc.ts | 3 +- .../datasource/graphite/graphite_query.ts | 12 +- .../app/plugins/datasource/graphite/meta.ts | 3 +- .../app/plugins/datasource/graphite/module.ts | 7 +- .../graphite/specs/graphite_query.test.ts | 3 +- .../datasource/graphite/specs/store.test.ts | 8 +- .../datasource/graphite/state/actions.ts | 6 +- .../datasource/graphite/state/context.tsx | 11 +- .../datasource/graphite/state/helpers.ts | 8 +- .../datasource/graphite/state/providers.ts | 11 +- .../datasource/graphite/state/store.ts | 17 +- .../app/plugins/datasource/graphite/types.ts | 4 +- .../influxdb/components/ConfigEditor.test.tsx | 3 +- .../influxdb/components/ConfigEditor.tsx | 4 +- .../influxdb/components/FluxQueryEditor.tsx | 10 +- .../influxdb/components/InfluxStartPage.tsx | 2 + .../influxdb/components/QueryEditor.tsx | 11 +- .../components/QueryEditorModeSwitcher.tsx | 1 + .../components/RawInfluxQLEditor.test.tsx | 7 +- .../influxdb/components/RawInfluxQLEditor.tsx | 5 +- .../components/VariableQueryEditor.tsx | 5 +- .../VisualInfluxQLEditor/AddButton.tsx | 2 + .../VisualInfluxQLEditor/Editor.tags.test.tsx | 10 +- .../VisualInfluxQLEditor/Editor.test.tsx | 8 +- .../VisualInfluxQLEditor/Editor.tsx | 25 +- .../VisualInfluxQLEditor/FormatAsSection.tsx | 9 +- .../VisualInfluxQLEditor/FromSection.tsx | 1 + .../VisualInfluxQLEditor/InputSection.tsx | 5 +- .../OrderByTimeSection.tsx | 6 +- .../VisualInfluxQLEditor/PartListSection.tsx | 12 +- .../components/VisualInfluxQLEditor/Seg.tsx | 8 +- .../VisualInfluxQLEditor/TagsSection.test.tsx | 6 +- .../VisualInfluxQLEditor/TagsSection.tsx | 9 +- .../VisualInfluxQLEditor/partListUtils.tsx | 14 +- .../influxdb/components/constants.ts | 1 + .../components/useShadowedState.test.ts | 1 + .../influxdb/components/useUniqueId.test.ts | 1 + .../influxdb/components/useUniqueId.ts | 2 +- .../plugins/datasource/influxdb/datasource.ts | 32 +- .../influxdb/influxQLMetadataQuery.ts | 2 +- .../datasource/influxdb/influx_query_model.ts | 8 +- .../datasource/influxdb/influx_series.ts | 3 +- .../app/plugins/datasource/influxdb/module.ts | 7 +- .../datasource/influxdb/queryUtils.test.ts | 3 +- .../plugins/datasource/influxdb/queryUtils.ts | 1 + .../datasource/influxdb/query_builder.ts | 1 + .../plugins/datasource/influxdb/query_part.ts | 1 + .../datasource/influxdb/response_parser.ts | 4 +- .../influxdb/specs/datasource.test.ts | 7 +- .../influxdb/specs/influx_series.test.ts | 1 + .../influxdb/specs/response_parser.test.ts | 14 +- .../jaeger/components/AdvancedOptions.tsx | 6 +- .../jaeger/components/ConfigEditor.tsx | 3 +- .../jaeger/components/QueryEditor.tsx | 5 +- .../jaeger/components/SearchForm.test.tsx | 21 +- .../jaeger/components/SearchForm.tsx | 11 +- .../datasource/jaeger/datasource.test.ts | 5 +- .../plugins/datasource/jaeger/datasource.ts | 9 +- .../datasource/jaeger/graphTransform.ts | 4 +- .../app/plugins/datasource/jaeger/module.ts | 5 +- .../jaeger/responseTransform.test.ts | 3 +- .../datasource/jaeger/responseTransform.ts | 1 + .../plugins/datasource/jaeger/testResponse.ts | 3 +- .../datasource/loki/add_label_to_query.ts | 4 +- .../loki/backendResultTransformer.test.ts | 3 +- .../loki/backendResultTransformer.ts | 3 +- .../components/AnnotationsQueryEditor.tsx | 8 +- .../loki/components/LokiCheatSheet.tsx | 4 +- .../LokiExploreQueryEditor.test.tsx | 15 +- .../components/LokiExploreQueryEditor.tsx | 4 +- .../loki/components/LokiLabelBrowser.test.tsx | 6 +- .../loki/components/LokiLabelBrowser.tsx | 12 +- .../loki/components/LokiOptionFields.test.tsx | 3 +- .../loki/components/LokiOptionFields.tsx | 5 +- .../loki/components/LokiQueryEditor.test.tsx | 6 +- .../loki/components/LokiQueryEditor.tsx | 3 +- .../components/LokiQueryEditorByApp.test.tsx | 11 +- .../loki/components/LokiQueryEditorByApp.tsx | 11 +- .../components/LokiQueryEditorForAlerting.tsx | 1 + .../loki/components/LokiQueryField.test.tsx | 6 +- .../loki/components/LokiQueryField.tsx | 17 +- .../datasource/loki/components/types.ts | 1 + .../loki/configuration/ConfigEditor.test.tsx | 9 +- .../loki/configuration/ConfigEditor.tsx | 9 +- .../loki/configuration/DebugSection.test.tsx | 6 +- .../loki/configuration/DebugSection.tsx | 11 +- .../loki/configuration/DerivedField.test.tsx | 8 +- .../loki/configuration/DerivedField.tsx | 8 +- .../loki/configuration/DerivedFields.test.tsx | 10 +- .../loki/configuration/DerivedFields.tsx | 9 +- .../loki/configuration/MaxLinesField.tsx | 1 + .../datasource/loki/datasource.test.ts | 17 +- .../app/plugins/datasource/loki/datasource.ts | 35 +- .../datasource/loki/language_provider.test.ts | 6 +- .../datasource/loki/language_provider.ts | 14 +- .../datasource/loki/live_streams.test.ts | 6 +- .../plugins/datasource/loki/live_streams.ts | 8 +- .../datasource/loki/makeTableFrames.test.ts | 1 + .../datasource/loki/makeTableFrames.ts | 3 +- public/app/plugins/datasource/loki/mocks.ts | 6 +- public/app/plugins/datasource/loki/module.ts | 4 +- .../datasource/loki/query_utils.test.ts | 2 +- .../plugins/datasource/loki/query_utils.ts | 1 + .../loki/querybuilder/LokiQueryModeller.ts | 1 + .../querybuilder/binaryScalarOperations.ts | 1 + .../components/LokiQueryBuilder.test.tsx | 9 +- .../components/LokiQueryBuilder.tsx | 15 +- .../LokiQueryBuilderContainer.test.tsx | 9 +- .../components/LokiQueryBuilderContainer.tsx | 8 +- .../components/LokiQueryBuilderExplained.tsx | 8 +- .../LokiQueryBuilderOptions.test.tsx | 8 +- .../components/LokiQueryBuilderOptions.tsx | 10 +- .../components/LokiQueryCodeEditor.tsx | 10 +- .../LokiQueryEditorSelector.test.tsx | 11 +- .../components/LokiQueryEditorSelector.tsx | 11 +- .../querybuilder/components/NestedQuery.tsx | 9 +- .../components/NestedQueryList.tsx | 5 +- .../querybuilder/components/QueryPreview.tsx | 10 +- .../loki/querybuilder/operations.ts | 1 + .../datasource/loki/querybuilder/parsing.ts | 5 +- .../datasource/loki/querybuilder/state.ts | 1 + .../loki/result_transformer.test.ts | 7 +- .../datasource/loki/result_transformer.ts | 7 +- .../datasource/loki/sortDataFrame.test.ts | 1 + .../app/plugins/datasource/loki/streaming.ts | 6 +- .../plugins/datasource/loki/syntax.test.ts | 3 +- public/app/plugins/datasource/loki/syntax.ts | 1 + public/app/plugins/datasource/loki/types.ts | 1 + .../datasource/mixed/MixedDataSource.test.ts | 4 +- .../datasource/mixed/MixedDataSource.ts | 7 +- .../plugins/datasource/mssql/datasource.ts | 7 +- public/app/plugins/datasource/mssql/module.ts | 5 +- .../plugins/datasource/mssql/query_ctrl.ts | 4 +- .../datasource/mssql/specs/datasource.test.ts | 13 +- .../plugins/datasource/mysql/datasource.ts | 12 +- public/app/plugins/datasource/mysql/module.ts | 8 +- .../datasource/mysql/mysql_query_model.ts | 3 +- .../plugins/datasource/mysql/query_ctrl.ts | 19 +- .../datasource/mysql/specs/datasource.test.ts | 8 +- .../opentsdb/components/ConfigEditor.tsx | 7 +- .../opentsdb/components/OpenTsdbDetails.tsx | 9 +- .../plugins/datasource/opentsdb/datasource.ts | 5 +- .../app/plugins/datasource/opentsdb/module.ts | 5 +- .../plugins/datasource/opentsdb/query_ctrl.ts | 5 +- .../opentsdb/specs/datasource.test.ts | 10 +- .../datasource/postgres/config_ctrl.ts | 4 +- .../datasource/postgres/datasource.test.ts | 4 +- .../plugins/datasource/postgres/datasource.ts | 13 +- .../app/plugins/datasource/postgres/module.ts | 5 +- .../postgres/postgres_query_model.ts | 3 +- .../plugins/datasource/postgres/query_ctrl.ts | 18 +- .../postgres/specs/datasource.test.ts | 7 +- .../postgres/specs/postgres_query.test.ts | 3 +- .../prometheus/add_label_to_query.ts | 3 +- .../prometheus/components/PromCheatSheet.tsx | 2 + .../components/PromExemplarField.tsx | 6 +- .../components/PromExploreExtraField.test.tsx | 3 +- .../components/PromExploreExtraField.tsx | 11 +- .../PromExploreQueryEditor.test.tsx | 11 +- .../components/PromExploreQueryEditor.tsx | 5 +- .../prometheus/components/PromLink.test.tsx | 7 +- .../prometheus/components/PromLink.tsx | 3 +- .../components/PromQueryEditor.test.tsx | 8 +- .../prometheus/components/PromQueryEditor.tsx | 7 +- .../components/PromQueryEditorByApp.test.tsx | 11 +- .../components/PromQueryEditorByApp.tsx | 11 +- .../components/PromQueryEditorForAlerting.tsx | 1 + .../components/PromQueryField.test.tsx | 9 +- .../prometheus/components/PromQueryField.tsx | 17 +- .../PrometheusMetricsBrowser.test.tsx | 6 +- .../components/PrometheusMetricsBrowser.tsx | 9 +- .../monaco-query-field/MonacoQueryField.tsx | 12 +- .../MonacoQueryFieldLazy.tsx | 1 + .../MonacoQueryFieldProps.ts | 3 +- .../MonacoQueryFieldWrapper.tsx | 1 + .../monaco-completion-provider/completions.ts | 5 +- .../monaco-completion-provider/index.ts | 2 +- .../monaco-completion-provider/situation.ts | 3 +- .../datasource/prometheus/components/types.ts | 1 + .../configuration/AzureAuthSettings.tsx | 6 +- .../configuration/AzureCredentialsConfig.ts | 1 + .../AzureCredentialsForm.test.tsx | 3 +- .../configuration/AzureCredentialsForm.tsx | 4 +- .../prometheus/configuration/ConfigEditor.tsx | 13 +- .../configuration/ExemplarSetting.tsx | 4 +- .../configuration/ExemplarsSettings.tsx | 5 +- .../configuration/PromSettings.test.tsx | 6 +- .../prometheus/configuration/PromSettings.tsx | 5 +- .../prometheus/configuration/mocks.ts | 3 +- .../datasource/prometheus/datasource.test.ts | 8 +- .../datasource/prometheus/datasource.tsx | 17 +- .../prometheus/language_provider.test.ts | 13 +- .../prometheus/language_provider.ts | 5 +- .../prometheus/language_utils.test.ts | 1 + .../datasource/prometheus/language_utils.ts | 10 +- .../prometheus/metric_find_query.test.ts | 5 +- .../prometheus/metric_find_query.ts | 3 +- .../datasource/prometheus/module.test.ts | 2 +- .../plugins/datasource/prometheus/module.ts | 5 +- .../datasource/prometheus/promql.test.ts | 3 +- .../plugins/datasource/prometheus/promql.ts | 1 + .../datasource/prometheus/query_hints.test.ts | 2 +- .../datasource/prometheus/query_hints.ts | 2 + .../querybuilder/PromQueryModeller.ts | 1 + .../querybuilder/binaryScalarOperations.ts | 10 +- .../components/LabelParamEditor.tsx | 4 +- .../components/MetricSelect.test.tsx | 3 +- .../querybuilder/components/MetricSelect.tsx | 11 +- .../querybuilder/components/NestedQuery.tsx | 7 +- .../components/NestedQueryList.tsx | 5 +- .../components/PromQueryBuilder.test.tsx | 17 +- .../components/PromQueryBuilder.tsx | 21 +- .../PromQueryBuilderContainer.test.tsx | 16 +- .../components/PromQueryBuilderContainer.tsx | 6 +- .../components/PromQueryBuilderExplained.tsx | 8 +- .../components/PromQueryBuilderHints.tsx | 10 +- .../PromQueryBuilderOptions.test.tsx | 9 +- .../components/PromQueryBuilderOptions.tsx | 13 +- .../components/PromQueryCodeEditor.tsx | 12 +- .../PromQueryEditorSelector.test.tsx | 14 +- .../components/PromQueryEditorSelector.tsx | 19 +- .../components/PromQueryLegendEditor.tsx | 4 +- .../querybuilder/components/QueryPreview.tsx | 10 +- .../prometheus/querybuilder/operations.ts | 2 +- .../prometheus/querybuilder/parsing.ts | 19 +- .../shared/AutoSizeInput.test.tsx | 3 +- .../querybuilder/shared/AutoSizeInput.tsx | 3 +- .../querybuilder/shared/FeedbackLink.tsx | 3 +- .../querybuilder/shared/LabelFilterItem.tsx | 6 +- .../querybuilder/shared/LabelFilters.test.tsx | 8 +- .../querybuilder/shared/LabelFilters.tsx | 7 +- .../shared/LokiAndPromQueryModellerBase.ts | 2 + .../querybuilder/shared/OperationEditor.tsx | 7 +- .../shared/OperationExplainedBox.tsx | 3 +- .../querybuilder/shared/OperationHeader.tsx | 4 +- .../shared/OperationInfoButton.tsx | 6 +- .../shared/OperationList.test.tsx | 17 +- .../querybuilder/shared/OperationList.tsx | 9 +- .../shared/OperationListExplained.tsx | 1 + .../shared/OperationParamEditor.tsx | 5 +- .../shared/OperationsEditorRow.tsx | 3 +- .../shared/QueryEditorModeToggle.tsx | 6 +- .../querybuilder/shared/QueryHeaderSwitch.tsx | 5 +- .../querybuilder/shared/QueryOptionGroup.tsx | 5 +- .../querybuilder/shared/operationUtils.ts | 11 +- .../querybuilder/shared/parsingUtils.test.ts | 3 +- .../querybuilder/shared/parsingUtils.ts | 1 + .../prometheus/querybuilder/shared/types.ts | 3 +- .../prometheus/querybuilder/state.test.ts | 1 + .../prometheus/querybuilder/state.ts | 2 + .../prometheus/result_transformer.test.ts | 1 + .../prometheus/result_transformer.ts | 8 +- .../plugins/datasource/prometheus/types.ts | 1 + .../datasource/prometheus/variables.ts | 8 +- .../tempo/QueryEditor/NativeSearch.test.tsx | 8 +- .../tempo/QueryEditor/NativeSearch.tsx | 20 +- .../tempo/QueryEditor/QueryField.tsx | 11 +- .../tempo/QueryEditor/ServiceGraphSection.tsx | 9 +- .../tempo/configuration/ConfigEditor.tsx | 12 +- .../configuration/LokiSearchSettings.tsx | 4 +- .../tempo/configuration/SearchSettings.tsx | 4 +- .../configuration/ServiceGraphSettings.tsx | 4 +- .../datasource/tempo/datasource.test.ts | 5 +- .../plugins/datasource/tempo/datasource.ts | 9 +- .../datasource/tempo/graphTransform.test.ts | 3 +- .../datasource/tempo/graphTransform.ts | 1 + .../datasource/tempo/language_provider.ts | 4 +- public/app/plugins/datasource/tempo/module.ts | 3 +- .../tempo/resultTransformer.test.ts | 4 +- .../datasource/tempo/resultTransformer.ts | 12 +- .../plugins/datasource/tempo/syntax.test.ts | 3 +- .../datasource/testdata/QueryEditor.test.tsx | 5 +- .../datasource/testdata/QueryEditor.tsx | 25 +- .../datasource/testdata/TestInfoTab.tsx | 3 +- .../testdata/components/CSVContentEditor.tsx | 2 + .../testdata/components/CSVFileEditor.tsx | 4 +- .../testdata/components/CSVWaveEditor.tsx | 4 +- .../testdata/components/ErrorEditor.tsx | 4 +- .../testdata/components/GrafanaLiveEditor.tsx | 4 +- .../testdata/components/NodeGraphEditor.tsx | 2 + .../components/PredictablePulseEditor.tsx | 4 +- .../testdata/components/RandomWalkEditor.tsx | 4 +- .../testdata/components/RawFrameEditor.tsx | 10 +- .../components/SimulationQueryEditor.tsx | 4 +- .../components/StreamingClientEditor.tsx | 4 +- .../testdata/components/USAQueryEditor.tsx | 4 +- .../plugins/datasource/testdata/datasource.ts | 9 +- .../plugins/datasource/testdata/module.tsx | 5 +- .../datasource/testdata/nodeGraphUtils.ts | 1 + .../plugins/datasource/testdata/runStreams.ts | 6 +- .../datasource/zipkin/ConfigEditor.tsx | 3 +- .../datasource/zipkin/QueryField.test.tsx | 8 +- .../plugins/datasource/zipkin/QueryField.tsx | 10 +- .../datasource/zipkin/datasource.test.ts | 7 +- .../plugins/datasource/zipkin/datasource.ts | 6 +- .../app/plugins/datasource/zipkin/module.ts | 5 +- .../zipkin/utils/graphTransform.test.ts | 3 +- .../datasource/zipkin/utils/graphTransform.ts | 3 +- .../datasource/zipkin/utils/testData.ts | 1 + .../datasource/zipkin/utils/testResponse.ts | 1 + .../zipkin/utils/transforms.test.ts | 5 +- .../datasource/zipkin/utils/transforms.ts | 4 +- .../plugins/panel/alertGroups/AlertGroup.tsx | 8 +- .../alertGroups/AlertGroupsPanel.test.tsx | 12 +- .../panel/alertGroups/AlertGroupsPanel.tsx | 16 +- .../app/plugins/panel/alertGroups/module.tsx | 6 +- .../panel/alertGroups/useFilteredGroups.ts | 3 +- .../panel/alertlist/AlertInstances.tsx | 14 +- .../app/plugins/panel/alertlist/AlertList.tsx | 14 +- .../alertlist/AlertListMigration.test.ts | 1 + .../alertlist/AlertListMigrationHandler.ts | 1 + .../panel/alertlist/GroupByWithLoading.tsx | 16 +- .../panel/alertlist/UnifiedAlertList.tsx | 22 +- public/app/plugins/panel/alertlist/module.tsx | 15 +- .../plugins/panel/alertlist/suggestions.ts | 1 + .../unified-alerting/GroupedView.tsx | 8 +- .../unified-alerting/UngroupedView.tsx | 6 +- public/app/plugins/panel/alertlist/util.ts | 4 +- .../panel/annolist/AnnoListPanel.test.tsx | 16 +- .../plugins/panel/annolist/AnnoListPanel.tsx | 20 +- .../panel/annolist/AnnotationListItem.tsx | 4 +- public/app/plugins/panel/annolist/module.tsx | 4 +- .../plugins/panel/barchart/BarChartPanel.tsx | 14 +- .../panel/barchart/TickSpacingEditor.tsx | 1 + public/app/plugins/panel/barchart/bars.ts | 13 +- public/app/plugins/panel/barchart/config.ts | 3 +- public/app/plugins/panel/barchart/module.tsx | 7 +- .../app/plugins/panel/barchart/suggestions.ts | 1 + .../app/plugins/panel/barchart/utils.test.ts | 19 +- public/app/plugins/panel/barchart/utils.ts | 18 +- .../panel/bargauge/BarGaugeMigrations.test.ts | 1 + .../panel/bargauge/BarGaugeMigrations.ts | 1 + .../panel/bargauge/BarGaugePanel.test.tsx | 5 +- .../plugins/panel/bargauge/BarGaugePanel.tsx | 9 +- public/app/plugins/panel/bargauge/module.tsx | 8 +- .../app/plugins/panel/bargauge/suggestions.ts | 1 + public/app/plugins/panel/bargauge/types.ts | 2 +- .../panel/candlestick/CandlestickPanel.tsx | 23 +- .../plugins/panel/candlestick/fields.test.ts | 1 + .../app/plugins/panel/candlestick/fields.ts | 2 + .../app/plugins/panel/candlestick/module.tsx | 10 +- .../plugins/panel/candlestick/suggestions.ts | 1 + public/app/plugins/panel/candlestick/utils.ts | 4 +- .../app/plugins/panel/canvas/CanvasPanel.tsx | 12 +- .../plugins/panel/canvas/editor/APIEditor.tsx | 3 +- .../canvas/editor/LayerElementListEditor.tsx | 24 +- .../panel/canvas/editor/PlacementEditor.tsx | 10 +- .../panel/canvas/editor/elementEditor.tsx | 8 +- .../panel/canvas/editor/layerEditor.tsx | 13 +- public/app/plugins/panel/canvas/module.tsx | 4 +- .../app/plugins/panel/dashlist/DashList.tsx | 13 +- public/app/plugins/panel/dashlist/module.tsx | 9 +- public/app/plugins/panel/debug/CursorView.tsx | 4 +- public/app/plugins/panel/debug/DebugPanel.tsx | 5 +- .../plugins/panel/debug/EventBusLogger.tsx | 5 +- .../plugins/panel/debug/RenderInfoViewer.tsx | 3 +- public/app/plugins/panel/debug/StateView.tsx | 2 + public/app/plugins/panel/debug/module.tsx | 1 + .../panel/gauge/GaugeMigrations.test.ts | 1 + .../plugins/panel/gauge/GaugeMigrations.ts | 3 +- public/app/plugins/panel/gauge/GaugePanel.tsx | 6 +- public/app/plugins/panel/gauge/module.tsx | 10 +- public/app/plugins/panel/gauge/suggestions.ts | 1 + .../plugins/panel/geomap/GeomapOverlay.tsx | 3 +- .../app/plugins/panel/geomap/GeomapPanel.tsx | 38 +- .../plugins/panel/geomap/GeomapTooltip.tsx | 5 +- .../components/ComplexDataHoverView.tsx | 8 +- .../panel/geomap/components/DataHoverRow.tsx | 3 +- .../panel/geomap/components/DataHoverRows.tsx | 10 +- .../panel/geomap/components/DataHoverTabs.tsx | 1 + .../panel/geomap/components/DataHoverView.tsx | 5 +- .../panel/geomap/components/DebugOverlay.tsx | 15 +- .../geomap/editor/GeomapStyleRulesEditor.tsx | 10 +- .../panel/geomap/editor/LayersEditor.tsx | 14 +- .../panel/geomap/editor/MapViewEditor.tsx | 8 +- .../panel/geomap/editor/StyleRuleEditor.tsx | 24 +- .../panel/geomap/editor/layerEditor.tsx | 14 +- public/app/plugins/panel/geomap/event.ts | 2 + .../app/plugins/panel/geomap/globalStyles.ts | 1 + .../panel/geomap/layers/basemaps/carto.ts | 5 +- .../panel/geomap/layers/basemaps/esri.ts | 4 +- .../panel/geomap/layers/basemaps/generic.ts | 5 +- .../panel/geomap/layers/basemaps/osm.ts | 5 +- .../plugins/panel/geomap/layers/registry.ts | 6 +- .../plugins/panel/geomap/migrations.test.ts | 1 + public/app/plugins/panel/geomap/migrations.ts | 4 +- public/app/plugins/panel/geomap/module.tsx | 14 +- .../app/plugins/panel/geomap/style/markers.ts | 8 +- .../app/plugins/panel/geomap/style/types.ts | 3 +- .../plugins/panel/geomap/style/utils.test.ts | 1 + .../app/plugins/panel/geomap/style/utils.ts | 1 + public/app/plugins/panel/geomap/types.ts | 10 +- .../checkFeatureMatchesStyleRule.test.ts | 2 + .../utils/checkFeatureMatchesStyleRule.ts | 1 + .../panel/geomap/utils/getFeatures.test.ts | 2 + .../plugins/panel/geomap/utils/getFeatures.ts | 4 +- .../panel/gettingstarted/GettingStarted.tsx | 10 +- .../gettingstarted/components/DocsCard.tsx | 11 +- .../panel/gettingstarted/components/Step.tsx | 7 +- .../components/TutorialCard.tsx | 7 +- .../gettingstarted/components/sharedStyles.ts | 3 +- .../plugins/panel/gettingstarted/module.ts | 1 + .../app/plugins/panel/gettingstarted/steps.ts | 3 +- .../panel/graph/GraphContextMenuCtrl.ts | 2 +- .../panel/graph/GraphMigrations.test.ts | 1 + .../app/plugins/panel/graph/Legend/Legend.tsx | 4 +- .../panel/graph/Legend/LegendSeriesItem.tsx | 7 +- .../plugins/panel/graph/annotation_tooltip.ts | 5 +- public/app/plugins/panel/graph/axes_editor.ts | 1 + .../app/plugins/panel/graph/data_processor.ts | 7 +- .../app/plugins/panel/graph/event_editor.ts | 6 +- .../app/plugins/panel/graph/event_manager.ts | 4 +- public/app/plugins/panel/graph/graph.ts | 34 +- .../app/plugins/panel/graph/graph_tooltip.ts | 5 +- public/app/plugins/panel/graph/histogram.ts | 3 +- .../plugins/panel/graph/jquery.flot.events.ts | 1 + public/app/plugins/panel/graph/module.ts | 30 +- .../panel/graph/series_overrides_ctrl.ts | 3 +- .../panel/graph/specs/data_processor.test.ts | 3 +- .../plugins/panel/graph/specs/graph.test.ts | 11 +- .../panel/graph/specs/graph_ctrl.test.ts | 3 +- .../panel/graph/specs/graph_tooltip.test.ts | 1 + .../graph/specs/threshold_manager.test.ts | 2 + .../graph/specs/time_region_manager.test.ts | 3 +- .../plugins/panel/graph/threshold_manager.ts | 3 +- .../plugins/panel/graph/thresholds_form.ts | 3 +- .../panel/graph/time_region_manager.ts | 1 + .../plugins/panel/graph/time_regions_form.ts | 1 + public/app/plugins/panel/graph/utils.test.ts | 1 + .../panel/heatmap-new/HeatmapHoverView.tsx | 7 +- .../panel/heatmap-new/HeatmapPanel.tsx | 11 +- .../plugins/panel/heatmap-new/fields.test.ts | 1 + .../app/plugins/panel/heatmap-new/fields.ts | 1 + .../panel/heatmap-new/migrations.test.ts | 1 + .../plugins/panel/heatmap-new/migrations.ts | 1 + .../app/plugins/panel/heatmap-new/module.tsx | 14 +- .../app/plugins/panel/heatmap-new/palettes.ts | 6 +- .../plugins/panel/heatmap-new/suggestions.ts | 1 + public/app/plugins/panel/heatmap-new/utils.ts | 4 +- .../app/plugins/panel/heatmap/color_legend.ts | 12 +- .../app/plugins/panel/heatmap/heatmap_ctrl.ts | 25 +- .../panel/heatmap/heatmap_data_converter.ts | 2 + .../plugins/panel/heatmap/heatmap_tooltip.ts | 4 +- public/app/plugins/panel/heatmap/rendering.ts | 16 +- .../panel/heatmap/specs/heatmap_ctrl.test.ts | 3 +- .../specs/heatmap_data_converter.test.ts | 4 +- .../app/plugins/panel/histogram/Histogram.tsx | 23 +- .../panel/histogram/HistogramPanel.tsx | 6 +- public/app/plugins/panel/histogram/module.tsx | 6 +- public/app/plugins/panel/histogram/utils.ts | 1 - public/app/plugins/panel/icon/IconPanel.tsx | 8 +- public/app/plugins/panel/icon/module.tsx | 7 +- .../plugins/panel/live/LiveChannelEditor.tsx | 7 +- public/app/plugins/panel/live/LivePanel.tsx | 13 +- public/app/plugins/panel/live/module.tsx | 1 + .../app/plugins/panel/logs/LogsPanel.test.tsx | 4 +- public/app/plugins/panel/logs/LogsPanel.tsx | 11 +- public/app/plugins/panel/logs/module.tsx | 3 +- public/app/plugins/panel/logs/suggestions.ts | 1 + public/app/plugins/panel/news/NewsPanel.tsx | 28 +- public/app/plugins/panel/news/atom.test.ts | 3 +- public/app/plugins/panel/news/module.tsx | 3 +- public/app/plugins/panel/news/rss.test.ts | 3 +- public/app/plugins/panel/news/utils.test.ts | 5 +- public/app/plugins/panel/news/utils.ts | 3 +- public/app/plugins/panel/nodeGraph/Edge.tsx | 1 + .../app/plugins/panel/nodeGraph/EdgeLabel.tsx | 6 +- .../plugins/panel/nodeGraph/Legend.test.tsx | 4 +- public/app/plugins/panel/nodeGraph/Legend.tsx | 12 +- public/app/plugins/panel/nodeGraph/Marker.tsx | 8 +- public/app/plugins/panel/nodeGraph/Node.tsx | 8 +- .../panel/nodeGraph/NodeGraph.test.tsx | 3 +- .../app/plugins/panel/nodeGraph/NodeGraph.tsx | 38 +- .../panel/nodeGraph/NodeGraphPanel.tsx | 13 +- .../plugins/panel/nodeGraph/ViewControls.tsx | 5 +- .../plugins/panel/nodeGraph/layout.test.ts | 1 + public/app/plugins/panel/nodeGraph/layout.ts | 14 +- public/app/plugins/panel/nodeGraph/module.tsx | 1 + public/app/plugins/panel/nodeGraph/types.ts | 1 + .../panel/nodeGraph/useCategorizeFrames.ts | 1 + .../panel/nodeGraph/useContextMenu.tsx | 12 +- .../nodeGraph/useFocusPositionOnLayout.ts | 1 + .../plugins/panel/nodeGraph/useNodeLimit.ts | 3 +- .../app/plugins/panel/nodeGraph/usePanning.ts | 3 +- .../app/plugins/panel/nodeGraph/utils.test.ts | 1 + public/app/plugins/panel/nodeGraph/utils.ts | 1 + .../app/plugins/panel/piechart/PieChart.tsx | 27 +- .../plugins/panel/piechart/PieChartPanel.tsx | 14 +- .../plugins/panel/piechart/migrations.test.ts | 1 + .../app/plugins/panel/piechart/migrations.ts | 1 + public/app/plugins/panel/piechart/module.tsx | 8 +- .../app/plugins/panel/piechart/suggestions.ts | 1 + .../plugins/panel/stat/StatMigrations.test.ts | 3 +- .../app/plugins/panel/stat/StatMigrations.ts | 5 +- public/app/plugins/panel/stat/StatPanel.tsx | 27 +- public/app/plugins/panel/stat/module.tsx | 7 +- public/app/plugins/panel/stat/suggestions.ts | 1 + public/app/plugins/panel/stat/types.ts | 14 +- .../state-timeline/StateTimelinePanel.tsx | 11 +- .../state-timeline/StateTimelineTooltip.tsx | 2 + .../panel/state-timeline/TimelineChart.tsx | 6 +- .../panel/state-timeline/migrations.test.ts | 1 + .../panel/state-timeline/migrations.ts | 6 +- .../plugins/panel/state-timeline/module.tsx | 8 +- .../panel/state-timeline/suggestions.ts | 1 + .../plugins/panel/state-timeline/timeline.ts | 12 +- .../panel/state-timeline/utils.test.ts | 1 + .../app/plugins/panel/state-timeline/utils.ts | 11 +- .../status-history/StatusHistoryPanel.tsx | 5 +- .../plugins/panel/status-history/module.tsx | 5 +- .../panel/status-history/suggestions.ts | 1 + .../plugins/panel/table-old/column_options.ts | 1 + public/app/plugins/panel/table-old/editor.ts | 1 + public/app/plugins/panel/table-old/module.ts | 20 +- .../app/plugins/panel/table-old/renderer.ts | 4 +- .../panel/table-old/specs/renderer.test.ts | 8 +- .../plugins/panel/table-old/transformers.ts | 10 +- public/app/plugins/panel/table-old/types.ts | 2 +- .../plugins/panel/table/PaginationEditor.tsx | 3 +- public/app/plugins/panel/table/TablePanel.tsx | 23 +- public/app/plugins/panel/table/footer.ts | 3 +- .../plugins/panel/table/migrations.test.ts | 1 + public/app/plugins/panel/table/migrations.ts | 4 +- public/app/plugins/panel/table/module.tsx | 9 +- public/app/plugins/panel/table/suggestions.ts | 1 + public/app/plugins/panel/text/TextPanel.tsx | 18 +- .../plugins/panel/text/TextPanelEditor.tsx | 5 +- public/app/plugins/panel/text/module.tsx | 2 +- .../text/textPanelMigrationHandler.test.ts | 5 +- .../panel/text/textPanelMigrationHandler.ts | 1 + .../panel/timeseries/FillBelowToEditor.tsx | 1 + .../panel/timeseries/LineStyleEditor.tsx | 3 +- .../panel/timeseries/SpanNullsEditor.tsx | 1 + .../timeseries/ThresholdsStyleEditor.tsx | 3 +- .../panel/timeseries/TimeSeriesPanel.tsx | 12 +- public/app/plugins/panel/timeseries/config.ts | 3 +- .../panel/timeseries/migrations.test.ts | 6 +- .../plugins/panel/timeseries/migrations.ts | 6 +- .../app/plugins/panel/timeseries/module.tsx | 7 +- .../colorSeriesConfigFactory.test.ts | 1 + .../overrides/hideSeriesConfigFactory.test.ts | 1 + .../plugins/AnnotationEditorPlugin.tsx | 8 +- .../timeseries/plugins/AnnotationsPlugin.tsx | 6 +- .../timeseries/plugins/ContextMenuPlugin.tsx | 7 +- .../timeseries/plugins/ExemplarMarker.tsx | 5 +- .../timeseries/plugins/ExemplarsPlugin.tsx | 6 +- .../timeseries/plugins/OutsideRangePlugin.tsx | 3 +- .../plugins/ThresholdControlsPlugin.tsx | 4 +- .../plugins/ThresholdDragHandle.tsx | 5 +- .../plugins/annotations/AnnotationEditor.tsx | 7 +- .../annotations/AnnotationEditorForm.tsx | 9 +- .../plugins/annotations/AnnotationMarker.tsx | 11 +- .../plugins/annotations/AnnotationTooltip.tsx | 8 +- .../panel/timeseries/plugins/styles.ts | 3 +- .../plugins/panel/timeseries/suggestions.ts | 1 + .../plugins/panel/timeseries/utils.test.ts | 1 + public/app/plugins/panel/welcome/Welcome.tsx | 3 +- public/app/plugins/panel/welcome/module.ts | 1 + .../plugins/panel/xychart/ExplicitEditor.tsx | 1 + .../app/plugins/panel/xychart/TooltipView.tsx | 8 +- .../plugins/panel/xychart/XYChartPanel2.tsx | 10 +- .../plugins/panel/xychart/XYDimsEditor.tsx | 7 +- public/app/plugins/panel/xychart/config.ts | 3 +- public/app/plugins/panel/xychart/dims.ts | 3 +- public/app/plugins/panel/xychart/module.tsx | 9 +- public/app/plugins/panel/xychart/scatter.ts | 13 +- public/app/plugins/panel/xychart/types.ts | 1 + public/app/plugins/sdk.ts | 2 +- public/app/routes/routes.tsx | 20 +- public/app/store/configureStore.ts | 11 +- public/app/types/appEvent.ts | 1 + public/app/types/dashboard.ts | 3 +- public/app/types/datasources.ts | 2 +- public/app/types/explore.ts | 1 + public/app/types/serviceaccount.ts | 1 + public/app/types/store.ts | 13 +- public/app/types/teams.ts | 1 + public/app/types/unified-alerting.ts | 1 + public/app/types/user.ts | 3 +- public/test/core/redux/reducerTester.test.ts | 2 +- public/test/core/redux/reducerTester.ts | 2 +- public/test/core/redux/reduxTester.ts | 10 +- public/test/core/thunk/thunkTester.ts | 2 +- public/test/global-jquery-shim.ts | 4 + public/test/helpers/TestProvider.tsx | 1 + public/test/helpers/convertToStoreState.ts | 2 +- .../helpers/getTemplateSrvDependencies.ts | 3 +- public/test/helpers/initTemplateSrv.ts | 4 +- public/test/jest-setup.ts | 18 +- public/test/matchers/index.ts | 5 +- public/test/matchers/toEmitValues.test.ts | 1 + public/test/matchers/toEmitValues.ts | 5 +- public/test/matchers/toEmitValuesWith.ts | 5 +- public/test/matchers/utils.ts | 3 +- public/test/mocks/datasource_srv.ts | 3 +- public/test/mocks/linguiMacro.tsx | 2 +- public/test/redux-rtl.tsx | 6 +- public/test/setupTests.ts | 1 + public/test/specs/helpers.ts | 7 +- scripts/cli/generateSassVariableFiles.ts | 3 +- scripts/webpack/dependencies.js | 3 +- scripts/webpack/loaders/compile.js | 5 +- scripts/webpack/sass.rule.js | 2 +- scripts/webpack/webpack.common.js | 3 +- scripts/webpack/webpack.dev.js | 11 +- scripts/webpack/webpack.hot.js | 9 +- scripts/webpack/webpack.prod.js | 11 +- yarn.lock | 154 ++++- 3311 files changed, 14807 insertions(+), 9523 deletions(-) create mode 100644 public/test/global-jquery-shim.ts diff --git a/.betterer.results b/.betterer.results index c90b157dd4a..186b3a43f37 100644 --- a/.betterer.results +++ b/.betterer.results @@ -5,329 +5,329 @@ // exports[`no enzyme tests`] = { value: `{ - "packages/grafana-ui/src/components/BarGauge/BarGauge.test.tsx:2315765050": [ - [1, 19, 13, "RegExp match", "2409514259"] + "packages/grafana-ui/src/components/BarGauge/BarGauge.test.tsx:4199795290": [ + [0, 19, 13, "RegExp match", "2409514259"] ], - "packages/grafana-ui/src/components/ColorPicker/NamedColorsPalette.test.tsx:1355456933": [ - [1, 31, 13, "RegExp match", "2409514259"] + "packages/grafana-ui/src/components/ColorPicker/NamedColorsPalette.test.tsx:3311646309": [ + [0, 31, 13, "RegExp match", "2409514259"] ], - "packages/grafana-ui/src/components/FileUpload/FileUpload.test.tsx:3475964456": [ - [1, 19, 13, "RegExp match", "2409514259"] + "packages/grafana-ui/src/components/FileUpload/FileUpload.test.tsx:4145620610": [ + [0, 19, 13, "RegExp match", "2409514259"] ], - "packages/grafana-ui/src/components/FormField/FormField.test.tsx:2387359174": [ - [1, 19, 13, "RegExp match", "2409514259"] + "packages/grafana-ui/src/components/FormField/FormField.test.tsx:3429087660": [ + [0, 19, 13, "RegExp match", "2409514259"] ], - "packages/grafana-ui/src/components/Forms/Legacy/Input/Input.test.tsx:4019574269": [ - [2, 19, 13, "RegExp match", "2409514259"] + "packages/grafana-ui/src/components/Forms/Legacy/Input/Input.test.tsx:3129955645": [ + [0, 19, 13, "RegExp match", "2409514259"] ], - "packages/grafana-ui/src/components/Gauge/Gauge.test.tsx:1435004725": [ - [1, 19, 13, "RegExp match", "2409514259"] + "packages/grafana-ui/src/components/Gauge/Gauge.test.tsx:2525939157": [ + [0, 19, 13, "RegExp match", "2409514259"] ], - "packages/grafana-ui/src/components/Graph/Graph.test.tsx:2882401917": [ - [1, 17, 13, "RegExp match", "2409514259"] + "packages/grafana-ui/src/components/Graph/Graph.test.tsx:1664091255": [ + [0, 17, 13, "RegExp match", "2409514259"] ], - "packages/grafana-ui/src/components/Graph/GraphTooltip/MultiModeGraphTooltip.test.tsx:3734531523": [ - [1, 17, 13, "RegExp match", "2409514259"] + "packages/grafana-ui/src/components/Graph/GraphTooltip/MultiModeGraphTooltip.test.tsx:1865444105": [ + [0, 17, 13, "RegExp match", "2409514259"] ], - "packages/grafana-ui/src/components/List/AbstractList.test.tsx:2210654375": [ - [1, 19, 13, "RegExp match", "2409514259"] + "packages/grafana-ui/src/components/List/AbstractList.test.tsx:2972876749": [ + [0, 19, 13, "RegExp match", "2409514259"] ], - "packages/grafana-ui/src/components/Logs/LogLabels.test.tsx:1113070745": [ - [1, 19, 13, "RegExp match", "2409514259"] + "packages/grafana-ui/src/components/Logs/LogLabels.test.tsx:1029448019": [ + [0, 19, 13, "RegExp match", "2409514259"] ], - "packages/grafana-ui/src/components/Logs/LogMessageAnsi.test.tsx:1478948568": [ - [1, 19, 13, "RegExp match", "2409514259"] + "packages/grafana-ui/src/components/Logs/LogMessageAnsi.test.tsx:1630730648": [ + [0, 19, 13, "RegExp match", "2409514259"] ], - "packages/grafana-ui/src/components/Logs/LogRowContextProvider.test.tsx:636540759": [ - [3, 17, 13, "RegExp match", "2409514259"] + "packages/grafana-ui/src/components/Logs/LogRowContextProvider.test.tsx:2719724375": [ + [0, 17, 13, "RegExp match", "2409514259"] ], - "packages/grafana-ui/src/components/Logs/LogRows.test.tsx:2288254498": [ - [3, 17, 13, "RegExp match", "2409514259"] + "packages/grafana-ui/src/components/Logs/LogRows.test.tsx:3121815234": [ + [0, 17, 13, "RegExp match", "2409514259"] ], - "packages/grafana-ui/src/components/QueryField/QueryField.test.tsx:1297745712": [ - [1, 19, 13, "RegExp match", "2409514259"] + "packages/grafana-ui/src/components/QueryField/QueryField.test.tsx:375894800": [ + [0, 19, 13, "RegExp match", "2409514259"] ], - "packages/grafana-ui/src/components/Slider/Slider.test.tsx:2110443485": [ - [3, 17, 13, "RegExp match", "2409514259"] + "packages/grafana-ui/src/components/Slider/Slider.test.tsx:751112695": [ + [0, 17, 13, "RegExp match", "2409514259"] ], - "packages/grafana-ui/src/components/Typeahead/PartialHighlighter.test.tsx:3831493850": [ - [1, 31, 13, "RegExp match", "2409514259"] + "packages/grafana-ui/src/components/Typeahead/PartialHighlighter.test.tsx:1751923376": [ + [0, 31, 13, "RegExp match", "2409514259"] ], - "packages/grafana-ui/src/components/Typeahead/Typeahead.test.tsx:1026793168": [ - [1, 17, 13, "RegExp match", "2409514259"] + "packages/grafana-ui/src/components/Typeahead/Typeahead.test.tsx:972524250": [ + [0, 17, 13, "RegExp match", "2409514259"] ], - "packages/grafana-ui/src/components/Typeahead/TypeaheadInfo.test.tsx:3968135869": [ - [1, 17, 13, "RegExp match", "2409514259"] + "packages/grafana-ui/src/components/Typeahead/TypeaheadInfo.test.tsx:3512289373": [ + [0, 17, 13, "RegExp match", "2409514259"] ], - "packages/grafana-ui/src/slate-plugins/braces.test.tsx:2551821825": [ - [3, 19, 13, "RegExp match", "2409514259"] + "packages/grafana-ui/src/slate-plugins/braces.test.tsx:1440546721": [ + [0, 19, 13, "RegExp match", "2409514259"] ], - "packages/grafana-ui/src/slate-plugins/clear.test.tsx:4145618392": [ - [3, 19, 13, "RegExp match", "2409514259"] + "packages/grafana-ui/src/slate-plugins/clear.test.tsx:1085648664": [ + [0, 19, 13, "RegExp match", "2409514259"] ], - "packages/grafana-ui/src/slate-plugins/runner.test.tsx:2165687770": [ - [3, 19, 13, "RegExp match", "2409514259"] + "packages/grafana-ui/src/slate-plugins/runner.test.tsx:446043290": [ + [0, 19, 13, "RegExp match", "2409514259"] ], - "packages/grafana-ui/src/slate-plugins/suggestions.test.tsx:4138775391": [ - [1, 18, 13, "RegExp match", "2409514259"] + "packages/grafana-ui/src/slate-plugins/suggestions.test.tsx:3654981205": [ + [0, 18, 13, "RegExp match", "2409514259"] ], - "packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/CanvasSpanGraph.test.js:3515574241": [ - [15, 19, 13, "RegExp match", "2409514259"] - ], - "packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/GraphTicks.test.js:1837731860": [ - [15, 19, 13, "RegExp match", "2409514259"] - ], - "packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/Scrubber.test.js:1200884350": [ - [15, 19, 13, "RegExp match", "2409514259"] - ], - "packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/TickLabels.test.js:3094256278": [ - [15, 19, 13, "RegExp match", "2409514259"] - ], - "packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/ViewingLayer.test.js:2643658696": [ + "packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/CanvasSpanGraph.test.js:1974748555": [ [14, 19, 13, "RegExp match", "2409514259"] ], - "packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/index.test.js:4118842298": [ - [15, 19, 13, "RegExp match", "2409514259"] - ], - "packages/jaeger-ui-components/src/TracePageHeader/TracePageHeader.test.js:3669774385": [ - [15, 26, 13, "RegExp match", "2409514259"] - ], - "packages/jaeger-ui-components/src/TracePageHeader/TracePageSearchBar.test.js:2095199604": [ - [15, 19, 13, "RegExp match", "2409514259"] - ], - "packages/jaeger-ui-components/src/TraceTimelineViewer/ListView/index.test.js:793239444": [ - [15, 26, 13, "RegExp match", "2409514259"] - ], - "packages/jaeger-ui-components/src/TraceTimelineViewer/ReferencesButton.test.js:2288177454": [ - [15, 19, 13, "RegExp match", "2409514259"] - ], - "packages/jaeger-ui-components/src/TraceTimelineViewer/SpanBar.test.js:2127169675": [ - [15, 17, 13, "RegExp match", "2409514259"] - ], - "packages/jaeger-ui-components/src/TraceTimelineViewer/SpanBarRow.test.js:814916029": [ - [15, 26, 13, "RegExp match", "2409514259"] - ], - "packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianKeyValues.test.js:2200354834": [ - [15, 19, 13, "RegExp match", "2409514259"] - ], - "packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianLogs.test.js:3242453659": [ - [15, 19, 13, "RegExp match", "2409514259"] - ], - "packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianReferences.test.js:1301875390": [ - [15, 19, 13, "RegExp match", "2409514259"] - ], - "packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianText.test.js:2881451220": [ - [15, 17, 13, "RegExp match", "2409514259"] - ], - "packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/KeyValuesTable.test.js:2159985979": [ - [15, 19, 13, "RegExp match", "2409514259"] - ], - "packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/TextList.test.js:3713828679": [ - [15, 19, 13, "RegExp match", "2409514259"] - ], - "packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/index.test.js:3788127934": [ - [17, 19, 13, "RegExp match", "2409514259"] - ], - "packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetailRow.test.js:1119974018": [ - [15, 19, 13, "RegExp match", "2409514259"] - ], - "packages/jaeger-ui-components/src/TraceTimelineViewer/SpanTreeOffset.test.js:232429058": [ + "packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/GraphTicks.test.js:940336852": [ [14, 19, 13, "RegExp match", "2409514259"] ], - "packages/jaeger-ui-components/src/TraceTimelineViewer/Ticks.test.js:2626977087": [ - [15, 19, 13, "RegExp match", "2409514259"] + "packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/Scrubber.test.js:4256741694": [ + [14, 19, 13, "RegExp match", "2409514259"] ], - "packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineCollapser.test.js:954294244": [ - [15, 19, 13, "RegExp match", "2409514259"] + "packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/TickLabels.test.js:2931161174": [ + [14, 19, 13, "RegExp match", "2409514259"] ], - "packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineColumnResizer.test.js:208811948": [ - [15, 17, 13, "RegExp match", "2409514259"] + "packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/ViewingLayer.test.js:1676554632": [ + [14, 19, 13, "RegExp match", "2409514259"] ], - "packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineHeaderRow.test.js:1197952226": [ - [15, 19, 13, "RegExp match", "2409514259"] + "packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/index.test.js:186764954": [ + [14, 19, 13, "RegExp match", "2409514259"] ], - "packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineViewingLayer.test.js:3714128222": [ - [15, 17, 13, "RegExp match", "2409514259"] - ], - "packages/jaeger-ui-components/src/TraceTimelineViewer/VirtualizedTraceView.test.js:2249890922": [ + "packages/jaeger-ui-components/src/TracePageHeader/TracePageHeader.test.js:3242042907": [ [14, 26, 13, "RegExp match", "2409514259"] ], - "packages/jaeger-ui-components/src/TraceTimelineViewer/index.test.js:4107025050": [ + "packages/jaeger-ui-components/src/TracePageHeader/TracePageSearchBar.test.js:2807329716": [ + [14, 19, 13, "RegExp match", "2409514259"] + ], + "packages/jaeger-ui-components/src/TraceTimelineViewer/ListView/index.test.js:1734982398": [ + [14, 26, 13, "RegExp match", "2409514259"] + ], + "packages/jaeger-ui-components/src/TraceTimelineViewer/ReferencesButton.test.js:3807792910": [ + [14, 19, 13, "RegExp match", "2409514259"] + ], + "packages/jaeger-ui-components/src/TraceTimelineViewer/SpanBar.test.js:1478502145": [ + [14, 17, 13, "RegExp match", "2409514259"] + ], + "packages/jaeger-ui-components/src/TraceTimelineViewer/SpanBarRow.test.js:3826510429": [ + [14, 26, 13, "RegExp match", "2409514259"] + ], + "packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianKeyValues.test.js:2408389970": [ + [14, 19, 13, "RegExp match", "2409514259"] + ], + "packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianLogs.test.js:3960703835": [ + [14, 19, 13, "RegExp match", "2409514259"] + ], + "packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianReferences.test.js:2429764318": [ + [14, 19, 13, "RegExp match", "2409514259"] + ], + "packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianText.test.js:1966455998": [ + [14, 17, 13, "RegExp match", "2409514259"] + ], + "packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/KeyValuesTable.test.js:3813002651": [ + [14, 19, 13, "RegExp match", "2409514259"] + ], + "packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/TextList.test.js:3006381933": [ + [14, 19, 13, "RegExp match", "2409514259"] + ], + "packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/index.test.js:3097530078": [ + [16, 19, 13, "RegExp match", "2409514259"] + ], + "packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetailRow.test.js:2623922632": [ + [14, 19, 13, "RegExp match", "2409514259"] + ], + "packages/jaeger-ui-components/src/TraceTimelineViewer/SpanTreeOffset.test.js:1117377794": [ + [14, 19, 13, "RegExp match", "2409514259"] + ], + "packages/jaeger-ui-components/src/TraceTimelineViewer/Ticks.test.js:743308415": [ + [14, 19, 13, "RegExp match", "2409514259"] + ], + "packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineCollapser.test.js:4018342820": [ + [14, 19, 13, "RegExp match", "2409514259"] + ], + "packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineColumnResizer.test.js:2286101708": [ + [15, 17, 13, "RegExp match", "2409514259"] + ], + "packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineHeaderRow.test.js:2106409544": [ + [14, 19, 13, "RegExp match", "2409514259"] + ], + "packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineViewingLayer.test.js:1423129438": [ + [15, 17, 13, "RegExp match", "2409514259"] + ], + "packages/jaeger-ui-components/src/TraceTimelineViewer/VirtualizedTraceView.test.js:2326471104": [ + [13, 26, 13, "RegExp match", "2409514259"] + ], + "packages/jaeger-ui-components/src/TraceTimelineViewer/index.test.js:381298544": [ + [14, 19, 13, "RegExp match", "2409514259"] + ], + "packages/jaeger-ui-components/src/common/CopyIcon.test.js:187212136": [ [15, 19, 13, "RegExp match", "2409514259"] ], - "packages/jaeger-ui-components/src/common/CopyIcon.test.js:3119664776": [ - [15, 19, 13, "RegExp match", "2409514259"] + "packages/jaeger-ui-components/src/common/NewWindowIcon.test.js:1750458349": [ + [14, 19, 13, "RegExp match", "2409514259"] ], - "packages/jaeger-ui-components/src/common/NewWindowIcon.test.js:3878561197": [ - [15, 19, 13, "RegExp match", "2409514259"] + "packages/jaeger-ui-components/src/common/UiFindInput.test.js:2207118020": [ + [14, 19, 13, "RegExp match", "2409514259"] ], - "packages/jaeger-ui-components/src/common/UiFindInput.test.js:2258975438": [ - [15, 19, 13, "RegExp match", "2409514259"] + "packages/jaeger-ui-components/src/url/ReferenceLink.test.js:3249503373": [ + [14, 26, 13, "RegExp match", "2409514259"] ], - "packages/jaeger-ui-components/src/url/ReferenceLink.test.js:830986413": [ - [15, 26, 13, "RegExp match", "2409514259"] + "public/app/core/components/PageActionBar/PageActionBar.test.tsx:1251504193": [ + [0, 19, 13, "RegExp match", "2409514259"] ], - "public/app/core/components/PageActionBar/PageActionBar.test.tsx:2111991019": [ + "public/app/core/components/QueryOperationRow/QueryOperationAction.test.tsx:3032694716": [ + [0, 19, 13, "RegExp match", "2409514259"] + ], + "public/app/core/components/QueryOperationRow/QueryOperationRow.test.tsx:2026575657": [ + [0, 26, 13, "RegExp match", "2409514259"] + ], + "public/app/core/components/Select/FolderPicker.test.tsx:993468764": [ + [0, 19, 13, "RegExp match", "2409514259"] + ], + "public/app/core/components/Select/MetricSelect.test.tsx:3351544014": [ + [0, 19, 13, "RegExp match", "2409514259"] + ], + "public/app/features/alerting/AlertRuleList.test.tsx:2998938420": [ + [0, 19, 13, "RegExp match", "2409514259"] + ], + "public/app/features/alerting/TestRuleResult.test.tsx:2358420489": [ + [0, 19, 13, "RegExp match", "2409514259"] + ], + "public/app/features/api-keys/ApiKeysAddedModal.test.tsx:3246264379": [ + [0, 20, 13, "RegExp match", "2409514259"] + ], + "public/app/features/dashboard/components/DashboardRow/DashboardRow.test.tsx:1463123173": [ + [0, 17, 13, "RegExp match", "2409514259"] + ], + "public/app/features/dashboard/components/SaveDashboard/forms/SaveDashboardAsForm.test.tsx:1969004590": [ + [0, 17, 13, "RegExp match", "2409514259"] + ], + "public/app/features/dashboard/components/SaveDashboard/forms/SaveDashboardForm.test.tsx:948029434": [ + [0, 17, 13, "RegExp match", "2409514259"] + ], + "public/app/features/dashboard/components/ShareModal/ShareLink.test.tsx:2357087833": [ + [0, 35, 13, "RegExp match", "2409514259"] + ], + "public/app/features/dashboard/dashgrid/DashboardGrid.test.tsx:2723773538": [ + [0, 35, 13, "RegExp match", "2409514259"] + ], + "public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderCorner.test.tsx:2851646279": [ + [0, 19, 13, "RegExp match", "2409514259"] + ], + "public/app/features/datasources/DashboardsTable.test.tsx:1950355032": [ + [0, 19, 13, "RegExp match", "2409514259"] + ], + "public/app/features/datasources/DataSourceDashboards.test.tsx:1369048021": [ + [0, 19, 13, "RegExp match", "2409514259"] + ], + "public/app/features/datasources/DataSourcesListPage.test.tsx:2960099202": [ + [0, 19, 13, "RegExp match", "2409514259"] + ], + "public/app/features/datasources/settings/BasicSettings.test.tsx:625016324": [ + [0, 19, 13, "RegExp match", "2409514259"] + ], + "public/app/features/datasources/settings/ButtonRow.test.tsx:1422996720": [ + [0, 19, 13, "RegExp match", "2409514259"] + ], + "public/app/features/dimensions/editors/ThresholdsEditor/ThresholdsEditor.test.tsx:4164297658": [ + [0, 17, 13, "RegExp match", "2409514259"] + ], + "public/app/features/explore/LiveLogs.test.tsx:156663779": [ + [0, 17, 13, "RegExp match", "2409514259"] + ], + "public/app/features/explore/RichHistory/RichHistoryStarredTab.test.tsx:3328200031": [ + [0, 17, 13, "RegExp match", "2409514259"] + ], + "public/app/features/explore/RunButton.test.tsx:4267530266": [ + [0, 19, 13, "RegExp match", "2409514259"] + ], + "public/app/features/explore/SecondaryActions.test.tsx:1177396128": [ + [0, 19, 13, "RegExp match", "2409514259"] + ], + "public/app/features/explore/TimeSyncButton.test.tsx:853739820": [ + [0, 17, 13, "RegExp match", "2409514259"] + ], + "public/app/features/folders/FolderSettingsPage.test.tsx:1109052730": [ + [0, 19, 13, "RegExp match", "2409514259"] + ], + "public/app/features/invites/InviteesTable.test.tsx:3612992381": [ + [0, 19, 13, "RegExp match", "2409514259"] + ], + "public/app/features/org/OrgDetailsPage.test.tsx:3835042085": [ + [0, 19, 13, "RegExp match", "2409514259"] + ], + "public/app/features/org/OrgProfile.test.tsx:623809345": [ + [0, 19, 13, "RegExp match", "2409514259"] + ], + "public/app/features/teams/CreateTeam.test.tsx:1750035593": [ + [0, 19, 13, "RegExp match", "2409514259"] + ], + "public/app/features/teams/TeamGroupSync.test.tsx:2526985933": [ + [0, 19, 13, "RegExp match", "2409514259"] + ], + "public/app/features/teams/TeamList.test.tsx:854193970": [ + [0, 19, 13, "RegExp match", "2409514259"] + ], + "public/app/features/teams/TeamMemberRow.test.tsx:1649328210": [ + [0, 19, 13, "RegExp match", "2409514259"] + ], + "public/app/features/teams/TeamMembers.test.tsx:4089428239": [ + [0, 19, 13, "RegExp match", "2409514259"] + ], + "public/app/features/teams/TeamPages.test.tsx:3990420214": [ + [0, 19, 13, "RegExp match", "2409514259"] + ], + "public/app/features/teams/TeamSettings.test.tsx:2043271249": [ + [0, 19, 13, "RegExp match", "2409514259"] + ], + "public/app/features/users/UsersActionBar.test.tsx:3740177621": [ + [0, 19, 13, "RegExp match", "2409514259"] + ], + "public/app/features/users/UsersListPage.test.tsx:3908145117": [ + [0, 19, 13, "RegExp match", "2409514259"] + ], + "public/app/features/users/UsersTable.test.tsx:263958312": [ + [0, 19, 13, "RegExp match", "2409514259"] + ], + "public/app/plugins/datasource/cloud-monitoring/components/Aggregation.test.tsx:3822406835": [ [1, 19, 13, "RegExp match", "2409514259"] ], - "public/app/core/components/QueryOperationRow/QueryOperationAction.test.tsx:1284778262": [ - [2, 19, 13, "RegExp match", "2409514259"] + "public/app/plugins/datasource/cloudwatch/components/ConfigEditor.test.tsx:1224072551": [ + [0, 19, 13, "RegExp match", "2409514259"] ], - "public/app/core/components/QueryOperationRow/QueryOperationRow.test.tsx:4115956163": [ - [2, 26, 13, "RegExp match", "2409514259"] - ], - "public/app/core/components/Select/FolderPicker.test.tsx:3389713532": [ + "public/app/plugins/datasource/cloudwatch/components/LogsQueryField.test.tsx:2097436158": [ [1, 19, 13, "RegExp match", "2409514259"] ], - "public/app/core/components/Select/MetricSelect.test.tsx:3409251428": [ - [1, 19, 13, "RegExp match", "2409514259"] + "public/app/plugins/datasource/elasticsearch/configuration/ConfigEditor.test.tsx:3481855642": [ + [0, 26, 13, "RegExp match", "2409514259"] ], - "public/app/features/alerting/AlertRuleList.test.tsx:1800339390": [ - [1, 19, 13, "RegExp match", "2409514259"] + "public/app/plugins/datasource/elasticsearch/configuration/DataLinks.test.tsx:248699332": [ + [0, 17, 13, "RegExp match", "2409514259"] ], - "public/app/features/alerting/TestRuleResult.test.tsx:4118445705": [ - [3, 19, 13, "RegExp match", "2409514259"] + "public/app/plugins/datasource/grafana-azure-monitor-datasource/components/deprecated/components/InsightsConfig.test.tsx:1107283234": [ + [0, 19, 13, "RegExp match", "2409514259"] ], - "public/app/features/api-keys/ApiKeysAddedModal.test.tsx:3516294961": [ - [1, 19, 13, "RegExp match", "2409514259"] + "public/app/plugins/datasource/influxdb/components/ConfigEditor.test.tsx:3456478975": [ + [0, 19, 13, "RegExp match", "2409514259"] ], - "public/app/features/dashboard/components/DashboardRow/DashboardRow.test.tsx:2934056165": [ - [1, 17, 13, "RegExp match", "2409514259"] + "public/app/plugins/datasource/loki/components/LokiExploreQueryEditor.test.tsx:1488067923": [ + [0, 26, 13, "RegExp match", "2409514259"] ], - "public/app/features/dashboard/components/SaveDashboard/forms/SaveDashboardAsForm.test.tsx:2536713486": [ - [1, 17, 13, "RegExp match", "2409514259"] + "public/app/plugins/datasource/loki/components/LokiQueryEditor.test.tsx:146069464": [ + [0, 19, 13, "RegExp match", "2409514259"] ], - "public/app/features/dashboard/components/SaveDashboard/forms/SaveDashboardForm.test.tsx:1262111696": [ - [1, 17, 13, "RegExp match", "2409514259"] + "public/app/plugins/datasource/loki/configuration/ConfigEditor.test.tsx:3658171175": [ + [0, 17, 13, "RegExp match", "2409514259"] ], - "public/app/features/dashboard/components/ShareModal/ShareLink.test.tsx:809006195": [ - [1, 35, 13, "RegExp match", "2409514259"] + "public/app/plugins/datasource/loki/configuration/DebugSection.test.tsx:1551927716": [ + [0, 17, 13, "RegExp match", "2409514259"] ], - "public/app/features/dashboard/dashgrid/DashboardGrid.test.tsx:3682134210": [ - [1, 35, 13, "RegExp match", "2409514259"] + "public/app/plugins/datasource/loki/configuration/DerivedField.test.tsx:3570129984": [ + [0, 19, 13, "RegExp match", "2409514259"] ], - "public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderCorner.test.tsx:3293585799": [ - [1, 19, 13, "RegExp match", "2409514259"] + "public/app/plugins/datasource/loki/configuration/DerivedFields.test.tsx:2402631398": [ + [0, 17, 13, "RegExp match", "2409514259"] ], - "public/app/features/datasources/DashboardsTable.test.tsx:1799076152": [ - [1, 19, 13, "RegExp match", "2409514259"] + "public/app/plugins/datasource/prometheus/configuration/AzureCredentialsForm.test.tsx:3424320489": [ + [0, 19, 13, "RegExp match", "2409514259"] ], - "public/app/features/datasources/DataSourceDashboards.test.tsx:3705773301": [ - [1, 19, 13, "RegExp match", "2409514259"] - ], - "public/app/features/datasources/DataSourcesListPage.test.tsx:1470540840": [ - [1, 19, 13, "RegExp match", "2409514259"] - ], - "public/app/features/datasources/settings/BasicSettings.test.tsx:3867031406": [ - [1, 19, 13, "RegExp match", "2409514259"] - ], - "public/app/features/datasources/settings/ButtonRow.test.tsx:1546608090": [ - [1, 19, 13, "RegExp match", "2409514259"] - ], - "public/app/features/dimensions/editors/ThresholdsEditor/ThresholdsEditor.test.tsx:2556927610": [ - [1, 17, 13, "RegExp match", "2409514259"] - ], - "public/app/features/explore/LiveLogs.test.tsx:1667605379": [ - [2, 17, 13, "RegExp match", "2409514259"] - ], - "public/app/features/explore/RichHistory/RichHistoryStarredTab.test.tsx:492930613": [ - [1, 17, 13, "RegExp match", "2409514259"] - ], - "public/app/features/explore/RunButton.test.tsx:138299098": [ - [3, 19, 13, "RegExp match", "2409514259"] - ], - "public/app/features/explore/SecondaryActions.test.tsx:2096700362": [ - [2, 19, 13, "RegExp match", "2409514259"] - ], - "public/app/features/explore/TimeSyncButton.test.tsx:4230066214": [ - [2, 17, 13, "RegExp match", "2409514259"] - ], - "public/app/features/folders/FolderSettingsPage.test.tsx:3884290298": [ - [2, 19, 13, "RegExp match", "2409514259"] - ], - "public/app/features/invites/InviteesTable.test.tsx:3077684439": [ - [1, 19, 13, "RegExp match", "2409514259"] - ], - "public/app/features/org/OrgDetailsPage.test.tsx:2540662821": [ - [1, 19, 13, "RegExp match", "2409514259"] - ], - "public/app/features/org/OrgProfile.test.tsx:4200739179": [ - [1, 19, 13, "RegExp match", "2409514259"] - ], - "public/app/features/teams/CreateTeam.test.tsx:262744099": [ - [1, 19, 13, "RegExp match", "2409514259"] - ], - "public/app/features/teams/TeamGroupSync.test.tsx:1549471437": [ - [1, 19, 13, "RegExp match", "2409514259"] - ], - "public/app/features/teams/TeamList.test.tsx:3009556824": [ - [1, 19, 13, "RegExp match", "2409514259"] - ], - "public/app/features/teams/TeamMemberRow.test.tsx:7032440": [ - [1, 19, 13, "RegExp match", "2409514259"] - ], - "public/app/features/teams/TeamMembers.test.tsx:3993436101": [ - [1, 19, 13, "RegExp match", "2409514259"] - ], - "public/app/features/teams/TeamPages.test.tsx:1265047708": [ - [1, 19, 13, "RegExp match", "2409514259"] - ], - "public/app/features/teams/TeamSettings.test.tsx:2628968507": [ - [1, 19, 13, "RegExp match", "2409514259"] - ], - "public/app/features/users/UsersActionBar.test.tsx:4031641375": [ - [1, 19, 13, "RegExp match", "2409514259"] - ], - "public/app/features/users/UsersListPage.test.tsx:2626906707": [ - [1, 19, 13, "RegExp match", "2409514259"] - ], - "public/app/features/users/UsersTable.test.tsx:3051231816": [ - [1, 19, 13, "RegExp match", "2409514259"] - ], - "public/app/plugins/datasource/cloud-monitoring/components/Aggregation.test.tsx:2813729913": [ - [2, 19, 13, "RegExp match", "2409514259"] - ], - "public/app/plugins/datasource/cloudwatch/components/ConfigEditor.test.tsx:2974837543": [ - [1, 19, 13, "RegExp match", "2409514259"] - ], - "public/app/plugins/datasource/cloudwatch/components/LogsQueryField.test.tsx:3888529428": [ - [1, 19, 13, "RegExp match", "2409514259"] - ], - "public/app/plugins/datasource/elasticsearch/configuration/ConfigEditor.test.tsx:1089831034": [ - [1, 26, 13, "RegExp match", "2409514259"] - ], - "public/app/plugins/datasource/elasticsearch/configuration/DataLinks.test.tsx:2916632804": [ - [1, 17, 13, "RegExp match", "2409514259"] - ], - "public/app/plugins/datasource/grafana-azure-monitor-datasource/components/deprecated/components/InsightsConfig.test.tsx:1635510338": [ - [1, 19, 13, "RegExp match", "2409514259"] - ], - "public/app/plugins/datasource/influxdb/components/ConfigEditor.test.tsx:767000341": [ - [1, 19, 13, "RegExp match", "2409514259"] - ], - "public/app/plugins/datasource/loki/components/LokiExploreQueryEditor.test.tsx:2608233977": [ - [1, 26, 13, "RegExp match", "2409514259"] - ], - "public/app/plugins/datasource/loki/components/LokiQueryEditor.test.tsx:2337402520": [ - [1, 19, 13, "RegExp match", "2409514259"] - ], - "public/app/plugins/datasource/loki/configuration/ConfigEditor.test.tsx:1661240493": [ - [1, 17, 13, "RegExp match", "2409514259"] - ], - "public/app/plugins/datasource/loki/configuration/DebugSection.test.tsx:2909181412": [ - [1, 17, 13, "RegExp match", "2409514259"] - ], - "public/app/plugins/datasource/loki/configuration/DerivedField.test.tsx:1527527456": [ - [1, 19, 13, "RegExp match", "2409514259"] - ], - "public/app/plugins/datasource/loki/configuration/DerivedFields.test.tsx:2923116422": [ - [1, 17, 13, "RegExp match", "2409514259"] - ], - "public/app/plugins/datasource/prometheus/configuration/AzureCredentialsForm.test.tsx:1231427": [ - [1, 19, 13, "RegExp match", "2409514259"] - ], - "public/app/plugins/panel/bargauge/BarGaugePanel.test.tsx:1527575498": [ - [1, 31, 13, "RegExp match", "2409514259"] + "public/app/plugins/panel/bargauge/BarGaugePanel.test.tsx:1597135392": [ + [0, 31, 13, "RegExp match", "2409514259"] ] }` }; diff --git a/.eslintignore b/.eslintignore index 1cafcb9a2f0..60181e855a4 100644 --- a/.eslintignore +++ b/.eslintignore @@ -20,3 +20,6 @@ vendor # Auto-generated localisation files public/locales/_build/ public/locales/**/*.js + +# Auto-generated icon file +packages/grafana-ui/src/components/Icon/iconBundle.ts diff --git a/.eslintrc b/.eslintrc index 6c02955b708..107d97eb655 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,12 +1,24 @@ { "extends": ["@grafana/eslint-config"], "root": true, - "plugins": ["@emotion", "lodash", "jest"], + "plugins": ["@emotion", "lodash", "jest", "import"], + "settings": { + "import/internal-regex": "^(app/)|(@grafana)", + "import/external-module-folders": ["node_modules", ".yarn"] + }, "rules": { "react/prop-types": "off", "@emotion/jsx-import": "error", "lodash/import-scope": [2, "member"], - "jest/no-focused-tests": "error" + "jest/no-focused-tests": "error", + "import/order": [ + "error", + { + "groups": [["builtin", "external"], "internal", "parent", "sibling", "index"], + "newlines-between": "always", + "alphabetize": { "order": "asc" } + } + ] }, "overrides": [ { diff --git a/e2e/dashboards-suite/dashboard-time-zone.spec.ts b/e2e/dashboards-suite/dashboard-time-zone.spec.ts index e2e8a69432e..da3924ac58d 100644 --- a/e2e/dashboards-suite/dashboard-time-zone.spec.ts +++ b/e2e/dashboards-suite/dashboard-time-zone.spec.ts @@ -1,4 +1,3 @@ -import { e2e } from '@grafana/e2e'; import { addDays, addHours, @@ -10,6 +9,8 @@ import { toDate, } from 'date-fns'; +import { e2e } from '@grafana/e2e'; + e2e.scenario({ describeName: 'Dashboard time zone support', itName: 'Tests dashboard time zone scenarios', diff --git a/e2e/panels-suite/panelEdit_queries.spec.ts b/e2e/panels-suite/panelEdit_queries.spec.ts index 0276011ae2f..c6c46223064 100644 --- a/e2e/panels-suite/panelEdit_queries.spec.ts +++ b/e2e/panels-suite/panelEdit_queries.spec.ts @@ -1,4 +1,5 @@ import { e2e } from '@grafana/e2e'; + import { expect } from '../../public/test/lib/common'; const flakyTimeout = 10000; diff --git a/e2e/smoke-tests-suite/1-smoketests.spec.ts b/e2e/smoke-tests-suite/1-smoketests.spec.ts index 2049b329695..6f2b7a19311 100644 --- a/e2e/smoke-tests-suite/1-smoketests.spec.ts +++ b/e2e/smoke-tests-suite/1-smoketests.spec.ts @@ -1,4 +1,5 @@ import { e2e } from '@grafana/e2e'; + import { smokeTestScenario } from '../shared/smokeTestScenario'; e2e.scenario(smokeTestScenario); diff --git a/e2e/verify/specs/smoketests.spec.ts b/e2e/verify/specs/smoketests.spec.ts index 185eb389e0f..d3c99b62166 100644 --- a/e2e/verify/specs/smoketests.spec.ts +++ b/e2e/verify/specs/smoketests.spec.ts @@ -1,4 +1,5 @@ import { e2e } from '@grafana/e2e'; + import { smokeTestScenario } from '../../shared/smokeTestScenario'; e2e.scenario(smokeTestScenario); diff --git a/package.json b/package.json index 3dcbc26e117..f29a1f170c9 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "lint:ts": "eslint . --ext .js,.tsx,.ts --cache", "lint:sass": "yarn stylelint '{public/sass,packages}/**/*.scss' --cache", "test:ci": "betterer ci && mkdir -p reports/junit && JEST_JUNIT_OUTPUT_DIR=reports/junit jest --ci --reporters=default --reporters=jest-junit -w ${TEST_MAX_WORKERS:-100%}", - "lint:fix": "yarn lint --fix", + "lint:fix": "yarn lint:ts --fix", "packages:build": "lerna run clean && lerna run build --ignore @grafana-plugins/input-datasource", "packages:docsExtract": "rm -rf ./reports/docs && lerna run docsExtract", "packages:docsToMarkdown": "api-documenter markdown --input-folder ./reports/docs/ --output-folder ./docs/sources/packages_api/ --hugo", @@ -182,6 +182,7 @@ "enzyme-to-json": "3.6.2", "eslint": "8.11.0", "eslint-config-prettier": "8.5.0", + "eslint-plugin-import": "^2.26.0", "eslint-plugin-jest": "26.1.2", "eslint-plugin-jsdoc": "38.0.6", "eslint-plugin-lodash": "7.4.0", diff --git a/packages/grafana-data/rollup.config.ts b/packages/grafana-data/rollup.config.ts index 980cb3e04e7..f763dcad48a 100644 --- a/packages/grafana-data/rollup.config.ts +++ b/packages/grafana-data/rollup.config.ts @@ -1,9 +1,9 @@ -import resolve from '@rollup/plugin-node-resolve'; import commonjs from '@rollup/plugin-commonjs'; -import sourceMaps from 'rollup-plugin-sourcemaps'; import json from '@rollup/plugin-json'; -import { terser } from 'rollup-plugin-terser'; +import resolve from '@rollup/plugin-node-resolve'; import path from 'path'; +import sourceMaps from 'rollup-plugin-sourcemaps'; +import { terser } from 'rollup-plugin-terser'; const pkg = require('./package.json'); diff --git a/packages/grafana-data/src/dataframe/ArrayDataFrame.test.ts b/packages/grafana-data/src/dataframe/ArrayDataFrame.test.ts index bdc06797d82..20001cb4913 100644 --- a/packages/grafana-data/src/dataframe/ArrayDataFrame.test.ts +++ b/packages/grafana-data/src/dataframe/ArrayDataFrame.test.ts @@ -1,6 +1,7 @@ +import { FieldType, DataFrame } from '../types'; + import { ArrayDataFrame } from './ArrayDataFrame'; import { toDataFrameDTO } from './processDataFrame'; -import { FieldType, DataFrame } from '../types'; describe('Array DataFrame', () => { const input = [ diff --git a/packages/grafana-data/src/dataframe/ArrayDataFrame.ts b/packages/grafana-data/src/dataframe/ArrayDataFrame.ts index ff69a9efbb0..83b23d23778 100644 --- a/packages/grafana-data/src/dataframe/ArrayDataFrame.ts +++ b/packages/grafana-data/src/dataframe/ArrayDataFrame.ts @@ -1,8 +1,9 @@ -import { Field, FieldType, DataFrame } from '../types/dataFrame'; -import { vectorToArray } from '../vector/vectorToArray'; import { Vector, QueryResultMeta } from '../types'; -import { guessFieldTypeFromNameAndValue, toDataFrameDTO } from './processDataFrame'; +import { Field, FieldType, DataFrame } from '../types/dataFrame'; import { FunctionalVector } from '../vector/FunctionalVector'; +import { vectorToArray } from '../vector/vectorToArray'; + +import { guessFieldTypeFromNameAndValue, toDataFrameDTO } from './processDataFrame'; /** @public */ export type ValueConverter = (val: any) => T; diff --git a/packages/grafana-data/src/dataframe/CircularDataFrame.ts b/packages/grafana-data/src/dataframe/CircularDataFrame.ts index 890be6c2f50..ea39654d47c 100644 --- a/packages/grafana-data/src/dataframe/CircularDataFrame.ts +++ b/packages/grafana-data/src/dataframe/CircularDataFrame.ts @@ -1,6 +1,7 @@ -import { MutableDataFrame } from './MutableDataFrame'; import { CircularVector } from '../vector/CircularVector'; +import { MutableDataFrame } from './MutableDataFrame'; + interface CircularOptions { append?: 'head' | 'tail'; capacity?: number; diff --git a/packages/grafana-data/src/dataframe/DataFrameJSON.test.ts b/packages/grafana-data/src/dataframe/DataFrameJSON.test.ts index b9c73ae4de9..b9fadc6c4aa 100644 --- a/packages/grafana-data/src/dataframe/DataFrameJSON.test.ts +++ b/packages/grafana-data/src/dataframe/DataFrameJSON.test.ts @@ -1,4 +1,5 @@ import { FieldType } from '../types/dataFrame'; + import { DataFrameJSON, dataFrameFromJSON } from './DataFrameJSON'; describe('DataFrame JSON', () => { diff --git a/packages/grafana-data/src/dataframe/DataFrameJSON.ts b/packages/grafana-data/src/dataframe/DataFrameJSON.ts index d99e87ad22d..e57984fb3ba 100644 --- a/packages/grafana-data/src/dataframe/DataFrameJSON.ts +++ b/packages/grafana-data/src/dataframe/DataFrameJSON.ts @@ -1,5 +1,6 @@ import { DataFrame, FieldType, FieldConfig, Labels, QueryResultMeta } from '../types'; import { ArrayVector } from '../vector'; + import { guessFieldTypeFromNameAndValue } from './processDataFrame'; /** diff --git a/packages/grafana-data/src/dataframe/DataFrameView.test.ts b/packages/grafana-data/src/dataframe/DataFrameView.test.ts index 91368341aba..8975da7b24f 100644 --- a/packages/grafana-data/src/dataframe/DataFrameView.test.ts +++ b/packages/grafana-data/src/dataframe/DataFrameView.test.ts @@ -1,7 +1,8 @@ -import { FieldType, DataFrameDTO } from '../types/dataFrame'; import { DateTime } from '../datetime/moment_wrapper'; -import { MutableDataFrame } from './MutableDataFrame'; +import { FieldType, DataFrameDTO } from '../types/dataFrame'; + import { DataFrameView } from './DataFrameView'; +import { MutableDataFrame } from './MutableDataFrame'; interface MySpecialObject { time: DateTime; diff --git a/packages/grafana-data/src/dataframe/DataFrameView.ts b/packages/grafana-data/src/dataframe/DataFrameView.ts index 9f8880d1aa5..9f75cc701e7 100644 --- a/packages/grafana-data/src/dataframe/DataFrameView.ts +++ b/packages/grafana-data/src/dataframe/DataFrameView.ts @@ -1,5 +1,5 @@ -import { DataFrame, Field } from '../types/dataFrame'; import { DisplayProcessor } from '../types'; +import { DataFrame, Field } from '../types/dataFrame'; import { FunctionalVector } from '../vector/FunctionalVector'; /** diff --git a/packages/grafana-data/src/dataframe/FieldCache.test.ts b/packages/grafana-data/src/dataframe/FieldCache.test.ts index 80423614fb2..f6d5a90c8ca 100644 --- a/packages/grafana-data/src/dataframe/FieldCache.test.ts +++ b/packages/grafana-data/src/dataframe/FieldCache.test.ts @@ -1,5 +1,6 @@ -import { FieldCache } from './FieldCache'; import { FieldType } from '../types/dataFrame'; + +import { FieldCache } from './FieldCache'; import { toDataFrame } from './processDataFrame'; describe('FieldCache', () => { diff --git a/packages/grafana-data/src/dataframe/MutableDataFrame.test.ts b/packages/grafana-data/src/dataframe/MutableDataFrame.test.ts index 36881613bdc..7718c62e469 100644 --- a/packages/grafana-data/src/dataframe/MutableDataFrame.test.ts +++ b/packages/grafana-data/src/dataframe/MutableDataFrame.test.ts @@ -1,4 +1,5 @@ import { DataFrameDTO, FieldType } from '../types/dataFrame'; + import { MutableDataFrame } from './MutableDataFrame'; describe('Reversing DataFrame', () => { diff --git a/packages/grafana-data/src/dataframe/MutableDataFrame.ts b/packages/grafana-data/src/dataframe/MutableDataFrame.ts index 2597aa17d8f..3b4a603268b 100644 --- a/packages/grafana-data/src/dataframe/MutableDataFrame.ts +++ b/packages/grafana-data/src/dataframe/MutableDataFrame.ts @@ -1,12 +1,14 @@ -import { Field, DataFrame, DataFrameDTO, FieldDTO, FieldType } from '../types/dataFrame'; -import { QueryResultMeta } from '../types/data'; -import { guessFieldTypeFromValue, guessFieldTypeForField, toDataFrameDTO } from './processDataFrame'; import { isString } from 'lodash'; -import { makeFieldParser } from '../utils/fieldParser'; + +import { QueryResultMeta } from '../types/data'; +import { Field, DataFrame, DataFrameDTO, FieldDTO, FieldType } from '../types/dataFrame'; import { MutableVector, Vector } from '../types/vector'; +import { makeFieldParser } from '../utils/fieldParser'; import { ArrayVector } from '../vector/ArrayVector'; import { FunctionalVector } from '../vector/FunctionalVector'; +import { guessFieldTypeFromValue, guessFieldTypeForField, toDataFrameDTO } from './processDataFrame'; + export type MutableField = Field>; type MutableVectorCreator = (buffer?: any[]) => MutableVector; diff --git a/packages/grafana-data/src/dataframe/dimensions.ts b/packages/grafana-data/src/dataframe/dimensions.ts index e3b145566d0..629ddcbae7c 100644 --- a/packages/grafana-data/src/dataframe/dimensions.ts +++ b/packages/grafana-data/src/dataframe/dimensions.ts @@ -1,5 +1,5 @@ -import { Field } from '../types/dataFrame'; import { KeyValue } from '../types/data'; +import { Field } from '../types/dataFrame'; export interface Dimension { // Name of the dimension diff --git a/packages/grafana-data/src/dataframe/frameComparisons.test.ts b/packages/grafana-data/src/dataframe/frameComparisons.test.ts index efd3e242e8f..a5feae7d51c 100644 --- a/packages/grafana-data/src/dataframe/frameComparisons.test.ts +++ b/packages/grafana-data/src/dataframe/frameComparisons.test.ts @@ -1,4 +1,5 @@ import { FieldType } from '../types/dataFrame'; + import { compareDataFrameStructures, compareArrayValues } from './frameComparisons'; import { toDataFrame } from './processDataFrame'; diff --git a/packages/grafana-data/src/dataframe/processDataFrame.test.ts b/packages/grafana-data/src/dataframe/processDataFrame.test.ts index 29bc386967e..0683697263e 100644 --- a/packages/grafana-data/src/dataframe/processDataFrame.test.ts +++ b/packages/grafana-data/src/dataframe/processDataFrame.test.ts @@ -1,3 +1,8 @@ +import { dateTime } from '../datetime/moment_wrapper'; +import { DataFrameDTO, FieldType, TableData, TimeSeries } from '../types/index'; + +import { ArrayDataFrame } from './ArrayDataFrame'; +import { MutableDataFrame } from './MutableDataFrame'; import { guessFieldTypeFromValue, guessFieldTypes, @@ -7,10 +12,7 @@ import { toDataFrame, toLegacyResponseData, } from './processDataFrame'; -import { DataFrameDTO, FieldType, TableData, TimeSeries } from '../types/index'; -import { dateTime } from '../datetime/moment_wrapper'; -import { MutableDataFrame } from './MutableDataFrame'; -import { ArrayDataFrame } from './ArrayDataFrame'; + import { getFieldTypeFromValue } from '.'; describe('toDataFrame', () => { diff --git a/packages/grafana-data/src/dataframe/processDataFrame.ts b/packages/grafana-data/src/dataframe/processDataFrame.ts index d3478cac95b..c1148f5ebff 100644 --- a/packages/grafana-data/src/dataframe/processDataFrame.ts +++ b/packages/grafana-data/src/dataframe/processDataFrame.ts @@ -2,6 +2,9 @@ import { isArray, isBoolean, isNumber, isString } from 'lodash'; // Types +import { isDateTime } from '../datetime/moment_wrapper'; +import { fieldIndexComparer } from '../field/fieldComparers'; +import { getFieldDisplayName } from '../field/fieldState'; import { DataFrame, Field, @@ -17,15 +20,13 @@ import { TIME_SERIES_VALUE_FIELD_NAME, TIME_SERIES_TIME_FIELD_NAME, } from '../types/index'; -import { isDateTime } from '../datetime/moment_wrapper'; import { ArrayVector } from '../vector/ArrayVector'; -import { MutableDataFrame } from './MutableDataFrame'; import { SortedVector } from '../vector/SortedVector'; -import { ArrayDataFrame } from './ArrayDataFrame'; -import { getFieldDisplayName } from '../field/fieldState'; -import { fieldIndexComparer } from '../field/fieldComparers'; import { vectorToArray } from '../vector/vectorToArray'; + +import { ArrayDataFrame } from './ArrayDataFrame'; import { dataFrameFromJSON } from './DataFrameJSON'; +import { MutableDataFrame } from './MutableDataFrame'; function convertTableToDataFrame(table: TableData): DataFrame { const fields = table.columns.map((c) => { diff --git a/packages/grafana-data/src/dataframe/utils.test.ts b/packages/grafana-data/src/dataframe/utils.test.ts index 943a1d900bf..b291b732fd4 100644 --- a/packages/grafana-data/src/dataframe/utils.test.ts +++ b/packages/grafana-data/src/dataframe/utils.test.ts @@ -1,5 +1,6 @@ -import { toDataFrame } from './processDataFrame'; import { FieldType } from '../types'; + +import { toDataFrame } from './processDataFrame'; import { anySeriesWithTimeField } from './utils'; describe('anySeriesWithTimeField', () => { diff --git a/packages/grafana-data/src/dataframe/utils.ts b/packages/grafana-data/src/dataframe/utils.ts index 4044393d839..0869d2ec135 100644 --- a/packages/grafana-data/src/dataframe/utils.ts +++ b/packages/grafana-data/src/dataframe/utils.ts @@ -1,4 +1,5 @@ import { DataFrame, FieldType } from '../types/dataFrame'; + import { getTimeField } from './processDataFrame'; export function isTimeSerie(frame: DataFrame) { diff --git a/packages/grafana-data/src/datetime/datemath.test.ts b/packages/grafana-data/src/datetime/datemath.test.ts index 6033fc3530a..d644f3be4a1 100644 --- a/packages/grafana-data/src/datetime/datemath.test.ts +++ b/packages/grafana-data/src/datetime/datemath.test.ts @@ -1,5 +1,5 @@ -import sinon, { SinonFakeTimers } from 'sinon'; import { each } from 'lodash'; +import sinon, { SinonFakeTimers } from 'sinon'; import * as dateMath from './datemath'; import { dateTime, DurationUnit, DateTime } from './moment_wrapper'; diff --git a/packages/grafana-data/src/datetime/datemath.ts b/packages/grafana-data/src/datetime/datemath.ts index a14aceeb7e9..5478aa53edf 100644 --- a/packages/grafana-data/src/datetime/datemath.ts +++ b/packages/grafana-data/src/datetime/datemath.ts @@ -1,7 +1,9 @@ import { includes, isDate } from 'lodash'; -import { DateTime, dateTime, dateTimeForTimeZone, DurationUnit, isDateTime, ISO_8601 } from './moment_wrapper'; + import { TimeZone } from '../types/index'; +import { DateTime, dateTime, dateTimeForTimeZone, DurationUnit, isDateTime, ISO_8601 } from './moment_wrapper'; + const units: DurationUnit[] = ['y', 'M', 'w', 'd', 'h', 'm', 's', 'Q']; /** diff --git a/packages/grafana-data/src/datetime/durationutil.ts b/packages/grafana-data/src/datetime/durationutil.ts index 73185a2c29b..372144fd6cf 100644 --- a/packages/grafana-data/src/datetime/durationutil.ts +++ b/packages/grafana-data/src/datetime/durationutil.ts @@ -1,6 +1,6 @@ import { Duration, Interval } from 'date-fns'; -import intervalToDuration from 'date-fns/intervalToDuration'; import add from 'date-fns/add'; +import intervalToDuration from 'date-fns/intervalToDuration'; const durationMap: { [key in Required]: string[] } = { years: ['y', 'Y', 'years'], diff --git a/packages/grafana-data/src/datetime/formatter.ts b/packages/grafana-data/src/datetime/formatter.ts index 108f0a7d9ff..2b084ab62ca 100644 --- a/packages/grafana-data/src/datetime/formatter.ts +++ b/packages/grafana-data/src/datetime/formatter.ts @@ -1,9 +1,11 @@ /* eslint-disable id-blacklist, no-restricted-imports, @typescript-eslint/ban-types */ import moment, { MomentInput, Moment } from 'moment-timezone'; + import { TimeZone } from '../types'; -import { DateTimeInput } from './moment_wrapper'; -import { systemDateFormats } from './formats'; + import { DateTimeOptions, getTimeZone } from './common'; +import { systemDateFormats } from './formats'; +import { DateTimeInput } from './moment_wrapper'; /** * The type describing the options that can be passed to the {@link dateTimeFormat} diff --git a/packages/grafana-data/src/datetime/moment_wrapper.ts b/packages/grafana-data/src/datetime/moment_wrapper.ts index 80af4900f8e..c22b045d796 100644 --- a/packages/grafana-data/src/datetime/moment_wrapper.ts +++ b/packages/grafana-data/src/datetime/moment_wrapper.ts @@ -1,6 +1,7 @@ +import moment, { Moment, MomentInput, DurationInputArg1, DurationInputArg2 } from 'moment'; + import { TimeZone } from '../types/time'; /* eslint-disable id-blacklist, no-restricted-imports, @typescript-eslint/ban-types */ -import moment, { Moment, MomentInput, DurationInputArg1, DurationInputArg2 } from 'moment'; export interface DateTimeBuiltinFormat { __momentBuiltinFormatBrand: any; } diff --git a/packages/grafana-data/src/datetime/parser.test.ts b/packages/grafana-data/src/datetime/parser.test.ts index 62209df8315..ec9e216184c 100644 --- a/packages/grafana-data/src/datetime/parser.test.ts +++ b/packages/grafana-data/src/datetime/parser.test.ts @@ -1,5 +1,5 @@ -import { dateTimeParse } from './parser'; import { systemDateFormats } from './formats'; +import { dateTimeParse } from './parser'; describe('dateTimeParse', () => { it('should be able to parse using default format', () => { diff --git a/packages/grafana-data/src/datetime/parser.ts b/packages/grafana-data/src/datetime/parser.ts index 26901deaaee..9aaf6fcde1b 100644 --- a/packages/grafana-data/src/datetime/parser.ts +++ b/packages/grafana-data/src/datetime/parser.ts @@ -1,10 +1,11 @@ /* eslint-disable id-blacklist, no-restricted-imports, @typescript-eslint/ban-types */ +import { lowerCase } from 'lodash'; import moment, { MomentInput } from 'moment-timezone'; -import { DateTimeInput, DateTime, isDateTime } from './moment_wrapper'; + import { DateTimeOptions, getTimeZone } from './common'; import { parse, isValid } from './datemath'; -import { lowerCase } from 'lodash'; import { systemDateFormats } from './formats'; +import { DateTimeInput, DateTime, isDateTime } from './moment_wrapper'; /** * The type that describes options that can be passed when parsing a date and time value. diff --git a/packages/grafana-data/src/datetime/rangeutil.test.ts b/packages/grafana-data/src/datetime/rangeutil.test.ts index 9d3980fb35a..d3f376faefb 100644 --- a/packages/grafana-data/src/datetime/rangeutil.test.ts +++ b/packages/grafana-data/src/datetime/rangeutil.test.ts @@ -1,7 +1,9 @@ import { TimeRange } from '../types/time'; -import { dateTime, rangeUtil } from './index'; + import { timeRangeToRelative } from './rangeutil'; +import { dateTime, rangeUtil } from './index'; + describe('Range Utils', () => { describe('relative time', () => { it('should identify absolute vs relative', () => { diff --git a/packages/grafana-data/src/datetime/rangeutil.ts b/packages/grafana-data/src/datetime/rangeutil.ts index 16e34be35ea..ec0dded1a86 100644 --- a/packages/grafana-data/src/datetime/rangeutil.ts +++ b/packages/grafana-data/src/datetime/rangeutil.ts @@ -3,8 +3,8 @@ import { each, has } from 'lodash'; import { RawTimeRange, TimeRange, TimeZone, IntervalValues, RelativeTimeRange, TimeOption } from '../types/time'; import * as dateMath from './datemath'; -import { isDateTime, DateTime, dateTime } from './moment_wrapper'; import { timeZoneAbbrevation, dateTimeFormat, dateTimeFormatTimeAgo } from './formatter'; +import { isDateTime, DateTime, dateTime } from './moment_wrapper'; import { dateTimeParse } from './parser'; const spans: { [key: string]: { display: string; section?: number } } = { diff --git a/packages/grafana-data/src/datetime/timezones.test.ts b/packages/grafana-data/src/datetime/timezones.test.ts index cd78b67940b..04e49cc90c2 100644 --- a/packages/grafana-data/src/datetime/timezones.test.ts +++ b/packages/grafana-data/src/datetime/timezones.test.ts @@ -1,5 +1,5 @@ -import { getTimeZoneInfo } from './timezones'; import { setTimeZoneResolver } from './common'; +import { getTimeZoneInfo } from './timezones'; describe('getTimeZoneInfo', () => { // global timezone is set to Pacific/Easter, see jest-config.js file diff --git a/packages/grafana-data/src/datetime/timezones.ts b/packages/grafana-data/src/datetime/timezones.ts index efd198474da..6241dd35f43 100644 --- a/packages/grafana-data/src/datetime/timezones.ts +++ b/packages/grafana-data/src/datetime/timezones.ts @@ -1,6 +1,8 @@ -import moment from 'moment-timezone'; import { memoize } from 'lodash'; +import moment from 'moment-timezone'; + import { TimeZone } from '../types'; + import { getTimeZone } from './common'; export enum InternalTimeZones { diff --git a/packages/grafana-data/src/events/EventBus.test.ts b/packages/grafana-data/src/events/EventBus.test.ts index e0b0ca34c15..be189e409c5 100644 --- a/packages/grafana-data/src/events/EventBus.test.ts +++ b/packages/grafana-data/src/events/EventBus.test.ts @@ -1,7 +1,7 @@ import { EventBusSrv } from './EventBus'; -import { BusEvent, BusEventWithPayload } from './types'; -import { eventFactory } from './eventFactory'; import { DataHoverEvent } from './common'; +import { eventFactory } from './eventFactory'; +import { BusEvent, BusEventWithPayload } from './types'; interface LoginEventPayload { logins: number; diff --git a/packages/grafana-data/src/events/EventBus.ts b/packages/grafana-data/src/events/EventBus.ts index 2dd3e7a55b2..ca498274da7 100644 --- a/packages/grafana-data/src/events/EventBus.ts +++ b/packages/grafana-data/src/events/EventBus.ts @@ -1,6 +1,7 @@ import EventEmitter from 'eventemitter3'; import { Unsubscribable, Observable } from 'rxjs'; import { filter } from 'rxjs/operators'; + import { EventBus, LegacyEmitter, diff --git a/packages/grafana-data/src/events/common.ts b/packages/grafana-data/src/events/common.ts index 0bad1af0080..4ed44ff945a 100644 --- a/packages/grafana-data/src/events/common.ts +++ b/packages/grafana-data/src/events/common.ts @@ -1,4 +1,5 @@ import { AnnotationEvent, DataFrame } from '../types'; + import { BusEventBase, BusEventWithPayload } from './types'; /** diff --git a/packages/grafana-data/src/field/FieldConfigOptionsRegistry.tsx b/packages/grafana-data/src/field/FieldConfigOptionsRegistry.tsx index 9166a6bbda5..d1081ef0628 100644 --- a/packages/grafana-data/src/field/FieldConfigOptionsRegistry.tsx +++ b/packages/grafana-data/src/field/FieldConfigOptionsRegistry.tsx @@ -1,4 +1,4 @@ -import { Registry } from '../utils/Registry'; import { FieldConfigPropertyItem } from '../types/fieldOverrides'; +import { Registry } from '../utils/Registry'; export class FieldConfigOptionsRegistry extends Registry {} diff --git a/packages/grafana-data/src/field/displayProcessor.test.ts b/packages/grafana-data/src/field/displayProcessor.test.ts index f6e45e844d7..51767895d2c 100644 --- a/packages/grafana-data/src/field/displayProcessor.test.ts +++ b/packages/grafana-data/src/field/displayProcessor.test.ts @@ -1,9 +1,10 @@ -import { getDisplayProcessor, getRawDisplayProcessor } from './displayProcessor'; -import { DisplayProcessor, DisplayValue } from '../types/displayValue'; -import { MappingType, ValueMapping } from '../types/valueMapping'; -import { FieldConfig, FieldType, ThresholdsMode } from '../types'; import { systemDateFormats } from '../datetime'; import { createTheme } from '../themes'; +import { FieldConfig, FieldType, ThresholdsMode } from '../types'; +import { DisplayProcessor, DisplayValue } from '../types/displayValue'; +import { MappingType, ValueMapping } from '../types/valueMapping'; + +import { getDisplayProcessor, getRawDisplayProcessor } from './displayProcessor'; function getDisplayProcessorFromConfig(config: FieldConfig) { return getDisplayProcessor({ diff --git a/packages/grafana-data/src/field/displayProcessor.ts b/packages/grafana-data/src/field/displayProcessor.ts index c3cc793df99..f4a7a79f907 100644 --- a/packages/grafana-data/src/field/displayProcessor.ts +++ b/packages/grafana-data/src/field/displayProcessor.ts @@ -2,16 +2,17 @@ import { toString, toNumber as _toNumber, isEmpty, isBoolean, isArray, join } from 'lodash'; // Types +import { getFieldTypeFromValue } from '../dataframe/processDataFrame'; +import { toUtc, dateTimeParse } from '../datetime'; +import { GrafanaTheme2 } from '../themes/types'; +import { KeyValue, TimeZone } from '../types'; import { Field, FieldType } from '../types/dataFrame'; import { DisplayProcessor, DisplayValue } from '../types/displayValue'; -import { getValueFormat, isBooleanUnit } from '../valueFormats/valueFormats'; -import { getValueMappingResult } from '../utils/valueMappings'; -import { toUtc, dateTimeParse } from '../datetime'; -import { KeyValue, TimeZone } from '../types'; -import { getScaleCalculator } from './scale'; -import { GrafanaTheme2 } from '../themes/types'; import { anyToNumber } from '../utils/anyToNumber'; -import { getFieldTypeFromValue } from '../dataframe/processDataFrame'; +import { getValueMappingResult } from '../utils/valueMappings'; +import { getValueFormat, isBooleanUnit } from '../valueFormats/valueFormats'; + +import { getScaleCalculator } from './scale'; interface DisplayProcessorOptions { field: Partial; diff --git a/packages/grafana-data/src/field/fieldColor.test.ts b/packages/grafana-data/src/field/fieldColor.test.ts index 08eb1a0bbb7..46a708d0fcd 100644 --- a/packages/grafana-data/src/field/fieldColor.test.ts +++ b/packages/grafana-data/src/field/fieldColor.test.ts @@ -1,6 +1,7 @@ import { createTheme } from '../themes'; import { Field, FieldColorModeId, FieldType } from '../types'; import { ArrayVector } from '../vector/ArrayVector'; + import { fieldColorModeRegistry, FieldValueColorCalculator, getFieldSeriesColor } from './fieldColor'; function getTestField(mode: string): Field { diff --git a/packages/grafana-data/src/field/fieldColor.ts b/packages/grafana-data/src/field/fieldColor.ts index ffbdf95ac23..003b2e8c684 100644 --- a/packages/grafana-data/src/field/fieldColor.ts +++ b/packages/grafana-data/src/field/fieldColor.ts @@ -1,11 +1,13 @@ +import { interpolateRgbBasis } from 'd3-interpolate'; + +import { GrafanaTheme2 } from '../themes/types'; +import { reduceField } from '../transformations/fieldReducer'; import { FALLBACK_COLOR, Field, FieldColorModeId, Threshold } from '../types'; import { RegistryItem } from '../utils'; import { Registry } from '../utils/Registry'; -import { interpolateRgbBasis } from 'd3-interpolate'; -import { fallBackTreshold } from './thresholds'; + import { getScaleCalculator, ColorScaleValue } from './scale'; -import { reduceField } from '../transformations/fieldReducer'; -import { GrafanaTheme2 } from '../themes/types'; +import { fallBackTreshold } from './thresholds'; /** @beta */ export type FieldValueColorCalculator = (value: number, percent: number, Threshold?: Threshold) => string; diff --git a/packages/grafana-data/src/field/fieldComparers.ts b/packages/grafana-data/src/field/fieldComparers.ts index 1eab7665c67..3deb8f6c12e 100644 --- a/packages/grafana-data/src/field/fieldComparers.ts +++ b/packages/grafana-data/src/field/fieldComparers.ts @@ -1,7 +1,8 @@ +import { isNumber } from 'lodash'; + +import { dateTime } from '../datetime'; import { Field, FieldType } from '../types/dataFrame'; import { Vector } from '../types/vector'; -import { dateTime } from '../datetime'; -import { isNumber } from 'lodash'; type IndexComparer = (a: number, b: number) => number; diff --git a/packages/grafana-data/src/field/fieldDisplay.test.ts b/packages/grafana-data/src/field/fieldDisplay.test.ts index b36c909dfd2..2a8d91aed78 100644 --- a/packages/grafana-data/src/field/fieldDisplay.test.ts +++ b/packages/grafana-data/src/field/fieldDisplay.test.ts @@ -1,11 +1,13 @@ import { merge } from 'lodash'; -import { getFieldDisplayValues, GetFieldDisplayValuesOptions } from './fieldDisplay'; + import { toDataFrame } from '../dataframe/processDataFrame'; +import { createTheme } from '../themes'; import { ReducerID } from '../transformations/fieldReducer'; import { MappingType, SpecialValueMatch, ValueMapping } from '../types'; -import { standardFieldConfigEditorRegistry } from './standardFieldConfigEditorRegistry'; -import { createTheme } from '../themes'; + import { getDisplayProcessor } from './displayProcessor'; +import { getFieldDisplayValues, GetFieldDisplayValuesOptions } from './fieldDisplay'; +import { standardFieldConfigEditorRegistry } from './standardFieldConfigEditorRegistry'; describe('FieldDisplay', () => { beforeAll(() => { diff --git a/packages/grafana-data/src/field/fieldDisplay.ts b/packages/grafana-data/src/field/fieldDisplay.ts index c9bf243688a..ac4c8f8d7b9 100644 --- a/packages/grafana-data/src/field/fieldDisplay.ts +++ b/packages/grafana-data/src/field/fieldDisplay.ts @@ -1,6 +1,11 @@ import { toString, isEmpty } from 'lodash'; -import { getDisplayProcessor } from './displayProcessor'; +import { DataFrameView } from '../dataframe/DataFrameView'; +import { getTimeField } from '../dataframe/processDataFrame'; +import { GrafanaTheme2 } from '../themes'; +import { getFieldMatcher } from '../transformations'; +import { reduceField, ReducerID } from '../transformations/fieldReducer'; +import { FieldMatcherID } from '../transformations/matchers/ids'; import { DataFrame, DisplayValue, @@ -14,13 +19,9 @@ import { TimeRange, TimeZone, } from '../types'; -import { DataFrameView } from '../dataframe/DataFrameView'; -import { GrafanaTheme2 } from '../themes'; -import { reduceField, ReducerID } from '../transformations/fieldReducer'; import { ScopedVars } from '../types/ScopedVars'; -import { getTimeField } from '../dataframe/processDataFrame'; -import { getFieldMatcher } from '../transformations'; -import { FieldMatcherID } from '../transformations/matchers/ids'; + +import { getDisplayProcessor } from './displayProcessor'; import { getFieldDisplayName } from './fieldState'; /** diff --git a/packages/grafana-data/src/field/fieldOverrides.test.ts b/packages/grafana-data/src/field/fieldOverrides.test.ts index 7a88ba7251a..41dc112fdc4 100644 --- a/packages/grafana-data/src/field/fieldOverrides.test.ts +++ b/packages/grafana-data/src/field/fieldOverrides.test.ts @@ -1,13 +1,6 @@ -import { - applyFieldOverrides, - applyRawFieldOverrides, - FieldOverrideEnv, - findNumericFieldMinMax, - getLinksSupplier, - setDynamicConfigValue, - setFieldConfigDefaults, -} from './fieldOverrides'; import { ArrayDataFrame, MutableDataFrame, toDataFrame } from '../dataframe'; +import { createTheme } from '../themes'; +import { FieldMatcherID } from '../transformations'; import { DataFrame, Field, @@ -22,12 +15,20 @@ import { } from '../types'; import { locationUtil, Registry } from '../utils'; import { mockStandardProperties } from '../utils/tests/mockStandardProperties'; -import { FieldMatcherID } from '../transformations'; -import { FieldConfigOptionsRegistry } from './FieldConfigOptionsRegistry'; -import { getFieldDisplayName } from './fieldState'; import { ArrayVector } from '../vector'; + +import { FieldConfigOptionsRegistry } from './FieldConfigOptionsRegistry'; import { getDisplayProcessor } from './displayProcessor'; -import { createTheme } from '../themes'; +import { + applyFieldOverrides, + applyRawFieldOverrides, + FieldOverrideEnv, + findNumericFieldMinMax, + getLinksSupplier, + setDynamicConfigValue, + setFieldConfigDefaults, +} from './fieldOverrides'; +import { getFieldDisplayName } from './fieldState'; const property1: any = { id: 'custom.property1', // Match field properties diff --git a/packages/grafana-data/src/field/fieldOverrides.ts b/packages/grafana-data/src/field/fieldOverrides.ts index a2292847c2f..e656aeea158 100644 --- a/packages/grafana-data/src/field/fieldOverrides.ts +++ b/packages/grafana-data/src/field/fieldOverrides.ts @@ -1,3 +1,9 @@ +import { isNumber, set, unset, get, cloneDeep } from 'lodash'; + +import { guessFieldTypeForField } from '../dataframe'; +import { getTimeField } from '../dataframe/processDataFrame'; +import { asHexString } from '../themes/colorManipulator'; +import { fieldMatchers, reduceField, ReducerID } from '../transformations'; import { ApplyFieldOverrideOptions, DataFrame, @@ -18,21 +24,17 @@ import { TimeZone, ValueLinkConfig, } from '../types'; -import { fieldMatchers, reduceField, ReducerID } from '../transformations'; import { FieldMatcher } from '../types/transformations'; -import { isNumber, set, unset, get, cloneDeep } from 'lodash'; -import { getDisplayProcessor, getRawDisplayProcessor } from './displayProcessor'; -import { guessFieldTypeForField } from '../dataframe'; -import { standardFieldConfigEditorRegistry } from './standardFieldConfigEditorRegistry'; -import { FieldConfigOptionsRegistry } from './FieldConfigOptionsRegistry'; import { DataLinkBuiltInVars, locationUtil } from '../utils'; -import { formattedValueToString } from '../valueFormats'; -import { getFieldDisplayValuesProxy } from './getFieldDisplayValuesProxy'; -import { getFrameDisplayName } from './fieldState'; -import { getTimeField } from '../dataframe/processDataFrame'; import { mapInternalLinkToExplore } from '../utils/dataLinks'; +import { formattedValueToString } from '../valueFormats'; + +import { FieldConfigOptionsRegistry } from './FieldConfigOptionsRegistry'; +import { getDisplayProcessor, getRawDisplayProcessor } from './displayProcessor'; +import { getFrameDisplayName } from './fieldState'; +import { getFieldDisplayValuesProxy } from './getFieldDisplayValuesProxy'; +import { standardFieldConfigEditorRegistry } from './standardFieldConfigEditorRegistry'; import { getTemplateProxyForField } from './templateProxies'; -import { asHexString } from '../themes/colorManipulator'; interface OverrideProps { match: FieldMatcher; diff --git a/packages/grafana-data/src/field/fieldState.test.ts b/packages/grafana-data/src/field/fieldState.test.ts index 656016fb9b3..8be0a7d4ad3 100644 --- a/packages/grafana-data/src/field/fieldState.test.ts +++ b/packages/grafana-data/src/field/fieldState.test.ts @@ -1,6 +1,7 @@ -import { DataFrame, TIME_SERIES_VALUE_FIELD_NAME, FieldType } from '../types'; -import { getFieldDisplayName, getFrameDisplayName } from './fieldState'; import { toDataFrame } from '../dataframe'; +import { DataFrame, TIME_SERIES_VALUE_FIELD_NAME, FieldType } from '../types'; + +import { getFieldDisplayName, getFrameDisplayName } from './fieldState'; interface TitleScenario { frames: DataFrame[]; diff --git a/packages/grafana-data/src/field/getFieldDisplayValuesProxy.test.tsx b/packages/grafana-data/src/field/getFieldDisplayValuesProxy.test.tsx index 0efbb4e1ffd..92b9181fe72 100644 --- a/packages/grafana-data/src/field/getFieldDisplayValuesProxy.test.tsx +++ b/packages/grafana-data/src/field/getFieldDisplayValuesProxy.test.tsx @@ -1,8 +1,9 @@ -import { getFieldDisplayValuesProxy } from './getFieldDisplayValuesProxy'; -import { applyFieldOverrides } from './fieldOverrides'; import { MutableDataFrame, toDataFrame } from '../dataframe'; import { createTheme } from '../themes'; +import { applyFieldOverrides } from './fieldOverrides'; +import { getFieldDisplayValuesProxy } from './getFieldDisplayValuesProxy'; + describe('getFieldDisplayValuesProxy', () => { const shortTimeField = [{ name: 'Time', values: [1, 2, 3] }]; diff --git a/packages/grafana-data/src/field/getFieldDisplayValuesProxy.ts b/packages/grafana-data/src/field/getFieldDisplayValuesProxy.ts index 4faec716e4a..aaeeb81012a 100644 --- a/packages/grafana-data/src/field/getFieldDisplayValuesProxy.ts +++ b/packages/grafana-data/src/field/getFieldDisplayValuesProxy.ts @@ -1,6 +1,8 @@ import { toNumber } from 'lodash'; + import { DataFrame, DisplayValue, TimeZone } from '../types'; import { formattedValueToString } from '../valueFormats'; + import { getDisplayProcessor } from './displayProcessor'; /** diff --git a/packages/grafana-data/src/field/scale.test.ts b/packages/grafana-data/src/field/scale.test.ts index da8340a4bef..9cfd9dbb1ce 100644 --- a/packages/grafana-data/src/field/scale.test.ts +++ b/packages/grafana-data/src/field/scale.test.ts @@ -1,9 +1,10 @@ -import { ThresholdsMode, Field, FieldType, FieldColorModeId } from '../types'; -import { sortThresholds } from './thresholds'; -import { ArrayVector } from '../vector/ArrayVector'; -import { getScaleCalculator } from './scale'; import { createTheme } from '../themes'; +import { ThresholdsMode, Field, FieldType, FieldColorModeId } from '../types'; import { getColorForTheme } from '../utils'; +import { ArrayVector } from '../vector/ArrayVector'; + +import { getScaleCalculator } from './scale'; +import { sortThresholds } from './thresholds'; describe('getScaleCalculator', () => { it('should return percent, threshold and color', () => { diff --git a/packages/grafana-data/src/field/scale.ts b/packages/grafana-data/src/field/scale.ts index 822348edeb9..e97b01faf94 100644 --- a/packages/grafana-data/src/field/scale.ts +++ b/packages/grafana-data/src/field/scale.ts @@ -1,7 +1,9 @@ import { isNumber } from 'lodash'; + import { GrafanaTheme2 } from '../themes/types'; import { reduceField, ReducerID } from '../transformations/fieldReducer'; import { Field, FieldConfig, FieldType, NumericRange, Threshold } from '../types'; + import { getFieldColorModeForField } from './fieldColor'; import { getActiveThresholdForValue } from './thresholds'; diff --git a/packages/grafana-data/src/field/standardFieldConfigEditorRegistry.ts b/packages/grafana-data/src/field/standardFieldConfigEditorRegistry.ts index 9bc019c5fcb..f99d8decb8e 100644 --- a/packages/grafana-data/src/field/standardFieldConfigEditorRegistry.ts +++ b/packages/grafana-data/src/field/standardFieldConfigEditorRegistry.ts @@ -1,8 +1,10 @@ -import { Registry, RegistryItem } from '../utils/Registry'; import { ComponentType } from 'react'; -import { FieldConfigOptionsRegistry } from './FieldConfigOptionsRegistry'; -import { DataFrame, InterpolateFunction, VariableSuggestionsScope, VariableSuggestion } from '../types'; + import { EventBus } from '../events'; +import { DataFrame, InterpolateFunction, VariableSuggestionsScope, VariableSuggestion } from '../types'; +import { Registry, RegistryItem } from '../utils/Registry'; + +import { FieldConfigOptionsRegistry } from './FieldConfigOptionsRegistry'; export interface StandardEditorContext { data: DataFrame[]; // All results diff --git a/packages/grafana-data/src/field/templateProxies.test.ts b/packages/grafana-data/src/field/templateProxies.test.ts index d1ea6745aa2..154bd77628d 100644 --- a/packages/grafana-data/src/field/templateProxies.test.ts +++ b/packages/grafana-data/src/field/templateProxies.test.ts @@ -1,6 +1,7 @@ -import { getTemplateProxyForField } from './templateProxies'; import { toDataFrame } from '../dataframe'; +import { getTemplateProxyForField } from './templateProxies'; + describe('Template proxies', () => { it('supports name and displayName', () => { const frames = [ diff --git a/packages/grafana-data/src/field/templateProxies.ts b/packages/grafana-data/src/field/templateProxies.ts index c667ed874cb..28d553ec4f7 100644 --- a/packages/grafana-data/src/field/templateProxies.ts +++ b/packages/grafana-data/src/field/templateProxies.ts @@ -1,7 +1,8 @@ import { DataFrame, Field } from '../types'; -import { getFieldDisplayName } from './fieldState'; import { formatLabels } from '../utils/labels'; +import { getFieldDisplayName } from './fieldState'; + /** * This object is created often, and only used when tmplates exist. Using a proxy lets us delay * calculations of the more complex structures (label names) until they are actually used diff --git a/packages/grafana-data/src/field/thresholds.test.ts b/packages/grafana-data/src/field/thresholds.test.ts index 52b232b9346..500aae9170a 100644 --- a/packages/grafana-data/src/field/thresholds.test.ts +++ b/packages/grafana-data/src/field/thresholds.test.ts @@ -1,8 +1,9 @@ import { ThresholdsConfig, ThresholdsMode, FieldConfig, Threshold, Field, FieldType } from '../types'; -import { sortThresholds, getActiveThreshold, getActiveThresholdForValue } from './thresholds'; -import { validateFieldConfig } from './fieldOverrides'; import { ArrayVector } from '../vector/ArrayVector'; +import { validateFieldConfig } from './fieldOverrides'; +import { sortThresholds, getActiveThreshold, getActiveThresholdForValue } from './thresholds'; + describe('thresholds', () => { test('sort thresholds', () => { const thresholds: ThresholdsConfig = { diff --git a/packages/grafana-data/src/geo/layer.ts b/packages/grafana-data/src/geo/layer.ts index 88c22cda757..60463aa7ebc 100644 --- a/packages/grafana-data/src/geo/layer.ts +++ b/packages/grafana-data/src/geo/layer.ts @@ -1,10 +1,11 @@ -import { RegistryItemWithOptions } from '../utils/Registry'; -import { PanelData } from '../types'; -import { GrafanaTheme2 } from '../themes'; -import { PanelOptionsEditorBuilder } from '../utils'; -import { ReactNode } from 'react'; import { PluggableMap } from 'ol'; import BaseLayer from 'ol/layer/Base'; +import { ReactNode } from 'react'; + +import { GrafanaTheme2 } from '../themes'; +import { PanelData } from '../types'; +import { PanelOptionsEditorBuilder } from '../utils'; +import { RegistryItemWithOptions } from '../utils/Registry'; /** * @alpha diff --git a/packages/grafana-data/src/panel/PanelPlugin.test.tsx b/packages/grafana-data/src/panel/PanelPlugin.test.tsx index ad403c73779..074b60db072 100644 --- a/packages/grafana-data/src/panel/PanelPlugin.test.tsx +++ b/packages/grafana-data/src/panel/PanelPlugin.test.tsx @@ -1,8 +1,10 @@ import React from 'react'; -import { identityOverrideProcessor, standardEditorsRegistry, standardFieldConfigEditorRegistry } from '../field'; -import { PanelPlugin } from './PanelPlugin'; -import { FieldConfigProperty } from '../types'; + import { PanelOptionsEditorBuilder } from '..'; +import { identityOverrideProcessor, standardEditorsRegistry, standardFieldConfigEditorRegistry } from '../field'; +import { FieldConfigProperty } from '../types'; + +import { PanelPlugin } from './PanelPlugin'; describe('PanelPlugin', () => { describe('declarative options', () => { diff --git a/packages/grafana-data/src/panel/PanelPlugin.ts b/packages/grafana-data/src/panel/PanelPlugin.ts index a2efd5cb665..dfbb009efdc 100644 --- a/packages/grafana-data/src/panel/PanelPlugin.ts +++ b/packages/grafana-data/src/panel/PanelPlugin.ts @@ -1,3 +1,7 @@ +import { set } from 'lodash'; +import { ComponentClass, ComponentType } from 'react'; + +import { FieldConfigOptionsRegistry, StandardEditorContext } from '../field'; import { FieldConfigSource, GrafanaPlugin, @@ -10,11 +14,9 @@ import { PanelPluginDataSupport, VisualizationSuggestionsSupplier, } from '../types'; -import { FieldConfigEditorBuilder, PanelOptionsEditorBuilder } from '../utils/OptionsUIBuilders'; -import { ComponentClass, ComponentType } from 'react'; -import { set } from 'lodash'; import { deprecationWarning } from '../utils'; -import { FieldConfigOptionsRegistry, StandardEditorContext } from '../field'; +import { FieldConfigEditorBuilder, PanelOptionsEditorBuilder } from '../utils/OptionsUIBuilders'; + import { createFieldConfigRegistry } from './registryFactories'; /** @beta */ diff --git a/packages/grafana-data/src/panel/registryFactories.ts b/packages/grafana-data/src/panel/registryFactories.ts index df811a35e20..0e007bc8ad0 100644 --- a/packages/grafana-data/src/panel/registryFactories.ts +++ b/packages/grafana-data/src/panel/registryFactories.ts @@ -2,6 +2,7 @@ import { FieldConfigOptionsRegistry } from '../field/FieldConfigOptionsRegistry' import { standardFieldConfigEditorRegistry } from '../field/standardFieldConfigEditorRegistry'; import { FieldConfigProperty, FieldConfigPropertyItem } from '../types/fieldOverrides'; import { FieldConfigEditorBuilder } from '../utils/OptionsUIBuilders'; + import { SetFieldConfigOptionsArgs } from './PanelPlugin'; /** diff --git a/packages/grafana-data/src/text/markdown.ts b/packages/grafana-data/src/text/markdown.ts index 5335d47145d..c93173828ff 100644 --- a/packages/grafana-data/src/text/markdown.ts +++ b/packages/grafana-data/src/text/markdown.ts @@ -1,4 +1,5 @@ import { marked } from 'marked'; + import { sanitize, sanitizeTextPanelContent } from './sanitize'; let hasInitialized = false; diff --git a/packages/grafana-data/src/text/sanitize.ts b/packages/grafana-data/src/text/sanitize.ts index 4a298f88db7..1539e83ed4d 100644 --- a/packages/grafana-data/src/text/sanitize.ts +++ b/packages/grafana-data/src/text/sanitize.ts @@ -1,5 +1,5 @@ -import * as xss from 'xss'; import { sanitizeUrl as braintreeSanitizeUrl } from '@braintree/sanitize-url'; +import * as xss from 'xss'; const XSSWL = Object.keys(xss.whiteList).reduce((acc, element) => { acc[element] = xss.whiteList[element]?.concat(['class', 'style']); diff --git a/packages/grafana-data/src/themes/createColors.ts b/packages/grafana-data/src/themes/createColors.ts index c98098d54f8..134c947721a 100644 --- a/packages/grafana-data/src/themes/createColors.ts +++ b/packages/grafana-data/src/themes/createColors.ts @@ -1,4 +1,5 @@ import { merge } from 'lodash'; + import { alpha, darken, emphasize, getContrastRatio, lighten } from './colorManipulator'; import { palette } from './palette'; import { DeepPartial, ThemeRichColor } from './types'; diff --git a/packages/grafana-data/src/themes/createTheme.ts b/packages/grafana-data/src/themes/createTheme.ts index 7b528b1bc9a..b445c170bb5 100644 --- a/packages/grafana-data/src/themes/createTheme.ts +++ b/packages/grafana-data/src/themes/createTheme.ts @@ -1,15 +1,15 @@ import { createBreakpoints } from './breakpoints'; -import { createComponents } from './createComponents'; import { createColors, ThemeColorsInput } from './createColors'; +import { createComponents } from './createComponents'; import { createShadows } from './createShadows'; import { createShape, ThemeShapeInput } from './createShape'; import { createSpacing, ThemeSpacingOptions } from './createSpacing'; import { createTransitions } from './createTransitions'; import { createTypography, ThemeTypographyInput } from './createTypography'; import { createV1Theme } from './createV1Theme'; +import { createVisualizationColors } from './createVisualizationColors'; import { GrafanaTheme2 } from './types'; import { zIndex } from './zIndex'; -import { createVisualizationColors } from './createVisualizationColors'; /** @internal */ export interface NewThemeOptions { diff --git a/packages/grafana-data/src/themes/createV1Theme.ts b/packages/grafana-data/src/themes/createV1Theme.ts index aacff43a32b..a4754db37e6 100644 --- a/packages/grafana-data/src/themes/createV1Theme.ts +++ b/packages/grafana-data/src/themes/createV1Theme.ts @@ -1,4 +1,5 @@ import { GrafanaTheme, GrafanaThemeCommons, GrafanaThemeType } from '../types'; + import { GrafanaTheme2 } from './types'; export function createV1Theme(theme: Omit): GrafanaTheme { diff --git a/packages/grafana-data/src/themes/createVisualizationColors.ts b/packages/grafana-data/src/themes/createVisualizationColors.ts index 3a9a442180a..258cbe887be 100644 --- a/packages/grafana-data/src/themes/createVisualizationColors.ts +++ b/packages/grafana-data/src/themes/createVisualizationColors.ts @@ -1,4 +1,5 @@ import { FALLBACK_COLOR } from '../types'; + import { ThemeColors } from './createColors'; /** diff --git a/packages/grafana-data/src/themes/types.ts b/packages/grafana-data/src/themes/types.ts index d9b4595154c..0857a5da886 100644 --- a/packages/grafana-data/src/themes/types.ts +++ b/packages/grafana-data/src/themes/types.ts @@ -1,14 +1,15 @@ import { GrafanaTheme } from '../types/theme'; + import { ThemeBreakpoints } from './breakpoints'; -import { ThemeComponents } from './createComponents'; import { ThemeColors } from './createColors'; +import { ThemeComponents } from './createComponents'; import { ThemeShadows } from './createShadows'; import { ThemeShape } from './createShape'; import { ThemeSpacing } from './createSpacing'; import { ThemeTransitions } from './createTransitions'; import { ThemeTypography } from './createTypography'; -import { ThemeZIndices } from './zIndex'; import { ThemeVisualizationColors } from './createVisualizationColors'; +import { ThemeZIndices } from './zIndex'; /** * @beta diff --git a/packages/grafana-data/src/transformations/fieldReducer.test.ts b/packages/grafana-data/src/transformations/fieldReducer.test.ts index ec22d69f552..243479b7f2d 100644 --- a/packages/grafana-data/src/transformations/fieldReducer.test.ts +++ b/packages/grafana-data/src/transformations/fieldReducer.test.ts @@ -1,12 +1,12 @@ import { difference } from 'lodash'; -import { fieldReducers, ReducerID, reduceField } from './fieldReducer'; - -import { Field, FieldType } from '../types/index'; -import { guessFieldTypeFromValue } from '../dataframe/processDataFrame'; import { MutableDataFrame } from '../dataframe/MutableDataFrame'; +import { guessFieldTypeFromValue } from '../dataframe/processDataFrame'; +import { Field, FieldType } from '../types/index'; import { ArrayVector } from '../vector/ArrayVector'; +import { fieldReducers, ReducerID, reduceField } from './fieldReducer'; + /** * Run a reducer and get back the value */ diff --git a/packages/grafana-data/src/transformations/matchers.ts b/packages/grafana-data/src/transformations/matchers.ts index aa5e6c7c8b2..603fdcbca2d 100644 --- a/packages/grafana-data/src/transformations/matchers.ts +++ b/packages/grafana-data/src/transformations/matchers.ts @@ -1,8 +1,4 @@ // Load the Builtin matchers -import { getFieldPredicateMatchers, getFramePredicateMatchers } from './matchers/predicates'; -import { getFieldNameMatchers, getFrameNameMatchers } from './matchers/nameMatcher'; -import { getFieldTypeMatchers } from './matchers/fieldTypeMatcher'; -import { getRefIdMatchers } from './matchers/refIdMatcher'; import { FieldMatcherInfo, MatcherConfig, @@ -13,11 +9,16 @@ import { ValueMatcher, } from '../types/transformations'; import { Registry } from '../utils/Registry'; + +import { getFieldTypeMatchers } from './matchers/fieldTypeMatcher'; +import { getFieldNameMatchers, getFrameNameMatchers } from './matchers/nameMatcher'; +import { getFieldPredicateMatchers, getFramePredicateMatchers } from './matchers/predicates'; +import { getRefIdMatchers } from './matchers/refIdMatcher'; +import { getSimpleFieldMatchers } from './matchers/simpleFieldMatcher'; +import { getEqualValueMatchers } from './matchers/valueMatchers/equalMatchers'; import { getNullValueMatchers } from './matchers/valueMatchers/nullMatchers'; import { getNumericValueMatchers } from './matchers/valueMatchers/numericMatchers'; -import { getEqualValueMatchers } from './matchers/valueMatchers/equalMatchers'; import { getRangeValueMatchers } from './matchers/valueMatchers/rangeMatchers'; -import { getSimpleFieldMatchers } from './matchers/simpleFieldMatcher'; import { getRegexValueMatcher } from './matchers/valueMatchers/regexMatchers'; /** diff --git a/packages/grafana-data/src/transformations/matchers/fieldTypeMatcher.test.ts b/packages/grafana-data/src/transformations/matchers/fieldTypeMatcher.test.ts index c6370b0ba8e..af055205159 100644 --- a/packages/grafana-data/src/transformations/matchers/fieldTypeMatcher.test.ts +++ b/packages/grafana-data/src/transformations/matchers/fieldTypeMatcher.test.ts @@ -1,7 +1,8 @@ +import { toDataFrame } from '../../dataframe/processDataFrame'; import { FieldType } from '../../types/dataFrame'; import { fieldMatchers } from '../matchers'; + import { FieldMatcherID } from './ids'; -import { toDataFrame } from '../../dataframe/processDataFrame'; export const simpleSeriesWithTypes = toDataFrame({ fields: [ diff --git a/packages/grafana-data/src/transformations/matchers/fieldTypeMatcher.ts b/packages/grafana-data/src/transformations/matchers/fieldTypeMatcher.ts index 4cb8201c08b..23967cad334 100644 --- a/packages/grafana-data/src/transformations/matchers/fieldTypeMatcher.ts +++ b/packages/grafana-data/src/transformations/matchers/fieldTypeMatcher.ts @@ -1,7 +1,8 @@ import { Field, FieldType, DataFrame } from '../../types/dataFrame'; -import { FieldMatcherID } from './ids'; import { FieldMatcherInfo } from '../../types/transformations'; +import { FieldMatcherID } from './ids'; + // General Field matcher const fieldTypeMatcher: FieldMatcherInfo = { id: FieldMatcherID.byType, diff --git a/packages/grafana-data/src/transformations/matchers/matchers.test.ts b/packages/grafana-data/src/transformations/matchers/matchers.test.ts index 81ea76b2b75..5ba48c3f3b2 100644 --- a/packages/grafana-data/src/transformations/matchers/matchers.test.ts +++ b/packages/grafana-data/src/transformations/matchers/matchers.test.ts @@ -1,4 +1,5 @@ import { fieldMatchers } from '../matchers'; + import { FieldMatcherID } from './ids'; describe('Matchers', () => { diff --git a/packages/grafana-data/src/transformations/matchers/nameMatcher.test.ts b/packages/grafana-data/src/transformations/matchers/nameMatcher.test.ts index 1ca7c454166..df611f50bcb 100644 --- a/packages/grafana-data/src/transformations/matchers/nameMatcher.test.ts +++ b/packages/grafana-data/src/transformations/matchers/nameMatcher.test.ts @@ -1,6 +1,7 @@ -import { getFieldMatcher } from '../matchers'; -import { FieldMatcherID } from './ids'; import { toDataFrame } from '../../dataframe/processDataFrame'; +import { getFieldMatcher } from '../matchers'; + +import { FieldMatcherID } from './ids'; import { ByNamesMatcherMode } from './nameMatcher'; describe('Field Name by Regexp Matcher', () => { diff --git a/packages/grafana-data/src/transformations/matchers/nameMatcher.ts b/packages/grafana-data/src/transformations/matchers/nameMatcher.ts index 2f7f6b34687..45f3e75606b 100644 --- a/packages/grafana-data/src/transformations/matchers/nameMatcher.ts +++ b/packages/grafana-data/src/transformations/matchers/nameMatcher.ts @@ -1,8 +1,9 @@ -import { Field, DataFrame } from '../../types/dataFrame'; -import { FieldMatcherID, FrameMatcherID } from './ids'; -import { FieldMatcherInfo, FrameMatcherInfo, FieldMatcher } from '../../types/transformations'; -import { stringToJsRegex } from '../../text/string'; import { getFieldDisplayName } from '../../field/fieldState'; +import { stringToJsRegex } from '../../text/string'; +import { Field, DataFrame } from '../../types/dataFrame'; +import { FieldMatcherInfo, FrameMatcherInfo, FieldMatcher } from '../../types/transformations'; + +import { FieldMatcherID, FrameMatcherID } from './ids'; export interface RegexpOrNamesMatcherOptions { pattern?: string; diff --git a/packages/grafana-data/src/transformations/matchers/predicates.test.ts b/packages/grafana-data/src/transformations/matchers/predicates.test.ts index ef007b5dc28..708d9aa8b9f 100644 --- a/packages/grafana-data/src/transformations/matchers/predicates.test.ts +++ b/packages/grafana-data/src/transformations/matchers/predicates.test.ts @@ -1,8 +1,9 @@ import { FieldType } from '../../types/dataFrame'; +import { MatcherConfig } from '../../types/transformations'; import { fieldMatchers } from '../matchers'; + import { simpleSeriesWithTypes } from './fieldTypeMatcher.test'; import { FieldMatcherID, MatcherID } from './ids'; -import { MatcherConfig } from '../../types/transformations'; const matchesNumberConfig: MatcherConfig = { id: FieldMatcherID.byType, diff --git a/packages/grafana-data/src/transformations/matchers/predicates.ts b/packages/grafana-data/src/transformations/matchers/predicates.ts index cf0b2a90ded..386d87b69fe 100644 --- a/packages/grafana-data/src/transformations/matchers/predicates.ts +++ b/packages/grafana-data/src/transformations/matchers/predicates.ts @@ -1,7 +1,8 @@ import { Field, DataFrame, FieldType } from '../../types/dataFrame'; -import { MatcherID } from './ids'; -import { getFieldMatcher, fieldMatchers, getFrameMatchers, frameMatchers } from '../matchers'; import { FieldMatcherInfo, MatcherConfig, FrameMatcherInfo } from '../../types/transformations'; +import { getFieldMatcher, fieldMatchers, getFrameMatchers, frameMatchers } from '../matchers'; + +import { MatcherID } from './ids'; const anyFieldMatcher: FieldMatcherInfo = { id: MatcherID.anyMatch, diff --git a/packages/grafana-data/src/transformations/matchers/refIdMatcher.ts b/packages/grafana-data/src/transformations/matchers/refIdMatcher.ts index a8e0aa99ede..1c9d5d5869d 100644 --- a/packages/grafana-data/src/transformations/matchers/refIdMatcher.ts +++ b/packages/grafana-data/src/transformations/matchers/refIdMatcher.ts @@ -1,7 +1,8 @@ -import { DataFrame } from '../../types/dataFrame'; -import { FrameMatcherID } from './ids'; -import { FrameMatcherInfo } from '../../types/transformations'; import { stringToJsRegex } from '../../text'; +import { DataFrame } from '../../types/dataFrame'; +import { FrameMatcherInfo } from '../../types/transformations'; + +import { FrameMatcherID } from './ids'; // General Field matcher const refIdMacher: FrameMatcherInfo = { diff --git a/packages/grafana-data/src/transformations/matchers/simpleFieldMatcher.ts b/packages/grafana-data/src/transformations/matchers/simpleFieldMatcher.ts index b32dfaf715c..70899669774 100644 --- a/packages/grafana-data/src/transformations/matchers/simpleFieldMatcher.ts +++ b/packages/grafana-data/src/transformations/matchers/simpleFieldMatcher.ts @@ -1,7 +1,8 @@ import { Field, FieldType, DataFrame } from '../../types/dataFrame'; -import { FieldMatcherID } from './ids'; import { FieldMatcherInfo } from '../../types/transformations'; +import { FieldMatcherID } from './ids'; + const firstFieldMatcher: FieldMatcherInfo = { id: FieldMatcherID.first, name: 'First Field', diff --git a/packages/grafana-data/src/transformations/matchers/valueMatchers/equalMatchers.ts b/packages/grafana-data/src/transformations/matchers/valueMatchers/equalMatchers.ts index c6b3deacdd4..3b9e4c3721a 100644 --- a/packages/grafana-data/src/transformations/matchers/valueMatchers/equalMatchers.ts +++ b/packages/grafana-data/src/transformations/matchers/valueMatchers/equalMatchers.ts @@ -1,6 +1,7 @@ import { Field } from '../../../types/dataFrame'; import { ValueMatcherInfo } from '../../../types/transformations'; import { ValueMatcherID } from '../ids'; + import { BasicValueMatcherOptions } from './types'; const isEqualValueMatcher: ValueMatcherInfo = { diff --git a/packages/grafana-data/src/transformations/matchers/valueMatchers/nullMatchers.ts b/packages/grafana-data/src/transformations/matchers/valueMatchers/nullMatchers.ts index e3f19a68d97..10e78201dbf 100644 --- a/packages/grafana-data/src/transformations/matchers/valueMatchers/nullMatchers.ts +++ b/packages/grafana-data/src/transformations/matchers/valueMatchers/nullMatchers.ts @@ -1,6 +1,7 @@ import { Field } from '../../../types/dataFrame'; import { ValueMatcherInfo } from '../../../types/transformations'; import { ValueMatcherID } from '../ids'; + import { ValueMatcherOptions } from './types'; const isNullValueMatcher: ValueMatcherInfo = { diff --git a/packages/grafana-data/src/transformations/matchers/valueMatchers/numericMatchers.ts b/packages/grafana-data/src/transformations/matchers/valueMatchers/numericMatchers.ts index 339cb0554dc..e2f24e6d98f 100644 --- a/packages/grafana-data/src/transformations/matchers/valueMatchers/numericMatchers.ts +++ b/packages/grafana-data/src/transformations/matchers/valueMatchers/numericMatchers.ts @@ -1,6 +1,7 @@ import { Field, FieldType } from '../../../types/dataFrame'; import { ValueMatcherInfo } from '../../../types/transformations'; import { ValueMatcherID } from '../ids'; + import { BasicValueMatcherOptions } from './types'; const isGreaterValueMatcher: ValueMatcherInfo> = { diff --git a/packages/grafana-data/src/transformations/matchers/valueMatchers/rangeMatchers.ts b/packages/grafana-data/src/transformations/matchers/valueMatchers/rangeMatchers.ts index 17edb0d4d41..45c438c1830 100644 --- a/packages/grafana-data/src/transformations/matchers/valueMatchers/rangeMatchers.ts +++ b/packages/grafana-data/src/transformations/matchers/valueMatchers/rangeMatchers.ts @@ -1,6 +1,7 @@ import { Field, FieldType } from '../../../types/dataFrame'; import { ValueMatcherInfo } from '../../../types/transformations'; import { ValueMatcherID } from '../ids'; + import { RangeValueMatcherOptions } from './types'; const isBetweenValueMatcher: ValueMatcherInfo> = { diff --git a/packages/grafana-data/src/transformations/matchers/valueMatchers/regexMatchers.ts b/packages/grafana-data/src/transformations/matchers/valueMatchers/regexMatchers.ts index b4b1590fd4b..92ec6582f33 100644 --- a/packages/grafana-data/src/transformations/matchers/valueMatchers/regexMatchers.ts +++ b/packages/grafana-data/src/transformations/matchers/valueMatchers/regexMatchers.ts @@ -1,6 +1,7 @@ import { Field } from '../../../types/dataFrame'; import { ValueMatcherInfo } from '../../../types/transformations'; import { ValueMatcherID } from '../ids'; + import { BasicValueMatcherOptions } from './types'; const regexValueMatcher: ValueMatcherInfo> = { diff --git a/packages/grafana-data/src/transformations/standardTransformersRegistry.ts b/packages/grafana-data/src/transformations/standardTransformersRegistry.ts index dc9fbaca85f..73d79a351ba 100644 --- a/packages/grafana-data/src/transformations/standardTransformersRegistry.ts +++ b/packages/grafana-data/src/transformations/standardTransformersRegistry.ts @@ -1,4 +1,5 @@ import React from 'react'; + import { DataFrame, DataTransformerInfo } from '../types'; import { Registry, RegistryItem } from '../utils/Registry'; diff --git a/packages/grafana-data/src/transformations/transformDataFrame.test.ts b/packages/grafana-data/src/transformations/transformDataFrame.test.ts index 6fefc2ae139..08412b09b68 100644 --- a/packages/grafana-data/src/transformations/transformDataFrame.test.ts +++ b/packages/grafana-data/src/transformations/transformDataFrame.test.ts @@ -1,11 +1,12 @@ -import { ReducerID } from './fieldReducer'; -import { DataTransformerID } from './transformers/ids'; import { toDataFrame } from '../dataframe/processDataFrame'; -import { mockTransformationsRegistry } from '../utils/tests/mockTransformationsRegistry'; -import { reduceTransformer } from './transformers/reduce'; -import { filterFieldsByNameTransformer } from './transformers/filterByName'; -import { transformDataFrame } from './transformDataFrame'; import { FieldType } from '../types'; +import { mockTransformationsRegistry } from '../utils/tests/mockTransformationsRegistry'; + +import { ReducerID } from './fieldReducer'; +import { transformDataFrame } from './transformDataFrame'; +import { filterFieldsByNameTransformer } from './transformers/filterByName'; +import { DataTransformerID } from './transformers/ids'; +import { reduceTransformer } from './transformers/reduce'; const seriesAWithSingleField = toDataFrame({ name: 'A', diff --git a/packages/grafana-data/src/transformations/transformDataFrame.ts b/packages/grafana-data/src/transformations/transformDataFrame.ts index 7f46fee8e50..14d3800e176 100644 --- a/packages/grafana-data/src/transformations/transformDataFrame.ts +++ b/packages/grafana-data/src/transformations/transformDataFrame.ts @@ -2,6 +2,7 @@ import { MonoTypeOperatorFunction, Observable, of } from 'rxjs'; import { map, mergeMap } from 'rxjs/operators'; import { DataFrame, DataTransformerConfig } from '../types'; + import { standardTransformersRegistry, TransformerRegistryItem } from './standardTransformersRegistry'; const getOperator = diff --git a/packages/grafana-data/src/transformations/transformers.ts b/packages/grafana-data/src/transformations/transformers.ts index 063e9f8ddf4..3836a6929da 100644 --- a/packages/grafana-data/src/transformations/transformers.ts +++ b/packages/grafana-data/src/transformations/transformers.ts @@ -1,25 +1,25 @@ -import { reduceTransformer } from './transformers/reduce'; -import { concatenateTransformer } from './transformers/concat'; import { calculateFieldTransformer } from './transformers/calculateField'; +import { concatenateTransformer } from './transformers/concat'; +import { convertFieldTypeTransformer } from './transformers/convertFieldType'; +import { ensureColumnsTransformer } from './transformers/ensureColumns'; import { filterFieldsTransformer, filterFramesTransformer } from './transformers/filter'; import { filterFieldsByNameTransformer } from './transformers/filterByName'; -import { noopTransformer } from './transformers/noop'; import { filterFramesByRefIdTransformer } from './transformers/filterByRefId'; +import { filterByValueTransformer } from './transformers/filterByValue'; +import { groupByTransformer } from './transformers/groupBy'; +import { groupingToMatrixTransformer } from './transformers/groupingToMatrix'; +import { histogramTransformer } from './transformers/histogram'; +import { labelsToFieldsTransformer } from './transformers/labelsToFields'; +import { mergeTransformer } from './transformers/merge'; +import { noopTransformer } from './transformers/noop'; import { orderFieldsTransformer } from './transformers/order'; import { organizeFieldsTransformer } from './transformers/organize'; +import { reduceTransformer } from './transformers/reduce'; +import { renameFieldsTransformer } from './transformers/rename'; +import { renameByRegexTransformer } from './transformers/renameByRegex'; import { seriesToColumnsTransformer } from './transformers/seriesToColumns'; import { seriesToRowsTransformer } from './transformers/seriesToRows'; -import { renameFieldsTransformer } from './transformers/rename'; -import { labelsToFieldsTransformer } from './transformers/labelsToFields'; -import { ensureColumnsTransformer } from './transformers/ensureColumns'; -import { groupByTransformer } from './transformers/groupBy'; import { sortByTransformer } from './transformers/sortBy'; -import { mergeTransformer } from './transformers/merge'; -import { renameByRegexTransformer } from './transformers/renameByRegex'; -import { filterByValueTransformer } from './transformers/filterByValue'; -import { histogramTransformer } from './transformers/histogram'; -import { convertFieldTypeTransformer } from './transformers/convertFieldType'; -import { groupingToMatrixTransformer } from './transformers/groupingToMatrix'; export const standardTransformers = { noopTransformer, diff --git a/packages/grafana-data/src/transformations/transformers/calculateField.test.ts b/packages/grafana-data/src/transformations/transformers/calculateField.test.ts index 5f0a6be0cd5..0ebf4030b33 100644 --- a/packages/grafana-data/src/transformations/transformers/calculateField.test.ts +++ b/packages/grafana-data/src/transformations/transformers/calculateField.test.ts @@ -1,13 +1,14 @@ -import { DataTransformerID } from './ids'; -import { toDataFrame } from '../../dataframe/processDataFrame'; -import { FieldType } from '../../types/dataFrame'; -import { ReducerID } from '../fieldReducer'; -import { mockTransformationsRegistry } from '../../utils/tests/mockTransformationsRegistry'; -import { transformDataFrame } from '../transformDataFrame'; -import { CalculateFieldMode, calculateFieldTransformer, ReduceOptions } from './calculateField'; import { DataFrameView } from '../../dataframe'; -import { BinaryOperationID } from '../../utils'; +import { toDataFrame } from '../../dataframe/processDataFrame'; import { ScopedVars } from '../../types'; +import { FieldType } from '../../types/dataFrame'; +import { BinaryOperationID } from '../../utils'; +import { mockTransformationsRegistry } from '../../utils/tests/mockTransformationsRegistry'; +import { ReducerID } from '../fieldReducer'; +import { transformDataFrame } from '../transformDataFrame'; + +import { CalculateFieldMode, calculateFieldTransformer, ReduceOptions } from './calculateField'; +import { DataTransformerID } from './ids'; const seriesA = toDataFrame({ fields: [ diff --git a/packages/grafana-data/src/transformations/transformers/calculateField.ts b/packages/grafana-data/src/transformations/transformers/calculateField.ts index e49920f803a..9462d56d113 100644 --- a/packages/grafana-data/src/transformations/transformers/calculateField.ts +++ b/packages/grafana-data/src/transformations/transformers/calculateField.ts @@ -1,18 +1,19 @@ +import { defaults } from 'lodash'; import { map } from 'rxjs/operators'; +import { getTimeField } from '../../dataframe/processDataFrame'; +import { getFieldDisplayName } from '../../field'; import { DataFrame, DataTransformerInfo, Field, FieldType, NullValueMode, Vector } from '../../types'; -import { DataTransformerID } from './ids'; +import { BinaryOperationID, binaryOperators } from '../../utils/binaryOperators'; +import { ArrayVector, BinaryOperationVector, ConstantVector } from '../../vector'; +import { AsNumberVector } from '../../vector/AsNumberVector'; +import { RowVector } from '../../vector/RowVector'; import { doStandardCalcs, fieldReducers, ReducerID } from '../fieldReducer'; import { getFieldMatcher } from '../matchers'; import { FieldMatcherID } from '../matchers/ids'; -import { RowVector } from '../../vector/RowVector'; -import { ArrayVector, BinaryOperationVector, ConstantVector } from '../../vector'; -import { AsNumberVector } from '../../vector/AsNumberVector'; -import { getTimeField } from '../../dataframe/processDataFrame'; -import { defaults } from 'lodash'; -import { BinaryOperationID, binaryOperators } from '../../utils/binaryOperators'; + import { ensureColumnsTransformer } from './ensureColumns'; -import { getFieldDisplayName } from '../../field'; +import { DataTransformerID } from './ids'; import { noopTransformer } from './noop'; export enum CalculateFieldMode { diff --git a/packages/grafana-data/src/transformations/transformers/concat.test.ts b/packages/grafana-data/src/transformations/transformers/concat.test.ts index f7d093289af..20d5b9ebaa9 100644 --- a/packages/grafana-data/src/transformations/transformers/concat.test.ts +++ b/packages/grafana-data/src/transformations/transformers/concat.test.ts @@ -1,4 +1,5 @@ import { toDataFrame } from '../../dataframe/processDataFrame'; + import { concatenateFields, ConcatenateFrameNameMode } from './concat'; export const simpleABC = toDataFrame({ diff --git a/packages/grafana-data/src/transformations/transformers/concat.ts b/packages/grafana-data/src/transformations/transformers/concat.ts index e7489d3bebc..e19728f0686 100644 --- a/packages/grafana-data/src/transformations/transformers/concat.ts +++ b/packages/grafana-data/src/transformations/transformers/concat.ts @@ -1,10 +1,11 @@ import { map } from 'rxjs/operators'; -import { DataTransformerID } from './ids'; -import { DataTransformerInfo } from '../../types/transformations'; import { DataFrame, Field, TIME_SERIES_VALUE_FIELD_NAME } from '../../types/dataFrame'; +import { DataTransformerInfo } from '../../types/transformations'; import { ArrayVector } from '../../vector'; +import { DataTransformerID } from './ids'; + export enum ConcatenateFrameNameMode { /** * Ignore the source frame name when moving to the destination diff --git a/packages/grafana-data/src/transformations/transformers/convertFieldType.test.ts b/packages/grafana-data/src/transformations/transformers/convertFieldType.test.ts index 8c74f1edbcd..467222765a4 100644 --- a/packages/grafana-data/src/transformations/transformers/convertFieldType.test.ts +++ b/packages/grafana-data/src/transformations/transformers/convertFieldType.test.ts @@ -2,6 +2,7 @@ import { toDataFrame } from '../../dataframe/processDataFrame'; import { Field, FieldType } from '../../types/dataFrame'; import { mockTransformationsRegistry } from '../../utils/tests/mockTransformationsRegistry'; import { ArrayVector } from '../../vector'; + import { ensureTimeField, convertFieldType, diff --git a/packages/grafana-data/src/transformations/transformers/convertFieldType.ts b/packages/grafana-data/src/transformations/transformers/convertFieldType.ts index dbfd943df6e..0ebf969524f 100644 --- a/packages/grafana-data/src/transformations/transformers/convertFieldType.ts +++ b/packages/grafana-data/src/transformations/transformers/convertFieldType.ts @@ -1,13 +1,14 @@ -import { SynchronousDataTransformerInfo } from '../../types'; import { map } from 'rxjs/operators'; -import { DataTransformerID } from './ids'; -import { DataFrame, Field, FieldType } from '../../types/dataFrame'; import { dateTimeParse } from '../../datetime'; +import { SynchronousDataTransformerInfo } from '../../types'; +import { DataFrame, Field, FieldType } from '../../types/dataFrame'; import { ArrayVector } from '../../vector'; import { fieldMatchers } from '../matchers'; import { FieldMatcherID } from '../matchers/ids'; +import { DataTransformerID } from './ids'; + export interface ConvertFieldTypeTransformerOptions { conversions: ConvertFieldTypeOptions[]; } diff --git a/packages/grafana-data/src/transformations/transformers/ensureColumns.test.ts b/packages/grafana-data/src/transformations/transformers/ensureColumns.test.ts index 5ed213c2fe7..75290127225 100644 --- a/packages/grafana-data/src/transformations/transformers/ensureColumns.test.ts +++ b/packages/grafana-data/src/transformations/transformers/ensureColumns.test.ts @@ -1,9 +1,10 @@ -import { DataTransformerID } from './ids'; import { toDataFrame } from '../../dataframe/processDataFrame'; import { FieldType } from '../../types/dataFrame'; import { mockTransformationsRegistry } from '../../utils/tests/mockTransformationsRegistry'; import { transformDataFrame } from '../transformDataFrame'; + import { ensureColumnsTransformer } from './ensureColumns'; +import { DataTransformerID } from './ids'; import { seriesToColumnsTransformer } from './seriesToColumns'; const seriesA = toDataFrame({ diff --git a/packages/grafana-data/src/transformations/transformers/ensureColumns.ts b/packages/grafana-data/src/transformations/transformers/ensureColumns.ts index 5b7f20511de..6f331e15f5f 100644 --- a/packages/grafana-data/src/transformations/transformers/ensureColumns.ts +++ b/packages/grafana-data/src/transformations/transformers/ensureColumns.ts @@ -1,10 +1,12 @@ -import { seriesToColumnsTransformer } from './seriesToColumns'; -import { DataFrame } from '../../types/dataFrame'; -import { getTimeField } from '../../dataframe/processDataFrame'; -import { SynchronousDataTransformerInfo } from '../../types/transformations'; -import { DataTransformerID } from './ids'; import { map } from 'rxjs/operators'; +import { getTimeField } from '../../dataframe/processDataFrame'; +import { DataFrame } from '../../types/dataFrame'; +import { SynchronousDataTransformerInfo } from '../../types/transformations'; + +import { DataTransformerID } from './ids'; +import { seriesToColumnsTransformer } from './seriesToColumns'; + export const ensureColumnsTransformer: SynchronousDataTransformerInfo = { id: DataTransformerID.ensureColumns, name: 'Ensure Columns Transformer', diff --git a/packages/grafana-data/src/transformations/transformers/filter.test.ts b/packages/grafana-data/src/transformations/transformers/filter.test.ts index 525acc92aa8..8959487020f 100644 --- a/packages/grafana-data/src/transformations/transformers/filter.test.ts +++ b/packages/grafana-data/src/transformations/transformers/filter.test.ts @@ -1,11 +1,12 @@ -import { FieldType } from '../../types/dataFrame'; -import { DataTransformerID } from './ids'; import { toDataFrame } from '../../dataframe/processDataFrame'; -import { FieldMatcherID } from '../matchers/ids'; +import { FieldType } from '../../types/dataFrame'; import { mockTransformationsRegistry } from '../../utils/tests/mockTransformationsRegistry'; -import { filterFieldsTransformer } from './filter'; +import { FieldMatcherID } from '../matchers/ids'; import { transformDataFrame } from '../transformDataFrame'; +import { filterFieldsTransformer } from './filter'; +import { DataTransformerID } from './ids'; + export const simpleSeriesWithTypes = toDataFrame({ fields: [ { name: 'A', type: FieldType.time, values: [1000, 2000] }, diff --git a/packages/grafana-data/src/transformations/transformers/filter.ts b/packages/grafana-data/src/transformations/transformers/filter.ts index 4ab327f9cd4..64a102b5514 100644 --- a/packages/grafana-data/src/transformations/transformers/filter.ts +++ b/packages/grafana-data/src/transformations/transformers/filter.ts @@ -1,11 +1,12 @@ import { map } from 'rxjs/operators'; -import { noopTransformer } from './noop'; import { DataFrame, Field } from '../../types/dataFrame'; -import { DataTransformerID } from './ids'; import { DataTransformerInfo, MatcherConfig } from '../../types/transformations'; import { getFieldMatcher, getFrameMatchers } from '../matchers'; +import { DataTransformerID } from './ids'; +import { noopTransformer } from './noop'; + export interface FilterOptions { include?: MatcherConfig; exclude?: MatcherConfig; diff --git a/packages/grafana-data/src/transformations/transformers/filterByName.test.ts b/packages/grafana-data/src/transformations/transformers/filterByName.test.ts index 9d4f06c2742..fa9b5cae4b9 100644 --- a/packages/grafana-data/src/transformations/transformers/filterByName.test.ts +++ b/packages/grafana-data/src/transformations/transformers/filterByName.test.ts @@ -1,11 +1,12 @@ -import { DataTransformerID } from './ids'; import { toDataFrame } from '../../dataframe/processDataFrame'; import { FieldType } from '../../types/dataFrame'; import { mockTransformationsRegistry } from '../../utils/tests/mockTransformationsRegistry'; -import { filterFieldsByNameTransformer } from './filterByName'; -import { filterFieldsTransformer } from './filter'; import { transformDataFrame } from '../transformDataFrame'; +import { filterFieldsTransformer } from './filter'; +import { filterFieldsByNameTransformer } from './filterByName'; +import { DataTransformerID } from './ids'; + export const seriesWithNamesToMatch = toDataFrame({ fields: [ { name: 'startsWithA', type: FieldType.time, values: [1000, 2000] }, diff --git a/packages/grafana-data/src/transformations/transformers/filterByName.ts b/packages/grafana-data/src/transformations/transformers/filterByName.ts index f6f58cbe60a..0f461eb81f9 100644 --- a/packages/grafana-data/src/transformations/transformers/filterByName.ts +++ b/packages/grafana-data/src/transformations/transformers/filterByName.ts @@ -1,9 +1,10 @@ -import { DataTransformerID } from './ids'; import { DataTransformerInfo, MatcherConfig } from '../../types/transformations'; import { FieldMatcherID } from '../matchers/ids'; -import { filterFieldsTransformer } from './filter'; import { RegexpOrNamesMatcherOptions } from '../matchers/nameMatcher'; +import { filterFieldsTransformer } from './filter'; +import { DataTransformerID } from './ids'; + export interface FilterFieldsByNameTransformerOptions { include?: RegexpOrNamesMatcherOptions; exclude?: RegexpOrNamesMatcherOptions; diff --git a/packages/grafana-data/src/transformations/transformers/filterByRefId.test.ts b/packages/grafana-data/src/transformations/transformers/filterByRefId.test.ts index a989e28ae11..f3c88698a6c 100644 --- a/packages/grafana-data/src/transformations/transformers/filterByRefId.test.ts +++ b/packages/grafana-data/src/transformations/transformers/filterByRefId.test.ts @@ -1,9 +1,10 @@ -import { DataTransformerID } from './ids'; import { toDataFrame } from '../../dataframe/processDataFrame'; import { mockTransformationsRegistry } from '../../utils/tests/mockTransformationsRegistry'; -import { filterFramesByRefIdTransformer } from './filterByRefId'; import { transformDataFrame } from '../transformDataFrame'; +import { filterFramesByRefIdTransformer } from './filterByRefId'; +import { DataTransformerID } from './ids'; + export const allSeries = [ toDataFrame({ refId: 'A', diff --git a/packages/grafana-data/src/transformations/transformers/filterByRefId.ts b/packages/grafana-data/src/transformations/transformers/filterByRefId.ts index 25b7b09e73d..29e6f50a808 100644 --- a/packages/grafana-data/src/transformations/transformers/filterByRefId.ts +++ b/packages/grafana-data/src/transformations/transformers/filterByRefId.ts @@ -1,8 +1,9 @@ -import { DataTransformerID } from './ids'; -import { filterFramesTransformer, FilterOptions } from './filter'; import { DataTransformerInfo } from '../../types/transformations'; import { FrameMatcherID } from '../matchers/ids'; +import { filterFramesTransformer, FilterOptions } from './filter'; +import { DataTransformerID } from './ids'; + export interface FilterFramesByRefIdTransformerOptions { include?: string; exclude?: string; diff --git a/packages/grafana-data/src/transformations/transformers/filterByValue.test.ts b/packages/grafana-data/src/transformations/transformers/filterByValue.test.ts index 062bb89bbc0..96fd6b4dae0 100644 --- a/packages/grafana-data/src/transformations/transformers/filterByValue.test.ts +++ b/packages/grafana-data/src/transformations/transformers/filterByValue.test.ts @@ -1,8 +1,11 @@ -import { mockTransformationsRegistry } from '../../utils/tests/mockTransformationsRegistry'; -import { DataTransformerConfig, FieldType, MatcherConfig } from '../../types'; -import { ArrayVector } from '../../vector'; -import { transformDataFrame } from '../transformDataFrame'; import { toDataFrame } from '../../dataframe/processDataFrame'; +import { DataTransformerConfig, FieldType, MatcherConfig } from '../../types'; +import { mockTransformationsRegistry } from '../../utils/tests/mockTransformationsRegistry'; +import { ArrayVector } from '../../vector'; +import { ValueMatcherID } from '../matchers/ids'; +import { BasicValueMatcherOptions } from '../matchers/valueMatchers/types'; +import { transformDataFrame } from '../transformDataFrame'; + import { FilterByValueMatch, filterByValueTransformer, @@ -10,8 +13,6 @@ import { FilterByValueType, } from './filterByValue'; import { DataTransformerID } from './ids'; -import { ValueMatcherID } from '../matchers/ids'; -import { BasicValueMatcherOptions } from '../matchers/valueMatchers/types'; const seriesAWithSingleField = toDataFrame({ name: 'A', diff --git a/packages/grafana-data/src/transformations/transformers/filterByValue.ts b/packages/grafana-data/src/transformations/transformers/filterByValue.ts index 9994821cb30..d12838c9d4a 100644 --- a/packages/grafana-data/src/transformations/transformers/filterByValue.ts +++ b/packages/grafana-data/src/transformations/transformers/filterByValue.ts @@ -1,12 +1,13 @@ import { map } from 'rxjs/operators'; -import { noopTransformer } from './noop'; -import { DataTransformerID } from './ids'; -import { DataTransformerInfo, MatcherConfig } from '../../types/transformations'; -import { DataFrame, Field } from '../../types/dataFrame'; import { getFieldDisplayName } from '../../field/fieldState'; -import { getValueMatcher } from '../matchers'; +import { DataFrame, Field } from '../../types/dataFrame'; +import { DataTransformerInfo, MatcherConfig } from '../../types/transformations'; import { ArrayVector } from '../../vector/ArrayVector'; +import { getValueMatcher } from '../matchers'; + +import { DataTransformerID } from './ids'; +import { noopTransformer } from './noop'; export enum FilterByValueType { exclude = 'exclude', diff --git a/packages/grafana-data/src/transformations/transformers/groupBy.test.ts b/packages/grafana-data/src/transformations/transformers/groupBy.test.ts index 76e420f61f6..d9e0e92cfeb 100644 --- a/packages/grafana-data/src/transformations/transformers/groupBy.test.ts +++ b/packages/grafana-data/src/transformations/transformers/groupBy.test.ts @@ -1,12 +1,14 @@ +import { DataTransformerConfig } from '@grafana/data'; + import { toDataFrame } from '../../dataframe/processDataFrame'; -import { GroupByOperationID, groupByTransformer, GroupByTransformerOptions } from './groupBy'; -import { mockTransformationsRegistry } from '../../utils/tests/mockTransformationsRegistry'; -import { transformDataFrame } from '../transformDataFrame'; import { Field, FieldType } from '../../types'; -import { DataTransformerID } from './ids'; +import { mockTransformationsRegistry } from '../../utils/tests/mockTransformationsRegistry'; import { ArrayVector } from '../../vector'; import { ReducerID } from '../fieldReducer'; -import { DataTransformerConfig } from '@grafana/data'; +import { transformDataFrame } from '../transformDataFrame'; + +import { GroupByOperationID, groupByTransformer, GroupByTransformerOptions } from './groupBy'; +import { DataTransformerID } from './ids'; describe('GroupBy transformer', () => { beforeAll(() => { diff --git a/packages/grafana-data/src/transformations/transformers/groupBy.ts b/packages/grafana-data/src/transformations/transformers/groupBy.ts index be1763833d2..1c95825d529 100644 --- a/packages/grafana-data/src/transformations/transformers/groupBy.ts +++ b/packages/grafana-data/src/transformations/transformers/groupBy.ts @@ -1,13 +1,14 @@ import { map } from 'rxjs/operators'; -import { DataTransformerID } from './ids'; +import { MutableField } from '../../dataframe/MutableDataFrame'; +import { guessFieldTypeForField } from '../../dataframe/processDataFrame'; +import { getFieldDisplayName } from '../../field/fieldState'; import { DataFrame, Field, FieldType } from '../../types/dataFrame'; import { DataTransformerInfo } from '../../types/transformations'; -import { getFieldDisplayName } from '../../field/fieldState'; import { ArrayVector } from '../../vector/ArrayVector'; -import { guessFieldTypeForField } from '../../dataframe/processDataFrame'; import { reduceField, ReducerID } from '../fieldReducer'; -import { MutableField } from '../../dataframe/MutableDataFrame'; + +import { DataTransformerID } from './ids'; export enum GroupByOperationID { aggregate = 'aggregate', diff --git a/packages/grafana-data/src/transformations/transformers/groupingToMatrix.test.ts b/packages/grafana-data/src/transformations/transformers/groupingToMatrix.test.ts index 103cf335a67..aea04e8ce70 100644 --- a/packages/grafana-data/src/transformations/transformers/groupingToMatrix.test.ts +++ b/packages/grafana-data/src/transformations/transformers/groupingToMatrix.test.ts @@ -7,9 +7,11 @@ import { toDataFrame, transformDataFrame, } from '@grafana/data'; -import { GroupingToMatrixTransformerOptions, groupingToMatrixTransformer } from './groupingToMatrix'; + import { mockTransformationsRegistry } from '../../utils/tests/mockTransformationsRegistry'; +import { GroupingToMatrixTransformerOptions, groupingToMatrixTransformer } from './groupingToMatrix'; + describe('Grouping to Matrix', () => { beforeAll(() => { mockTransformationsRegistry([groupingToMatrixTransformer]); diff --git a/packages/grafana-data/src/transformations/transformers/groupingToMatrix.ts b/packages/grafana-data/src/transformations/transformers/groupingToMatrix.ts index 4d8a8729ff7..b73b6cf0520 100644 --- a/packages/grafana-data/src/transformations/transformers/groupingToMatrix.ts +++ b/packages/grafana-data/src/transformations/transformers/groupingToMatrix.ts @@ -1,9 +1,10 @@ import { map } from 'rxjs/operators'; -import { DataFrame, DataTransformerInfo, Field, FieldType, Vector } from '../../types'; -import { DataTransformerID } from './ids'; import { MutableDataFrame } from '../../dataframe'; import { getFieldDisplayName } from '../../field/fieldState'; +import { DataFrame, DataTransformerInfo, Field, FieldType, Vector } from '../../types'; + +import { DataTransformerID } from './ids'; export interface GroupingToMatrixTransformerOptions { columnField?: string; diff --git a/packages/grafana-data/src/transformations/transformers/histogram.test.ts b/packages/grafana-data/src/transformations/transformers/histogram.test.ts index 22e9ea0f06a..a2f0b1952a2 100644 --- a/packages/grafana-data/src/transformations/transformers/histogram.test.ts +++ b/packages/grafana-data/src/transformations/transformers/histogram.test.ts @@ -1,6 +1,7 @@ import { toDataFrame } from '../../dataframe/processDataFrame'; import { FieldType } from '../../types/dataFrame'; import { mockTransformationsRegistry } from '../../utils/tests/mockTransformationsRegistry'; + import { histogramTransformer, buildHistogram, histogramFieldsToFrame } from './histogram'; describe('histogram frames frames', () => { diff --git a/packages/grafana-data/src/transformations/transformers/histogram.ts b/packages/grafana-data/src/transformations/transformers/histogram.ts index a48f00c1861..9dc72bcfd31 100644 --- a/packages/grafana-data/src/transformations/transformers/histogram.ts +++ b/packages/grafana-data/src/transformations/transformers/histogram.ts @@ -1,12 +1,13 @@ -import { SynchronousDataTransformerInfo } from '../../types'; import { map } from 'rxjs/operators'; -import { DataTransformerID } from './ids'; -import { DataFrame, Field, FieldConfig, FieldType } from '../../types/dataFrame'; -import { ArrayVector } from '../../vector/ArrayVector'; -import { AlignedData, join } from './joinDataFrames'; import { getDisplayProcessor } from '../../field'; import { createTheme, GrafanaTheme2 } from '../../themes'; +import { SynchronousDataTransformerInfo } from '../../types'; +import { DataFrame, Field, FieldConfig, FieldType } from '../../types/dataFrame'; +import { ArrayVector } from '../../vector/ArrayVector'; + +import { DataTransformerID } from './ids'; +import { AlignedData, join } from './joinDataFrames'; /** * @internal diff --git a/packages/grafana-data/src/transformations/transformers/joinDataFrames.test.ts b/packages/grafana-data/src/transformations/transformers/joinDataFrames.test.ts index a5d11987b68..2f78fa5c901 100644 --- a/packages/grafana-data/src/transformations/transformers/joinDataFrames.test.ts +++ b/packages/grafana-data/src/transformations/transformers/joinDataFrames.test.ts @@ -2,6 +2,7 @@ import { toDataFrame } from '../../dataframe/processDataFrame'; import { FieldType } from '../../types/dataFrame'; import { mockTransformationsRegistry } from '../../utils/tests/mockTransformationsRegistry'; import { ArrayVector } from '../../vector'; + import { calculateFieldTransformer } from './calculateField'; import { isLikelyAscendingVector, outerJoinDataFrames } from './joinDataFrames'; diff --git a/packages/grafana-data/src/transformations/transformers/joinDataFrames.ts b/packages/grafana-data/src/transformations/transformers/joinDataFrames.ts index c366a55e5ff..39b95b6ae3c 100644 --- a/packages/grafana-data/src/transformations/transformers/joinDataFrames.ts +++ b/packages/grafana-data/src/transformations/transformers/joinDataFrames.ts @@ -1,8 +1,8 @@ +import { getTimeField, sortDataFrame } from '../../dataframe'; import { DataFrame, Field, FieldMatcher, FieldType, Vector } from '../../types'; import { ArrayVector } from '../../vector'; import { fieldMatchers } from '../matchers'; import { FieldMatcherID } from '../matchers/ids'; -import { getTimeField, sortDataFrame } from '../../dataframe'; export function pickBestJoinField(data: DataFrame[]): FieldMatcher { const { timeField } = getTimeField(data[0]); diff --git a/packages/grafana-data/src/transformations/transformers/labelsToFields.test.ts b/packages/grafana-data/src/transformations/transformers/labelsToFields.test.ts index 515b39c42ae..41dccaeb826 100644 --- a/packages/grafana-data/src/transformations/transformers/labelsToFields.test.ts +++ b/packages/grafana-data/src/transformations/transformers/labelsToFields.test.ts @@ -1,10 +1,11 @@ -import { mockTransformationsRegistry } from '../../utils/tests/mockTransformationsRegistry'; -import { LabelsToFieldsMode, LabelsToFieldsOptions, labelsToFieldsTransformer } from './labelsToFields'; -import { DataFrame, DataTransformerConfig, FieldDTO, FieldType } from '../../types'; -import { DataTransformerID } from './ids'; import { toDataFrame, toDataFrameDTO } from '../../dataframe'; +import { DataFrame, DataTransformerConfig, FieldDTO, FieldType } from '../../types'; +import { mockTransformationsRegistry } from '../../utils/tests/mockTransformationsRegistry'; import { transformDataFrame } from '../transformDataFrame'; +import { DataTransformerID } from './ids'; +import { LabelsToFieldsMode, LabelsToFieldsOptions, labelsToFieldsTransformer } from './labelsToFields'; + describe('Labels as Columns', () => { beforeAll(() => { mockTransformationsRegistry([labelsToFieldsTransformer]); diff --git a/packages/grafana-data/src/transformations/transformers/labelsToFields.ts b/packages/grafana-data/src/transformations/transformers/labelsToFields.ts index f60e68cb86c..c4814f7ecc7 100644 --- a/packages/grafana-data/src/transformations/transformers/labelsToFields.ts +++ b/packages/grafana-data/src/transformations/transformers/labelsToFields.ts @@ -1,9 +1,10 @@ import { map } from 'rxjs/operators'; -import { DataFrame, Field, FieldType, SynchronousDataTransformerInfo } from '../../types'; -import { DataTransformerID } from './ids'; -import { ArrayVector } from '../../vector'; import { getFieldDisplayName } from '../..'; +import { DataFrame, Field, FieldType, SynchronousDataTransformerInfo } from '../../types'; +import { ArrayVector } from '../../vector'; + +import { DataTransformerID } from './ids'; export enum LabelsToFieldsMode { Columns = 'columns', // default mode diff --git a/packages/grafana-data/src/transformations/transformers/merge.test.ts b/packages/grafana-data/src/transformations/transformers/merge.test.ts index 8fb57860490..9c4b210e42f 100644 --- a/packages/grafana-data/src/transformations/transformers/merge.test.ts +++ b/packages/grafana-data/src/transformations/transformers/merge.test.ts @@ -1,9 +1,10 @@ -import { mockTransformationsRegistry } from '../../utils/tests/mockTransformationsRegistry'; -import { DataTransformerConfig, DisplayProcessor, Field, FieldType } from '../../types'; -import { DataTransformerID } from './ids'; import { toDataFrame } from '../../dataframe'; -import { transformDataFrame } from '../transformDataFrame'; +import { DataTransformerConfig, DisplayProcessor, Field, FieldType } from '../../types'; +import { mockTransformationsRegistry } from '../../utils/tests/mockTransformationsRegistry'; import { ArrayVector } from '../../vector'; +import { transformDataFrame } from '../transformDataFrame'; + +import { DataTransformerID } from './ids'; import { mergeTransformer, MergeTransformerOptions } from './merge'; describe('Merge multiple to single', () => { diff --git a/packages/grafana-data/src/transformations/transformers/merge.ts b/packages/grafana-data/src/transformations/transformers/merge.ts index cecbb1cf9c7..55185c0756d 100644 --- a/packages/grafana-data/src/transformations/transformers/merge.ts +++ b/packages/grafana-data/src/transformations/transformers/merge.ts @@ -1,11 +1,12 @@ +import { omit } from 'lodash'; import { map } from 'rxjs/operators'; -import { DataTransformerID } from './ids'; -import { DataTransformerInfo } from '../../types/transformations'; -import { DataFrame, Field } from '../../types/dataFrame'; -import { omit } from 'lodash'; -import { ArrayVector } from '../../vector/ArrayVector'; import { MutableDataFrame } from '../../dataframe'; +import { DataFrame, Field } from '../../types/dataFrame'; +import { DataTransformerInfo } from '../../types/transformations'; +import { ArrayVector } from '../../vector/ArrayVector'; + +import { DataTransformerID } from './ids'; interface ValuePointer { key: string; diff --git a/packages/grafana-data/src/transformations/transformers/noop.ts b/packages/grafana-data/src/transformations/transformers/noop.ts index 32c60101086..ba70bd27b36 100644 --- a/packages/grafana-data/src/transformations/transformers/noop.ts +++ b/packages/grafana-data/src/transformations/transformers/noop.ts @@ -1,6 +1,7 @@ -import { DataTransformerID } from './ids'; import { DataTransformerInfo } from '../../types/transformations'; +import { DataTransformerID } from './ids'; + export interface NoopTransformerOptions { include?: string; exclude?: string; diff --git a/packages/grafana-data/src/transformations/transformers/order.test.ts b/packages/grafana-data/src/transformations/transformers/order.test.ts index 8ecd42ec4e1..41c74ad0433 100644 --- a/packages/grafana-data/src/transformations/transformers/order.test.ts +++ b/packages/grafana-data/src/transformations/transformers/order.test.ts @@ -6,9 +6,11 @@ import { toDataFrame, transformDataFrame, } from '@grafana/data'; -import { orderFieldsTransformer, OrderFieldsTransformerOptions } from './order'; + import { mockTransformationsRegistry } from '../../utils/tests/mockTransformationsRegistry'; +import { orderFieldsTransformer, OrderFieldsTransformerOptions } from './order'; + describe('Order Transformer', () => { beforeAll(() => { mockTransformationsRegistry([orderFieldsTransformer]); diff --git a/packages/grafana-data/src/transformations/transformers/order.ts b/packages/grafana-data/src/transformations/transformers/order.ts index 577d154da8a..402f90058d0 100644 --- a/packages/grafana-data/src/transformations/transformers/order.ts +++ b/packages/grafana-data/src/transformations/transformers/order.ts @@ -1,9 +1,11 @@ -import { DataTransformerID } from './ids'; -import { DataTransformerInfo } from '../../types/transformations'; -import { DataFrame, Field } from '../../types'; -import { getFieldDisplayName } from '../../field/fieldState'; import { map } from 'rxjs/operators'; +import { getFieldDisplayName } from '../../field/fieldState'; +import { DataFrame, Field } from '../../types'; +import { DataTransformerInfo } from '../../types/transformations'; + +import { DataTransformerID } from './ids'; + export interface OrderFieldsTransformerOptions { indexByName: Record; } diff --git a/packages/grafana-data/src/transformations/transformers/organize.test.ts b/packages/grafana-data/src/transformations/transformers/organize.test.ts index 28ec939938a..4388237853d 100644 --- a/packages/grafana-data/src/transformations/transformers/organize.test.ts +++ b/packages/grafana-data/src/transformations/transformers/organize.test.ts @@ -6,9 +6,11 @@ import { toDataFrame, transformDataFrame, } from '@grafana/data'; -import { organizeFieldsTransformer, OrganizeFieldsTransformerOptions } from './organize'; + import { mockTransformationsRegistry } from '../../utils/tests/mockTransformationsRegistry'; +import { organizeFieldsTransformer, OrganizeFieldsTransformerOptions } from './organize'; + describe('OrganizeFields Transformer', () => { beforeAll(() => { mockTransformationsRegistry([organizeFieldsTransformer]); diff --git a/packages/grafana-data/src/transformations/transformers/organize.ts b/packages/grafana-data/src/transformations/transformers/organize.ts index 7913cdb87bb..3a13a0fbc47 100644 --- a/packages/grafana-data/src/transformations/transformers/organize.ts +++ b/packages/grafana-data/src/transformations/transformers/organize.ts @@ -1,7 +1,8 @@ -import { DataTransformerID } from './ids'; import { DataTransformerInfo } from '../../types/transformations'; -import { orderFieldsTransformer, OrderFieldsTransformerOptions } from './order'; + import { filterFieldsByNameTransformer } from './filterByName'; +import { DataTransformerID } from './ids'; +import { orderFieldsTransformer, OrderFieldsTransformerOptions } from './order'; import { renameFieldsTransformer, RenameFieldsTransformerOptions } from './rename'; export interface OrganizeFieldsTransformerOptions diff --git a/packages/grafana-data/src/transformations/transformers/reduce.test.ts b/packages/grafana-data/src/transformations/transformers/reduce.test.ts index 721d34514a5..92369e07222 100644 --- a/packages/grafana-data/src/transformations/transformers/reduce.test.ts +++ b/packages/grafana-data/src/transformations/transformers/reduce.test.ts @@ -1,13 +1,14 @@ -import { ReducerID } from '../fieldReducer'; -import { DataTransformerID } from './ids'; -import { toDataFrame } from '../../dataframe/processDataFrame'; -import { mockTransformationsRegistry } from '../../utils/tests/mockTransformationsRegistry'; -import { reduceFields, reduceTransformer, ReduceTransformerOptions } from './reduce'; -import { transformDataFrame } from '../transformDataFrame'; -import { DataTransformerConfig, Field, FieldType } from '../../types'; -import { ArrayVector } from '../../vector'; -import { notTimeFieldMatcher } from '../matchers/predicates'; import { DataFrameView } from '../../dataframe'; +import { toDataFrame } from '../../dataframe/processDataFrame'; +import { DataTransformerConfig, Field, FieldType } from '../../types'; +import { mockTransformationsRegistry } from '../../utils/tests/mockTransformationsRegistry'; +import { ArrayVector } from '../../vector'; +import { ReducerID } from '../fieldReducer'; +import { notTimeFieldMatcher } from '../matchers/predicates'; +import { transformDataFrame } from '../transformDataFrame'; + +import { DataTransformerID } from './ids'; +import { reduceFields, reduceTransformer, ReduceTransformerOptions } from './reduce'; const seriesAWithSingleField = toDataFrame({ name: 'A', diff --git a/packages/grafana-data/src/transformations/transformers/reduce.ts b/packages/grafana-data/src/transformations/transformers/reduce.ts index 1250dc9039d..7a5beed909f 100644 --- a/packages/grafana-data/src/transformations/transformers/reduce.ts +++ b/packages/grafana-data/src/transformations/transformers/reduce.ts @@ -1,15 +1,16 @@ import { map } from 'rxjs/operators'; -import { DataTransformerID } from './ids'; -import { DataTransformerInfo, FieldMatcher, MatcherConfig } from '../../types/transformations'; -import { fieldReducers, reduceField, ReducerID } from '../fieldReducer'; -import { alwaysFieldMatcher, notTimeFieldMatcher } from '../matchers/predicates'; -import { DataFrame, Field, FieldType } from '../../types/dataFrame'; -import { ArrayVector } from '../../vector/ArrayVector'; -import { KeyValue } from '../../types/data'; import { guessFieldTypeForField } from '../../dataframe/processDataFrame'; -import { getFieldMatcher } from '../matchers'; import { getFieldDisplayName } from '../../field'; +import { KeyValue } from '../../types/data'; +import { DataFrame, Field, FieldType } from '../../types/dataFrame'; +import { DataTransformerInfo, FieldMatcher, MatcherConfig } from '../../types/transformations'; +import { ArrayVector } from '../../vector/ArrayVector'; +import { fieldReducers, reduceField, ReducerID } from '../fieldReducer'; +import { getFieldMatcher } from '../matchers'; +import { alwaysFieldMatcher, notTimeFieldMatcher } from '../matchers/predicates'; + +import { DataTransformerID } from './ids'; export enum ReduceTransformerMode { SeriesToRows = 'seriesToRows', // default diff --git a/packages/grafana-data/src/transformations/transformers/rename.test.ts b/packages/grafana-data/src/transformations/transformers/rename.test.ts index 10cff84ab99..db64088de31 100644 --- a/packages/grafana-data/src/transformations/transformers/rename.test.ts +++ b/packages/grafana-data/src/transformations/transformers/rename.test.ts @@ -6,9 +6,11 @@ import { toDataFrame, transformDataFrame, } from '@grafana/data'; -import { renameFieldsTransformer, RenameFieldsTransformerOptions } from './rename'; + import { mockTransformationsRegistry } from '../../utils/tests/mockTransformationsRegistry'; +import { renameFieldsTransformer, RenameFieldsTransformerOptions } from './rename'; + describe('Rename Transformer', () => { beforeAll(() => { mockTransformationsRegistry([renameFieldsTransformer]); diff --git a/packages/grafana-data/src/transformations/transformers/rename.ts b/packages/grafana-data/src/transformations/transformers/rename.ts index 3ecb9170c9d..a19f40e0359 100644 --- a/packages/grafana-data/src/transformations/transformers/rename.ts +++ b/packages/grafana-data/src/transformations/transformers/rename.ts @@ -1,9 +1,11 @@ -import { DataTransformerID } from './ids'; -import { DataTransformerInfo } from '../../types/transformations'; -import { DataFrame, Field } from '../../types/dataFrame'; -import { getFieldDisplayName } from '../../field/fieldState'; import { map } from 'rxjs/operators'; +import { getFieldDisplayName } from '../../field/fieldState'; +import { DataFrame, Field } from '../../types/dataFrame'; +import { DataTransformerInfo } from '../../types/transformations'; + +import { DataTransformerID } from './ids'; + export interface RenameFieldsTransformerOptions { renameByName: Record; } diff --git a/packages/grafana-data/src/transformations/transformers/renameByRegex.test.ts b/packages/grafana-data/src/transformations/transformers/renameByRegex.test.ts index ae617320ab9..aa630829a58 100644 --- a/packages/grafana-data/src/transformations/transformers/renameByRegex.test.ts +++ b/packages/grafana-data/src/transformations/transformers/renameByRegex.test.ts @@ -1,7 +1,9 @@ import { DataTransformerConfig, DataTransformerID, FieldType, toDataFrame, transformDataFrame } from '@grafana/data'; -import { renameByRegexTransformer, RenameByRegexTransformerOptions } from './renameByRegex'; + import { mockTransformationsRegistry } from '../../utils/tests/mockTransformationsRegistry'; +import { renameByRegexTransformer, RenameByRegexTransformerOptions } from './renameByRegex'; + describe('Rename By Regex Transformer', () => { beforeAll(() => { mockTransformationsRegistry([renameByRegexTransformer]); diff --git a/packages/grafana-data/src/transformations/transformers/renameByRegex.ts b/packages/grafana-data/src/transformations/transformers/renameByRegex.ts index be93f52a4ec..05426c988c0 100644 --- a/packages/grafana-data/src/transformations/transformers/renameByRegex.ts +++ b/packages/grafana-data/src/transformations/transformers/renameByRegex.ts @@ -1,8 +1,10 @@ -import { DataTransformerID } from './ids'; -import { DataTransformerInfo } from '../../types/transformations'; import { map } from 'rxjs/operators'; -import { DataFrame } from '../../types/dataFrame'; + import { getFieldDisplayName } from '../../field/fieldState'; +import { DataFrame } from '../../types/dataFrame'; +import { DataTransformerInfo } from '../../types/transformations'; + +import { DataTransformerID } from './ids'; /** * Options for renameByRegexTransformer diff --git a/packages/grafana-data/src/transformations/transformers/seriesToColumns.test.ts b/packages/grafana-data/src/transformations/transformers/seriesToColumns.test.ts index 24cd021ea8c..6ce2f840424 100644 --- a/packages/grafana-data/src/transformations/transformers/seriesToColumns.test.ts +++ b/packages/grafana-data/src/transformations/transformers/seriesToColumns.test.ts @@ -6,9 +6,11 @@ import { toDataFrame, transformDataFrame, } from '@grafana/data'; -import { SeriesToColumnsOptions, seriesToColumnsTransformer } from './seriesToColumns'; + import { mockTransformationsRegistry } from '../../utils/tests/mockTransformationsRegistry'; +import { SeriesToColumnsOptions, seriesToColumnsTransformer } from './seriesToColumns'; + describe('SeriesToColumns Transformer', () => { beforeAll(() => { mockTransformationsRegistry([seriesToColumnsTransformer]); diff --git a/packages/grafana-data/src/transformations/transformers/seriesToColumns.ts b/packages/grafana-data/src/transformations/transformers/seriesToColumns.ts index 08170d1192b..785a8be6fda 100644 --- a/packages/grafana-data/src/transformations/transformers/seriesToColumns.ts +++ b/packages/grafana-data/src/transformations/transformers/seriesToColumns.ts @@ -1,11 +1,12 @@ import { map } from 'rxjs/operators'; import { DataFrame, SynchronousDataTransformerInfo, FieldMatcher } from '../../types'; -import { DataTransformerID } from './ids'; -import { outerJoinDataFrames } from './joinDataFrames'; import { fieldMatchers } from '../matchers'; import { FieldMatcherID } from '../matchers/ids'; +import { DataTransformerID } from './ids'; +import { outerJoinDataFrames } from './joinDataFrames'; + export interface SeriesToColumnsOptions { byField?: string; // empty will pick the field automatically } diff --git a/packages/grafana-data/src/transformations/transformers/seriesToRows.test.ts b/packages/grafana-data/src/transformations/transformers/seriesToRows.test.ts index bb43826010f..9cfc1d930ef 100644 --- a/packages/grafana-data/src/transformations/transformers/seriesToRows.test.ts +++ b/packages/grafana-data/src/transformations/transformers/seriesToRows.test.ts @@ -1,9 +1,10 @@ -import { mockTransformationsRegistry } from '../../utils/tests/mockTransformationsRegistry'; -import { DataTransformerConfig, Field, FieldType } from '../../types'; -import { DataTransformerID } from './ids'; import { toDataFrame } from '../../dataframe'; -import { transformDataFrame } from '../transformDataFrame'; +import { DataTransformerConfig, Field, FieldType } from '../../types'; +import { mockTransformationsRegistry } from '../../utils/tests/mockTransformationsRegistry'; import { ArrayVector } from '../../vector'; +import { transformDataFrame } from '../transformDataFrame'; + +import { DataTransformerID } from './ids'; import { seriesToRowsTransformer, SeriesToRowsTransformerOptions } from './seriesToRows'; describe('Series to rows', () => { diff --git a/packages/grafana-data/src/transformations/transformers/seriesToRows.ts b/packages/grafana-data/src/transformations/transformers/seriesToRows.ts index a2ddb11f80e..8121784b476 100644 --- a/packages/grafana-data/src/transformations/transformers/seriesToRows.ts +++ b/packages/grafana-data/src/transformations/transformers/seriesToRows.ts @@ -1,8 +1,9 @@ import { omit } from 'lodash'; import { map } from 'rxjs/operators'; -import { DataTransformerID } from './ids'; -import { DataTransformerInfo } from '../../types/transformations'; +import { MutableDataFrame, sortDataFrame } from '../../dataframe'; +import { isTimeSeries } from '../../dataframe/utils'; +import { getFrameDisplayName } from '../../field/fieldState'; import { Field, FieldType, @@ -10,10 +11,10 @@ import { TIME_SERIES_TIME_FIELD_NAME, TIME_SERIES_VALUE_FIELD_NAME, } from '../../types/dataFrame'; -import { isTimeSeries } from '../../dataframe/utils'; -import { MutableDataFrame, sortDataFrame } from '../../dataframe'; +import { DataTransformerInfo } from '../../types/transformations'; import { ArrayVector } from '../../vector'; -import { getFrameDisplayName } from '../../field/fieldState'; + +import { DataTransformerID } from './ids'; export interface SeriesToRowsTransformerOptions {} diff --git a/packages/grafana-data/src/transformations/transformers/sortBy.test.ts b/packages/grafana-data/src/transformations/transformers/sortBy.test.ts index 534bd5680ec..6a12bbde0f6 100644 --- a/packages/grafana-data/src/transformations/transformers/sortBy.test.ts +++ b/packages/grafana-data/src/transformations/transformers/sortBy.test.ts @@ -1,10 +1,12 @@ +import { DataTransformerConfig } from '@grafana/data'; + import { toDataFrame } from '../../dataframe/processDataFrame'; -import { sortByTransformer, SortByTransformerOptions } from './sortBy'; +import { Field, FieldType } from '../../types'; import { mockTransformationsRegistry } from '../../utils/tests/mockTransformationsRegistry'; import { transformDataFrame } from '../transformDataFrame'; -import { Field, FieldType } from '../../types'; + import { DataTransformerID } from './ids'; -import { DataTransformerConfig } from '@grafana/data'; +import { sortByTransformer, SortByTransformerOptions } from './sortBy'; const testFrame = toDataFrame({ name: 'A', diff --git a/packages/grafana-data/src/transformations/transformers/sortBy.ts b/packages/grafana-data/src/transformations/transformers/sortBy.ts index 2e377291c3f..1bf8ba2d859 100644 --- a/packages/grafana-data/src/transformations/transformers/sortBy.ts +++ b/packages/grafana-data/src/transformations/transformers/sortBy.ts @@ -1,10 +1,11 @@ import { map } from 'rxjs/operators'; -import { DataTransformerID } from './ids'; -import { DataTransformerInfo } from '../../types/transformations'; -import { DataFrame } from '../../types'; -import { getFieldDisplayName } from '../../field'; import { sortDataFrame } from '../../dataframe'; +import { getFieldDisplayName } from '../../field'; +import { DataFrame } from '../../types'; +import { DataTransformerInfo } from '../../types/transformations'; + +import { DataTransformerID } from './ids'; export interface SortByField { field: string; diff --git a/packages/grafana-data/src/types/OptionsUIRegistryBuilder.ts b/packages/grafana-data/src/types/OptionsUIRegistryBuilder.ts index 42235c7eb0a..72bc00abfac 100644 --- a/packages/grafana-data/src/types/OptionsUIRegistryBuilder.ts +++ b/packages/grafana-data/src/types/OptionsUIRegistryBuilder.ts @@ -1,11 +1,13 @@ import { ComponentType } from 'react'; -import { RegistryItem, Registry } from '../utils/Registry'; + import { NumberFieldConfigSettings, SliderFieldConfigSettings, SelectFieldConfigSettings, StringFieldConfigSettings, } from '../field'; +import { RegistryItem, Registry } from '../utils/Registry'; + import { OptionEditorConfig } from './options'; /** diff --git a/packages/grafana-data/src/types/annotations.ts b/packages/grafana-data/src/types/annotations.ts index 26867af8b2b..e701b6b3841 100644 --- a/packages/grafana-data/src/types/annotations.ts +++ b/packages/grafana-data/src/types/annotations.ts @@ -1,8 +1,8 @@ -import { Observable } from 'rxjs'; import { ComponentType } from 'react'; +import { Observable } from 'rxjs'; -import { QueryEditorProps } from './datasource'; import { DataFrame } from './dataFrame'; +import { QueryEditorProps } from './datasource'; import { DataQuery, DataSourceRef } from './query'; /** diff --git a/packages/grafana-data/src/types/app.ts b/packages/grafana-data/src/types/app.ts index fe23e8fc6f1..04beaa52ed0 100644 --- a/packages/grafana-data/src/types/app.ts +++ b/packages/grafana-data/src/types/app.ts @@ -1,4 +1,5 @@ import { ComponentType } from 'react'; + import { KeyValue } from './data'; import { NavModel } from './navModel'; import { PluginMeta, GrafanaPlugin, PluginIncludeType } from './plugin'; diff --git a/packages/grafana-data/src/types/config.ts b/packages/grafana-data/src/types/config.ts index 0c49f3249bc..bc7c0f13a15 100644 --- a/packages/grafana-data/src/types/config.ts +++ b/packages/grafana-data/src/types/config.ts @@ -1,10 +1,12 @@ +import { SystemDateFormatSettings } from '../datetime'; +import { MapLayerOptions } from '../geo/layer'; +import { GrafanaTheme2 } from '../themes'; + import { DataSourceInstanceSettings } from './datasource'; +import { FeatureToggles } from './featureToggles.gen'; import { PanelPluginMeta } from './panel'; import { GrafanaTheme } from './theme'; -import { SystemDateFormatSettings } from '../datetime'; -import { GrafanaTheme2 } from '../themes'; -import { MapLayerOptions } from '../geo/layer'; -import { FeatureToggles } from './featureToggles.gen'; + import { NavLinkDTO, OrgRole } from '.'; /** diff --git a/packages/grafana-data/src/types/data.ts b/packages/grafana-data/src/types/data.ts index e7a4f3655a6..ab18139742b 100644 --- a/packages/grafana-data/src/types/data.ts +++ b/packages/grafana-data/src/types/data.ts @@ -1,9 +1,10 @@ import { DataFrameDTO, FieldConfig } from './dataFrame'; -import { DataTransformerConfig } from './transformations'; -import { ApplyFieldOverrideOptions } from './fieldOverrides'; -import { PanelPluginDataSupport } from '.'; -import { DataTopic } from './query'; import { DataFrameType } from './dataFrameTypes'; +import { ApplyFieldOverrideOptions } from './fieldOverrides'; +import { DataTopic } from './query'; +import { DataTransformerConfig } from './transformations'; + +import { PanelPluginDataSupport } from '.'; export type KeyValue = Record; diff --git a/packages/grafana-data/src/types/dataFrame.ts b/packages/grafana-data/src/types/dataFrame.ts index d0f6726017d..e385ca4fb15 100644 --- a/packages/grafana-data/src/types/dataFrame.ts +++ b/packages/grafana-data/src/types/dataFrame.ts @@ -1,11 +1,11 @@ +import { ScopedVars } from './ScopedVars'; +import { QueryResultBase, Labels, NullValueMode } from './data'; +import { DataLink, LinkModel } from './dataLink'; +import { DisplayProcessor, DisplayValue } from './displayValue'; +import { FieldColor } from './fieldColor'; import { ThresholdsConfig } from './thresholds'; import { ValueMapping } from './valueMapping'; -import { QueryResultBase, Labels, NullValueMode } from './data'; -import { DisplayProcessor, DisplayValue } from './displayValue'; -import { DataLink, LinkModel } from './dataLink'; import { Vector } from './vector'; -import { FieldColor } from './fieldColor'; -import { ScopedVars } from './ScopedVars'; /** @public */ export enum FieldType { diff --git a/packages/grafana-data/src/types/dataLink.ts b/packages/grafana-data/src/types/dataLink.ts index a0c6ac312e2..6d741b2d801 100644 --- a/packages/grafana-data/src/types/dataLink.ts +++ b/packages/grafana-data/src/types/dataLink.ts @@ -1,6 +1,6 @@ -import { DataQuery } from './query'; -import { InterpolateFunction } from './panel'; import { ExplorePanelsState } from './explore'; +import { InterpolateFunction } from './panel'; +import { DataQuery } from './query'; /** * Callback info for DataLink click events diff --git a/packages/grafana-data/src/types/datasource.ts b/packages/grafana-data/src/types/datasource.ts index 1396140c41e..c3bf11b2ef2 100644 --- a/packages/grafana-data/src/types/datasource.ts +++ b/packages/grafana-data/src/types/datasource.ts @@ -1,17 +1,20 @@ -import { Observable } from 'rxjs'; import { ComponentType } from 'react'; -import { GrafanaPlugin, PluginMeta } from './plugin'; -import { PanelData } from './panel'; -import { LogRowModel } from './logs'; +import { Observable } from 'rxjs'; + +import { makeClassES5Compatible } from '../utils/makeClassES5Compatible'; + +import { ScopedVars } from './ScopedVars'; import { AnnotationEvent, AnnotationQuery, AnnotationSupport } from './annotations'; +import { CoreApp } from './app'; import { KeyValue, LoadingState, TableData, TimeSeries } from './data'; import { DataFrame, DataFrameDTO } from './dataFrame'; -import { RawTimeRange, TimeRange } from './time'; -import { ScopedVars } from './ScopedVars'; -import { CoreApp } from './app'; -import { CustomVariableSupport, DataSourceVariableSupport, StandardVariableSupport } from './variables'; -import { makeClassES5Compatible } from '../utils/makeClassES5Compatible'; +import { LogRowModel } from './logs'; +import { PanelData } from './panel'; +import { GrafanaPlugin, PluginMeta } from './plugin'; import { DataQuery } from './query'; +import { RawTimeRange, TimeRange } from './time'; +import { CustomVariableSupport, DataSourceVariableSupport, StandardVariableSupport } from './variables'; + import { DataSourceRef, WithAccessControlMetadata } from '.'; export interface DataSourcePluginOptionsEditorProps { diff --git a/packages/grafana-data/src/types/fieldOverrides.ts b/packages/grafana-data/src/types/fieldOverrides.ts index 57532652ea2..088b0847a97 100644 --- a/packages/grafana-data/src/types/fieldOverrides.ts +++ b/packages/grafana-data/src/types/fieldOverrides.ts @@ -1,10 +1,12 @@ import { ComponentType } from 'react'; -import { MatcherConfig, FieldConfig, Field, DataFrame, TimeZone } from '../types'; -import { InterpolateFunction } from './panel'; + import { StandardEditorProps, FieldConfigOptionsRegistry, StandardEditorContext } from '../field'; +import { GrafanaTheme2 } from '../themes'; +import { MatcherConfig, FieldConfig, Field, DataFrame, TimeZone } from '../types'; + import { OptionsEditorItem } from './OptionsUIRegistryBuilder'; import { OptionEditorConfig } from './options'; -import { GrafanaTheme2 } from '../themes'; +import { InterpolateFunction } from './panel'; export interface DynamicConfigValue { id: string; diff --git a/packages/grafana-data/src/types/graph.ts b/packages/grafana-data/src/types/graph.ts index 91604f5ae29..83f18ab5ab4 100644 --- a/packages/grafana-data/src/types/graph.ts +++ b/packages/grafana-data/src/types/graph.ts @@ -1,5 +1,5 @@ -import { DisplayValue } from './displayValue'; import { Field } from './dataFrame'; +import { DisplayValue } from './displayValue'; export interface YAxis { index: number; diff --git a/packages/grafana-data/src/types/legacyEvents.ts b/packages/grafana-data/src/types/legacyEvents.ts index df93d2f5f15..8154a322159 100644 --- a/packages/grafana-data/src/types/legacyEvents.ts +++ b/packages/grafana-data/src/types/legacyEvents.ts @@ -1,9 +1,10 @@ -import { DataQueryError, DataQueryResponseData } from './datasource'; -import { AngularPanelMenuItem } from './panel'; -import { DataFrame } from './dataFrame'; +import { DataHoverPayload } from '../events'; import { eventFactory } from '../events/eventFactory'; import { BusEventBase, BusEventWithPayload } from '../events/types'; -import { DataHoverPayload } from '../events'; + +import { DataFrame } from './dataFrame'; +import { DataQueryError, DataQueryResponseData } from './datasource'; +import { AngularPanelMenuItem } from './panel'; export type AlertPayload = [string, string?, string?]; export type AlertErrorPayload = [string, (string | Error)?, string?]; diff --git a/packages/grafana-data/src/types/logs.ts b/packages/grafana-data/src/types/logs.ts index d6b4522c83c..daececb446e 100644 --- a/packages/grafana-data/src/types/logs.ts +++ b/packages/grafana-data/src/types/logs.ts @@ -1,8 +1,8 @@ import { Labels } from './data'; import { DataFrame } from './dataFrame'; +import { DataQueryResponse } from './datasource'; import { DataQuery } from './query'; import { AbsoluteTimeRange } from './time'; -import { DataQueryResponse } from './datasource'; /** * Mapping of log level abbreviation to canonical log level. diff --git a/packages/grafana-data/src/types/logsVolume.ts b/packages/grafana-data/src/types/logsVolume.ts index bbb73eef7a1..925f63d899b 100644 --- a/packages/grafana-data/src/types/logsVolume.ts +++ b/packages/grafana-data/src/types/logsVolume.ts @@ -1,7 +1,8 @@ -import { DataQuery } from './query'; -import { DataQueryRequest, DataQueryResponse } from './datasource'; import { Observable } from 'rxjs'; +import { DataQueryRequest, DataQueryResponse } from './datasource'; +import { DataQuery } from './query'; + /** * TODO: This should be added to ./logs.ts but because of cross reference between ./datasource.ts and ./logs.ts it can * be done only after decoupling "logs" from "datasource" (https://github.com/grafana/grafana/pull/39536) diff --git a/packages/grafana-data/src/types/panel.ts b/packages/grafana-data/src/types/panel.ts index b5a0dbdd534..9061fdf9e3e 100644 --- a/packages/grafana-data/src/types/panel.ts +++ b/packages/grafana-data/src/types/panel.ts @@ -1,19 +1,21 @@ -import { DataQueryError, DataQueryRequest, DataQueryTimings } from './datasource'; -import { PluginMeta } from './plugin'; -import { ScopedVars } from './ScopedVars'; -import { LoadingState, PreferredVisualisationType } from './data'; -import { DataFrame, FieldType } from './dataFrame'; -import { AbsoluteTimeRange, TimeRange, TimeZone } from './time'; +import { defaultsDeep } from 'lodash'; + import { EventBus } from '../events'; -import { FieldConfigSource } from './fieldOverrides'; -import { Registry } from '../utils'; import { StandardEditorProps } from '../field'; +import { Registry } from '../utils'; + import { OptionsEditorItem } from './OptionsUIRegistryBuilder'; -import { OptionEditorConfig } from './options'; +import { ScopedVars } from './ScopedVars'; import { AlertStateInfo } from './alerts'; import { PanelModel } from './dashboard'; +import { LoadingState, PreferredVisualisationType } from './data'; +import { DataFrame, FieldType } from './dataFrame'; +import { DataQueryError, DataQueryRequest, DataQueryTimings } from './datasource'; +import { FieldConfigSource } from './fieldOverrides'; +import { OptionEditorConfig } from './options'; +import { PluginMeta } from './plugin'; +import { AbsoluteTimeRange, TimeRange, TimeZone } from './time'; import { DataTransformerConfig } from './transformations'; -import { defaultsDeep } from 'lodash'; export type InterpolateFunction = (value: string, scopedVars?: ScopedVars, format?: string | Function) => string; diff --git a/packages/grafana-data/src/types/plugin.ts b/packages/grafana-data/src/types/plugin.ts index d2f027a1f92..a3c08442493 100644 --- a/packages/grafana-data/src/types/plugin.ts +++ b/packages/grafana-data/src/types/plugin.ts @@ -1,4 +1,5 @@ import { ComponentType } from 'react'; + import { KeyValue } from './data'; /** Describes plugins life cycle status */ diff --git a/packages/grafana-data/src/types/queryRunner.ts b/packages/grafana-data/src/types/queryRunner.ts index ef5a9100d79..09d40b0e151 100644 --- a/packages/grafana-data/src/types/queryRunner.ts +++ b/packages/grafana-data/src/types/queryRunner.ts @@ -1,8 +1,9 @@ import { Observable } from 'rxjs'; -import { DataQuery, DataSourceRef } from './query'; + +import { ScopedVars } from './ScopedVars'; import { DataSourceApi } from './datasource'; import { PanelData } from './panel'; -import { ScopedVars } from './ScopedVars'; +import { DataQuery, DataSourceRef } from './query'; import { TimeRange, TimeZone } from './time'; /** diff --git a/packages/grafana-data/src/types/transformations.ts b/packages/grafana-data/src/types/transformations.ts index 8e2ae2552f4..5af323890ac 100644 --- a/packages/grafana-data/src/types/transformations.ts +++ b/packages/grafana-data/src/types/transformations.ts @@ -1,8 +1,9 @@ import { MonoTypeOperatorFunction } from 'rxjs'; -import { DataFrame, Field } from './dataFrame'; import { RegistryItemWithOptions } from '../utils/Registry'; + import { ScopedVars } from './ScopedVars'; +import { DataFrame, Field } from './dataFrame'; /** * Function that transform data frames (AKA transformer) diff --git a/packages/grafana-data/src/types/variables.ts b/packages/grafana-data/src/types/variables.ts index 1c90dcd7b3e..a7d3087d8ff 100644 --- a/packages/grafana-data/src/types/variables.ts +++ b/packages/grafana-data/src/types/variables.ts @@ -1,6 +1,5 @@ import { ComponentType } from 'react'; import { Observable } from 'rxjs'; -import { DataQuery } from './query'; import { DataQueryRequest, @@ -11,6 +10,7 @@ import { DataSourceQueryType, QueryEditorProps, } from './datasource'; +import { DataQuery } from './query'; /** * Enum with the different variable support types diff --git a/packages/grafana-data/src/utils/OptionsUIBuilders.ts b/packages/grafana-data/src/utils/OptionsUIBuilders.ts index d6c760f04ea..3ce6b10d217 100644 --- a/packages/grafana-data/src/utils/OptionsUIBuilders.ts +++ b/packages/grafana-data/src/utils/OptionsUIBuilders.ts @@ -1,6 +1,3 @@ -import { FieldConfigEditorProps, FieldConfigPropertyItem, FieldConfigEditorConfig } from '../types/fieldOverrides'; -import { OptionsEditorItem, OptionsUIRegistryBuilder } from '../types/OptionsUIRegistryBuilder'; -import { PanelOptionsEditorConfig, PanelOptionsEditorItem } from '../types/panel'; import { numberOverrideProcessor, selectOverrideProcessor, @@ -19,6 +16,9 @@ import { StandardEditorContext, } from '../field'; import { PanelOptionsSupplier } from '../panel/PanelPlugin'; +import { OptionsEditorItem, OptionsUIRegistryBuilder } from '../types/OptionsUIRegistryBuilder'; +import { FieldConfigEditorProps, FieldConfigPropertyItem, FieldConfigEditorConfig } from '../types/fieldOverrides'; +import { PanelOptionsEditorConfig, PanelOptionsEditorItem } from '../types/panel'; /** * Fluent API for declarative creation of field config option editors diff --git a/packages/grafana-data/src/utils/Registry.test.ts b/packages/grafana-data/src/utils/Registry.test.ts index a979c2c6103..b1d30bb6bf7 100644 --- a/packages/grafana-data/src/utils/Registry.test.ts +++ b/packages/grafana-data/src/utils/Registry.test.ts @@ -1,6 +1,7 @@ -import { Registry } from './Registry'; import { FieldReducerInfo, fieldReducers, ReducerID } from '../transformations'; +import { Registry } from './Registry'; + describe('Registry', () => { describe('selectOptions', () => { describe('when called with current', () => { diff --git a/packages/grafana-data/src/utils/arrayUtils.test.ts b/packages/grafana-data/src/utils/arrayUtils.test.ts index 6f7c81aa8ea..892624c5bb2 100644 --- a/packages/grafana-data/src/utils/arrayUtils.test.ts +++ b/packages/grafana-data/src/utils/arrayUtils.test.ts @@ -1,4 +1,5 @@ import { SortOrder } from '@grafana/schema'; + import { sortValues } from './arrayUtils'; describe('arrayUtils', () => { diff --git a/packages/grafana-data/src/utils/csv.test.ts b/packages/grafana-data/src/utils/csv.test.ts index ea5f6598bf1..f6e6ff6817f 100644 --- a/packages/grafana-data/src/utils/csv.test.ts +++ b/packages/grafana-data/src/utils/csv.test.ts @@ -1,12 +1,13 @@ -import { CSVHeaderStyle, readCSV, toCSV } from './csv'; -import { getDataFrameRow, toDataFrameDTO } from '../dataframe/processDataFrame'; - // Test with local CSV files import fs from 'fs'; + import { MutableDataFrame } from '../dataframe'; +import { getDataFrameRow, toDataFrameDTO } from '../dataframe/processDataFrame'; import { getDisplayProcessor } from '../field'; import { createTheme } from '../themes'; +import { CSVHeaderStyle, readCSV, toCSV } from './csv'; + describe('read csv', () => { it('should get X and y', () => { const text = ',1\n2,3,4\n5,6\n,,,7'; diff --git a/packages/grafana-data/src/utils/csv.ts b/packages/grafana-data/src/utils/csv.ts index 11dc0be344a..6ad8c464fc7 100644 --- a/packages/grafana-data/src/utils/csv.ts +++ b/packages/grafana-data/src/utils/csv.ts @@ -1,12 +1,12 @@ // Libraries -import Papa, { ParseConfig, Parser, ParseResult } from 'papaparse'; import { defaults } from 'lodash'; +import Papa, { ParseConfig, Parser, ParseResult } from 'papaparse'; // Types -import { DataFrame, Field, FieldConfig, FieldType } from '../types'; -import { guessFieldTypeFromValue } from '../dataframe/processDataFrame'; import { MutableDataFrame } from '../dataframe/MutableDataFrame'; +import { guessFieldTypeFromValue } from '../dataframe/processDataFrame'; import { getFieldDisplayName } from '../field'; +import { DataFrame, Field, FieldConfig, FieldType } from '../types'; import { formattedValueToString } from '../valueFormats'; export enum CSVHeaderStyle { diff --git a/packages/grafana-data/src/utils/dataLinks.test.ts b/packages/grafana-data/src/utils/dataLinks.test.ts index b609ed2827b..93a249a1df7 100644 --- a/packages/grafana-data/src/utils/dataLinks.test.ts +++ b/packages/grafana-data/src/utils/dataLinks.test.ts @@ -1,7 +1,8 @@ -import { mapInternalLinkToExplore } from './dataLinks'; import { DataLink, FieldType } from '../types'; import { ArrayVector } from '../vector'; +import { mapInternalLinkToExplore } from './dataLinks'; + describe('mapInternalLinkToExplore', () => { it('creates internal link', () => { const dataLink = { diff --git a/packages/grafana-data/src/utils/dataLinks.ts b/packages/grafana-data/src/utils/dataLinks.ts index ce279fe5421..71dabe78e51 100644 --- a/packages/grafana-data/src/utils/dataLinks.ts +++ b/packages/grafana-data/src/utils/dataLinks.ts @@ -10,6 +10,7 @@ import { SplitOpen, TimeRange, } from '../types'; + import { locationUtil } from './location'; import { serializeStateToUrlParam } from './url'; diff --git a/packages/grafana-data/src/utils/datasource.ts b/packages/grafana-data/src/utils/datasource.ts index a57f51a1bdd..95f5ec9af0d 100644 --- a/packages/grafana-data/src/utils/datasource.ts +++ b/packages/grafana-data/src/utils/datasource.ts @@ -1,4 +1,5 @@ import { isString } from 'lodash'; + import { DataSourcePluginOptionsEditorProps, SelectableValue, diff --git a/packages/grafana-data/src/utils/fieldParser.ts b/packages/grafana-data/src/utils/fieldParser.ts index 939f4e401f2..1763cef86ac 100644 --- a/packages/grafana-data/src/utils/fieldParser.ts +++ b/packages/grafana-data/src/utils/fieldParser.ts @@ -1,5 +1,5 @@ -import { Field, FieldType } from '../types/dataFrame'; import { guessFieldTypeFromValue } from '../dataframe/processDataFrame'; +import { Field, FieldType } from '../types/dataFrame'; export function makeFieldParser(value: any, field: Field): (value: string) => any { if (!field.type) { diff --git a/packages/grafana-data/src/utils/flotPairs.test.ts b/packages/grafana-data/src/utils/flotPairs.test.ts index 69dc3e137a3..1ab5d314b2c 100644 --- a/packages/grafana-data/src/utils/flotPairs.test.ts +++ b/packages/grafana-data/src/utils/flotPairs.test.ts @@ -1,7 +1,8 @@ import { MutableDataFrame } from '../dataframe/MutableDataFrame'; -import { getFlotPairs, getFlotPairsConstant } from './flotPairs'; -import { TimeRange } from '../types/time'; import { dateTime } from '../datetime/moment_wrapper'; +import { TimeRange } from '../types/time'; + +import { getFlotPairs, getFlotPairsConstant } from './flotPairs'; describe('getFlotPairs', () => { const series = new MutableDataFrame({ diff --git a/packages/grafana-data/src/utils/flotPairs.ts b/packages/grafana-data/src/utils/flotPairs.ts index 7f99dd11fdb..f17c992742a 100644 --- a/packages/grafana-data/src/utils/flotPairs.ts +++ b/packages/grafana-data/src/utils/flotPairs.ts @@ -1,5 +1,5 @@ -import { Field } from '../types/dataFrame'; import { NullValueMode } from '../types/data'; +import { Field } from '../types/dataFrame'; import { GraphSeriesValue } from '../types/graph'; import { TimeRange } from '../types/time'; diff --git a/packages/grafana-data/src/utils/labels.test.ts b/packages/grafana-data/src/utils/labels.test.ts index d70e9847be6..5bf7d79a093 100644 --- a/packages/grafana-data/src/utils/labels.test.ts +++ b/packages/grafana-data/src/utils/labels.test.ts @@ -1,6 +1,7 @@ -import { parseLabels, formatLabels, findCommonLabels, findUniqueLabels, matchAllLabels } from './labels'; import { Labels } from '../types/data'; +import { parseLabels, formatLabels, findCommonLabels, findUniqueLabels, matchAllLabels } from './labels'; + describe('parseLabels()', () => { it('returns no labels on empty labels string', () => { expect(parseLabels('')).toEqual({}); diff --git a/packages/grafana-data/src/utils/location.ts b/packages/grafana-data/src/utils/location.ts index 7df8796b41b..ee538687394 100644 --- a/packages/grafana-data/src/utils/location.ts +++ b/packages/grafana-data/src/utils/location.ts @@ -1,7 +1,9 @@ import { Location } from 'history'; -import { GrafanaConfig, RawTimeRange, ScopedVars } from '../types'; -import { UrlQueryMap, urlUtil } from './url'; + import { textUtil } from '../text'; +import { GrafanaConfig, RawTimeRange, ScopedVars } from '../types'; + +import { UrlQueryMap, urlUtil } from './url'; let grafanaConfig: GrafanaConfig = { appSubUrl: '' } as any; let getTimeRangeUrlParams: () => RawTimeRange; diff --git a/packages/grafana-data/src/utils/logs.test.ts b/packages/grafana-data/src/utils/logs.test.ts index 11f1248b0c7..cc2387aeec5 100644 --- a/packages/grafana-data/src/utils/logs.test.ts +++ b/packages/grafana-data/src/utils/logs.test.ts @@ -1,5 +1,6 @@ -import { LogLevel, LogsModel, LogRowModel, LogsSortOrder } from '../types/logs'; import { MutableDataFrame } from '../dataframe/MutableDataFrame'; +import { LogLevel, LogsModel, LogRowModel, LogsSortOrder } from '../types/logs'; + import { getLogLevel, calculateLogsLabelStats, diff --git a/packages/grafana-data/src/utils/logs.ts b/packages/grafana-data/src/utils/logs.ts index a95d14fc42e..7fa62feb5d2 100644 --- a/packages/grafana-data/src/utils/logs.ts +++ b/packages/grafana-data/src/utils/logs.ts @@ -1,7 +1,7 @@ import { countBy, chain, escapeRegExp } from 'lodash'; -import { LogLevel, LogRowModel, LogLabelStatsModel, LogsParser, LogsModel, LogsSortOrder } from '../types/logs'; import { DataFrame, FieldType } from '../types/index'; +import { LogLevel, LogRowModel, LogLabelStatsModel, LogsParser, LogsModel, LogsSortOrder } from '../types/logs'; import { ArrayVector } from '../vector/ArrayVector'; // This matches: diff --git a/packages/grafana-data/src/utils/namedColorsPalette.test.ts b/packages/grafana-data/src/utils/namedColorsPalette.test.ts index 2ee9ab1437e..debb0630409 100644 --- a/packages/grafana-data/src/utils/namedColorsPalette.test.ts +++ b/packages/grafana-data/src/utils/namedColorsPalette.test.ts @@ -1,6 +1,7 @@ -import { getColorForTheme } from './namedColorsPalette'; import { createTheme } from '../themes'; +import { getColorForTheme } from './namedColorsPalette'; + describe('colors', () => { const theme = createTheme(); diff --git a/packages/grafana-data/src/utils/series.test.ts b/packages/grafana-data/src/utils/series.test.ts index 4ef77d80726..5ab3d843a14 100644 --- a/packages/grafana-data/src/utils/series.test.ts +++ b/packages/grafana-data/src/utils/series.test.ts @@ -1,7 +1,8 @@ -import { getSeriesTimeStep, hasMsResolution } from './series'; import { Field, FieldType } from '../types'; import { ArrayVector } from '../vector'; +import { getSeriesTimeStep, hasMsResolution } from './series'; + const uniformTimeField: Field = { name: 'time', type: FieldType.time, diff --git a/packages/grafana-data/src/utils/valueMappings.test.ts b/packages/grafana-data/src/utils/valueMappings.test.ts index 11e76aefc94..8acee459ce7 100644 --- a/packages/grafana-data/src/utils/valueMappings.test.ts +++ b/packages/grafana-data/src/utils/valueMappings.test.ts @@ -1,6 +1,7 @@ -import { getValueMappingResult, isNumeric } from './valueMappings'; import { ValueMapping, MappingType, SpecialValueMatch } from '../types'; +import { getValueMappingResult, isNumeric } from './valueMappings'; + const testSet1: ValueMapping[] = [ { type: MappingType.ValueToText, diff --git a/packages/grafana-data/src/utils/valueMappings.ts b/packages/grafana-data/src/utils/valueMappings.ts index e774d058016..3cc2a79c1ec 100644 --- a/packages/grafana-data/src/utils/valueMappings.ts +++ b/packages/grafana-data/src/utils/valueMappings.ts @@ -1,3 +1,5 @@ +import { getActiveThreshold } from '../field'; +import { stringToJsRegex } from '../text/string'; import { MappingType, SpecialValueMatch, @@ -7,8 +9,6 @@ import { ValueMappingResult, SpecialValueOptions, } from '../types'; -import { getActiveThreshold } from '../field'; -import { stringToJsRegex } from '../text/string'; export function getValueMappingResult(valueMappings: ValueMapping[], value: any): ValueMappingResult | null { for (const vm of valueMappings) { diff --git a/packages/grafana-data/src/valueFormats/arithmeticFormatters.ts b/packages/grafana-data/src/valueFormats/arithmeticFormatters.ts index 6aca412f113..a28e2ee7405 100644 --- a/packages/grafana-data/src/valueFormats/arithmeticFormatters.ts +++ b/packages/grafana-data/src/valueFormats/arithmeticFormatters.ts @@ -1,6 +1,7 @@ -import { toFixed, FormattedValue } from './valueFormats'; import { DecimalCount } from '../types/displayValue'; +import { toFixed, FormattedValue } from './valueFormats'; + export function toPercent(size: number, decimals: DecimalCount): FormattedValue { if (size === null) { return { text: '' }; diff --git a/packages/grafana-data/src/valueFormats/categories.ts b/packages/grafana-data/src/valueFormats/categories.ts index 2b3340f9e97..dd6e2455908 100644 --- a/packages/grafana-data/src/valueFormats/categories.ts +++ b/packages/grafana-data/src/valueFormats/categories.ts @@ -1,12 +1,4 @@ -import { - locale, - scaledUnits, - simpleCountUnit, - toFixedUnit, - ValueFormatCategory, - stringFormater, - booleanValueFormatter, -} from './valueFormats'; +import { toHex, sci, toHex0x, toPercent, toPercentUnit } from './arithmeticFormatters'; import { dateTimeAsIso, dateTimeAsIsoNoDateIfToday, @@ -31,8 +23,16 @@ import { toTimeTicks, dateTimeSystemFormatter, } from './dateTimeFormatters'; -import { toHex, sci, toHex0x, toPercent, toPercentUnit } from './arithmeticFormatters'; import { binaryPrefix, currency, SIPrefix } from './symbolFormatters'; +import { + locale, + scaledUnits, + simpleCountUnit, + toFixedUnit, + ValueFormatCategory, + stringFormater, + booleanValueFormatter, +} from './valueFormats'; export const getCategories = (): ValueFormatCategory[] => [ { diff --git a/packages/grafana-data/src/valueFormats/dateTimeFormatters.test.ts b/packages/grafana-data/src/valueFormats/dateTimeFormatters.test.ts index 80b6b9123b5..d61beabce0d 100644 --- a/packages/grafana-data/src/valueFormats/dateTimeFormatters.test.ts +++ b/packages/grafana-data/src/valueFormats/dateTimeFormatters.test.ts @@ -1,3 +1,5 @@ +import { toUtc, dateTime } from '../datetime/moment_wrapper'; + import { dateTimeAsIso, dateTimeAsIsoNoDateIfToday, @@ -17,7 +19,6 @@ import { toSeconds, } from './dateTimeFormatters'; import { formattedValueToString } from './valueFormats'; -import { toUtc, dateTime } from '../datetime/moment_wrapper'; describe('date time formats', () => { const epoch = 1505634997920; diff --git a/packages/grafana-data/src/valueFormats/dateTimeFormatters.ts b/packages/grafana-data/src/valueFormats/dateTimeFormatters.ts index 3f95589d5c3..408f85c5e73 100644 --- a/packages/grafana-data/src/valueFormats/dateTimeFormatters.ts +++ b/packages/grafana-data/src/valueFormats/dateTimeFormatters.ts @@ -1,9 +1,9 @@ +import { dateTimeFormat, dateTimeFormatTimeAgo, localTimeFormat, systemDateFormats } from '../datetime'; import { toDuration as duration, toUtc, dateTime } from '../datetime/moment_wrapper'; +import { TimeZone } from '../types'; +import { DecimalCount } from '../types/displayValue'; import { toFixed, toFixedScaled, FormattedValue, ValueFormatter } from './valueFormats'; -import { DecimalCount } from '../types/displayValue'; -import { TimeZone } from '../types'; -import { dateTimeFormat, dateTimeFormatTimeAgo, localTimeFormat, systemDateFormats } from '../datetime'; interface IntervalsInSeconds { [interval: string]: number; diff --git a/packages/grafana-data/src/valueFormats/symbolFormatters.ts b/packages/grafana-data/src/valueFormats/symbolFormatters.ts index 54c96bfb966..cb59e83f464 100644 --- a/packages/grafana-data/src/valueFormats/symbolFormatters.ts +++ b/packages/grafana-data/src/valueFormats/symbolFormatters.ts @@ -1,6 +1,7 @@ -import { scaledUnits, ValueFormatter } from './valueFormats'; import { DecimalCount } from '../types/displayValue'; +import { scaledUnits, ValueFormatter } from './valueFormats'; + export function currency(symbol: string, asSuffix?: boolean): ValueFormatter { const units = ['', 'K', 'M', 'B', 'T']; const scaler = scaledUnits(1000, units); diff --git a/packages/grafana-data/src/valueFormats/valueFormats.test.ts b/packages/grafana-data/src/valueFormats/valueFormats.test.ts index 3aedf0f42bc..202eeccfe4d 100644 --- a/packages/grafana-data/src/valueFormats/valueFormats.test.ts +++ b/packages/grafana-data/src/valueFormats/valueFormats.test.ts @@ -1,7 +1,8 @@ -import { toFixed, getValueFormat, scaledUnits, formattedValueToString } from './valueFormats'; -import { DecimalCount } from '../types/displayValue'; -import { TimeZone } from '../types'; import { dateTime } from '../datetime'; +import { TimeZone } from '../types'; +import { DecimalCount } from '../types/displayValue'; + +import { toFixed, getValueFormat, scaledUnits, formattedValueToString } from './valueFormats'; interface ValueFormatTest { id: string; diff --git a/packages/grafana-data/src/valueFormats/valueFormats.ts b/packages/grafana-data/src/valueFormats/valueFormats.ts index 76a38232cdf..c0ea18dfd31 100644 --- a/packages/grafana-data/src/valueFormats/valueFormats.ts +++ b/packages/grafana-data/src/valueFormats/valueFormats.ts @@ -1,8 +1,9 @@ -import { getCategories } from './categories'; +import { TimeZone } from '../types'; import { DecimalCount } from '../types/displayValue'; + +import { getCategories } from './categories'; import { toDateTimeValueFormatter } from './dateTimeFormatters'; import { getOffsetFromSIPrefix, SIPrefix, currency } from './symbolFormatters'; -import { TimeZone } from '../types'; export interface FormattedValue { text: string; diff --git a/packages/grafana-data/src/vector/AppendedVectors.test.ts b/packages/grafana-data/src/vector/AppendedVectors.test.ts index 9d39b47ce09..00c1f4272b2 100644 --- a/packages/grafana-data/src/vector/AppendedVectors.test.ts +++ b/packages/grafana-data/src/vector/AppendedVectors.test.ts @@ -1,5 +1,5 @@ -import { ArrayVector } from './ArrayVector'; import { AppendedVectors } from './AppendedVectors'; +import { ArrayVector } from './ArrayVector'; describe('Check Appending Vector', () => { it('should transparently join them', () => { diff --git a/packages/grafana-data/src/vector/AppendedVectors.ts b/packages/grafana-data/src/vector/AppendedVectors.ts index 7d806cfbbd2..cc33811f731 100644 --- a/packages/grafana-data/src/vector/AppendedVectors.ts +++ b/packages/grafana-data/src/vector/AppendedVectors.ts @@ -1,4 +1,5 @@ import { Vector } from '../types/vector'; + import { vectorToArray } from './vectorToArray'; interface AppendedVectorInfo { diff --git a/packages/grafana-data/src/vector/ArrayVector.ts b/packages/grafana-data/src/vector/ArrayVector.ts index 3df650e3044..d153cfb636c 100644 --- a/packages/grafana-data/src/vector/ArrayVector.ts +++ b/packages/grafana-data/src/vector/ArrayVector.ts @@ -1,4 +1,5 @@ import { MutableVector } from '../types/vector'; + import { FunctionalVector } from './FunctionalVector'; /** diff --git a/packages/grafana-data/src/vector/AsNumberVector.ts b/packages/grafana-data/src/vector/AsNumberVector.ts index c8a65916a3f..775068dbe45 100644 --- a/packages/grafana-data/src/vector/AsNumberVector.ts +++ b/packages/grafana-data/src/vector/AsNumberVector.ts @@ -1,4 +1,5 @@ import { Vector } from '../types'; + import { FunctionalVector } from './FunctionalVector'; /** diff --git a/packages/grafana-data/src/vector/BinaryOperationVector.test.ts b/packages/grafana-data/src/vector/BinaryOperationVector.test.ts index c6d9955cbaf..d26ed06d3bb 100644 --- a/packages/grafana-data/src/vector/BinaryOperationVector.test.ts +++ b/packages/grafana-data/src/vector/BinaryOperationVector.test.ts @@ -1,7 +1,8 @@ +import { binaryOperators, BinaryOperationID } from '../utils/binaryOperators'; + import { ArrayVector } from './ArrayVector'; import { BinaryOperationVector } from './BinaryOperationVector'; import { ConstantVector } from './ConstantVector'; -import { binaryOperators, BinaryOperationID } from '../utils/binaryOperators'; describe('ScaledVector', () => { it('should support multiply operations', () => { diff --git a/packages/grafana-data/src/vector/BinaryOperationVector.ts b/packages/grafana-data/src/vector/BinaryOperationVector.ts index 1740f99bb72..a8ea3024bec 100644 --- a/packages/grafana-data/src/vector/BinaryOperationVector.ts +++ b/packages/grafana-data/src/vector/BinaryOperationVector.ts @@ -1,7 +1,8 @@ import { Vector } from '../types/vector'; -import { vectorToArray } from './vectorToArray'; import { BinaryOperation } from '../utils/binaryOperators'; +import { vectorToArray } from './vectorToArray'; + /** * @public */ diff --git a/packages/grafana-data/src/vector/CircularVector.ts b/packages/grafana-data/src/vector/CircularVector.ts index 3f3b1f6c95e..6d848ad40f4 100644 --- a/packages/grafana-data/src/vector/CircularVector.ts +++ b/packages/grafana-data/src/vector/CircularVector.ts @@ -1,6 +1,7 @@ import { MutableVector } from '../types/vector'; -import { vectorToArray } from './vectorToArray'; + import { FunctionalVector } from './FunctionalVector'; +import { vectorToArray } from './vectorToArray'; interface CircularOptions { buffer?: T[]; diff --git a/packages/grafana-data/src/vector/FormattedVector.ts b/packages/grafana-data/src/vector/FormattedVector.ts index f30e958026d..277342173ed 100644 --- a/packages/grafana-data/src/vector/FormattedVector.ts +++ b/packages/grafana-data/src/vector/FormattedVector.ts @@ -1,6 +1,7 @@ -import { Vector } from '../types/vector'; import { DisplayProcessor } from '../types'; +import { Vector } from '../types/vector'; import { formattedValueToString } from '../valueFormats'; + import { FunctionalVector } from './FunctionalVector'; /** diff --git a/packages/grafana-data/src/vector/FunctionalVector.ts b/packages/grafana-data/src/vector/FunctionalVector.ts index 6a6c719be2a..b9f4e22907b 100644 --- a/packages/grafana-data/src/vector/FunctionalVector.ts +++ b/packages/grafana-data/src/vector/FunctionalVector.ts @@ -1,6 +1,7 @@ -import { vectorToArray } from './vectorToArray'; import { Vector } from '../types'; +import { vectorToArray } from './vectorToArray'; + /** @public */ export abstract class FunctionalVector implements Vector, Iterable { abstract get length(): number; diff --git a/packages/grafana-data/src/vector/IndexVector.ts b/packages/grafana-data/src/vector/IndexVector.ts index df695fc0e6c..4a7fc3dfc27 100644 --- a/packages/grafana-data/src/vector/IndexVector.ts +++ b/packages/grafana-data/src/vector/IndexVector.ts @@ -1,4 +1,5 @@ import { Field, FieldType } from '../types'; + import { FunctionalVector } from './FunctionalVector'; /** diff --git a/packages/grafana-data/src/vector/RowVector.ts b/packages/grafana-data/src/vector/RowVector.ts index d05904c28b3..21746be48fd 100644 --- a/packages/grafana-data/src/vector/RowVector.ts +++ b/packages/grafana-data/src/vector/RowVector.ts @@ -1,4 +1,5 @@ import { Vector } from '../types'; + import { vectorToArray } from './vectorToArray'; /** diff --git a/packages/grafana-data/src/vector/SortedVector.ts b/packages/grafana-data/src/vector/SortedVector.ts index 33b97f6778f..0d66dff6ded 100644 --- a/packages/grafana-data/src/vector/SortedVector.ts +++ b/packages/grafana-data/src/vector/SortedVector.ts @@ -1,4 +1,5 @@ import { Vector } from '../types/vector'; + import { vectorToArray } from './vectorToArray'; /** diff --git a/packages/grafana-e2e-selectors/src/selectors/index.ts b/packages/grafana-e2e-selectors/src/selectors/index.ts index 7f82a08b6ce..5cedeb04627 100644 --- a/packages/grafana-e2e-selectors/src/selectors/index.ts +++ b/packages/grafana-e2e-selectors/src/selectors/index.ts @@ -1,7 +1,8 @@ -import { Pages } from './pages'; -import { Components } from './components'; import { E2ESelectors } from '../types'; +import { Components } from './components'; +import { Pages } from './pages'; + /** * Exposes selectors in package for easy use in e2e tests and in production code * diff --git a/packages/grafana-e2e/cli.js b/packages/grafana-e2e/cli.js index 88dedf61da9..c2d42b204e4 100644 --- a/packages/grafana-e2e/cli.js +++ b/packages/grafana-e2e/cli.js @@ -1,7 +1,7 @@ -const execa = require('execa'); const { program } = require('commander'); -const resolveBin = require('resolve-as-bin'); +const execa = require('execa'); const { resolve, sep } = require('path'); +const resolveBin = require('resolve-as-bin'); const cypress = (commandName, { updateScreenshots }) => { // Support running an unpublished dev build diff --git a/packages/grafana-e2e/cypress/plugins/benchmark/CDPDataCollector.ts b/packages/grafana-e2e/cypress/plugins/benchmark/CDPDataCollector.ts index b3f59028d06..76e120a741c 100644 --- a/packages/grafana-e2e/cypress/plugins/benchmark/CDPDataCollector.ts +++ b/packages/grafana-e2e/cypress/plugins/benchmark/CDPDataCollector.ts @@ -1,8 +1,8 @@ import CDP from 'chrome-remote-interface'; +import ProtocolProxyApi from 'devtools-protocol/types/protocol-proxy-api'; +import { countBy, mean } from 'lodash'; import Tracelib, { TraceEvent } from 'tracelib'; -import { countBy, mean } from 'lodash'; -import ProtocolProxyApi from 'devtools-protocol/types/protocol-proxy-api'; import { CollectedData, DataCollector, DataCollectorName } from './DataCollector'; type CDPDataCollectorDeps = { diff --git a/packages/grafana-e2e/cypress/plugins/benchmark/formatting.ts b/packages/grafana-e2e/cypress/plugins/benchmark/formatting.ts index 8372309f50f..3ecb983a027 100644 --- a/packages/grafana-e2e/cypress/plugins/benchmark/formatting.ts +++ b/packages/grafana-e2e/cypress/plugins/benchmark/formatting.ts @@ -1,6 +1,7 @@ -import { CollectedData, DataCollectorName } from './DataCollector'; import { fromPairs } from 'lodash'; +import { CollectedData, DataCollectorName } from './DataCollector'; + type Stats = { sum: number; min: number; diff --git a/packages/grafana-e2e/cypress/plugins/benchmark/index.ts b/packages/grafana-e2e/cypress/plugins/benchmark/index.ts index d822b40dc67..22307555d58 100644 --- a/packages/grafana-e2e/cypress/plugins/benchmark/index.ts +++ b/packages/grafana-e2e/cypress/plugins/benchmark/index.ts @@ -1,7 +1,8 @@ -import { CollectedData, DataCollector } from './DataCollector'; -import { CDPDataCollector } from './CDPDataCollector'; -import { fromPairs } from 'lodash'; import fs from 'fs'; +import { fromPairs } from 'lodash'; + +import { CDPDataCollector } from './CDPDataCollector'; +import { CollectedData, DataCollector } from './DataCollector'; import { formatResults } from './formatting'; const remoteDebuggingPortOptionPrefix = '--remote-debugging-port='; diff --git a/packages/grafana-e2e/cypress/plugins/index.js b/packages/grafana-e2e/cypress/plugins/index.js index d9c4eebba76..9b3125623ed 100644 --- a/packages/grafana-e2e/cypress/plugins/index.js +++ b/packages/grafana-e2e/cypress/plugins/index.js @@ -1,11 +1,11 @@ const fs = require('fs'); const path = require('path'); +const benchmarkPlugin = require('./benchmark'); const compareScreenshots = require('./compareScreenshots'); const extendConfig = require('./extendConfig'); const readProvisions = require('./readProvisions'); const typescriptPreprocessor = require('./typescriptPreprocessor'); -const benchmarkPlugin = require('./benchmark'); module.exports = (on, config) => { if (config.env['BENCHMARK_PLUGIN_ENABLED'] === true) { diff --git a/packages/grafana-e2e/cypress/plugins/readProvisions.js b/packages/grafana-e2e/cypress/plugins/readProvisions.js index 92f6c16c223..f82542d2070 100644 --- a/packages/grafana-e2e/cypress/plugins/readProvisions.js +++ b/packages/grafana-e2e/cypress/plugins/readProvisions.js @@ -1,9 +1,9 @@ 'use strict'; -const { parse: parseYml } = require('yaml'); const { promises: { readFile }, } = require('fs'); const { resolve: resolvePath } = require('path'); +const { parse: parseYml } = require('yaml'); const readProvision = (filePath) => readFile(filePath, 'utf8').then((contents) => parseYml(contents)); diff --git a/packages/grafana-e2e/cypress/plugins/typescriptPreprocessor.js b/packages/grafana-e2e/cypress/plugins/typescriptPreprocessor.js index 8de33d53e2f..be506578188 100644 --- a/packages/grafana-e2e/cypress/plugins/typescriptPreprocessor.js +++ b/packages/grafana-e2e/cypress/plugins/typescriptPreprocessor.js @@ -1,5 +1,5 @@ -const { resolve } = require('path'); const wp = require('@cypress/webpack-preprocessor'); +const { resolve } = require('path'); const anyNodeModules = /node_modules/; const packageRoot = resolve(`${__dirname}/../../`); diff --git a/packages/grafana-e2e/rollup.config.ts b/packages/grafana-e2e/rollup.config.ts index 341c18b8719..b3189469b61 100644 --- a/packages/grafana-e2e/rollup.config.ts +++ b/packages/grafana-e2e/rollup.config.ts @@ -1,5 +1,5 @@ -import resolve from '@rollup/plugin-node-resolve'; import commonjs from '@rollup/plugin-commonjs'; +import resolve from '@rollup/plugin-node-resolve'; import copy from 'rollup-plugin-copy'; import sourceMaps from 'rollup-plugin-sourcemaps'; import { terser } from 'rollup-plugin-terser'; diff --git a/packages/grafana-e2e/src/flows/addDashboard.ts b/packages/grafana-e2e/src/flows/addDashboard.ts index d7efeb9c9ba..252f9b79156 100644 --- a/packages/grafana-e2e/src/flows/addDashboard.ts +++ b/packages/grafana-e2e/src/flows/addDashboard.ts @@ -1,9 +1,11 @@ -import { DeleteDashboardConfig } from './deleteDashboard'; +import { v4 as uuidv4 } from 'uuid'; + import { e2e } from '../index'; import { getDashboardUid } from '../support/url'; -import { setDashboardTimeRange, TimeRangeConfig } from './setDashboardTimeRange'; -import { v4 as uuidv4 } from 'uuid'; + +import { DeleteDashboardConfig } from './deleteDashboard'; import { selectOption } from './selectOption'; +import { setDashboardTimeRange, TimeRangeConfig } from './setDashboardTimeRange'; export interface AddAnnotationConfig { dataSource: string; diff --git a/packages/grafana-e2e/src/flows/addDataSource.ts b/packages/grafana-e2e/src/flows/addDataSource.ts index bb507f12c49..5c6a9fdcd5e 100644 --- a/packages/grafana-e2e/src/flows/addDataSource.ts +++ b/packages/grafana-e2e/src/flows/addDataSource.ts @@ -1,7 +1,9 @@ -import { DeleteDataSourceConfig } from './deleteDataSource'; -import { e2e } from '../index'; import { v4 as uuidv4 } from 'uuid'; +import { e2e } from '../index'; + +import { DeleteDataSourceConfig } from './deleteDataSource'; + export interface AddDataSourceConfig { basicAuth: boolean; basicAuthPassword: string; diff --git a/packages/grafana-e2e/src/flows/addPanel.ts b/packages/grafana-e2e/src/flows/addPanel.ts index f24029c400b..0f214e51835 100644 --- a/packages/grafana-e2e/src/flows/addPanel.ts +++ b/packages/grafana-e2e/src/flows/addPanel.ts @@ -1,7 +1,9 @@ -import { configurePanel, PartialAddPanelConfig } from './configurePanel'; -import { getScenarioContext } from '../support/scenarioContext'; import { v4 as uuidv4 } from 'uuid'; +import { getScenarioContext } from '../support/scenarioContext'; + +import { configurePanel, PartialAddPanelConfig } from './configurePanel'; + export const addPanel = (config?: Partial) => getScenarioContext().then(({ lastAddedDataSource }: any) => configurePanel({ diff --git a/packages/grafana-e2e/src/flows/configurePanel.ts b/packages/grafana-e2e/src/flows/configurePanel.ts index 182bdaab287..275561809d1 100644 --- a/packages/grafana-e2e/src/flows/configurePanel.ts +++ b/packages/grafana-e2e/src/flows/configurePanel.ts @@ -1,5 +1,6 @@ import { e2e } from '../index'; import { getScenarioContext } from '../support/scenarioContext'; + import { selectOption } from './selectOption'; import { setDashboardTimeRange } from './setDashboardTimeRange'; import { TimeRangeConfig } from './setTimeRange'; diff --git a/packages/grafana-e2e/src/flows/importDashboard.ts b/packages/grafana-e2e/src/flows/importDashboard.ts index c054dd4ad3a..3b4e37371f1 100644 --- a/packages/grafana-e2e/src/flows/importDashboard.ts +++ b/packages/grafana-e2e/src/flows/importDashboard.ts @@ -1,7 +1,8 @@ -import { DeleteDashboardConfig } from '.'; import { e2e } from '../index'; import { fromBaseUrl, getDashboardUid } from '../support/url'; +import { DeleteDashboardConfig } from '.'; + type Panel = { title: string; [key: string]: unknown; diff --git a/packages/grafana-e2e/src/flows/importDashboards.ts b/packages/grafana-e2e/src/flows/importDashboards.ts index 24b7bd356f8..90a126b947a 100644 --- a/packages/grafana-e2e/src/flows/importDashboards.ts +++ b/packages/grafana-e2e/src/flows/importDashboards.ts @@ -1,6 +1,7 @@ -import { importDashboard, Dashboard } from './importDashboard'; import { e2e } from '../index'; +import { importDashboard, Dashboard } from './importDashboard'; + /** * Smoke test several dashboard json files from a test directory * and validate that all the panels in each import finish loading their queries diff --git a/packages/grafana-e2e/src/flows/openDashboard.ts b/packages/grafana-e2e/src/flows/openDashboard.ts index 67c9544b8fe..c535099e63a 100644 --- a/packages/grafana-e2e/src/flows/openDashboard.ts +++ b/packages/grafana-e2e/src/flows/openDashboard.ts @@ -1,5 +1,6 @@ import { e2e } from '../index'; import { getScenarioContext } from '../support/scenarioContext'; + import { setDashboardTimeRange, TimeRangeConfig } from './setDashboardTimeRange'; interface OpenDashboardDefault { diff --git a/packages/grafana-e2e/src/flows/setTimeRange.ts b/packages/grafana-e2e/src/flows/setTimeRange.ts index bcf719087d8..ad5b1d84081 100644 --- a/packages/grafana-e2e/src/flows/setTimeRange.ts +++ b/packages/grafana-e2e/src/flows/setTimeRange.ts @@ -1,4 +1,5 @@ import { e2e } from '../index'; + import { selectOption } from './selectOption'; export interface TimeRangeConfig { diff --git a/packages/grafana-e2e/src/index.ts b/packages/grafana-e2e/src/index.ts index b4c62c16352..58cacd133cf 100644 --- a/packages/grafana-e2e/src/index.ts +++ b/packages/grafana-e2e/src/index.ts @@ -3,12 +3,13 @@ * * @packageDocumentation */ -import { e2eScenario, ScenarioArguments } from './support/scenario'; -import { benchmark } from './support/benchmark'; -import { getScenarioContext, setScenarioContext } from './support/scenarioContext'; -import { e2eFactory } from './support'; import { E2ESelectors, Selectors, selectors } from '@grafana/e2e-selectors'; + import * as flows from './flows'; +import { e2eFactory } from './support'; +import { benchmark } from './support/benchmark'; +import { e2eScenario, ScenarioArguments } from './support/scenario'; +import { getScenarioContext, setScenarioContext } from './support/scenarioContext'; import * as typings from './typings'; const e2eObject = { diff --git a/packages/grafana-e2e/src/support/scenarioContext.ts b/packages/grafana-e2e/src/support/scenarioContext.ts index eeba3776c6e..510408a2b56 100644 --- a/packages/grafana-e2e/src/support/scenarioContext.ts +++ b/packages/grafana-e2e/src/support/scenarioContext.ts @@ -1,6 +1,6 @@ -import { e2e } from '../index'; import { DeleteDashboardConfig } from '../flows/deleteDashboard'; import { DeleteDataSourceConfig } from '../flows/deleteDataSource'; +import { e2e } from '../index'; export interface ScenarioContext { addedDashboards: DeleteDashboardConfig[]; diff --git a/packages/grafana-e2e/src/support/types.ts b/packages/grafana-e2e/src/support/types.ts index c0db64b11bb..e44a978194c 100644 --- a/packages/grafana-e2e/src/support/types.ts +++ b/packages/grafana-e2e/src/support/types.ts @@ -1,5 +1,7 @@ import { CssSelector, FunctionSelector, Selectors, StringSelector, UrlSelector } from '@grafana/e2e-selectors'; + import { e2e } from '../index'; + import { Selector } from './selector'; import { fromBaseUrl } from './url'; diff --git a/packages/grafana-runtime/rollup.config.ts b/packages/grafana-runtime/rollup.config.ts index 5fa32f856b1..c0bd7cbd7a5 100644 --- a/packages/grafana-runtime/rollup.config.ts +++ b/packages/grafana-runtime/rollup.config.ts @@ -1,5 +1,5 @@ -import resolve from '@rollup/plugin-node-resolve'; import commonjs from '@rollup/plugin-commonjs'; +import resolve from '@rollup/plugin-node-resolve'; import sourceMaps from 'rollup-plugin-sourcemaps'; import { terser } from 'rollup-plugin-terser'; diff --git a/packages/grafana-runtime/src/components/DataSourcePicker.test.tsx b/packages/grafana-runtime/src/components/DataSourcePicker.test.tsx index 10a2cbd7b17..e41eaeaa4f0 100644 --- a/packages/grafana-runtime/src/components/DataSourcePicker.test.tsx +++ b/packages/grafana-runtime/src/components/DataSourcePicker.test.tsx @@ -1,7 +1,8 @@ -import React from 'react'; -import { DataSourcePicker } from './DataSourcePicker'; import { render } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import React from 'react'; + +import { DataSourcePicker } from './DataSourcePicker'; jest.mock('../services/dataSourceSrv'); diff --git a/packages/grafana-runtime/src/components/DataSourcePicker.tsx b/packages/grafana-runtime/src/components/DataSourcePicker.tsx index 1d71963d9a7..fd0ddb7f307 100644 --- a/packages/grafana-runtime/src/components/DataSourcePicker.tsx +++ b/packages/grafana-runtime/src/components/DataSourcePicker.tsx @@ -2,7 +2,6 @@ import React, { PureComponent } from 'react'; // Components -import { ActionMeta, HorizontalGroup, PluginSignatureBadge, Select } from '@grafana/ui'; import { DataSourceInstanceSettings, DataSourceRef, @@ -11,6 +10,8 @@ import { SelectableValue, } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; +import { ActionMeta, HorizontalGroup, PluginSignatureBadge, Select } from '@grafana/ui'; + import { getDataSourceSrv } from '../services/dataSourceSrv'; /** diff --git a/packages/grafana-runtime/src/components/PanelDataErrorView.tsx b/packages/grafana-runtime/src/components/PanelDataErrorView.tsx index 2e3907c9264..61b88a63032 100644 --- a/packages/grafana-runtime/src/components/PanelDataErrorView.tsx +++ b/packages/grafana-runtime/src/components/PanelDataErrorView.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { FieldConfigSource, PanelData } from '@grafana/data'; /** diff --git a/packages/grafana-runtime/src/components/PanelRenderer.tsx b/packages/grafana-runtime/src/components/PanelRenderer.tsx index a2f8cc341cd..374ac9bb5fe 100644 --- a/packages/grafana-runtime/src/components/PanelRenderer.tsx +++ b/packages/grafana-runtime/src/components/PanelRenderer.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { AbsoluteTimeRange, FieldConfigSource, PanelData } from '@grafana/data'; /** diff --git a/packages/grafana-runtime/src/config.ts b/packages/grafana-runtime/src/config.ts index d5076e5ae6a..a37143b9de8 100644 --- a/packages/grafana-runtime/src/config.ts +++ b/packages/grafana-runtime/src/config.ts @@ -1,4 +1,5 @@ import { merge } from 'lodash'; + import { BootData, BuildInfo, diff --git a/packages/grafana-runtime/src/services/LocationService.ts b/packages/grafana-runtime/src/services/LocationService.ts index e76cc4c57d7..d09b4590447 100644 --- a/packages/grafana-runtime/src/services/LocationService.ts +++ b/packages/grafana-runtime/src/services/LocationService.ts @@ -1,9 +1,12 @@ -import { deprecationWarning, UrlQueryMap, urlUtil } from '@grafana/data'; import * as H from 'history'; -import { LocationUpdate } from './LocationSrv'; + +import { deprecationWarning, UrlQueryMap, urlUtil } from '@grafana/data'; import { attachDebugger, createLogger } from '@grafana/ui'; + import { config } from '../config'; +import { LocationUpdate } from './LocationSrv'; + /** * @public * A wrapper to help work with browser location and history diff --git a/packages/grafana-runtime/src/services/live.ts b/packages/grafana-runtime/src/services/live.ts index a29973a0644..f452cf35e04 100644 --- a/packages/grafana-runtime/src/services/live.ts +++ b/packages/grafana-runtime/src/services/live.ts @@ -1,3 +1,5 @@ +import { Observable } from 'rxjs'; + import { DataFrameJSON, DataQueryRequest, @@ -6,7 +8,6 @@ import { LiveChannelEvent, LiveChannelPresenceStatus, } from '@grafana/data'; -import { Observable } from 'rxjs'; /** * @alpha -- experimental diff --git a/packages/grafana-runtime/src/utils/DataSourceWithBackend.test.ts b/packages/grafana-runtime/src/utils/DataSourceWithBackend.test.ts index 622dcaf4f8d..0a3b68801f7 100644 --- a/packages/grafana-runtime/src/utils/DataSourceWithBackend.test.ts +++ b/packages/grafana-runtime/src/utils/DataSourceWithBackend.test.ts @@ -1,5 +1,6 @@ +import { of } from 'rxjs'; import { BackendSrv, BackendSrvRequest } from 'src/services'; -import { DataSourceWithBackend, standardStreamOptionsProvider, toStreamingDataResponse } from './DataSourceWithBackend'; + import { DataSourceJsonData, DataQuery, @@ -9,7 +10,8 @@ import { MutableDataFrame, DataSourceRef, } from '@grafana/data'; -import { of } from 'rxjs'; + +import { DataSourceWithBackend, standardStreamOptionsProvider, toStreamingDataResponse } from './DataSourceWithBackend'; class MyDataSource extends DataSourceWithBackend { constructor(instanceSettings: DataSourceInstanceSettings) { diff --git a/packages/grafana-runtime/src/utils/DataSourceWithBackend.ts b/packages/grafana-runtime/src/utils/DataSourceWithBackend.ts index 9040bd70796..f79f76eaddb 100644 --- a/packages/grafana-runtime/src/utils/DataSourceWithBackend.ts +++ b/packages/grafana-runtime/src/utils/DataSourceWithBackend.ts @@ -1,3 +1,6 @@ +import { merge, Observable, of } from 'rxjs'; +import { catchError, switchMap } from 'rxjs/operators'; + import { DataSourceApi, DataQueryRequest, @@ -13,8 +16,8 @@ import { DataSourceRef, dataFrameToJSON, } from '@grafana/data'; -import { merge, Observable, of } from 'rxjs'; -import { catchError, switchMap } from 'rxjs/operators'; + +import { config } from '../config'; import { getBackendSrv, getDataSourceSrv, @@ -22,7 +25,7 @@ import { StreamingFrameOptions, StreamingFrameAction, } from '../services'; -import { config } from '../config'; + import { BackendDataSourceResponse, toDataQueryResponse } from './queryResponse'; /** diff --git a/packages/grafana-runtime/src/utils/analytics.ts b/packages/grafana-runtime/src/utils/analytics.ts index 3488de8eaf2..9ec3ce4b97d 100644 --- a/packages/grafana-runtime/src/utils/analytics.ts +++ b/packages/grafana-runtime/src/utils/analytics.ts @@ -1,3 +1,5 @@ +import { config } from '../config'; +import { locationService } from '../services'; import { getEchoSrv, EchoEventType } from '../services/EchoSrv'; import { ExperimentViewEchoEvent, @@ -6,8 +8,6 @@ import { MetaAnalyticsEventPayload, PageviewEchoEvent, } from '../types/analytics'; -import { locationService } from '../services'; -import { config } from '../config'; /** * Helper function to report meta analytics to the {@link EchoSrv}. diff --git a/packages/grafana-runtime/src/utils/plugin.ts b/packages/grafana-runtime/src/utils/plugin.ts index 5791dd00519..9a5363e3f07 100644 --- a/packages/grafana-runtime/src/utils/plugin.ts +++ b/packages/grafana-runtime/src/utils/plugin.ts @@ -1,7 +1,9 @@ +// @ts-ignore +import System from 'systemjs/dist/system.js'; + import { config } from '../config'; // @ts-ignore -import System from 'systemjs/dist/system.js'; /** * Option to specify a plugin css that should be applied for the dark diff --git a/packages/grafana-runtime/src/utils/queryResponse.test.ts b/packages/grafana-runtime/src/utils/queryResponse.test.ts index cb2ef029708..149c88526ac 100644 --- a/packages/grafana-runtime/src/utils/queryResponse.test.ts +++ b/packages/grafana-runtime/src/utils/queryResponse.test.ts @@ -1,5 +1,7 @@ -import { DataQuery, toDataFrameDTO, DataFrame } from '@grafana/data'; import { FetchError, FetchResponse } from 'src/services'; + +import { DataQuery, toDataFrameDTO, DataFrame } from '@grafana/data'; + import { BackendDataSourceResponse, cachedResponseNotice, toDataQueryResponse, toTestingStatus } from './queryResponse'; const resp = { diff --git a/packages/grafana-runtime/src/utils/queryResponse.ts b/packages/grafana-runtime/src/utils/queryResponse.ts index 800918ab0aa..a17aaf1c1d9 100644 --- a/packages/grafana-runtime/src/utils/queryResponse.ts +++ b/packages/grafana-runtime/src/utils/queryResponse.ts @@ -14,7 +14,9 @@ import { dataFrameFromJSON, QueryResultMetaNotice, } from '@grafana/data'; + import { FetchError, FetchResponse } from '../services'; + import { toDataQueryError } from './toDataQueryError'; export const cachedResponseNotice: QueryResultMetaNotice = { severity: 'info', text: 'Cached response' }; diff --git a/packages/grafana-schema/rollup.config.ts b/packages/grafana-schema/rollup.config.ts index 5342797fe32..f0159430417 100644 --- a/packages/grafana-schema/rollup.config.ts +++ b/packages/grafana-schema/rollup.config.ts @@ -1,5 +1,5 @@ -import resolve from '@rollup/plugin-node-resolve'; import commonjs from '@rollup/plugin-commonjs'; +import resolve from '@rollup/plugin-node-resolve'; import sourceMaps from 'rollup-plugin-sourcemaps'; import { terser } from 'rollup-plugin-terser'; diff --git a/packages/grafana-toolkit/docker/grafana-plugin-ci-alpine/install/bin/githubRelease.js b/packages/grafana-toolkit/docker/grafana-plugin-ci-alpine/install/bin/githubRelease.js index 54062c15767..5db7d4bcc2c 100644 --- a/packages/grafana-toolkit/docker/grafana-plugin-ci-alpine/install/bin/githubRelease.js +++ b/packages/grafana-toolkit/docker/grafana-plugin-ci-alpine/install/bin/githubRelease.js @@ -1,11 +1,12 @@ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); +var fs = require('fs'); +var path = require('path'); var tslib_1 = require('tslib'); + var getPluginId_1 = require('../../config/utils/getPluginId'); var pluginValidation_1 = require('../../config/utils/pluginValidation'); var env_1 = require('../../plugins/env'); -var path = require('path'); -var fs = require('fs'); // @ts-ignore // import execa = require('execa'); var githubClient_1 = tslib_1.__importDefault(require('./githubClient')); diff --git a/packages/grafana-toolkit/src/cli/index.ts b/packages/grafana-toolkit/src/cli/index.ts index f8ec7bc945d..8dc814cf0fb 100644 --- a/packages/grafana-toolkit/src/cli/index.ts +++ b/packages/grafana-toolkit/src/cli/index.ts @@ -1,26 +1,27 @@ // @ts-ignore import chalk from 'chalk'; import { program } from 'commander'; -import { execTask } from './utils/execTask'; -import { startTask } from './tasks/core.start'; + import { changelogTask } from './tasks/changelog'; import { cherryPickTask } from './tasks/cherrypick'; -import { templateTask } from './tasks/template'; -import { pluginBuildTask } from './tasks/plugin.build'; -import { toolkitBuildTask } from './tasks/toolkit.build'; -import { pluginTestTask } from './tasks/plugin.tests'; -import { searchTestDataSetupTask } from './tasks/searchTestDataSetup'; import { closeMilestoneTask } from './tasks/closeMilestone'; -import { pluginDevTask } from './tasks/plugin.dev'; -import { getToolkitVersion, githubPublishTask } from './tasks/plugin.utils'; -import { pluginUpdateTask } from './tasks/plugin.update'; -import { ciBuildPluginTask, ciPackagePluginTask, ciPluginReportTask } from './tasks/plugin.ci'; -import { buildPackageTask } from './tasks/package.build'; -import { pluginCreateTask } from './tasks/plugin.create'; -import { pluginSignTask } from './tasks/plugin.sign'; -import { bundleManagedTask } from './tasks/plugin/bundle.managed'; import { componentCreateTask } from './tasks/component.create'; +import { startTask } from './tasks/core.start'; import { nodeVersionCheckerTask } from './tasks/nodeVersionChecker'; +import { buildPackageTask } from './tasks/package.build'; +import { pluginBuildTask } from './tasks/plugin.build'; +import { ciBuildPluginTask, ciPackagePluginTask, ciPluginReportTask } from './tasks/plugin.ci'; +import { pluginCreateTask } from './tasks/plugin.create'; +import { pluginDevTask } from './tasks/plugin.dev'; +import { pluginSignTask } from './tasks/plugin.sign'; +import { pluginTestTask } from './tasks/plugin.tests'; +import { pluginUpdateTask } from './tasks/plugin.update'; +import { getToolkitVersion, githubPublishTask } from './tasks/plugin.utils'; +import { bundleManagedTask } from './tasks/plugin/bundle.managed'; +import { searchTestDataSetupTask } from './tasks/searchTestDataSetup'; +import { templateTask } from './tasks/template'; +import { toolkitBuildTask } from './tasks/toolkit.build'; +import { execTask } from './utils/execTask'; export const run = (includeInternalScripts = false) => { if (includeInternalScripts) { diff --git a/packages/grafana-toolkit/src/cli/tasks/changelog.ts b/packages/grafana-toolkit/src/cli/tasks/changelog.ts index 7e797d15ec9..9815045be4b 100644 --- a/packages/grafana-toolkit/src/cli/tasks/changelog.ts +++ b/packages/grafana-toolkit/src/cli/tasks/changelog.ts @@ -1,9 +1,11 @@ -import { difference, sortBy } from 'lodash'; -import { Task } from './task'; -import GithubClient from '../utils/githubClient'; import chalk from 'chalk'; +import { difference, sortBy } from 'lodash'; + +import GithubClient from '../utils/githubClient'; import { useSpinner } from '../utils/useSpinner'; +import { Task } from './task'; + interface ChangelogOptions { milestone: string; } diff --git a/packages/grafana-toolkit/src/cli/tasks/cherrypick.ts b/packages/grafana-toolkit/src/cli/tasks/cherrypick.ts index 1a446a13381..3aa66dd33f2 100644 --- a/packages/grafana-toolkit/src/cli/tasks/cherrypick.ts +++ b/packages/grafana-toolkit/src/cli/tasks/cherrypick.ts @@ -1,6 +1,7 @@ -import { Task, TaskRunner } from './task'; import GithubClient from '../utils/githubClient'; +import { Task, TaskRunner } from './task'; + interface CherryPickOptions { enterprise: boolean; } diff --git a/packages/grafana-toolkit/src/cli/tasks/closeMilestone.ts b/packages/grafana-toolkit/src/cli/tasks/closeMilestone.ts index 0ac396a36fe..39a67830510 100644 --- a/packages/grafana-toolkit/src/cli/tasks/closeMilestone.ts +++ b/packages/grafana-toolkit/src/cli/tasks/closeMilestone.ts @@ -1,6 +1,7 @@ -import { Task, TaskRunner } from './task'; import GithubClient from '../utils/githubClient'; +import { Task, TaskRunner } from './task'; + interface CloseMilestoneOptions { milestone: string; dryRun: boolean; diff --git a/packages/grafana-toolkit/src/cli/tasks/component.create.ts b/packages/grafana-toolkit/src/cli/tasks/component.create.ts index 8227c450c36..311c4223a82 100644 --- a/packages/grafana-toolkit/src/cli/tasks/component.create.ts +++ b/packages/grafana-toolkit/src/cli/tasks/component.create.ts @@ -1,10 +1,12 @@ -import { Task, TaskRunner } from './task'; import fs from 'fs'; -import { template as _template } from 'lodash'; import { prompt } from 'inquirer'; +import { template as _template } from 'lodash'; + +import { componentTpl, docsTpl, storyTpl, testTpl } from '../templates'; import { pascalCase } from '../utils/pascalCase'; import { promptConfirm, promptInput, promptList } from '../utils/prompt'; -import { componentTpl, docsTpl, storyTpl, testTpl } from '../templates'; + +import { Task, TaskRunner } from './task'; interface Details { name?: string; diff --git a/packages/grafana-toolkit/src/cli/tasks/core.start.ts b/packages/grafana-toolkit/src/cli/tasks/core.start.ts index d3d94dbc9f4..0d7e372f05f 100644 --- a/packages/grafana-toolkit/src/cli/tasks/core.start.ts +++ b/packages/grafana-toolkit/src/cli/tasks/core.start.ts @@ -1,5 +1,6 @@ //@ts-ignore import concurrently from 'concurrently'; + import { Task, TaskRunner } from './task'; interface StartTaskOptions { diff --git a/packages/grafana-toolkit/src/cli/tasks/nodeVersionChecker.ts b/packages/grafana-toolkit/src/cli/tasks/nodeVersionChecker.ts index 3e9942b08b5..d7bcbe0ff8e 100644 --- a/packages/grafana-toolkit/src/cli/tasks/nodeVersionChecker.ts +++ b/packages/grafana-toolkit/src/cli/tasks/nodeVersionChecker.ts @@ -1,7 +1,8 @@ -import { Task, TaskRunner } from './task'; import chalk from 'chalk'; -import { coerce, satisfies } from 'semver'; import { readFileSync } from 'fs'; +import { coerce, satisfies } from 'semver'; + +import { Task, TaskRunner } from './task'; interface FailedVersionCheck { file: string; diff --git a/packages/grafana-toolkit/src/cli/tasks/package.build.ts b/packages/grafana-toolkit/src/cli/tasks/package.build.ts index 5e00ffb2f47..844cc76e798 100644 --- a/packages/grafana-toolkit/src/cli/tasks/package.build.ts +++ b/packages/grafana-toolkit/src/cli/tasks/package.build.ts @@ -1,11 +1,13 @@ +import chalk from 'chalk'; import execa = require('execa'); import { promises as fs } from 'fs'; -import * as path from 'path'; -import chalk from 'chalk'; -import { useSpinner } from '../utils/useSpinner'; -import { Task, TaskRunner } from './task'; -import { cloneDeep } from 'lodash'; import globby from 'globby'; +import { cloneDeep } from 'lodash'; +import * as path from 'path'; + +import { useSpinner } from '../utils/useSpinner'; + +import { Task, TaskRunner } from './task'; const clean = (cwd: string) => useSpinner('Cleaning', () => execa('npm', ['run', 'clean'], { cwd })); diff --git a/packages/grafana-toolkit/src/cli/tasks/plugin.build.ts b/packages/grafana-toolkit/src/cli/tasks/plugin.build.ts index 02b6d668477..6fc22e1de95 100644 --- a/packages/grafana-toolkit/src/cli/tasks/plugin.build.ts +++ b/packages/grafana-toolkit/src/cli/tasks/plugin.build.ts @@ -1,14 +1,16 @@ -import { useSpinner } from '../utils/useSpinner'; -import { testPlugin } from './plugin/tests'; -import { Task, TaskRunner } from './task'; -import rimrafCallback from 'rimraf'; -import { resolve as resolvePath } from 'path'; -import { promisify } from 'util'; -import globby from 'globby'; +import { CLIEngine } from 'eslint'; import execa from 'execa'; import { constants as fsConstants, promises as fs } from 'fs'; -import { CLIEngine } from 'eslint'; +import globby from 'globby'; +import { resolve as resolvePath } from 'path'; +import rimrafCallback from 'rimraf'; +import { promisify } from 'util'; + +import { useSpinner } from '../utils/useSpinner'; + import { bundlePlugin as bundleFn, PluginBundleOptions } from './plugin/bundle'; +import { testPlugin } from './plugin/tests'; +import { Task, TaskRunner } from './task'; const { access, copyFile } = fs; const { COPYFILE_EXCL } = fsConstants; diff --git a/packages/grafana-toolkit/src/cli/tasks/plugin.ci.ts b/packages/grafana-toolkit/src/cli/tasks/plugin.ci.ts index eb880cd5c96..40d8eb0072f 100644 --- a/packages/grafana-toolkit/src/cli/tasks/plugin.ci.ts +++ b/packages/grafana-toolkit/src/cli/tasks/plugin.ci.ts @@ -1,12 +1,11 @@ -import { Task, TaskRunner } from './task'; -import { pluginBuildRunner } from './plugin.build'; -import { getPluginJson } from '../../config/utils/pluginValidation'; -import { getPluginId } from '../../config/utils/getPluginId'; import execa = require('execa'); -import path = require('path'); import fs from 'fs-extra'; -import { getPackageDetails, getGrafanaVersions, readGitLog } from '../../plugins/utils'; -import { buildManifest, signManifest, saveManifest } from '../../plugins/manifest'; +import path = require('path'); +import rimrafCallback from 'rimraf'; +import { promisify } from 'util'; + +import { getPluginId } from '../../config/utils/getPluginId'; +import { getPluginJson } from '../../config/utils/pluginValidation'; import { getJobFolder, writeJobStats, @@ -15,10 +14,13 @@ import { getPullRequestNumber, getCircleDownloadBaseURL, } from '../../plugins/env'; -import { agregateWorkflowInfo, agregateCoverageInfo, agregateTestInfo } from '../../plugins/workflow'; +import { buildManifest, signManifest, saveManifest } from '../../plugins/manifest'; import { PluginPackageDetails, PluginBuildReport } from '../../plugins/types'; -import rimrafCallback from 'rimraf'; -import { promisify } from 'util'; +import { getPackageDetails, getGrafanaVersions, readGitLog } from '../../plugins/utils'; +import { agregateWorkflowInfo, agregateCoverageInfo, agregateTestInfo } from '../../plugins/workflow'; + +import { pluginBuildRunner } from './plugin.build'; +import { Task, TaskRunner } from './task'; const rimraf = promisify(rimrafCallback); export interface PluginCIOptions { diff --git a/packages/grafana-toolkit/src/cli/tasks/plugin.create.ts b/packages/grafana-toolkit/src/cli/tasks/plugin.create.ts index 2b9a400df71..b276b869716 100644 --- a/packages/grafana-toolkit/src/cli/tasks/plugin.create.ts +++ b/packages/grafana-toolkit/src/cli/tasks/plugin.create.ts @@ -1,6 +1,8 @@ import { prompt } from 'inquirer'; import path from 'path'; + import { promptConfirm } from '../utils/prompt'; + import { fetchTemplate, formatPluginDetails, diff --git a/packages/grafana-toolkit/src/cli/tasks/plugin.dev.ts b/packages/grafana-toolkit/src/cli/tasks/plugin.dev.ts index 7585bdf5956..1b9a15b4136 100644 --- a/packages/grafana-toolkit/src/cli/tasks/plugin.dev.ts +++ b/packages/grafana-toolkit/src/cli/tasks/plugin.dev.ts @@ -1,10 +1,12 @@ -import { Task, TaskRunner } from './task'; -import { bundlePlugin as bundleFn, PluginBundleOptions } from './plugin/bundle'; -import { useSpinner } from '../utils/useSpinner'; -import { lintPlugin } from './plugin.build'; import execa = require('execa'); import path = require('path'); +import { useSpinner } from '../utils/useSpinner'; + +import { lintPlugin } from './plugin.build'; +import { bundlePlugin as bundleFn, PluginBundleOptions } from './plugin/bundle'; +import { Task, TaskRunner } from './task'; + const bundlePlugin = (options: PluginBundleOptions) => useSpinner('Bundling plugin in dev mode', () => bundleFn(options)); diff --git a/packages/grafana-toolkit/src/cli/tasks/plugin.sign.ts b/packages/grafana-toolkit/src/cli/tasks/plugin.sign.ts index c8c566a88b6..7424bdeb1fb 100644 --- a/packages/grafana-toolkit/src/cli/tasks/plugin.sign.ts +++ b/packages/grafana-toolkit/src/cli/tasks/plugin.sign.ts @@ -1,7 +1,9 @@ import path from 'path'; + import { buildManifest, signManifest, saveManifest } from '../../plugins/manifest'; -import { Task, TaskRunner } from './task'; + import { getToolkitVersion } from './plugin.utils'; +import { Task, TaskRunner } from './task'; interface PluginSignOptions { signatureType?: string; rootUrls?: string[]; diff --git a/packages/grafana-toolkit/src/cli/tasks/plugin.tests.ts b/packages/grafana-toolkit/src/cli/tasks/plugin.tests.ts index f85c3f18828..ff75d91d1d6 100644 --- a/packages/grafana-toolkit/src/cli/tasks/plugin.tests.ts +++ b/packages/grafana-toolkit/src/cli/tasks/plugin.tests.ts @@ -1,5 +1,5 @@ -import { Task, TaskRunner } from './task'; import { testPlugin, PluginTestOptions } from './plugin/tests'; +import { Task, TaskRunner } from './task'; const pluginTestRunner: TaskRunner = async (options) => { await testPlugin(options); diff --git a/packages/grafana-toolkit/src/cli/tasks/plugin.update.ts b/packages/grafana-toolkit/src/cli/tasks/plugin.update.ts index 026d9d05dcf..fee3286b395 100644 --- a/packages/grafana-toolkit/src/cli/tasks/plugin.update.ts +++ b/packages/grafana-toolkit/src/cli/tasks/plugin.update.ts @@ -1,8 +1,10 @@ -import { Task, TaskRunner } from './task'; -import { useSpinner } from '../utils/useSpinner'; import fs = require('fs'); import path = require('path'); +import { useSpinner } from '../utils/useSpinner'; + +import { Task, TaskRunner } from './task'; + interface UpdatePluginTask {} const updateCiConfig = () => diff --git a/packages/grafana-toolkit/src/cli/tasks/plugin.utils.ts b/packages/grafana-toolkit/src/cli/tasks/plugin.utils.ts index ee32cf54177..7852bd1d8b6 100755 --- a/packages/grafana-toolkit/src/cli/tasks/plugin.utils.ts +++ b/packages/grafana-toolkit/src/cli/tasks/plugin.utils.ts @@ -1,13 +1,14 @@ -import { Task, TaskRunner } from './task'; -import { getPluginJson } from '../../config/utils/pluginValidation'; -import { GitHubRelease } from '../utils/githubRelease'; -import { getPluginId } from '../../config/utils/getPluginId'; -import { getCiFolder } from '../../plugins/env'; -import { useSpinner } from '../utils/useSpinner'; -import { readFileSync } from 'fs'; - -import path = require('path'); import execa = require('execa'); +import { readFileSync } from 'fs'; +import path = require('path'); + +import { getPluginId } from '../../config/utils/getPluginId'; +import { getPluginJson } from '../../config/utils/pluginValidation'; +import { getCiFolder } from '../../plugins/env'; +import { GitHubRelease } from '../utils/githubRelease'; +import { useSpinner } from '../utils/useSpinner'; + +import { Task, TaskRunner } from './task'; interface Command extends Array {} const DEFAULT_EMAIL_ADDRESS = 'eng@grafana.com'; diff --git a/packages/grafana-toolkit/src/cli/tasks/plugin/bundle.managed.ts b/packages/grafana-toolkit/src/cli/tasks/plugin/bundle.managed.ts index 052c067a759..7ffd6c32d6d 100644 --- a/packages/grafana-toolkit/src/cli/tasks/plugin/bundle.managed.ts +++ b/packages/grafana-toolkit/src/cli/tasks/plugin/bundle.managed.ts @@ -1,6 +1,7 @@ -import { promises as fs } from 'fs'; -import { Task, TaskRunner } from '../task'; import execa = require('execa'); +import { promises as fs } from 'fs'; + +import { Task, TaskRunner } from '../task'; interface BundeManagedOptions {} diff --git a/packages/grafana-toolkit/src/cli/tasks/plugin/bundle.ts b/packages/grafana-toolkit/src/cli/tasks/plugin/bundle.ts index 003dcf82786..345392ad632 100644 --- a/packages/grafana-toolkit/src/cli/tasks/plugin/bundle.ts +++ b/packages/grafana-toolkit/src/cli/tasks/plugin/bundle.ts @@ -1,6 +1,7 @@ -import webpack = require('webpack'); -import formatWebpackMessages = require('react-dev-utils/formatWebpackMessages'); import clearConsole = require('react-dev-utils/clearConsole'); +import formatWebpackMessages = require('react-dev-utils/formatWebpackMessages'); +import webpack = require('webpack'); + import { loadWebpackConfig } from '../../../config/webpack.plugin.config'; export interface PluginBundleOptions { diff --git a/packages/grafana-toolkit/src/cli/tasks/plugin/create.ts b/packages/grafana-toolkit/src/cli/tasks/plugin/create.ts index f4f9143944c..5073acadfe9 100644 --- a/packages/grafana-toolkit/src/cli/tasks/plugin/create.ts +++ b/packages/grafana-toolkit/src/cli/tasks/plugin/create.ts @@ -5,6 +5,7 @@ import { prompt } from 'inquirer'; import { kebabCase } from 'lodash'; import path from 'path'; import gitPromise from 'simple-git'; + import { promptConfirm, promptInput } from '../../utils/prompt'; import { rmdir } from '../../utils/rmdir'; import { useSpinner } from '../../utils/useSpinner'; diff --git a/packages/grafana-toolkit/src/cli/tasks/plugin/tests.ts b/packages/grafana-toolkit/src/cli/tasks/plugin/tests.ts index dd47ba0938c..7b8970bf769 100644 --- a/packages/grafana-toolkit/src/cli/tasks/plugin/tests.ts +++ b/packages/grafana-toolkit/src/cli/tasks/plugin/tests.ts @@ -1,6 +1,7 @@ import { runCLI } from '@jest/core'; -import { useSpinner } from '../../utils/useSpinner'; + import { loadJestPluginConfig } from '../../../config/jest.plugin.config'; +import { useSpinner } from '../../utils/useSpinner'; export interface PluginTestOptions { updateSnapshot: boolean; diff --git a/packages/grafana-toolkit/src/cli/tasks/searchTestDataSetup.ts b/packages/grafana-toolkit/src/cli/tasks/searchTestDataSetup.ts index 84c0ac0cc82..6f8fc346e6d 100644 --- a/packages/grafana-toolkit/src/cli/tasks/searchTestDataSetup.ts +++ b/packages/grafana-toolkit/src/cli/tasks/searchTestDataSetup.ts @@ -1,4 +1,5 @@ import axios from 'axios'; + import { Task, TaskRunner } from './task'; interface SearchTestDataSetupOptions { diff --git a/packages/grafana-toolkit/src/cli/tasks/toolkit.build.ts b/packages/grafana-toolkit/src/cli/tasks/toolkit.build.ts index 47ccccd0e2f..ae1308d9a17 100644 --- a/packages/grafana-toolkit/src/cli/tasks/toolkit.build.ts +++ b/packages/grafana-toolkit/src/cli/tasks/toolkit.build.ts @@ -1,7 +1,9 @@ +import chalk from 'chalk'; import execa = require('execa'); import * as fs from 'fs'; -import chalk from 'chalk'; + import { useSpinner } from '../utils/useSpinner'; + import { Task, TaskRunner } from './task'; const path = require('path'); diff --git a/packages/grafana-toolkit/src/cli/utils/execTask.ts b/packages/grafana-toolkit/src/cli/utils/execTask.ts index a4fe883169f..906fcc6ed07 100644 --- a/packages/grafana-toolkit/src/cli/utils/execTask.ts +++ b/packages/grafana-toolkit/src/cli/utils/execTask.ts @@ -1,7 +1,8 @@ /* eslint-disable no-console */ -import { Task } from '../tasks/task'; import chalk from 'chalk'; +import { Task } from '../tasks/task'; + interface TaskBasicOptions { // Don't print task details when running silent?: boolean; diff --git a/packages/grafana-toolkit/src/cli/utils/githubRelease.ts b/packages/grafana-toolkit/src/cli/utils/githubRelease.ts index 2dbd1b6126e..1d59e2d4516 100644 --- a/packages/grafana-toolkit/src/cli/utils/githubRelease.ts +++ b/packages/grafana-toolkit/src/cli/utils/githubRelease.ts @@ -1,10 +1,12 @@ +import { AxiosResponse } from 'axios'; +import fs = require('fs'); +import path = require('path'); + import { getPluginId } from '../../config/utils/getPluginId'; import { getPluginJson } from '../../config/utils/pluginValidation'; import { getCiFolder } from '../../plugins/env'; -import path = require('path'); -import fs = require('fs'); + import GithubClient from './githubClient'; -import { AxiosResponse } from 'axios'; const resolveContentType = (extension: string): string => { if (extension.startsWith('.')) { diff --git a/packages/grafana-toolkit/src/config/jest.plugin.config.ts b/packages/grafana-toolkit/src/config/jest.plugin.config.ts index c0539c4d0b5..647dc976526 100644 --- a/packages/grafana-toolkit/src/config/jest.plugin.config.ts +++ b/packages/grafana-toolkit/src/config/jest.plugin.config.ts @@ -1,5 +1,5 @@ -import path = require('path'); import fs from 'fs'; +import path = require('path'); export const allowedJestConfigOverrides = [ 'snapshotSerializers', diff --git a/packages/grafana-toolkit/src/config/webpack.plugin.config.test.ts b/packages/grafana-toolkit/src/config/webpack.plugin.config.test.ts index 7d893834c56..ea20c19979f 100644 --- a/packages/grafana-toolkit/src/config/webpack.plugin.config.test.ts +++ b/packages/grafana-toolkit/src/config/webpack.plugin.config.test.ts @@ -1,5 +1,6 @@ -import { findModuleFiles, loadWebpackConfig } from './webpack.plugin.config'; import fs from 'fs'; + +import { findModuleFiles, loadWebpackConfig } from './webpack.plugin.config'; // eslint-disable-next-line no-duplicate-imports import * as webpackConfig from './webpack.plugin.config'; diff --git a/packages/grafana-toolkit/src/config/webpack.plugin.config.ts b/packages/grafana-toolkit/src/config/webpack.plugin.config.ts index 60ccf8f3c81..09f57379e9b 100644 --- a/packages/grafana-toolkit/src/config/webpack.plugin.config.ts +++ b/packages/grafana-toolkit/src/config/webpack.plugin.config.ts @@ -1,20 +1,21 @@ -const fs = require('fs'); -const util = require('util'); -const path = require('path'); +import * as webpack from 'webpack'; + +import { getStyleLoaders, getStylesheetEntries, getFileLoaders } from './webpack/loaders'; + const CopyWebpackPlugin = require('copy-webpack-plugin'); -const ReplaceInFileWebpackPlugin = require('replace-in-file-webpack-plugin'); -const TerserPlugin = require('terser-webpack-plugin'); +const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); +const fs = require('fs'); +const HtmlWebpackPlugin = require('html-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin'); -const HtmlWebpackPlugin = require('html-webpack-plugin'); -const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); +const path = require('path'); +const ReplaceInFileWebpackPlugin = require('replace-in-file-webpack-plugin'); +const TerserPlugin = require('terser-webpack-plugin'); +const util = require('util'); const readdirPromise = util.promisify(fs.readdir); const accessPromise = util.promisify(fs.access); -import * as webpack from 'webpack'; -import { getStyleLoaders, getStylesheetEntries, getFileLoaders } from './webpack/loaders'; - export interface WebpackConfigurationOptions { watch?: boolean; production?: boolean; diff --git a/packages/grafana-toolkit/src/config/webpack/loaders.ts b/packages/grafana-toolkit/src/config/webpack/loaders.ts index b247726ee75..fc4a386df45 100644 --- a/packages/grafana-toolkit/src/config/webpack/loaders.ts +++ b/packages/grafana-toolkit/src/config/webpack/loaders.ts @@ -1,5 +1,6 @@ import fs from 'fs'; import path from 'path'; + import { getPluginId } from '../utils/getPluginId'; const MiniCssExtractPlugin = require('mini-css-extract-plugin'); diff --git a/packages/grafana-toolkit/src/plugins/env.ts b/packages/grafana-toolkit/src/plugins/env.ts index 06b659c1c3f..f79b68d449d 100644 --- a/packages/grafana-toolkit/src/plugins/env.ts +++ b/packages/grafana-toolkit/src/plugins/env.ts @@ -1,7 +1,9 @@ import execa from 'execa'; -import path from 'path'; import fs from 'fs'; +import path from 'path'; + import { PluginBuildInfo } from '@grafana/data'; + import { JobInfo } from './types'; const getJobFromProcessArgv = () => { diff --git a/packages/grafana-toolkit/src/plugins/manifest.ts b/packages/grafana-toolkit/src/plugins/manifest.ts index 1b209c6f3d9..17c1f052170 100644 --- a/packages/grafana-toolkit/src/plugins/manifest.ts +++ b/packages/grafana-toolkit/src/plugins/manifest.ts @@ -1,6 +1,7 @@ -import path from 'path'; -import fs from 'fs'; import crypto from 'crypto'; +import fs from 'fs'; +import path from 'path'; + import { ManifestInfo } from './types'; const MANIFEST_FILE = 'MANIFEST.txt'; diff --git a/packages/grafana-toolkit/src/plugins/utils.ts b/packages/grafana-toolkit/src/plugins/utils.ts index 739c837b1e8..e968fc31fd0 100644 --- a/packages/grafana-toolkit/src/plugins/utils.ts +++ b/packages/grafana-toolkit/src/plugins/utils.ts @@ -1,7 +1,9 @@ import execa from 'execa'; -import path from 'path'; import fs from 'fs'; +import path from 'path'; + import { KeyValue } from '@grafana/data'; + import { ExtensionSize, ZipFileInfo, GitLogInfo } from './types'; const md5File = require('md5-file'); diff --git a/packages/grafana-toolkit/src/plugins/workflow.ts b/packages/grafana-toolkit/src/plugins/workflow.ts index 770afe48a18..ea653836841 100644 --- a/packages/grafana-toolkit/src/plugins/workflow.ts +++ b/packages/grafana-toolkit/src/plugins/workflow.ts @@ -1,7 +1,8 @@ -import path from 'path'; import fs from 'fs'; -import { JobInfo, WorkflowInfo, CoverageInfo, TestResultsInfo } from './types'; +import path from 'path'; + import { getBuildNumber, getCiFolder } from './env'; +import { JobInfo, WorkflowInfo, CoverageInfo, TestResultsInfo } from './types'; export const agregateWorkflowInfo = (): WorkflowInfo => { const now = Date.now(); diff --git a/packages/grafana-ui/rollup.config.ts b/packages/grafana-ui/rollup.config.ts index 71f712df14f..a19e76cb0eb 100644 --- a/packages/grafana-ui/rollup.config.ts +++ b/packages/grafana-ui/rollup.config.ts @@ -1,5 +1,5 @@ -import resolve from '@rollup/plugin-node-resolve'; import commonjs from '@rollup/plugin-commonjs'; +import resolve from '@rollup/plugin-node-resolve'; import svg from 'rollup-plugin-svg-import'; import { terser } from 'rollup-plugin-terser'; diff --git a/packages/grafana-ui/src/components/Alert/Alert.story.tsx b/packages/grafana-ui/src/components/Alert/Alert.story.tsx index cb159b1862e..ac1cd03c2b6 100644 --- a/packages/grafana-ui/src/components/Alert/Alert.story.tsx +++ b/packages/grafana-ui/src/components/Alert/Alert.story.tsx @@ -1,11 +1,14 @@ -import React from 'react'; -import { Story } from '@storybook/react'; import { action } from '@storybook/addon-actions'; +import { Story } from '@storybook/react'; +import React from 'react'; + import { Alert, AlertVariant, VerticalGroup } from '@grafana/ui'; -import { Props } from './Alert'; + +import { StoryExample } from '../../utils/storybook/StoryExample'; import { withCenteredStory, withHorizontallyCenteredStory } from '../../utils/storybook/withCenteredStory'; import mdx from '../Alert/Alert.mdx'; -import { StoryExample } from '../../utils/storybook/StoryExample'; + +import { Props } from './Alert'; const severities: AlertVariant[] = ['error', 'warning', 'info', 'success']; diff --git a/packages/grafana-ui/src/components/Alert/Alert.tsx b/packages/grafana-ui/src/components/Alert/Alert.tsx index ddf70797e43..5acb3049b10 100644 --- a/packages/grafana-ui/src/components/Alert/Alert.tsx +++ b/packages/grafana-ui/src/components/Alert/Alert.tsx @@ -1,12 +1,14 @@ -import React, { HTMLAttributes, ReactNode } from 'react'; import { css, cx } from '@emotion/css'; +import React, { HTMLAttributes, ReactNode } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; + import { useTheme2 } from '../../themes'; -import { Icon } from '../Icon/Icon'; import { IconName } from '../../types/icon'; -import { IconButton } from '../IconButton/IconButton'; import { Button } from '../Button/Button'; +import { Icon } from '../Icon/Icon'; +import { IconButton } from '../IconButton/IconButton'; export type AlertVariant = 'success' | 'warning' | 'error' | 'info'; diff --git a/packages/grafana-ui/src/components/Badge/Badge.story.tsx b/packages/grafana-ui/src/components/Badge/Badge.story.tsx index 32aa3a63969..7bf2c11bbcb 100644 --- a/packages/grafana-ui/src/components/Badge/Badge.story.tsx +++ b/packages/grafana-ui/src/components/Badge/Badge.story.tsx @@ -1,8 +1,11 @@ -import React from 'react'; import { Story } from '@storybook/react'; +import React from 'react'; + import { Badge, BadgeProps } from '@grafana/ui'; + import { iconOptions } from '../../utils/storybook/knobs'; import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; + import mdx from './Badge.mdx'; export default { diff --git a/packages/grafana-ui/src/components/Badge/Badge.tsx b/packages/grafana-ui/src/components/Badge/Badge.tsx index 053f063e51d..aa81bdfed1b 100644 --- a/packages/grafana-ui/src/components/Badge/Badge.tsx +++ b/packages/grafana-ui/src/components/Badge/Badge.tsx @@ -1,13 +1,15 @@ +import { css, cx } from '@emotion/css'; import React, { HTMLAttributes } from 'react'; -import { Icon } from '../Icon/Icon'; +import tinycolor from 'tinycolor2'; + +import { getColorForTheme, GrafanaTheme } from '@grafana/data'; + import { useTheme } from '../../themes/ThemeContext'; import { stylesFactory } from '../../themes/stylesFactory'; import { IconName } from '../../types'; -import { Tooltip } from '../Tooltip/Tooltip'; -import { getColorForTheme, GrafanaTheme } from '@grafana/data'; -import tinycolor from 'tinycolor2'; -import { css, cx } from '@emotion/css'; +import { Icon } from '../Icon/Icon'; import { HorizontalGroup } from '../Layout/Layout'; +import { Tooltip } from '../Tooltip/Tooltip'; export type BadgeColor = 'blue' | 'red' | 'green' | 'orange' | 'purple'; diff --git a/packages/grafana-ui/src/components/BarGauge/BarGauge.story.tsx b/packages/grafana-ui/src/components/BarGauge/BarGauge.story.tsx index 232ff7d67f7..6857739711b 100644 --- a/packages/grafana-ui/src/components/BarGauge/BarGauge.story.tsx +++ b/packages/grafana-ui/src/components/BarGauge/BarGauge.story.tsx @@ -1,11 +1,14 @@ -import React from 'react'; import { Story, Meta } from '@storybook/react'; -import { BarGauge, BarGaugeDisplayMode } from '@grafana/ui'; +import React from 'react'; + import { VizOrientation, ThresholdsMode, Field, FieldType, getDisplayProcessor } from '@grafana/data'; -import { Props } from './BarGauge'; -import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; -import mdx from './BarGauge.mdx'; +import { BarGauge, BarGaugeDisplayMode } from '@grafana/ui'; + import { useTheme2 } from '../../themes'; +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; + +import { Props } from './BarGauge'; +import mdx from './BarGauge.mdx'; export default { title: 'Visualizations/BarGauge', diff --git a/packages/grafana-ui/src/components/BarGauge/BarGauge.test.tsx b/packages/grafana-ui/src/components/BarGauge/BarGauge.test.tsx index e92a4af9dc3..ecafd8ffeae 100644 --- a/packages/grafana-ui/src/components/BarGauge/BarGauge.test.tsx +++ b/packages/grafana-ui/src/components/BarGauge/BarGauge.test.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { shallow } from 'enzyme'; +import React from 'react'; + import { DisplayValue, VizOrientation, @@ -10,6 +11,7 @@ import { getDisplayProcessor, createTheme, } from '@grafana/data'; + import { BarGauge, Props, diff --git a/packages/grafana-ui/src/components/BarGauge/BarGauge.tsx b/packages/grafana-ui/src/components/BarGauge/BarGauge.tsx index b83267f1e05..6155bacad5a 100644 --- a/packages/grafana-ui/src/components/BarGauge/BarGauge.tsx +++ b/packages/grafana-ui/src/components/BarGauge/BarGauge.tsx @@ -1,6 +1,7 @@ // Library import React, { CSSProperties, PureComponent, ReactNode } from 'react'; import tinycolor from 'tinycolor2'; + import { DisplayProcessor, DisplayValue, @@ -19,9 +20,10 @@ import { VizOrientation, } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; -import { FormattedValueDisplay } from '../FormattedValueDisplay/FormattedValueDisplay'; -import { calculateFontSize, measureText } from '../../utils/measureText'; + import { Themeable2 } from '../../types'; +import { calculateFontSize, measureText } from '../../utils/measureText'; +import { FormattedValueDisplay } from '../FormattedValueDisplay/FormattedValueDisplay'; const MIN_VALUE_HEIGHT = 18; const MAX_VALUE_HEIGHT = 50; diff --git a/packages/grafana-ui/src/components/BigValue/BigValue.story.tsx b/packages/grafana-ui/src/components/BigValue/BigValue.story.tsx index 7b1ee1b665b..4376f990360 100644 --- a/packages/grafana-ui/src/components/BigValue/BigValue.story.tsx +++ b/packages/grafana-ui/src/components/BigValue/BigValue.story.tsx @@ -1,5 +1,11 @@ -import React from 'react'; import { Story, Meta } from '@storybook/react'; +import React from 'react'; + +import { ArrayVector, FieldSparkline, FieldType } from '@grafana/data'; + +import { useTheme2 } from '../../themes'; +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; + import { BigValue, BigValueColorMode, @@ -8,10 +14,7 @@ import { BigValueTextMode, Props, } from './BigValue'; -import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; import mdx from './BigValue.mdx'; -import { useTheme2 } from '../../themes'; -import { ArrayVector, FieldSparkline, FieldType } from '@grafana/data'; export default { title: 'Visualizations/BigValue', diff --git a/packages/grafana-ui/src/components/BigValue/BigValue.test.tsx b/packages/grafana-ui/src/components/BigValue/BigValue.test.tsx index 16efc2b43c3..645d40a1e48 100644 --- a/packages/grafana-ui/src/components/BigValue/BigValue.test.tsx +++ b/packages/grafana-ui/src/components/BigValue/BigValue.test.tsx @@ -1,8 +1,10 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; -import { BigValue, BigValueColorMode, BigValueGraphMode, Props } from './BigValue'; +import React from 'react'; + import { createTheme } from '@grafana/data'; +import { BigValue, BigValueColorMode, BigValueGraphMode, Props } from './BigValue'; + function getProps(propOverrides?: Partial): Props { const props: Props = { colorMode: BigValueColorMode.Background, diff --git a/packages/grafana-ui/src/components/BigValue/BigValue.tsx b/packages/grafana-ui/src/components/BigValue/BigValue.tsx index 864c2547199..789bd7fd93a 100644 --- a/packages/grafana-ui/src/components/BigValue/BigValue.tsx +++ b/packages/grafana-ui/src/components/BigValue/BigValue.tsx @@ -1,10 +1,12 @@ import React, { PureComponent } from 'react'; + import { DisplayValue, DisplayValueAlignmentFactors, FieldSparkline, TextDisplayOptions } from '@grafana/data'; import { Themeable2 } from '../../types'; -import { buildLayout } from './BigValueLayout'; import { FormattedValueDisplay } from '../FormattedValueDisplay/FormattedValueDisplay'; +import { buildLayout } from './BigValueLayout'; + export enum BigValueColorMode { Value = 'value', Background = 'background', diff --git a/packages/grafana-ui/src/components/BigValue/BigValueLayout.test.tsx b/packages/grafana-ui/src/components/BigValue/BigValueLayout.test.tsx index 7b7d2b6791c..373b93e0b94 100644 --- a/packages/grafana-ui/src/components/BigValue/BigValueLayout.test.tsx +++ b/packages/grafana-ui/src/components/BigValue/BigValueLayout.test.tsx @@ -1,6 +1,7 @@ +import { ArrayVector, createTheme, FieldType } from '@grafana/data'; + import { Props, BigValueColorMode, BigValueGraphMode, BigValueTextMode } from './BigValue'; import { buildLayout, StackedWithChartLayout, StackedWithNoChartLayout, WideWithChartLayout } from './BigValueLayout'; -import { ArrayVector, createTheme, FieldType } from '@grafana/data'; function getProps(propOverrides?: Partial): Props { const props: Props = { diff --git a/packages/grafana-ui/src/components/BigValue/BigValueLayout.tsx b/packages/grafana-ui/src/components/BigValue/BigValueLayout.tsx index 7f3bde9344f..d7c04e01fdd 100644 --- a/packages/grafana-ui/src/components/BigValue/BigValueLayout.tsx +++ b/packages/grafana-ui/src/components/BigValue/BigValueLayout.tsx @@ -1,17 +1,15 @@ -// Libraries import React, { CSSProperties } from 'react'; import tinycolor from 'tinycolor2'; -// Utils import { formattedValueToString, DisplayValue, FieldConfig, FieldType } from '@grafana/data'; -import { calculateFontSize } from '../../utils/measureText'; - -// Types -import { BigValueColorMode, Props, BigValueJustifyMode, BigValueTextMode } from './BigValue'; -import { getTextColorForBackground } from '../../utils'; import { GraphDrawStyle, GraphFieldConfig } from '@grafana/schema'; + +import { getTextColorForBackground } from '../../utils'; +import { calculateFontSize } from '../../utils/measureText'; import { Sparkline } from '../Sparkline/Sparkline'; +import { BigValueColorMode, Props, BigValueJustifyMode, BigValueTextMode } from './BigValue'; + const LINE_HEIGHT = 1.2; const MAX_TITLE_SIZE = 30; diff --git a/packages/grafana-ui/src/components/BrowserLabel/Label.tsx b/packages/grafana-ui/src/components/BrowserLabel/Label.tsx index 8132c891b5a..fb4c77592d5 100644 --- a/packages/grafana-ui/src/components/BrowserLabel/Label.tsx +++ b/packages/grafana-ui/src/components/BrowserLabel/Label.tsx @@ -1,11 +1,13 @@ -import React, { forwardRef, HTMLAttributes, useCallback } from 'react'; import { cx, css } from '@emotion/css'; -import { GrafanaTheme2 } from '@grafana/data'; -import { useTheme2 } from '../../themes'; +import React, { forwardRef, HTMLAttributes, useCallback } from 'react'; // @ts-ignore import Highlighter from 'react-highlight-words'; -import { PartialHighlighter } from '../Typeahead/PartialHighlighter'; + +import { GrafanaTheme2 } from '@grafana/data'; + +import { useTheme2 } from '../../themes'; import { HighlightPart } from '../../types'; +import { PartialHighlighter } from '../Typeahead/PartialHighlighter'; type OnLabelClick = (name: string, value: string | undefined, event: React.MouseEvent) => void; diff --git a/packages/grafana-ui/src/components/Button/Button.story.tsx b/packages/grafana-ui/src/components/Button/Button.story.tsx index 9d70bf1b304..66588655cbc 100644 --- a/packages/grafana-ui/src/components/Button/Button.story.tsx +++ b/packages/grafana-ui/src/components/Button/Button.story.tsx @@ -1,11 +1,13 @@ -import React from 'react'; import { Story, Meta } from '@storybook/react'; -import { allButtonVariants, allButtonFills, Button, ButtonProps } from './Button'; -import mdx from './Button.mdx'; -import { HorizontalGroup, VerticalGroup } from '../Layout/Layout'; -import { ButtonGroup } from './ButtonGroup'; +import React from 'react'; + import { ComponentSize } from '../../types/size'; import { Card } from '../Card/Card'; +import { HorizontalGroup, VerticalGroup } from '../Layout/Layout'; + +import { allButtonVariants, allButtonFills, Button, ButtonProps } from './Button'; +import mdx from './Button.mdx'; +import { ButtonGroup } from './ButtonGroup'; export default { title: 'Buttons/Button', diff --git a/packages/grafana-ui/src/components/Button/Button.tsx b/packages/grafana-ui/src/components/Button/Button.tsx index d1cf2db8dd4..bfe0ad73563 100644 --- a/packages/grafana-ui/src/components/Button/Button.tsx +++ b/packages/grafana-ui/src/components/Button/Button.tsx @@ -1,11 +1,13 @@ -import React, { AnchorHTMLAttributes, ButtonHTMLAttributes } from 'react'; import { css, CSSObject, cx } from '@emotion/css'; -import { useTheme2 } from '../../themes'; -import { IconName } from '../../types/icon'; -import { getPropertiesForButtonSize } from '../Forms/commonStyles'; +import React, { AnchorHTMLAttributes, ButtonHTMLAttributes } from 'react'; + import { colorManipulator, GrafanaTheme2, ThemeRichColor } from '@grafana/data'; -import { ComponentSize } from '../../types/size'; + +import { useTheme2 } from '../../themes'; import { getFocusStyles, getMouseFocusStyles } from '../../themes/mixins'; +import { IconName } from '../../types/icon'; +import { ComponentSize } from '../../types/size'; +import { getPropertiesForButtonSize } from '../Forms/commonStyles'; import { Icon } from '../Icon/Icon'; export type ButtonVariant = 'primary' | 'secondary' | 'destructive' | 'link'; diff --git a/packages/grafana-ui/src/components/Button/ButtonGroup.tsx b/packages/grafana-ui/src/components/Button/ButtonGroup.tsx index 456bb7ab811..3fe6187198b 100644 --- a/packages/grafana-ui/src/components/Button/ButtonGroup.tsx +++ b/packages/grafana-ui/src/components/Button/ButtonGroup.tsx @@ -1,8 +1,10 @@ -import React, { forwardRef, HTMLAttributes } from 'react'; import { css, cx } from '@emotion/css'; -import { useStyles2 } from '../../themes'; +import React, { forwardRef, HTMLAttributes } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; +import { useStyles2 } from '../../themes'; + export interface Props extends HTMLAttributes { className?: string; } diff --git a/packages/grafana-ui/src/components/Button/FullWidthButtonContainer.tsx b/packages/grafana-ui/src/components/Button/FullWidthButtonContainer.tsx index 601aec9ffa5..e49056997f1 100644 --- a/packages/grafana-ui/src/components/Button/FullWidthButtonContainer.tsx +++ b/packages/grafana-ui/src/components/Button/FullWidthButtonContainer.tsx @@ -1,5 +1,6 @@ -import React, { FC } from 'react'; import { css, cx } from '@emotion/css'; +import React, { FC } from 'react'; + import { stylesFactory } from '../../themes'; export interface Props { diff --git a/packages/grafana-ui/src/components/Button/ToolbarButton.story.tsx b/packages/grafana-ui/src/components/Button/ToolbarButton.story.tsx index d20f90cde72..f152001023c 100644 --- a/packages/grafana-ui/src/components/Button/ToolbarButton.story.tsx +++ b/packages/grafana-ui/src/components/Button/ToolbarButton.story.tsx @@ -1,9 +1,12 @@ import React from 'react'; + import { ToolbarButton, ButtonGroup, VerticalGroup, HorizontalGroup } from '@grafana/ui'; -import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; -import { ToolbarButtonRow } from './ToolbarButtonRow'; -import { ToolbarButtonVariant } from './ToolbarButton'; + import { DashboardStoryCanvas } from '../../utils/storybook/DashboardStoryCanvas'; +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; + +import { ToolbarButtonVariant } from './ToolbarButton'; +import { ToolbarButtonRow } from './ToolbarButtonRow'; export default { title: 'Buttons/ToolbarButton', diff --git a/packages/grafana-ui/src/components/Button/ToolbarButton.tsx b/packages/grafana-ui/src/components/Button/ToolbarButton.tsx index c262b2962eb..739c27e3fdf 100644 --- a/packages/grafana-ui/src/components/Button/ToolbarButton.tsx +++ b/packages/grafana-ui/src/components/Button/ToolbarButton.tsx @@ -1,14 +1,17 @@ -import React, { forwardRef, ButtonHTMLAttributes } from 'react'; import { cx, css } from '@emotion/css'; -import { GrafanaTheme2 } from '@grafana/data'; -import { styleMixins, useStyles2 } from '../../themes'; -import { IconName } from '../../types/icon'; -import { Tooltip } from '../Tooltip/Tooltip'; -import { Icon } from '../Icon/Icon'; -import { getPropertiesForVariant } from './Button'; import { isString } from 'lodash'; +import React, { forwardRef, ButtonHTMLAttributes } from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; + +import { styleMixins, useStyles2 } from '../../themes'; import { getFocusStyles, getMouseFocusStyles } from '../../themes/mixins'; +import { IconName } from '../../types/icon'; +import { Icon } from '../Icon/Icon'; +import { Tooltip } from '../Tooltip/Tooltip'; + +import { getPropertiesForVariant } from './Button'; export interface Props extends ButtonHTMLAttributes { /** Icon name */ diff --git a/packages/grafana-ui/src/components/Button/ToolbarButtonRow.tsx b/packages/grafana-ui/src/components/Button/ToolbarButtonRow.tsx index eda19387c44..cfc2493a68e 100644 --- a/packages/grafana-ui/src/components/Button/ToolbarButtonRow.tsx +++ b/packages/grafana-ui/src/components/Button/ToolbarButtonRow.tsx @@ -1,8 +1,10 @@ -import React, { forwardRef, HTMLAttributes } from 'react'; import { css, cx } from '@emotion/css'; -import { useStyles2 } from '../../themes'; +import React, { forwardRef, HTMLAttributes } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; +import { useStyles2 } from '../../themes'; + export interface Props extends HTMLAttributes { className?: string; } diff --git a/packages/grafana-ui/src/components/ButtonCascader/ButtonCascader.story.tsx b/packages/grafana-ui/src/components/ButtonCascader/ButtonCascader.story.tsx index 27b5e5cbfe7..c4970a83e33 100644 --- a/packages/grafana-ui/src/components/ButtonCascader/ButtonCascader.story.tsx +++ b/packages/grafana-ui/src/components/ButtonCascader/ButtonCascader.story.tsx @@ -1,7 +1,10 @@ -import React from 'react'; import { Story, Meta } from '@storybook/react'; -import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; +import React from 'react'; + import { ButtonCascader } from '@grafana/ui'; + +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; + import { ButtonCascaderProps } from './ButtonCascader'; export default { diff --git a/packages/grafana-ui/src/components/ButtonCascader/ButtonCascader.tsx b/packages/grafana-ui/src/components/ButtonCascader/ButtonCascader.tsx index a57f85d85ad..c0ad9212b9c 100644 --- a/packages/grafana-ui/src/components/ButtonCascader/ButtonCascader.tsx +++ b/packages/grafana-ui/src/components/ButtonCascader/ButtonCascader.tsx @@ -1,13 +1,14 @@ -import React from 'react'; -import { IconName } from '../../types/icon'; import { css } from '@emotion/css'; - import RCCascader from 'rc-cascader'; +import React from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; + +import { stylesFactory, useTheme2 } from '../../themes'; +import { IconName } from '../../types/icon'; +import { Button, ButtonProps } from '../Button'; import { CascaderOption } from '../Cascader/Cascader'; import { onChangeCascader, onLoadDataCascader } from '../Cascader/optionMappings'; -import { stylesFactory, useTheme2 } from '../../themes'; -import { GrafanaTheme2 } from '@grafana/data'; -import { Button, ButtonProps } from '../Button'; import { Icon } from '../Icon/Icon'; export interface ButtonCascaderProps { diff --git a/packages/grafana-ui/src/components/CallToActionCard/CallToActionCard.story.internal.tsx b/packages/grafana-ui/src/components/CallToActionCard/CallToActionCard.story.internal.tsx index 31ea9c22152..b048dfb9acf 100644 --- a/packages/grafana-ui/src/components/CallToActionCard/CallToActionCard.story.internal.tsx +++ b/packages/grafana-ui/src/components/CallToActionCard/CallToActionCard.story.internal.tsx @@ -1,8 +1,10 @@ -import React from 'react'; -import { CallToActionCard, CallToActionCardProps } from './CallToActionCard'; -import { Story, Meta } from '@storybook/react'; -import { Button } from '../Button/Button'; import { action } from '@storybook/addon-actions'; +import { Story, Meta } from '@storybook/react'; +import React from 'react'; + +import { Button } from '../Button/Button'; + +import { CallToActionCard, CallToActionCardProps } from './CallToActionCard'; export default { title: 'Layout/CallToActionCard', diff --git a/packages/grafana-ui/src/components/CallToActionCard/CallToActionCard.test.tsx b/packages/grafana-ui/src/components/CallToActionCard/CallToActionCard.test.tsx index 1e2a72d8f81..4d7a66badd2 100644 --- a/packages/grafana-ui/src/components/CallToActionCard/CallToActionCard.test.tsx +++ b/packages/grafana-ui/src/components/CallToActionCard/CallToActionCard.test.tsx @@ -1,8 +1,10 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; -import { CallToActionCard } from './CallToActionCard'; +import React from 'react'; + import { expect } from '../../../../../public/test/lib/common'; +import { CallToActionCard } from './CallToActionCard'; + describe('CallToActionCard', () => { describe('rendering', () => { it('should render callToActionElement', () => { diff --git a/packages/grafana-ui/src/components/CallToActionCard/CallToActionCard.tsx b/packages/grafana-ui/src/components/CallToActionCard/CallToActionCard.tsx index d566a866d79..64b179aeece 100644 --- a/packages/grafana-ui/src/components/CallToActionCard/CallToActionCard.tsx +++ b/packages/grafana-ui/src/components/CallToActionCard/CallToActionCard.tsx @@ -1,8 +1,10 @@ -import React from 'react'; import { css, cx } from '@emotion/css'; -import { useStyles2 } from '../../themes/ThemeContext'; +import React from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; +import { useStyles2 } from '../../themes/ThemeContext'; + export interface CallToActionCardProps { message?: string | JSX.Element; callToActionElement: JSX.Element; diff --git a/packages/grafana-ui/src/components/Card/Card.story.tsx b/packages/grafana-ui/src/components/Card/Card.story.tsx index 08893cf8d50..a6e06b499bd 100644 --- a/packages/grafana-ui/src/components/Card/Card.story.tsx +++ b/packages/grafana-ui/src/components/Card/Card.story.tsx @@ -1,12 +1,14 @@ -import React from 'react'; import { Story } from '@storybook/react'; +import React from 'react'; + import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; -import { Card, Props } from './Card'; -import mdx from './Card.mdx'; import { Button } from '../Button'; import { IconButton } from '../IconButton/IconButton'; -import { TagList } from '../Tags/TagList'; import { VerticalGroup } from '../Layout/Layout'; +import { TagList } from '../Tags/TagList'; + +import { Card, Props } from './Card'; +import mdx from './Card.mdx'; const logo = 'https://grafana.com/static/assets/img/apple-touch-icon.png'; diff --git a/packages/grafana-ui/src/components/Card/Card.test.tsx b/packages/grafana-ui/src/components/Card/Card.test.tsx index 9b147a42b01..87e3c5fff6d 100644 --- a/packages/grafana-ui/src/components/Card/Card.test.tsx +++ b/packages/grafana-ui/src/components/Card/Card.test.tsx @@ -1,9 +1,11 @@ -import React from 'react'; import { render, screen, fireEvent } from '@testing-library/react'; -import { Card } from './Card'; +import React from 'react'; + import { Button } from '../Button'; import { IconButton } from '../IconButton/IconButton'; +import { Card } from './Card'; + describe('Card', () => { it('should execute callback when clicked', () => { const callback = jest.fn(); diff --git a/packages/grafana-ui/src/components/Card/Card.tsx b/packages/grafana-ui/src/components/Card/Card.tsx index 427a82ddac0..f5056e9b232 100644 --- a/packages/grafana-ui/src/components/Card/Card.tsx +++ b/packages/grafana-ui/src/components/Card/Card.tsx @@ -1,10 +1,13 @@ -import React, { memo, cloneElement, FC, useMemo, useContext, ReactNode } from 'react'; import { css, cx } from '@emotion/css'; +import React, { memo, cloneElement, FC, useMemo, useContext, ReactNode } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; + import { useStyles2, useTheme2 } from '../../themes'; -import { CardContainer, CardContainerProps, getCardContainerStyles } from './CardContainer'; import { getFocusStyles } from '../../themes/mixins'; +import { CardContainer, CardContainerProps, getCardContainerStyles } from './CardContainer'; + /** * @public */ diff --git a/packages/grafana-ui/src/components/Card/CardContainer.tsx b/packages/grafana-ui/src/components/Card/CardContainer.tsx index 64bfe047e9c..3f81e998dc2 100644 --- a/packages/grafana-ui/src/components/Card/CardContainer.tsx +++ b/packages/grafana-ui/src/components/Card/CardContainer.tsx @@ -1,6 +1,8 @@ -import React, { HTMLAttributes } from 'react'; import { css, cx } from '@emotion/css'; +import React, { HTMLAttributes } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; + import { styleMixins, stylesFactory, useStyles2, useTheme2 } from '../../themes'; /** diff --git a/packages/grafana-ui/src/components/Cascader/Cascader.story.tsx b/packages/grafana-ui/src/components/Cascader/Cascader.story.tsx index a3ea1f80dc7..537f64a44b7 100644 --- a/packages/grafana-ui/src/components/Cascader/Cascader.story.tsx +++ b/packages/grafana-ui/src/components/Cascader/Cascader.story.tsx @@ -1,9 +1,12 @@ import { Story, Meta } from '@storybook/react'; -import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; +import React from 'react'; + import { Cascader } from '@grafana/ui'; + +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; + import { CascaderOption, CascaderProps } from './Cascader'; import mdx from './Cascader.mdx'; -import React from 'react'; const onSelect = (val: string) => console.log(val); const options = [ diff --git a/packages/grafana-ui/src/components/Cascader/Cascader.test.tsx b/packages/grafana-ui/src/components/Cascader/Cascader.test.tsx index b0f36e10610..e2dafc03041 100644 --- a/packages/grafana-ui/src/components/Cascader/Cascader.test.tsx +++ b/packages/grafana-ui/src/components/Cascader/Cascader.test.tsx @@ -1,8 +1,9 @@ -import React from 'react'; -import { Cascader, CascaderOption, CascaderProps } from './Cascader'; import { act, render, screen } from '@testing-library/react'; import userEvent, { PointerEventsCheckLevel } from '@testing-library/user-event'; import { UserEvent } from '@testing-library/user-event/dist/types/setup'; +import React from 'react'; + +import { Cascader, CascaderOption, CascaderProps } from './Cascader'; const options = [ { diff --git a/packages/grafana-ui/src/components/Cascader/Cascader.tsx b/packages/grafana-ui/src/components/Cascader/Cascader.tsx index a6f57c14759..5b061f0e943 100644 --- a/packages/grafana-ui/src/components/Cascader/Cascader.tsx +++ b/packages/grafana-ui/src/components/Cascader/Cascader.tsx @@ -1,13 +1,15 @@ -import React from 'react'; -import { Icon } from '../Icon/Icon'; -import RCCascader from 'rc-cascader'; - -import { Select } from '../Select/Select'; -import { Input } from '../Input/Input'; -import { SelectableValue } from '@grafana/data'; import { css } from '@emotion/css'; -import { onChangeCascader } from './optionMappings'; import memoizeOne from 'memoize-one'; +import RCCascader from 'rc-cascader'; +import React from 'react'; + +import { SelectableValue } from '@grafana/data'; + +import { Icon } from '../Icon/Icon'; +import { Input } from '../Input/Input'; +import { Select } from '../Select/Select'; + +import { onChangeCascader } from './optionMappings'; export interface CascaderProps { /** The separator between levels in the search */ diff --git a/packages/grafana-ui/src/components/Cascader/optionMappings.ts b/packages/grafana-ui/src/components/Cascader/optionMappings.ts index c616a09d603..6d490609d70 100644 --- a/packages/grafana-ui/src/components/Cascader/optionMappings.ts +++ b/packages/grafana-ui/src/components/Cascader/optionMappings.ts @@ -1,4 +1,5 @@ import { SingleValueType, BaseOptionType as RCCascaderOption } from 'rc-cascader/lib/Cascader'; + import { CascaderOption } from './Cascader'; type onChangeType = ((values: string[], options: CascaderOption[]) => void) | undefined; diff --git a/packages/grafana-ui/src/components/ClickOutsideWrapper/ClickOutsideWrapper.story.tsx b/packages/grafana-ui/src/components/ClickOutsideWrapper/ClickOutsideWrapper.story.tsx index 8746e6b2904..e9b5a6b1e50 100644 --- a/packages/grafana-ui/src/components/ClickOutsideWrapper/ClickOutsideWrapper.story.tsx +++ b/packages/grafana-ui/src/components/ClickOutsideWrapper/ClickOutsideWrapper.story.tsx @@ -1,7 +1,9 @@ -import React from 'react'; import { action } from '@storybook/addon-actions'; -import { ClickOutsideWrapper } from './ClickOutsideWrapper'; +import React from 'react'; + import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; + +import { ClickOutsideWrapper } from './ClickOutsideWrapper'; import mdx from './ClickOutsideWrapper.mdx'; export default { diff --git a/packages/grafana-ui/src/components/ClipboardButton/ClipboardButton.story.internal.tsx b/packages/grafana-ui/src/components/ClipboardButton/ClipboardButton.story.internal.tsx index 8bc335d7e32..db7a783962f 100644 --- a/packages/grafana-ui/src/components/ClipboardButton/ClipboardButton.story.internal.tsx +++ b/packages/grafana-ui/src/components/ClipboardButton/ClipboardButton.story.internal.tsx @@ -1,8 +1,10 @@ -import React, { useState } from 'react'; import { Story, Meta } from '@storybook/react'; +import React, { useState } from 'react'; + import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; -import { ClipboardButton, Props } from './ClipboardButton'; import { Input } from '../Forms/Legacy/Input/Input'; + +import { ClipboardButton, Props } from './ClipboardButton'; import mdx from './ClipboardButton.mdx'; export default { diff --git a/packages/grafana-ui/src/components/ClipboardButton/ClipboardButton.tsx b/packages/grafana-ui/src/components/ClipboardButton/ClipboardButton.tsx index 63c1aba06c9..61f7a19debe 100644 --- a/packages/grafana-ui/src/components/ClipboardButton/ClipboardButton.tsx +++ b/packages/grafana-ui/src/components/ClipboardButton/ClipboardButton.tsx @@ -1,4 +1,5 @@ import React, { useCallback, useRef } from 'react'; + import { Button, ButtonProps } from '../Button'; /** @deprecated Will be removed in next major release */ diff --git a/packages/grafana-ui/src/components/Collapse/CollapsableSection.story.tsx b/packages/grafana-ui/src/components/Collapse/CollapsableSection.story.tsx index 6e02c8cf7bc..a86051a369e 100644 --- a/packages/grafana-ui/src/components/Collapse/CollapsableSection.story.tsx +++ b/packages/grafana-ui/src/components/Collapse/CollapsableSection.story.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { CollapsableSection } from './CollapsableSection'; import mdx from './CollapsableSection.mdx'; diff --git a/packages/grafana-ui/src/components/Collapse/CollapsableSection.tsx b/packages/grafana-ui/src/components/Collapse/CollapsableSection.tsx index c58c7b8c3a1..13fff992cb0 100644 --- a/packages/grafana-ui/src/components/Collapse/CollapsableSection.tsx +++ b/packages/grafana-ui/src/components/Collapse/CollapsableSection.tsx @@ -1,9 +1,11 @@ -import React, { FC, ReactNode, useRef, useState } from 'react'; -import { uniqueId } from 'lodash'; import { css, cx } from '@emotion/css'; -import { useStyles2 } from '../../themes'; -import { Icon, Spinner } from '..'; +import { uniqueId } from 'lodash'; +import React, { FC, ReactNode, useRef, useState } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; + +import { Icon, Spinner } from '..'; +import { useStyles2 } from '../../themes'; import { getFocusStyles } from '../../themes/mixins'; export interface Props { diff --git a/packages/grafana-ui/src/components/Collapse/Collapse.story.tsx b/packages/grafana-ui/src/components/Collapse/Collapse.story.tsx index b7b00dcbd08..9d8fc0ca0d5 100644 --- a/packages/grafana-ui/src/components/Collapse/Collapse.story.tsx +++ b/packages/grafana-ui/src/components/Collapse/Collapse.story.tsx @@ -1,7 +1,9 @@ import React from 'react'; -import { Collapse, ControlledCollapse } from './Collapse'; -import { withCenteredStory, withHorizontallyCenteredStory } from '../../utils/storybook/withCenteredStory'; + import { UseState } from '../../utils/storybook/UseState'; +import { withCenteredStory, withHorizontallyCenteredStory } from '../../utils/storybook/withCenteredStory'; + +import { Collapse, ControlledCollapse } from './Collapse'; import mdx from './Collapse.mdx'; export default { diff --git a/packages/grafana-ui/src/components/Collapse/Collapse.tsx b/packages/grafana-ui/src/components/Collapse/Collapse.tsx index 2b081551287..13f871bf326 100644 --- a/packages/grafana-ui/src/components/Collapse/Collapse.tsx +++ b/packages/grafana-ui/src/components/Collapse/Collapse.tsx @@ -1,7 +1,8 @@ import { css, cx } from '@emotion/css'; -import { GrafanaTheme2 } from '@grafana/data'; import React, { FunctionComponent, useState } from 'react'; +import { GrafanaTheme2 } from '@grafana/data'; + import { useStyles2 } from '../../themes/ThemeContext'; import { Icon } from '../Icon/Icon'; diff --git a/packages/grafana-ui/src/components/ColorPicker/ColorInput.tsx b/packages/grafana-ui/src/components/ColorPicker/ColorInput.tsx index 684dd41c53b..5877ba3f959 100644 --- a/packages/grafana-ui/src/components/ColorPicker/ColorInput.tsx +++ b/packages/grafana-ui/src/components/ColorPicker/ColorInput.tsx @@ -1,12 +1,14 @@ +import { cx, css } from '@emotion/css'; +import { debounce } from 'lodash'; import React from 'react'; import tinycolor from 'tinycolor2'; -import { debounce } from 'lodash'; + +import { GrafanaTheme2 } from '@grafana/data'; + +import { useStyles2 } from '../../themes'; +import { Input } from '../Input/Input'; import { ColorPickerProps } from './ColorPickerPopover'; -import { Input } from '../Input/Input'; -import { useStyles2 } from '../../themes'; -import { GrafanaTheme2 } from '@grafana/data'; -import { cx, css } from '@emotion/css'; interface ColorInputState { previousColor: string; diff --git a/packages/grafana-ui/src/components/ColorPicker/ColorPicker.story.tsx b/packages/grafana-ui/src/components/ColorPicker/ColorPicker.story.tsx index 1312169c203..200154f0ff0 100644 --- a/packages/grafana-ui/src/components/ColorPicker/ColorPicker.story.tsx +++ b/packages/grafana-ui/src/components/ColorPicker/ColorPicker.story.tsx @@ -1,12 +1,15 @@ -import React from 'react'; -import { Meta, Story } from '@storybook/react'; -import { SeriesColorPicker, ColorPicker } from '@grafana/ui'; import { action } from '@storybook/addon-actions'; -import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; +import { Meta, Story } from '@storybook/react'; +import React from 'react'; + +import { SeriesColorPicker, ColorPicker } from '@grafana/ui'; + import { UseState } from '../../utils/storybook/UseState'; +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; import { renderComponentWithTheme } from '../../utils/storybook/withTheme'; -import { ColorPickerProps } from './ColorPickerPopover'; + import mdx from './ColorPicker.mdx'; +import { ColorPickerProps } from './ColorPickerPopover'; export default { title: 'Pickers and Editors/ColorPicker', diff --git a/packages/grafana-ui/src/components/ColorPicker/ColorPicker.test.tsx b/packages/grafana-ui/src/components/ColorPicker/ColorPicker.test.tsx index 00a703f3eae..78350a9108a 100644 --- a/packages/grafana-ui/src/components/ColorPicker/ColorPicker.test.tsx +++ b/packages/grafana-ui/src/components/ColorPicker/ColorPicker.test.tsx @@ -1,5 +1,6 @@ import React from 'react'; import renderer from 'react-test-renderer'; + import { ColorPicker } from './ColorPicker'; import { ColorSwatch } from './ColorSwatch'; diff --git a/packages/grafana-ui/src/components/ColorPicker/ColorPicker.tsx b/packages/grafana-ui/src/components/ColorPicker/ColorPicker.tsx index 4d96440b69b..453c7d430c6 100644 --- a/packages/grafana-ui/src/components/ColorPicker/ColorPicker.tsx +++ b/packages/grafana-ui/src/components/ColorPicker/ColorPicker.tsx @@ -1,14 +1,16 @@ -import React, { Component, createRef } from 'react'; -import { PopoverController } from '../Tooltip/PopoverController'; -import { Popover } from '../Tooltip/Popover'; -import { ColorPickerPopover, ColorPickerProps, ColorPickerChangeHandler } from './ColorPickerPopover'; -import { GrafanaTheme2 } from '@grafana/data'; -import { SeriesColorPickerPopover } from './SeriesColorPickerPopover'; - import { css } from '@emotion/css'; +import React, { Component, createRef } from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; + import { withTheme2, stylesFactory } from '../../themes'; -import { ColorSwatch } from './ColorSwatch'; import { closePopover } from '../../utils/closePopover'; +import { Popover } from '../Tooltip/Popover'; +import { PopoverController } from '../Tooltip/PopoverController'; + +import { ColorPickerPopover, ColorPickerProps, ColorPickerChangeHandler } from './ColorPickerPopover'; +import { ColorSwatch } from './ColorSwatch'; +import { SeriesColorPickerPopover } from './SeriesColorPickerPopover'; /** * If you need custom trigger for the color picker you can do that with a render prop pattern and supply a function diff --git a/packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.story.tsx b/packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.story.tsx index 5b04d0da970..a26e055b490 100644 --- a/packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.story.tsx +++ b/packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.story.tsx @@ -1,9 +1,9 @@ -import { ColorPickerPopover } from './ColorPickerPopover'; - import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; -import { SeriesColorPickerPopover } from './SeriesColorPickerPopover'; import { renderComponentWithTheme } from '../../utils/storybook/withTheme'; +import { ColorPickerPopover } from './ColorPickerPopover'; +import { SeriesColorPickerPopover } from './SeriesColorPickerPopover'; + export default { title: 'Pickers and Editors/ColorPicker/Popovers', component: ColorPickerPopover, diff --git a/packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.test.tsx b/packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.test.tsx index d4f22689b04..cc60ee3c0b7 100644 --- a/packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.test.tsx +++ b/packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.test.tsx @@ -1,8 +1,10 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; -import { ColorPickerPopover } from './ColorPickerPopover'; -import { createTheme } from '@grafana/data'; import userEvent from '@testing-library/user-event'; +import React from 'react'; + +import { createTheme } from '@grafana/data'; + +import { ColorPickerPopover } from './ColorPickerPopover'; describe('ColorPickerPopover', () => { const theme = createTheme(); diff --git a/packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.tsx b/packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.tsx index 4bfa15710c2..3a77661ac44 100644 --- a/packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.tsx +++ b/packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.tsx @@ -1,13 +1,16 @@ -import React from 'react'; -import { NamedColorsPalette } from './NamedColorsPalette'; -import { PopoverContentProps } from '../Tooltip'; -import SpectrumPalette from './SpectrumPalette'; -import { Themeable2 } from '../../types/theme'; -import { warnAboutColorPickerPropsDeprecation } from './warnAboutColorPickerPropsDeprecation'; import { css } from '@emotion/css'; -import { GrafanaTheme2, colorManipulator } from '@grafana/data'; -import { stylesFactory, withTheme2 } from '../../themes'; import { FocusScope } from '@react-aria/focus'; +import React from 'react'; + +import { GrafanaTheme2, colorManipulator } from '@grafana/data'; + +import { stylesFactory, withTheme2 } from '../../themes'; +import { Themeable2 } from '../../types/theme'; +import { PopoverContentProps } from '../Tooltip'; + +import { NamedColorsPalette } from './NamedColorsPalette'; +import SpectrumPalette from './SpectrumPalette'; +import { warnAboutColorPickerPropsDeprecation } from './warnAboutColorPickerPropsDeprecation'; export type ColorPickerChangeHandler = (color: string) => void; diff --git a/packages/grafana-ui/src/components/ColorPicker/ColorSwatch.tsx b/packages/grafana-ui/src/components/ColorPicker/ColorSwatch.tsx index 99417069381..309b1f852a3 100644 --- a/packages/grafana-ui/src/components/ColorPicker/ColorSwatch.tsx +++ b/packages/grafana-ui/src/components/ColorPicker/ColorSwatch.tsx @@ -1,10 +1,12 @@ +import { css } from '@emotion/css'; import { useFocusRing } from '@react-aria/focus'; import React from 'react'; import tinycolor from 'tinycolor2'; -import { useTheme2 } from '../../themes/ThemeContext'; -import { selectors } from '@grafana/e2e-selectors'; + import { GrafanaTheme2 } from '@grafana/data'; -import { css } from '@emotion/css'; +import { selectors } from '@grafana/e2e-selectors'; + +import { useTheme2 } from '../../themes/ThemeContext'; /** @internal */ export enum ColorSwatchVariant { diff --git a/packages/grafana-ui/src/components/ColorPicker/NamedColorsGroup.tsx b/packages/grafana-ui/src/components/ColorPicker/NamedColorsGroup.tsx index 607eaf03f4b..016d155d242 100644 --- a/packages/grafana-ui/src/components/ColorPicker/NamedColorsGroup.tsx +++ b/packages/grafana-ui/src/components/ColorPicker/NamedColorsGroup.tsx @@ -1,12 +1,15 @@ -import React, { FunctionComponent } from 'react'; -import { GrafanaTheme2, ThemeVizHue } from '@grafana/data'; -import { Property } from 'csstype'; -import { ColorSwatch, ColorSwatchVariant } from './ColorSwatch'; -import { upperFirst } from 'lodash'; -import { useStyles2 } from '../../themes/ThemeContext'; import { css } from '@emotion/css'; +import { Property } from 'csstype'; +import { upperFirst } from 'lodash'; +import React, { FunctionComponent } from 'react'; + +import { GrafanaTheme2, ThemeVizHue } from '@grafana/data'; + +import { useStyles2 } from '../../themes/ThemeContext'; import { reverseMap } from '../../utils/reverseMap'; +import { ColorSwatch, ColorSwatchVariant } from './ColorSwatch'; + interface NamedColorsGroupProps { hue: ThemeVizHue; selectedColor?: Property.Color; diff --git a/packages/grafana-ui/src/components/ColorPicker/NamedColorsPalette.story.tsx b/packages/grafana-ui/src/components/ColorPicker/NamedColorsPalette.story.tsx index cb24e5ce367..f5f20cca365 100644 --- a/packages/grafana-ui/src/components/ColorPicker/NamedColorsPalette.story.tsx +++ b/packages/grafana-ui/src/components/ColorPicker/NamedColorsPalette.story.tsx @@ -1,8 +1,10 @@ -import React, { useState } from 'react'; -import { NamedColorsPalette, NamedColorsPaletteProps } from './NamedColorsPalette'; import { Meta, Story } from '@storybook/react'; +import React, { useState } from 'react'; + import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; + import mdx from './ColorPicker.mdx'; +import { NamedColorsPalette, NamedColorsPaletteProps } from './NamedColorsPalette'; export default { title: 'Pickers and Editors/ColorPicker/Palettes/NamedColorsPalette', diff --git a/packages/grafana-ui/src/components/ColorPicker/NamedColorsPalette.test.tsx b/packages/grafana-ui/src/components/ColorPicker/NamedColorsPalette.test.tsx index 023dad1f14a..21409e560bb 100644 --- a/packages/grafana-ui/src/components/ColorPicker/NamedColorsPalette.test.tsx +++ b/packages/grafana-ui/src/components/ColorPicker/NamedColorsPalette.test.tsx @@ -1,8 +1,10 @@ -import React from 'react'; import { mount, ReactWrapper } from 'enzyme'; -import { NamedColorsPalette } from './NamedColorsPalette'; +import React from 'react'; + import { createTheme } from '@grafana/data'; + import { ColorSwatch } from './ColorSwatch'; +import { NamedColorsPalette } from './NamedColorsPalette'; describe('NamedColorsPalette', () => { const theme = createTheme(); diff --git a/packages/grafana-ui/src/components/ColorPicker/NamedColorsPalette.tsx b/packages/grafana-ui/src/components/ColorPicker/NamedColorsPalette.tsx index 548b814c354..266eb238aaa 100644 --- a/packages/grafana-ui/src/components/ColorPicker/NamedColorsPalette.tsx +++ b/packages/grafana-ui/src/components/ColorPicker/NamedColorsPalette.tsx @@ -1,9 +1,12 @@ -import React from 'react'; -import NamedColorsGroup from './NamedColorsGroup'; -import { ColorSwatch } from './ColorSwatch'; -import { useStyles2, useTheme2 } from '../../themes/ThemeContext'; -import { GrafanaTheme2 } from '@grafana/data'; import { css } from '@emotion/css'; +import React from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; + +import { useStyles2, useTheme2 } from '../../themes/ThemeContext'; + +import { ColorSwatch } from './ColorSwatch'; +import NamedColorsGroup from './NamedColorsGroup'; export interface NamedColorsPaletteProps { color?: string; diff --git a/packages/grafana-ui/src/components/ColorPicker/SeriesColorPickerPopover.tsx b/packages/grafana-ui/src/components/ColorPicker/SeriesColorPickerPopover.tsx index 0cf754b2db3..1d6de01a9e0 100644 --- a/packages/grafana-ui/src/components/ColorPicker/SeriesColorPickerPopover.tsx +++ b/packages/grafana-ui/src/components/ColorPicker/SeriesColorPickerPopover.tsx @@ -1,11 +1,12 @@ +import { css } from '@emotion/css'; import React, { FunctionComponent } from 'react'; -import { ColorPickerPopover, ColorPickerProps } from './ColorPickerPopover'; -import { PopoverContentProps } from '../Tooltip'; -import { Switch } from '../Forms/Legacy/Switch/Switch'; -import { css } from '@emotion/css'; import { withTheme2, useStyles } from '../../themes'; import { Button } from '../Button'; +import { Switch } from '../Forms/Legacy/Switch/Switch'; +import { PopoverContentProps } from '../Tooltip'; + +import { ColorPickerPopover, ColorPickerProps } from './ColorPickerPopover'; export interface SeriesColorPickerPopoverProps extends ColorPickerProps, PopoverContentProps { yaxis?: number; diff --git a/packages/grafana-ui/src/components/ColorPicker/SpectrumPalette.story.tsx b/packages/grafana-ui/src/components/ColorPicker/SpectrumPalette.story.tsx index dc6713e3e93..8b50293f658 100644 --- a/packages/grafana-ui/src/components/ColorPicker/SpectrumPalette.story.tsx +++ b/packages/grafana-ui/src/components/ColorPicker/SpectrumPalette.story.tsx @@ -1,9 +1,11 @@ import React from 'react'; -import SpectrumPalette from './SpectrumPalette'; -import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; + import { UseState } from '../../utils/storybook/UseState'; +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; import { renderComponentWithTheme } from '../../utils/storybook/withTheme'; + import mdx from './ColorPicker.mdx'; +import SpectrumPalette from './SpectrumPalette'; export default { title: 'Pickers and Editors/ColorPicker/Palettes/SpectrumPalette', diff --git a/packages/grafana-ui/src/components/ColorPicker/SpectrumPalette.tsx b/packages/grafana-ui/src/components/ColorPicker/SpectrumPalette.tsx index 3b6a7ca51fd..7006a1e8636 100644 --- a/packages/grafana-ui/src/components/ColorPicker/SpectrumPalette.tsx +++ b/packages/grafana-ui/src/components/ColorPicker/SpectrumPalette.tsx @@ -1,12 +1,14 @@ -import React, { useMemo, useState } from 'react'; - -import { RgbaStringColorPicker } from 'react-colorful'; -import tinycolor from 'tinycolor2'; -import ColorInput from './ColorInput'; -import { GrafanaTheme2, colorManipulator } from '@grafana/data'; import { css, cx } from '@emotion/css'; -import { useStyles2, useTheme2 } from '../../themes'; +import React, { useMemo, useState } from 'react'; +import { RgbaStringColorPicker } from 'react-colorful'; import { useThrottleFn } from 'react-use'; +import tinycolor from 'tinycolor2'; + +import { GrafanaTheme2, colorManipulator } from '@grafana/data'; + +import { useStyles2, useTheme2 } from '../../themes'; + +import ColorInput from './ColorInput'; export interface SpectrumPaletteProps { color: string; diff --git a/packages/grafana-ui/src/components/ColorPicker/warnAboutColorPickerPropsDeprecation.ts b/packages/grafana-ui/src/components/ColorPicker/warnAboutColorPickerPropsDeprecation.ts index 145cf5d5c67..9f58ba70285 100644 --- a/packages/grafana-ui/src/components/ColorPicker/warnAboutColorPickerPropsDeprecation.ts +++ b/packages/grafana-ui/src/components/ColorPicker/warnAboutColorPickerPropsDeprecation.ts @@ -1,4 +1,5 @@ import { deprecationWarning } from '@grafana/data'; + import { ColorPickerProps } from './ColorPickerPopover'; export const warnAboutColorPickerPropsDeprecation = (componentName: string, props: ColorPickerProps) => { diff --git a/packages/grafana-ui/src/components/ConfirmButton/ConfirmButton.story.tsx b/packages/grafana-ui/src/components/ConfirmButton/ConfirmButton.story.tsx index cdf99180555..adab9546c4f 100644 --- a/packages/grafana-ui/src/components/ConfirmButton/ConfirmButton.story.tsx +++ b/packages/grafana-ui/src/components/ConfirmButton/ConfirmButton.story.tsx @@ -1,12 +1,15 @@ -import React from 'react'; -import { Meta, Story } from '@storybook/react'; -import { ConfirmButton } from '@grafana/ui'; -import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; import { action } from '@storybook/addon-actions'; +import { Meta, Story } from '@storybook/react'; +import React from 'react'; + +import { ConfirmButton } from '@grafana/ui'; + +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; import { Button } from '../Button'; -import { DeleteButton } from './DeleteButton'; + import { Props } from './ConfirmButton'; import mdx from './ConfirmButton.mdx'; +import { DeleteButton } from './DeleteButton'; export default { title: 'Buttons/ConfirmButton', diff --git a/packages/grafana-ui/src/components/ConfirmButton/ConfirmButton.test.tsx b/packages/grafana-ui/src/components/ConfirmButton/ConfirmButton.test.tsx index 3fd006dc194..6a91f927413 100644 --- a/packages/grafana-ui/src/components/ConfirmButton/ConfirmButton.test.tsx +++ b/packages/grafana-ui/src/components/ConfirmButton/ConfirmButton.test.tsx @@ -1,9 +1,10 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import React from 'react'; + +import { expect } from '../../../../../public/test/lib/common'; import { ConfirmButton } from './ConfirmButton'; -import { expect } from '../../../../../public/test/lib/common'; describe('ConfirmButton', () => { it('should show confirm delete when clicked', async () => { diff --git a/packages/grafana-ui/src/components/ConfirmButton/ConfirmButton.tsx b/packages/grafana-ui/src/components/ConfirmButton/ConfirmButton.tsx index d41edf0b699..a9c39369c6d 100644 --- a/packages/grafana-ui/src/components/ConfirmButton/ConfirmButton.tsx +++ b/packages/grafana-ui/src/components/ConfirmButton/ConfirmButton.tsx @@ -1,7 +1,9 @@ -import React, { PureComponent, SyntheticEvent } from 'react'; import { cx, css } from '@emotion/css'; -import { stylesFactory, withTheme } from '../../themes'; +import React, { PureComponent, SyntheticEvent } from 'react'; + import { GrafanaTheme } from '@grafana/data'; + +import { stylesFactory, withTheme } from '../../themes'; import { Themeable } from '../../types'; import { ComponentSize } from '../../types/size'; import { Button, ButtonVariant } from '../Button'; diff --git a/packages/grafana-ui/src/components/ConfirmButton/DeleteButton.tsx b/packages/grafana-ui/src/components/ConfirmButton/DeleteButton.tsx index f383a31ef5d..c0e5014d5d9 100644 --- a/packages/grafana-ui/src/components/ConfirmButton/DeleteButton.tsx +++ b/packages/grafana-ui/src/components/ConfirmButton/DeleteButton.tsx @@ -1,8 +1,10 @@ import React, { FC } from 'react'; -import { ConfirmButton } from './ConfirmButton'; + import { ComponentSize } from '../../types/size'; import { Button } from '../Button'; +import { ConfirmButton } from './ConfirmButton'; + export interface Props { /** Confirm action callback */ onConfirm(): void; diff --git a/packages/grafana-ui/src/components/ConfirmModal/ConfirmModal.story.tsx b/packages/grafana-ui/src/components/ConfirmModal/ConfirmModal.story.tsx index e0c265d4412..11fef1700df 100644 --- a/packages/grafana-ui/src/components/ConfirmModal/ConfirmModal.story.tsx +++ b/packages/grafana-ui/src/components/ConfirmModal/ConfirmModal.story.tsx @@ -1,10 +1,13 @@ -import React from 'react'; -import { Meta, Story } from '@storybook/react'; import { action } from '@storybook/addon-actions'; -import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; +import { Meta, Story } from '@storybook/react'; +import React from 'react'; + import { ConfirmModal } from '@grafana/ui'; -import mdx from './ConfirmModal.mdx'; + +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; + import { ConfirmModalProps } from './ConfirmModal'; +import mdx from './ConfirmModal.mdx'; const defaultExcludes = ['onConfirm', 'onDismiss', 'onAlternative']; diff --git a/packages/grafana-ui/src/components/ConfirmModal/ConfirmModal.test.tsx b/packages/grafana-ui/src/components/ConfirmModal/ConfirmModal.test.tsx index 50a9482c9af..8c7a2f93c88 100644 --- a/packages/grafana-ui/src/components/ConfirmModal/ConfirmModal.test.tsx +++ b/packages/grafana-ui/src/components/ConfirmModal/ConfirmModal.test.tsx @@ -1,5 +1,5 @@ -import React from 'react'; import { render, screen, within } from '@testing-library/react'; +import React from 'react'; import { ConfirmModal } from './ConfirmModal'; diff --git a/packages/grafana-ui/src/components/ConfirmModal/ConfirmModal.tsx b/packages/grafana-ui/src/components/ConfirmModal/ConfirmModal.tsx index 99d5bf676c6..8139228a81c 100644 --- a/packages/grafana-ui/src/components/ConfirmModal/ConfirmModal.tsx +++ b/packages/grafana-ui/src/components/ConfirmModal/ConfirmModal.tsx @@ -1,13 +1,14 @@ -import React, { useEffect, useRef, useState } from 'react'; import { css } from '@emotion/css'; +import React, { useEffect, useRef, useState } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; -import { Modal } from '../Modal/Modal'; +import { HorizontalGroup, Input } from '..'; +import { useStyles2 } from '../../themes'; import { IconName } from '../../types/icon'; import { Button } from '../Button'; -import { useStyles2 } from '../../themes'; -import { HorizontalGroup, Input } from '..'; +import { Modal } from '../Modal/Modal'; export interface ConfirmModalProps { /** Toggle modal's open/closed state */ diff --git a/packages/grafana-ui/src/components/ContextMenu/ContextMenu.story.tsx b/packages/grafana-ui/src/components/ContextMenu/ContextMenu.story.tsx index edcc1948814..077dc698184 100644 --- a/packages/grafana-ui/src/components/ContextMenu/ContextMenu.story.tsx +++ b/packages/grafana-ui/src/components/ContextMenu/ContextMenu.story.tsx @@ -1,12 +1,14 @@ import React from 'react'; + import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; import { IconButton } from '../IconButton/IconButton'; -import { ContextMenu } from './ContextMenu'; -import { WithContextMenu } from './WithContextMenu'; -import mdx from './ContextMenu.mdx'; import { MenuGroup } from '../Menu/MenuGroup'; import { MenuItem } from '../Menu/MenuItem'; +import { ContextMenu } from './ContextMenu'; +import mdx from './ContextMenu.mdx'; +import { WithContextMenu } from './WithContextMenu'; + export default { title: 'General/ContextMenu', component: ContextMenu, diff --git a/packages/grafana-ui/src/components/ContextMenu/ContextMenu.tsx b/packages/grafana-ui/src/components/ContextMenu/ContextMenu.tsx index d4312d6a3db..bde5b951c51 100644 --- a/packages/grafana-ui/src/components/ContextMenu/ContextMenu.tsx +++ b/packages/grafana-ui/src/components/ContextMenu/ContextMenu.tsx @@ -1,8 +1,10 @@ import React, { useRef, useState, useLayoutEffect } from 'react'; -import { selectors } from '@grafana/e2e-selectors'; import { useClickAway } from 'react-use'; -import { Portal } from '../Portal/Portal'; + +import { selectors } from '@grafana/e2e-selectors'; + import { Menu } from '../Menu/Menu'; +import { Portal } from '../Portal/Portal'; export interface ContextMenuProps { /** Starting horizontal position for the menu */ diff --git a/packages/grafana-ui/src/components/ContextMenu/WithContextMenu.tsx b/packages/grafana-ui/src/components/ContextMenu/WithContextMenu.tsx index 92c862c8c77..c502306b351 100644 --- a/packages/grafana-ui/src/components/ContextMenu/WithContextMenu.tsx +++ b/packages/grafana-ui/src/components/ContextMenu/WithContextMenu.tsx @@ -1,4 +1,5 @@ import React, { useState } from 'react'; + import { ContextMenu } from '../ContextMenu/ContextMenu'; interface WithContextMenuProps { diff --git a/packages/grafana-ui/src/components/CustomScrollbar/CustomScrollbar.test.tsx b/packages/grafana-ui/src/components/CustomScrollbar/CustomScrollbar.test.tsx index 32375a5dc29..0c8c84a229d 100644 --- a/packages/grafana-ui/src/components/CustomScrollbar/CustomScrollbar.test.tsx +++ b/packages/grafana-ui/src/components/CustomScrollbar/CustomScrollbar.test.tsx @@ -1,5 +1,6 @@ import React from 'react'; import renderer from 'react-test-renderer'; + import { CustomScrollbar } from './CustomScrollbar'; describe('CustomScrollbar', () => { diff --git a/packages/grafana-ui/src/components/CustomScrollbar/CustomScrollbar.tsx b/packages/grafana-ui/src/components/CustomScrollbar/CustomScrollbar.tsx index fa228b87877..a5091495894 100644 --- a/packages/grafana-ui/src/components/CustomScrollbar/CustomScrollbar.tsx +++ b/packages/grafana-ui/src/components/CustomScrollbar/CustomScrollbar.tsx @@ -1,9 +1,11 @@ import { css } from '@emotion/css'; -import { GrafanaTheme2 } from '@grafana/data'; import classNames from 'classnames'; import { isNil } from 'lodash'; import React, { FC, RefCallback, useCallback, useEffect, useRef } from 'react'; import Scrollbars, { positionValues } from 'react-custom-scrollbars-2'; + +import { GrafanaTheme2 } from '@grafana/data'; + import { useStyles2 } from '../../themes'; export type ScrollbarPosition = positionValues; diff --git a/packages/grafana-ui/src/components/DataLinks/DataLinkButton.tsx b/packages/grafana-ui/src/components/DataLinks/DataLinkButton.tsx index 95d8b8d4160..e9309429c50 100644 --- a/packages/grafana-ui/src/components/DataLinks/DataLinkButton.tsx +++ b/packages/grafana-ui/src/components/DataLinks/DataLinkButton.tsx @@ -1,5 +1,7 @@ -import { Field, LinkModel } from '@grafana/data'; import React from 'react'; + +import { Field, LinkModel } from '@grafana/data'; + import { ButtonProps, Button } from '../Button'; type DataLinkButtonProps = { diff --git a/packages/grafana-ui/src/components/DataLinks/DataLinkEditor.tsx b/packages/grafana-ui/src/components/DataLinks/DataLinkEditor.tsx index b433d029a7f..820fae0b5bb 100644 --- a/packages/grafana-ui/src/components/DataLinks/DataLinkEditor.tsx +++ b/packages/grafana-ui/src/components/DataLinks/DataLinkEditor.tsx @@ -1,11 +1,14 @@ -import React, { ChangeEvent } from 'react'; -import { VariableSuggestion, GrafanaTheme2, DataLink } from '@grafana/data'; -import { Switch } from '../Switch/Switch'; import { css } from '@emotion/css'; +import React, { ChangeEvent } from 'react'; + +import { VariableSuggestion, GrafanaTheme2, DataLink } from '@grafana/data'; + import { useStyles2 } from '../../themes/index'; -import { DataLinkInput } from './DataLinkInput'; import { Field } from '../Forms/Field'; import { Input } from '../Input/Input'; +import { Switch } from '../Switch/Switch'; + +import { DataLinkInput } from './DataLinkInput'; interface DataLinkEditorProps { index: number; diff --git a/packages/grafana-ui/src/components/DataLinks/DataLinkInput.tsx b/packages/grafana-ui/src/components/DataLinks/DataLinkInput.tsx index 2395c016e5d..c6d958ed9c0 100644 --- a/packages/grafana-ui/src/components/DataLinks/DataLinkInput.tsx +++ b/packages/grafana-ui/src/components/DataLinks/DataLinkInput.tsx @@ -1,24 +1,24 @@ -import React, { memo, RefObject, useEffect, useMemo, useRef, useState } from 'react'; -import usePrevious from 'react-use/lib/usePrevious'; -import { DataLinkSuggestions } from './DataLinkSuggestions'; -import { makeValue } from '../../index'; -import { SelectionReference } from './SelectionReference'; -import { Portal } from '../index'; - -// @ts-ignore +import { css, cx } from '@emotion/css'; import Prism, { Grammar, LanguageMap } from 'prismjs'; -import { Editor } from '@grafana/slate-react'; +import React, { memo, RefObject, useEffect, useMemo, useRef, useState } from 'react'; +import { Popper as ReactPopper } from 'react-popper'; +import usePrevious from 'react-use/lib/usePrevious'; import { Value } from 'slate'; import Plain from 'slate-plain-serializer'; -import { Popper as ReactPopper } from 'react-popper'; -import { css, cx } from '@emotion/css'; -import { SlatePrism } from '../../slate-plugins'; -import { SCHEMA } from '../../utils/slate'; -import { useStyles2 } from '../../themes'; import { DataLinkBuiltInVars, GrafanaTheme2, VariableOrigin, VariableSuggestion } from '@grafana/data'; -import { getInputStyles } from '../Input/Input'; +import { Editor } from '@grafana/slate-react'; + +import { makeValue } from '../../index'; +import { SlatePrism } from '../../slate-plugins'; +import { useStyles2 } from '../../themes'; +import { SCHEMA } from '../../utils/slate'; import CustomScrollbar from '../CustomScrollbar/CustomScrollbar'; +import { getInputStyles } from '../Input/Input'; +import { Portal } from '../index'; + +import { DataLinkSuggestions } from './DataLinkSuggestions'; +import { SelectionReference } from './SelectionReference'; const modulo = (a: number, n: number) => a - n * Math.floor(a / n); diff --git a/packages/grafana-ui/src/components/DataLinks/DataLinkSuggestions.tsx b/packages/grafana-ui/src/components/DataLinks/DataLinkSuggestions.tsx index e3dff49688c..fe493efe315 100644 --- a/packages/grafana-ui/src/components/DataLinks/DataLinkSuggestions.tsx +++ b/packages/grafana-ui/src/components/DataLinks/DataLinkSuggestions.tsx @@ -1,10 +1,12 @@ -import { VariableSuggestion, GrafanaTheme2 } from '@grafana/data'; import { css, cx } from '@emotion/css'; import { groupBy, capitalize } from 'lodash'; import React, { useRef, useMemo } from 'react'; import useClickAway from 'react-use/lib/useClickAway'; -import { List } from '../index'; + +import { VariableSuggestion, GrafanaTheme2 } from '@grafana/data'; + import { useStyles2 } from '../../themes'; +import { List } from '../index'; interface DataLinkSuggestionsProps { activeRef?: React.RefObject; diff --git a/packages/grafana-ui/src/components/DataLinks/DataLinksContextMenu.test.tsx b/packages/grafana-ui/src/components/DataLinks/DataLinksContextMenu.test.tsx index 9ac75b37da0..8deb2ff2f50 100644 --- a/packages/grafana-ui/src/components/DataLinks/DataLinksContextMenu.test.tsx +++ b/packages/grafana-ui/src/components/DataLinks/DataLinksContextMenu.test.tsx @@ -1,8 +1,10 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; -import { DataLinksContextMenu } from './DataLinksContextMenu'; +import React from 'react'; + import { selectors } from '@grafana/e2e-selectors'; +import { DataLinksContextMenu } from './DataLinksContextMenu'; + const fakeAriaLabel = 'fake aria label'; describe('DataLinksContextMenu', () => { it('renders context menu when there are more than one data links', () => { diff --git a/packages/grafana-ui/src/components/DataLinks/DataLinksContextMenu.tsx b/packages/grafana-ui/src/components/DataLinks/DataLinksContextMenu.tsx index 2756b65ae41..5a700355ae6 100644 --- a/packages/grafana-ui/src/components/DataLinks/DataLinksContextMenu.tsx +++ b/packages/grafana-ui/src/components/DataLinks/DataLinksContextMenu.tsx @@ -1,9 +1,11 @@ +import { css } from '@emotion/css'; import React from 'react'; + import { FieldConfig, LinkModel } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; -import { css } from '@emotion/css'; -import { WithContextMenu } from '../ContextMenu/WithContextMenu'; + import { linkModelToContextMenuItems } from '../../utils/dataLinks'; +import { WithContextMenu } from '../ContextMenu/WithContextMenu'; import { MenuGroup, MenuItemsGroup } from '../Menu/MenuGroup'; import { MenuItem } from '../Menu/MenuItem'; diff --git a/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinkEditorModalContent.tsx b/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinkEditorModalContent.tsx index 3d3a25fd749..3adecc87e0c 100644 --- a/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinkEditorModalContent.tsx +++ b/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinkEditorModalContent.tsx @@ -1,8 +1,10 @@ -import { DataFrame, DataLink, VariableSuggestion } from '@grafana/data'; import React, { FC, useState } from 'react'; -import { DataLinkEditor } from '../DataLinkEditor'; + +import { DataFrame, DataLink, VariableSuggestion } from '@grafana/data'; + import { Button } from '../../Button'; import { Modal } from '../../Modal/Modal'; +import { DataLinkEditor } from '../DataLinkEditor'; interface DataLinkEditorModalContentProps { link: DataLink; diff --git a/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksInlineEditor.tsx b/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksInlineEditor.tsx index c4e56940a23..c0db22200d1 100644 --- a/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksInlineEditor.tsx +++ b/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksInlineEditor.tsx @@ -1,12 +1,15 @@ -import { DataFrame, DataLink, GrafanaTheme2, VariableSuggestion } from '@grafana/data'; -import React, { useState } from 'react'; import { css } from '@emotion/css'; -import { Button } from '../../Button/Button'; import { cloneDeep } from 'lodash'; -import { Modal } from '../../Modal/Modal'; +import React, { useState } from 'react'; + +import { DataFrame, DataLink, GrafanaTheme2, VariableSuggestion } from '@grafana/data'; + import { stylesFactory, useTheme2 } from '../../../themes'; -import { DataLinksListItem } from './DataLinksListItem'; +import { Button } from '../../Button/Button'; +import { Modal } from '../../Modal/Modal'; + import { DataLinkEditorModalContent } from './DataLinkEditorModalContent'; +import { DataLinksListItem } from './DataLinksListItem'; interface DataLinksInlineEditorProps { links?: DataLink[]; diff --git a/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksListItem.test.tsx b/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksListItem.test.tsx index c2655b8d8a5..4e9d27d7f3d 100644 --- a/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksListItem.test.tsx +++ b/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksListItem.test.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; +import React from 'react'; + import { DataLinksListItem, DataLinksListItemProps } from './DataLinksListItem'; const baseLink = { diff --git a/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksListItem.tsx b/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksListItem.tsx index 5fc55c310a2..03fcfdd6623 100644 --- a/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksListItem.tsx +++ b/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksListItem.tsx @@ -1,9 +1,11 @@ -import React, { FC } from 'react'; import { css, cx } from '@emotion/css'; +import React, { FC } from 'react'; + import { DataFrame, DataLink, GrafanaTheme2 } from '@grafana/data'; + import { stylesFactory, useTheme2 } from '../../../themes'; -import { HorizontalGroup, VerticalGroup } from '../../Layout/Layout'; import { IconButton } from '../../IconButton/IconButton'; +import { HorizontalGroup, VerticalGroup } from '../../Layout/Layout'; export interface DataLinksListItemProps { index: number; diff --git a/packages/grafana-ui/src/components/DataLinks/FieldLinkList.tsx b/packages/grafana-ui/src/components/DataLinks/FieldLinkList.tsx index 0124ac5d74f..548131230d3 100644 --- a/packages/grafana-ui/src/components/DataLinks/FieldLinkList.tsx +++ b/packages/grafana-ui/src/components/DataLinks/FieldLinkList.tsx @@ -1,8 +1,11 @@ -import { Field, GrafanaTheme, LinkModel } from '@grafana/data'; import { css } from '@emotion/css'; import React from 'react'; + +import { Field, GrafanaTheme, LinkModel } from '@grafana/data'; + import { useStyles } from '../../themes'; import { Icon } from '../Icon/Icon'; + import { DataLinkButton } from './DataLinkButton'; type Props = { diff --git a/packages/grafana-ui/src/components/DataSourceSettings/AlertingSettings.tsx b/packages/grafana-ui/src/components/DataSourceSettings/AlertingSettings.tsx index 79135144cbd..ac2c050f512 100644 --- a/packages/grafana-ui/src/components/DataSourceSettings/AlertingSettings.tsx +++ b/packages/grafana-ui/src/components/DataSourceSettings/AlertingSettings.tsx @@ -1,8 +1,10 @@ -import { DataSourceInstanceSettings, DataSourceJsonData, DataSourcePluginOptionsEditorProps } from '@grafana/data'; import React, { useMemo } from 'react'; -import { Switch } from '../Forms/Legacy/Switch/Switch'; + +import { DataSourceInstanceSettings, DataSourceJsonData, DataSourcePluginOptionsEditorProps } from '@grafana/data'; + import { InlineField } from '../Forms/InlineField'; import { InlineFieldRow } from '../Forms/InlineFieldRow'; +import { Switch } from '../Forms/Legacy/Switch/Switch'; import { Select } from '../Select/Select'; interface Props extends Pick, 'options' | 'onOptionsChange'> { diff --git a/packages/grafana-ui/src/components/DataSourceSettings/BasicAuthSettings.tsx b/packages/grafana-ui/src/components/DataSourceSettings/BasicAuthSettings.tsx index e7459507628..4755f7cb59d 100644 --- a/packages/grafana-ui/src/components/DataSourceSettings/BasicAuthSettings.tsx +++ b/packages/grafana-ui/src/components/DataSourceSettings/BasicAuthSettings.tsx @@ -1,10 +1,11 @@ import React from 'react'; import { InlineField } from '../..'; -import { HttpSettingsProps } from './types'; import { FormField } from '../FormField/FormField'; import { SecretFormField } from '../SecretFormField/SecretFormField'; +import { HttpSettingsProps } from './types'; + export const BasicAuthSettings: React.FC = ({ dataSourceConfig, onChange }) => { const password = dataSourceConfig.secureJsonData ? dataSourceConfig.secureJsonData.basicAuthPassword : ''; diff --git a/packages/grafana-ui/src/components/DataSourceSettings/CertificationKey.tsx b/packages/grafana-ui/src/components/DataSourceSettings/CertificationKey.tsx index 56e238464a8..20b57fc6576 100644 --- a/packages/grafana-ui/src/components/DataSourceSettings/CertificationKey.tsx +++ b/packages/grafana-ui/src/components/DataSourceSettings/CertificationKey.tsx @@ -1,9 +1,10 @@ import React, { ChangeEvent, MouseEvent, FC } from 'react'; -import { Input } from '../Input/Input'; + import { Button } from '../Button'; -import { TextArea } from '../TextArea/TextArea'; import { InlineField } from '../Forms/InlineField'; import { InlineFieldRow } from '../Forms/InlineFieldRow'; +import { Input } from '../Input/Input'; +import { TextArea } from '../TextArea/TextArea'; interface Props { label: string; diff --git a/packages/grafana-ui/src/components/DataSourceSettings/CustomHeadersSettings.test.tsx b/packages/grafana-ui/src/components/DataSourceSettings/CustomHeadersSettings.test.tsx index 75dcefc6e2e..dc39d17f41b 100644 --- a/packages/grafana-ui/src/components/DataSourceSettings/CustomHeadersSettings.test.tsx +++ b/packages/grafana-ui/src/components/DataSourceSettings/CustomHeadersSettings.test.tsx @@ -1,7 +1,8 @@ -import React from 'react'; -import { CustomHeadersSettings, Props } from './CustomHeadersSettings'; import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import React from 'react'; + +import { CustomHeadersSettings, Props } from './CustomHeadersSettings'; const setup = (propOverrides?: object) => { const onChange = jest.fn(); diff --git a/packages/grafana-ui/src/components/DataSourceSettings/CustomHeadersSettings.tsx b/packages/grafana-ui/src/components/DataSourceSettings/CustomHeadersSettings.tsx index 586221ab2c4..ade08af90b7 100644 --- a/packages/grafana-ui/src/components/DataSourceSettings/CustomHeadersSettings.tsx +++ b/packages/grafana-ui/src/components/DataSourceSettings/CustomHeadersSettings.tsx @@ -1,12 +1,14 @@ -import React, { PureComponent } from 'react'; import { css } from '@emotion/css'; import { uniqueId } from 'lodash'; +import React, { PureComponent } from 'react'; + import { DataSourceSettings } from '@grafana/data'; + +import { stylesFactory } from '../../themes'; import { Button } from '../Button'; import { FormField } from '../FormField/FormField'; import { Icon } from '../Icon/Icon'; import { SecretFormField } from '../SecretFormField/SecretFormField'; -import { stylesFactory } from '../../themes'; export interface CustomHeader { id: string; diff --git a/packages/grafana-ui/src/components/DataSourceSettings/DataSourceHttpSettings.story.tsx b/packages/grafana-ui/src/components/DataSourceSettings/DataSourceHttpSettings.story.tsx index 913cf939838..17ebfcc7b66 100644 --- a/packages/grafana-ui/src/components/DataSourceSettings/DataSourceHttpSettings.story.tsx +++ b/packages/grafana-ui/src/components/DataSourceSettings/DataSourceHttpSettings.story.tsx @@ -1,8 +1,10 @@ import React from 'react'; + import { DataSourceSettings } from '@grafana/data'; -import { DataSourceHttpSettings } from './DataSourceHttpSettings'; import { UseState } from '../../utils/storybook/UseState'; + +import { DataSourceHttpSettings } from './DataSourceHttpSettings'; import mdx from './DataSourceHttpSettings.mdx'; const settingsMock: DataSourceSettings = { diff --git a/packages/grafana-ui/src/components/DataSourceSettings/DataSourceHttpSettings.tsx b/packages/grafana-ui/src/components/DataSourceSettings/DataSourceHttpSettings.tsx index 6e44460f34f..9cf6da6aba2 100644 --- a/packages/grafana-ui/src/components/DataSourceSettings/DataSourceHttpSettings.tsx +++ b/packages/grafana-ui/src/components/DataSourceSettings/DataSourceHttpSettings.tsx @@ -1,20 +1,23 @@ -import React, { useState, useCallback } from 'react'; import { css, cx } from '@emotion/css'; +import React, { useState, useCallback } from 'react'; + import { DataSourceSettings, SelectableValue } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; -import { BasicAuthSettings } from './BasicAuthSettings'; -import { HttpProxySettings } from './HttpProxySettings'; -import { TLSAuthSettings } from './TLSAuthSettings'; -import { CustomHeadersSettings } from './CustomHeadersSettings'; -import { Select } from '../Select/Select'; + +import { useTheme } from '../../themes'; +import { FormField } from '../FormField/FormField'; +import { InlineFormLabel } from '../FormLabel/FormLabel'; import { Input } from '../Forms/Legacy/Input/Input'; import { Switch } from '../Forms/Legacy/Switch/Switch'; import { Icon } from '../Icon/Icon'; -import { FormField } from '../FormField/FormField'; -import { InlineFormLabel } from '../FormLabel/FormLabel'; +import { Select } from '../Select/Select'; import { TagsInput } from '../TagsInput/TagsInput'; + +import { BasicAuthSettings } from './BasicAuthSettings'; +import { CustomHeadersSettings } from './CustomHeadersSettings'; +import { HttpProxySettings } from './HttpProxySettings'; import { SigV4AuthSettings } from './SigV4AuthSettings'; -import { useTheme } from '../../themes'; +import { TLSAuthSettings } from './TLSAuthSettings'; import { HttpSettingsProps } from './types'; const ACCESS_OPTIONS: Array> = [ diff --git a/packages/grafana-ui/src/components/DataSourceSettings/HttpProxySettings.tsx b/packages/grafana-ui/src/components/DataSourceSettings/HttpProxySettings.tsx index 4441672d276..07ab46edec3 100644 --- a/packages/grafana-ui/src/components/DataSourceSettings/HttpProxySettings.tsx +++ b/packages/grafana-ui/src/components/DataSourceSettings/HttpProxySettings.tsx @@ -1,7 +1,9 @@ import React from 'react'; -import { HttpSettingsBaseProps } from './types'; + import { Switch } from '../Forms/Legacy/Switch/Switch'; +import { HttpSettingsBaseProps } from './types'; + export const HttpProxySettings: React.FC = ({ dataSourceConfig, onChange, diff --git a/packages/grafana-ui/src/components/DataSourceSettings/SigV4AuthSettings.tsx b/packages/grafana-ui/src/components/DataSourceSettings/SigV4AuthSettings.tsx index d7ce2687278..965721d9fc1 100644 --- a/packages/grafana-ui/src/components/DataSourceSettings/SigV4AuthSettings.tsx +++ b/packages/grafana-ui/src/components/DataSourceSettings/SigV4AuthSettings.tsx @@ -1,12 +1,14 @@ import React from 'react'; -import { HttpSettingsBaseProps } from './types'; -import { DataSourceSettings } from '@grafana/data'; + import { AwsAuthDataSourceSecureJsonData, AwsAuthDataSourceJsonData, ConnectionConfig, ConnectionConfigProps, } from '@grafana/aws-sdk'; +import { DataSourceSettings } from '@grafana/data'; + +import { HttpSettingsBaseProps } from './types'; export const SigV4AuthSettings: React.FC = (props) => { const { dataSourceConfig, onChange } = props; diff --git a/packages/grafana-ui/src/components/DataSourceSettings/TLSAuthSettings.tsx b/packages/grafana-ui/src/components/DataSourceSettings/TLSAuthSettings.tsx index 73b42b0206c..9c29706f0c0 100644 --- a/packages/grafana-ui/src/components/DataSourceSettings/TLSAuthSettings.tsx +++ b/packages/grafana-ui/src/components/DataSourceSettings/TLSAuthSettings.tsx @@ -1,11 +1,14 @@ -import React from 'react'; -import { KeyValue } from '@grafana/data'; import { css, cx } from '@emotion/css'; -import { Tooltip } from '../Tooltip/Tooltip'; +import React from 'react'; + +import { KeyValue } from '@grafana/data'; + +import { FormField } from '../FormField/FormField'; import { Icon } from '../Icon/Icon'; +import { Tooltip } from '../Tooltip/Tooltip'; + import { CertificationKey } from './CertificationKey'; import { HttpSettingsBaseProps } from './types'; -import { FormField } from '../FormField/FormField'; export const TLSAuthSettings: React.FC = ({ dataSourceConfig, onChange }) => { const hasTLSCACert = dataSourceConfig.secureJsonFields && dataSourceConfig.secureJsonFields.tlsCACert; diff --git a/packages/grafana-ui/src/components/DataSourceSettings/types.ts b/packages/grafana-ui/src/components/DataSourceSettings/types.ts index ae71ad191d5..c5c2cc4789a 100644 --- a/packages/grafana-ui/src/components/DataSourceSettings/types.ts +++ b/packages/grafana-ui/src/components/DataSourceSettings/types.ts @@ -1,4 +1,5 @@ import React from 'react'; + import { DataSourceSettings } from '@grafana/data'; export interface AzureAuthSettings { diff --git a/packages/grafana-ui/src/components/DateTimePickers/DatePicker/DatePicker.story.tsx b/packages/grafana-ui/src/components/DateTimePickers/DatePicker/DatePicker.story.tsx index be64460e183..eca86234fb9 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/DatePicker/DatePicker.story.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/DatePicker/DatePicker.story.tsx @@ -1,8 +1,10 @@ import React, { useState } from 'react'; -import { DatePicker } from './DatePicker'; -import { Button } from '../../Button/Button'; -import mdx from './DatePicker.mdx'; + import { withCenteredStory } from '../../../utils/storybook/withCenteredStory'; +import { Button } from '../../Button/Button'; + +import { DatePicker } from './DatePicker'; +import mdx from './DatePicker.mdx'; export default { title: 'Pickers and Editors/TimePickers/Pickers And Editors/DatePicker', diff --git a/packages/grafana-ui/src/components/DateTimePickers/DatePicker/DatePicker.test.tsx b/packages/grafana-ui/src/components/DateTimePickers/DatePicker/DatePicker.test.tsx index 61b56adfcd9..7ee7671bcc8 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/DatePicker/DatePicker.test.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/DatePicker/DatePicker.test.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { fireEvent, render, screen } from '@testing-library/react'; +import React from 'react'; + import { DatePicker } from './DatePicker'; describe('DatePicker', () => { diff --git a/packages/grafana-ui/src/components/DateTimePickers/DatePicker/DatePicker.tsx b/packages/grafana-ui/src/components/DateTimePickers/DatePicker/DatePicker.tsx index 7fdc9dba1a0..8e2397df452 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/DatePicker/DatePicker.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/DatePicker/DatePicker.tsx @@ -1,7 +1,9 @@ +import { css } from '@emotion/css'; import React, { memo } from 'react'; import Calendar from 'react-calendar'; -import { css } from '@emotion/css'; + import { GrafanaTheme2 } from '@grafana/data'; + import { useStyles2 } from '../../../themes'; import { ClickOutsideWrapper } from '../../ClickOutsideWrapper/ClickOutsideWrapper'; import { Icon } from '../../Icon/Icon'; diff --git a/packages/grafana-ui/src/components/DateTimePickers/DatePickerWithInput/DatePickerWithInput.story.tsx b/packages/grafana-ui/src/components/DateTimePickers/DatePickerWithInput/DatePickerWithInput.story.tsx index 4fe461cc117..2ccd0ee3121 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/DatePickerWithInput/DatePickerWithInput.story.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/DatePickerWithInput/DatePickerWithInput.story.tsx @@ -1,6 +1,8 @@ import React, { useState } from 'react'; -import { DatePickerWithInput } from './DatePickerWithInput'; + import { withCenteredStory } from '../../../utils/storybook/withCenteredStory'; + +import { DatePickerWithInput } from './DatePickerWithInput'; import mdx from './DatePickerWithInput.mdx'; export default { diff --git a/packages/grafana-ui/src/components/DateTimePickers/DatePickerWithInput/DatePickerWithInput.test.tsx b/packages/grafana-ui/src/components/DateTimePickers/DatePickerWithInput/DatePickerWithInput.test.tsx index e80823e91f9..f67bedfd45c 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/DatePickerWithInput/DatePickerWithInput.test.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/DatePickerWithInput/DatePickerWithInput.test.tsx @@ -1,8 +1,10 @@ -import React from 'react'; import { fireEvent, render, screen } from '@testing-library/react'; -import { DatePickerWithInput } from './DatePickerWithInput'; +import React from 'react'; + import { dateTimeFormat } from '@grafana/data'; +import { DatePickerWithInput } from './DatePickerWithInput'; + describe('DatePickerWithInput', () => { it('renders date input', () => { render(); diff --git a/packages/grafana-ui/src/components/DateTimePickers/DatePickerWithInput/DatePickerWithInput.tsx b/packages/grafana-ui/src/components/DateTimePickers/DatePickerWithInput/DatePickerWithInput.tsx index ea76baa8bab..ac924d7be24 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/DatePickerWithInput/DatePickerWithInput.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/DatePickerWithInput/DatePickerWithInput.tsx @@ -1,9 +1,11 @@ -import React, { ChangeEvent } from 'react'; import { css } from '@emotion/css'; +import React, { ChangeEvent } from 'react'; + import { dateTime } from '@grafana/data'; -import { DatePicker } from '../DatePicker/DatePicker'; -import { Props as InputProps, Input } from '../../Input/Input'; + import { useStyles } from '../../../themes'; +import { Props as InputProps, Input } from '../../Input/Input'; +import { DatePicker } from '../DatePicker/DatePicker'; export const formatDate = (date: Date | string) => dateTime(date).format('L'); diff --git a/packages/grafana-ui/src/components/DateTimePickers/DateTimePicker/DateTimePicker.story.tsx b/packages/grafana-ui/src/components/DateTimePickers/DateTimePicker/DateTimePicker.story.tsx index 0e005d42a6d..ac6a6500eeb 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/DateTimePicker/DateTimePicker.story.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/DateTimePicker/DateTimePicker.story.tsx @@ -1,8 +1,11 @@ -import React, { useState } from 'react'; import { Story, Meta } from '@storybook/react'; +import React, { useState } from 'react'; + import { dateTime, DateTime } from '@grafana/data'; -import { DateTimePicker, Props } from './DateTimePicker'; + import { withCenteredStory } from '../../../utils/storybook/withCenteredStory'; + +import { DateTimePicker, Props } from './DateTimePicker'; import mdx from './DateTimePicker.mdx'; export default { diff --git a/packages/grafana-ui/src/components/DateTimePickers/DateTimePicker/DateTimePicker.test.tsx b/packages/grafana-ui/src/components/DateTimePickers/DateTimePicker/DateTimePicker.test.tsx index 526abef54fb..15e65ffe738 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/DateTimePicker/DateTimePicker.test.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/DateTimePicker/DateTimePicker.test.tsx @@ -1,6 +1,8 @@ -import React from 'react'; import { fireEvent, render, screen } from '@testing-library/react'; +import React from 'react'; + import { dateTime } from '@grafana/data'; + import { DateTimePicker, Props } from './DateTimePicker'; const renderDatetimePicker = (props?: Props) => { diff --git a/packages/grafana-ui/src/components/DateTimePickers/DateTimePicker/DateTimePicker.tsx b/packages/grafana-ui/src/components/DateTimePickers/DateTimePicker/DateTimePicker.tsx index e375170e4b8..b94b60fa7f4 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/DateTimePicker/DateTimePicker.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/DateTimePicker/DateTimePicker.tsx @@ -1,14 +1,16 @@ -import React, { FC, FormEvent, ReactNode, useCallback, useEffect, useState } from 'react'; -import { useMedia } from 'react-use'; -import Calendar from 'react-calendar'; import { css, cx } from '@emotion/css'; +import React, { FC, FormEvent, ReactNode, useCallback, useEffect, useState } from 'react'; +import Calendar from 'react-calendar'; +import { useMedia } from 'react-use'; + import { dateTimeFormat, DateTime, dateTime, GrafanaTheme2, isDateTime } from '@grafana/data'; + import { Button, ClickOutsideWrapper, HorizontalGroup, Icon, InlineField, Input, Portal } from '../..'; -import { TimeOfDayPicker } from '../TimeOfDayPicker'; -import { getStyles as getCalendarStyles } from '../TimeRangePicker/TimePickerCalendar'; import { useStyles2, useTheme2 } from '../../../themes'; -import { isValid } from '../utils'; +import { TimeOfDayPicker } from '../TimeOfDayPicker'; import { getBodyStyles } from '../TimeRangePicker/CalendarBody'; +import { getStyles as getCalendarStyles } from '../TimeRangePicker/TimePickerCalendar'; +import { isValid } from '../utils'; export interface Props { /** Input date for the component */ diff --git a/packages/grafana-ui/src/components/DateTimePickers/RelativeTimeRangePicker/RelativeTimeRangePicker.story.tsx b/packages/grafana-ui/src/components/DateTimePickers/RelativeTimeRangePicker/RelativeTimeRangePicker.story.tsx index dadccfb4865..c726f5f86c6 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/RelativeTimeRangePicker/RelativeTimeRangePicker.story.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/RelativeTimeRangePicker/RelativeTimeRangePicker.story.tsx @@ -1,7 +1,9 @@ -import React from 'react'; import { action } from '@storybook/addon-actions'; +import React from 'react'; + import { UseState } from '../../../utils/storybook/UseState'; import { withCenteredStory } from '../../../utils/storybook/withCenteredStory'; + import { RelativeTimeRangePicker } from './RelativeTimeRangePicker'; export default { diff --git a/packages/grafana-ui/src/components/DateTimePickers/RelativeTimeRangePicker/RelativeTimeRangePicker.test.tsx b/packages/grafana-ui/src/components/DateTimePickers/RelativeTimeRangePicker/RelativeTimeRangePicker.test.tsx index 5f29941476e..635d906a6f0 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/RelativeTimeRangePicker/RelativeTimeRangePicker.test.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/RelativeTimeRangePicker/RelativeTimeRangePicker.test.tsx @@ -1,8 +1,10 @@ -import React, { useState } from 'react'; import { render, fireEvent, RenderResult } from '@testing-library/react'; -import { RelativeTimeRangePicker } from './RelativeTimeRangePicker'; +import React, { useState } from 'react'; + import { RelativeTimeRange } from '@grafana/data'; +import { RelativeTimeRangePicker } from './RelativeTimeRangePicker'; + function setup(initial: RelativeTimeRange = { from: 900, to: 0 }): RenderResult { const StatefulPicker: React.FC<{}> = () => { const [value, setValue] = useState(initial); diff --git a/packages/grafana-ui/src/components/DateTimePickers/RelativeTimeRangePicker/RelativeTimeRangePicker.tsx b/packages/grafana-ui/src/components/DateTimePickers/RelativeTimeRangePicker/RelativeTimeRangePicker.tsx index 02f7945ceb5..26a97a28b48 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/RelativeTimeRangePicker/RelativeTimeRangePicker.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/RelativeTimeRangePicker/RelativeTimeRangePicker.tsx @@ -1,13 +1,20 @@ -import React, { FormEvent, ReactElement, useCallback, useState } from 'react'; import { css, cx } from '@emotion/css'; +import React, { FormEvent, ReactElement, useCallback, useState } from 'react'; + import { RelativeTimeRange, GrafanaTheme2, TimeOption } from '@grafana/data'; + import { useStyles2 } from '../../../themes'; import { Button } from '../../Button'; import { ClickOutsideWrapper } from '../../ClickOutsideWrapper/ClickOutsideWrapper'; +import CustomScrollbar from '../../CustomScrollbar/CustomScrollbar'; +import { Field } from '../../Forms/Field'; +import { Icon } from '../../Icon/Icon'; +import { getInputStyles, Input } from '../../Input/Input'; +import { Tooltip } from '../../Tooltip/Tooltip'; +import { TimePickerTitle } from '../TimeRangePicker/TimePickerTitle'; import { TimeRangeList } from '../TimeRangePicker/TimeRangeList'; import { quickOptions } from '../options'; -import CustomScrollbar from '../../CustomScrollbar/CustomScrollbar'; -import { TimePickerTitle } from '../TimeRangePicker/TimePickerTitle'; + import { isRangeValid, isRelativeFormat, @@ -15,10 +22,6 @@ import { mapRelativeTimeRangeToOption, RangeValidation, } from './utils'; -import { Field } from '../../Forms/Field'; -import { getInputStyles, Input } from '../../Input/Input'; -import { Icon } from '../../Icon/Icon'; -import { Tooltip } from '../../Tooltip/Tooltip'; /** * @internal diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeOfDayPicker.story.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeOfDayPicker.story.tsx index 70d201883ab..72d768b27b1 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeOfDayPicker.story.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeOfDayPicker.story.tsx @@ -1,10 +1,11 @@ -import React from 'react'; import { action } from '@storybook/addon-actions'; +import React from 'react'; +import { dateTime } from '@grafana/data'; import { TimeOfDayPicker } from '@grafana/ui'; + import { UseState } from '../../utils/storybook/UseState'; import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; -import { dateTime } from '@grafana/data'; export default { title: 'Pickers and Editors/TimePickers/TimeOfDayPicker', diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeOfDayPicker.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeOfDayPicker.tsx index 673426766c6..6d5bc4a2732 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeOfDayPicker.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeOfDayPicker.tsx @@ -1,12 +1,14 @@ -import React, { FC } from 'react'; -import RcTimePicker from 'rc-time-picker'; import { css, cx } from '@emotion/css'; +import RcTimePicker from 'rc-time-picker'; +import React, { FC } from 'react'; + import { dateTime, DateTime, dateTimeAsMoment, GrafanaTheme } from '@grafana/data'; + import { Icon, useStyles } from '../../index'; import { stylesFactory } from '../../themes'; +import { focusCss } from '../../themes/mixins'; import { inputSizes } from '../Forms/commonStyles'; import { FormInputSize } from '../Forms/types'; -import { focusCss } from '../../themes/mixins'; export interface Props { onChange: (value: DateTime) => void; diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangeInput.story.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangeInput.story.tsx index 419c25cc564..36706e2ad7b 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangeInput.story.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangeInput.story.tsx @@ -1,10 +1,13 @@ +import { action } from '@storybook/addon-actions'; import { Story } from '@storybook/react'; import React from 'react'; -import { action } from '@storybook/addon-actions'; + import { dateTime, DefaultTimeZone, TimeRange, TimeZone } from '@grafana/data'; -import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; -import { UseState } from '../../utils/storybook/UseState'; import { TimeRangeInput } from '@grafana/ui'; + +import { UseState } from '../../utils/storybook/UseState'; +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; + import { TimeRangeInputProps } from './TimeRangeInput'; import mdx from './TimeRangeInput.mdx'; diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangeInput.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangeInput.tsx index f946c588b25..f934ed4a7eb 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangeInput.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangeInput.tsx @@ -1,15 +1,18 @@ -import React, { FC, FormEvent, MouseEvent, useState } from 'react'; import { css, cx } from '@emotion/css'; +import React, { FC, FormEvent, MouseEvent, useState } from 'react'; + import { dateMath, dateTime, getDefaultTimeRange, GrafanaTheme2, TimeRange, TimeZone } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; + +import { stylesFactory } from '../../themes'; import { useTheme2 } from '../../themes/ThemeContext'; import { ClickOutsideWrapper } from '../ClickOutsideWrapper/ClickOutsideWrapper'; import { Icon } from '../Icon/Icon'; import { getInputStyles } from '../Input/Input'; + import { TimePickerButtonLabel } from './TimeRangePicker'; import { TimePickerContent } from './TimeRangePicker/TimePickerContent'; import { quickOptions } from './options'; -import { selectors } from '@grafana/e2e-selectors'; -import { stylesFactory } from '../../themes'; const isValidTimeRange = (range: any) => { return dateMath.isValid(range.from) && dateMath.isValid(range.to); diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.story.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.story.tsx index a08fd639a8c..7ca94e6aab2 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.story.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.story.tsx @@ -1,15 +1,17 @@ +import { action } from '@storybook/addon-actions'; import { Story } from '@storybook/react'; import React from 'react'; -import { action } from '@storybook/addon-actions'; +import { dateTime, TimeRange, DefaultTimeZone, TimeZone, isDateTime } from '@grafana/data'; import { Button, TimeRangePicker } from '@grafana/ui'; + +import { DashboardStoryCanvas } from '../../utils/storybook/DashboardStoryCanvas'; import { UseState } from '../../utils/storybook/UseState'; import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; -import { dateTime, TimeRange, DefaultTimeZone, TimeZone, isDateTime } from '@grafana/data'; -import { TimeRangePickerProps } from './TimeRangePicker'; -import { DashboardStoryCanvas } from '../../utils/storybook/DashboardStoryCanvas'; import { HorizontalGroup, VerticalGroup } from '../Layout/Layout'; +import { TimeRangePickerProps } from './TimeRangePicker'; + export default { title: 'Pickers and Editors/TimePickers/TimeRangePicker', component: TimeRangePicker, diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.test.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.test.tsx index 12aeb15caa2..f3ac08567ab 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.test.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.test.tsx @@ -1,6 +1,8 @@ -import { createTheme, dateTime, TimeRange } from '@grafana/data'; import { render } from '@testing-library/react'; import React from 'react'; + +import { createTheme, dateTime, TimeRange } from '@grafana/data'; + import { UnthemedTimeRangePicker } from './TimeRangePicker'; const from = dateTime('2019-12-17T07:48:27.433Z'); diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.tsx index 449e905e3e1..375650c9fa3 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.tsx @@ -1,16 +1,9 @@ -// Libraries -import React, { memo, FormEvent, createRef, useState, ReactElement } from 'react'; import { css } from '@emotion/css'; +import { useDialog } from '@react-aria/dialog'; +import { FocusScope } from '@react-aria/focus'; +import { useOverlay } from '@react-aria/overlays'; +import React, { memo, FormEvent, createRef, useState, ReactElement } from 'react'; -// Components -import { Tooltip } from '../Tooltip/Tooltip'; -import { TimePickerContent } from './TimeRangePicker/TimePickerContent'; - -// Utils & Services -import { stylesFactory } from '../../themes/stylesFactory'; -import { withTheme, useTheme } from '../../themes/ThemeContext'; - -// Types import { isDateTime, rangeUtil, @@ -21,13 +14,16 @@ import { TimeZone, dateMath, } from '@grafana/data'; -import { Themeable } from '../../types'; -import { quickOptions } from './options'; -import { ButtonGroup, ToolbarButton } from '../Button'; import { selectors } from '@grafana/e2e-selectors'; -import { useDialog } from '@react-aria/dialog'; -import { useOverlay } from '@react-aria/overlays'; -import { FocusScope } from '@react-aria/focus'; + +import { withTheme, useTheme } from '../../themes/ThemeContext'; +import { stylesFactory } from '../../themes/stylesFactory'; +import { Themeable } from '../../types'; +import { ButtonGroup, ToolbarButton } from '../Button'; +import { Tooltip } from '../Tooltip/Tooltip'; + +import { TimePickerContent } from './TimeRangePicker/TimePickerContent'; +import { quickOptions } from './options'; /** @public */ export interface TimeRangePickerProps extends Themeable { diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/CalendarBody.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/CalendarBody.tsx index d561b68f31d..fdc684547d3 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/CalendarBody.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/CalendarBody.tsx @@ -1,11 +1,14 @@ -import React, { useCallback } from 'react'; -import { useStyles2 } from '../../../themes'; -import Calendar from 'react-calendar'; import { css } from '@emotion/css'; -import { Icon } from '../../Icon/Icon'; -import { TimePickerCalendarProps } from './TimePickerCalendar'; +import React, { useCallback } from 'react'; +import Calendar from 'react-calendar'; + import { GrafanaTheme2, dateTime, dateTimeParse, DateTime, TimeZone } from '@grafana/data'; +import { useStyles2 } from '../../../themes'; +import { Icon } from '../../Icon/Icon'; + +import { TimePickerCalendarProps } from './TimePickerCalendar'; + export function Body({ onChange, from, to, timeZone }: TimePickerCalendarProps) { const value = inputToValue(from, to); const onCalendarChange = useOnCalendarChange(onChange, timeZone); diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/CalendarFooter.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/CalendarFooter.tsx index e12dfbda9e8..59d54f6020e 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/CalendarFooter.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/CalendarFooter.tsx @@ -1,8 +1,11 @@ +import { css } from '@emotion/css'; import React from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; + import { useStyles2 } from '../../../themes'; import { Button } from '../../Button'; -import { css } from '@emotion/css'; -import { GrafanaTheme2 } from '@grafana/data'; + import { TimePickerCalendarProps } from './TimePickerCalendar'; export function Footer({ onClose, onApply }: TimePickerCalendarProps) { diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/CalendarHeader.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/CalendarHeader.tsx index 87ac740e560..e8ea6d9a0cf 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/CalendarHeader.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/CalendarHeader.tsx @@ -1,11 +1,14 @@ -import React from 'react'; -import { TimePickerTitle } from './TimePickerTitle'; -import { Button } from '../../Button'; -import { selectors } from '@grafana/e2e-selectors'; -import { TimePickerCalendarProps } from './TimePickerCalendar'; -import { useStyles2 } from '../../../themes'; -import { GrafanaTheme2 } from '@grafana/data'; import { css } from '@emotion/css'; +import React from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; + +import { useStyles2 } from '../../../themes'; +import { Button } from '../../Button'; + +import { TimePickerCalendarProps } from './TimePickerCalendar'; +import { TimePickerTitle } from './TimePickerTitle'; export function Header({ onClose }: TimePickerCalendarProps) { const styles = useStyles2(getHeaderStyles); diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerCalendar.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerCalendar.tsx index 27ecce05cd9..826707a4cbc 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerCalendar.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerCalendar.tsx @@ -1,14 +1,17 @@ -import React, { FormEvent, memo } from 'react'; import { css } from '@emotion/css'; -import { DateTime, GrafanaTheme2, TimeZone } from '@grafana/data'; -import { useTheme2 } from '../../../themes'; -import { Header } from './CalendarHeader'; -import { selectors } from '@grafana/e2e-selectors'; import { useDialog } from '@react-aria/dialog'; import { FocusScope } from '@react-aria/focus'; import { OverlayContainer, useOverlay } from '@react-aria/overlays'; +import React, { FormEvent, memo } from 'react'; + +import { DateTime, GrafanaTheme2, TimeZone } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; + +import { useTheme2 } from '../../../themes'; + import { Body } from './CalendarBody'; import { Footer } from './CalendarFooter'; +import { Header } from './CalendarHeader'; export const getStyles = (theme: GrafanaTheme2, isReversed = false) => { return { diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerContent.test.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerContent.test.tsx index 07d0fafb57b..40d9dc2b693 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerContent.test.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerContent.test.tsx @@ -1,6 +1,8 @@ -import { dateTime, TimeRange } from '@grafana/data'; import { render, RenderResult, screen } from '@testing-library/react'; import React from 'react'; + +import { dateTime, TimeRange } from '@grafana/data'; + import { PropsWithScreenSize, TimePickerContentWithScreenSize } from './TimePickerContent'; describe('TimePickerContent', () => { diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerContent.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerContent.tsx index f3a3dd0d406..2a7ca635dc3 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerContent.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerContent.tsx @@ -1,17 +1,20 @@ -import { GrafanaTheme2, isDateTime, rangeUtil, RawTimeRange, TimeOption, TimeRange, TimeZone } from '@grafana/data'; import { css, cx } from '@emotion/css'; import React, { memo, useMemo, useState } from 'react'; + +import { GrafanaTheme2, isDateTime, rangeUtil, RawTimeRange, TimeOption, TimeRange, TimeZone } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; + +import { FilterInput } from '../..'; import { stylesFactory, useTheme2 } from '../../../themes'; +import { getFocusStyles } from '../../../themes/mixins'; import { CustomScrollbar } from '../../CustomScrollbar/CustomScrollbar'; import { Icon } from '../../Icon/Icon'; -import { mapOptionToTimeRange, mapRangeToTimeOption } from './mapper'; + +import { TimePickerFooter } from './TimePickerFooter'; import { TimePickerTitle } from './TimePickerTitle'; import { TimeRangeForm } from './TimeRangeForm'; import { TimeRangeList } from './TimeRangeList'; -import { TimePickerFooter } from './TimePickerFooter'; -import { getFocusStyles } from '../../../themes/mixins'; -import { selectors } from '@grafana/e2e-selectors'; -import { FilterInput } from '../..'; +import { mapOptionToTimeRange, mapRangeToTimeOption } from './mapper'; interface Props { value: TimeRange; diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerFooter.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerFooter.tsx index 1f605ee5629..faead588eb3 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerFooter.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerFooter.tsx @@ -1,15 +1,17 @@ -import React, { FC, useCallback, useState } from 'react'; import { css, cx } from '@emotion/css'; +import { isString } from 'lodash'; +import React, { FC, useCallback, useState } from 'react'; + import { getTimeZoneInfo, GrafanaTheme2, TimeZone } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; + +import { Field, RadioButtonGroup, Select } from '../..'; import { stylesFactory, useTheme2 } from '../../../themes'; -import { TimeZoneTitle } from '../TimeZonePicker/TimeZoneTitle'; -import { TimeZoneDescription } from '../TimeZonePicker/TimeZoneDescription'; -import { TimeZoneOffset } from '../TimeZonePicker/TimeZoneOffset'; import { Button } from '../../Button'; import { TimeZonePicker } from '../TimeZonePicker'; -import { isString } from 'lodash'; -import { selectors } from '@grafana/e2e-selectors'; -import { Field, RadioButtonGroup, Select } from '../..'; +import { TimeZoneDescription } from '../TimeZonePicker/TimeZoneDescription'; +import { TimeZoneOffset } from '../TimeZonePicker/TimeZoneOffset'; +import { TimeZoneTitle } from '../TimeZonePicker/TimeZoneTitle'; import { monthOptions } from '../options'; interface Props { diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerTitle.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerTitle.tsx index 1fa12216e7b..20bf4d120f3 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerTitle.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerTitle.tsx @@ -1,6 +1,8 @@ -import React, { memo, PropsWithChildren } from 'react'; import { css } from '@emotion/css'; +import React, { memo, PropsWithChildren } from 'react'; + import { GrafanaTheme } from '@grafana/data'; + import { useTheme, stylesFactory } from '../../../themes'; const getStyle = stylesFactory((theme: GrafanaTheme) => { diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeForm.test.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeForm.test.tsx index 57c6cfab340..d67f44b2ec0 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeForm.test.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeForm.test.tsx @@ -1,9 +1,11 @@ -import React from 'react'; import { fireEvent, render, RenderResult } from '@testing-library/react'; +import React from 'react'; + import { dateTimeParse, TimeRange } from '@grafana/data'; -import { TimeRangeForm } from './TimeRangeForm'; import { selectors } from '@grafana/e2e-selectors'; +import { TimeRangeForm } from './TimeRangeForm'; + type TimeRangeFormRenderResult = RenderResult & { getCalendarDayByLabelText(label: string): HTMLButtonElement; }; diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeForm.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeForm.tsx index 904a26f760b..60c1584af2a 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeForm.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeForm.tsx @@ -1,4 +1,6 @@ import { css } from '@emotion/css'; +import React, { FormEvent, useCallback, useEffect, useState } from 'react'; + import { dateMath, DateTime, @@ -12,12 +14,13 @@ import { TimeZone, } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; -import React, { FormEvent, useCallback, useEffect, useState } from 'react'; + import { Icon, Tooltip } from '../..'; import { useStyles2 } from '../../..'; import { Button } from '../../Button'; import { Field } from '../../Forms/Field'; import { Input } from '../../Input/Input'; + import TimePickerCalendar from './TimePickerCalendar'; interface Props { diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeList.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeList.tsx index f6ad8eed76e..71d2cf2d26b 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeList.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeList.tsx @@ -1,9 +1,12 @@ -import React, { ReactNode } from 'react'; import { css } from '@emotion/css'; +import React, { ReactNode } from 'react'; + import { TimeOption } from '@grafana/data'; + +import { stylesFactory } from '../../../themes'; + import { TimePickerTitle } from './TimePickerTitle'; import { TimeRangeOption } from './TimeRangeOption'; -import { stylesFactory } from '../../../themes'; const getStyles = stylesFactory(() => { return { diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeOption.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeOption.tsx index 14627ea9589..5a9d11c8e9a 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeOption.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeOption.tsx @@ -1,9 +1,11 @@ -import React, { memo } from 'react'; import { css, cx } from '@emotion/css'; +import React, { memo } from 'react'; +import { v4 as uuidv4 } from 'uuid'; + import { GrafanaTheme2, TimeOption } from '@grafana/data'; + import { useStyles2 } from '../../../themes/ThemeContext'; import { getFocusStyles } from '../../../themes/mixins'; -import { v4 as uuidv4 } from 'uuid'; const getStyles = (theme: GrafanaTheme2) => { return { diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeZonePicker.story.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeZonePicker.story.tsx index 56dd301bdc6..b476337e708 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeZonePicker.story.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeZonePicker.story.tsx @@ -1,7 +1,8 @@ -import React from 'react'; import { action } from '@storybook/addon-actions'; +import React from 'react'; import { TimeZonePicker } from '@grafana/ui'; + import { UseState } from '../../utils/storybook/UseState'; import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeZonePicker.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeZonePicker.tsx index badc806f9d7..8fc52be3cef 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeZonePicker.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeZonePicker.tsx @@ -1,5 +1,6 @@ -import React, { useMemo, useCallback } from 'react'; import { toLower, isEmpty, isString } from 'lodash'; +import React, { useMemo, useCallback } from 'react'; + import { SelectableValue, getTimeZoneInfo, @@ -9,10 +10,12 @@ import { TimeZone, InternalTimeZones, } from '@grafana/data'; + import { Select } from '../Select/Select'; -import { CompactTimeZoneOption, WideTimeZoneOption, SelectableZone } from './TimeZonePicker/TimeZoneOption'; + import { TimeZoneGroup } from './TimeZonePicker/TimeZoneGroup'; import { formatUtcOffset } from './TimeZonePicker/TimeZoneOffset'; +import { CompactTimeZoneOption, WideTimeZoneOption, SelectableZone } from './TimeZonePicker/TimeZoneOption'; export interface Props { onChange: (timeZone?: TimeZone) => void; diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeZonePicker/TimeZoneDescription.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeZonePicker/TimeZoneDescription.tsx index 8d4a173ed52..fbfb016ccdf 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeZonePicker/TimeZoneDescription.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeZonePicker/TimeZoneDescription.tsx @@ -1,6 +1,8 @@ -import React, { PropsWithChildren, useMemo } from 'react'; import { css } from '@emotion/css'; +import React, { PropsWithChildren, useMemo } from 'react'; + import { GrafanaTheme, TimeZoneInfo } from '@grafana/data'; + import { useTheme, stylesFactory } from '../../../themes'; interface Props { diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeZonePicker/TimeZoneGroup.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeZonePicker/TimeZoneGroup.tsx index 68060b2d14a..faa416d6afa 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeZonePicker/TimeZoneGroup.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeZonePicker/TimeZoneGroup.tsx @@ -1,6 +1,8 @@ -import React, { PropsWithChildren } from 'react'; import { css } from '@emotion/css'; +import React, { PropsWithChildren } from 'react'; + import { GrafanaTheme } from '@grafana/data'; + import { useTheme, stylesFactory } from '../../../themes'; interface Props { diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeZonePicker/TimeZoneOffset.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeZonePicker/TimeZoneOffset.tsx index 742a5cdd65f..5904f99899c 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeZonePicker/TimeZoneOffset.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeZonePicker/TimeZoneOffset.tsx @@ -1,8 +1,10 @@ -import React, { PropsWithChildren } from 'react'; import { css, cx } from '@emotion/css'; -import { GrafanaTheme, TimeZone, dateTimeFormat } from '@grafana/data'; -import { useTheme, stylesFactory } from '../../../themes'; import { isString } from 'lodash'; +import React, { PropsWithChildren } from 'react'; + +import { GrafanaTheme, TimeZone, dateTimeFormat } from '@grafana/data'; + +import { useTheme, stylesFactory } from '../../../themes'; interface Props { timestamp: number; diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeZonePicker/TimeZoneOption.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeZonePicker/TimeZoneOption.tsx index cfe89819af9..3c8807dfea0 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeZonePicker/TimeZoneOption.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeZonePicker/TimeZoneOption.tsx @@ -1,13 +1,16 @@ -import React, { PropsWithChildren } from 'react'; import { css, cx } from '@emotion/css'; +import { isString } from 'lodash'; +import React, { PropsWithChildren } from 'react'; + import { GrafanaTheme2, SelectableValue, getTimeZoneInfo } from '@grafana/data'; + import { useTheme2 } from '../../../themes/ThemeContext'; import { stylesFactory } from '../../../themes/stylesFactory'; import { Icon } from '../../Icon/Icon'; -import { TimeZoneOffset } from './TimeZoneOffset'; + import { TimeZoneDescription } from './TimeZoneDescription'; +import { TimeZoneOffset } from './TimeZoneOffset'; import { TimeZoneTitle } from './TimeZoneTitle'; -import { isString } from 'lodash'; interface Props { isFocused: boolean; diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeZonePicker/TimeZoneTitle.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeZonePicker/TimeZoneTitle.tsx index 7fb95bdc381..9194e45de76 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeZonePicker/TimeZoneTitle.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeZonePicker/TimeZoneTitle.tsx @@ -1,6 +1,8 @@ -import React, { ReactNode } from 'react'; import { css } from '@emotion/css'; +import React, { ReactNode } from 'react'; + import { GrafanaTheme } from '@grafana/data'; + import { useTheme, stylesFactory } from '../../../themes'; interface Props { diff --git a/packages/grafana-ui/src/components/DateTimePickers/WeekStartPicker.story.tsx b/packages/grafana-ui/src/components/DateTimePickers/WeekStartPicker.story.tsx index 85742db207e..e42e3c87c02 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/WeekStartPicker.story.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/WeekStartPicker.story.tsx @@ -1,7 +1,8 @@ -import React from 'react'; import { action } from '@storybook/addon-actions'; +import React from 'react'; import { WeekStartPicker } from '@grafana/ui'; + import { UseState } from '../../utils/storybook/UseState'; import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; diff --git a/packages/grafana-ui/src/components/DateTimePickers/WeekStartPicker.tsx b/packages/grafana-ui/src/components/DateTimePickers/WeekStartPicker.tsx index 858d42e6c96..72962bd258d 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/WeekStartPicker.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/WeekStartPicker.tsx @@ -1,8 +1,10 @@ import React, { useCallback } from 'react'; + import { SelectableValue } from '@grafana/data'; -import { Select } from '../Select/Select'; import { selectors } from '@grafana/e2e-selectors'; +import { Select } from '../Select/Select'; + export interface Props { onChange: (weekStart: string) => void; value: string; diff --git a/packages/grafana-ui/src/components/Drawer/Drawer.story.tsx b/packages/grafana-ui/src/components/Drawer/Drawer.story.tsx index db92c2864b3..fb491d5c8c1 100644 --- a/packages/grafana-ui/src/components/Drawer/Drawer.story.tsx +++ b/packages/grafana-ui/src/components/Drawer/Drawer.story.tsx @@ -1,10 +1,13 @@ -import React, { useState } from 'react'; import { Story } from '@storybook/react'; +import React, { useState } from 'react'; + import { Button, Drawer, Tab, TabsBar } from '@grafana/ui'; + import { UseState } from '../../utils/storybook/UseState'; import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; -import mdx from './Drawer.mdx'; + import { Props } from './Drawer'; +import mdx from './Drawer.mdx'; export default { title: 'Overlays/Drawer', diff --git a/packages/grafana-ui/src/components/Drawer/Drawer.tsx b/packages/grafana-ui/src/components/Drawer/Drawer.tsx index 1f515190742..7bf729d0334 100644 --- a/packages/grafana-ui/src/components/Drawer/Drawer.tsx +++ b/packages/grafana-ui/src/components/Drawer/Drawer.tsx @@ -1,15 +1,16 @@ -import React, { CSSProperties, ReactNode, useState, useEffect } from 'react'; -import { GrafanaTheme2 } from '@grafana/data'; -import RcDrawer from 'rc-drawer'; import { css } from '@emotion/css'; +import { useDialog } from '@react-aria/dialog'; +import { FocusScope } from '@react-aria/focus'; +import { useOverlay } from '@react-aria/overlays'; +import RcDrawer from 'rc-drawer'; +import React, { CSSProperties, ReactNode, useState, useEffect } from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; +import { useStyles2 } from '../../themes'; import { CustomScrollbar } from '../CustomScrollbar/CustomScrollbar'; import { IconButton } from '../IconButton/IconButton'; -import { useStyles2 } from '../../themes'; -import { FocusScope } from '@react-aria/focus'; -import { useDialog } from '@react-aria/dialog'; -import { useOverlay } from '@react-aria/overlays'; export interface Props { children: ReactNode; diff --git a/packages/grafana-ui/src/components/Dropdown/ButtonSelect.story.internal.tsx b/packages/grafana-ui/src/components/Dropdown/ButtonSelect.story.internal.tsx index e2737ec0eb8..0fda4e017c9 100644 --- a/packages/grafana-ui/src/components/Dropdown/ButtonSelect.story.internal.tsx +++ b/packages/grafana-ui/src/components/Dropdown/ButtonSelect.story.internal.tsx @@ -1,11 +1,14 @@ -import React from 'react'; import { action } from '@storybook/addon-actions'; import { Meta, Story } from '@storybook/react'; -import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; -import { UseState } from '../../utils/storybook/UseState'; +import React from 'react'; + import { SelectableValue } from '@grafana/data'; -import { ButtonSelect } from './ButtonSelect'; + import { DashboardStoryCanvas } from '../../utils/storybook/DashboardStoryCanvas'; +import { UseState } from '../../utils/storybook/UseState'; +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; + +import { ButtonSelect } from './ButtonSelect'; export default { title: 'Forms/Select/ButtonSelect', diff --git a/packages/grafana-ui/src/components/Dropdown/ButtonSelect.tsx b/packages/grafana-ui/src/components/Dropdown/ButtonSelect.tsx index c078b23ba1d..be0ae91df41 100644 --- a/packages/grafana-ui/src/components/Dropdown/ButtonSelect.tsx +++ b/packages/grafana-ui/src/components/Dropdown/ButtonSelect.tsx @@ -1,16 +1,18 @@ +import { css } from '@emotion/css'; +import { useButton } from '@react-aria/button'; +import { FocusScope } from '@react-aria/focus'; +import { useMenuTrigger } from '@react-aria/menu'; +import { useMenuTriggerState } from '@react-stately/menu'; import React, { HTMLAttributes } from 'react'; -import { PopoverContent } from '../Tooltip'; + import { GrafanaTheme2, SelectableValue } from '@grafana/data'; + +import { useStyles2 } from '../../themes/ThemeContext'; import { ToolbarButtonVariant, ToolbarButton, ButtonGroup } from '../Button'; import { ClickOutsideWrapper } from '../ClickOutsideWrapper/ClickOutsideWrapper'; -import { css } from '@emotion/css'; -import { useStyles2 } from '../../themes/ThemeContext'; import { Menu } from '../Menu/Menu'; import { MenuItem } from '../Menu/MenuItem'; -import { FocusScope } from '@react-aria/focus'; -import { useMenuTriggerState } from '@react-stately/menu'; -import { useMenuTrigger } from '@react-aria/menu'; -import { useButton } from '@react-aria/button'; +import { PopoverContent } from '../Tooltip'; export interface Props extends HTMLAttributes { className?: string; diff --git a/packages/grafana-ui/src/components/EmptySearchResult/EmptySearchResult.story.tsx b/packages/grafana-ui/src/components/EmptySearchResult/EmptySearchResult.story.tsx index dc57b6fb9b3..90e18b2c0ac 100644 --- a/packages/grafana-ui/src/components/EmptySearchResult/EmptySearchResult.story.tsx +++ b/packages/grafana-ui/src/components/EmptySearchResult/EmptySearchResult.story.tsx @@ -1,6 +1,8 @@ import React from 'react'; -import { EmptySearchResult } from './EmptySearchResult'; + import { withCenteredStory } from '@grafana/ui/src/utils/storybook/withCenteredStory'; + +import { EmptySearchResult } from './EmptySearchResult'; import mdx from './EmptySearchResult.mdx'; export default { diff --git a/packages/grafana-ui/src/components/EmptySearchResult/EmptySearchResult.tsx b/packages/grafana-ui/src/components/EmptySearchResult/EmptySearchResult.tsx index 6c1490351f0..a340d7154b0 100644 --- a/packages/grafana-ui/src/components/EmptySearchResult/EmptySearchResult.tsx +++ b/packages/grafana-ui/src/components/EmptySearchResult/EmptySearchResult.tsx @@ -1,6 +1,8 @@ -import React, { FC } from 'react'; -import { GrafanaTheme2 } from '@grafana/data'; import { css } from '@emotion/css'; +import React, { FC } from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; + import { useStyles2 } from '../../themes'; export interface Props { diff --git a/packages/grafana-ui/src/components/ErrorBoundary/ErrorBoundary.story.tsx b/packages/grafana-ui/src/components/ErrorBoundary/ErrorBoundary.story.tsx index 2231c657fdb..885cd49be2f 100644 --- a/packages/grafana-ui/src/components/ErrorBoundary/ErrorBoundary.story.tsx +++ b/packages/grafana-ui/src/components/ErrorBoundary/ErrorBoundary.story.tsx @@ -1,10 +1,13 @@ import React, { useState } from 'react'; -import { ErrorBoundary, ErrorBoundaryAlert } from './ErrorBoundary'; + import { withCenteredStory } from '@grafana/ui/src/utils/storybook/withCenteredStory'; -import mdx from './ErrorBoundary.mdx'; -import { Button } from '../Button'; -import { ErrorWithStack } from './ErrorWithStack'; + import { Alert } from '../Alert/Alert'; +import { Button } from '../Button'; + +import { ErrorBoundary, ErrorBoundaryAlert } from './ErrorBoundary'; +import mdx from './ErrorBoundary.mdx'; +import { ErrorWithStack } from './ErrorWithStack'; export default { title: 'General/ErrorBoundary', diff --git a/packages/grafana-ui/src/components/ErrorBoundary/ErrorBoundary.test.tsx b/packages/grafana-ui/src/components/ErrorBoundary/ErrorBoundary.test.tsx index 925210cfcd7..62d888eccf8 100644 --- a/packages/grafana-ui/src/components/ErrorBoundary/ErrorBoundary.test.tsx +++ b/packages/grafana-ui/src/components/ErrorBoundary/ErrorBoundary.test.tsx @@ -1,7 +1,8 @@ -import React, { FC } from 'react'; -import { render, screen } from '@testing-library/react'; -import { ErrorBoundary } from './ErrorBoundary'; import { captureException } from '@sentry/browser'; +import { render, screen } from '@testing-library/react'; +import React, { FC } from 'react'; + +import { ErrorBoundary } from './ErrorBoundary'; jest.mock('@sentry/browser'); diff --git a/packages/grafana-ui/src/components/ErrorBoundary/ErrorBoundary.tsx b/packages/grafana-ui/src/components/ErrorBoundary/ErrorBoundary.tsx index 6496443c96f..a929bbfec35 100644 --- a/packages/grafana-ui/src/components/ErrorBoundary/ErrorBoundary.tsx +++ b/packages/grafana-ui/src/components/ErrorBoundary/ErrorBoundary.tsx @@ -1,6 +1,8 @@ -import React, { PureComponent, ReactNode, ComponentType } from 'react'; import { captureException } from '@sentry/browser'; +import React, { PureComponent, ReactNode, ComponentType } from 'react'; + import { Alert } from '../Alert/Alert'; + import { ErrorWithStack } from './ErrorWithStack'; export interface ErrorInfo { diff --git a/packages/grafana-ui/src/components/ErrorBoundary/ErrorWithStack.tsx b/packages/grafana-ui/src/components/ErrorBoundary/ErrorWithStack.tsx index 50708a572c0..4a2cb35f693 100644 --- a/packages/grafana-ui/src/components/ErrorBoundary/ErrorWithStack.tsx +++ b/packages/grafana-ui/src/components/ErrorBoundary/ErrorWithStack.tsx @@ -1,7 +1,9 @@ -import React, { FunctionComponent } from 'react'; -import { ErrorBoundaryApi } from './ErrorBoundary'; -import { stylesFactory } from '../../themes'; import { css } from '@emotion/css'; +import React, { FunctionComponent } from 'react'; + +import { stylesFactory } from '../../themes'; + +import { ErrorBoundaryApi } from './ErrorBoundary'; const getStyles = stylesFactory(() => { return css` diff --git a/packages/grafana-ui/src/components/FileDropzone/FileDropzone.story.tsx b/packages/grafana-ui/src/components/FileDropzone/FileDropzone.story.tsx index 9451ddfa1a8..32466894539 100644 --- a/packages/grafana-ui/src/components/FileDropzone/FileDropzone.story.tsx +++ b/packages/grafana-ui/src/components/FileDropzone/FileDropzone.story.tsx @@ -1,7 +1,10 @@ -import { FileDropzone, FileDropzoneProps } from '@grafana/ui'; import { Meta, Story } from '@storybook/react'; import React from 'react'; + +import { FileDropzone, FileDropzoneProps } from '@grafana/ui'; + import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; + import mdx from './FileDropzone.mdx'; export default { diff --git a/packages/grafana-ui/src/components/FileDropzone/FileDropzone.test.tsx b/packages/grafana-ui/src/components/FileDropzone/FileDropzone.test.tsx index 2d589f69ef6..3f970c5cd88 100644 --- a/packages/grafana-ui/src/components/FileDropzone/FileDropzone.test.tsx +++ b/packages/grafana-ui/src/components/FileDropzone/FileDropzone.test.tsx @@ -1,5 +1,6 @@ import { fireEvent, render, screen } from '@testing-library/react'; import React from 'react'; + import { FileDropzone } from './FileDropzone'; import { REMOVE_FILE } from './FileListItem'; diff --git a/packages/grafana-ui/src/components/FileDropzone/FileDropzone.tsx b/packages/grafana-ui/src/components/FileDropzone/FileDropzone.tsx index 5f3f5bf120f..c9daf9daa80 100644 --- a/packages/grafana-ui/src/components/FileDropzone/FileDropzone.tsx +++ b/packages/grafana-ui/src/components/FileDropzone/FileDropzone.tsx @@ -1,10 +1,13 @@ import { css, cx } from '@emotion/css'; -import { GrafanaTheme2 } from '@grafana/data'; import { uniqueId } from 'lodash'; import React, { ReactNode, useCallback, useState } from 'react'; import { DropEvent, DropzoneOptions, FileRejection, useDropzone } from 'react-dropzone'; + +import { GrafanaTheme2 } from '@grafana/data'; + import { useTheme2 } from '../../themes'; import { Icon } from '../Icon/Icon'; + import { FileListItem } from './FileListItem'; export interface FileDropzoneProps { diff --git a/packages/grafana-ui/src/components/FileDropzone/FileListItem.story.tsx b/packages/grafana-ui/src/components/FileDropzone/FileListItem.story.tsx index af0ae0ce612..654922796e9 100644 --- a/packages/grafana-ui/src/components/FileDropzone/FileListItem.story.tsx +++ b/packages/grafana-ui/src/components/FileDropzone/FileListItem.story.tsx @@ -1,6 +1,8 @@ import { Meta, Story } from '@storybook/react'; import React from 'react'; + import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; + import { FileListItem as FileListItemComponent, FileListItemProps } from './FileListItem'; import mdx from './FileListItem.mdx'; diff --git a/packages/grafana-ui/src/components/FileDropzone/FileListItem.test.tsx b/packages/grafana-ui/src/components/FileDropzone/FileListItem.test.tsx index e1a0e75f2de..0ac8d8536ae 100644 --- a/packages/grafana-ui/src/components/FileDropzone/FileListItem.test.tsx +++ b/packages/grafana-ui/src/components/FileDropzone/FileListItem.test.tsx @@ -1,5 +1,6 @@ import { fireEvent, render, screen } from '@testing-library/react'; import React from 'react'; + import { FileListItem, REMOVE_FILE } from './FileListItem'; const file = ({ diff --git a/packages/grafana-ui/src/components/FileDropzone/FileListItem.tsx b/packages/grafana-ui/src/components/FileDropzone/FileListItem.tsx index cf039248391..fba1fb6e4c9 100644 --- a/packages/grafana-ui/src/components/FileDropzone/FileListItem.tsx +++ b/packages/grafana-ui/src/components/FileDropzone/FileListItem.tsx @@ -1,11 +1,14 @@ import { css } from '@emotion/css'; -import { formattedValueToString, getValueFormat, GrafanaTheme2 } from '@grafana/data'; import React from 'react'; + +import { formattedValueToString, getValueFormat, GrafanaTheme2 } from '@grafana/data'; + import { useStyles2 } from '../../themes'; import { trimFileName } from '../../utils/file'; import { Button } from '../Button'; import { Icon } from '../Icon/Icon'; import { IconButton } from '../IconButton/IconButton'; + import { DropzoneFile } from './FileDropzone'; export const REMOVE_FILE = 'Remove file'; diff --git a/packages/grafana-ui/src/components/FileUpload/FileUpload.story.tsx b/packages/grafana-ui/src/components/FileUpload/FileUpload.story.tsx index ea5a4b975f5..a0d32acb972 100644 --- a/packages/grafana-ui/src/components/FileUpload/FileUpload.story.tsx +++ b/packages/grafana-ui/src/components/FileUpload/FileUpload.story.tsx @@ -1,8 +1,11 @@ -import React from 'react'; -import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; -import { FileUpload } from '@grafana/ui'; -import mdx from './FileUpload.mdx'; import { Meta, Story } from '@storybook/react'; +import React from 'react'; + +import { FileUpload } from '@grafana/ui'; + +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; + +import mdx from './FileUpload.mdx'; export default { title: 'Forms/FileUpload', diff --git a/packages/grafana-ui/src/components/FileUpload/FileUpload.test.tsx b/packages/grafana-ui/src/components/FileUpload/FileUpload.test.tsx index eff5555819e..8860c2efa62 100644 --- a/packages/grafana-ui/src/components/FileUpload/FileUpload.test.tsx +++ b/packages/grafana-ui/src/components/FileUpload/FileUpload.test.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { shallow } from 'enzyme'; +import React from 'react'; + import { FileUpload } from './FileUpload'; describe('FileUpload', () => { diff --git a/packages/grafana-ui/src/components/FileUpload/FileUpload.tsx b/packages/grafana-ui/src/components/FileUpload/FileUpload.tsx index 48310576ae8..98fc47e7c5c 100644 --- a/packages/grafana-ui/src/components/FileUpload/FileUpload.tsx +++ b/packages/grafana-ui/src/components/FileUpload/FileUpload.tsx @@ -1,11 +1,13 @@ -import React, { FC, FormEvent, useCallback, useState } from 'react'; -import { GrafanaTheme2 } from '@grafana/data'; import { css, cx } from '@emotion/css'; -import { Icon } from '../index'; +import React, { FC, FormEvent, useCallback, useState } from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; + import { stylesFactory, useTheme2 } from '../../themes'; import { ComponentSize } from '../../types/size'; -import { getButtonStyles } from '../Button'; import { trimFileName } from '../../utils/file'; +import { getButtonStyles } from '../Button'; +import { Icon } from '../index'; export interface Props { /** Callback function to handle uploaded file */ diff --git a/packages/grafana-ui/src/components/FilterInput/FilterInput.tsx b/packages/grafana-ui/src/components/FilterInput/FilterInput.tsx index d394ae335c1..31537f5d131 100644 --- a/packages/grafana-ui/src/components/FilterInput/FilterInput.tsx +++ b/packages/grafana-ui/src/components/FilterInput/FilterInput.tsx @@ -1,5 +1,7 @@ import React, { HTMLProps } from 'react'; + import { escapeStringForRegex, unEscapeStringFromRegex } from '@grafana/data'; + import { Button, Icon, Input } from '..'; import { useCombinedRefs } from '../../utils/useCombinedRefs'; diff --git a/packages/grafana-ui/src/components/FilterPill/FilterPill.story.tsx b/packages/grafana-ui/src/components/FilterPill/FilterPill.story.tsx index d84751db2a8..0a5c007ae5f 100644 --- a/packages/grafana-ui/src/components/FilterPill/FilterPill.story.tsx +++ b/packages/grafana-ui/src/components/FilterPill/FilterPill.story.tsx @@ -1,11 +1,14 @@ -import React, { useState } from 'react'; import { Story } from '@storybook/react'; -import { FilterPill, FilterPillProps } from './FilterPill'; +import React, { useState } from 'react'; + import { withCenteredStory } from '@grafana/ui/src/utils/storybook/withCenteredStory'; -import mdx from './FilterPill.mdx'; + import { getAvailableIcons } from '../../types'; import { HorizontalGroup } from '../Layout/Layout'; +import { FilterPill, FilterPillProps } from './FilterPill'; +import mdx from './FilterPill.mdx'; + export default { title: 'General/FilterPill', component: FilterPill, diff --git a/packages/grafana-ui/src/components/FilterPill/FilterPill.tsx b/packages/grafana-ui/src/components/FilterPill/FilterPill.tsx index 654f19eb875..c1a36603a06 100644 --- a/packages/grafana-ui/src/components/FilterPill/FilterPill.tsx +++ b/packages/grafana-ui/src/components/FilterPill/FilterPill.tsx @@ -1,9 +1,11 @@ -import React from 'react'; -import { useStyles2 } from '../../themes'; -import { GrafanaTheme2 } from '@grafana/data'; import { css, cx } from '@emotion/css'; -import { Icon } from '../Icon/Icon'; +import React from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; + +import { useStyles2 } from '../../themes'; import { IconName } from '../../types'; +import { Icon } from '../Icon/Icon'; export interface FilterPillProps { selected: boolean; diff --git a/packages/grafana-ui/src/components/FormField/FormField.story.internal.tsx b/packages/grafana-ui/src/components/FormField/FormField.story.internal.tsx index 7b320bdf72a..5b3fe2a013a 100644 --- a/packages/grafana-ui/src/components/FormField/FormField.story.internal.tsx +++ b/packages/grafana-ui/src/components/FormField/FormField.story.internal.tsx @@ -1,6 +1,8 @@ -import React from 'react'; import { Meta, Story } from '@storybook/react'; +import React from 'react'; + import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; + import { FormField, Props } from './FormField'; export default { diff --git a/packages/grafana-ui/src/components/FormField/FormField.test.tsx b/packages/grafana-ui/src/components/FormField/FormField.test.tsx index 95ccb57b658..9cd91048024 100644 --- a/packages/grafana-ui/src/components/FormField/FormField.test.tsx +++ b/packages/grafana-ui/src/components/FormField/FormField.test.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { shallow } from 'enzyme'; +import React from 'react'; + import { FormField, Props } from './FormField'; const setup = (propOverrides?: Partial) => { diff --git a/packages/grafana-ui/src/components/FormField/FormField.tsx b/packages/grafana-ui/src/components/FormField/FormField.tsx index 1ef3a594610..b15b54c3e1a 100644 --- a/packages/grafana-ui/src/components/FormField/FormField.tsx +++ b/packages/grafana-ui/src/components/FormField/FormField.tsx @@ -1,5 +1,6 @@ -import React, { InputHTMLAttributes, FunctionComponent } from 'react'; import { css, cx } from '@emotion/css'; +import React, { InputHTMLAttributes, FunctionComponent } from 'react'; + import { InlineFormLabel } from '../FormLabel/FormLabel'; import { PopoverContent } from '../Tooltip'; diff --git a/packages/grafana-ui/src/components/FormLabel/FormLabel.tsx b/packages/grafana-ui/src/components/FormLabel/FormLabel.tsx index b80178030ba..ae6c1c46466 100644 --- a/packages/grafana-ui/src/components/FormLabel/FormLabel.tsx +++ b/packages/grafana-ui/src/components/FormLabel/FormLabel.tsx @@ -1,7 +1,8 @@ -import React, { FunctionComponent, ReactNode } from 'react'; import classNames from 'classnames'; -import { Tooltip, PopoverContent } from '../Tooltip'; +import React, { FunctionComponent, ReactNode } from 'react'; + import { Icon } from '../Icon/Icon'; +import { Tooltip, PopoverContent } from '../Tooltip'; interface Props { children: ReactNode; diff --git a/packages/grafana-ui/src/components/FormattedValueDisplay/FormattedValueDisplay.story.tsx b/packages/grafana-ui/src/components/FormattedValueDisplay/FormattedValueDisplay.story.tsx index d81bceb6b8b..94f6827be04 100644 --- a/packages/grafana-ui/src/components/FormattedValueDisplay/FormattedValueDisplay.story.tsx +++ b/packages/grafana-ui/src/components/FormattedValueDisplay/FormattedValueDisplay.story.tsx @@ -1,6 +1,8 @@ import React from 'react'; -import { FormattedValueDisplay } from './FormattedValueDisplay'; + import { withCenteredStory } from '@grafana/ui/src/utils/storybook/withCenteredStory'; + +import { FormattedValueDisplay } from './FormattedValueDisplay'; import mdx from './FormattedValueDisplay.mdx'; export default { diff --git a/packages/grafana-ui/src/components/FormattedValueDisplay/FormattedValueDisplay.tsx b/packages/grafana-ui/src/components/FormattedValueDisplay/FormattedValueDisplay.tsx index decb8f2486b..17a074d0f8c 100644 --- a/packages/grafana-ui/src/components/FormattedValueDisplay/FormattedValueDisplay.tsx +++ b/packages/grafana-ui/src/components/FormattedValueDisplay/FormattedValueDisplay.tsx @@ -1,4 +1,5 @@ import React, { FC, CSSProperties, HTMLProps } from 'react'; + import { FormattedValue } from '@grafana/data'; export interface Props extends Omit, 'className' | 'value' | 'style'> { diff --git a/packages/grafana-ui/src/components/Forms/Checkbox.story.tsx b/packages/grafana-ui/src/components/Forms/Checkbox.story.tsx index 3f7229f13c1..c80d0a25f20 100644 --- a/packages/grafana-ui/src/components/Forms/Checkbox.story.tsx +++ b/packages/grafana-ui/src/components/Forms/Checkbox.story.tsx @@ -1,7 +1,9 @@ import React, { useState, useCallback } from 'react'; -import mdx from './Checkbox.mdx'; -import { Checkbox } from './Checkbox'; + import { VerticalGroup } from '../Layout/Layout'; + +import { Checkbox } from './Checkbox'; +import mdx from './Checkbox.mdx'; import { Field } from './Field'; export default { diff --git a/packages/grafana-ui/src/components/Forms/Checkbox.tsx b/packages/grafana-ui/src/components/Forms/Checkbox.tsx index c6af215247e..9fd8b8ff8c8 100644 --- a/packages/grafana-ui/src/components/Forms/Checkbox.tsx +++ b/packages/grafana-ui/src/components/Forms/Checkbox.tsx @@ -1,10 +1,13 @@ -import React, { HTMLProps, useCallback } from 'react'; -import { GrafanaTheme2 } from '@grafana/data'; -import { getLabelStyles } from './Label'; -import { stylesFactory, useStyles2 } from '../../themes'; import { css, cx } from '@emotion/css'; +import React, { HTMLProps, useCallback } from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; + +import { stylesFactory, useStyles2 } from '../../themes'; import { getFocusStyles, getMouseFocusStyles } from '../../themes/mixins'; +import { getLabelStyles } from './Label'; + export interface CheckboxProps extends Omit, 'value'> { label?: string; description?: string; diff --git a/packages/grafana-ui/src/components/Forms/Field.story.tsx b/packages/grafana-ui/src/components/Forms/Field.story.tsx index de99d13f7d2..859fc811c77 100644 --- a/packages/grafana-ui/src/components/Forms/Field.story.tsx +++ b/packages/grafana-ui/src/components/Forms/Field.story.tsx @@ -1,7 +1,9 @@ -import React, { useState, useCallback } from 'react'; import { Story } from '@storybook/react'; -import { Field, FieldProps } from './Field'; +import React, { useState, useCallback } from 'react'; + import { Input, Switch } from '..'; + +import { Field, FieldProps } from './Field'; import mdx from './Field.mdx'; export default { diff --git a/packages/grafana-ui/src/components/Forms/Field.test.tsx b/packages/grafana-ui/src/components/Forms/Field.test.tsx index c4e44205bc5..a4fd7e59d26 100644 --- a/packages/grafana-ui/src/components/Forms/Field.test.tsx +++ b/packages/grafana-ui/src/components/Forms/Field.test.tsx @@ -1,9 +1,11 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; +import React from 'react'; + import { Input } from '../Input/Input'; -import { Field } from './Field'; import { Select } from '../Select/Select'; +import { Field } from './Field'; + describe('Field', () => { it('renders the label', () => { render( diff --git a/packages/grafana-ui/src/components/Forms/Field.tsx b/packages/grafana-ui/src/components/Forms/Field.tsx index 490a0d0f09e..82ab1d5d949 100644 --- a/packages/grafana-ui/src/components/Forms/Field.tsx +++ b/packages/grafana-ui/src/components/Forms/Field.tsx @@ -1,11 +1,14 @@ -import React, { HTMLAttributes } from 'react'; -import { Label } from './Label'; -import { stylesFactory, useTheme2 } from '../../themes'; import { css, cx } from '@emotion/css'; +import React, { HTMLAttributes } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; -import { FieldValidationMessage } from './FieldValidationMessage'; + +import { stylesFactory, useTheme2 } from '../../themes'; import { getChildId } from '../../utils/reactUtils'; +import { FieldValidationMessage } from './FieldValidationMessage'; +import { Label } from './Label'; + export interface FieldProps extends HTMLAttributes { /** Form input element, i.e Input or Switch */ children: React.ReactElement; diff --git a/packages/grafana-ui/src/components/Forms/FieldArray.story.tsx b/packages/grafana-ui/src/components/Forms/FieldArray.story.tsx index 88404a3d08b..6b60b083f46 100644 --- a/packages/grafana-ui/src/components/Forms/FieldArray.story.tsx +++ b/packages/grafana-ui/src/components/Forms/FieldArray.story.tsx @@ -1,10 +1,13 @@ +import { Meta, Story } from '@storybook/react'; import React from 'react'; + +import { Form, Input, Button, HorizontalGroup } from '@grafana/ui'; + import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; import { withStoryContainer } from '../../utils/storybook/withStoryContainer'; -import { Form, Input, Button, HorizontalGroup } from '@grafana/ui'; + import { FieldArray } from './FieldArray'; import mdx from './FieldArray.mdx'; -import { Meta, Story } from '@storybook/react'; export default { title: 'Forms/FieldArray', diff --git a/packages/grafana-ui/src/components/Forms/FieldArray.tsx b/packages/grafana-ui/src/components/Forms/FieldArray.tsx index 48e4eb7df3c..bab7d3ebae1 100644 --- a/packages/grafana-ui/src/components/Forms/FieldArray.tsx +++ b/packages/grafana-ui/src/components/Forms/FieldArray.tsx @@ -1,5 +1,6 @@ import { FC } from 'react'; import { useFieldArray, UseFieldArrayProps } from 'react-hook-form'; + import { FieldArrayApi } from '../../types'; export interface FieldArrayProps extends UseFieldArrayProps { diff --git a/packages/grafana-ui/src/components/Forms/FieldSet.story.tsx b/packages/grafana-ui/src/components/Forms/FieldSet.story.tsx index 38420169f69..da5856bb665 100644 --- a/packages/grafana-ui/src/components/Forms/FieldSet.story.tsx +++ b/packages/grafana-ui/src/components/Forms/FieldSet.story.tsx @@ -1,9 +1,12 @@ import React from 'react'; -import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; + import { Input, Form, FieldSet, Field } from '@grafana/ui'; -import mdx from './FieldSet.mdx'; + +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; import { Button } from '../Button'; +import mdx from './FieldSet.mdx'; + export default { title: 'Forms/FieldSet', component: FieldSet, diff --git a/packages/grafana-ui/src/components/Forms/FieldSet.tsx b/packages/grafana-ui/src/components/Forms/FieldSet.tsx index 0749e9856de..11ab276b3b6 100644 --- a/packages/grafana-ui/src/components/Forms/FieldSet.tsx +++ b/packages/grafana-ui/src/components/Forms/FieldSet.tsx @@ -1,7 +1,10 @@ -import React, { FC, HTMLProps } from 'react'; import { css, cx } from '@emotion/css'; +import React, { FC, HTMLProps } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; + import { stylesFactory, useTheme2 } from '../../themes'; + import { Legend } from './Legend'; export interface Props extends Omit, 'label'> { diff --git a/packages/grafana-ui/src/components/Forms/FieldValidationMessage.story.tsx b/packages/grafana-ui/src/components/Forms/FieldValidationMessage.story.tsx index d5d162062d8..b9fe82c76da 100644 --- a/packages/grafana-ui/src/components/Forms/FieldValidationMessage.story.tsx +++ b/packages/grafana-ui/src/components/Forms/FieldValidationMessage.story.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { Meta, Story } from '@storybook/react'; +import React from 'react'; + import { FieldValidationMessage } from './FieldValidationMessage'; import mdx from './FieldValidationMessage.mdx'; diff --git a/packages/grafana-ui/src/components/Forms/FieldValidationMessage.tsx b/packages/grafana-ui/src/components/Forms/FieldValidationMessage.tsx index 2e551d7b764..975b574f6f4 100644 --- a/packages/grafana-ui/src/components/Forms/FieldValidationMessage.tsx +++ b/packages/grafana-ui/src/components/Forms/FieldValidationMessage.tsx @@ -1,8 +1,10 @@ -import React from 'react'; import { css, cx } from '@emotion/css'; +import React from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; -import { Icon } from '../Icon/Icon'; + import { stylesFactory, useTheme2 } from '../../themes'; +import { Icon } from '../Icon/Icon'; export interface FieldValidationMessageProps { /** Override component style */ diff --git a/packages/grafana-ui/src/components/Forms/Form.story.tsx b/packages/grafana-ui/src/components/Forms/Form.story.tsx index e1ae71daa9b..ce9960dd60f 100644 --- a/packages/grafana-ui/src/components/Forms/Form.story.tsx +++ b/packages/grafana-ui/src/components/Forms/Form.story.tsx @@ -1,6 +1,7 @@ +import { Story } from '@storybook/react'; import React from 'react'; import { ValidateResult } from 'react-hook-form'; -import { Story } from '@storybook/react'; + import { Field, Legend, @@ -14,8 +15,10 @@ import { TextArea, RadioButtonGroup, } from '@grafana/ui'; + import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; import { withStoryContainer } from '../../utils/storybook/withStoryContainer'; + import mdx from './Form.mdx'; export default { diff --git a/packages/grafana-ui/src/components/Forms/Form.tsx b/packages/grafana-ui/src/components/Forms/Form.tsx index b10051597ae..cc722fdcfe2 100644 --- a/packages/grafana-ui/src/components/Forms/Form.tsx +++ b/packages/grafana-ui/src/components/Forms/Form.tsx @@ -1,7 +1,8 @@ +import { css } from '@emotion/css'; import React, { HTMLProps, useEffect } from 'react'; import { useForm, Mode, DeepPartial, UnpackNestedValue, SubmitHandler } from 'react-hook-form'; + import { FormAPI } from '../../types'; -import { css } from '@emotion/css'; interface FormProps extends Omit, 'onSubmit'> { validateOn?: Mode; diff --git a/packages/grafana-ui/src/components/Forms/InlineField.story.tsx b/packages/grafana-ui/src/components/Forms/InlineField.story.tsx index b9357bb6215..6f051006a15 100644 --- a/packages/grafana-ui/src/components/Forms/InlineField.story.tsx +++ b/packages/grafana-ui/src/components/Forms/InlineField.story.tsx @@ -1,7 +1,9 @@ -import React from 'react'; import { action } from '@storybook/addon-actions'; +import React from 'react'; + import { Input } from '../Input/Input'; import { Select } from '../Select/Select'; + import { InlineField } from './InlineField'; import mdx from './InlineField.mdx'; diff --git a/packages/grafana-ui/src/components/Forms/InlineField.test.tsx b/packages/grafana-ui/src/components/Forms/InlineField.test.tsx index 8ad2241d9cc..7730f890f0c 100644 --- a/packages/grafana-ui/src/components/Forms/InlineField.test.tsx +++ b/packages/grafana-ui/src/components/Forms/InlineField.test.tsx @@ -1,9 +1,11 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; +import React from 'react'; + import { Input } from '../Input/Input'; -import { InlineField } from './InlineField'; import { Select } from '../Select/Select'; +import { InlineField } from './InlineField'; + describe('InlineField', () => { it('renders the label', () => { render( diff --git a/packages/grafana-ui/src/components/Forms/InlineField.tsx b/packages/grafana-ui/src/components/Forms/InlineField.tsx index ae0f9b9bfb1..c7806e649e7 100644 --- a/packages/grafana-ui/src/components/Forms/InlineField.tsx +++ b/packages/grafana-ui/src/components/Forms/InlineField.tsx @@ -1,12 +1,15 @@ -import React, { FC } from 'react'; import { cx, css } from '@emotion/css'; +import React, { FC } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; + import { useTheme2 } from '../../themes'; -import { InlineLabel } from './InlineLabel'; -import { PopoverContent } from '../Tooltip'; -import { FieldProps } from './Field'; import { getChildId } from '../../utils/reactUtils'; +import { PopoverContent } from '../Tooltip'; + +import { FieldProps } from './Field'; import { FieldValidationMessage } from './FieldValidationMessage'; +import { InlineLabel } from './InlineLabel'; export interface Props extends Omit { /** Content for the label's tooltip */ diff --git a/packages/grafana-ui/src/components/Forms/InlineFieldRow.story.tsx b/packages/grafana-ui/src/components/Forms/InlineFieldRow.story.tsx index f4c43643a54..3e12be9767a 100644 --- a/packages/grafana-ui/src/components/Forms/InlineFieldRow.story.tsx +++ b/packages/grafana-ui/src/components/Forms/InlineFieldRow.story.tsx @@ -1,8 +1,10 @@ import React from 'react'; + +import { Input } from '../Input/Input'; + +import { InlineField } from './InlineField'; import { InlineFieldRow } from './InlineFieldRow'; import mdx from './InlineFieldRow.mdx'; -import { InlineField } from './InlineField'; -import { Input } from '../Input/Input'; export default { title: 'Forms/InlineFieldRow', diff --git a/packages/grafana-ui/src/components/Forms/InlineFieldRow.tsx b/packages/grafana-ui/src/components/Forms/InlineFieldRow.tsx index 0409ef4d326..f9af56470b2 100644 --- a/packages/grafana-ui/src/components/Forms/InlineFieldRow.tsx +++ b/packages/grafana-ui/src/components/Forms/InlineFieldRow.tsx @@ -1,8 +1,10 @@ -import React, { FC, HTMLProps, ReactNode } from 'react'; import { css, cx } from '@emotion/css'; -import { useStyles } from '../../themes'; +import React, { FC, HTMLProps, ReactNode } from 'react'; + import { GrafanaTheme } from '@grafana/data'; +import { useStyles } from '../../themes'; + export interface Props extends Omit, 'css'> { children: ReactNode | ReactNode[]; } diff --git a/packages/grafana-ui/src/components/Forms/InlineLabel.story.tsx b/packages/grafana-ui/src/components/Forms/InlineLabel.story.tsx index 857bbd00fbd..6f491dba9a9 100644 --- a/packages/grafana-ui/src/components/Forms/InlineLabel.story.tsx +++ b/packages/grafana-ui/src/components/Forms/InlineLabel.story.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { InlineLabel } from './InlineLabel'; import mdx from './InlineLabel.mdx'; diff --git a/packages/grafana-ui/src/components/Forms/InlineLabel.tsx b/packages/grafana-ui/src/components/Forms/InlineLabel.tsx index 7f98ba25684..03f1045c109 100644 --- a/packages/grafana-ui/src/components/Forms/InlineLabel.tsx +++ b/packages/grafana-ui/src/components/Forms/InlineLabel.tsx @@ -1,10 +1,12 @@ import { css, cx } from '@emotion/css'; -import { GrafanaTheme } from '@grafana/data'; import React, { FunctionComponent } from 'react'; +import { GrafanaTheme } from '@grafana/data'; + import { useTheme } from '../../themes'; import { Icon } from '../Icon/Icon'; import { PopoverContent, Tooltip } from '../Tooltip'; + import { LabelProps } from './Label'; export interface Props extends Omit { diff --git a/packages/grafana-ui/src/components/Forms/InlineSegmentGroup.tsx b/packages/grafana-ui/src/components/Forms/InlineSegmentGroup.tsx index b4eabd3b518..aff6abc6a55 100644 --- a/packages/grafana-ui/src/components/Forms/InlineSegmentGroup.tsx +++ b/packages/grafana-ui/src/components/Forms/InlineSegmentGroup.tsx @@ -1,6 +1,8 @@ -import React, { FC } from 'react'; import { cx, css } from '@emotion/css'; +import React, { FC } from 'react'; + import { GrafanaTheme } from '@grafana/data'; + import { useTheme } from '../../themes'; export interface Props { diff --git a/packages/grafana-ui/src/components/Forms/Label.story.tsx b/packages/grafana-ui/src/components/Forms/Label.story.tsx index ac452922229..42ee838e2a0 100644 --- a/packages/grafana-ui/src/components/Forms/Label.story.tsx +++ b/packages/grafana-ui/src/components/Forms/Label.story.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { Label } from './Label'; import mdx from './Label.mdx'; diff --git a/packages/grafana-ui/src/components/Forms/Label.tsx b/packages/grafana-ui/src/components/Forms/Label.tsx index 746f1d389db..ca1c6501232 100644 --- a/packages/grafana-ui/src/components/Forms/Label.tsx +++ b/packages/grafana-ui/src/components/Forms/Label.tsx @@ -1,7 +1,9 @@ -import React from 'react'; -import { useTheme2, stylesFactory } from '../../themes'; -import { GrafanaTheme2 } from '@grafana/data'; import { css, cx } from '@emotion/css'; +import React from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; + +import { useTheme2, stylesFactory } from '../../themes'; import { Icon } from '../Icon/Icon'; export interface LabelProps extends React.LabelHTMLAttributes { diff --git a/packages/grafana-ui/src/components/Forms/Legacy/Input/Input.story.internal.tsx b/packages/grafana-ui/src/components/Forms/Legacy/Input/Input.story.internal.tsx index d23efafc09e..3adc868b1ca 100644 --- a/packages/grafana-ui/src/components/Forms/Legacy/Input/Input.story.internal.tsx +++ b/packages/grafana-ui/src/components/Forms/Legacy/Input/Input.story.internal.tsx @@ -1,10 +1,11 @@ -import React, { useState } from 'react'; -import { zip, fromPairs } from 'lodash'; - -import { withCenteredStory } from '../../../../utils/storybook/withCenteredStory'; -import { Input } from './Input'; import { Meta, Story } from '@storybook/react'; +import { zip, fromPairs } from 'lodash'; +import React, { useState } from 'react'; + import { EventsWithValidation } from '../../../../utils'; +import { withCenteredStory } from '../../../../utils/storybook/withCenteredStory'; + +import { Input } from './Input'; export default { title: 'Forms/Legacy/Input', diff --git a/packages/grafana-ui/src/components/Forms/Legacy/Input/Input.test.tsx b/packages/grafana-ui/src/components/Forms/Legacy/Input/Input.test.tsx index da8b30d124b..18f5487b4e0 100644 --- a/packages/grafana-ui/src/components/Forms/Legacy/Input/Input.test.tsx +++ b/packages/grafana-ui/src/components/Forms/Legacy/Input/Input.test.tsx @@ -1,9 +1,11 @@ +import { shallow } from 'enzyme'; import React from 'react'; import renderer from 'react-test-renderer'; -import { shallow } from 'enzyme'; -import { Input } from './Input'; -import { EventsWithValidation } from '../../../../utils'; + import { ValidationEvents } from '../../../../types'; +import { EventsWithValidation } from '../../../../utils'; + +import { Input } from './Input'; const TEST_ERROR_MESSAGE = 'Value must be empty or less than 3 chars'; const testBlurValidation: ValidationEvents = { diff --git a/packages/grafana-ui/src/components/Forms/Legacy/Input/Input.tsx b/packages/grafana-ui/src/components/Forms/Legacy/Input/Input.tsx index 85e28a09442..76742d372c6 100644 --- a/packages/grafana-ui/src/components/Forms/Legacy/Input/Input.tsx +++ b/packages/grafana-ui/src/components/Forms/Legacy/Input/Input.tsx @@ -1,7 +1,8 @@ -import React, { PureComponent, ChangeEvent } from 'react'; import classNames from 'classnames'; -import { validate, EventsWithValidation, hasValidationEvent } from '../../../../utils'; +import React, { PureComponent, ChangeEvent } from 'react'; + import { ValidationEvents, ValidationRule } from '../../../../types'; +import { validate, EventsWithValidation, hasValidationEvent } from '../../../../utils'; export enum LegacyInputStatus { Invalid = 'invalid', diff --git a/packages/grafana-ui/src/components/Forms/Legacy/Select/IndicatorsContainer.tsx b/packages/grafana-ui/src/components/Forms/Legacy/Select/IndicatorsContainer.tsx index d586997b37b..0cfe9a8cca0 100644 --- a/packages/grafana-ui/src/components/Forms/Legacy/Select/IndicatorsContainer.tsx +++ b/packages/grafana-ui/src/components/Forms/Legacy/Select/IndicatorsContainer.tsx @@ -1,7 +1,8 @@ import React from 'react'; -import { Icon } from '../../../Icon/Icon'; import { components } from 'react-select'; +import { Icon } from '../../../Icon/Icon'; + export const IndicatorsContainer = (props: any) => { const isOpen = props.selectProps.menuIsOpen; return ( diff --git a/packages/grafana-ui/src/components/Forms/Legacy/Select/NoOptionsMessage.tsx b/packages/grafana-ui/src/components/Forms/Legacy/Select/NoOptionsMessage.tsx index 077199661ed..f596a7f9c66 100644 --- a/packages/grafana-ui/src/components/Forms/Legacy/Select/NoOptionsMessage.tsx +++ b/packages/grafana-ui/src/components/Forms/Legacy/Select/NoOptionsMessage.tsx @@ -1,5 +1,6 @@ import React from 'react'; import { components, NoticeProps, GroupBase } from 'react-select'; + import { SelectableValue } from '@grafana/data'; export type Props = NoticeProps, boolean, GroupBase>>; diff --git a/packages/grafana-ui/src/components/Forms/Legacy/Select/Select.story.internal.tsx b/packages/grafana-ui/src/components/Forms/Legacy/Select/Select.story.internal.tsx index 2f9a66737d0..0c1dccb4102 100644 --- a/packages/grafana-ui/src/components/Forms/Legacy/Select/Select.story.internal.tsx +++ b/packages/grafana-ui/src/components/Forms/Legacy/Select/Select.story.internal.tsx @@ -1,9 +1,12 @@ -import React, { useState, useCallback } from 'react'; import { action } from '@storybook/addon-actions'; import { Meta, Story } from '@storybook/react'; -import { withCenteredStory } from '../../../../utils/storybook/withCenteredStory'; -import { UseState } from '../../../../utils/storybook/UseState'; +import React, { useState, useCallback } from 'react'; + import { SelectableValue } from '@grafana/data'; + +import { UseState } from '../../../../utils/storybook/UseState'; +import { withCenteredStory } from '../../../../utils/storybook/withCenteredStory'; + import { Select, AsyncSelect as AsyncSelectComponent } from './Select'; export default { diff --git a/packages/grafana-ui/src/components/Forms/Legacy/Select/Select.tsx b/packages/grafana-ui/src/components/Forms/Legacy/Select/Select.tsx index a45de860d6c..2baa2101721 100644 --- a/packages/grafana-ui/src/components/Forms/Legacy/Select/Select.tsx +++ b/packages/grafana-ui/src/components/Forms/Legacy/Select/Select.tsx @@ -2,21 +2,23 @@ import classNames from 'classnames'; import React, { PureComponent } from 'react'; import { default as ReactSelect, components } from 'react-select'; -import Creatable from 'react-select/creatable'; import { default as ReactAsyncSelect } from 'react-select/async'; +import Creatable from 'react-select/creatable'; // Components -import { SelectOption } from './SelectOption'; +import { GrafanaTheme2, SelectableValue } from '@grafana/data'; + +import { ThemeContext } from '../../../../themes'; +import { CustomScrollbar } from '../../../CustomScrollbar/CustomScrollbar'; import { SelectOptionGroup } from '../../../Select/SelectOptionGroup'; import { SingleValue } from '../../../Select/SingleValue'; +import resetSelectStyles from '../../../Select/resetSelectStyles'; import { SelectCommonProps, SelectAsyncProps } from '../../../Select/types'; +import { Tooltip, PopoverContent } from '../../../Tooltip'; + import IndicatorsContainer from './IndicatorsContainer'; import NoOptionsMessage from './NoOptionsMessage'; -import resetSelectStyles from '../../../Select/resetSelectStyles'; -import { CustomScrollbar } from '../../../CustomScrollbar/CustomScrollbar'; -import { Tooltip, PopoverContent } from '../../../Tooltip'; -import { GrafanaTheme2, SelectableValue } from '@grafana/data'; -import { ThemeContext } from '../../../../themes'; +import { SelectOption } from './SelectOption'; /** * Changes in new selects: diff --git a/packages/grafana-ui/src/components/Forms/Legacy/Select/SelectOption.test.tsx b/packages/grafana-ui/src/components/Forms/Legacy/Select/SelectOption.test.tsx index aa68baed4c6..091601dcd5f 100644 --- a/packages/grafana-ui/src/components/Forms/Legacy/Select/SelectOption.test.tsx +++ b/packages/grafana-ui/src/components/Forms/Legacy/Select/SelectOption.test.tsx @@ -1,7 +1,8 @@ import React from 'react'; -import renderer from 'react-test-renderer'; -import SelectOption from './SelectOption'; import { OptionProps } from 'react-select'; +import renderer from 'react-test-renderer'; + +import SelectOption from './SelectOption'; const model: OptionProps = { data: jest.fn(), diff --git a/packages/grafana-ui/src/components/Forms/Legacy/Select/SelectOption.tsx b/packages/grafana-ui/src/components/Forms/Legacy/Select/SelectOption.tsx index b0f49f78f33..ecfa3948e54 100644 --- a/packages/grafana-ui/src/components/Forms/Legacy/Select/SelectOption.tsx +++ b/packages/grafana-ui/src/components/Forms/Legacy/Select/SelectOption.tsx @@ -1,7 +1,8 @@ import React from 'react'; -import { Icon } from '../../../Icon/Icon'; import { components, OptionProps } from 'react-select'; +import { Icon } from '../../../Icon/Icon'; + // https://github.com/JedWatson/react-select/issues/3038 export interface ExtendedOptionProps extends OptionProps { data: { diff --git a/packages/grafana-ui/src/components/Forms/Legacy/Switch/Switch.story.internal.tsx b/packages/grafana-ui/src/components/Forms/Legacy/Switch/Switch.story.internal.tsx index 699c8bfbfaf..d6ab701e5e1 100644 --- a/packages/grafana-ui/src/components/Forms/Legacy/Switch/Switch.story.internal.tsx +++ b/packages/grafana-ui/src/components/Forms/Legacy/Switch/Switch.story.internal.tsx @@ -1,7 +1,7 @@ +import { Meta, Story } from '@storybook/react'; import React, { useState } from 'react'; import { Props, Switch } from './Switch'; -import { Meta, Story } from '@storybook/react'; export default { title: 'Forms/Legacy/Switch', diff --git a/packages/grafana-ui/src/components/Forms/Legacy/Switch/Switch.tsx b/packages/grafana-ui/src/components/Forms/Legacy/Switch/Switch.tsx index 30a380cd470..f35ee957060 100644 --- a/packages/grafana-ui/src/components/Forms/Legacy/Switch/Switch.tsx +++ b/packages/grafana-ui/src/components/Forms/Legacy/Switch/Switch.tsx @@ -1,8 +1,9 @@ -import React, { PureComponent } from 'react'; -import { uniqueId } from 'lodash'; import { Placement } from '@popperjs/core'; -import { Tooltip } from '../../../Tooltip/Tooltip'; +import { uniqueId } from 'lodash'; +import React, { PureComponent } from 'react'; + import { Icon } from '../../..'; +import { Tooltip } from '../../../Tooltip/Tooltip'; export interface Props { label: string; diff --git a/packages/grafana-ui/src/components/Forms/Legend.story.tsx b/packages/grafana-ui/src/components/Forms/Legend.story.tsx index 75acb2e7574..d7e4fc8e081 100644 --- a/packages/grafana-ui/src/components/Forms/Legend.story.tsx +++ b/packages/grafana-ui/src/components/Forms/Legend.story.tsx @@ -1,7 +1,8 @@ -import React from 'react'; import { Meta, Story } from '@storybook/react'; +import React from 'react'; import { Legend } from '@grafana/ui'; + import mdx from './Legend.mdx'; export default { diff --git a/packages/grafana-ui/src/components/Forms/Legend.tsx b/packages/grafana-ui/src/components/Forms/Legend.tsx index 8e75237c7a1..523792e0869 100644 --- a/packages/grafana-ui/src/components/Forms/Legend.tsx +++ b/packages/grafana-ui/src/components/Forms/Legend.tsx @@ -1,7 +1,9 @@ -import React, { ReactNode } from 'react'; -import { useTheme, stylesFactory } from '../../themes'; -import { GrafanaTheme } from '@grafana/data'; import { css, cx } from '@emotion/css'; +import React, { ReactNode } from 'react'; + +import { GrafanaTheme } from '@grafana/data'; + +import { useTheme, stylesFactory } from '../../themes'; export interface LabelProps extends React.HTMLAttributes { children: string | ReactNode; diff --git a/packages/grafana-ui/src/components/Forms/RadioButtonGroup/RadioButton.tsx b/packages/grafana-ui/src/components/Forms/RadioButtonGroup/RadioButton.tsx index c72688619be..7c1d0768e10 100644 --- a/packages/grafana-ui/src/components/Forms/RadioButtonGroup/RadioButton.tsx +++ b/packages/grafana-ui/src/components/Forms/RadioButtonGroup/RadioButton.tsx @@ -1,11 +1,13 @@ -import React from 'react'; -import { useTheme2, stylesFactory } from '../../../themes'; -import { GrafanaTheme2 } from '@grafana/data'; import { css } from '@emotion/css'; -import { getPropertiesForButtonSize } from '../commonStyles'; -import { getFocusStyles, getMouseFocusStyles } from '../../../themes/mixins'; +import React from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; import { StringSelector } from '@grafana/e2e-selectors'; +import { useTheme2, stylesFactory } from '../../../themes'; +import { getFocusStyles, getMouseFocusStyles } from '../../../themes/mixins'; +import { getPropertiesForButtonSize } from '../commonStyles'; + export type RadioButtonSize = 'sm' | 'md'; export interface RadioButtonProps { diff --git a/packages/grafana-ui/src/components/Forms/RadioButtonGroup/RadioButtonGroup.story.tsx b/packages/grafana-ui/src/components/Forms/RadioButtonGroup/RadioButtonGroup.story.tsx index 40799595321..3a46d409047 100644 --- a/packages/grafana-ui/src/components/Forms/RadioButtonGroup/RadioButtonGroup.story.tsx +++ b/packages/grafana-ui/src/components/Forms/RadioButtonGroup/RadioButtonGroup.story.tsx @@ -1,7 +1,8 @@ -import React, { useState } from 'react'; -import mdx from './RadioButtonGroup.mdx'; -import { RadioButtonGroup } from './RadioButtonGroup'; import { Story } from '@storybook/react'; +import React, { useState } from 'react'; + +import { RadioButtonGroup } from './RadioButtonGroup'; +import mdx from './RadioButtonGroup.mdx'; export default { title: 'Forms/RadioButtonGroup', diff --git a/packages/grafana-ui/src/components/Forms/RadioButtonGroup/RadioButtonGroup.tsx b/packages/grafana-ui/src/components/Forms/RadioButtonGroup/RadioButtonGroup.tsx index c817ef4d391..135c0689b98 100644 --- a/packages/grafana-ui/src/components/Forms/RadioButtonGroup/RadioButtonGroup.tsx +++ b/packages/grafana-ui/src/components/Forms/RadioButtonGroup/RadioButtonGroup.tsx @@ -1,11 +1,14 @@ -import React, { useCallback, useEffect, useRef } from 'react'; import { css, cx } from '@emotion/css'; import { uniqueId } from 'lodash'; +import React, { useCallback, useEffect, useRef } from 'react'; + import { GrafanaTheme2, SelectableValue } from '@grafana/data'; -import { RadioButtonSize, RadioButton } from './RadioButton'; -import { Icon } from '../../Icon/Icon'; -import { IconName } from '../../../types/icon'; + import { useStyles2 } from '../../../themes'; +import { IconName } from '../../../types/icon'; +import { Icon } from '../../Icon/Icon'; + +import { RadioButtonSize, RadioButton } from './RadioButton'; export interface RadioButtonGroupProps { value?: T; diff --git a/packages/grafana-ui/src/components/Forms/commonStyles.ts b/packages/grafana-ui/src/components/Forms/commonStyles.ts index 04b00612770..4107d030e10 100644 --- a/packages/grafana-ui/src/components/Forms/commonStyles.ts +++ b/packages/grafana-ui/src/components/Forms/commonStyles.ts @@ -1,5 +1,7 @@ import { css, cx } from '@emotion/css'; + import { GrafanaTheme, GrafanaTheme2 } from '@grafana/data'; + import { focusCss } from '../../themes/mixins'; import { ComponentSize } from '../../types/size'; diff --git a/packages/grafana-ui/src/components/Forms/getFormStyles.ts b/packages/grafana-ui/src/components/Forms/getFormStyles.ts index 6d0faf7b8e5..a730ab50efd 100644 --- a/packages/grafana-ui/src/components/Forms/getFormStyles.ts +++ b/packages/grafana-ui/src/components/Forms/getFormStyles.ts @@ -1,12 +1,14 @@ -import { stylesFactory } from '../../themes'; import { GrafanaTheme2 } from '@grafana/data'; + +import { stylesFactory } from '../../themes'; +import { ComponentSize } from '../../types/size'; +import { getButtonStyles, ButtonVariant } from '../Button'; +import { getInputStyles } from '../Input/Input'; + +import { getCheckboxStyles } from './Checkbox'; +import { getFieldValidationMessageStyles } from './FieldValidationMessage'; import { getLabelStyles } from './Label'; import { getLegendStyles } from './Legend'; -import { getFieldValidationMessageStyles } from './FieldValidationMessage'; -import { getButtonStyles, ButtonVariant } from '../Button'; -import { ComponentSize } from '../../types/size'; -import { getInputStyles } from '../Input/Input'; -import { getCheckboxStyles } from './Checkbox'; /** @deprecated */ export const getFormStyles = stylesFactory( diff --git a/packages/grafana-ui/src/components/Gauge/Gauge.test.tsx b/packages/grafana-ui/src/components/Gauge/Gauge.test.tsx index 251e50e8d0a..9a1e0ebdd80 100644 --- a/packages/grafana-ui/src/components/Gauge/Gauge.test.tsx +++ b/packages/grafana-ui/src/components/Gauge/Gauge.test.tsx @@ -1,9 +1,11 @@ -import React from 'react'; import { shallow } from 'enzyme'; +import React from 'react'; + +import { ThresholdsMode, FieldConfig, FieldColorModeId } from '@grafana/data'; + +import { getTheme } from '../../themes'; import { Gauge, Props } from './Gauge'; -import { getTheme } from '../../themes'; -import { ThresholdsMode, FieldConfig, FieldColorModeId } from '@grafana/data'; jest.mock('jquery', () => ({ plot: jest.fn(), diff --git a/packages/grafana-ui/src/components/Gauge/Gauge.tsx b/packages/grafana-ui/src/components/Gauge/Gauge.tsx index 0be0a4da88a..f35c53901f7 100644 --- a/packages/grafana-ui/src/components/Gauge/Gauge.tsx +++ b/packages/grafana-ui/src/components/Gauge/Gauge.tsx @@ -1,5 +1,6 @@ -import React, { PureComponent } from 'react'; import $ from 'jquery'; +import React, { PureComponent } from 'react'; + import { DisplayValue, formattedValueToString, @@ -14,6 +15,7 @@ import { FALLBACK_COLOR, TextDisplayOptions, } from '@grafana/data'; + import { Themeable } from '../../types'; import { calculateFontSize } from '../../utils/measureText'; diff --git a/packages/grafana-ui/src/components/Graph/Graph.test.tsx b/packages/grafana-ui/src/components/Graph/Graph.test.tsx index 68dcd1a3669..628538d33f7 100644 --- a/packages/grafana-ui/src/components/Graph/Graph.test.tsx +++ b/packages/grafana-ui/src/components/Graph/Graph.test.tsx @@ -1,9 +1,12 @@ -import React from 'react'; import { mount } from 'enzyme'; -import Graph from './Graph'; -import { TooltipDisplayMode } from '@grafana/schema'; -import { VizTooltip } from '../VizTooltip'; +import React from 'react'; + import { GraphSeriesXY, FieldType, ArrayVector, dateTime, FieldColorModeId, DisplayProcessor } from '@grafana/data'; +import { TooltipDisplayMode } from '@grafana/schema'; + +import { VizTooltip } from '../VizTooltip'; + +import Graph from './Graph'; const display: DisplayProcessor = (v) => ({ numeric: v, text: String(v), color: 'red' }); diff --git a/packages/grafana-ui/src/components/Graph/Graph.tsx b/packages/grafana-ui/src/components/Graph/Graph.tsx index 9938e158cf8..3a7d3aea487 100644 --- a/packages/grafana-ui/src/components/Graph/Graph.tsx +++ b/packages/grafana-ui/src/components/Graph/Graph.tsx @@ -1,15 +1,18 @@ // Libraries import $ from 'jquery'; -import React, { PureComponent } from 'react'; import { uniqBy } from 'lodash'; +import React, { PureComponent } from 'react'; + // Types -import { TooltipDisplayMode } from '@grafana/schema'; import { TimeRange, GraphSeriesXY, TimeZone, createDimension } from '@grafana/data'; -import { FlotPosition, FlotItem } from './types'; +import { TooltipDisplayMode } from '@grafana/schema'; + import { VizTooltipProps, VizTooltipContentProps, ActiveDimensions, VizTooltip } from '../VizTooltip'; -import { GraphTooltip } from './GraphTooltip/GraphTooltip'; + import { GraphContextMenu, GraphContextMenuProps, ContextDimensions } from './GraphContextMenu'; +import { GraphTooltip } from './GraphTooltip/GraphTooltip'; import { GraphDimensions } from './GraphTooltip/types'; +import { FlotPosition, FlotItem } from './types'; import { graphTimeFormat, graphTickFormatter } from './utils'; export interface GraphProps { diff --git a/packages/grafana-ui/src/components/Graph/GraphContextMenu.tsx b/packages/grafana-ui/src/components/Graph/GraphContextMenu.tsx index cd0dba40497..4ec9c631470 100644 --- a/packages/grafana-ui/src/components/Graph/GraphContextMenu.tsx +++ b/packages/grafana-ui/src/components/Graph/GraphContextMenu.tsx @@ -1,6 +1,6 @@ +import { css } from '@emotion/css'; import React from 'react'; -import { ContextMenu, ContextMenuProps } from '../ContextMenu/ContextMenu'; -import { GraphDimensions } from './GraphTooltip/types'; + import { FlotDataPoint, getValueFromDimension, @@ -9,13 +9,16 @@ import { TimeZone, FormattedValue, } from '@grafana/data'; + import { useTheme } from '../../themes'; -import { HorizontalGroup } from '../Layout/Layout'; +import { ContextMenu, ContextMenuProps } from '../ContextMenu/ContextMenu'; import { FormattedValueDisplay } from '../FormattedValueDisplay/FormattedValueDisplay'; -import { SeriesIcon } from '../VizLegend/SeriesIcon'; -import { css } from '@emotion/css'; +import { HorizontalGroup } from '../Layout/Layout'; import { MenuGroup, MenuGroupProps } from '../Menu/MenuGroup'; import { MenuItem } from '../Menu/MenuItem'; +import { SeriesIcon } from '../VizLegend/SeriesIcon'; + +import { GraphDimensions } from './GraphTooltip/types'; export type ContextDimensions = { [key in keyof T]: [number, number | undefined] | null }; diff --git a/packages/grafana-ui/src/components/Graph/GraphSeriesToggler.tsx b/packages/grafana-ui/src/components/Graph/GraphSeriesToggler.tsx index c646d090f45..cd1a33aa4d7 100644 --- a/packages/grafana-ui/src/components/Graph/GraphSeriesToggler.tsx +++ b/packages/grafana-ui/src/components/Graph/GraphSeriesToggler.tsx @@ -1,6 +1,7 @@ -import React from 'react'; -import { GraphSeriesXY } from '@grafana/data'; import { difference, isEqual } from 'lodash'; +import React from 'react'; + +import { GraphSeriesXY } from '@grafana/data'; export interface GraphSeriesTogglerAPI { onSeriesToggle: (label: string, event: React.MouseEvent) => void; diff --git a/packages/grafana-ui/src/components/Graph/GraphTooltip/GraphTooltip.tsx b/packages/grafana-ui/src/components/Graph/GraphTooltip/GraphTooltip.tsx index 6472dd40119..1e86a5da86e 100644 --- a/packages/grafana-ui/src/components/Graph/GraphTooltip/GraphTooltip.tsx +++ b/packages/grafana-ui/src/components/Graph/GraphTooltip/GraphTooltip.tsx @@ -1,7 +1,9 @@ import React from 'react'; + import { VizTooltipContentProps } from '../../VizTooltip'; -import { SingleModeGraphTooltip } from './SingleModeGraphTooltip'; + import { MultiModeGraphTooltip } from './MultiModeGraphTooltip'; +import { SingleModeGraphTooltip } from './SingleModeGraphTooltip'; import { GraphDimensions } from './types'; export const GraphTooltip: React.FC> = ({ diff --git a/packages/grafana-ui/src/components/Graph/GraphTooltip/MultiModeGraphTooltip.test.tsx b/packages/grafana-ui/src/components/Graph/GraphTooltip/MultiModeGraphTooltip.test.tsx index 067627d0380..b3af9200fbb 100644 --- a/packages/grafana-ui/src/components/Graph/GraphTooltip/MultiModeGraphTooltip.test.tsx +++ b/packages/grafana-ui/src/components/Graph/GraphTooltip/MultiModeGraphTooltip.test.tsx @@ -1,10 +1,13 @@ -import React from 'react'; import { mount } from 'enzyme'; -import { MultiModeGraphTooltip } from './MultiModeGraphTooltip'; +import React from 'react'; + import { createDimension, ArrayVector, FieldType, DisplayProcessor } from '@grafana/data'; -import { GraphDimensions } from './types'; + import { ActiveDimensions } from '../../VizTooltip'; +import { MultiModeGraphTooltip } from './MultiModeGraphTooltip'; +import { GraphDimensions } from './types'; + let dimensions: GraphDimensions; describe('MultiModeGraphTooltip', () => { diff --git a/packages/grafana-ui/src/components/Graph/GraphTooltip/MultiModeGraphTooltip.tsx b/packages/grafana-ui/src/components/Graph/GraphTooltip/MultiModeGraphTooltip.tsx index 73a1988704b..973d5e059d7 100644 --- a/packages/grafana-ui/src/components/Graph/GraphTooltip/MultiModeGraphTooltip.tsx +++ b/packages/grafana-ui/src/components/Graph/GraphTooltip/MultiModeGraphTooltip.tsx @@ -1,10 +1,13 @@ import React from 'react'; -import { SeriesTable } from '../../VizTooltip'; -import { GraphTooltipContentProps } from './types'; -import { getMultiSeriesGraphHoverInfo } from '../utils'; -import { FlotPosition } from '../types'; + import { getValueFromDimension } from '@grafana/data'; +import { SeriesTable } from '../../VizTooltip'; +import { FlotPosition } from '../types'; +import { getMultiSeriesGraphHoverInfo } from '../utils'; + +import { GraphTooltipContentProps } from './types'; + export const MultiModeGraphTooltip: React.FC< GraphTooltipContentProps & { // We expect position to figure out correct values when not hovering over a datapoint diff --git a/packages/grafana-ui/src/components/Graph/GraphTooltip/SingleModeGraphTooltip.tsx b/packages/grafana-ui/src/components/Graph/GraphTooltip/SingleModeGraphTooltip.tsx index 716fda9d34c..6335d6a7d76 100644 --- a/packages/grafana-ui/src/components/Graph/GraphTooltip/SingleModeGraphTooltip.tsx +++ b/packages/grafana-ui/src/components/Graph/GraphTooltip/SingleModeGraphTooltip.tsx @@ -1,11 +1,14 @@ import React from 'react'; + import { getValueFromDimension, getColumnFromDimension, formattedValueToString, getFieldDisplayName, } from '@grafana/data'; + import { SeriesTable } from '../../VizTooltip'; + import { GraphTooltipContentProps } from './types'; export const SingleModeGraphTooltip: React.FC = ({ diff --git a/packages/grafana-ui/src/components/Graph/GraphTooltip/types.ts b/packages/grafana-ui/src/components/Graph/GraphTooltip/types.ts index bc807a9a93d..ccf04ef1175 100644 --- a/packages/grafana-ui/src/components/Graph/GraphTooltip/types.ts +++ b/packages/grafana-ui/src/components/Graph/GraphTooltip/types.ts @@ -1,6 +1,7 @@ -import { ActiveDimensions } from '../../VizTooltip'; import { Dimension, Dimensions, TimeZone } from '@grafana/data'; +import { ActiveDimensions } from '../../VizTooltip'; + export interface GraphDimensions extends Dimensions { xAxis: Dimension; yAxis: Dimension; diff --git a/packages/grafana-ui/src/components/Graph/GraphWithLegend.story.internal.tsx b/packages/grafana-ui/src/components/Graph/GraphWithLegend.story.internal.tsx index 03748655594..723e4d3c3b1 100644 --- a/packages/grafana-ui/src/components/Graph/GraphWithLegend.story.internal.tsx +++ b/packages/grafana-ui/src/components/Graph/GraphWithLegend.story.internal.tsx @@ -1,10 +1,12 @@ +import { Story } from '@storybook/react'; import React from 'react'; -import { Story } from '@storybook/react'; -import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; -import { GraphWithLegend, GraphWithLegendProps } from './GraphWithLegend'; -import { LegendDisplayMode } from '@grafana/schema'; import { GraphSeriesXY, FieldType, ArrayVector, dateTime, FieldColorModeId } from '@grafana/data'; +import { LegendDisplayMode } from '@grafana/schema'; + +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; + +import { GraphWithLegend, GraphWithLegendProps } from './GraphWithLegend'; export default { title: 'Visualizations/Graph/GraphWithLegend', diff --git a/packages/grafana-ui/src/components/Graph/GraphWithLegend.tsx b/packages/grafana-ui/src/components/Graph/GraphWithLegend.tsx index f65a981fbfa..693b8763024 100644 --- a/packages/grafana-ui/src/components/Graph/GraphWithLegend.tsx +++ b/packages/grafana-ui/src/components/Graph/GraphWithLegend.tsx @@ -1,15 +1,17 @@ // Libraries -import React from 'react'; import { css } from '@emotion/css'; +import React from 'react'; + import { GraphSeriesValue } from '@grafana/data'; +import { LegendDisplayMode, LegendPlacement } from '@grafana/schema'; + +import { stylesFactory } from '../../themes'; +import { CustomScrollbar } from '../CustomScrollbar/CustomScrollbar'; +import { VizLegend } from '../VizLegend/VizLegend'; +import { VizLegendItem } from '../VizLegend/types'; import { Graph, GraphProps } from './Graph'; -import { VizLegendItem } from '../VizLegend/types'; -import { LegendDisplayMode, LegendPlacement } from '@grafana/schema'; -import { VizLegend } from '../VizLegend/VizLegend'; -import { CustomScrollbar } from '../CustomScrollbar/CustomScrollbar'; -import { stylesFactory } from '../../themes'; export interface GraphWithLegendProps extends GraphProps { legendDisplayMode: LegendDisplayMode; diff --git a/packages/grafana-ui/src/components/Graph/utils.test.ts b/packages/grafana-ui/src/components/Graph/utils.test.ts index f1209a088d5..742cd90acb6 100644 --- a/packages/grafana-ui/src/components/Graph/utils.test.ts +++ b/packages/grafana-ui/src/components/Graph/utils.test.ts @@ -9,7 +9,9 @@ import { createTheme, DataFrame, } from '@grafana/data'; + import { getTheme } from '../../themes'; + import { getMultiSeriesGraphHoverInfo, findHoverIndexFromData, graphTimeFormat } from './utils'; const mockResult = ( diff --git a/packages/grafana-ui/src/components/GraphNG/GraphNG.tsx b/packages/grafana-ui/src/components/GraphNG/GraphNG.tsx index e02a291226a..9783be08b37 100755 --- a/packages/grafana-ui/src/components/GraphNG/GraphNG.tsx +++ b/packages/grafana-ui/src/components/GraphNG/GraphNG.tsx @@ -1,7 +1,8 @@ import React from 'react'; +import { Subscription } from 'rxjs'; +import { throttleTime } from 'rxjs/operators'; import uPlot, { AlignedData } from 'uplot'; -import { Themeable2 } from '../../types'; -import { findMidPointYPosition, pluginLog } from '../uPlot/utils'; + import { DataFrame, DataHoverClearEvent, @@ -13,17 +14,19 @@ import { TimeRange, TimeZone, } from '@grafana/data'; -import { preparePlotFrame as defaultPreparePlotFrame } from './utils'; import { VizLegendOptions } from '@grafana/schema'; + +import { Themeable2 } from '../../types'; import { PanelContext, PanelContextRoot } from '../PanelChrome/PanelContext'; -import { Subscription } from 'rxjs'; -import { throttleTime } from 'rxjs/operators'; -import { GraphNGLegendEvent, XYFieldMatchers } from './types'; -import { Renderers, UPlotConfigBuilder } from '../uPlot/config/UPlotConfigBuilder'; import { VizLayout } from '../VizLayout/VizLayout'; import { UPlotChart } from '../uPlot/Plot'; -import { ScaleProps } from '../uPlot/config/UPlotScaleBuilder'; import { AxisProps } from '../uPlot/config/UPlotAxisBuilder'; +import { Renderers, UPlotConfigBuilder } from '../uPlot/config/UPlotConfigBuilder'; +import { ScaleProps } from '../uPlot/config/UPlotScaleBuilder'; +import { findMidPointYPosition, pluginLog } from '../uPlot/utils'; + +import { GraphNGLegendEvent, XYFieldMatchers } from './types'; +import { preparePlotFrame as defaultPreparePlotFrame } from './utils'; /** * @internal -- not a public API diff --git a/packages/grafana-ui/src/components/GraphNG/hooks.ts b/packages/grafana-ui/src/components/GraphNG/hooks.ts index 1a8db1a0449..c21a7a9f775 100644 --- a/packages/grafana-ui/src/components/GraphNG/hooks.ts +++ b/packages/grafana-ui/src/components/GraphNG/hooks.ts @@ -1,7 +1,9 @@ -import { DataFrame, DataFrameFieldIndex, Field } from '@grafana/data'; -import { XYFieldMatchers } from './types'; import React, { useCallback, useContext } from 'react'; +import { DataFrame, DataFrameFieldIndex, Field } from '@grafana/data'; + +import { XYFieldMatchers } from './types'; + /** @alpha */ interface GraphNGContextType { mapSeriesIndexToDataFrameFieldIndex: (index: number) => DataFrameFieldIndex; diff --git a/packages/grafana-ui/src/components/GraphNG/nullInsertThreshold.test.ts b/packages/grafana-ui/src/components/GraphNG/nullInsertThreshold.test.ts index f56b3f4d777..2888434cf9d 100644 --- a/packages/grafana-ui/src/components/GraphNG/nullInsertThreshold.test.ts +++ b/packages/grafana-ui/src/components/GraphNG/nullInsertThreshold.test.ts @@ -1,4 +1,5 @@ import { ArrayVector, FieldType, MutableDataFrame } from '@grafana/data'; + import { applyNullInsertThreshold } from './nullInsertThreshold'; function randInt(min: number, max: number) { diff --git a/packages/grafana-ui/src/components/GraphNG/types.ts b/packages/grafana-ui/src/components/GraphNG/types.ts index 33553ec5d5c..534cd9edf4d 100644 --- a/packages/grafana-ui/src/components/GraphNG/types.ts +++ b/packages/grafana-ui/src/components/GraphNG/types.ts @@ -1,4 +1,5 @@ import { DataFrameFieldIndex, FieldMatcher } from '@grafana/data'; + import { SeriesVisibilityChangeMode } from '../PanelChrome'; /** diff --git a/packages/grafana-ui/src/components/GraphNG/utils.test.ts b/packages/grafana-ui/src/components/GraphNG/utils.test.ts index 0cc6b59533c..7395c859226 100644 --- a/packages/grafana-ui/src/components/GraphNG/utils.test.ts +++ b/packages/grafana-ui/src/components/GraphNG/utils.test.ts @@ -1,5 +1,3 @@ -import { preparePlotFrame } from './utils'; -import { preparePlotConfigBuilder } from '../TimeSeries/utils'; import { createTheme, DashboardCursorSync, @@ -22,6 +20,10 @@ import { StackingMode, } from '@grafana/schema'; +import { preparePlotConfigBuilder } from '../TimeSeries/utils'; + +import { preparePlotFrame } from './utils'; + function mockDataFrame() { const df1 = new MutableDataFrame({ refId: 'A', diff --git a/packages/grafana-ui/src/components/GraphNG/utils.ts b/packages/grafana-ui/src/components/GraphNG/utils.ts index 30450b0dd01..41558d9bd3c 100644 --- a/packages/grafana-ui/src/components/GraphNG/utils.ts +++ b/packages/grafana-ui/src/components/GraphNG/utils.ts @@ -1,7 +1,4 @@ -import { XYFieldMatchers } from './types'; import { ArrayVector, DataFrame, FieldConfig, FieldType, outerJoinDataFrames, TimeRange } from '@grafana/data'; -import { nullToUndefThreshold } from './nullToUndefThreshold'; -import { applyNullInsertThreshold } from './nullInsertThreshold'; import { AxisPlacement, GraphDrawStyle, @@ -9,7 +6,11 @@ import { ScaleDistribution, ScaleDistributionConfig, } from '@grafana/schema'; + import { FIXED_UNIT } from './GraphNG'; +import { applyNullInsertThreshold } from './nullInsertThreshold'; +import { nullToUndefThreshold } from './nullToUndefThreshold'; +import { XYFieldMatchers } from './types'; // will mutate the DataFrame's fields' values function applySpanNullsThresholds(frame: DataFrame) { diff --git a/packages/grafana-ui/src/components/Icon/Icon.story.tsx b/packages/grafana-ui/src/components/Icon/Icon.story.tsx index 6a1a270ee26..5f817f080a2 100644 --- a/packages/grafana-ui/src/components/Icon/Icon.story.tsx +++ b/packages/grafana-ui/src/components/Icon/Icon.story.tsx @@ -1,9 +1,12 @@ -import React, { ChangeEvent, useState } from 'react'; import { css } from '@emotion/css'; +import React, { ChangeEvent, useState } from 'react'; + import { Input, Field, Icon } from '@grafana/ui'; + +import { useTheme } from '../../themes'; import { getAvailableIcons, IconName } from '../../types'; import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; -import { useTheme } from '../../themes'; + import mdx from './Icon.mdx'; export default { diff --git a/packages/grafana-ui/src/components/Icon/Icon.tsx b/packages/grafana-ui/src/components/Icon/Icon.tsx index 4d78992869a..230a82a2c26 100644 --- a/packages/grafana-ui/src/components/Icon/Icon.tsx +++ b/packages/grafana-ui/src/components/Icon/Icon.tsx @@ -1,10 +1,13 @@ -import React from 'react'; import { css, cx } from '@emotion/css'; -import { GrafanaTheme } from '@grafana/data'; -import { stylesFactory } from '../../themes/stylesFactory'; -import { useTheme } from '../../themes/ThemeContext'; -import { IconName, IconType, IconSize } from '../../types/icon'; +import React from 'react'; import SVG from 'react-inlinesvg'; + +import { GrafanaTheme } from '@grafana/data'; + +import { useTheme } from '../../themes/ThemeContext'; +import { stylesFactory } from '../../themes/stylesFactory'; +import { IconName, IconType, IconSize } from '../../types/icon'; + import { cacheInitialized, initIconCache, iconRoot } from './iconBundle'; import { getIconSubDir, getSvgSize } from './utils'; diff --git a/packages/grafana-ui/src/components/Icon/iconBundle.ts b/packages/grafana-ui/src/components/Icon/iconBundle.ts index 3d7d280c83e..88e9fb7c5ac 100644 --- a/packages/grafana-ui/src/components/Icon/iconBundle.ts +++ b/packages/grafana-ui/src/components/Icon/iconBundle.ts @@ -1,15 +1,24 @@ // This file was autogenerated from // https://github.com/grafana/icons -import { cacheStore } from 'react-inlinesvg'; - -export let cacheInitialized = false; -export let iconRoot = 'public/img/icons'; - -function cacheItem(content: string, path: string) { - cacheStore[iconRoot + path] = { content, status: 'loaded', queue: [] }; -} - +import u1141 from '!!raw-loader!../../../../../public/img/icons/custom/gf-bar-alignment-after.svg'; +import u1142 from '!!raw-loader!../../../../../public/img/icons/custom/gf-bar-alignment-before.svg'; +import u1143 from '!!raw-loader!../../../../../public/img/icons/custom/gf-bar-alignment-center.svg'; +import u1137 from '!!raw-loader!../../../../../public/img/icons/custom/gf-grid.svg'; +import u1144 from '!!raw-loader!../../../../../public/img/icons/custom/gf-interpolation-linear.svg'; +import u1145 from '!!raw-loader!../../../../../public/img/icons/custom/gf-interpolation-smooth.svg'; +import u1146 from '!!raw-loader!../../../../../public/img/icons/custom/gf-interpolation-step-after.svg'; +import u1147 from '!!raw-loader!../../../../../public/img/icons/custom/gf-interpolation-step-before.svg'; +import u1138 from '!!raw-loader!../../../../../public/img/icons/custom/gf-landscape.svg'; +import u1139 from '!!raw-loader!../../../../../public/img/icons/custom/gf-layout-simple.svg'; +import u1148 from '!!raw-loader!../../../../../public/img/icons/custom/gf-logs.svg'; +import u1140 from '!!raw-loader!../../../../../public/img/icons/custom/gf-portrait.svg'; +import u1149 from '!!raw-loader!../../../../../public/img/icons/mono/favorite.svg'; +import u1150 from '!!raw-loader!../../../../../public/img/icons/mono/grafana.svg'; +import u1152 from '!!raw-loader!../../../../../public/img/icons/mono/heart-break.svg'; +import u1151 from '!!raw-loader!../../../../../public/img/icons/mono/heart.svg'; +import u1154 from '!!raw-loader!../../../../../public/img/icons/mono/library-panel.svg'; +import u1153 from '!!raw-loader!../../../../../public/img/icons/mono/panel-add.svg'; import u1001 from '!!raw-loader!../../../../../public/img/icons/unicons/angle-double-down.svg'; import u1002 from '!!raw-loader!../../../../../public/img/icons/unicons/angle-double-right.svg'; import u1003 from '!!raw-loader!../../../../../public/img/icons/unicons/angle-down.svg'; @@ -17,44 +26,47 @@ import u1004 from '!!raw-loader!../../../../../public/img/icons/unicons/angle-le import u1005 from '!!raw-loader!../../../../../public/img/icons/unicons/angle-right.svg'; import u1006 from '!!raw-loader!../../../../../public/img/icons/unicons/angle-up.svg'; import u1007 from '!!raw-loader!../../../../../public/img/icons/unicons/apps.svg'; -import u1008 from '!!raw-loader!../../../../../public/img/icons/unicons/arrow.svg'; import u1009 from '!!raw-loader!../../../../../public/img/icons/unicons/arrow-down.svg'; import u1010 from '!!raw-loader!../../../../../public/img/icons/unicons/arrow-from-right.svg'; import u1011 from '!!raw-loader!../../../../../public/img/icons/unicons/arrow-left.svg'; import u1012 from '!!raw-loader!../../../../../public/img/icons/unicons/arrow-random.svg'; import u1013 from '!!raw-loader!../../../../../public/img/icons/unicons/arrow-right.svg'; import u1014 from '!!raw-loader!../../../../../public/img/icons/unicons/arrow-up.svg'; +import u1008 from '!!raw-loader!../../../../../public/img/icons/unicons/arrow.svg'; import u1015 from '!!raw-loader!../../../../../public/img/icons/unicons/arrows-h.svg'; import u1016 from '!!raw-loader!../../../../../public/img/icons/unicons/backward.svg'; import u1017 from '!!raw-loader!../../../../../public/img/icons/unicons/bars.svg'; -import u1018 from '!!raw-loader!../../../../../public/img/icons/unicons/bell.svg'; import u1019 from '!!raw-loader!../../../../../public/img/icons/unicons/bell-slash.svg'; +import u1018 from '!!raw-loader!../../../../../public/img/icons/unicons/bell.svg'; import u1020 from '!!raw-loader!../../../../../public/img/icons/unicons/bolt.svg'; -import u1021 from '!!raw-loader!../../../../../public/img/icons/unicons/book.svg'; import u1022 from '!!raw-loader!../../../../../public/img/icons/unicons/book-open.svg'; +import u1021 from '!!raw-loader!../../../../../public/img/icons/unicons/book.svg'; import u1023 from '!!raw-loader!../../../../../public/img/icons/unicons/brackets-curly.svg'; import u1024 from '!!raw-loader!../../../../../public/img/icons/unicons/bug.svg'; import u1025 from '!!raw-loader!../../../../../public/img/icons/unicons/building.svg'; import u1026 from '!!raw-loader!../../../../../public/img/icons/unicons/calculator-alt.svg'; import u1027 from '!!raw-loader!../../../../../public/img/icons/unicons/calendar-alt.svg'; import u1028 from '!!raw-loader!../../../../../public/img/icons/unicons/camera.svg'; +import u1136 from '!!raw-loader!../../../../../public/img/icons/unicons/capture.svg'; import u1029 from '!!raw-loader!../../../../../public/img/icons/unicons/channel-add.svg'; import u1030 from '!!raw-loader!../../../../../public/img/icons/unicons/chart-line.svg'; -import u1031 from '!!raw-loader!../../../../../public/img/icons/unicons/check.svg'; import u1032 from '!!raw-loader!../../../../../public/img/icons/unicons/check-circle.svg'; +import u1031 from '!!raw-loader!../../../../../public/img/icons/unicons/check.svg'; import u1033 from '!!raw-loader!../../../../../public/img/icons/unicons/circle.svg'; import u1034 from '!!raw-loader!../../../../../public/img/icons/unicons/clipboard-alt.svg'; import u1035 from '!!raw-loader!../../../../../public/img/icons/unicons/clock-nine.svg'; -import u1036 from '!!raw-loader!../../../../../public/img/icons/unicons/cloud.svg'; import u1037 from '!!raw-loader!../../../../../public/img/icons/unicons/cloud-download.svg'; +import u1122 from '!!raw-loader!../../../../../public/img/icons/unicons/cloud-upload.svg'; +import u1036 from '!!raw-loader!../../../../../public/img/icons/unicons/cloud.svg'; import u1038 from '!!raw-loader!../../../../../public/img/icons/unicons/code-branch.svg'; import u1039 from '!!raw-loader!../../../../../public/img/icons/unicons/cog.svg'; import u1040 from '!!raw-loader!../../../../../public/img/icons/unicons/columns.svg'; -import u1041 from '!!raw-loader!../../../../../public/img/icons/unicons/comment-alt.svg'; import u1042 from '!!raw-loader!../../../../../public/img/icons/unicons/comment-alt-share.svg'; +import u1041 from '!!raw-loader!../../../../../public/img/icons/unicons/comment-alt.svg'; import u1043 from '!!raw-loader!../../../../../public/img/icons/unicons/comments-alt.svg'; import u1044 from '!!raw-loader!../../../../../public/img/icons/unicons/compass.svg'; import u1045 from '!!raw-loader!../../../../../public/img/icons/unicons/copy.svg'; +import u1123 from '!!raw-loader!../../../../../public/img/icons/unicons/credit-card.svg'; import u1046 from '!!raw-loader!../../../../../public/img/icons/unicons/cube.svg'; import u1047 from '!!raw-loader!../../../../../public/img/icons/unicons/dashboard.svg'; import u1048 from '!!raw-loader!../../../../../public/img/icons/unicons/database.svg'; @@ -67,48 +79,60 @@ import u1054 from '!!raw-loader!../../../../../public/img/icons/unicons/envelope import u1055 from '!!raw-loader!../../../../../public/img/icons/unicons/exchange-alt.svg'; import u1056 from '!!raw-loader!../../../../../public/img/icons/unicons/exclamation-triangle.svg'; import u1057 from '!!raw-loader!../../../../../public/img/icons/unicons/external-link-alt.svg'; -import u1058 from '!!raw-loader!../../../../../public/img/icons/unicons/eye.svg'; import u1059 from '!!raw-loader!../../../../../public/img/icons/unicons/eye-slash.svg'; +import u1058 from '!!raw-loader!../../../../../public/img/icons/unicons/eye.svg'; import u1060 from '!!raw-loader!../../../../../public/img/icons/unicons/file-alt.svg'; import u1061 from '!!raw-loader!../../../../../public/img/icons/unicons/file-blank.svg'; +import u1124 from '!!raw-loader!../../../../../public/img/icons/unicons/file-copy-alt.svg'; import u1062 from '!!raw-loader!../../../../../public/img/icons/unicons/filter.svg'; -import u1063 from '!!raw-loader!../../../../../public/img/icons/unicons/folder.svg'; +import u1125 from '!!raw-loader!../../../../../public/img/icons/unicons/fire.svg'; import u1064 from '!!raw-loader!../../../../../public/img/icons/unicons/folder-open.svg'; import u1065 from '!!raw-loader!../../../../../public/img/icons/unicons/folder-plus.svg'; import u1066 from '!!raw-loader!../../../../../public/img/icons/unicons/folder-upload.svg'; +import u1063 from '!!raw-loader!../../../../../public/img/icons/unicons/folder.svg'; import u1067 from '!!raw-loader!../../../../../public/img/icons/unicons/forward.svg'; import u1068 from '!!raw-loader!../../../../../public/img/icons/unicons/graph-bar.svg'; import u1069 from '!!raw-loader!../../../../../public/img/icons/unicons/history.svg'; import u1070 from '!!raw-loader!../../../../../public/img/icons/unicons/home-alt.svg'; +import u1126 from '!!raw-loader!../../../../../public/img/icons/unicons/hourglass.svg'; import u1071 from '!!raw-loader!../../../../../public/img/icons/unicons/import.svg'; -import u1072 from '!!raw-loader!../../../../../public/img/icons/unicons/info.svg'; import u1073 from '!!raw-loader!../../../../../public/img/icons/unicons/info-circle.svg'; +import u1072 from '!!raw-loader!../../../../../public/img/icons/unicons/info.svg'; import u1074 from '!!raw-loader!../../../../../public/img/icons/unicons/key-skeleton-alt.svg'; import u1075 from '!!raw-loader!../../../../../public/img/icons/unicons/keyboard.svg'; +import u1127 from '!!raw-loader!../../../../../public/img/icons/unicons/layer-group.svg'; +import u1128 from '!!raw-loader!../../../../../public/img/icons/unicons/line-alt.svg'; import u1076 from '!!raw-loader!../../../../../public/img/icons/unicons/link.svg'; +import u1129 from '!!raw-loader!../../../../../public/img/icons/unicons/list-ui-alt.svg'; import u1077 from '!!raw-loader!../../../../../public/img/icons/unicons/list-ul.svg'; import u1078 from '!!raw-loader!../../../../../public/img/icons/unicons/lock.svg'; -import u1079 from '!!raw-loader!../../../../../public/img/icons/unicons/minus.svg'; +import u1130 from '!!raw-loader!../../../../../public/img/icons/unicons/message.svg'; import u1080 from '!!raw-loader!../../../../../public/img/icons/unicons/minus-circle.svg'; +import u1079 from '!!raw-loader!../../../../../public/img/icons/unicons/minus.svg'; import u1081 from '!!raw-loader!../../../../../public/img/icons/unicons/mobile-android.svg'; import u1082 from '!!raw-loader!../../../../../public/img/icons/unicons/monitor.svg'; +import u1131 from '!!raw-loader!../../../../../public/img/icons/unicons/palette.svg'; import u1083 from '!!raw-loader!../../../../../public/img/icons/unicons/pause.svg'; import u1084 from '!!raw-loader!../../../../../public/img/icons/unicons/pen.svg'; +import u1132 from '!!raw-loader!../../../../../public/img/icons/unicons/percentage.svg'; import u1085 from '!!raw-loader!../../../../../public/img/icons/unicons/play.svg'; import u1086 from '!!raw-loader!../../../../../public/img/icons/unicons/plug.svg'; -import u1087 from '!!raw-loader!../../../../../public/img/icons/unicons/plus.svg'; import u1088 from '!!raw-loader!../../../../../public/img/icons/unicons/plus-circle.svg'; +import u1134 from '!!raw-loader!../../../../../public/img/icons/unicons/plus-square.svg'; +import u1087 from '!!raw-loader!../../../../../public/img/icons/unicons/plus.svg'; import u1089 from '!!raw-loader!../../../../../public/img/icons/unicons/power.svg'; import u1090 from '!!raw-loader!../../../../../public/img/icons/unicons/presentation-play.svg'; import u1091 from '!!raw-loader!../../../../../public/img/icons/unicons/process.svg'; import u1092 from '!!raw-loader!../../../../../public/img/icons/unicons/question-circle.svg'; +import u1155 from '!!raw-loader!../../../../../public/img/icons/unicons/record-audio.svg'; import u1093 from '!!raw-loader!../../../../../public/img/icons/unicons/repeat.svg'; import u1094 from '!!raw-loader!../../../../../public/img/icons/unicons/rocket.svg'; import u1095 from '!!raw-loader!../../../../../public/img/icons/unicons/save.svg'; -import u1096 from '!!raw-loader!../../../../../public/img/icons/unicons/search.svg'; import u1097 from '!!raw-loader!../../../../../public/img/icons/unicons/search-minus.svg'; import u1098 from '!!raw-loader!../../../../../public/img/icons/unicons/search-plus.svg'; +import u1096 from '!!raw-loader!../../../../../public/img/icons/unicons/search.svg'; import u1099 from '!!raw-loader!../../../../../public/img/icons/unicons/share-alt.svg'; +import u1133 from '!!raw-loader!../../../../../public/img/icons/unicons/shield-exclamation.svg'; import u1100 from '!!raw-loader!../../../../../public/img/icons/unicons/shield.svg'; import u1101 from '!!raw-loader!../../../../../public/img/icons/unicons/signal.svg'; import u1102 from '!!raw-loader!../../../../../public/img/icons/unicons/signin.svg'; @@ -131,40 +155,15 @@ import u1118 from '!!raw-loader!../../../../../public/img/icons/unicons/upload.s import u1119 from '!!raw-loader!../../../../../public/img/icons/unicons/user.svg'; import u1120 from '!!raw-loader!../../../../../public/img/icons/unicons/users-alt.svg'; import u1121 from '!!raw-loader!../../../../../public/img/icons/unicons/wrap-text.svg'; -import u1122 from '!!raw-loader!../../../../../public/img/icons/unicons/cloud-upload.svg'; -import u1123 from '!!raw-loader!../../../../../public/img/icons/unicons/credit-card.svg'; -import u1124 from '!!raw-loader!../../../../../public/img/icons/unicons/file-copy-alt.svg'; -import u1125 from '!!raw-loader!../../../../../public/img/icons/unicons/fire.svg'; -import u1126 from '!!raw-loader!../../../../../public/img/icons/unicons/hourglass.svg'; -import u1127 from '!!raw-loader!../../../../../public/img/icons/unicons/layer-group.svg'; -import u1128 from '!!raw-loader!../../../../../public/img/icons/unicons/line-alt.svg'; -import u1129 from '!!raw-loader!../../../../../public/img/icons/unicons/list-ui-alt.svg'; -import u1130 from '!!raw-loader!../../../../../public/img/icons/unicons/message.svg'; -import u1131 from '!!raw-loader!../../../../../public/img/icons/unicons/palette.svg'; -import u1132 from '!!raw-loader!../../../../../public/img/icons/unicons/percentage.svg'; -import u1133 from '!!raw-loader!../../../../../public/img/icons/unicons/shield-exclamation.svg'; -import u1134 from '!!raw-loader!../../../../../public/img/icons/unicons/plus-square.svg'; import u1135 from '!!raw-loader!../../../../../public/img/icons/unicons/x.svg'; -import u1136 from '!!raw-loader!../../../../../public/img/icons/unicons/capture.svg'; -import u1137 from '!!raw-loader!../../../../../public/img/icons/custom/gf-grid.svg'; -import u1138 from '!!raw-loader!../../../../../public/img/icons/custom/gf-landscape.svg'; -import u1139 from '!!raw-loader!../../../../../public/img/icons/custom/gf-layout-simple.svg'; -import u1140 from '!!raw-loader!../../../../../public/img/icons/custom/gf-portrait.svg'; -import u1141 from '!!raw-loader!../../../../../public/img/icons/custom/gf-bar-alignment-after.svg'; -import u1142 from '!!raw-loader!../../../../../public/img/icons/custom/gf-bar-alignment-before.svg'; -import u1143 from '!!raw-loader!../../../../../public/img/icons/custom/gf-bar-alignment-center.svg'; -import u1144 from '!!raw-loader!../../../../../public/img/icons/custom/gf-interpolation-linear.svg'; -import u1145 from '!!raw-loader!../../../../../public/img/icons/custom/gf-interpolation-smooth.svg'; -import u1146 from '!!raw-loader!../../../../../public/img/icons/custom/gf-interpolation-step-after.svg'; -import u1147 from '!!raw-loader!../../../../../public/img/icons/custom/gf-interpolation-step-before.svg'; -import u1148 from '!!raw-loader!../../../../../public/img/icons/custom/gf-logs.svg'; -import u1149 from '!!raw-loader!../../../../../public/img/icons/mono/favorite.svg'; -import u1150 from '!!raw-loader!../../../../../public/img/icons/mono/grafana.svg'; -import u1151 from '!!raw-loader!../../../../../public/img/icons/mono/heart.svg'; -import u1152 from '!!raw-loader!../../../../../public/img/icons/mono/heart-break.svg'; -import u1153 from '!!raw-loader!../../../../../public/img/icons/mono/panel-add.svg'; -import u1154 from '!!raw-loader!../../../../../public/img/icons/mono/library-panel.svg'; -import u1155 from '!!raw-loader!../../../../../public/img/icons/unicons/record-audio.svg'; +import { cacheStore } from 'react-inlinesvg'; + +export let cacheInitialized = false; +export let iconRoot = 'public/img/icons'; + +function cacheItem(content: string, path: string) { + cacheStore[iconRoot + path] = { content, status: 'loaded', queue: [] }; +} export function initIconCache() { cacheInitialized = true; diff --git a/packages/grafana-ui/src/components/IconButton/IconButton.story.tsx b/packages/grafana-ui/src/components/IconButton/IconButton.story.tsx index 3a0737d31c0..05e05318e94 100644 --- a/packages/grafana-ui/src/components/IconButton/IconButton.story.tsx +++ b/packages/grafana-ui/src/components/IconButton/IconButton.story.tsx @@ -1,12 +1,14 @@ -import React from 'react'; import { css } from '@emotion/css'; -import { IconButton, IconButtonVariant } from './IconButton'; -import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; +import React from 'react'; + import { useTheme2 } from '../../themes'; import { IconSize, IconName } from '../../types'; -import mdx from './IconButton.mdx'; +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; import { VerticalGroup } from '../Layout/Layout'; +import { IconButton, IconButtonVariant } from './IconButton'; +import mdx from './IconButton.mdx'; + export default { title: 'Buttons/IconButton', component: IconButton, diff --git a/packages/grafana-ui/src/components/IconButton/IconButton.tsx b/packages/grafana-ui/src/components/IconButton/IconButton.tsx index 484fe64b002..dfddd2b1c9e 100644 --- a/packages/grafana-ui/src/components/IconButton/IconButton.tsx +++ b/packages/grafana-ui/src/components/IconButton/IconButton.tsx @@ -1,13 +1,15 @@ +import { css, cx } from '@emotion/css'; import React from 'react'; + +import { GrafanaTheme2, colorManipulator } from '@grafana/data'; + +import { useTheme2 } from '../../themes/ThemeContext'; +import { getFocusStyles, getMouseFocusStyles } from '../../themes/mixins'; +import { stylesFactory } from '../../themes/stylesFactory'; +import { IconName, IconSize, IconType } from '../../types/icon'; import { Icon } from '../Icon/Icon'; import { getSvgSize } from '../Icon/utils'; -import { IconName, IconSize, IconType } from '../../types/icon'; -import { stylesFactory } from '../../themes/stylesFactory'; -import { css, cx } from '@emotion/css'; -import { useTheme2 } from '../../themes/ThemeContext'; -import { GrafanaTheme2, colorManipulator } from '@grafana/data'; import { TooltipPlacement, PopoverContent, Tooltip } from '../Tooltip'; -import { getFocusStyles, getMouseFocusStyles } from '../../themes/mixins'; export type IconButtonVariant = 'primary' | 'secondary' | 'destructive'; diff --git a/packages/grafana-ui/src/components/InfoBox/FeatureInfoBox.tsx b/packages/grafana-ui/src/components/InfoBox/FeatureInfoBox.tsx index 5e75f40b2c6..56ddec29a53 100644 --- a/packages/grafana-ui/src/components/InfoBox/FeatureInfoBox.tsx +++ b/packages/grafana-ui/src/components/InfoBox/FeatureInfoBox.tsx @@ -1,9 +1,12 @@ +import { css } from '@emotion/css'; import React from 'react'; -import { InfoBox, InfoBoxProps } from './InfoBox'; + import { FeatureState, GrafanaTheme } from '@grafana/data'; + import { stylesFactory, useStyles } from '../../themes'; import { Badge, BadgeProps } from '../Badge/Badge'; -import { css } from '@emotion/css'; + +import { InfoBox, InfoBoxProps } from './InfoBox'; export interface FeatureInfoBoxProps extends Omit { title: string; diff --git a/packages/grafana-ui/src/components/InfoBox/InfoBox.story.tsx b/packages/grafana-ui/src/components/InfoBox/InfoBox.story.tsx index 250d89a4167..b62014cd36e 100644 --- a/packages/grafana-ui/src/components/InfoBox/InfoBox.story.tsx +++ b/packages/grafana-ui/src/components/InfoBox/InfoBox.story.tsx @@ -1,10 +1,12 @@ +import { Story } from '@storybook/react'; import React from 'react'; + import { FeatureState } from '@grafana/data'; import { InfoBox, FeatureInfoBox, VerticalGroup } from '@grafana/ui'; -import mdx from './InfoBox.mdx'; -import { Story } from '@storybook/react'; + import { FeatureInfoBoxProps } from './FeatureInfoBox'; import { InfoBoxProps } from './InfoBox'; +import mdx from './InfoBox.mdx'; export default { title: 'Layout/InfoBox', diff --git a/packages/grafana-ui/src/components/InfoBox/InfoBox.tsx b/packages/grafana-ui/src/components/InfoBox/InfoBox.tsx index 1a9421ebdaf..1d79acf7a74 100644 --- a/packages/grafana-ui/src/components/InfoBox/InfoBox.tsx +++ b/packages/grafana-ui/src/components/InfoBox/InfoBox.tsx @@ -1,9 +1,11 @@ -import React from 'react'; import { css, cx } from '@emotion/css'; +import React from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; -import { Icon } from '../Icon/Icon'; -import { Alert, AlertVariant } from '../Alert/Alert'; + import { stylesFactory, useStyles2 } from '../../themes'; +import { Alert, AlertVariant } from '../Alert/Alert'; +import { Icon } from '../Icon/Icon'; export interface InfoBoxProps extends Omit, 'title'> { children: React.ReactNode; diff --git a/packages/grafana-ui/src/components/InfoTooltip/InfoTooltip.story.internal.tsx b/packages/grafana-ui/src/components/InfoTooltip/InfoTooltip.story.internal.tsx index 75a5abf8be2..10249e122bd 100644 --- a/packages/grafana-ui/src/components/InfoTooltip/InfoTooltip.story.internal.tsx +++ b/packages/grafana-ui/src/components/InfoTooltip/InfoTooltip.story.internal.tsx @@ -1,9 +1,10 @@ import React from 'react'; import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; -import { InfoTooltip } from './InfoTooltip'; import { VizTooltip } from '../VizTooltip'; +import { InfoTooltip } from './InfoTooltip'; + export default { title: 'Overlays/TooltipInternal', component: VizTooltip, diff --git a/packages/grafana-ui/src/components/InfoTooltip/InfoTooltip.tsx b/packages/grafana-ui/src/components/InfoTooltip/InfoTooltip.tsx index b0fd4d8202f..8eaaf3fa68f 100644 --- a/packages/grafana-ui/src/components/InfoTooltip/InfoTooltip.tsx +++ b/packages/grafana-ui/src/components/InfoTooltip/InfoTooltip.tsx @@ -1,6 +1,7 @@ import React from 'react'; -import { TooltipProps, PopoverContent } from '../Tooltip'; + import { IconButton } from '../IconButton/IconButton'; +import { TooltipProps, PopoverContent } from '../Tooltip'; interface InfoTooltipProps extends Omit { children: PopoverContent; diff --git a/packages/grafana-ui/src/components/Input/Input.story.tsx b/packages/grafana-ui/src/components/Input/Input.story.tsx index 8ef80b2d9db..14e324e348f 100644 --- a/packages/grafana-ui/src/components/Input/Input.story.tsx +++ b/packages/grafana-ui/src/components/Input/Input.story.tsx @@ -1,11 +1,14 @@ -import React, { useState } from 'react'; import { Story, Meta } from '@storybook/react'; -import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; -import mdx from './Input.mdx'; -import { getAvailableIcons, IconName } from '../../types'; +import React, { useState } from 'react'; + import { KeyValue } from '@grafana/data'; import { Field, Icon, Button, Input } from '@grafana/ui'; +import { getAvailableIcons, IconName } from '../../types'; +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; + +import mdx from './Input.mdx'; + const prefixSuffixOpts = { None: null, Text: '$', diff --git a/packages/grafana-ui/src/components/Input/Input.tsx b/packages/grafana-ui/src/components/Input/Input.tsx index e24d961514c..454e9763b3f 100644 --- a/packages/grafana-ui/src/components/Input/Input.tsx +++ b/packages/grafana-ui/src/components/Input/Input.tsx @@ -1,11 +1,13 @@ -import React, { HTMLProps, ReactNode } from 'react'; -import { GrafanaTheme2 } from '@grafana/data'; import { css, cx } from '@emotion/css'; -import { getFocusStyle, sharedInputStyle } from '../Forms/commonStyles'; -import { stylesFactory, useTheme2 } from '../../themes'; -import { Spinner } from '../Spinner/Spinner'; +import React, { HTMLProps, ReactNode } from 'react'; import useMeasure from 'react-use/lib/useMeasure'; +import { GrafanaTheme2 } from '@grafana/data'; + +import { stylesFactory, useTheme2 } from '../../themes'; +import { getFocusStyle, sharedInputStyle } from '../Forms/commonStyles'; +import { Spinner } from '../Spinner/Spinner'; + export interface Props extends Omit, 'prefix' | 'size'> { /** Sets the width to a multiple of 8px. Should only be used with inline forms. Setting width of the container is preferred in other cases.*/ width?: number; diff --git a/packages/grafana-ui/src/components/JSONFormatter/JSONFormatter.tsx b/packages/grafana-ui/src/components/JSONFormatter/JSONFormatter.tsx index 0e405beb5a8..ca815e8c760 100644 --- a/packages/grafana-ui/src/components/JSONFormatter/JSONFormatter.tsx +++ b/packages/grafana-ui/src/components/JSONFormatter/JSONFormatter.tsx @@ -1,4 +1,5 @@ import React, { PureComponent, createRef } from 'react'; + import { JsonExplorer } from './json_explorer/json_explorer'; // We have made some monkey-patching of json-formatter-js so we can't switch right now interface Props { diff --git a/packages/grafana-ui/src/components/JSONFormatter/json_explorer/json_explorer.ts b/packages/grafana-ui/src/components/JSONFormatter/json_explorer/json_explorer.ts index 62e911b414f..c6eecd5da31 100644 --- a/packages/grafana-ui/src/components/JSONFormatter/json_explorer/json_explorer.ts +++ b/packages/grafana-ui/src/components/JSONFormatter/json_explorer/json_explorer.ts @@ -1,10 +1,10 @@ // Based on work https://github.com/mohsen1/json-formatter-js // License MIT, Copyright (c) 2015 Mohsen Azimi -import { isObject, getObjectName, getType, getValuePreview, cssClass, createElement } from './helpers'; - import { isNumber } from 'lodash'; +import { isObject, getObjectName, getType, getValuePreview, cssClass, createElement } from './helpers'; + const DATE_STRING_REGEX = /(^\d{1,4}[\.|\\/|-]\d{1,2}[\.|\\/|-]\d{1,4})(\s*(?:0?[1-9]:[0-5]|1(?=[012])\d:[0-5])\d\s*[ap]m)?$/; const PARTIAL_DATE_REGEX = /\d{2}:\d{2}:\d{2} GMT-\d{4}/; diff --git a/packages/grafana-ui/src/components/Layout/Layout.story.tsx b/packages/grafana-ui/src/components/Layout/Layout.story.tsx index c20f008707f..47f566b3352 100644 --- a/packages/grafana-ui/src/components/Layout/Layout.story.tsx +++ b/packages/grafana-ui/src/components/Layout/Layout.story.tsx @@ -1,9 +1,12 @@ -import React from 'react'; -import { withCenteredStory, withHorizontallyCenteredStory } from '../../utils/storybook/withCenteredStory'; -import { Layout, LayoutProps } from './Layout'; -import { Button, VerticalGroup, HorizontalGroup } from '@grafana/ui'; -import { withStoryContainer } from '../../utils/storybook/withStoryContainer'; import { Story, Meta } from '@storybook/react'; +import React from 'react'; + +import { Button, VerticalGroup, HorizontalGroup } from '@grafana/ui'; + +import { withCenteredStory, withHorizontallyCenteredStory } from '../../utils/storybook/withCenteredStory'; +import { withStoryContainer } from '../../utils/storybook/withStoryContainer'; + +import { Layout, LayoutProps } from './Layout'; import mdx from './Layout.mdx'; export default { diff --git a/packages/grafana-ui/src/components/Layout/Layout.tsx b/packages/grafana-ui/src/components/Layout/Layout.tsx index 2e53b8a3c0d..6b2ea79264e 100644 --- a/packages/grafana-ui/src/components/Layout/Layout.tsx +++ b/packages/grafana-ui/src/components/Layout/Layout.tsx @@ -1,6 +1,8 @@ -import React, { HTMLProps } from 'react'; import { css, cx } from '@emotion/css'; +import React, { HTMLProps } from 'react'; + import { GrafanaTheme } from '@grafana/data'; + import { stylesFactory, useTheme } from '../../themes'; enum Orientation { diff --git a/packages/grafana-ui/src/components/Link/Link.tsx b/packages/grafana-ui/src/components/Link/Link.tsx index 4510d463428..0b9e9c80dd1 100644 --- a/packages/grafana-ui/src/components/Link/Link.tsx +++ b/packages/grafana-ui/src/components/Link/Link.tsx @@ -1,7 +1,8 @@ -import { locationUtil, textUtil } from '@grafana/data'; import React, { AnchorHTMLAttributes, forwardRef } from 'react'; import { Link as RouterLink } from 'react-router-dom'; +import { locationUtil, textUtil } from '@grafana/data'; + export interface Props extends AnchorHTMLAttributes {} /** diff --git a/packages/grafana-ui/src/components/List/AbstractList.test.tsx b/packages/grafana-ui/src/components/List/AbstractList.test.tsx index 6538a806d61..c1265cf59c9 100644 --- a/packages/grafana-ui/src/components/List/AbstractList.test.tsx +++ b/packages/grafana-ui/src/components/List/AbstractList.test.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { shallow } from 'enzyme'; +import React from 'react'; + import { AbstractList } from './AbstractList'; describe('AbstractList', () => { diff --git a/packages/grafana-ui/src/components/List/AbstractList.tsx b/packages/grafana-ui/src/components/List/AbstractList.tsx index f372dfdf30d..e0d3e54f8a2 100644 --- a/packages/grafana-ui/src/components/List/AbstractList.tsx +++ b/packages/grafana-ui/src/components/List/AbstractList.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { cx, css } from '@emotion/css'; +import React from 'react'; + import { stylesFactory } from '../../themes'; export interface ListProps { diff --git a/packages/grafana-ui/src/components/List/InlineList.tsx b/packages/grafana-ui/src/components/List/InlineList.tsx index aadfd84046f..bcb9f2a77f0 100644 --- a/packages/grafana-ui/src/components/List/InlineList.tsx +++ b/packages/grafana-ui/src/components/List/InlineList.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { ListProps, AbstractList } from './AbstractList'; export class InlineList extends React.PureComponent> { diff --git a/packages/grafana-ui/src/components/List/List.story.internal.tsx b/packages/grafana-ui/src/components/List/List.story.internal.tsx index f9111158270..2a7a74dfddc 100644 --- a/packages/grafana-ui/src/components/List/List.story.internal.tsx +++ b/packages/grafana-ui/src/components/List/List.story.internal.tsx @@ -1,9 +1,10 @@ -import React from 'react'; -import { Story, Meta } from '@storybook/react'; -import { List } from './List'; import { css, cx } from '@emotion/css'; +import { Story, Meta } from '@storybook/react'; +import React from 'react'; import tinycolor from 'tinycolor2'; + import { InlineList } from './InlineList'; +import { List } from './List'; export default { title: 'Layout/List', diff --git a/packages/grafana-ui/src/components/List/List.tsx b/packages/grafana-ui/src/components/List/List.tsx index 1fcc7d9ae01..70730f9d0e4 100644 --- a/packages/grafana-ui/src/components/List/List.tsx +++ b/packages/grafana-ui/src/components/List/List.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { ListProps, AbstractList } from './AbstractList'; export class List extends React.PureComponent> { diff --git a/packages/grafana-ui/src/components/LoadingPlaceholder/LoadingPlaceholder.story.tsx b/packages/grafana-ui/src/components/LoadingPlaceholder/LoadingPlaceholder.story.tsx index ad8215e0aaa..450dad89719 100644 --- a/packages/grafana-ui/src/components/LoadingPlaceholder/LoadingPlaceholder.story.tsx +++ b/packages/grafana-ui/src/components/LoadingPlaceholder/LoadingPlaceholder.story.tsx @@ -1,6 +1,8 @@ import React from 'react'; -import { LoadingPlaceholder } from './LoadingPlaceholder'; + import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; + +import { LoadingPlaceholder } from './LoadingPlaceholder'; import mdx from './LoadingPlaceholder.mdx'; export default { diff --git a/packages/grafana-ui/src/components/LoadingPlaceholder/LoadingPlaceholder.tsx b/packages/grafana-ui/src/components/LoadingPlaceholder/LoadingPlaceholder.tsx index 233a14020a3..968c1c3039a 100644 --- a/packages/grafana-ui/src/components/LoadingPlaceholder/LoadingPlaceholder.tsx +++ b/packages/grafana-ui/src/components/LoadingPlaceholder/LoadingPlaceholder.tsx @@ -1,8 +1,10 @@ -import React, { HTMLAttributes, SFC } from 'react'; import { css, cx } from '@emotion/css'; +import React, { HTMLAttributes, SFC } from 'react'; + import { GrafanaTheme } from '@grafana/data'; -import { Spinner } from '../Spinner/Spinner'; + import { useStyles } from '../../themes'; +import { Spinner } from '../Spinner/Spinner'; /** * @public diff --git a/packages/grafana-ui/src/components/Logs/LogDetails.test.tsx b/packages/grafana-ui/src/components/Logs/LogDetails.test.tsx index e0b68c0bbaa..dfa3dc70505 100644 --- a/packages/grafana-ui/src/components/Logs/LogDetails.test.tsx +++ b/packages/grafana-ui/src/components/Logs/LogDetails.test.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { render, screen, within } from '@testing-library/react'; +import React from 'react'; + import { Field, GrafanaTheme2, LogLevel, LogRowModel, MutableDataFrame } from '@grafana/data'; import { LogDetails, Props } from './LogDetails'; diff --git a/packages/grafana-ui/src/components/Logs/LogDetails.tsx b/packages/grafana-ui/src/components/Logs/LogDetails.tsx index b5d2adbc943..4c9d0262c21 100644 --- a/packages/grafana-ui/src/components/Logs/LogDetails.tsx +++ b/packages/grafana-ui/src/components/Logs/LogDetails.tsx @@ -1,6 +1,7 @@ -import React, { PureComponent } from 'react'; -import memoizeOne from 'memoize-one'; import { css, cx } from '@emotion/css'; +import memoizeOne from 'memoize-one'; +import React, { PureComponent } from 'react'; + import { calculateFieldStats, calculateLogsLabelStats, @@ -12,15 +13,16 @@ import { GrafanaTheme2, } from '@grafana/data'; -import { Themeable2 } from '../../types/theme'; import { withTheme2 } from '../../themes/index'; +import { Themeable2 } from '../../types/theme'; +import { Icon } from '../Icon/Icon'; +import { Tooltip } from '../Tooltip/Tooltip'; + +import { LogDetailsRow } from './LogDetailsRow'; import { getLogRowStyles } from './getLogRowStyles'; import { getAllFields } from './logParser'; //Components -import { LogDetailsRow } from './LogDetailsRow'; -import { Tooltip } from '../Tooltip/Tooltip'; -import { Icon } from '../Icon/Icon'; export interface Props extends Themeable2 { row: LogRowModel; diff --git a/packages/grafana-ui/src/components/Logs/LogDetailsRow.test.tsx b/packages/grafana-ui/src/components/Logs/LogDetailsRow.test.tsx index 781320c1f70..11d470c0edd 100644 --- a/packages/grafana-ui/src/components/Logs/LogDetailsRow.test.tsx +++ b/packages/grafana-ui/src/components/Logs/LogDetailsRow.test.tsx @@ -1,5 +1,6 @@ -import React, { ComponentProps } from 'react'; import { screen, render, fireEvent } from '@testing-library/react'; +import React, { ComponentProps } from 'react'; + import { LogDetailsRow } from './LogDetailsRow'; type Props = ComponentProps; diff --git a/packages/grafana-ui/src/components/Logs/LogDetailsRow.tsx b/packages/grafana-ui/src/components/Logs/LogDetailsRow.tsx index e20cdf055fe..d483403f414 100644 --- a/packages/grafana-ui/src/components/Logs/LogDetailsRow.tsx +++ b/packages/grafana-ui/src/components/Logs/LogDetailsRow.tsx @@ -1,15 +1,17 @@ -import React, { PureComponent } from 'react'; import { css, cx } from '@emotion/css'; +import React, { PureComponent } from 'react'; + import { Field, LinkModel, LogLabelStatsModel, GrafanaTheme2 } from '@grafana/data'; -import { Themeable2 } from '../../types/theme'; import { withTheme2 } from '../../themes/index'; +import { Themeable2 } from '../../types/theme'; +import { DataLinkButton } from '../DataLinks/DataLinkButton'; +import { IconButton } from '../IconButton/IconButton'; + +import { LogLabelStats } from './LogLabelStats'; import { getLogRowStyles } from './getLogRowStyles'; //Components -import { LogLabelStats } from './LogLabelStats'; -import { IconButton } from '../IconButton/IconButton'; -import { DataLinkButton } from '../DataLinks/DataLinkButton'; export interface Props extends Themeable2 { parsedValue: string; diff --git a/packages/grafana-ui/src/components/Logs/LogLabelStats.tsx b/packages/grafana-ui/src/components/Logs/LogLabelStats.tsx index fd5aa50d4d5..609a8065bfd 100644 --- a/packages/grafana-ui/src/components/Logs/LogLabelStats.tsx +++ b/packages/grafana-ui/src/components/Logs/LogLabelStats.tsx @@ -1,10 +1,11 @@ -import React, { PureComponent } from 'react'; import { css } from '@emotion/css'; +import React, { PureComponent } from 'react'; + import { LogLabelStatsModel, GrafanaTheme } from '@grafana/data'; -import { Themeable } from '../../types/theme'; import { stylesFactory } from '../../themes'; import { withTheme } from '../../themes/index'; +import { Themeable } from '../../types/theme'; //Components import { LogLabelStatsRow } from './LogLabelStatsRow'; diff --git a/packages/grafana-ui/src/components/Logs/LogLabelStatsRow.tsx b/packages/grafana-ui/src/components/Logs/LogLabelStatsRow.tsx index d477a1851e7..e18637678de 100644 --- a/packages/grafana-ui/src/components/Logs/LogLabelStatsRow.tsx +++ b/packages/grafana-ui/src/components/Logs/LogLabelStatsRow.tsx @@ -1,6 +1,8 @@ -import React, { FunctionComponent } from 'react'; import { css, cx } from '@emotion/css'; +import React, { FunctionComponent } from 'react'; + import { GrafanaTheme } from '@grafana/data'; + import { useStyles } from '../../themes/ThemeContext'; const getStyles = (theme: GrafanaTheme) => ({ diff --git a/packages/grafana-ui/src/components/Logs/LogLabels.test.tsx b/packages/grafana-ui/src/components/Logs/LogLabels.test.tsx index eaee962f963..fc1a4f23120 100644 --- a/packages/grafana-ui/src/components/Logs/LogLabels.test.tsx +++ b/packages/grafana-ui/src/components/Logs/LogLabels.test.tsx @@ -1,8 +1,9 @@ -import React from 'react'; import { shallow } from 'enzyme'; +import React from 'react'; + +import { getTheme } from '../../themes'; import { UnThemedLogLabels as LogLabels } from './LogLabels'; -import { getTheme } from '../../themes'; describe('', () => { it('renders notice when no labels are found', () => { diff --git a/packages/grafana-ui/src/components/Logs/LogLabels.tsx b/packages/grafana-ui/src/components/Logs/LogLabels.tsx index 0c88e4c2239..aad16e60cbf 100644 --- a/packages/grafana-ui/src/components/Logs/LogLabels.tsx +++ b/packages/grafana-ui/src/components/Logs/LogLabels.tsx @@ -1,10 +1,11 @@ -import React, { FunctionComponent } from 'react'; import { css, cx } from '@emotion/css'; +import React, { FunctionComponent } from 'react'; + import { GrafanaTheme, Labels } from '@grafana/data'; import { stylesFactory } from '../../themes'; -import { Themeable } from '../../types/theme'; import { withTheme } from '../../themes/ThemeContext'; +import { Themeable } from '../../types/theme'; // Levels are already encoded in color, filename is a Loki-ism const HIDDEN_LABELS = ['level', 'lvl', 'filename']; diff --git a/packages/grafana-ui/src/components/Logs/LogMessageAnsi.test.tsx b/packages/grafana-ui/src/components/Logs/LogMessageAnsi.test.tsx index 4dac18ce2e8..8bafbb9725a 100644 --- a/packages/grafana-ui/src/components/Logs/LogMessageAnsi.test.tsx +++ b/packages/grafana-ui/src/components/Logs/LogMessageAnsi.test.tsx @@ -1,6 +1,8 @@ -import { createTheme } from '@grafana/data'; import { shallow } from 'enzyme'; import React from 'react'; + +import { createTheme } from '@grafana/data'; + import { UnThemedLogMessageAnsi as LogMessageAnsi } from './LogMessageAnsi'; describe('', () => { diff --git a/packages/grafana-ui/src/components/Logs/LogMessageAnsi.tsx b/packages/grafana-ui/src/components/Logs/LogMessageAnsi.tsx index 478b4f68236..b7633b714b5 100644 --- a/packages/grafana-ui/src/components/Logs/LogMessageAnsi.tsx +++ b/packages/grafana-ui/src/components/Logs/LogMessageAnsi.tsx @@ -1,8 +1,10 @@ -import { findHighlightChunksInText, GrafanaTheme2 } from '@grafana/data'; import ansicolor from 'ansicolor'; import React, { PureComponent } from 'react'; // @ts-ignore import Highlighter from 'react-highlight-words'; + +import { findHighlightChunksInText, GrafanaTheme2 } from '@grafana/data'; + import { withTheme2 } from '../../themes'; import { Themeable2 } from '../../types'; diff --git a/packages/grafana-ui/src/components/Logs/LogRow.tsx b/packages/grafana-ui/src/components/Logs/LogRow.tsx index 5c2c2b6a9ed..dc62deea068 100644 --- a/packages/grafana-ui/src/components/Logs/LogRow.tsx +++ b/packages/grafana-ui/src/components/Logs/LogRow.tsx @@ -1,4 +1,6 @@ +import { cx, css } from '@emotion/css'; import React, { PureComponent } from 'react'; + import { Field, LinkModel, @@ -11,10 +13,14 @@ import { escapeUnescapedString, GrafanaTheme2, } from '@grafana/data'; + +import { styleMixins, withTheme2 } from '../../themes/index'; +import { Themeable2 } from '../../types/theme'; import { Icon } from '../Icon/Icon'; import { Tooltip } from '../Tooltip/Tooltip'; -import { cx, css } from '@emotion/css'; +import { LogDetails } from './LogDetails'; +import { LogLabels } from './LogLabels'; import { LogRowContextRows, LogRowContextQueryErrors, @@ -22,15 +28,11 @@ import { LogRowContextProvider, RowContextOptions, } from './LogRowContextProvider'; -import { Themeable2 } from '../../types/theme'; -import { styleMixins, withTheme2 } from '../../themes/index'; +import { LogRowMessage } from './LogRowMessage'; +import { LogRowMessageDetectedFields } from './LogRowMessageDetectedFields'; import { getLogRowStyles } from './getLogRowStyles'; //Components -import { LogDetails } from './LogDetails'; -import { LogRowMessageDetectedFields } from './LogRowMessageDetectedFields'; -import { LogRowMessage } from './LogRowMessage'; -import { LogLabels } from './LogLabels'; interface Props extends Themeable2 { row: LogRowModel; diff --git a/packages/grafana-ui/src/components/Logs/LogRowContext.test.tsx b/packages/grafana-ui/src/components/Logs/LogRowContext.test.tsx index 759f34880c9..b63d7f8f791 100644 --- a/packages/grafana-ui/src/components/Logs/LogRowContext.test.tsx +++ b/packages/grafana-ui/src/components/Logs/LogRowContext.test.tsx @@ -1,6 +1,8 @@ -import React from 'react'; -import { LogRowModel } from '@grafana/data'; import { render, screen } from '@testing-library/react'; +import React from 'react'; + +import { LogRowModel } from '@grafana/data'; + import { LogRowContextGroup } from './LogRowContext'; describe('LogRowContextGroup component', () => { diff --git a/packages/grafana-ui/src/components/Logs/LogRowContext.tsx b/packages/grafana-ui/src/components/Logs/LogRowContext.tsx index f5f2a38667d..ee68d49fd3d 100644 --- a/packages/grafana-ui/src/components/Logs/LogRowContext.tsx +++ b/packages/grafana-ui/src/components/Logs/LogRowContext.tsx @@ -1,14 +1,16 @@ -import React, { useRef, useState, useLayoutEffect, useEffect } from 'react'; -import { GrafanaTheme, DataQueryError, LogRowModel, textUtil } from '@grafana/data'; import { css, cx } from '@emotion/css'; +import React, { useRef, useState, useLayoutEffect, useEffect } from 'react'; + +import { GrafanaTheme, DataQueryError, LogRowModel, textUtil } from '@grafana/data'; -import { Alert } from '../Alert/Alert'; -import { LogRowContextRows, LogRowContextQueryErrors, HasMoreContextRows } from './LogRowContextProvider'; import { useStyles, useTheme } from '../../themes/ThemeContext'; +import { Alert } from '../Alert/Alert'; +import { ClickOutsideWrapper } from '../ClickOutsideWrapper/ClickOutsideWrapper'; import { CustomScrollbar } from '../CustomScrollbar/CustomScrollbar'; import { List } from '../List/List'; -import { ClickOutsideWrapper } from '../ClickOutsideWrapper/ClickOutsideWrapper'; + import { LogMessageAnsi } from './LogMessageAnsi'; +import { LogRowContextRows, LogRowContextQueryErrors, HasMoreContextRows } from './LogRowContextProvider'; interface LogRowContextProps { row: LogRowModel; diff --git a/packages/grafana-ui/src/components/Logs/LogRowContextProvider.test.tsx b/packages/grafana-ui/src/components/Logs/LogRowContextProvider.test.tsx index 62f03812b2a..4ea6cfd27d6 100644 --- a/packages/grafana-ui/src/components/Logs/LogRowContextProvider.test.tsx +++ b/packages/grafana-ui/src/components/Logs/LogRowContextProvider.test.tsx @@ -1,9 +1,11 @@ -import React from 'react'; -import { FieldType, LogRowModel, MutableDataFrame, Labels, LogLevel, DataQueryResponse } from '@grafana/data'; -import { getRowContexts, LogRowContextProvider } from './LogRowContextProvider'; import { mount } from 'enzyme'; +import React from 'react'; import { act } from 'react-dom/test-utils'; +import { FieldType, LogRowModel, MutableDataFrame, Labels, LogLevel, DataQueryResponse } from '@grafana/data'; + +import { getRowContexts, LogRowContextProvider } from './LogRowContextProvider'; + describe('getRowContexts', () => { describe('when called with a DataFrame and results are returned', () => { it('then the result should be in correct format and filtered', async () => { diff --git a/packages/grafana-ui/src/components/Logs/LogRowContextProvider.tsx b/packages/grafana-ui/src/components/Logs/LogRowContextProvider.tsx index c1858755633..2751f623c12 100644 --- a/packages/grafana-ui/src/components/Logs/LogRowContextProvider.tsx +++ b/packages/grafana-ui/src/components/Logs/LogRowContextProvider.tsx @@ -1,3 +1,6 @@ +import React, { useState, useEffect } from 'react'; +import useAsync from 'react-use/lib/useAsync'; + import { LogRowModel, toDataFrame, @@ -7,8 +10,6 @@ import { DataQueryResponse, DataQueryError, } from '@grafana/data'; -import React, { useState, useEffect } from 'react'; -import useAsync from 'react-use/lib/useAsync'; export interface RowContextOptions { direction?: 'BACKWARD' | 'FORWARD'; diff --git a/packages/grafana-ui/src/components/Logs/LogRowMessage.tsx b/packages/grafana-ui/src/components/Logs/LogRowMessage.tsx index 140bb0a733f..7a8e8694245 100644 --- a/packages/grafana-ui/src/components/Logs/LogRowMessage.tsx +++ b/packages/grafana-ui/src/components/Logs/LogRowMessage.tsx @@ -1,19 +1,23 @@ -import React, { PureComponent } from 'react'; -import tinycolor from 'tinycolor2'; import { css, cx } from '@emotion/css'; -import { LogRowModel, findHighlightChunksInText, GrafanaTheme2 } from '@grafana/data'; import memoizeOne from 'memoize-one'; - +import React, { PureComponent } from 'react'; // @ts-ignore import Highlighter from 'react-highlight-words'; -import { LogRowContextQueryErrors, HasMoreContextRows, LogRowContextRows } from './LogRowContextProvider'; -import { Themeable2 } from '../../types/theme'; +import tinycolor from 'tinycolor2'; + +import { LogRowModel, findHighlightChunksInText, GrafanaTheme2 } from '@grafana/data'; + +// @ts-ignore + import { withTheme2 } from '../../themes/index'; +import { Themeable2 } from '../../types/theme'; + +import { LogMessageAnsi } from './LogMessageAnsi'; +import { LogRowContext } from './LogRowContext'; +import { LogRowContextQueryErrors, HasMoreContextRows, LogRowContextRows } from './LogRowContextProvider'; import { getLogRowStyles } from './getLogRowStyles'; //Components -import { LogRowContext } from './LogRowContext'; -import { LogMessageAnsi } from './LogMessageAnsi'; export const MAX_CHARACTERS = 100000; diff --git a/packages/grafana-ui/src/components/Logs/LogRowMessageDetectedFields.tsx b/packages/grafana-ui/src/components/Logs/LogRowMessageDetectedFields.tsx index f1a174b52fa..15415f0a406 100644 --- a/packages/grafana-ui/src/components/Logs/LogRowMessageDetectedFields.tsx +++ b/packages/grafana-ui/src/components/Logs/LogRowMessageDetectedFields.tsx @@ -1,9 +1,10 @@ -import React, { PureComponent } from 'react'; import { cx, css } from '@emotion/css'; +import React, { PureComponent } from 'react'; + import { LogRowModel, Field, LinkModel } from '@grafana/data'; -import { Themeable } from '../../types/theme'; import { withTheme } from '../../themes/index'; +import { Themeable } from '../../types/theme'; import { getAllFields } from './logParser'; diff --git a/packages/grafana-ui/src/components/Logs/LogRows.test.tsx b/packages/grafana-ui/src/components/Logs/LogRows.test.tsx index 4de84bae8da..7b9cd409578 100644 --- a/packages/grafana-ui/src/components/Logs/LogRows.test.tsx +++ b/packages/grafana-ui/src/components/Logs/LogRows.test.tsx @@ -1,9 +1,11 @@ -import React from 'react'; -import { range } from 'lodash'; -import { LogRows, PREVIEW_LIMIT } from './LogRows'; import { mount } from 'enzyme'; +import { range } from 'lodash'; +import React from 'react'; + import { LogLevel, LogRowModel, LogsDedupStrategy, MutableDataFrame, LogsSortOrder } from '@grafana/data'; + import { LogRow } from './LogRow'; +import { LogRows, PREVIEW_LIMIT } from './LogRows'; describe('LogRows', () => { it('renders rows', () => { diff --git a/packages/grafana-ui/src/components/Logs/LogRows.tsx b/packages/grafana-ui/src/components/Logs/LogRows.tsx index 0971ddba9ee..a59d3c71b15 100644 --- a/packages/grafana-ui/src/components/Logs/LogRows.tsx +++ b/packages/grafana-ui/src/components/Logs/LogRows.tsx @@ -1,14 +1,15 @@ -import React, { PureComponent } from 'react'; import memoizeOne from 'memoize-one'; +import React, { PureComponent } from 'react'; + import { TimeZone, LogsDedupStrategy, LogRowModel, Field, LinkModel, LogsSortOrder, sortLogRows } from '@grafana/data'; -import { Themeable2 } from '../../types/theme'; import { withTheme2 } from '../../themes/index'; -import { getLogRowStyles } from './getLogRowStyles'; +import { Themeable2 } from '../../types/theme'; //Components import { LogRow } from './LogRow'; import { RowContextOptions } from './LogRowContextProvider'; +import { getLogRowStyles } from './getLogRowStyles'; export const PREVIEW_LIMIT = 100; diff --git a/packages/grafana-ui/src/components/Logs/getLogRowStyles.ts b/packages/grafana-ui/src/components/Logs/getLogRowStyles.ts index 7bf0896aceb..d97196c8701 100644 --- a/packages/grafana-ui/src/components/Logs/getLogRowStyles.ts +++ b/packages/grafana-ui/src/components/Logs/getLogRowStyles.ts @@ -1,5 +1,7 @@ import { css } from '@emotion/css'; + import { GrafanaTheme2, LogLevel } from '@grafana/data'; + import { styleMixins, stylesFactory } from '../../themes'; export const getLogRowStyles = stylesFactory((theme: GrafanaTheme2, logLevel?: LogLevel) => { diff --git a/packages/grafana-ui/src/components/Logs/logParser.ts b/packages/grafana-ui/src/components/Logs/logParser.ts index a8ff5725bb6..ecb11fcade4 100644 --- a/packages/grafana-ui/src/components/Logs/logParser.ts +++ b/packages/grafana-ui/src/components/Logs/logParser.ts @@ -1,6 +1,7 @@ -import { Field, getParser, LinkModel, LogRowModel } from '@grafana/data'; import memoizeOne from 'memoize-one'; +import { Field, getParser, LinkModel, LogRowModel } from '@grafana/data'; + import { MAX_CHARACTERS } from './LogRowMessage'; const memoizedGetParser = memoizeOne(getParser); diff --git a/packages/grafana-ui/src/components/MatchersUI/FieldNameByRegexMatcherEditor.tsx b/packages/grafana-ui/src/components/MatchersUI/FieldNameByRegexMatcherEditor.tsx index 48739edad90..5a99d3bd304 100644 --- a/packages/grafana-ui/src/components/MatchersUI/FieldNameByRegexMatcherEditor.tsx +++ b/packages/grafana-ui/src/components/MatchersUI/FieldNameByRegexMatcherEditor.tsx @@ -1,8 +1,11 @@ import React, { memo, useCallback } from 'react'; -import { MatcherUIProps, FieldMatcherUIRegistryItem } from './types'; + import { FieldMatcherID, fieldMatchers } from '@grafana/data'; + import { Input } from '../Input/Input'; +import { MatcherUIProps, FieldMatcherUIRegistryItem } from './types'; + export const FieldNameByRegexMatcherEditor = memo>((props) => { const { options, onChange } = props; diff --git a/packages/grafana-ui/src/components/MatchersUI/FieldNameMatcherEditor.tsx b/packages/grafana-ui/src/components/MatchersUI/FieldNameMatcherEditor.tsx index d2d4b9249cf..89dcb35fcb4 100644 --- a/packages/grafana-ui/src/components/MatchersUI/FieldNameMatcherEditor.tsx +++ b/packages/grafana-ui/src/components/MatchersUI/FieldNameMatcherEditor.tsx @@ -1,7 +1,10 @@ import React, { memo, useCallback } from 'react'; -import { MatcherUIProps, FieldMatcherUIRegistryItem } from './types'; + import { FieldMatcherID, fieldMatchers, SelectableValue } from '@grafana/data'; + import { Select } from '../Select/Select'; + +import { MatcherUIProps, FieldMatcherUIRegistryItem } from './types'; import { useFieldDisplayNames, useSelectOptions, frameHasName } from './utils'; export const FieldNameMatcherEditor = memo>((props) => { diff --git a/packages/grafana-ui/src/components/MatchersUI/FieldNamePicker.tsx b/packages/grafana-ui/src/components/MatchersUI/FieldNamePicker.tsx index da26fd7c0a4..e483e2fd3c8 100644 --- a/packages/grafana-ui/src/components/MatchersUI/FieldNamePicker.tsx +++ b/packages/grafana-ui/src/components/MatchersUI/FieldNamePicker.tsx @@ -1,6 +1,9 @@ import React, { useCallback } from 'react'; + import { FieldNamePickerConfigSettings, SelectableValue, StandardEditorProps } from '@grafana/data'; + import { Select } from '../Select/Select'; + import { useFieldDisplayNames, useSelectOptions, frameHasName } from './utils'; // Pick a field name out of the fulds diff --git a/packages/grafana-ui/src/components/MatchersUI/FieldNamesMatcherEditor.tsx b/packages/grafana-ui/src/components/MatchersUI/FieldNamesMatcherEditor.tsx index 3d52275d9eb..3e37f6f9734 100644 --- a/packages/grafana-ui/src/components/MatchersUI/FieldNamesMatcherEditor.tsx +++ b/packages/grafana-ui/src/components/MatchersUI/FieldNamesMatcherEditor.tsx @@ -1,8 +1,11 @@ import React, { memo, useCallback } from 'react'; -import { MatcherUIProps, FieldMatcherUIRegistryItem } from './types'; + import { FieldMatcherID, fieldMatchers, SelectableValue, ByNamesMatcherOptions } from '@grafana/data'; -import { MultiSelect } from '../Select/Select'; + import { Input } from '../Input/Input'; +import { MultiSelect } from '../Select/Select'; + +import { MatcherUIProps, FieldMatcherUIRegistryItem } from './types'; import { useFieldDisplayNames, useSelectOptions, frameHasName } from './utils'; export const FieldNamesMatcherEditor = memo>((props) => { diff --git a/packages/grafana-ui/src/components/MatchersUI/FieldTypeMatcherEditor.tsx b/packages/grafana-ui/src/components/MatchersUI/FieldTypeMatcherEditor.tsx index 6c9a0c78304..a4f3a1de274 100644 --- a/packages/grafana-ui/src/components/MatchersUI/FieldTypeMatcherEditor.tsx +++ b/packages/grafana-ui/src/components/MatchersUI/FieldTypeMatcherEditor.tsx @@ -1,8 +1,11 @@ import React, { memo, useMemo, useCallback } from 'react'; -import { MatcherUIProps, FieldMatcherUIRegistryItem } from './types'; + import { FieldMatcherID, fieldMatchers, SelectableValue, FieldType, DataFrame } from '@grafana/data'; + import { Select } from '../Select/Select'; +import { MatcherUIProps, FieldMatcherUIRegistryItem } from './types'; + export const FieldTypeMatcherEditor = memo>((props) => { const { data, options, onChange: onChangeFromProps, id } = props; const counts = useFieldCounts(data); diff --git a/packages/grafana-ui/src/components/MatchersUI/FieldsByFrameRefIdMatcher.tsx b/packages/grafana-ui/src/components/MatchersUI/FieldsByFrameRefIdMatcher.tsx index 57c78198b80..b50cda2db54 100644 --- a/packages/grafana-ui/src/components/MatchersUI/FieldsByFrameRefIdMatcher.tsx +++ b/packages/grafana-ui/src/components/MatchersUI/FieldsByFrameRefIdMatcher.tsx @@ -1,8 +1,11 @@ import React, { memo, useMemo, useCallback } from 'react'; -import { MatcherUIProps, FieldMatcherUIRegistryItem } from './types'; + import { FieldMatcherID, fieldMatchers, SelectableValue, DataFrame } from '@grafana/data'; + import { Select } from '../Select/Select'; +import { MatcherUIProps, FieldMatcherUIRegistryItem } from './types'; + /** * UI to configure "fields by frame refId"-matcher. * @public diff --git a/packages/grafana-ui/src/components/MatchersUI/fieldMatchersUI.ts b/packages/grafana-ui/src/components/MatchersUI/fieldMatchersUI.ts index 26cda2b0ad4..72c22e193c5 100644 --- a/packages/grafana-ui/src/components/MatchersUI/fieldMatchersUI.ts +++ b/packages/grafana-ui/src/components/MatchersUI/fieldMatchersUI.ts @@ -1,10 +1,11 @@ import { Registry } from '@grafana/data'; -import { FieldMatcherUIRegistryItem } from './types'; -import { fieldNameMatcherItem } from './FieldNameMatcherEditor'; + import { fieldNameByRegexMatcherItem } from './FieldNameByRegexMatcherEditor'; +import { fieldNameMatcherItem } from './FieldNameMatcherEditor'; +import { fieldNamesMatcherItem } from './FieldNamesMatcherEditor'; import { fieldTypeMatcherItem } from './FieldTypeMatcherEditor'; import { fieldsByFrameRefIdItem } from './FieldsByFrameRefIdMatcher'; -import { fieldNamesMatcherItem } from './FieldNamesMatcherEditor'; +import { FieldMatcherUIRegistryItem } from './types'; export const fieldMatchersUI = new Registry>(() => [ fieldNameMatcherItem, diff --git a/packages/grafana-ui/src/components/MatchersUI/types.ts b/packages/grafana-ui/src/components/MatchersUI/types.ts index 64e4a2d9515..868adc8a527 100644 --- a/packages/grafana-ui/src/components/MatchersUI/types.ts +++ b/packages/grafana-ui/src/components/MatchersUI/types.ts @@ -1,4 +1,5 @@ import React from 'react'; + import { DataFrame, RegistryItem, FieldMatcherInfo } from '@grafana/data'; export interface FieldMatcherUIRegistryItem extends RegistryItem { diff --git a/packages/grafana-ui/src/components/MatchersUI/utils.ts b/packages/grafana-ui/src/components/MatchersUI/utils.ts index ccbf9545081..490a514009a 100644 --- a/packages/grafana-ui/src/components/MatchersUI/utils.ts +++ b/packages/grafana-ui/src/components/MatchersUI/utils.ts @@ -1,5 +1,7 @@ import { useMemo } from 'react'; + import { DataFrame, Field, getFieldDisplayName, SelectableValue } from '@grafana/data'; + import { getFieldTypeIcon } from '../../types'; /** diff --git a/packages/grafana-ui/src/components/Menu/Menu.story.internal.tsx b/packages/grafana-ui/src/components/Menu/Menu.story.internal.tsx index 896162f0e2f..e3513121c61 100644 --- a/packages/grafana-ui/src/components/Menu/Menu.story.internal.tsx +++ b/packages/grafana-ui/src/components/Menu/Menu.story.internal.tsx @@ -1,12 +1,14 @@ -import React from 'react'; import { Story } from '@storybook/react'; -import { Menu, MenuProps } from './Menu'; -import { MenuItem } from './MenuItem'; -import { MenuGroup } from './MenuGroup'; +import React from 'react'; + import { GraphContextMenuHeader } from '..'; import { StoryExample } from '../../utils/storybook/StoryExample'; import { VerticalGroup } from '../Layout/Layout'; +import { Menu, MenuProps } from './Menu'; +import { MenuGroup } from './MenuGroup'; +import { MenuItem } from './MenuItem'; + export default { title: 'General/Menu', component: Menu, diff --git a/packages/grafana-ui/src/components/Menu/Menu.test.tsx b/packages/grafana-ui/src/components/Menu/Menu.test.tsx index cd29211bca7..0df2af1c7ad 100644 --- a/packages/grafana-ui/src/components/Menu/Menu.test.tsx +++ b/packages/grafana-ui/src/components/Menu/Menu.test.tsx @@ -1,6 +1,8 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; +import React from 'react'; + import { selectors } from '@grafana/e2e-selectors'; + import { Menu } from './Menu'; import { MenuGroup } from './MenuGroup'; import { MenuItem } from './MenuItem'; diff --git a/packages/grafana-ui/src/components/Menu/Menu.tsx b/packages/grafana-ui/src/components/Menu/Menu.tsx index 60773029cb8..1104dac5e9d 100644 --- a/packages/grafana-ui/src/components/Menu/Menu.tsx +++ b/packages/grafana-ui/src/components/Menu/Menu.tsx @@ -1,7 +1,10 @@ -import React, { useImperativeHandle, useRef } from 'react'; import { css } from '@emotion/css'; +import React, { useImperativeHandle, useRef } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; + import { useStyles2 } from '../../themes'; + import { useMenuFocus } from './hooks'; /** @internal */ diff --git a/packages/grafana-ui/src/components/Menu/MenuGroup.tsx b/packages/grafana-ui/src/components/Menu/MenuGroup.tsx index b730ec8685c..2054dde3b6c 100644 --- a/packages/grafana-ui/src/components/Menu/MenuGroup.tsx +++ b/packages/grafana-ui/src/components/Menu/MenuGroup.tsx @@ -1,9 +1,12 @@ -import React from 'react'; import { css } from '@emotion/css'; -import { GrafanaTheme2 } from '@grafana/data'; -import { useStyles2 } from '../../themes'; -import { MenuItemProps } from './MenuItem'; import { uniqueId } from 'lodash'; +import React from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; + +import { useStyles2 } from '../../themes'; + +import { MenuItemProps } from './MenuItem'; /** @internal */ export interface MenuItemsGroup { diff --git a/packages/grafana-ui/src/components/Menu/MenuItem.test.tsx b/packages/grafana-ui/src/components/Menu/MenuItem.test.tsx index 5de2a902c81..39f5719361b 100644 --- a/packages/grafana-ui/src/components/Menu/MenuItem.test.tsx +++ b/packages/grafana-ui/src/components/Menu/MenuItem.test.tsx @@ -1,7 +1,9 @@ -import React from 'react'; -import { render, screen } from '@testing-library/react'; import { fireEvent } from '@testing-library/dom'; +import { render, screen } from '@testing-library/react'; +import React from 'react'; + import { selectors } from '@grafana/e2e-selectors'; + import { MenuItem, MenuItemProps } from './MenuItem'; describe('MenuItem', () => { diff --git a/packages/grafana-ui/src/components/Menu/MenuItem.tsx b/packages/grafana-ui/src/components/Menu/MenuItem.tsx index 4a383214c2c..7f47ba10b92 100644 --- a/packages/grafana-ui/src/components/Menu/MenuItem.tsx +++ b/packages/grafana-ui/src/components/Menu/MenuItem.tsx @@ -1,11 +1,14 @@ -import React, { ReactElement, useCallback, useMemo, useState, useRef, useImperativeHandle } from 'react'; import { css, cx } from '@emotion/css'; +import React, { ReactElement, useCallback, useMemo, useState, useRef, useImperativeHandle } from 'react'; + import { GrafanaTheme2, LinkTarget } from '@grafana/data'; + import { useStyles2 } from '../../themes'; -import { Icon } from '../Icon/Icon'; -import { IconName } from '../../types'; -import { SubMenu } from './SubMenu'; import { getFocusStyles } from '../../themes/mixins'; +import { IconName } from '../../types'; +import { Icon } from '../Icon/Icon'; + +import { SubMenu } from './SubMenu'; /** @internal */ export type MenuItemElement = HTMLAnchorElement & HTMLButtonElement & HTMLDivElement; diff --git a/packages/grafana-ui/src/components/Menu/SubMenu.test.tsx b/packages/grafana-ui/src/components/Menu/SubMenu.test.tsx index b96064ffbfe..a7785fe8974 100644 --- a/packages/grafana-ui/src/components/Menu/SubMenu.test.tsx +++ b/packages/grafana-ui/src/components/Menu/SubMenu.test.tsx @@ -1,6 +1,8 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; +import React from 'react'; + import { selectors } from '@grafana/e2e-selectors'; + import { MenuItem } from './MenuItem'; import { SubMenu } from './SubMenu'; diff --git a/packages/grafana-ui/src/components/Menu/SubMenu.tsx b/packages/grafana-ui/src/components/Menu/SubMenu.tsx index cbdab1f25f6..dfab72235e3 100644 --- a/packages/grafana-ui/src/components/Menu/SubMenu.tsx +++ b/packages/grafana-ui/src/components/Menu/SubMenu.tsx @@ -1,12 +1,15 @@ -import React, { ReactElement, useRef } from 'react'; import { css } from '@emotion/css'; +import React, { ReactElement, useRef } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; + import { useStyles2 } from '../../themes'; import { Icon } from '../Icon/Icon'; + import { MenuItemProps } from './MenuItem'; -import { getPosition } from './utils'; import { useMenuFocus } from './hooks'; +import { getPosition } from './utils'; /** @internal */ export interface SubMenuProps { diff --git a/packages/grafana-ui/src/components/Menu/hooks.test.tsx b/packages/grafana-ui/src/components/Menu/hooks.test.tsx index 6c2203075d6..a35406e6a35 100644 --- a/packages/grafana-ui/src/components/Menu/hooks.test.tsx +++ b/packages/grafana-ui/src/components/Menu/hooks.test.tsx @@ -1,7 +1,8 @@ -import React, { createRef, KeyboardEvent, RefObject } from 'react'; -import { render, screen } from '@testing-library/react'; import { fireEvent } from '@testing-library/dom'; +import { render, screen } from '@testing-library/react'; import { act, renderHook } from '@testing-library/react-hooks'; +import React, { createRef, KeyboardEvent, RefObject } from 'react'; + import { useMenuFocus } from './hooks'; describe('useMenuFocus', () => { diff --git a/packages/grafana-ui/src/components/Menu/hooks.ts b/packages/grafana-ui/src/components/Menu/hooks.ts index 1ea4525bad0..b21f220c302 100644 --- a/packages/grafana-ui/src/components/Menu/hooks.ts +++ b/packages/grafana-ui/src/components/Menu/hooks.ts @@ -1,5 +1,6 @@ import { RefObject, useEffect, useState } from 'react'; import { useEffectOnce } from 'react-use'; + import { MenuItemElement } from './MenuItem'; const modulo = (a: number, n: number) => ((a % n) + n) % n; diff --git a/packages/grafana-ui/src/components/Modal/Modal.story.tsx b/packages/grafana-ui/src/components/Modal/Modal.story.tsx index ee2e9e3bdee..e294d5f2479 100644 --- a/packages/grafana-ui/src/components/Modal/Modal.story.tsx +++ b/packages/grafana-ui/src/components/Modal/Modal.story.tsx @@ -1,12 +1,14 @@ -import React, { useState } from 'react'; -import { oneLineTrim } from 'common-tags'; -import { Story, Meta } from '@storybook/react'; -import { getAvailableIcons } from '../../types'; -import { Button, Modal, ModalTabsHeader, TabContent } from '@grafana/ui'; import { css, cx } from '@emotion/css'; +import { Story, Meta } from '@storybook/react'; +import { oneLineTrim } from 'common-tags'; +import React, { useState } from 'react'; -import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; +import { Button, Modal, ModalTabsHeader, TabContent } from '@grafana/ui'; + +import { getAvailableIcons } from '../../types'; import { UseState } from '../../utils/storybook/UseState'; +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; + import mdx from './Modal.mdx'; export default { diff --git a/packages/grafana-ui/src/components/Modal/Modal.test.tsx b/packages/grafana-ui/src/components/Modal/Modal.test.tsx index f629c8fb54d..08d558d395b 100644 --- a/packages/grafana-ui/src/components/Modal/Modal.test.tsx +++ b/packages/grafana-ui/src/components/Modal/Modal.test.tsx @@ -1,6 +1,7 @@ -import React from 'react'; -import { Modal } from './Modal'; import { render, screen } from '@testing-library/react'; +import React from 'react'; + +import { Modal } from './Modal'; describe('Modal', () => { it('renders nothing by default or when isOpen is false', () => { diff --git a/packages/grafana-ui/src/components/Modal/Modal.tsx b/packages/grafana-ui/src/components/Modal/Modal.tsx index a159a2825ec..8b2e6adc175 100644 --- a/packages/grafana-ui/src/components/Modal/Modal.tsx +++ b/packages/grafana-ui/src/components/Modal/Modal.tsx @@ -1,7 +1,6 @@ import { cx } from '@emotion/css'; -import { FocusScope } from '@react-aria/focus'; import { useDialog } from '@react-aria/dialog'; - +import { FocusScope } from '@react-aria/focus'; import { OverlayContainer, useOverlay } from '@react-aria/overlays'; import React, { PropsWithChildren, useRef } from 'react'; @@ -9,8 +8,9 @@ import { useTheme2 } from '../../themes'; import { IconName } from '../../types'; import { IconButton } from '../IconButton/IconButton'; import { HorizontalGroup } from '../Layout/Layout'; -import { getModalStyles } from './getModalStyles'; + import { ModalHeader } from './ModalHeader'; +import { getModalStyles } from './getModalStyles'; export interface Props { /** @deprecated no longer used */ diff --git a/packages/grafana-ui/src/components/Modal/ModalHeader.tsx b/packages/grafana-ui/src/components/Modal/ModalHeader.tsx index 6d5c2c1acaf..3eeaaffdaf7 100644 --- a/packages/grafana-ui/src/components/Modal/ModalHeader.tsx +++ b/packages/grafana-ui/src/components/Modal/ModalHeader.tsx @@ -1,7 +1,9 @@ import React from 'react'; -import { getModalStyles } from './getModalStyles'; -import { IconName } from '../../types'; + import { useStyles2 } from '../../themes'; +import { IconName } from '../../types'; + +import { getModalStyles } from './getModalStyles'; interface Props { title: string; diff --git a/packages/grafana-ui/src/components/Modal/ModalTabContent.tsx b/packages/grafana-ui/src/components/Modal/ModalTabContent.tsx index 8b00f9c8f9a..1c1bbb13d76 100644 --- a/packages/grafana-ui/src/components/Modal/ModalTabContent.tsx +++ b/packages/grafana-ui/src/components/Modal/ModalTabContent.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { IconName } from '../../types'; interface Props { diff --git a/packages/grafana-ui/src/components/Modal/ModalTabsHeader.tsx b/packages/grafana-ui/src/components/Modal/ModalTabsHeader.tsx index a4a2820ab2c..dd2c09e129d 100644 --- a/packages/grafana-ui/src/components/Modal/ModalTabsHeader.tsx +++ b/packages/grafana-ui/src/components/Modal/ModalTabsHeader.tsx @@ -1,8 +1,11 @@ import React from 'react'; + import { NavModelItem } from '@grafana/data'; + import { IconName } from '../../types'; -import { TabsBar } from '../Tabs/TabsBar'; import { Tab } from '../Tabs/Tab'; +import { TabsBar } from '../Tabs/TabsBar'; + import { ModalHeader } from './ModalHeader'; interface ModalTab { diff --git a/packages/grafana-ui/src/components/Modal/getModalStyles.ts b/packages/grafana-ui/src/components/Modal/getModalStyles.ts index 312c517baa0..470f0201ac6 100644 --- a/packages/grafana-ui/src/components/Modal/getModalStyles.ts +++ b/packages/grafana-ui/src/components/Modal/getModalStyles.ts @@ -1,5 +1,7 @@ import { css } from '@emotion/css'; + import { GrafanaTheme2 } from '@grafana/data'; + import { stylesFactory } from '../../themes'; export const getModalStyles = stylesFactory((theme: GrafanaTheme2) => { diff --git a/packages/grafana-ui/src/components/Monaco/CodeEditor.story.internal.tsx b/packages/grafana-ui/src/components/Monaco/CodeEditor.story.internal.tsx index 507693571f0..9fd540a97dd 100644 --- a/packages/grafana-ui/src/components/Monaco/CodeEditor.story.internal.tsx +++ b/packages/grafana-ui/src/components/Monaco/CodeEditor.story.internal.tsx @@ -1,9 +1,11 @@ -import React from 'react'; -import { Meta, Story } from '@storybook/react'; import { action } from '@storybook/addon-actions'; +import { Meta, Story } from '@storybook/react'; +import React from 'react'; + import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; -import mdx from './CodeEditor.mdx'; + import { CodeEditor } from './CodeEditor'; +import mdx from './CodeEditor.mdx'; export default { title: 'CodeEditor', diff --git a/packages/grafana-ui/src/components/Monaco/CodeEditor.tsx b/packages/grafana-ui/src/components/Monaco/CodeEditor.tsx index b2eef4196e2..c6f8dad7157 100644 --- a/packages/grafana-ui/src/components/Monaco/CodeEditor.tsx +++ b/packages/grafana-ui/src/components/Monaco/CodeEditor.tsx @@ -1,15 +1,16 @@ -import React from 'react'; import { css } from '@emotion/css'; -import { ReactMonacoEditorLazy } from './ReactMonacoEditorLazy'; import type * as monacoType from 'monaco-editor/esm/vs/editor/editor.api'; -import { selectors } from '@grafana/e2e-selectors'; +import React from 'react'; + import { GrafanaTheme2, monacoLanguageRegistry } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; import { withTheme2 } from '../../themes'; import { Themeable2 } from '../../types'; -import { CodeEditorProps, Monaco, MonacoEditor as MonacoEditorType, MonacoOptions } from './types'; +import { ReactMonacoEditorLazy } from './ReactMonacoEditorLazy'; import { registerSuggestions } from './suggestions'; +import { CodeEditorProps, Monaco, MonacoEditor as MonacoEditorType, MonacoOptions } from './types'; type Props = CodeEditorProps & Themeable2; diff --git a/packages/grafana-ui/src/components/Monaco/ReactMonacoEditor.tsx b/packages/grafana-ui/src/components/Monaco/ReactMonacoEditor.tsx index d0a00fa1172..b2efffd2d7b 100644 --- a/packages/grafana-ui/src/components/Monaco/ReactMonacoEditor.tsx +++ b/packages/grafana-ui/src/components/Monaco/ReactMonacoEditor.tsx @@ -1,7 +1,9 @@ -import React, { useEffect } from 'react'; import MonacoEditor, { loader as monacoEditorLoader, useMonaco } from '@monaco-editor/react'; -import defineThemes from './theme'; +import React, { useEffect } from 'react'; + import { useTheme2 } from '../../themes'; + +import defineThemes from './theme'; import type { ReactMonacoEditorProps } from './types'; let initalized = false; diff --git a/packages/grafana-ui/src/components/Monaco/ReactMonacoEditorLazy.tsx b/packages/grafana-ui/src/components/Monaco/ReactMonacoEditorLazy.tsx index b8db38dac1c..5075f66242d 100644 --- a/packages/grafana-ui/src/components/Monaco/ReactMonacoEditorLazy.tsx +++ b/packages/grafana-ui/src/components/Monaco/ReactMonacoEditorLazy.tsx @@ -1,6 +1,8 @@ import React from 'react'; -import { useAsyncDependency } from '../../utils/useAsyncDependency'; + import { ErrorWithStack, LoadingPlaceholder } from '..'; +import { useAsyncDependency } from '../../utils/useAsyncDependency'; + // we only use import type so it will not be included in the bundle import type { ReactMonacoEditorProps } from './types'; diff --git a/packages/grafana-ui/src/components/Monaco/theme.ts b/packages/grafana-ui/src/components/Monaco/theme.ts index a85d79ac025..d073f40377e 100644 --- a/packages/grafana-ui/src/components/Monaco/theme.ts +++ b/packages/grafana-ui/src/components/Monaco/theme.ts @@ -1,4 +1,5 @@ import { GrafanaTheme2 } from '@grafana/data'; + import { Monaco, monacoTypes } from './types'; function getColors(theme?: GrafanaTheme2): monacoTypes.editor.IColors { diff --git a/packages/grafana-ui/src/components/Monaco/types.ts b/packages/grafana-ui/src/components/Monaco/types.ts index 876a941b02e..94ae00f245e 100644 --- a/packages/grafana-ui/src/components/Monaco/types.ts +++ b/packages/grafana-ui/src/components/Monaco/types.ts @@ -1,6 +1,6 @@ // We use `import type` to guarantee it'll be erased from the JS and it doesnt accidently bundle monaco -import type * as monacoType from 'monaco-editor/esm/vs/editor/editor.api'; import type { EditorProps } from '@monaco-editor/react'; +import type * as monacoType from 'monaco-editor/esm/vs/editor/editor.api'; // we do not allow customizing the theme. // (theme is complicated in Monaco, right now there is diff --git a/packages/grafana-ui/src/components/Monaco/utils.ts b/packages/grafana-ui/src/components/Monaco/utils.ts index c2f50ab19fa..3dbf207064a 100644 --- a/packages/grafana-ui/src/components/Monaco/utils.ts +++ b/packages/grafana-ui/src/components/Monaco/utils.ts @@ -1,4 +1,5 @@ import { VariableSuggestion } from '@grafana/data'; + import { CodeEditorSuggestionItem, CodeEditorSuggestionItemKind } from './types'; /** diff --git a/packages/grafana-ui/src/components/OptionsUI/color.tsx b/packages/grafana-ui/src/components/OptionsUI/color.tsx index 3b182dfd907..216591410d5 100644 --- a/packages/grafana-ui/src/components/OptionsUI/color.tsx +++ b/packages/grafana-ui/src/components/OptionsUI/color.tsx @@ -1,8 +1,10 @@ -import React from 'react'; -import { GrafanaTheme2 } from '@grafana/data'; -import { ColorPicker } from '../ColorPicker/ColorPicker'; -import { useTheme2, useStyles2 } from '../../themes'; import { css } from '@emotion/css'; +import React from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; + +import { useTheme2, useStyles2 } from '../../themes'; +import { ColorPicker } from '../ColorPicker/ColorPicker'; import { ColorSwatch } from '../ColorPicker/ColorSwatch'; /** diff --git a/packages/grafana-ui/src/components/OptionsUI/fieldColor.tsx b/packages/grafana-ui/src/components/OptionsUI/fieldColor.tsx index 21b1f4f24da..41e6d0fdb61 100644 --- a/packages/grafana-ui/src/components/OptionsUI/fieldColor.tsx +++ b/packages/grafana-ui/src/components/OptionsUI/fieldColor.tsx @@ -1,4 +1,6 @@ +import { css } from '@emotion/css'; import React, { CSSProperties, FC } from 'react'; + import { FieldConfigEditorProps, FieldColorModeId, @@ -11,12 +13,13 @@ import { FieldColorSeriesByMode, getFieldColorMode, } from '@grafana/data'; -import { Select } from '../Select/Select'; -import { ColorValueEditor } from './color'; + import { useStyles2, useTheme2 } from '../../themes/ThemeContext'; -import { css } from '@emotion/css'; import { Field } from '../Forms/Field'; import { RadioButtonGroup } from '../Forms/RadioButtonGroup/RadioButtonGroup'; +import { Select } from '../Select/Select'; + +import { ColorValueEditor } from './color'; export const FieldColorEditor: React.FC> = ({ value, diff --git a/packages/grafana-ui/src/components/OptionsUI/links.tsx b/packages/grafana-ui/src/components/OptionsUI/links.tsx index 844b9e75534..9501e9a0b7a 100644 --- a/packages/grafana-ui/src/components/OptionsUI/links.tsx +++ b/packages/grafana-ui/src/components/OptionsUI/links.tsx @@ -1,10 +1,12 @@ import React from 'react'; + import { DataLink, DataLinksFieldConfigSettings, FieldConfigEditorProps, VariableSuggestionsScope, } from '@grafana/data'; + import { DataLinksInlineEditor } from '../DataLinks/DataLinksInlineEditor/DataLinksInlineEditor'; export const DataLinksValueEditor: React.FC> = ({ diff --git a/packages/grafana-ui/src/components/OptionsUI/multiSelect.tsx b/packages/grafana-ui/src/components/OptionsUI/multiSelect.tsx index c6d45a53d87..5970d7cddfe 100644 --- a/packages/grafana-ui/src/components/OptionsUI/multiSelect.tsx +++ b/packages/grafana-ui/src/components/OptionsUI/multiSelect.tsx @@ -1,5 +1,7 @@ import React from 'react'; + import { FieldConfigEditorProps, SelectFieldConfigSettings, SelectableValue } from '@grafana/data'; + import { MultiSelect } from '../Select/Select'; interface State { diff --git a/packages/grafana-ui/src/components/OptionsUI/number.tsx b/packages/grafana-ui/src/components/OptionsUI/number.tsx index a2741d7f1d5..8d14073c517 100644 --- a/packages/grafana-ui/src/components/OptionsUI/number.tsx +++ b/packages/grafana-ui/src/components/OptionsUI/number.tsx @@ -1,10 +1,12 @@ import React, { useCallback } from 'react'; + import { FieldConfigEditorProps, toIntegerOrUndefined, toFloatOrUndefined, NumberFieldConfigSettings, } from '@grafana/data'; + import { Input } from '../Input/Input'; export const NumberValueEditor: React.FC> = ({ diff --git a/packages/grafana-ui/src/components/OptionsUI/select.tsx b/packages/grafana-ui/src/components/OptionsUI/select.tsx index 2c3405bbcc0..2737963faf9 100644 --- a/packages/grafana-ui/src/components/OptionsUI/select.tsx +++ b/packages/grafana-ui/src/components/OptionsUI/select.tsx @@ -1,5 +1,7 @@ import React from 'react'; + import { FieldConfigEditorProps, SelectFieldConfigSettings, SelectableValue } from '@grafana/data'; + import { Select } from '../Select/Select'; interface State { diff --git a/packages/grafana-ui/src/components/OptionsUI/slider.tsx b/packages/grafana-ui/src/components/OptionsUI/slider.tsx index 56a7699a3dd..ea2af1014db 100644 --- a/packages/grafana-ui/src/components/OptionsUI/slider.tsx +++ b/packages/grafana-ui/src/components/OptionsUI/slider.tsx @@ -1,5 +1,7 @@ import React from 'react'; + import { FieldConfigEditorProps, SliderFieldConfigSettings } from '@grafana/data'; + import { Slider } from '../Slider/Slider'; export const SliderValueEditor: React.FC> = ({ diff --git a/packages/grafana-ui/src/components/OptionsUI/stats.tsx b/packages/grafana-ui/src/components/OptionsUI/stats.tsx index 01bdca1c455..146a1371e4e 100644 --- a/packages/grafana-ui/src/components/OptionsUI/stats.tsx +++ b/packages/grafana-ui/src/components/OptionsUI/stats.tsx @@ -1,5 +1,7 @@ import React from 'react'; + import { FieldConfigEditorProps, StatsPickerConfigSettings } from '@grafana/data'; + import { StatsPicker } from '../StatsPicker/StatsPicker'; export const StatsPickerEditor: React.FC> = ({ diff --git a/packages/grafana-ui/src/components/OptionsUI/string.tsx b/packages/grafana-ui/src/components/OptionsUI/string.tsx index c8f9db7412c..7e22b318db6 100644 --- a/packages/grafana-ui/src/components/OptionsUI/string.tsx +++ b/packages/grafana-ui/src/components/OptionsUI/string.tsx @@ -1,5 +1,7 @@ import React, { useCallback } from 'react'; + import { StandardEditorProps, StringFieldConfigSettings } from '@grafana/data'; + import { Input } from '../Input/Input'; import { TextArea } from '../TextArea/TextArea'; diff --git a/packages/grafana-ui/src/components/OptionsUI/strings.tsx b/packages/grafana-ui/src/components/OptionsUI/strings.tsx index 9e1098818a6..4b5c55e3c84 100644 --- a/packages/grafana-ui/src/components/OptionsUI/strings.tsx +++ b/packages/grafana-ui/src/components/OptionsUI/strings.tsx @@ -1,10 +1,12 @@ -import React from 'react'; -import { FieldConfigEditorProps, StringFieldConfigSettings, GrafanaTheme } from '@grafana/data'; -import { Input } from '../Input/Input'; -import { Icon } from '../Icon/Icon'; -import { stylesFactory, getTheme } from '../../themes'; import { css } from '@emotion/css'; +import React from 'react'; + +import { FieldConfigEditorProps, StringFieldConfigSettings, GrafanaTheme } from '@grafana/data'; + +import { stylesFactory, getTheme } from '../../themes'; import { Button } from '../Button'; +import { Icon } from '../Icon/Icon'; +import { Input } from '../Input/Input'; type Props = FieldConfigEditorProps; interface State { diff --git a/packages/grafana-ui/src/components/OptionsUI/units.tsx b/packages/grafana-ui/src/components/OptionsUI/units.tsx index 6431f49de00..695681649fc 100644 --- a/packages/grafana-ui/src/components/OptionsUI/units.tsx +++ b/packages/grafana-ui/src/components/OptionsUI/units.tsx @@ -1,6 +1,7 @@ import React from 'react'; import { FieldConfigEditorProps, UnitFieldConfigSettings } from '@grafana/data'; + import { UnitPicker } from '../UnitPicker/UnitPicker'; export const UnitValueEditor: React.FC> = ({ diff --git a/packages/grafana-ui/src/components/PageLayout/PageToolbar.story.tsx b/packages/grafana-ui/src/components/PageLayout/PageToolbar.story.tsx index 502cabf497d..f1ee83d2ed1 100644 --- a/packages/grafana-ui/src/components/PageLayout/PageToolbar.story.tsx +++ b/packages/grafana-ui/src/components/PageLayout/PageToolbar.story.tsx @@ -1,11 +1,14 @@ -import React from 'react'; -import { ToolbarButton, VerticalGroup } from '@grafana/ui'; -import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; -import { PageToolbar } from './PageToolbar'; -import { StoryExample } from '../../utils/storybook/StoryExample'; import { action } from '@storybook/addon-actions'; +import React from 'react'; + +import { ToolbarButton, VerticalGroup } from '@grafana/ui'; + +import { StoryExample } from '../../utils/storybook/StoryExample'; +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; import { IconButton } from '../IconButton/IconButton'; +import { PageToolbar } from './PageToolbar'; + export default { title: 'Layout/PageToolbar', component: PageToolbar, diff --git a/packages/grafana-ui/src/components/PageLayout/PageToolbar.tsx b/packages/grafana-ui/src/components/PageLayout/PageToolbar.tsx index 07c02c3bc65..7fbc8336df9 100644 --- a/packages/grafana-ui/src/components/PageLayout/PageToolbar.tsx +++ b/packages/grafana-ui/src/components/PageLayout/PageToolbar.tsx @@ -1,14 +1,16 @@ -import React, { FC, ReactNode } from 'react'; import { css, cx } from '@emotion/css'; +import React, { FC, ReactNode } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; + +import { Link } from '..'; +import { styleMixins } from '../../themes'; import { useStyles2 } from '../../themes/ThemeContext'; +import { getFocusStyles } from '../../themes/mixins'; import { IconName } from '../../types'; import { Icon } from '../Icon/Icon'; -import { styleMixins } from '../../themes'; import { IconButton } from '../IconButton/IconButton'; -import { selectors } from '@grafana/e2e-selectors'; -import { Link } from '..'; -import { getFocusStyles } from '../../themes/mixins'; export interface Props { pageIcon?: IconName; diff --git a/packages/grafana-ui/src/components/Pagination/Pagination.story.tsx b/packages/grafana-ui/src/components/Pagination/Pagination.story.tsx index fca8d762155..80192bfee0e 100644 --- a/packages/grafana-ui/src/components/Pagination/Pagination.story.tsx +++ b/packages/grafana-ui/src/components/Pagination/Pagination.story.tsx @@ -1,9 +1,12 @@ -import React, { useState } from 'react'; import { Story } from '@storybook/react'; -import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; +import React, { useState } from 'react'; + import { Pagination } from '@grafana/ui'; -import mdx from './Pagination.mdx'; + +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; + import { Props } from './Pagination'; +import mdx from './Pagination.mdx'; export default { title: 'Buttons/Pagination', diff --git a/packages/grafana-ui/src/components/Pagination/Pagination.test.tsx b/packages/grafana-ui/src/components/Pagination/Pagination.test.tsx index 305e25050a3..68a85e6746c 100644 --- a/packages/grafana-ui/src/components/Pagination/Pagination.test.tsx +++ b/packages/grafana-ui/src/components/Pagination/Pagination.test.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; +import React from 'react'; + import { Pagination } from './Pagination'; describe('Pagination component', () => { diff --git a/packages/grafana-ui/src/components/Pagination/Pagination.tsx b/packages/grafana-ui/src/components/Pagination/Pagination.tsx index a15b7a1fe24..df605c60156 100644 --- a/packages/grafana-ui/src/components/Pagination/Pagination.tsx +++ b/packages/grafana-ui/src/components/Pagination/Pagination.tsx @@ -1,5 +1,6 @@ -import React, { useMemo } from 'react'; import { css } from '@emotion/css'; +import React, { useMemo } from 'react'; + import { useStyles2 } from '../../themes'; import { Button, ButtonVariant } from '../Button'; import { Icon } from '../Icon/Icon'; diff --git a/packages/grafana-ui/src/components/PanelChrome/ErrorIndicator.tsx b/packages/grafana-ui/src/components/PanelChrome/ErrorIndicator.tsx index 44a74d1d37e..b2ebb0860eb 100644 --- a/packages/grafana-ui/src/components/PanelChrome/ErrorIndicator.tsx +++ b/packages/grafana-ui/src/components/PanelChrome/ErrorIndicator.tsx @@ -1,9 +1,11 @@ -import React from 'react'; import { css, cx } from '@emotion/css'; +import React from 'react'; + +import { GrafanaTheme } from '@grafana/data'; + +import { useStyles } from '../../themes'; import { Icon } from '../Icon/Icon'; import { Tooltip } from '../Tooltip/Tooltip'; -import { useStyles } from '../../themes'; -import { GrafanaTheme } from '@grafana/data'; /** * @internal diff --git a/packages/grafana-ui/src/components/PanelChrome/LoadingIndicator.tsx b/packages/grafana-ui/src/components/PanelChrome/LoadingIndicator.tsx index 92bd024b6de..c5999d19f07 100644 --- a/packages/grafana-ui/src/components/PanelChrome/LoadingIndicator.tsx +++ b/packages/grafana-ui/src/components/PanelChrome/LoadingIndicator.tsx @@ -1,9 +1,11 @@ -import React from 'react'; import { css, cx } from '@emotion/css'; +import React from 'react'; + import { selectors } from '@grafana/e2e-selectors'; + +import { useStyles } from '../../themes'; import { Icon } from '../Icon/Icon'; import { Tooltip } from '../Tooltip/Tooltip'; -import { useStyles } from '../../themes'; /** * @internal diff --git a/packages/grafana-ui/src/components/PanelChrome/PanelChrome.story.tsx b/packages/grafana-ui/src/components/PanelChrome/PanelChrome.story.tsx index dab30b5d7c6..a14a0ffed96 100644 --- a/packages/grafana-ui/src/components/PanelChrome/PanelChrome.story.tsx +++ b/packages/grafana-ui/src/components/PanelChrome/PanelChrome.story.tsx @@ -1,11 +1,13 @@ -import React, { CSSProperties, useState } from 'react'; -import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; -import { PanelChrome, useTheme, PanelChromeProps } from '@grafana/ui'; -import { HorizontalGroup, VerticalGroup } from '../Layout/Layout'; import { merge } from 'lodash'; -import { GrafanaTheme } from '@grafana/data'; +import React, { CSSProperties, useState } from 'react'; import { useInterval } from 'react-use'; +import { GrafanaTheme } from '@grafana/data'; +import { PanelChrome, useTheme, PanelChromeProps } from '@grafana/ui'; + +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; +import { HorizontalGroup, VerticalGroup } from '../Layout/Layout'; + export default { title: 'Visualizations/PanelChrome', component: PanelChrome, diff --git a/packages/grafana-ui/src/components/PanelChrome/PanelChrome.tsx b/packages/grafana-ui/src/components/PanelChrome/PanelChrome.tsx index ab053e5ff1f..1b759ac826f 100644 --- a/packages/grafana-ui/src/components/PanelChrome/PanelChrome.tsx +++ b/packages/grafana-ui/src/components/PanelChrome/PanelChrome.tsx @@ -1,8 +1,10 @@ -import React, { CSSProperties, ReactNode } from 'react'; import { css } from '@emotion/css'; -import { useStyles2, useTheme2 } from '../../themes'; +import React, { CSSProperties, ReactNode } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; +import { useStyles2, useTheme2 } from '../../themes'; + /** * @internal */ diff --git a/packages/grafana-ui/src/components/PanelChrome/PanelContext.ts b/packages/grafana-ui/src/components/PanelChrome/PanelContext.ts index fbbf77f9dba..692b4e7d76c 100644 --- a/packages/grafana-ui/src/components/PanelChrome/PanelContext.ts +++ b/packages/grafana-ui/src/components/PanelChrome/PanelContext.ts @@ -1,3 +1,5 @@ +import React from 'react'; + import { EventBusSrv, EventBus, @@ -7,7 +9,7 @@ import { SplitOpen, CoreApp, } from '@grafana/data'; -import React from 'react'; + import { SeriesVisibilityChangeMode } from '.'; /** @alpha */ diff --git a/packages/grafana-ui/src/components/PanelChrome/index.ts b/packages/grafana-ui/src/components/PanelChrome/index.ts index 34b9286b246..db314257e28 100644 --- a/packages/grafana-ui/src/components/PanelChrome/index.ts +++ b/packages/grafana-ui/src/components/PanelChrome/index.ts @@ -1,6 +1,7 @@ import React from 'react'; -import { LoadingIndicator } from './LoadingIndicator'; + import { ErrorIndicator } from './ErrorIndicator'; +import { LoadingIndicator } from './LoadingIndicator'; import { PanelChrome as PanelChromeComponent, PanelChromeProps } from './PanelChrome'; /** diff --git a/packages/grafana-ui/src/components/PluginSignatureBadge/PluginSignatureBadge.story.tsx b/packages/grafana-ui/src/components/PluginSignatureBadge/PluginSignatureBadge.story.tsx index 4c92e79a7fa..0f35ecf1404 100644 --- a/packages/grafana-ui/src/components/PluginSignatureBadge/PluginSignatureBadge.story.tsx +++ b/packages/grafana-ui/src/components/PluginSignatureBadge/PluginSignatureBadge.story.tsx @@ -1,8 +1,10 @@ -import React from 'react'; import { Story } from '@storybook/react'; -import { PluginSignatureBadge } from '@grafana/ui'; -import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; +import React from 'react'; + import { PluginSignatureStatus } from '@grafana/data'; +import { PluginSignatureBadge } from '@grafana/ui'; + +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; export default { title: 'Data Display/PluginSignatureBadge', diff --git a/packages/grafana-ui/src/components/PluginSignatureBadge/PluginSignatureBadge.tsx b/packages/grafana-ui/src/components/PluginSignatureBadge/PluginSignatureBadge.tsx index d237060127e..6913310a7df 100644 --- a/packages/grafana-ui/src/components/PluginSignatureBadge/PluginSignatureBadge.tsx +++ b/packages/grafana-ui/src/components/PluginSignatureBadge/PluginSignatureBadge.tsx @@ -1,5 +1,7 @@ import React, { HTMLAttributes } from 'react'; + import { PluginSignatureStatus } from '@grafana/data'; + import { Badge, BadgeProps } from '../Badge/Badge'; /** diff --git a/packages/grafana-ui/src/components/Portal/Portal.tsx b/packages/grafana-ui/src/components/Portal/Portal.tsx index a5397721eba..0d260cca338 100644 --- a/packages/grafana-ui/src/components/Portal/Portal.tsx +++ b/packages/grafana-ui/src/components/Portal/Portal.tsx @@ -1,5 +1,6 @@ import React, { PropsWithChildren, useLayoutEffect, useRef } from 'react'; import ReactDOM from 'react-dom'; + import { useTheme2 } from '../../themes'; interface Props { diff --git a/packages/grafana-ui/src/components/QueryField/QueryField.story.tsx b/packages/grafana-ui/src/components/QueryField/QueryField.story.tsx index de2ffe3e60e..d7bae075ae9 100644 --- a/packages/grafana-ui/src/components/QueryField/QueryField.story.tsx +++ b/packages/grafana-ui/src/components/QueryField/QueryField.story.tsx @@ -1,7 +1,9 @@ import React from 'react'; -import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; + import { QueryField } from '@grafana/ui'; +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; + export default { title: 'Data Source/QueryField', component: QueryField, diff --git a/packages/grafana-ui/src/components/QueryField/QueryField.test.tsx b/packages/grafana-ui/src/components/QueryField/QueryField.test.tsx index fdfee01c17f..0ce32772ca0 100644 --- a/packages/grafana-ui/src/components/QueryField/QueryField.test.tsx +++ b/packages/grafana-ui/src/components/QueryField/QueryField.test.tsx @@ -1,9 +1,11 @@ -import React from 'react'; import { shallow } from 'enzyme'; -import { UnThemedQueryField } from './QueryField'; +import React from 'react'; import { Editor } from 'slate'; + import { createTheme } from '@grafana/data'; +import { UnThemedQueryField } from './QueryField'; + describe('', () => { it('should render with null initial value', () => { const wrapper = shallow( diff --git a/packages/grafana-ui/src/components/QueryField/QueryField.tsx b/packages/grafana-ui/src/components/QueryField/QueryField.tsx index bf22dac6fe0..e3ddca39eb4 100644 --- a/packages/grafana-ui/src/components/QueryField/QueryField.tsx +++ b/packages/grafana-ui/src/components/QueryField/QueryField.tsx @@ -1,20 +1,13 @@ +import { css, cx } from '@emotion/css'; +import classnames from 'classnames'; import { debounce } from 'lodash'; import React, { Context } from 'react'; - import { Value, Editor as CoreEditor } from 'slate'; -import { Editor, Plugin } from '@grafana/slate-react'; import Plain from 'slate-plain-serializer'; -import classnames from 'classnames'; -import { - ClearPlugin, - NewlinePlugin, - SelectionShortcutsPlugin, - IndentationPlugin, - ClipboardPlugin, - RunnerPlugin, - SuggestionsPlugin, -} from '../../slate-plugins'; +import { GrafanaTheme2 } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; +import { Editor, Plugin } from '@grafana/slate-react'; import { makeValue, @@ -25,9 +18,15 @@ import { SuggestionsState, Themeable2, } from '../..'; -import { selectors } from '@grafana/e2e-selectors'; -import { css, cx } from '@emotion/css'; -import { GrafanaTheme2 } from '@grafana/data'; +import { + ClearPlugin, + NewlinePlugin, + SelectionShortcutsPlugin, + IndentationPlugin, + ClipboardPlugin, + RunnerPlugin, + SuggestionsPlugin, +} from '../../slate-plugins'; import { withTheme2 } from '../../themes'; import { getFocusStyles } from '../../themes/mixins'; diff --git a/packages/grafana-ui/src/components/RefreshPicker/RefreshPicker.story.tsx b/packages/grafana-ui/src/components/RefreshPicker/RefreshPicker.story.tsx index c18c2663402..1ec9a5bafb3 100644 --- a/packages/grafana-ui/src/components/RefreshPicker/RefreshPicker.story.tsx +++ b/packages/grafana-ui/src/components/RefreshPicker/RefreshPicker.story.tsx @@ -1,10 +1,12 @@ -import React from 'react'; import { action } from '@storybook/addon-actions'; -import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; -import { UseState } from '../../utils/storybook/UseState'; +import React from 'react'; + import { RefreshPicker } from '@grafana/ui'; -import { StoryExample } from '../../utils/storybook/StoryExample'; + import { DashboardStoryCanvas } from '../../utils/storybook/DashboardStoryCanvas'; +import { StoryExample } from '../../utils/storybook/StoryExample'; +import { UseState } from '../../utils/storybook/UseState'; +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; import { HorizontalGroup } from '../Layout/Layout'; export default { diff --git a/packages/grafana-ui/src/components/RefreshPicker/RefreshPicker.tsx b/packages/grafana-ui/src/components/RefreshPicker/RefreshPicker.tsx index 2ceeaa18023..2e437b0076b 100644 --- a/packages/grafana-ui/src/components/RefreshPicker/RefreshPicker.tsx +++ b/packages/grafana-ui/src/components/RefreshPicker/RefreshPicker.tsx @@ -1,10 +1,12 @@ -import React, { PureComponent } from 'react'; import formatDuration from 'date-fns/formatDuration'; +import React, { PureComponent } from 'react'; + import { SelectableValue, parseDuration } from '@grafana/data'; -import { ButtonSelect } from '../Dropdown/ButtonSelect'; -import { ButtonGroup, ToolbarButton, ToolbarButtonVariant } from '../Button'; import { selectors } from '@grafana/e2e-selectors'; +import { ButtonGroup, ToolbarButton, ToolbarButtonVariant } from '../Button'; +import { ButtonSelect } from '../Dropdown/ButtonSelect'; + // Default intervals used in the refresh picker component export const defaultIntervals = ['5s', '10s', '30s', '1m', '5m', '15m', '30m', '1h', '2h', '1d']; const offLabel = 'Auto refresh turned off. Choose refresh time interval'; diff --git a/packages/grafana-ui/src/components/SecretFormField/SecretFormField.story.internal.tsx b/packages/grafana-ui/src/components/SecretFormField/SecretFormField.story.internal.tsx index 82c14a89d48..b9666246562 100644 --- a/packages/grafana-ui/src/components/SecretFormField/SecretFormField.story.internal.tsx +++ b/packages/grafana-ui/src/components/SecretFormField/SecretFormField.story.internal.tsx @@ -1,10 +1,11 @@ -import React from 'react'; import { action } from '@storybook/addon-actions'; import { Meta, Story } from '@storybook/react'; +import React from 'react'; + +import { UseState } from '../../utils/storybook/UseState'; +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; import { SecretFormField, Props } from './SecretFormField'; -import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; -import { UseState } from '../../utils/storybook/UseState'; export default { title: 'Forms/SecretFormField', diff --git a/packages/grafana-ui/src/components/SecretFormField/SecretFormField.tsx b/packages/grafana-ui/src/components/SecretFormField/SecretFormField.tsx index d71dc7a68e4..27da639c5ff 100644 --- a/packages/grafana-ui/src/components/SecretFormField/SecretFormField.tsx +++ b/packages/grafana-ui/src/components/SecretFormField/SecretFormField.tsx @@ -1,8 +1,9 @@ +import { css, cx } from '@emotion/css'; import { omit } from 'lodash'; import React, { InputHTMLAttributes, FunctionComponent } from 'react'; -import { FormField } from '../FormField/FormField'; + import { Button } from '../Button/Button'; -import { css, cx } from '@emotion/css'; +import { FormField } from '../FormField/FormField'; import { PopoverContent } from '../Tooltip'; export interface Props extends Omit, 'onReset'> { diff --git a/packages/grafana-ui/src/components/SecretInput/SecretInput.story.tsx b/packages/grafana-ui/src/components/SecretInput/SecretInput.story.tsx index 60da75ef7de..e19028188fc 100644 --- a/packages/grafana-ui/src/components/SecretInput/SecretInput.story.tsx +++ b/packages/grafana-ui/src/components/SecretInput/SecretInput.story.tsx @@ -1,8 +1,10 @@ -import React, { useState, ChangeEvent } from 'react'; import { Story, Meta } from '@storybook/react'; -import { SecretInput, Props } from './SecretInput'; +import React, { useState, ChangeEvent } from 'react'; + import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; +import { SecretInput, Props } from './SecretInput'; + export default { title: 'Forms/SecretInput', component: SecretInput, diff --git a/packages/grafana-ui/src/components/SecretInput/SecretInput.test.tsx b/packages/grafana-ui/src/components/SecretInput/SecretInput.test.tsx index fb525e93a1b..284b30fbf35 100644 --- a/packages/grafana-ui/src/components/SecretInput/SecretInput.test.tsx +++ b/packages/grafana-ui/src/components/SecretInput/SecretInput.test.tsx @@ -1,6 +1,7 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import React from 'react'; + import { SecretInput, RESET_BUTTON_TEXT, CONFIGURED_TEXT } from './SecretInput'; const PLACEHOLDER_TEXT = 'Your secret...'; diff --git a/packages/grafana-ui/src/components/SecretInput/SecretInput.tsx b/packages/grafana-ui/src/components/SecretInput/SecretInput.tsx index d46a70903a1..b996cf70236 100644 --- a/packages/grafana-ui/src/components/SecretInput/SecretInput.tsx +++ b/packages/grafana-ui/src/components/SecretInput/SecretInput.tsx @@ -1,7 +1,8 @@ import * as React from 'react'; + +import { Button } from '../Button'; import { Input } from '../Input/Input'; import { HorizontalGroup } from '../Layout/Layout'; -import { Button } from '../Button'; export type Props = React.ComponentProps & { /** TRUE if the secret was already configured. (It is needed as often the backend doesn't send back the actual secret, only the information that it was configured) */ diff --git a/packages/grafana-ui/src/components/Segment/Segment.story.tsx b/packages/grafana-ui/src/components/Segment/Segment.story.tsx index ab629544ce8..663753c26c9 100644 --- a/packages/grafana-ui/src/components/Segment/Segment.story.tsx +++ b/packages/grafana-ui/src/components/Segment/Segment.story.tsx @@ -1,5 +1,6 @@ -import React, { useState } from 'react'; import { action } from '@storybook/addon-actions'; +import React, { useState } from 'react'; + import { Segment, Icon, SegmentSection } from '@grafana/ui'; const AddButton = ( diff --git a/packages/grafana-ui/src/components/Segment/Segment.tsx b/packages/grafana-ui/src/components/Segment/Segment.tsx index 23fa86e7f5a..c5eb15e91cf 100644 --- a/packages/grafana-ui/src/components/Segment/Segment.tsx +++ b/packages/grafana-ui/src/components/Segment/Segment.tsx @@ -1,11 +1,15 @@ -import React, { HTMLProps } from 'react'; import { cx } from '@emotion/css'; import { isObject } from 'lodash'; +import React, { HTMLProps } from 'react'; + import { SelectableValue } from '@grafana/data'; -import { SegmentSelect, useExpandableLabel, SegmentProps } from './'; -import { getSegmentStyles } from './styles'; -import { InlineLabel } from '../Forms/InlineLabel'; + import { useStyles } from '../../themes'; +import { InlineLabel } from '../Forms/InlineLabel'; + +import { getSegmentStyles } from './styles'; + +import { SegmentSelect, useExpandableLabel, SegmentProps } from './'; export interface SegmentSyncProps extends SegmentProps, Omit, 'value' | 'onChange'> { value?: T | SelectableValue; diff --git a/packages/grafana-ui/src/components/Segment/SegmentAsync.story.tsx b/packages/grafana-ui/src/components/Segment/SegmentAsync.story.tsx index 0c720b7350c..409f952c3cf 100644 --- a/packages/grafana-ui/src/components/Segment/SegmentAsync.story.tsx +++ b/packages/grafana-ui/src/components/Segment/SegmentAsync.story.tsx @@ -1,6 +1,7 @@ +import { action } from '@storybook/addon-actions'; import React, { useState } from 'react'; import { AsyncState } from 'react-use/lib/useAsync'; -import { action } from '@storybook/addon-actions'; + import { SelectableValue } from '@grafana/data'; import { SegmentAsync, Icon, SegmentSection } from '@grafana/ui'; diff --git a/packages/grafana-ui/src/components/Segment/SegmentAsync.tsx b/packages/grafana-ui/src/components/Segment/SegmentAsync.tsx index b952c38367e..cfdf16c6c5d 100644 --- a/packages/grafana-ui/src/components/Segment/SegmentAsync.tsx +++ b/packages/grafana-ui/src/components/Segment/SegmentAsync.tsx @@ -1,14 +1,18 @@ -import React, { HTMLProps } from 'react'; import { cx } from '@emotion/css'; import { isObject } from 'lodash'; -import { SegmentSelect } from './SegmentSelect'; -import { SelectableValue } from '@grafana/data'; -import { useExpandableLabel, SegmentProps } from '.'; +import React, { HTMLProps } from 'react'; import { useAsyncFn } from 'react-use'; import { AsyncState } from 'react-use/lib/useAsync'; -import { getSegmentStyles } from './styles'; -import { InlineLabel } from '../Forms/InlineLabel'; + +import { SelectableValue } from '@grafana/data'; + import { useStyles } from '../../themes'; +import { InlineLabel } from '../Forms/InlineLabel'; + +import { SegmentSelect } from './SegmentSelect'; +import { getSegmentStyles } from './styles'; + +import { useExpandableLabel, SegmentProps } from '.'; export interface SegmentAsyncProps extends SegmentProps, Omit, 'value' | 'onChange'> { value?: T | SelectableValue; diff --git a/packages/grafana-ui/src/components/Segment/SegmentInput.story.tsx b/packages/grafana-ui/src/components/Segment/SegmentInput.story.tsx index af21609e1df..a7eb9ba2d51 100644 --- a/packages/grafana-ui/src/components/Segment/SegmentInput.story.tsx +++ b/packages/grafana-ui/src/components/Segment/SegmentInput.story.tsx @@ -1,5 +1,6 @@ -import React, { useState } from 'react'; import { action } from '@storybook/addon-actions'; +import React, { useState } from 'react'; + import { SegmentInput, Icon, SegmentSection } from '@grafana/ui'; const SegmentFrame = ({ children }: any) => ( diff --git a/packages/grafana-ui/src/components/Segment/SegmentInput.tsx b/packages/grafana-ui/src/components/Segment/SegmentInput.tsx index 286c4b25288..048e439cb7b 100644 --- a/packages/grafana-ui/src/components/Segment/SegmentInput.tsx +++ b/packages/grafana-ui/src/components/Segment/SegmentInput.tsx @@ -1,11 +1,14 @@ -import React, { HTMLProps, useRef, useState } from 'react'; import { cx, css } from '@emotion/css'; +import React, { HTMLProps, useRef, useState } from 'react'; import useClickAway from 'react-use/lib/useClickAway'; -import { measureText } from '../../utils/measureText'; -import { useExpandableLabel, SegmentProps } from '.'; -import { getSegmentStyles } from './styles'; -import { InlineLabel } from '../Forms/InlineLabel'; + import { useStyles } from '../../themes'; +import { measureText } from '../../utils/measureText'; +import { InlineLabel } from '../Forms/InlineLabel'; + +import { getSegmentStyles } from './styles'; + +import { useExpandableLabel, SegmentProps } from '.'; export interface SegmentInputProps extends SegmentProps, Omit, 'value' | 'onChange'> { value: string | number; diff --git a/packages/grafana-ui/src/components/Segment/SegmentSection.tsx b/packages/grafana-ui/src/components/Segment/SegmentSection.tsx index a724c310391..03c13b77fff 100644 --- a/packages/grafana-ui/src/components/Segment/SegmentSection.tsx +++ b/packages/grafana-ui/src/components/Segment/SegmentSection.tsx @@ -1,9 +1,11 @@ -import React from 'react'; import { css } from '@emotion/css'; +import React from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; + import { useStyles2 } from '../../themes'; -import { InlineLabel } from '../Forms/InlineLabel'; import { InlineFieldRow } from '../Forms/InlineFieldRow'; +import { InlineLabel } from '../Forms/InlineLabel'; /** * Horizontal section for editor components. diff --git a/packages/grafana-ui/src/components/Segment/SegmentSelect.tsx b/packages/grafana-ui/src/components/Segment/SegmentSelect.tsx index a50d59b4285..6d6a1fed373 100644 --- a/packages/grafana-ui/src/components/Segment/SegmentSelect.tsx +++ b/packages/grafana-ui/src/components/Segment/SegmentSelect.tsx @@ -1,7 +1,9 @@ import React, { HTMLProps, useRef } from 'react'; + import { SelectableValue } from '@grafana/data'; -import { AsyncSelect, Select } from '../Select/Select'; + import { useTheme2 } from '../../themes/ThemeContext'; +import { AsyncSelect, Select } from '../Select/Select'; /** @internal * Should be used only internally by Segment/SegmentAsync which can guarantee that SegmentSelect is hidden diff --git a/packages/grafana-ui/src/components/Segment/styles.ts b/packages/grafana-ui/src/components/Segment/styles.ts index ad71e9ed31a..fab1d691a15 100644 --- a/packages/grafana-ui/src/components/Segment/styles.ts +++ b/packages/grafana-ui/src/components/Segment/styles.ts @@ -1,6 +1,7 @@ -import { GrafanaTheme } from '@grafana/data'; import { css } from '@emotion/css'; +import { GrafanaTheme } from '@grafana/data'; + export const getSegmentStyles = (theme: GrafanaTheme) => { return { segment: css` diff --git a/packages/grafana-ui/src/components/Select/Container.tsx b/packages/grafana-ui/src/components/Select/Container.tsx index 97095b3d401..33eacc870bd 100644 --- a/packages/grafana-ui/src/components/Select/Container.tsx +++ b/packages/grafana-ui/src/components/Select/Container.tsx @@ -1,12 +1,14 @@ +import { css, cx } from '@emotion/css'; import React from 'react'; +import { components, ContainerProps, GroupBase } from 'react-select'; + +import { GrafanaTheme2 } from '@grafana/data'; + +import { stylesFactory } from '../../themes'; import { useTheme2 } from '../../themes/ThemeContext'; +import { focusCss } from '../../themes/mixins'; import { sharedInputStyle } from '../Forms/commonStyles'; import { getInputStyles } from '../Input/Input'; -import { css, cx } from '@emotion/css'; -import { stylesFactory } from '../../themes'; -import { GrafanaTheme2 } from '@grafana/data'; -import { focusCss } from '../../themes/mixins'; -import { components, ContainerProps, GroupBase } from 'react-select'; export const SelectContainer = >( props: ContainerProps & { isFocused: boolean } diff --git a/packages/grafana-ui/src/components/Select/DropdownIndicator.tsx b/packages/grafana-ui/src/components/Select/DropdownIndicator.tsx index 0da7adfd403..0a9fc619deb 100644 --- a/packages/grafana-ui/src/components/Select/DropdownIndicator.tsx +++ b/packages/grafana-ui/src/components/Select/DropdownIndicator.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { Icon } from '../Icon/Icon'; interface DropdownIndicatorProps { diff --git a/packages/grafana-ui/src/components/Select/IndicatorsContainer.tsx b/packages/grafana-ui/src/components/Select/IndicatorsContainer.tsx index 35ef549b262..010e028c0c5 100644 --- a/packages/grafana-ui/src/components/Select/IndicatorsContainer.tsx +++ b/packages/grafana-ui/src/components/Select/IndicatorsContainer.tsx @@ -1,7 +1,8 @@ +import { cx, css } from '@emotion/css'; import React from 'react'; + import { useTheme2 } from '../../themes/ThemeContext'; import { getInputStyles } from '../Input/Input'; -import { cx, css } from '@emotion/css'; export const IndicatorsContainer = React.forwardRef>((props, ref) => { const { children } = props; diff --git a/packages/grafana-ui/src/components/Select/InputControl.tsx b/packages/grafana-ui/src/components/Select/InputControl.tsx index d06a268ebc7..c41f466163f 100644 --- a/packages/grafana-ui/src/components/Select/InputControl.tsx +++ b/packages/grafana-ui/src/components/Select/InputControl.tsx @@ -1,10 +1,12 @@ +import { css, cx } from '@emotion/css'; import React from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; + +import { stylesFactory } from '../../themes'; import { useTheme2 } from '../../themes/ThemeContext'; import { inputPadding } from '../Forms/commonStyles'; import { getInputStyles } from '../Input/Input'; -import { css, cx } from '@emotion/css'; -import { stylesFactory } from '../../themes'; -import { GrafanaTheme2 } from '@grafana/data'; interface InputControlProps { /** Show an icon as a prefix in the input */ diff --git a/packages/grafana-ui/src/components/Select/MultiValue.tsx b/packages/grafana-ui/src/components/Select/MultiValue.tsx index c7166459e68..0a02abc316a 100644 --- a/packages/grafana-ui/src/components/Select/MultiValue.tsx +++ b/packages/grafana-ui/src/components/Select/MultiValue.tsx @@ -2,6 +2,7 @@ import React from 'react'; import { useTheme2 } from '../../themes'; import { IconButton } from '../IconButton/IconButton'; + import { getSelectStyles } from './getSelectStyles'; interface MultiValueContainerProps { diff --git a/packages/grafana-ui/src/components/Select/Select.story.tsx b/packages/grafana-ui/src/components/Select/Select.story.tsx index 9ce878c5972..5466c26ce73 100644 --- a/packages/grafana-ui/src/components/Select/Select.story.tsx +++ b/packages/grafana-ui/src/components/Select/Select.story.tsx @@ -1,14 +1,17 @@ -import React, { useState } from 'react'; -import { withCenteredStory, withHorizontallyCenteredStory } from '../../utils/storybook/withCenteredStory'; -import { SelectableValue } from '@grafana/data'; -import { Icon, Select, AsyncSelect, MultiSelect, AsyncMultiSelect } from '@grafana/ui'; -import { getAvailableIcons, IconName } from '../../types'; -import { SelectCommonProps } from './types'; -import { Meta, Story } from '@storybook/react'; -import { generateOptions } from './mockOptions'; -import mdx from './Select.mdx'; import { auto } from '@popperjs/core'; import { action } from '@storybook/addon-actions'; +import { Meta, Story } from '@storybook/react'; +import React, { useState } from 'react'; + +import { SelectableValue } from '@grafana/data'; +import { Icon, Select, AsyncSelect, MultiSelect, AsyncMultiSelect } from '@grafana/ui'; + +import { getAvailableIcons, IconName } from '../../types'; +import { withCenteredStory, withHorizontallyCenteredStory } from '../../utils/storybook/withCenteredStory'; + +import mdx from './Select.mdx'; +import { generateOptions } from './mockOptions'; +import { SelectCommonProps } from './types'; export default { title: 'Forms/Select', diff --git a/packages/grafana-ui/src/components/Select/Select.tsx b/packages/grafana-ui/src/components/Select/Select.tsx index ad94830f156..0dc8310c474 100644 --- a/packages/grafana-ui/src/components/Select/Select.tsx +++ b/packages/grafana-ui/src/components/Select/Select.tsx @@ -1,8 +1,10 @@ import React from 'react'; + import { SelectableValue } from '@grafana/data'; -import { SelectCommonProps, MultiSelectCommonProps, SelectAsyncProps } from './types'; + import { SelectBase } from './SelectBase'; import { SelectContainer, SelectContainerProps } from './SelectContainer'; +import { SelectCommonProps, MultiSelectCommonProps, SelectAsyncProps } from './types'; export function Select(props: SelectCommonProps) { return ; diff --git a/packages/grafana-ui/src/components/Select/SelectBase.test.tsx b/packages/grafana-ui/src/components/Select/SelectBase.test.tsx index 680d07ffc2c..26b8b20cb4a 100644 --- a/packages/grafana-ui/src/components/Select/SelectBase.test.tsx +++ b/packages/grafana-ui/src/components/Select/SelectBase.test.tsx @@ -1,9 +1,11 @@ -import React, { useState } from 'react'; import { render, screen, fireEvent } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { selectOptionInTest } from './test-utils'; +import React, { useState } from 'react'; + import { SelectableValue } from '@grafana/data'; + import { SelectBase } from './SelectBase'; +import { selectOptionInTest } from './test-utils'; describe('SelectBase', () => { const onChangeHandler = () => jest.fn(); diff --git a/packages/grafana-ui/src/components/Select/SelectBase.tsx b/packages/grafana-ui/src/components/Select/SelectBase.tsx index b74dc5258d0..d6ab426a6cb 100644 --- a/packages/grafana-ui/src/components/Select/SelectBase.tsx +++ b/packages/grafana-ui/src/components/Select/SelectBase.tsx @@ -1,25 +1,26 @@ import React, { ComponentProps, useCallback, useEffect, useRef, useState } from 'react'; import { default as ReactSelect } from 'react-select'; -import Creatable from 'react-select/creatable'; import { default as ReactAsyncSelect } from 'react-select/async'; import { default as AsyncCreatable } from 'react-select/async-creatable'; +import Creatable from 'react-select/creatable'; +import { useTheme2 } from '../../themes'; import { Icon } from '../Icon/Icon'; import { Spinner } from '../Spinner/Spinner'; -import { useCustomSelectStyles } from './resetSelectStyles'; -import { SelectMenu, SelectMenuOptions } from './SelectMenu'; -import { IndicatorsContainer } from './IndicatorsContainer'; -import { ValueContainer } from './ValueContainer'; -import { InputControl } from './InputControl'; -import { SelectContainer } from './SelectContainer'; + import { DropdownIndicator } from './DropdownIndicator'; +import { IndicatorsContainer } from './IndicatorsContainer'; +import { InputControl } from './InputControl'; +import { MultiValueContainer, MultiValueRemove } from './MultiValue'; +import { SelectContainer } from './SelectContainer'; +import { SelectMenu, SelectMenuOptions } from './SelectMenu'; import { SelectOptionGroup } from './SelectOptionGroup'; import { SingleValue } from './SingleValue'; -import { MultiValueContainer, MultiValueRemove } from './MultiValue'; -import { useTheme2 } from '../../themes'; +import { ValueContainer } from './ValueContainer'; import { getSelectStyles } from './getSelectStyles'; -import { cleanValue, findSelectedValue } from './utils'; +import { useCustomSelectStyles } from './resetSelectStyles'; import { ActionMeta, SelectBaseProps, SelectValue } from './types'; +import { cleanValue, findSelectedValue } from './utils'; interface ExtraValuesIndicatorProps { maxVisibleValues?: number | undefined; diff --git a/packages/grafana-ui/src/components/Select/SelectContainer.tsx b/packages/grafana-ui/src/components/Select/SelectContainer.tsx index 6fdda6e9807..c7d500e9706 100644 --- a/packages/grafana-ui/src/components/Select/SelectContainer.tsx +++ b/packages/grafana-ui/src/components/Select/SelectContainer.tsx @@ -1,12 +1,14 @@ +import { css, cx } from '@emotion/css'; import React from 'react'; +import { components, ContainerProps as BaseContainerProps, GroupBase } from 'react-select'; + +import { GrafanaTheme2 } from '@grafana/data'; + +import { stylesFactory } from '../../themes'; import { useTheme2 } from '../../themes/ThemeContext'; +import { focusCss } from '../../themes/mixins'; import { sharedInputStyle } from '../Forms/commonStyles'; import { getInputStyles } from '../Input/Input'; -import { css, cx } from '@emotion/css'; -import { stylesFactory } from '../../themes'; -import { GrafanaTheme2 } from '@grafana/data'; -import { focusCss } from '../../themes/mixins'; -import { components, ContainerProps as BaseContainerProps, GroupBase } from 'react-select'; // isFocus prop is actually available, but its not in the types for the version we have. export interface SelectContainerProps> diff --git a/packages/grafana-ui/src/components/Select/SelectMenu.tsx b/packages/grafana-ui/src/components/Select/SelectMenu.tsx index d01197e3c71..d3e9c7c4352 100644 --- a/packages/grafana-ui/src/components/Select/SelectMenu.tsx +++ b/packages/grafana-ui/src/components/Select/SelectMenu.tsx @@ -1,11 +1,14 @@ -import React, { FC, RefCallback } from 'react'; -import { useTheme2 } from '../../themes/ThemeContext'; -import { getSelectStyles } from './getSelectStyles'; import { cx } from '@emotion/css'; +import React, { FC, RefCallback } from 'react'; + import { SelectableValue } from '@grafana/data'; + +import { useTheme2 } from '../../themes/ThemeContext'; +import { IconName } from '../../types'; import { CustomScrollbar } from '../CustomScrollbar/CustomScrollbar'; import { Icon } from '../Icon/Icon'; -import { IconName } from '../../types'; + +import { getSelectStyles } from './getSelectStyles'; interface SelectMenuProps { maxHeight: number; diff --git a/packages/grafana-ui/src/components/Select/SelectOptionGroup.tsx b/packages/grafana-ui/src/components/Select/SelectOptionGroup.tsx index 01697dd9a56..5d7ec5a2f24 100644 --- a/packages/grafana-ui/src/components/Select/SelectOptionGroup.tsx +++ b/packages/grafana-ui/src/components/Select/SelectOptionGroup.tsx @@ -1,7 +1,9 @@ -import React, { PureComponent } from 'react'; import { css } from '@emotion/css'; -import { GrafanaTheme } from '@grafana/data'; +import React, { PureComponent } from 'react'; import { GroupProps } from 'react-select'; + +import { GrafanaTheme } from '@grafana/data'; + import { stylesFactory, withTheme } from '../../themes'; import { Themeable } from '../../types'; import { Icon } from '../Icon/Icon'; diff --git a/packages/grafana-ui/src/components/Select/SingleValue.tsx b/packages/grafana-ui/src/components/Select/SingleValue.tsx index 8ae91d4ab4c..785978ad195 100644 --- a/packages/grafana-ui/src/components/Select/SingleValue.tsx +++ b/packages/grafana-ui/src/components/Select/SingleValue.tsx @@ -1,14 +1,16 @@ -import React from 'react'; import { css, cx } from '@emotion/css'; +import React from 'react'; import { components, GroupBase, SingleValueProps } from 'react-select'; -import { useDelayedSwitch } from '../../utils/useDelayedSwitch'; -import { useStyles2 } from '../../themes'; -import { SlideOutTransition } from '../transitions/SlideOutTransition'; -import { FadeTransition } from '../transitions/FadeTransition'; -import { Spinner } from '../Spinner/Spinner'; -import { GrafanaTheme2, SelectableValue } from '@grafana/data'; import tinycolor from 'tinycolor2'; +import { GrafanaTheme2, SelectableValue } from '@grafana/data'; + +import { useStyles2 } from '../../themes'; +import { useDelayedSwitch } from '../../utils/useDelayedSwitch'; +import { Spinner } from '../Spinner/Spinner'; +import { FadeTransition } from '../transitions/FadeTransition'; +import { SlideOutTransition } from '../transitions/SlideOutTransition'; + const getStyles = (theme: GrafanaTheme2) => { const singleValue = css` label: singleValue; diff --git a/packages/grafana-ui/src/components/Select/ValueContainer.tsx b/packages/grafana-ui/src/components/Select/ValueContainer.tsx index fbcf76805da..91fee0e95c3 100644 --- a/packages/grafana-ui/src/components/Select/ValueContainer.tsx +++ b/packages/grafana-ui/src/components/Select/ValueContainer.tsx @@ -1,7 +1,10 @@ -import React, { ReactNode } from 'react'; import { cx } from '@emotion/css'; +import React, { ReactNode } from 'react'; + import { GrafanaTheme } from '@grafana/data'; + import { withTheme2 } from '../../themes/ThemeContext'; + import { getSelectStyles } from './getSelectStyles'; class UnthemedValueContainer extends React.Component { diff --git a/packages/grafana-ui/src/components/Select/getSelectStyles.ts b/packages/grafana-ui/src/components/Select/getSelectStyles.ts index e3e2c7a4606..09b2eb3ec58 100644 --- a/packages/grafana-ui/src/components/Select/getSelectStyles.ts +++ b/packages/grafana-ui/src/components/Select/getSelectStyles.ts @@ -1,7 +1,9 @@ -import { stylesFactory } from '../../themes/stylesFactory'; import { css } from '@emotion/css'; + import { GrafanaTheme2 } from '@grafana/data'; +import { stylesFactory } from '../../themes/stylesFactory'; + export const getSelectStyles = stylesFactory((theme: GrafanaTheme2) => { return { menu: css` diff --git a/packages/grafana-ui/src/components/Select/mockOptions.tsx b/packages/grafana-ui/src/components/Select/mockOptions.tsx index 56eea3cfae0..de67501cd00 100644 --- a/packages/grafana-ui/src/components/Select/mockOptions.tsx +++ b/packages/grafana-ui/src/components/Select/mockOptions.tsx @@ -1,6 +1,7 @@ -import { SelectableValue } from '@grafana/data'; import { kebabCase } from 'lodash'; +import { SelectableValue } from '@grafana/data'; + export const generateOptions = (desc = false) => { const values = [ 'Sharilyn Markowitz', diff --git a/packages/grafana-ui/src/components/Select/resetSelectStyles.ts b/packages/grafana-ui/src/components/Select/resetSelectStyles.ts index 9c90d1d701e..6ffe4fa5aff 100644 --- a/packages/grafana-ui/src/components/Select/resetSelectStyles.ts +++ b/packages/grafana-ui/src/components/Select/resetSelectStyles.ts @@ -1,7 +1,8 @@ -import { GrafanaTheme2 } from '@grafana/data'; import { useMemo } from 'react'; import { CSSObjectWithLabel } from 'react-select'; +import { GrafanaTheme2 } from '@grafana/data'; + export default function resetSelectStyles(theme: GrafanaTheme2) { return { clearIndicator: () => ({}), diff --git a/packages/grafana-ui/src/components/Select/types.ts b/packages/grafana-ui/src/components/Select/types.ts index 12606c768c0..a634735b24a 100644 --- a/packages/grafana-ui/src/components/Select/types.ts +++ b/packages/grafana-ui/src/components/Select/types.ts @@ -1,7 +1,8 @@ -import { SelectableValue } from '@grafana/data'; import React from 'react'; import { ActionMeta as SelectActionMeta, GroupBase, OptionsOrGroups } from 'react-select'; +import { SelectableValue } from '@grafana/data'; + export type SelectValue = T | SelectableValue | T[] | Array>; export type ActionMeta = SelectActionMeta<{}>; export type InputActionMeta = { diff --git a/packages/grafana-ui/src/components/Select/utils.test.ts b/packages/grafana-ui/src/components/Select/utils.test.ts index e279b9418f1..2beda650e46 100644 --- a/packages/grafana-ui/src/components/Select/utils.test.ts +++ b/packages/grafana-ui/src/components/Select/utils.test.ts @@ -1,7 +1,8 @@ -import { cleanValue, findSelectedValue } from './utils'; -import { SelectableOptGroup } from './types'; import { SelectableValue } from '@grafana/data'; +import { SelectableOptGroup } from './types'; +import { cleanValue, findSelectedValue } from './utils'; + const optGroup: SelectableOptGroup[] = [ { label: 'Group 1', diff --git a/packages/grafana-ui/src/components/Select/utils.ts b/packages/grafana-ui/src/components/Select/utils.ts index a564781c398..5972ec6a888 100644 --- a/packages/grafana-ui/src/components/Select/utils.ts +++ b/packages/grafana-ui/src/components/Select/utils.ts @@ -1,4 +1,5 @@ import { SelectableValue } from '@grafana/data'; + import { SelectableOptGroup } from './types'; /** diff --git a/packages/grafana-ui/src/components/SetInterval/SetInterval.tsx b/packages/grafana-ui/src/components/SetInterval/SetInterval.tsx index e80746a436d..7d6f2089a4e 100644 --- a/packages/grafana-ui/src/components/SetInterval/SetInterval.tsx +++ b/packages/grafana-ui/src/components/SetInterval/SetInterval.tsx @@ -1,9 +1,10 @@ +import { isEqual } from 'lodash'; import { PureComponent } from 'react'; import { interval, Subscription, Subject, of, NEVER } from 'rxjs'; import { tap, switchMap } from 'rxjs/operators'; -import { isEqual } from 'lodash'; import { stringToMs, SelectableValue } from '@grafana/data'; + import { RefreshPicker } from '../RefreshPicker/RefreshPicker'; export function getIntervalFromString(strInterval: string): SelectableValue { diff --git a/packages/grafana-ui/src/components/SingleStatShared/SingleStatBaseOptions.test.ts b/packages/grafana-ui/src/components/SingleStatShared/SingleStatBaseOptions.test.ts index b7f6778f40c..f4ca88af522 100644 --- a/packages/grafana-ui/src/components/SingleStatShared/SingleStatBaseOptions.test.ts +++ b/packages/grafana-ui/src/components/SingleStatShared/SingleStatBaseOptions.test.ts @@ -1,6 +1,7 @@ -import { sharedSingleStatMigrationHandler, sharedSingleStatPanelChangedHandler } from './SingleStatBaseOptions'; import { PanelModel } from '@grafana/data'; +import { sharedSingleStatMigrationHandler, sharedSingleStatPanelChangedHandler } from './SingleStatBaseOptions'; + describe('sharedSingleStatMigrationHandler', () => { it('from old valueOptions model without pluginVersion', () => { const panel = { diff --git a/packages/grafana-ui/src/components/SingleStatShared/SingleStatBaseOptions.ts b/packages/grafana-ui/src/components/SingleStatShared/SingleStatBaseOptions.ts index c884ac1b7f9..ee5febb6c56 100644 --- a/packages/grafana-ui/src/components/SingleStatShared/SingleStatBaseOptions.ts +++ b/packages/grafana-ui/src/components/SingleStatShared/SingleStatBaseOptions.ts @@ -1,6 +1,5 @@ import { cloneDeep, isNumber, omit } from 'lodash'; -import { OptionsWithTextFormatting } from '@grafana/schema'; import { convertOldAngularValueMappings, FieldColorModeId, @@ -17,6 +16,7 @@ import { ValueMapping, VizOrientation, } from '@grafana/data'; +import { OptionsWithTextFormatting } from '@grafana/schema'; export interface SingleStatBaseOptions extends OptionsWithTextFormatting { reduceOptions: ReduceDataOptions; diff --git a/packages/grafana-ui/src/components/Slider/RangeSlider.story.tsx b/packages/grafana-ui/src/components/Slider/RangeSlider.story.tsx index ca4f1807380..32626f110bc 100644 --- a/packages/grafana-ui/src/components/Slider/RangeSlider.story.tsx +++ b/packages/grafana-ui/src/components/Slider/RangeSlider.story.tsx @@ -1,7 +1,9 @@ -import React from 'react'; -import { RangeSlider } from '@grafana/ui'; -import { RangeSliderProps } from './types'; import { Meta, Story } from '@storybook/react'; +import React from 'react'; + +import { RangeSlider } from '@grafana/ui'; + +import { RangeSliderProps } from './types'; export default { title: 'Forms/Slider/Range', diff --git a/packages/grafana-ui/src/components/Slider/RangeSlider.test.tsx b/packages/grafana-ui/src/components/Slider/RangeSlider.test.tsx index 6011cbff161..081921efa8e 100644 --- a/packages/grafana-ui/src/components/Slider/RangeSlider.test.tsx +++ b/packages/grafana-ui/src/components/Slider/RangeSlider.test.tsx @@ -1,7 +1,8 @@ +import { render } from '@testing-library/react'; import React from 'react'; + import { RangeSlider } from './RangeSlider'; import { RangeSliderProps } from './types'; -import { render } from '@testing-library/react'; const sliderProps: RangeSliderProps = { min: 10, diff --git a/packages/grafana-ui/src/components/Slider/RangeSlider.tsx b/packages/grafana-ui/src/components/Slider/RangeSlider.tsx index 02fefaf5036..6fbbd592022 100644 --- a/packages/grafana-ui/src/components/Slider/RangeSlider.tsx +++ b/packages/grafana-ui/src/components/Slider/RangeSlider.tsx @@ -1,8 +1,10 @@ -import React, { FunctionComponent } from 'react'; -import { Range as RangeComponent, createSliderWithTooltip } from 'rc-slider'; import { cx } from '@emotion/css'; import { Global } from '@emotion/react'; +import { Range as RangeComponent, createSliderWithTooltip } from 'rc-slider'; +import React, { FunctionComponent } from 'react'; + import { useTheme2 } from '../../themes/ThemeContext'; + import { getStyles } from './styles'; import { RangeSliderProps } from './types'; diff --git a/packages/grafana-ui/src/components/Slider/Slider.story.tsx b/packages/grafana-ui/src/components/Slider/Slider.story.tsx index 4263897134b..453562e6a32 100644 --- a/packages/grafana-ui/src/components/Slider/Slider.story.tsx +++ b/packages/grafana-ui/src/components/Slider/Slider.story.tsx @@ -1,8 +1,11 @@ -import React from 'react'; -import { Slider } from '@grafana/ui'; -import { SliderProps } from './types'; -import { Orientation } from '../../types/orientation'; import { Story, Meta } from '@storybook/react'; +import React from 'react'; + +import { Slider } from '@grafana/ui'; + +import { Orientation } from '../../types/orientation'; + +import { SliderProps } from './types'; export default { title: 'Forms/Slider', diff --git a/packages/grafana-ui/src/components/Slider/Slider.test.tsx b/packages/grafana-ui/src/components/Slider/Slider.test.tsx index d4274a8dc4b..a3f3e30d4d0 100644 --- a/packages/grafana-ui/src/components/Slider/Slider.test.tsx +++ b/packages/grafana-ui/src/components/Slider/Slider.test.tsx @@ -1,7 +1,8 @@ +import { mount } from 'enzyme'; import React from 'react'; + import { Slider } from './Slider'; import { SliderProps } from './types'; -import { mount } from 'enzyme'; const sliderProps: SliderProps = { min: 10, diff --git a/packages/grafana-ui/src/components/Slider/Slider.tsx b/packages/grafana-ui/src/components/Slider/Slider.tsx index 57c7b643302..7f161850ec2 100644 --- a/packages/grafana-ui/src/components/Slider/Slider.tsx +++ b/packages/grafana-ui/src/components/Slider/Slider.tsx @@ -1,12 +1,13 @@ -import React, { useState, useCallback, ChangeEvent, FunctionComponent, FocusEvent } from 'react'; -import SliderComponent from 'rc-slider'; - import { cx } from '@emotion/css'; import { Global } from '@emotion/react'; +import SliderComponent from 'rc-slider'; +import React, { useState, useCallback, ChangeEvent, FunctionComponent, FocusEvent } from 'react'; + import { useTheme2 } from '../../themes/ThemeContext'; +import { Input } from '../Input/Input'; + import { getStyles } from './styles'; import { SliderProps } from './types'; -import { Input } from '../Input/Input'; /** * @public diff --git a/packages/grafana-ui/src/components/Slider/styles.ts b/packages/grafana-ui/src/components/Slider/styles.ts index d3fb8df7b57..3e37f1a3a54 100644 --- a/packages/grafana-ui/src/components/Slider/styles.ts +++ b/packages/grafana-ui/src/components/Slider/styles.ts @@ -1,7 +1,9 @@ -import { stylesFactory } from '../../themes'; -import { GrafanaTheme2 } from '@grafana/data'; -import { css as cssCore } from '@emotion/react'; import { css } from '@emotion/css'; +import { css as cssCore } from '@emotion/react'; + +import { GrafanaTheme2 } from '@grafana/data'; + +import { stylesFactory } from '../../themes'; export const getStyles = stylesFactory((theme: GrafanaTheme2, isHorizontal: boolean, hasMarks = false) => { const { spacing } = theme; diff --git a/packages/grafana-ui/src/components/Slider/types.ts b/packages/grafana-ui/src/components/Slider/types.ts index aed05a6dd03..2551ac84937 100644 --- a/packages/grafana-ui/src/components/Slider/types.ts +++ b/packages/grafana-ui/src/components/Slider/types.ts @@ -1,4 +1,5 @@ import { SliderMarks } from '@grafana/data'; + import { Orientation } from '../../types/orientation'; interface CommonSliderProps { diff --git a/packages/grafana-ui/src/components/Sparkline/Sparkline.tsx b/packages/grafana-ui/src/components/Sparkline/Sparkline.tsx index c956b401e0e..270b103aa9f 100755 --- a/packages/grafana-ui/src/components/Sparkline/Sparkline.tsx +++ b/packages/grafana-ui/src/components/Sparkline/Sparkline.tsx @@ -1,5 +1,7 @@ +import { isEqual } from 'lodash'; import React, { PureComponent } from 'react'; import { AlignedData, Range } from 'uplot'; + import { compareDataFrameStructures, DataFrame, @@ -17,12 +19,13 @@ import { ScaleDirection, ScaleOrientation, } from '@grafana/schema'; -import { UPlotConfigBuilder } from '../uPlot/config/UPlotConfigBuilder'; -import { UPlotChart } from '../uPlot/Plot'; + import { Themeable2 } from '../../types'; +import { UPlotChart } from '../uPlot/Plot'; +import { UPlotConfigBuilder } from '../uPlot/config/UPlotConfigBuilder'; import { preparePlotData2, getStackingGroups } from '../uPlot/utils'; + import { preparePlotFrame } from './utils'; -import { isEqual } from 'lodash'; export interface SparklineProps extends Themeable2 { width: number; diff --git a/packages/grafana-ui/src/components/Sparkline/utils.ts b/packages/grafana-ui/src/components/Sparkline/utils.ts index 9f57db07152..0d8952f9daa 100644 --- a/packages/grafana-ui/src/components/Sparkline/utils.ts +++ b/packages/grafana-ui/src/components/Sparkline/utils.ts @@ -1,5 +1,6 @@ import { DataFrame, FieldConfig, FieldSparkline, IndexVector } from '@grafana/data'; import { GraphFieldConfig } from '@grafana/schema'; + import { applyNullInsertThreshold } from '../GraphNG/nullInsertThreshold'; /** @internal diff --git a/packages/grafana-ui/src/components/Spinner/Spinner.story.tsx b/packages/grafana-ui/src/components/Spinner/Spinner.story.tsx index efa629230a6..26fab9a2b4a 100644 --- a/packages/grafana-ui/src/components/Spinner/Spinner.story.tsx +++ b/packages/grafana-ui/src/components/Spinner/Spinner.story.tsx @@ -1,7 +1,10 @@ -import React from 'react'; import { Meta, Story } from '@storybook/react'; -import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; +import React from 'react'; + import { Spinner } from '@grafana/ui'; + +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; + import { Props } from './Spinner'; import mdx from './Spinner.mdx'; diff --git a/packages/grafana-ui/src/components/Spinner/Spinner.tsx b/packages/grafana-ui/src/components/Spinner/Spinner.tsx index a77f80a9e5b..ad25d9fbc65 100644 --- a/packages/grafana-ui/src/components/Spinner/Spinner.tsx +++ b/packages/grafana-ui/src/components/Spinner/Spinner.tsx @@ -1,5 +1,6 @@ -import React, { FC } from 'react'; import { cx, css } from '@emotion/css'; +import React, { FC } from 'react'; + import { stylesFactory } from '../../themes'; import { Icon } from '../Icon/Icon'; diff --git a/packages/grafana-ui/src/components/StatsPicker/StatsPicker.story.tsx b/packages/grafana-ui/src/components/StatsPicker/StatsPicker.story.tsx index 1ae6bb255eb..906dec9004f 100644 --- a/packages/grafana-ui/src/components/StatsPicker/StatsPicker.story.tsx +++ b/packages/grafana-ui/src/components/StatsPicker/StatsPicker.story.tsx @@ -1,9 +1,11 @@ +import { action } from '@storybook/addon-actions'; +import { Meta, Story } from '@storybook/react'; import React, { PureComponent } from 'react'; -import { action } from '@storybook/addon-actions'; -import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; import { StatsPicker } from '@grafana/ui'; -import { Meta, Story } from '@storybook/react'; + +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; + import { Props } from './StatsPicker'; interface State { diff --git a/packages/grafana-ui/src/components/StatsPicker/StatsPicker.tsx b/packages/grafana-ui/src/components/StatsPicker/StatsPicker.tsx index 6742fa7c573..8fedd043c67 100644 --- a/packages/grafana-ui/src/components/StatsPicker/StatsPicker.tsx +++ b/packages/grafana-ui/src/components/StatsPicker/StatsPicker.tsx @@ -1,11 +1,10 @@ +import { difference } from 'lodash'; import React, { PureComponent } from 'react'; -import { difference } from 'lodash'; +import { fieldReducers, SelectableValue } from '@grafana/data'; import { Select } from '../Select/Select'; -import { fieldReducers, SelectableValue } from '@grafana/data'; - export interface Props { placeholder?: string; onChange: (stats: string[]) => void; diff --git a/packages/grafana-ui/src/components/Switch/Switch.story.tsx b/packages/grafana-ui/src/components/Switch/Switch.story.tsx index 1210266f1ce..638c51d834c 100644 --- a/packages/grafana-ui/src/components/Switch/Switch.story.tsx +++ b/packages/grafana-ui/src/components/Switch/Switch.story.tsx @@ -1,10 +1,13 @@ -import React, { useState, useCallback } from 'react'; import { Meta, Story } from '@storybook/react'; -import { withCenteredStory, withHorizontallyCenteredStory } from '../../utils/storybook/withCenteredStory'; +import React, { useState, useCallback } from 'react'; + import { InlineField, Switch, InlineSwitch } from '@grafana/ui'; -import mdx from './Switch.mdx'; -import { InlineFieldRow } from '../Forms/InlineFieldRow'; + +import { withCenteredStory, withHorizontallyCenteredStory } from '../../utils/storybook/withCenteredStory'; import { Field } from '../Forms/Field'; +import { InlineFieldRow } from '../Forms/InlineFieldRow'; + +import mdx from './Switch.mdx'; export default { title: 'Forms/Switch', diff --git a/packages/grafana-ui/src/components/Switch/Switch.tsx b/packages/grafana-ui/src/components/Switch/Switch.tsx index c80c8fae90c..d1d22d44d26 100644 --- a/packages/grafana-ui/src/components/Switch/Switch.tsx +++ b/packages/grafana-ui/src/components/Switch/Switch.tsx @@ -1,7 +1,9 @@ -import React, { HTMLProps, useRef } from 'react'; import { css, cx } from '@emotion/css'; import { uniqueId } from 'lodash'; +import React, { HTMLProps, useRef } from 'react'; + import { GrafanaTheme2, deprecationWarning } from '@grafana/data'; + import { stylesFactory, useTheme2 } from '../../themes'; import { getFocusStyles, getMouseFocusStyles } from '../../themes/mixins'; diff --git a/packages/grafana-ui/src/components/TabbedContainer/TabbedContainer.tsx b/packages/grafana-ui/src/components/TabbedContainer/TabbedContainer.tsx index 233afeffd38..0baad2778c7 100644 --- a/packages/grafana-ui/src/components/TabbedContainer/TabbedContainer.tsx +++ b/packages/grafana-ui/src/components/TabbedContainer/TabbedContainer.tsx @@ -1,9 +1,10 @@ -import React, { useState } from 'react'; import { css } from '@emotion/css'; +import React, { useState } from 'react'; import { SelectableValue, GrafanaTheme2 } from '@grafana/data'; -import { stylesFactory, useTheme2 } from '../../themes'; + import { IconName, TabsBar, Tab, IconButton, CustomScrollbar, TabContent } from '../..'; +import { stylesFactory, useTheme2 } from '../../themes'; export interface TabConfig { label: string; diff --git a/packages/grafana-ui/src/components/Table/BarGaugeCell.tsx b/packages/grafana-ui/src/components/Table/BarGaugeCell.tsx index 1d68b923893..cf63bc98f01 100644 --- a/packages/grafana-ui/src/components/Table/BarGaugeCell.tsx +++ b/packages/grafana-ui/src/components/Table/BarGaugeCell.tsx @@ -1,9 +1,12 @@ -import React, { FC } from 'react'; -import { ThresholdsConfig, ThresholdsMode, VizOrientation, getFieldConfigWithMinMax, LinkModel } from '@grafana/data'; -import { BarGauge, BarGaugeDisplayMode } from '../BarGauge/BarGauge'; -import { TableCellProps, TableCellDisplayMode } from './types'; -import { DataLinksContextMenu, DataLinksContextMenuApi } from '../DataLinks/DataLinksContextMenu'; import { isFunction } from 'lodash'; +import React, { FC } from 'react'; + +import { ThresholdsConfig, ThresholdsMode, VizOrientation, getFieldConfigWithMinMax, LinkModel } from '@grafana/data'; + +import { BarGauge, BarGaugeDisplayMode } from '../BarGauge/BarGauge'; +import { DataLinksContextMenu, DataLinksContextMenuApi } from '../DataLinks/DataLinksContextMenu'; + +import { TableCellProps, TableCellDisplayMode } from './types'; const defaultScale: ThresholdsConfig = { mode: ThresholdsMode.Absolute, diff --git a/packages/grafana-ui/src/components/Table/CellActions.tsx b/packages/grafana-ui/src/components/Table/CellActions.tsx index bf140fca42d..d0b368bdf55 100644 --- a/packages/grafana-ui/src/components/Table/CellActions.tsx +++ b/packages/grafana-ui/src/components/Table/CellActions.tsx @@ -1,8 +1,10 @@ import React, { useCallback, useState } from 'react'; + import { IconSize } from '../../types/icon'; import { IconButton } from '../IconButton/IconButton'; import { HorizontalGroup } from '../Layout/Layout'; import { TooltipPlacement } from '../Tooltip'; + import { TableCellInspectModal } from './TableCellInspectModal'; import { FILTER_FOR_OPERATOR, FILTER_OUT_OPERATOR, TableCellProps, TableFieldOptions } from './types'; import { getTextAlign } from './utils'; diff --git a/packages/grafana-ui/src/components/Table/DefaultCell.tsx b/packages/grafana-ui/src/components/Table/DefaultCell.tsx index 476cd60b492..9730270d562 100644 --- a/packages/grafana-ui/src/components/Table/DefaultCell.tsx +++ b/packages/grafana-ui/src/components/Table/DefaultCell.tsx @@ -1,11 +1,13 @@ import React, { FC, ReactElement } from 'react'; +import tinycolor from 'tinycolor2'; + import { DisplayValue, Field, formattedValueToString } from '@grafana/data'; -import { TableCellDisplayMode, TableCellProps, TableFieldOptions } from './types'; -import tinycolor from 'tinycolor2'; -import { TableStyles } from './styles'; import { getTextColorForBackground, getCellLinks } from '../../utils'; + import { CellActions } from './CellActions'; +import { TableStyles } from './styles'; +import { TableCellDisplayMode, TableCellProps, TableFieldOptions } from './types'; export const DefaultCell: FC = (props) => { const { field, cell, tableStyles, row, cellProps } = props; diff --git a/packages/grafana-ui/src/components/Table/Filter.tsx b/packages/grafana-ui/src/components/Table/Filter.tsx index be30f07871a..824bcdfc3b2 100644 --- a/packages/grafana-ui/src/components/Table/Filter.tsx +++ b/packages/grafana-ui/src/components/Table/Filter.tsx @@ -1,12 +1,14 @@ -import React, { FC, useCallback, useMemo, useRef, useState } from 'react'; import { css, cx } from '@emotion/css'; +import React, { FC, useCallback, useMemo, useRef, useState } from 'react'; + import { Field, GrafanaTheme } from '@grafana/data'; -import { TableStyles } from './styles'; +import { Popover } from '..'; import { stylesFactory, useStyles } from '../../themes'; import { Icon } from '../Icon/Icon'; + import { FilterPopup } from './FilterPopup'; -import { Popover } from '..'; +import { TableStyles } from './styles'; interface Props { column: any; diff --git a/packages/grafana-ui/src/components/Table/FilterList.tsx b/packages/grafana-ui/src/components/Table/FilterList.tsx index d14bd9c36d4..0d914f8f134 100644 --- a/packages/grafana-ui/src/components/Table/FilterList.tsx +++ b/packages/grafana-ui/src/components/Table/FilterList.tsx @@ -1,10 +1,11 @@ +import { css } from '@emotion/css'; import React, { FC, useCallback, useMemo, useState } from 'react'; import { FixedSizeList as List } from 'react-window'; -import { css } from '@emotion/css'; + import { GrafanaTheme2, SelectableValue } from '@grafana/data'; -import { stylesFactory, useTheme2 } from '../../themes'; import { Checkbox, FilterInput, Label, VerticalGroup } from '..'; +import { stylesFactory, useTheme2 } from '../../themes'; interface Props { values: SelectableValue[]; diff --git a/packages/grafana-ui/src/components/Table/FilterPopup.tsx b/packages/grafana-ui/src/components/Table/FilterPopup.tsx index c5cebb9a1f7..4045839e718 100644 --- a/packages/grafana-ui/src/components/Table/FilterPopup.tsx +++ b/packages/grafana-ui/src/components/Table/FilterPopup.tsx @@ -1,11 +1,13 @@ -import React, { FC, useCallback, useMemo, useState } from 'react'; -import { Field, GrafanaTheme, SelectableValue } from '@grafana/data'; import { css, cx } from '@emotion/css'; +import React, { FC, useCallback, useMemo, useState } from 'react'; + +import { Field, GrafanaTheme, SelectableValue } from '@grafana/data'; -import { TableStyles } from './styles'; -import { stylesFactory, useStyles, useTheme2 } from '../../themes'; import { Button, ClickOutsideWrapper, HorizontalGroup, IconButton, Label, VerticalGroup } from '..'; +import { stylesFactory, useStyles, useTheme2 } from '../../themes'; + import { FilterList } from './FilterList'; +import { TableStyles } from './styles'; import { calculateUniqueFieldValues, getFilteredOptions, valuesToOptions } from './utils'; interface Props { diff --git a/packages/grafana-ui/src/components/Table/FooterCell.tsx b/packages/grafana-ui/src/components/Table/FooterCell.tsx index 98a950d637d..cadfb05ed31 100644 --- a/packages/grafana-ui/src/components/Table/FooterCell.tsx +++ b/packages/grafana-ui/src/components/Table/FooterCell.tsx @@ -1,7 +1,9 @@ -import React from 'react'; -import { FooterItem } from './types'; -import { KeyValue } from '@grafana/data'; import { css } from '@emotion/css'; +import React from 'react'; + +import { KeyValue } from '@grafana/data'; + +import { FooterItem } from './types'; export interface FooterProps { value: FooterItem; diff --git a/packages/grafana-ui/src/components/Table/FooterRow.tsx b/packages/grafana-ui/src/components/Table/FooterRow.tsx index c032c3d3597..f92a393a811 100644 --- a/packages/grafana-ui/src/components/Table/FooterRow.tsx +++ b/packages/grafana-ui/src/components/Table/FooterRow.tsx @@ -1,10 +1,13 @@ import React from 'react'; import { ColumnInstance, HeaderGroup } from 'react-table'; + import { selectors } from '@grafana/e2e-selectors'; -import { getTableStyles, TableStyles } from './styles'; + import { useStyles2 } from '../../themes'; -import { FooterItem } from './types'; + import { EmptyCell, FooterCell } from './FooterCell'; +import { getTableStyles, TableStyles } from './styles'; +import { FooterItem } from './types'; export interface FooterRowProps { totalColumnsWidth: number; diff --git a/packages/grafana-ui/src/components/Table/GeoCell.tsx b/packages/grafana-ui/src/components/Table/GeoCell.tsx index be42a323deb..1ac13627427 100644 --- a/packages/grafana-ui/src/components/Table/GeoCell.tsx +++ b/packages/grafana-ui/src/components/Table/GeoCell.tsx @@ -1,7 +1,8 @@ -import React from 'react'; -import { TableCellProps } from './types'; -import { Geometry } from 'ol/geom'; import WKT from 'ol/format/WKT'; +import { Geometry } from 'ol/geom'; +import React from 'react'; + +import { TableCellProps } from './types'; export function GeoCell(props: TableCellProps): JSX.Element { const { cell, tableStyles, cellProps } = props; diff --git a/packages/grafana-ui/src/components/Table/HeaderRow.tsx b/packages/grafana-ui/src/components/Table/HeaderRow.tsx index a935b961249..2c59d649eaf 100644 --- a/packages/grafana-ui/src/components/Table/HeaderRow.tsx +++ b/packages/grafana-ui/src/components/Table/HeaderRow.tsx @@ -1,12 +1,15 @@ import React from 'react'; import { HeaderGroup, Column } from 'react-table'; + import { DataFrame, Field } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; -import { getTableStyles, TableStyles } from './styles'; + import { useStyles2 } from '../../themes'; -import { Filter } from './Filter'; -import { Icon } from '../Icon/Icon'; import { getFieldTypeIcon } from '../../types'; +import { Icon } from '../Icon/Icon'; + +import { Filter } from './Filter'; +import { getTableStyles, TableStyles } from './styles'; export interface HeaderRowProps { headerGroups: HeaderGroup[]; diff --git a/packages/grafana-ui/src/components/Table/ImageCell.tsx b/packages/grafana-ui/src/components/Table/ImageCell.tsx index 1a11d3eede7..e9d9d42b981 100644 --- a/packages/grafana-ui/src/components/Table/ImageCell.tsx +++ b/packages/grafana-ui/src/components/Table/ImageCell.tsx @@ -1,5 +1,7 @@ import React, { FC } from 'react'; + import { getCellLinks } from '../../utils'; + import { TableCellProps } from './types'; export const ImageCell: FC = (props) => { diff --git a/packages/grafana-ui/src/components/Table/JSONViewCell.tsx b/packages/grafana-ui/src/components/Table/JSONViewCell.tsx index 6efeb2feb10..6f2c62a8c9a 100644 --- a/packages/grafana-ui/src/components/Table/JSONViewCell.tsx +++ b/packages/grafana-ui/src/components/Table/JSONViewCell.tsx @@ -1,10 +1,12 @@ -import React from 'react'; import { css, cx } from '@emotion/css'; import { isString } from 'lodash'; -import { TableCellProps, TableFieldOptions } from './types'; -import { CellActions } from './CellActions'; +import React from 'react'; + import { getCellLinks } from '../../utils'; +import { CellActions } from './CellActions'; +import { TableCellProps, TableFieldOptions } from './types'; + export function JSONViewCell(props: TableCellProps): JSX.Element { const { cell, tableStyles, cellProps, field, row } = props; const inspectEnabled = Boolean((field.config.custom as TableFieldOptions)?.inspect); diff --git a/packages/grafana-ui/src/components/Table/Table.story.tsx b/packages/grafana-ui/src/components/Table/Table.story.tsx index 385206a6e57..194cb581618 100644 --- a/packages/grafana-ui/src/components/Table/Table.story.tsx +++ b/packages/grafana-ui/src/components/Table/Table.story.tsx @@ -1,10 +1,7 @@ -import React from 'react'; -import { merge } from 'lodash'; -import { Table } from '@grafana/ui'; -import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; import { Meta, Story } from '@storybook/react'; -import { useTheme2 } from '../../themes'; -import mdx from './Table.mdx'; +import { merge } from 'lodash'; +import React from 'react'; + import { DataFrame, FieldType, @@ -15,7 +12,13 @@ import { FieldConfig, formattedValueToString, } from '@grafana/data'; +import { Table } from '@grafana/ui'; + +import { useTheme2 } from '../../themes'; import { prepDataForStorybook } from '../../utils/storybook/data'; +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; + +import mdx from './Table.mdx'; import { FooterItem } from './types'; export default { diff --git a/packages/grafana-ui/src/components/Table/Table.test.tsx b/packages/grafana-ui/src/components/Table/Table.test.tsx index 91d8bab44e9..1eb1e91be58 100644 --- a/packages/grafana-ui/src/components/Table/Table.test.tsx +++ b/packages/grafana-ui/src/components/Table/Table.test.tsx @@ -1,7 +1,9 @@ -import React from 'react'; import { render, screen, within } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import React from 'react'; + import { applyFieldOverrides, createTheme, DataFrame, FieldType, toDataFrame } from '@grafana/data'; + import { Props, Table } from './Table'; function getDefaultDataFrame(): DataFrame { diff --git a/packages/grafana-ui/src/components/Table/Table.tsx b/packages/grafana-ui/src/components/Table/Table.tsx index 1097fad630f..7e407d12e04 100644 --- a/packages/grafana-ui/src/components/Table/Table.tsx +++ b/packages/grafana-ui/src/components/Table/Table.tsx @@ -1,5 +1,4 @@ import React, { FC, memo, useCallback, useEffect, useMemo } from 'react'; -import { DataFrame, getFieldDisplayName } from '@grafana/data'; import { Cell, Column, @@ -12,7 +11,17 @@ import { useTable, } from 'react-table'; import { FixedSizeList } from 'react-window'; -import { getColumns, sortCaseInsensitive, sortNumber } from './utils'; + +import { DataFrame, getFieldDisplayName } from '@grafana/data'; + +import { useStyles2 } from '../../themes'; +import { CustomScrollbar } from '../CustomScrollbar/CustomScrollbar'; +import { Pagination } from '../Pagination/Pagination'; + +import { FooterRow } from './FooterRow'; +import { HeaderRow } from './HeaderRow'; +import { TableCell } from './TableCell'; +import { getTableStyles } from './styles'; import { TableColumnResizeActionCallback, TableFilterActionCallback, @@ -20,13 +29,7 @@ import { TableSortByActionCallback, TableSortByFieldState, } from './types'; -import { getTableStyles } from './styles'; -import { CustomScrollbar } from '../CustomScrollbar/CustomScrollbar'; -import { TableCell } from './TableCell'; -import { useStyles2 } from '../../themes'; -import { FooterRow } from './FooterRow'; -import { HeaderRow } from './HeaderRow'; -import { Pagination } from '../Pagination/Pagination'; +import { getColumns, sortCaseInsensitive, sortNumber } from './utils'; const COLUMN_MIN_WIDTH = 150; diff --git a/packages/grafana-ui/src/components/Table/TableCell.tsx b/packages/grafana-ui/src/components/Table/TableCell.tsx index f8a075f8eb3..09b6f4bb6d5 100644 --- a/packages/grafana-ui/src/components/Table/TableCell.tsx +++ b/packages/grafana-ui/src/components/Table/TableCell.tsx @@ -1,7 +1,8 @@ import React, { FC } from 'react'; import { Cell } from 'react-table'; -import { GrafanaTableColumn, TableFilterActionCallback } from './types'; + import { TableStyles } from './styles'; +import { GrafanaTableColumn, TableFilterActionCallback } from './types'; export interface Props { cell: Cell; diff --git a/packages/grafana-ui/src/components/Table/TableCellInspectModal.tsx b/packages/grafana-ui/src/components/Table/TableCellInspectModal.tsx index a5d204fe058..2feb934a8c0 100644 --- a/packages/grafana-ui/src/components/Table/TableCellInspectModal.tsx +++ b/packages/grafana-ui/src/components/Table/TableCellInspectModal.tsx @@ -1,5 +1,6 @@ import { isString } from 'lodash'; import React, { useEffect, useState } from 'react'; + import { ClipboardButton } from '../ClipboardButton/ClipboardButton'; import { Icon } from '../Icon/Icon'; import { Modal } from '../Modal/Modal'; diff --git a/packages/grafana-ui/src/components/Table/styles.ts b/packages/grafana-ui/src/components/Table/styles.ts index 3682b5da17e..7bb9d5b5b21 100644 --- a/packages/grafana-ui/src/components/Table/styles.ts +++ b/packages/grafana-ui/src/components/Table/styles.ts @@ -1,5 +1,7 @@ import { css, CSSObject } from '@emotion/css'; + import { GrafanaTheme2 } from '@grafana/data'; + import { getScrollbarWidth } from '../../utils'; export const getTableStyles = (theme: GrafanaTheme2) => { diff --git a/packages/grafana-ui/src/components/Table/types.ts b/packages/grafana-ui/src/components/Table/types.ts index aa7480bb35e..82441536f51 100644 --- a/packages/grafana-ui/src/components/Table/types.ts +++ b/packages/grafana-ui/src/components/Table/types.ts @@ -1,8 +1,10 @@ -import { CellProps, Column, Row } from 'react-table'; -import { Field, KeyValue, SelectableValue } from '@grafana/data'; -import { TableStyles } from './styles'; -import { FC } from 'react'; import { Property } from 'csstype'; +import { FC } from 'react'; +import { CellProps, Column, Row } from 'react-table'; + +import { Field, KeyValue, SelectableValue } from '@grafana/data'; + +import { TableStyles } from './styles'; export { TableFieldOptions, TableCellDisplayMode, FieldTextAlignment } from '@grafana/schema'; diff --git a/packages/grafana-ui/src/components/Table/utils.test.ts b/packages/grafana-ui/src/components/Table/utils.test.ts index bb2ff5b70d9..1dad733f3ca 100644 --- a/packages/grafana-ui/src/components/Table/utils.test.ts +++ b/packages/grafana-ui/src/components/Table/utils.test.ts @@ -1,4 +1,5 @@ import { ArrayVector, Field, FieldType, MutableDataFrame, SelectableValue } from '@grafana/data'; + import { calculateUniqueFieldValues, filterByValue, diff --git a/packages/grafana-ui/src/components/Table/utils.ts b/packages/grafana-ui/src/components/Table/utils.ts index 6691efef841..5b6e13c740f 100644 --- a/packages/grafana-ui/src/components/Table/utils.ts +++ b/packages/grafana-ui/src/components/Table/utils.ts @@ -1,6 +1,7 @@ -import { Row } from 'react-table'; -import memoizeOne from 'memoize-one'; import { Property } from 'csstype'; +import memoizeOne from 'memoize-one'; +import { Row } from 'react-table'; + import { DataFrame, Field, @@ -10,13 +11,13 @@ import { SelectableValue, } from '@grafana/data'; -import { DefaultCell } from './DefaultCell'; import { BarGaugeCell } from './BarGaugeCell'; -import { CellComponent, TableCellDisplayMode, TableFieldOptions, FooterItem, GrafanaTableColumn } from './types'; -import { JSONViewCell } from './JSONViewCell'; +import { DefaultCell } from './DefaultCell'; +import { getFooterValue } from './FooterRow'; import { GeoCell } from './GeoCell'; import { ImageCell } from './ImageCell'; -import { getFooterValue } from './FooterRow'; +import { JSONViewCell } from './JSONViewCell'; +import { CellComponent, TableCellDisplayMode, TableFieldOptions, FooterItem, GrafanaTableColumn } from './types'; export function getTextAlign(field?: Field): Property.JustifyContent { if (!field) { diff --git a/packages/grafana-ui/src/components/TableInputCSV/TableInputCSV.story.internal.tsx b/packages/grafana-ui/src/components/TableInputCSV/TableInputCSV.story.internal.tsx index b3ad26c955a..f7aa4f7cb34 100644 --- a/packages/grafana-ui/src/components/TableInputCSV/TableInputCSV.story.internal.tsx +++ b/packages/grafana-ui/src/components/TableInputCSV/TableInputCSV.story.internal.tsx @@ -1,11 +1,13 @@ +import { action } from '@storybook/addon-actions'; +import { Meta } from '@storybook/react'; import React from 'react'; -import { TableInputCSV } from './TableInputCSV'; -import { Meta } from '@storybook/react'; -import { action } from '@storybook/addon-actions'; import { DataFrame } from '@grafana/data'; + import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; +import { TableInputCSV } from './TableInputCSV'; + export default { title: 'Forms/TableInputCSV', component: TableInputCSV, diff --git a/packages/grafana-ui/src/components/TableInputCSV/TableInputCSV.test.tsx b/packages/grafana-ui/src/components/TableInputCSV/TableInputCSV.test.tsx index e2953fc1c43..246352eff1b 100644 --- a/packages/grafana-ui/src/components/TableInputCSV/TableInputCSV.test.tsx +++ b/packages/grafana-ui/src/components/TableInputCSV/TableInputCSV.test.tsx @@ -1,9 +1,10 @@ import React from 'react'; - import renderer from 'react-test-renderer'; -import { TableInputCSV } from './TableInputCSV'; + import { DataFrame } from '@grafana/data'; +import { TableInputCSV } from './TableInputCSV'; + describe('TableInputCSV', () => { it('renders correctly', () => { const tree = renderer diff --git a/packages/grafana-ui/src/components/TableInputCSV/TableInputCSV.tsx b/packages/grafana-ui/src/components/TableInputCSV/TableInputCSV.tsx index 0a9deb6bc63..70665de1fd7 100644 --- a/packages/grafana-ui/src/components/TableInputCSV/TableInputCSV.tsx +++ b/packages/grafana-ui/src/components/TableInputCSV/TableInputCSV.tsx @@ -1,11 +1,13 @@ -import React from 'react'; -import { debounce } from 'lodash'; import { css } from '@emotion/css'; +import { debounce } from 'lodash'; +import React from 'react'; + import { GrafanaTheme, DataFrame, CSVConfig, readCSV } from '@grafana/data'; -import { Icon } from '../Icon/Icon'; -import { Themeable } from '../../types/theme'; -import { TextArea } from '../TextArea/TextArea'; + import { stylesFactory, withTheme } from '../../themes'; +import { Themeable } from '../../types/theme'; +import { Icon } from '../Icon/Icon'; +import { TextArea } from '../TextArea/TextArea'; interface Props extends Themeable { config?: CSVConfig; diff --git a/packages/grafana-ui/src/components/Tabs/Counter.tsx b/packages/grafana-ui/src/components/Tabs/Counter.tsx index e90e621787b..7bb63b2ecd9 100644 --- a/packages/grafana-ui/src/components/Tabs/Counter.tsx +++ b/packages/grafana-ui/src/components/Tabs/Counter.tsx @@ -1,8 +1,10 @@ -import React, { FC } from 'react'; import { css } from '@emotion/css'; -import { stylesFactory, useStyles2 } from '../../themes'; +import React, { FC } from 'react'; + import { GrafanaTheme2, locale } from '@grafana/data'; +import { stylesFactory, useStyles2 } from '../../themes'; + const getStyles = stylesFactory((theme: GrafanaTheme2) => { return { counter: css` diff --git a/packages/grafana-ui/src/components/Tabs/Tab.tsx b/packages/grafana-ui/src/components/Tabs/Tab.tsx index d45f33cc436..ffa743b861c 100644 --- a/packages/grafana-ui/src/components/Tabs/Tab.tsx +++ b/packages/grafana-ui/src/components/Tabs/Tab.tsx @@ -1,13 +1,15 @@ -import React, { HTMLProps } from 'react'; import { css, cx } from '@emotion/css'; +import React, { HTMLProps } from 'react'; + import { GrafanaTheme2, NavModelItem } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; -import { Icon } from '../Icon/Icon'; -import { IconName } from '../../types'; import { stylesFactory, useTheme2 } from '../../themes'; -import { Counter } from './Counter'; import { getFocusStyles } from '../../themes/mixins'; +import { IconName } from '../../types'; +import { Icon } from '../Icon/Icon'; + +import { Counter } from './Counter'; export interface TabProps extends HTMLProps { label: string; diff --git a/packages/grafana-ui/src/components/Tabs/TabContent.tsx b/packages/grafana-ui/src/components/Tabs/TabContent.tsx index 6168f0f6767..eb50ed3a974 100644 --- a/packages/grafana-ui/src/components/Tabs/TabContent.tsx +++ b/packages/grafana-ui/src/components/Tabs/TabContent.tsx @@ -1,8 +1,10 @@ -import React, { FC, HTMLAttributes, ReactNode } from 'react'; -import { stylesFactory, useTheme2 } from '../../themes'; import { css, cx } from '@emotion/css'; +import React, { FC, HTMLAttributes, ReactNode } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; +import { stylesFactory, useTheme2 } from '../../themes'; + interface Props extends HTMLAttributes { children: ReactNode; } diff --git a/packages/grafana-ui/src/components/Tabs/Tabs.story.tsx b/packages/grafana-ui/src/components/Tabs/Tabs.story.tsx index bedfe9cdea8..43adec962f4 100644 --- a/packages/grafana-ui/src/components/Tabs/Tabs.story.tsx +++ b/packages/grafana-ui/src/components/Tabs/Tabs.story.tsx @@ -1,10 +1,13 @@ -import React, { useState } from 'react'; import { Story } from '@storybook/react'; -import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; +import React, { useState } from 'react'; + import { TabsBar, Tab, TabContent, Counter as TabCounter } from '@grafana/ui'; -import mdx from './TabsBar.mdx'; -import { CounterProps } from './Counter'; + import { DashboardStoryCanvas } from '../../utils/storybook/DashboardStoryCanvas'; +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; + +import { CounterProps } from './Counter'; +import mdx from './TabsBar.mdx'; export default { title: 'Layout/Tabs', diff --git a/packages/grafana-ui/src/components/Tabs/TabsBar.tsx b/packages/grafana-ui/src/components/Tabs/TabsBar.tsx index 13fccb9223f..73acd2a67bc 100644 --- a/packages/grafana-ui/src/components/Tabs/TabsBar.tsx +++ b/packages/grafana-ui/src/components/Tabs/TabsBar.tsx @@ -1,7 +1,9 @@ -import React, { ReactNode } from 'react'; -import { stylesFactory, useTheme2 } from '../../themes'; -import { GrafanaTheme2 } from '@grafana/data'; import { css, cx } from '@emotion/css'; +import React, { ReactNode } from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; + +import { stylesFactory, useTheme2 } from '../../themes'; export interface Props { /** Children should be a single or an array of */ diff --git a/packages/grafana-ui/src/components/Tags/Tag.story.tsx b/packages/grafana-ui/src/components/Tags/Tag.story.tsx index 8c67194cd82..07222066547 100644 --- a/packages/grafana-ui/src/components/Tags/Tag.story.tsx +++ b/packages/grafana-ui/src/components/Tags/Tag.story.tsx @@ -1,7 +1,10 @@ -import React from 'react'; import { action } from '@storybook/addon-actions'; +import React from 'react'; + import { Tag } from '@grafana/ui'; + import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; + import mdx from './Tag.mdx'; export default { diff --git a/packages/grafana-ui/src/components/Tags/Tag.tsx b/packages/grafana-ui/src/components/Tags/Tag.tsx index 01fc15e68cc..eee65fa0cd8 100644 --- a/packages/grafana-ui/src/components/Tags/Tag.tsx +++ b/packages/grafana-ui/src/components/Tags/Tag.tsx @@ -1,9 +1,11 @@ -import React, { forwardRef, HTMLAttributes } from 'react'; import { cx, css } from '@emotion/css'; +import React, { forwardRef, HTMLAttributes } from 'react'; + import { GrafanaTheme } from '@grafana/data'; + import { useTheme } from '../../themes'; -import { getTagColor, getTagColorsFromName } from '../../utils'; import { IconName } from '../../types/icon'; +import { getTagColor, getTagColorsFromName } from '../../utils'; import { Icon } from '../Icon/Icon'; /** diff --git a/packages/grafana-ui/src/components/Tags/TagList.story.tsx b/packages/grafana-ui/src/components/Tags/TagList.story.tsx index 0f42221e34f..f4281880aef 100644 --- a/packages/grafana-ui/src/components/Tags/TagList.story.tsx +++ b/packages/grafana-ui/src/components/Tags/TagList.story.tsx @@ -1,7 +1,9 @@ -import React from 'react'; import { action } from '@storybook/addon-actions'; -import { TagList } from './TagList'; +import React from 'react'; + import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; + +import { TagList } from './TagList'; import mdx from './TagList.mdx'; export default { diff --git a/packages/grafana-ui/src/components/Tags/TagList.tsx b/packages/grafana-ui/src/components/Tags/TagList.tsx index 25e6825f1f6..d22be614c5a 100644 --- a/packages/grafana-ui/src/components/Tags/TagList.tsx +++ b/packages/grafana-ui/src/components/Tags/TagList.tsx @@ -1,10 +1,13 @@ -import React, { forwardRef, memo } from 'react'; import { css, cx } from '@emotion/css'; -import { OnTagClick, Tag } from './Tag'; -import { useTheme2 } from '../../themes'; +import React, { forwardRef, memo } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; + +import { useTheme2 } from '../../themes'; import { IconName } from '../../types/icon'; +import { OnTagClick, Tag } from './Tag'; + export interface Props { displayMax?: number; tags: string[]; diff --git a/packages/grafana-ui/src/components/TagsInput/TagItem.tsx b/packages/grafana-ui/src/components/TagsInput/TagItem.tsx index 7af715e5f00..6ef390c1b04 100644 --- a/packages/grafana-ui/src/components/TagsInput/TagItem.tsx +++ b/packages/grafana-ui/src/components/TagsInput/TagItem.tsx @@ -1,8 +1,10 @@ -import React, { FC } from 'react'; import { css } from '@emotion/css'; -import { getTagColorsFromName } from '../../utils'; -import { stylesFactory, useTheme } from '../../themes'; +import React, { FC } from 'react'; + import { GrafanaTheme } from '@grafana/data'; + +import { stylesFactory, useTheme } from '../../themes'; +import { getTagColorsFromName } from '../../utils'; import { IconButton } from '../IconButton/IconButton'; interface Props { diff --git a/packages/grafana-ui/src/components/TagsInput/TagsInput.story.tsx b/packages/grafana-ui/src/components/TagsInput/TagsInput.story.tsx index 74b12e197d6..d7ef294c2e4 100644 --- a/packages/grafana-ui/src/components/TagsInput/TagsInput.story.tsx +++ b/packages/grafana-ui/src/components/TagsInput/TagsInput.story.tsx @@ -1,9 +1,11 @@ -import React, { useState } from 'react'; import { Meta, Story } from '@storybook/react'; -import { TagsInput, Props } from './TagsInput'; -import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; +import React, { useState } from 'react'; + import { StoryExample } from '../../utils/storybook/StoryExample'; +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; import { VerticalGroup } from '../Layout/Layout'; + +import { TagsInput, Props } from './TagsInput'; import mdx from './TagsInput.mdx'; export default { diff --git a/packages/grafana-ui/src/components/TagsInput/TagsInput.test.tsx b/packages/grafana-ui/src/components/TagsInput/TagsInput.test.tsx index 15e8697c1fd..4c0db8c1014 100644 --- a/packages/grafana-ui/src/components/TagsInput/TagsInput.test.tsx +++ b/packages/grafana-ui/src/components/TagsInput/TagsInput.test.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { render, fireEvent, screen } from '@testing-library/react'; +import React from 'react'; + import { TagsInput } from './TagsInput'; describe('TagsInput', () => { diff --git a/packages/grafana-ui/src/components/TagsInput/TagsInput.tsx b/packages/grafana-ui/src/components/TagsInput/TagsInput.tsx index bcd41ca683e..5e1246e09a3 100644 --- a/packages/grafana-ui/src/components/TagsInput/TagsInput.tsx +++ b/packages/grafana-ui/src/components/TagsInput/TagsInput.tsx @@ -1,11 +1,14 @@ -import React, { ChangeEvent, KeyboardEvent, FC, useState } from 'react'; import { css, cx } from '@emotion/css'; -import { Button } from '../Button'; -import { TagItem } from './TagItem'; -import { useStyles, useTheme2 } from '../../themes/ThemeContext'; +import React, { ChangeEvent, KeyboardEvent, FC, useState } from 'react'; + import { GrafanaTheme } from '@grafana/data'; + +import { useStyles, useTheme2 } from '../../themes/ThemeContext'; +import { Button } from '../Button'; import { Input } from '../Input/Input'; +import { TagItem } from './TagItem'; + export interface Props { placeholder?: string; /** Array of selected tags */ diff --git a/packages/grafana-ui/src/components/TextArea/TextArea.story.tsx b/packages/grafana-ui/src/components/TextArea/TextArea.story.tsx index 3508c9116b9..d2d533f3b71 100644 --- a/packages/grafana-ui/src/components/TextArea/TextArea.story.tsx +++ b/packages/grafana-ui/src/components/TextArea/TextArea.story.tsx @@ -1,7 +1,10 @@ -import React from 'react'; -import { TextArea } from '@grafana/ui'; -import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; import { Meta, Story } from '@storybook/react'; +import React from 'react'; + +import { TextArea } from '@grafana/ui'; + +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; + import mdx from './TextArea.mdx'; export default { diff --git a/packages/grafana-ui/src/components/TextArea/TextArea.tsx b/packages/grafana-ui/src/components/TextArea/TextArea.tsx index 679890c3245..aa235615756 100644 --- a/packages/grafana-ui/src/components/TextArea/TextArea.tsx +++ b/packages/grafana-ui/src/components/TextArea/TextArea.tsx @@ -1,6 +1,8 @@ -import React, { HTMLProps } from 'react'; -import { GrafanaTheme2 } from '@grafana/data'; import { css, cx } from '@emotion/css'; +import React, { HTMLProps } from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; + import { stylesFactory, useTheme2 } from '../../themes'; import { getFocusStyle, sharedInputStyle } from '../Forms/commonStyles'; diff --git a/packages/grafana-ui/src/components/ThemeDemos/EmotionPerfTest.tsx b/packages/grafana-ui/src/components/ThemeDemos/EmotionPerfTest.tsx index 13d8b10ccea..4d551791f88 100644 --- a/packages/grafana-ui/src/components/ThemeDemos/EmotionPerfTest.tsx +++ b/packages/grafana-ui/src/components/ThemeDemos/EmotionPerfTest.tsx @@ -1,12 +1,14 @@ /** @jsxImportSource @emotion/react */ -import { Profiler, ProfilerOnRenderCallback, useState, FC } from 'react'; -import { GrafanaTheme2 } from '@grafana/data'; import { css, cx } from '@emotion/css'; +import classnames from 'classnames'; +import { Profiler, ProfilerOnRenderCallback, useState, FC } from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; + import { useStyles2, useTheme2 } from '../../themes'; import { Button } from '../Button'; import { VerticalGroup } from '../Layout/Layout'; -import classnames from 'classnames'; export function EmotionPerfTest() { console.log('process.env.NODE_ENV', process.env.NODE_ENV); diff --git a/packages/grafana-ui/src/components/ThemeDemos/ThemeDemo.story.tsx b/packages/grafana-ui/src/components/ThemeDemos/ThemeDemo.story.tsx index e2d778ba0af..6b9b5a4088b 100644 --- a/packages/grafana-ui/src/components/ThemeDemos/ThemeDemo.story.tsx +++ b/packages/grafana-ui/src/components/ThemeDemos/ThemeDemo.story.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { EmotionPerfTest } from './EmotionPerfTest'; import { ThemeDemo as NewThemeDemoComponent } from './ThemeDemo'; diff --git a/packages/grafana-ui/src/components/ThemeDemos/ThemeDemo.tsx b/packages/grafana-ui/src/components/ThemeDemos/ThemeDemo.tsx index 60ba274bd57..f71acfc76c7 100644 --- a/packages/grafana-ui/src/components/ThemeDemos/ThemeDemo.tsx +++ b/packages/grafana-ui/src/components/ThemeDemos/ThemeDemo.tsx @@ -1,19 +1,21 @@ -import React, { FC, useState } from 'react'; import { css, cx } from '@emotion/css'; -import { useTheme2 } from '../../themes/ThemeContext'; -import { Icon } from '../Icon/Icon'; -import { HorizontalGroup, VerticalGroup } from '../Layout/Layout'; +import React, { FC, useState } from 'react'; + import { GrafanaTheme2, ThemeRichColor } from '@grafana/data'; + +import { useTheme2 } from '../../themes/ThemeContext'; +import { allButtonVariants, Button } from '../Button'; +import { Card } from '../Card/Card'; import { CollapsableSection } from '../Collapse/CollapsableSection'; import { Field } from '../Forms/Field'; -import { Input } from '../Input/Input'; -import { RadioButtonGroup } from '../Forms/RadioButtonGroup/RadioButtonGroup'; -import { Switch } from '../Switch/Switch'; -import { allButtonVariants, Button } from '../Button'; import { InlineField } from '../Forms/InlineField'; import { InlineFieldRow } from '../Forms/InlineFieldRow'; -import { Card } from '../Card/Card'; +import { RadioButtonGroup } from '../Forms/RadioButtonGroup/RadioButtonGroup'; +import { Icon } from '../Icon/Icon'; +import { Input } from '../Input/Input'; +import { HorizontalGroup, VerticalGroup } from '../Layout/Layout'; import { Select } from '../Select/Select'; +import { Switch } from '../Switch/Switch'; interface DemoBoxProps { bg?: string; diff --git a/packages/grafana-ui/src/components/TimeSeries/TimeSeries.tsx b/packages/grafana-ui/src/components/TimeSeries/TimeSeries.tsx index e3d54e93ce5..39ee24a3bbb 100644 --- a/packages/grafana-ui/src/components/TimeSeries/TimeSeries.tsx +++ b/packages/grafana-ui/src/components/TimeSeries/TimeSeries.tsx @@ -1,13 +1,16 @@ import React from 'react'; + import { DataFrame, TimeRange } from '@grafana/data'; -import { GraphNG, GraphNGProps } from '../GraphNG/GraphNG'; -import { UPlotConfigBuilder } from '../uPlot/config/UPlotConfigBuilder'; -import { PlotLegend } from '../uPlot/PlotLegend'; import { LegendDisplayMode } from '@grafana/schema'; -import { preparePlotConfigBuilder } from './utils'; -import { withTheme2 } from '../../themes/ThemeContext'; -import { PanelContext, PanelContextRoot } from '../PanelChrome/PanelContext'; + import { PropDiffFn } from '../../../../../packages/grafana-ui/src/components/GraphNG/GraphNG'; +import { withTheme2 } from '../../themes/ThemeContext'; +import { GraphNG, GraphNGProps } from '../GraphNG/GraphNG'; +import { PanelContext, PanelContextRoot } from '../PanelChrome/PanelContext'; +import { PlotLegend } from '../uPlot/PlotLegend'; +import { UPlotConfigBuilder } from '../uPlot/config/UPlotConfigBuilder'; + +import { preparePlotConfigBuilder } from './utils'; const propsToDiff: Array = ['legend', 'options']; diff --git a/packages/grafana-ui/src/components/TimeSeries/utils.ts b/packages/grafana-ui/src/components/TimeSeries/utils.ts index ed9e084759e..062378b5124 100644 --- a/packages/grafana-ui/src/components/TimeSeries/utils.ts +++ b/packages/grafana-ui/src/components/TimeSeries/utils.ts @@ -1,4 +1,6 @@ import { isNumber } from 'lodash'; +import uPlot from 'uplot'; + import { DashboardCursorSync, DataFrame, @@ -13,8 +15,6 @@ import { getFieldDisplayName, getDisplayProcessor, } from '@grafana/data'; - -import { UPlotConfigBuilder, UPlotConfigPrepFn } from '../uPlot/config/UPlotConfigBuilder'; import { AxisPlacement, GraphDrawStyle, @@ -25,9 +25,10 @@ import { ScaleOrientation, StackingMode, } from '@grafana/schema'; -import { getStackingGroups, preparePlotData2 } from '../uPlot/utils'; -import uPlot from 'uplot'; + import { buildScaleKey } from '../GraphNG/utils'; +import { UPlotConfigBuilder, UPlotConfigPrepFn } from '../uPlot/config/UPlotConfigBuilder'; +import { getStackingGroups, preparePlotData2 } from '../uPlot/utils'; const defaultFormatter = (v: any) => (v == null ? '-' : v.toFixed(1)); diff --git a/packages/grafana-ui/src/components/Tooltip/Popover.tsx b/packages/grafana-ui/src/components/Tooltip/Popover.tsx index b9197a90baa..e0b2939eb87 100644 --- a/packages/grafana-ui/src/components/Tooltip/Popover.tsx +++ b/packages/grafana-ui/src/components/Tooltip/Popover.tsx @@ -1,8 +1,10 @@ -import React, { PureComponent } from 'react'; -import { Placement, VirtualElement } from '@popperjs/core'; +import { Placement, VirtualElement } from '@popperjs/core'; +import React, { PureComponent } from 'react'; import { Manager, Popper as ReactPopper, PopperArrowProps } from 'react-popper'; -import { Portal } from '../Portal/Portal'; import Transition from 'react-transition-group/Transition'; + +import { Portal } from '../Portal/Portal'; + import { PopoverContent } from './types'; const defaultTransitionStyles = { diff --git a/packages/grafana-ui/src/components/Tooltip/PopoverController.tsx b/packages/grafana-ui/src/components/Tooltip/PopoverController.tsx index c68cac0271d..ae5534cb65d 100644 --- a/packages/grafana-ui/src/components/Tooltip/PopoverController.tsx +++ b/packages/grafana-ui/src/components/Tooltip/PopoverController.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { Placement } from '@popperjs/core'; +import React from 'react'; + import { PopoverContent } from './types'; type PopperControllerRenderProp = ( diff --git a/packages/grafana-ui/src/components/Tooltip/Tooltip.story.tsx b/packages/grafana-ui/src/components/Tooltip/Tooltip.story.tsx index a3ab4d1f1f2..ee48d28c088 100644 --- a/packages/grafana-ui/src/components/Tooltip/Tooltip.story.tsx +++ b/packages/grafana-ui/src/components/Tooltip/Tooltip.story.tsx @@ -1,10 +1,12 @@ -import React from 'react'; import { Story } from '@storybook/react'; -import { Tooltip } from './Tooltip'; +import React from 'react'; + import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; import { Button } from '../Button'; import mdx from '../Tooltip/Tooltip.mdx'; +import { Tooltip } from './Tooltip'; + export default { title: 'Overlays/Tooltip', component: Tooltip, diff --git a/packages/grafana-ui/src/components/Tooltip/Tooltip.test.tsx b/packages/grafana-ui/src/components/Tooltip/Tooltip.test.tsx index d318be466e6..68dbc689ce0 100644 --- a/packages/grafana-ui/src/components/Tooltip/Tooltip.test.tsx +++ b/packages/grafana-ui/src/components/Tooltip/Tooltip.test.tsx @@ -1,5 +1,6 @@ -import React from 'react'; -import { render, screen } from '@testing-library/react'; +import { render, screen } from '@testing-library/react'; +import React from 'react'; + import { Tooltip } from './Tooltip'; describe('Tooltip', () => { diff --git a/packages/grafana-ui/src/components/Tooltip/Tooltip.tsx b/packages/grafana-ui/src/components/Tooltip/Tooltip.tsx index ba5cd2b2b9f..08647671b66 100644 --- a/packages/grafana-ui/src/components/Tooltip/Tooltip.tsx +++ b/packages/grafana-ui/src/components/Tooltip/Tooltip.tsx @@ -1,11 +1,14 @@ +import { css } from '@emotion/css'; import React from 'react'; import { usePopperTooltip } from 'react-popper-tooltip'; + import { colorManipulator, GrafanaTheme2 } from '@grafana/data'; -import { css } from '@emotion/css'; + import { useStyles2 } from '../../themes/ThemeContext'; -import { PopoverContent, TooltipPlacement } from './types'; import { Portal } from '../Portal/Portal'; +import { PopoverContent, TooltipPlacement } from './types'; + export interface TooltipProps { theme?: 'info' | 'error' | 'info-alt'; show?: boolean; diff --git a/packages/grafana-ui/src/components/Typeahead/PartialHighlighter.test.tsx b/packages/grafana-ui/src/components/Typeahead/PartialHighlighter.test.tsx index 55008a6cf46..a73a9c63d16 100644 --- a/packages/grafana-ui/src/components/Typeahead/PartialHighlighter.test.tsx +++ b/packages/grafana-ui/src/components/Typeahead/PartialHighlighter.test.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { mount, ReactWrapper } from 'enzyme'; +import React from 'react'; + import { PartialHighlighter } from './PartialHighlighter'; function assertPart(component: ReactWrapper, isHighlighted: boolean, text: string): void { diff --git a/packages/grafana-ui/src/components/Typeahead/PartialHighlighter.tsx b/packages/grafana-ui/src/components/Typeahead/PartialHighlighter.tsx index 04e967b3b7e..13bbde407e5 100644 --- a/packages/grafana-ui/src/components/Typeahead/PartialHighlighter.tsx +++ b/packages/grafana-ui/src/components/Typeahead/PartialHighlighter.tsx @@ -1,4 +1,5 @@ import React, { createElement } from 'react'; + import { HighlightPart } from '../../types'; interface Props { diff --git a/packages/grafana-ui/src/components/Typeahead/Typeahead.test.tsx b/packages/grafana-ui/src/components/Typeahead/Typeahead.test.tsx index ffe7380e941..a2ac0365890 100644 --- a/packages/grafana-ui/src/components/Typeahead/Typeahead.test.tsx +++ b/packages/grafana-ui/src/components/Typeahead/Typeahead.test.tsx @@ -1,9 +1,10 @@ -import React from 'react'; import { mount } from 'enzyme'; +import React from 'react'; + +import { CompletionItemGroup, CompletionItemKind } from '../../types'; import { Typeahead, State } from './Typeahead'; import { TypeaheadItem } from './TypeaheadItem'; -import { CompletionItemGroup, CompletionItemKind } from '../../types'; describe('Typeahead', () => { const completionItemGroups = [{ label: 'my group', items: [{ label: 'first item' }] }]; diff --git a/packages/grafana-ui/src/components/Typeahead/Typeahead.tsx b/packages/grafana-ui/src/components/Typeahead/Typeahead.tsx index 3dc06442c4c..01526c98439 100644 --- a/packages/grafana-ui/src/components/Typeahead/Typeahead.tsx +++ b/packages/grafana-ui/src/components/Typeahead/Typeahead.tsx @@ -1,13 +1,14 @@ +import { isEqual } from 'lodash'; import React, { createRef } from 'react'; import ReactDOM from 'react-dom'; -import { isEqual } from 'lodash'; import { FixedSizeList } from 'react-window'; +import { ThemeContext } from '../../themes/ThemeContext'; +import { CompletionItem, CompletionItemGroup, CompletionItemKind } from '../../types/completion'; +import { flattenGroupItems, calculateLongestLabel, calculateListSizes } from '../../utils/typeahead'; + import { TypeaheadInfo } from './TypeaheadInfo'; import { TypeaheadItem } from './TypeaheadItem'; -import { flattenGroupItems, calculateLongestLabel, calculateListSizes } from '../../utils/typeahead'; -import { ThemeContext } from '../../themes/ThemeContext'; -import { CompletionItem, CompletionItemGroup, CompletionItemKind } from '../../types/completion'; const modulo = (a: number, n: number) => a - n * Math.floor(a / n); diff --git a/packages/grafana-ui/src/components/Typeahead/TypeaheadInfo.test.tsx b/packages/grafana-ui/src/components/Typeahead/TypeaheadInfo.test.tsx index 0864fa79b84..78624ee43ef 100644 --- a/packages/grafana-ui/src/components/Typeahead/TypeaheadInfo.test.tsx +++ b/packages/grafana-ui/src/components/Typeahead/TypeaheadInfo.test.tsx @@ -1,8 +1,10 @@ -import React from 'react'; import { mount } from 'enzyme'; -import { TypeaheadInfo } from './TypeaheadInfo'; +import React from 'react'; + import { CompletionItem } from '../../types'; +import { TypeaheadInfo } from './TypeaheadInfo'; + describe('TypeaheadInfo component', () => { it('should show documentation as rendered markdown if passed as a markdown', () => { const item: CompletionItem = { label: 'markdown', documentation: '**bold**' }; diff --git a/packages/grafana-ui/src/components/Typeahead/TypeaheadInfo.tsx b/packages/grafana-ui/src/components/Typeahead/TypeaheadInfo.tsx index df7b0ba3d55..30c4b10fd2a 100644 --- a/packages/grafana-ui/src/components/Typeahead/TypeaheadInfo.tsx +++ b/packages/grafana-ui/src/components/Typeahead/TypeaheadInfo.tsx @@ -1,7 +1,8 @@ -import React from 'react'; import { css, cx } from '@emotion/css'; +import React from 'react'; import { GrafanaTheme, renderMarkdown } from '@grafana/data'; + import { useTheme } from '../../themes/ThemeContext'; import { CompletionItem } from '../../types'; diff --git a/packages/grafana-ui/src/components/Typeahead/TypeaheadItem.tsx b/packages/grafana-ui/src/components/Typeahead/TypeaheadItem.tsx index c2cde3dbd39..d75685d866e 100644 --- a/packages/grafana-ui/src/components/Typeahead/TypeaheadItem.tsx +++ b/packages/grafana-ui/src/components/Typeahead/TypeaheadItem.tsx @@ -1,12 +1,14 @@ +import { css, cx } from '@emotion/css'; import React from 'react'; - // @ts-ignore import Highlighter from 'react-highlight-words'; -import { css, cx } from '@emotion/css'; + import { GrafanaTheme } from '@grafana/data'; -import { CompletionItem, CompletionItemKind } from '../../types/completion'; -import { PartialHighlighter } from './PartialHighlighter'; + import { useStyles } from '../../themes/ThemeContext'; +import { CompletionItem, CompletionItemKind } from '../../types/completion'; + +import { PartialHighlighter } from './PartialHighlighter'; interface Props { isSelected: boolean; diff --git a/packages/grafana-ui/src/components/Typography/Typography.story.tsx b/packages/grafana-ui/src/components/Typography/Typography.story.tsx index 4069fc442a1..941a2f5d2b4 100644 --- a/packages/grafana-ui/src/components/Typography/Typography.story.tsx +++ b/packages/grafana-ui/src/components/Typography/Typography.story.tsx @@ -1,6 +1,8 @@ import React from 'react'; + import { StoryExample } from '../../utils/storybook/StoryExample'; import { VerticalGroup } from '../Layout/Layout'; + import { Typography } from './Typography'; export default { diff --git a/packages/grafana-ui/src/components/UnitPicker/UnitPicker.story.tsx b/packages/grafana-ui/src/components/UnitPicker/UnitPicker.story.tsx index 29f173341c6..558a7c5f080 100644 --- a/packages/grafana-ui/src/components/UnitPicker/UnitPicker.story.tsx +++ b/packages/grafana-ui/src/components/UnitPicker/UnitPicker.story.tsx @@ -1,7 +1,9 @@ import React from 'react'; -import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; import { UnitPicker } from '@grafana/ui'; + +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; + import mdx from './UnitPicker.mdx'; export default { diff --git a/packages/grafana-ui/src/components/UnitPicker/UnitPicker.tsx b/packages/grafana-ui/src/components/UnitPicker/UnitPicker.tsx index bbf1b48a9b8..570b4e9de5f 100644 --- a/packages/grafana-ui/src/components/UnitPicker/UnitPicker.tsx +++ b/packages/grafana-ui/src/components/UnitPicker/UnitPicker.tsx @@ -1,7 +1,9 @@ import React, { PureComponent } from 'react'; -import { Cascader, CascaderOption } from '../Cascader/Cascader'; + import { getValueFormats, SelectableValue } from '@grafana/data'; +import { Cascader, CascaderOption } from '../Cascader/Cascader'; + interface Props { onChange: (item?: string) => void; value?: string; diff --git a/packages/grafana-ui/src/components/ValuePicker/ValuePicker.story.tsx b/packages/grafana-ui/src/components/ValuePicker/ValuePicker.story.tsx index 96401c4edb7..920adc40273 100644 --- a/packages/grafana-ui/src/components/ValuePicker/ValuePicker.story.tsx +++ b/packages/grafana-ui/src/components/ValuePicker/ValuePicker.story.tsx @@ -1,11 +1,14 @@ -import React from 'react'; import { Story } from '@storybook/react'; +import React from 'react'; + import { ValuePicker } from '@grafana/ui'; -import { generateOptions } from '../Select/mockOptions'; -import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; + import { getAvailableIcons } from '../../types'; -import mdx from './ValuePicker.mdx'; +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; +import { generateOptions } from '../Select/mockOptions'; + import { ValuePickerProps } from './ValuePicker'; +import mdx from './ValuePicker.mdx'; export default { title: 'Pickers and Editors/ValuePicker', diff --git a/packages/grafana-ui/src/components/ValuePicker/ValuePicker.tsx b/packages/grafana-ui/src/components/ValuePicker/ValuePicker.tsx index 53c68bcb47f..9edba661e15 100644 --- a/packages/grafana-ui/src/components/ValuePicker/ValuePicker.tsx +++ b/packages/grafana-ui/src/components/ValuePicker/ValuePicker.tsx @@ -1,11 +1,13 @@ import React, { useState } from 'react'; -import { IconName } from '../../types'; + import { SelectableValue } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; + +import { useTheme2 } from '../../themes'; +import { IconName } from '../../types'; +import { ComponentSize } from '../../types/size'; import { Button, ButtonVariant } from '../Button'; import { Select } from '../Select/Select'; -import { ComponentSize } from '../../types/size'; -import { selectors } from '@grafana/e2e-selectors'; -import { useTheme2 } from '../../themes'; export interface ValuePickerProps { /** Label to display on the picker button */ diff --git a/packages/grafana-ui/src/components/VizLayout/VizLayout.story.tsx b/packages/grafana-ui/src/components/VizLayout/VizLayout.story.tsx index b42a145b634..c919cc70aa5 100644 --- a/packages/grafana-ui/src/components/VizLayout/VizLayout.story.tsx +++ b/packages/grafana-ui/src/components/VizLayout/VizLayout.story.tsx @@ -1,6 +1,8 @@ -import React, { useEffect, useState } from 'react'; -import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; import { Story } from '@storybook/react'; +import React, { useEffect, useState } from 'react'; + +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; + import { VizLayout } from './VizLayout'; export default { diff --git a/packages/grafana-ui/src/components/VizLayout/VizLayout.tsx b/packages/grafana-ui/src/components/VizLayout/VizLayout.tsx index 83444158386..3f91557fc78 100644 --- a/packages/grafana-ui/src/components/VizLayout/VizLayout.tsx +++ b/packages/grafana-ui/src/components/VizLayout/VizLayout.tsx @@ -1,11 +1,13 @@ +import { css } from '@emotion/css'; import React, { FC, CSSProperties, ComponentType } from 'react'; import { useMeasure } from 'react-use'; -import { css } from '@emotion/css'; -import { LegendPlacement } from '@grafana/schema'; + import { GrafanaTheme2 } from '@grafana/data'; -import { CustomScrollbar } from '../CustomScrollbar/CustomScrollbar'; -import { getFocusStyles } from '../../themes/mixins'; +import { LegendPlacement } from '@grafana/schema'; + import { useStyles2 } from '../../themes/ThemeContext'; +import { getFocusStyles } from '../../themes/mixins'; +import { CustomScrollbar } from '../CustomScrollbar/CustomScrollbar'; /** * @beta diff --git a/packages/grafana-ui/src/components/VizLegend/SeriesIcon.test.tsx b/packages/grafana-ui/src/components/VizLegend/SeriesIcon.test.tsx index 037eb0472a8..79672cd68ee 100644 --- a/packages/grafana-ui/src/components/VizLegend/SeriesIcon.test.tsx +++ b/packages/grafana-ui/src/components/VizLegend/SeriesIcon.test.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { render } from '@testing-library/react'; +import React from 'react'; + import { SeriesIcon } from './SeriesIcon'; describe('SeriesIcon', () => { diff --git a/packages/grafana-ui/src/components/VizLegend/SeriesIcon.tsx b/packages/grafana-ui/src/components/VizLegend/SeriesIcon.tsx index 89711d53307..ec91ac063ff 100644 --- a/packages/grafana-ui/src/components/VizLegend/SeriesIcon.tsx +++ b/packages/grafana-ui/src/components/VizLegend/SeriesIcon.tsx @@ -1,7 +1,9 @@ import React, { CSSProperties } from 'react'; -import { useTheme2 } from '../../themes'; + import { fieldColorModeRegistry } from '@grafana/data'; +import { useTheme2 } from '../../themes'; + export interface Props extends React.HTMLAttributes { color?: string; gradient?: string; diff --git a/packages/grafana-ui/src/components/VizLegend/VizLegend.story.tsx b/packages/grafana-ui/src/components/VizLegend/VizLegend.story.tsx index b9bc1a66037..d5db02e57a5 100644 --- a/packages/grafana-ui/src/components/VizLegend/VizLegend.story.tsx +++ b/packages/grafana-ui/src/components/VizLegend/VizLegend.story.tsx @@ -1,11 +1,13 @@ -import React, { FC, useEffect, useState } from 'react'; -import { useTheme, VizLegend } from '@grafana/ui'; import { Story, Meta } from '@storybook/react'; -import {} from './VizLegendListItem'; +import React, { FC, useEffect, useState } from 'react'; + import { DisplayValue, getColorForTheme, GrafanaTheme } from '@grafana/data'; -import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; -import { VizLegendItem } from './types'; import { LegendDisplayMode, LegendPlacement } from '@grafana/schema'; +import { useTheme, VizLegend } from '@grafana/ui'; + +import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; + +import { VizLegendItem } from './types'; export default { title: 'Visualizations/VizLegend', diff --git a/packages/grafana-ui/src/components/VizLegend/VizLegend.tsx b/packages/grafana-ui/src/components/VizLegend/VizLegend.tsx index c44a72924d2..ddbc3dd383c 100644 --- a/packages/grafana-ui/src/components/VizLegend/VizLegend.tsx +++ b/packages/grafana-ui/src/components/VizLegend/VizLegend.tsx @@ -1,10 +1,13 @@ import React, { useCallback } from 'react'; -import { LegendProps, SeriesVisibilityChangeBehavior, VizLegendItem } from './types'; -import { LegendDisplayMode } from '@grafana/schema'; -import { VizLegendTable } from './VizLegendTable'; -import { VizLegendList } from './VizLegendList'; + import { DataHoverClearEvent, DataHoverEvent } from '@grafana/data'; +import { LegendDisplayMode } from '@grafana/schema'; + import { SeriesVisibilityChangeMode, usePanelContext } from '../PanelChrome'; + +import { VizLegendList } from './VizLegendList'; +import { VizLegendTable } from './VizLegendTable'; +import { LegendProps, SeriesVisibilityChangeBehavior, VizLegendItem } from './types'; import { mapMouseEventToMode } from './utils'; /** diff --git a/packages/grafana-ui/src/components/VizLegend/VizLegendList.tsx b/packages/grafana-ui/src/components/VizLegend/VizLegendList.tsx index a701431caa7..d0ca8d96597 100644 --- a/packages/grafana-ui/src/components/VizLegend/VizLegendList.tsx +++ b/packages/grafana-ui/src/components/VizLegend/VizLegendList.tsx @@ -1,11 +1,14 @@ +import { css, cx } from '@emotion/css'; import React from 'react'; -import { VizLegendBaseProps, VizLegendItem } from './types'; + +import { GrafanaTheme } from '@grafana/data'; + +import { useStyles } from '../../themes'; import { InlineList } from '../List/InlineList'; import { List } from '../List/List'; -import { css, cx } from '@emotion/css'; -import { useStyles } from '../../themes'; -import { GrafanaTheme } from '@grafana/data'; + import { VizLegendListItem } from './VizLegendListItem'; +import { VizLegendBaseProps, VizLegendItem } from './types'; export interface Props extends VizLegendBaseProps {} diff --git a/packages/grafana-ui/src/components/VizLegend/VizLegendListItem.tsx b/packages/grafana-ui/src/components/VizLegend/VizLegendListItem.tsx index 16f77707c99..1861e99fe83 100644 --- a/packages/grafana-ui/src/components/VizLegend/VizLegendListItem.tsx +++ b/packages/grafana-ui/src/components/VizLegend/VizLegendListItem.tsx @@ -1,12 +1,15 @@ -import React, { useCallback } from 'react'; import { css, cx } from '@emotion/css'; -import { VizLegendSeriesIcon } from './VizLegendSeriesIcon'; -import { VizLegendItem } from './types'; -import { VizLegendStatsList } from './VizLegendStatsList'; -import { useStyles } from '../../themes'; +import React, { useCallback } from 'react'; + import { GrafanaTheme } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; +import { useStyles } from '../../themes'; + +import { VizLegendSeriesIcon } from './VizLegendSeriesIcon'; +import { VizLegendStatsList } from './VizLegendStatsList'; +import { VizLegendItem } from './types'; + export interface Props { item: VizLegendItem; className?: string; diff --git a/packages/grafana-ui/src/components/VizLegend/VizLegendSeriesIcon.tsx b/packages/grafana-ui/src/components/VizLegend/VizLegendSeriesIcon.tsx index 943eb6d1ac4..250de0703e7 100644 --- a/packages/grafana-ui/src/components/VizLegend/VizLegendSeriesIcon.tsx +++ b/packages/grafana-ui/src/components/VizLegend/VizLegendSeriesIcon.tsx @@ -1,6 +1,8 @@ import React, { useCallback } from 'react'; + import { SeriesColorPicker } from '../ColorPicker/ColorPicker'; import { usePanelContext } from '../PanelChrome'; + import { SeriesIcon } from './SeriesIcon'; interface Props { diff --git a/packages/grafana-ui/src/components/VizLegend/VizLegendStatsList.tsx b/packages/grafana-ui/src/components/VizLegend/VizLegendStatsList.tsx index 2fdf0db9961..c4f32f678f3 100644 --- a/packages/grafana-ui/src/components/VizLegend/VizLegendStatsList.tsx +++ b/packages/grafana-ui/src/components/VizLegend/VizLegendStatsList.tsx @@ -1,9 +1,11 @@ -import React from 'react'; -import { InlineList } from '../List/InlineList'; import { css } from '@emotion/css'; -import { DisplayValue, formattedValueToString } from '@grafana/data'; import { capitalize } from 'lodash'; +import React from 'react'; + +import { DisplayValue, formattedValueToString } from '@grafana/data'; + import { useStyles } from '../../themes/ThemeContext'; +import { InlineList } from '../List/InlineList'; /** * @internal diff --git a/packages/grafana-ui/src/components/VizLegend/VizLegendTable.tsx b/packages/grafana-ui/src/components/VizLegend/VizLegendTable.tsx index 0bd289bd8f9..06d5666076f 100644 --- a/packages/grafana-ui/src/components/VizLegend/VizLegendTable.tsx +++ b/packages/grafana-ui/src/components/VizLegend/VizLegendTable.tsx @@ -1,12 +1,15 @@ -import React from 'react'; import { css, cx } from '@emotion/css'; -import { VizLegendTableProps } from './types'; -import { Icon } from '../Icon/Icon'; -import { useStyles2 } from '../../themes/ThemeContext'; import { orderBy } from 'lodash'; -import { LegendTableItem } from './VizLegendTableItem'; +import React from 'react'; + import { DisplayValue, GrafanaTheme2 } from '@grafana/data'; +import { useStyles2 } from '../../themes/ThemeContext'; +import { Icon } from '../Icon/Icon'; + +import { LegendTableItem } from './VizLegendTableItem'; +import { VizLegendTableProps } from './types'; + /** * @internal */ diff --git a/packages/grafana-ui/src/components/VizLegend/VizLegendTableItem.tsx b/packages/grafana-ui/src/components/VizLegend/VizLegendTableItem.tsx index f35f7bbb712..2454ffaf38e 100644 --- a/packages/grafana-ui/src/components/VizLegend/VizLegendTableItem.tsx +++ b/packages/grafana-ui/src/components/VizLegend/VizLegendTableItem.tsx @@ -1,10 +1,13 @@ -import React, { useCallback } from 'react'; import { css, cx } from '@emotion/css'; +import React, { useCallback } from 'react'; + +import { formattedValueToString, GrafanaTheme2 } from '@grafana/data'; + +import { styleMixins } from '../../themes'; +import { useStyles2 } from '../../themes/ThemeContext'; + import { VizLegendSeriesIcon } from './VizLegendSeriesIcon'; import { VizLegendItem } from './types'; -import { useStyles2 } from '../../themes/ThemeContext'; -import { styleMixins } from '../../themes'; -import { formattedValueToString, GrafanaTheme2 } from '@grafana/data'; export interface Props { key?: React.Key; diff --git a/packages/grafana-ui/src/components/VizRepeater/VizRepeater.tsx b/packages/grafana-ui/src/components/VizRepeater/VizRepeater.tsx index 4ea26ba9fc8..544e8c1515f 100644 --- a/packages/grafana-ui/src/components/VizRepeater/VizRepeater.tsx +++ b/packages/grafana-ui/src/components/VizRepeater/VizRepeater.tsx @@ -1,5 +1,7 @@ import React, { PureComponent, CSSProperties } from 'react'; + import { VizOrientation } from '@grafana/data'; + import { calculateGridDimensions } from '../../utils/squares'; interface Props { diff --git a/packages/grafana-ui/src/components/VizTooltip/SeriesTable.story.tsx b/packages/grafana-ui/src/components/VizTooltip/SeriesTable.story.tsx index 352f0ab0093..d05577f1695 100644 --- a/packages/grafana-ui/src/components/VizTooltip/SeriesTable.story.tsx +++ b/packages/grafana-ui/src/components/VizTooltip/SeriesTable.story.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { Story, Meta } from '@storybook/react'; +import React from 'react'; + import { SeriesTable, SeriesTableProps } from './SeriesTable'; export default { diff --git a/packages/grafana-ui/src/components/VizTooltip/SeriesTable.tsx b/packages/grafana-ui/src/components/VizTooltip/SeriesTable.tsx index 7643b7a5333..c6b43c34ccc 100644 --- a/packages/grafana-ui/src/components/VizTooltip/SeriesTable.tsx +++ b/packages/grafana-ui/src/components/VizTooltip/SeriesTable.tsx @@ -1,8 +1,10 @@ -import React from 'react'; -import { GrafanaTheme2, GraphSeriesValue } from '@grafana/data'; import { css, cx } from '@emotion/css'; -import { SeriesIcon } from '../VizLegend/SeriesIcon'; +import React from 'react'; + +import { GrafanaTheme2, GraphSeriesValue } from '@grafana/data'; + import { useStyles2 } from '../../themes'; +import { SeriesIcon } from '../VizLegend/SeriesIcon'; /** * @public diff --git a/packages/grafana-ui/src/components/VizTooltip/VizTooltip.tsx b/packages/grafana-ui/src/components/VizTooltip/VizTooltip.tsx index ffcc3de94fc..dd3a1a6012c 100644 --- a/packages/grafana-ui/src/components/VizTooltip/VizTooltip.tsx +++ b/packages/grafana-ui/src/components/VizTooltip/VizTooltip.tsx @@ -1,12 +1,15 @@ -import React from 'react'; import { css } from '@emotion/css'; -import { Portal } from '../Portal/Portal'; +import React from 'react'; + import { Dimensions, TimeZone } from '@grafana/data'; -import { FlotPosition } from '../Graph/types'; -import { VizTooltipContainer } from './VizTooltipContainer'; -import { useStyles } from '../../themes'; import { TooltipDisplayMode } from '@grafana/schema'; +import { useStyles } from '../../themes'; +import { FlotPosition } from '../Graph/types'; +import { Portal } from '../Portal/Portal'; + +import { VizTooltipContainer } from './VizTooltipContainer'; + // Describes active dimensions user interacts with // It's a key-value pair where: // - key is the name of the dimension diff --git a/packages/grafana-ui/src/components/VizTooltip/VizTooltipContainer.tsx b/packages/grafana-ui/src/components/VizTooltip/VizTooltipContainer.tsx index 50f7f976166..5f556fbcd34 100644 --- a/packages/grafana-ui/src/components/VizTooltip/VizTooltipContainer.tsx +++ b/packages/grafana-ui/src/components/VizTooltip/VizTooltipContainer.tsx @@ -1,9 +1,12 @@ -import React, { useState, HTMLAttributes, useMemo, useRef, useLayoutEffect } from 'react'; import { css, cx } from '@emotion/css'; +import React, { useState, HTMLAttributes, useMemo, useRef, useLayoutEffect } from 'react'; +import useWindowSize from 'react-use/lib/useWindowSize'; + +import { Dimensions2D, GrafanaTheme2 } from '@grafana/data'; + import { useStyles2 } from '../../themes'; import { getTooltipContainerStyles } from '../../themes/mixins'; -import useWindowSize from 'react-use/lib/useWindowSize'; -import { Dimensions2D, GrafanaTheme2 } from '@grafana/data'; + import { calculateTooltipPosition } from './utils'; /** diff --git a/packages/grafana-ui/src/components/index.ts b/packages/grafana-ui/src/components/index.ts index f4733b6ff7d..e4208a61655 100644 --- a/packages/grafana-ui/src/components/index.ts +++ b/packages/grafana-ui/src/components/index.ts @@ -1,3 +1,11 @@ +import { FormField } from './FormField/FormField'; +import { Input, LegacyInputStatus } from './Forms/Legacy/Input/Input'; +import { IndicatorsContainer } from './Forms/Legacy/Select/IndicatorsContainer'; +import { NoOptionsMessage } from './Forms/Legacy/Select/NoOptionsMessage'; +import { AsyncSelect, Select } from './Forms/Legacy/Select/Select'; +import { Switch } from './Forms/Legacy/Switch/Switch'; +import { SecretFormField } from './SecretFormField/SecretFormField'; + export { Icon } from './Icon/Icon'; export { IconButton, IconButtonVariant } from './IconButton/IconButton'; export { ConfirmButton } from './ConfirmButton/ConfirmButton'; @@ -42,7 +50,6 @@ export { FilterPill } from './FilterPill/FilterPill'; export { ConfirmModal, ConfirmModalProps } from './ConfirmModal/ConfirmModal'; export { QueryField } from './QueryField/QueryField'; -// Code editor export { CodeEditor } from './Monaco/CodeEditor'; export { ReactMonacoEditorLazy as ReactMonacoEditor } from './Monaco/ReactMonacoEditorLazy'; @@ -230,18 +237,6 @@ export { PluginSignatureBadge, PluginSignatureBadgeProps } from './PluginSignatu // Export this until we've figured out a good approach to inline form styles. export { InlineFormLabel } from './FormLabel/FormLabel'; -// Select -import { AsyncSelect, Select } from './Forms/Legacy/Select/Select'; -import { IndicatorsContainer } from './Forms/Legacy/Select/IndicatorsContainer'; -import { NoOptionsMessage } from './Forms/Legacy/Select/NoOptionsMessage'; - -//Input -import { Input, LegacyInputStatus } from './Forms/Legacy/Input/Input'; -import { FormField } from './FormField/FormField'; -import { SecretFormField } from './SecretFormField/SecretFormField'; - -import { Switch } from './Forms/Legacy/Switch/Switch'; - const LegacyForms = { SecretFormField, FormField, diff --git a/packages/grafana-ui/src/components/transitions/FadeTransition.tsx b/packages/grafana-ui/src/components/transitions/FadeTransition.tsx index 2a3f3ac2941..3d985302920 100644 --- a/packages/grafana-ui/src/components/transitions/FadeTransition.tsx +++ b/packages/grafana-ui/src/components/transitions/FadeTransition.tsx @@ -1,6 +1,7 @@ -import React from 'react'; import { css } from '@emotion/css'; +import React from 'react'; import { CSSTransition } from 'react-transition-group'; + import { stylesFactory } from '../../themes'; const getStyles = stylesFactory((duration: number) => { diff --git a/packages/grafana-ui/src/components/transitions/SlideOutTransition.tsx b/packages/grafana-ui/src/components/transitions/SlideOutTransition.tsx index aeaf0216512..4bdac36eb2c 100644 --- a/packages/grafana-ui/src/components/transitions/SlideOutTransition.tsx +++ b/packages/grafana-ui/src/components/transitions/SlideOutTransition.tsx @@ -1,6 +1,7 @@ -import React from 'react'; import { css } from '@emotion/css'; +import React from 'react'; import { CSSTransition } from 'react-transition-group'; + import { stylesFactory } from '../../themes'; const getStyles = stylesFactory((duration: number, measurement: 'width' | 'height', size: number) => { diff --git a/packages/grafana-ui/src/components/uPlot/Plot.test.tsx b/packages/grafana-ui/src/components/uPlot/Plot.test.tsx index 7505c6cb26f..9fed6ed14e6 100644 --- a/packages/grafana-ui/src/components/uPlot/Plot.test.tsx +++ b/packages/grafana-ui/src/components/uPlot/Plot.test.tsx @@ -1,13 +1,15 @@ -import React from 'react'; -import { UPlotChart } from './Plot'; import { render } from '@testing-library/react'; +import createMockRaf from 'mock-raf'; +import React from 'react'; +import uPlot from 'uplot'; + import { ArrayVector, dateTime, FieldConfig, FieldType, MutableDataFrame } from '@grafana/data'; import { GraphFieldConfig, GraphDrawStyle } from '@grafana/schema'; -import uPlot from 'uplot'; -import createMockRaf from 'mock-raf'; + +import { UPlotChart } from './Plot'; import { UPlotConfigBuilder } from './config/UPlotConfigBuilder'; -import { preparePlotData2, getStackingGroups } from './utils'; import { SeriesProps } from './config/UPlotSeriesBuilder'; +import { preparePlotData2, getStackingGroups } from './utils'; const mockRaf = createMockRaf(); const setDataMock = jest.fn(); diff --git a/packages/grafana-ui/src/components/uPlot/Plot.tsx b/packages/grafana-ui/src/components/uPlot/Plot.tsx index 7b1aba9de4a..6b4c3efd187 100755 --- a/packages/grafana-ui/src/components/uPlot/Plot.tsx +++ b/packages/grafana-ui/src/components/uPlot/Plot.tsx @@ -1,7 +1,8 @@ import React, { createRef } from 'react'; import uPlot, { AlignedData, Options } from 'uplot'; -import { DEFAULT_PLOT_CONFIG, pluginLog } from './utils'; + import { PlotProps } from './types'; +import { DEFAULT_PLOT_CONFIG, pluginLog } from './utils'; function sameDims(prevProps: PlotProps, nextProps: PlotProps) { return nextProps.width === prevProps.width && nextProps.height === prevProps.height; diff --git a/packages/grafana-ui/src/components/uPlot/PlotLegend.tsx b/packages/grafana-ui/src/components/uPlot/PlotLegend.tsx index ae7117765b6..188f3d93c33 100644 --- a/packages/grafana-ui/src/components/uPlot/PlotLegend.tsx +++ b/packages/grafana-ui/src/components/uPlot/PlotLegend.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { DataFrame, DisplayValue, @@ -7,12 +8,14 @@ import { getFieldSeriesColor, reduceField, } from '@grafana/data'; -import { UPlotConfigBuilder } from './config/UPlotConfigBuilder'; -import { VizLegendItem } from '../VizLegend/types'; import { VizLegendOptions, AxisPlacement } from '@grafana/schema'; + +import { useTheme2 } from '../../themes'; import { VizLayout, VizLayoutLegendProps } from '../VizLayout/VizLayout'; import { VizLegend } from '../VizLegend/VizLegend'; -import { useTheme2 } from '../../themes'; +import { VizLegendItem } from '../VizLegend/types'; + +import { UPlotConfigBuilder } from './config/UPlotConfigBuilder'; const defaultFormatter = (v: any) => (v == null ? '-' : v.toFixed(1)); diff --git a/packages/grafana-ui/src/components/uPlot/config/UPlotAxisBuilder.ts b/packages/grafana-ui/src/components/uPlot/config/UPlotAxisBuilder.ts index aed1c014597..59b4e50b66a 100644 --- a/packages/grafana-ui/src/components/uPlot/config/UPlotAxisBuilder.ts +++ b/packages/grafana-ui/src/components/uPlot/config/UPlotAxisBuilder.ts @@ -1,8 +1,11 @@ -import { dateTimeFormat, GrafanaTheme2, isBooleanUnit, systemDateFormats, TimeZone } from '@grafana/data'; import uPlot, { Axis } from 'uplot'; -import { PlotConfigBuilder } from '../types'; -import { measureText } from '../../../utils/measureText'; + +import { dateTimeFormat, GrafanaTheme2, isBooleanUnit, systemDateFormats, TimeZone } from '@grafana/data'; import { AxisPlacement } from '@grafana/schema'; + +import { measureText } from '../../../utils/measureText'; +import { PlotConfigBuilder } from '../types'; + import { optMinMax } from './UPlotScaleBuilder'; export interface AxisProps { diff --git a/packages/grafana-ui/src/components/uPlot/config/UPlotConfigBuilder.test.ts b/packages/grafana-ui/src/components/uPlot/config/UPlotConfigBuilder.test.ts index 9d432d46cde..a2c6f852117 100644 --- a/packages/grafana-ui/src/components/uPlot/config/UPlotConfigBuilder.test.ts +++ b/packages/grafana-ui/src/components/uPlot/config/UPlotConfigBuilder.test.ts @@ -1,6 +1,6 @@ // TODO: migrate tests below to the builder -import { UPlotConfigBuilder } from './UPlotConfigBuilder'; +import { createTheme, ThresholdsMode } from '@grafana/data'; import { GraphGradientMode, AxisPlacement, @@ -11,7 +11,8 @@ import { GraphTresholdsStyleMode, ScaleDistribution, } from '@grafana/schema'; -import { createTheme, ThresholdsMode } from '@grafana/data'; + +import { UPlotConfigBuilder } from './UPlotConfigBuilder'; describe('UPlotConfigBuilder', () => { const darkTheme = createTheme(); diff --git a/packages/grafana-ui/src/components/uPlot/config/UPlotConfigBuilder.ts b/packages/grafana-ui/src/components/uPlot/config/UPlotConfigBuilder.ts index 95408d8ae66..cc2b2124989 100644 --- a/packages/grafana-ui/src/components/uPlot/config/UPlotConfigBuilder.ts +++ b/packages/grafana-ui/src/components/uPlot/config/UPlotConfigBuilder.ts @@ -1,5 +1,6 @@ -import uPlot, { Cursor, Band, Hooks, Select, AlignedData, Padding, Series } from 'uplot'; import { merge } from 'lodash'; +import uPlot, { Cursor, Band, Hooks, Select, AlignedData, Padding, Series } from 'uplot'; + import { DataFrame, DefaultTimeZone, @@ -10,12 +11,14 @@ import { TimeRange, TimeZone, } from '@grafana/data'; +import { AxisPlacement } from '@grafana/schema'; + import { FacetedData, PlotConfig, PlotTooltipInterpolator } from '../types'; +import { getStackingBands, pluginLog, StackingGroup } from '../utils'; + +import { AxisProps, UPlotAxisBuilder } from './UPlotAxisBuilder'; import { ScaleProps, UPlotScaleBuilder } from './UPlotScaleBuilder'; import { SeriesProps, UPlotSeriesBuilder } from './UPlotSeriesBuilder'; -import { AxisProps, UPlotAxisBuilder } from './UPlotAxisBuilder'; -import { AxisPlacement } from '@grafana/schema'; -import { getStackingBands, pluginLog, StackingGroup } from '../utils'; import { getThresholdsDrawHook, UPlotThresholdOptions } from './UPlotThresholds'; const cursorDefaults: Cursor = { diff --git a/packages/grafana-ui/src/components/uPlot/config/UPlotScaleBuilder.ts b/packages/grafana-ui/src/components/uPlot/config/UPlotScaleBuilder.ts index 4491ebc4e5a..db2bb0309d1 100644 --- a/packages/grafana-ui/src/components/uPlot/config/UPlotScaleBuilder.ts +++ b/packages/grafana-ui/src/components/uPlot/config/UPlotScaleBuilder.ts @@ -1,7 +1,9 @@ import uPlot, { Scale, Range } from 'uplot'; -import { PlotConfigBuilder } from '../types'; -import { ScaleOrientation, ScaleDirection, ScaleDistribution } from '@grafana/schema'; + import { isBooleanUnit } from '@grafana/data'; +import { ScaleOrientation, ScaleDirection, ScaleDistribution } from '@grafana/schema'; + +import { PlotConfigBuilder } from '../types'; export interface ScaleProps { scaleKey: string; diff --git a/packages/grafana-ui/src/components/uPlot/config/UPlotSeriesBuilder.ts b/packages/grafana-ui/src/components/uPlot/config/UPlotSeriesBuilder.ts index ae0a7df62a9..fe0c7f081f3 100755 --- a/packages/grafana-ui/src/components/uPlot/config/UPlotSeriesBuilder.ts +++ b/packages/grafana-ui/src/components/uPlot/config/UPlotSeriesBuilder.ts @@ -1,3 +1,5 @@ +import uPlot, { Series } from 'uplot'; + import { colorManipulator, DataFrameFieldIndex, @@ -7,7 +9,6 @@ import { GrafanaTheme2, ThresholdsConfig, } from '@grafana/data'; -import uPlot, { Series } from 'uplot'; import { BarAlignment, BarConfig, @@ -19,7 +20,9 @@ import { PointsConfig, VisibilityMode, } from '@grafana/schema'; + import { PlotConfigBuilder } from '../types'; + import { getHueGradientFn, getOpacityGradientFn, getScaleGradientFn } from './gradientFills'; export interface SeriesProps extends LineConfig, BarConfig, FillConfig, PointsConfig { diff --git a/packages/grafana-ui/src/components/uPlot/config/UPlotThresholds.ts b/packages/grafana-ui/src/components/uPlot/config/UPlotThresholds.ts index a682824599f..d9e81d2b89a 100644 --- a/packages/grafana-ui/src/components/uPlot/config/UPlotThresholds.ts +++ b/packages/grafana-ui/src/components/uPlot/config/UPlotThresholds.ts @@ -1,9 +1,11 @@ -import { GrafanaTheme2, Threshold, ThresholdsConfig, ThresholdsMode } from '@grafana/data'; -import { GraphThresholdsStyleConfig, GraphTresholdsStyleMode } from '@grafana/schema'; -import { getGradientRange, scaleGradient } from './gradientFills'; import tinycolor from 'tinycolor2'; import uPlot from 'uplot'; +import { GrafanaTheme2, Threshold, ThresholdsConfig, ThresholdsMode } from '@grafana/data'; +import { GraphThresholdsStyleConfig, GraphTresholdsStyleMode } from '@grafana/schema'; + +import { getGradientRange, scaleGradient } from './gradientFills'; + export interface UPlotThresholdOptions { scaleKey: string; thresholds: ThresholdsConfig; diff --git a/packages/grafana-ui/src/components/uPlot/config/gradientFills.ts b/packages/grafana-ui/src/components/uPlot/config/gradientFills.ts index f1443c6d587..c61ebaefb7c 100644 --- a/packages/grafana-ui/src/components/uPlot/config/gradientFills.ts +++ b/packages/grafana-ui/src/components/uPlot/config/gradientFills.ts @@ -1,3 +1,6 @@ +import tinycolor from 'tinycolor2'; +import uPlot from 'uplot'; + import { colorManipulator, FieldColorMode, @@ -7,8 +10,7 @@ import { ThresholdsMode, } from '@grafana/data'; import { ScaleOrientation } from '@grafana/schema'; -import tinycolor from 'tinycolor2'; -import uPlot from 'uplot'; + import { getCanvasContext } from '../../../utils/measureText'; function makeDirectionalGradient(direction: GradientDirection, bbox: uPlot.BBox, ctx: CanvasRenderingContext2D) { diff --git a/packages/grafana-ui/src/components/uPlot/geometries/EventsCanvas.tsx b/packages/grafana-ui/src/components/uPlot/geometries/EventsCanvas.tsx index 85d248fe84c..60223af3884 100644 --- a/packages/grafana-ui/src/components/uPlot/geometries/EventsCanvas.tsx +++ b/packages/grafana-ui/src/components/uPlot/geometries/EventsCanvas.tsx @@ -1,10 +1,13 @@ -import { DataFrame, DataFrameFieldIndex } from '@grafana/data'; import React, { useLayoutEffect, useMemo, useRef, useState } from 'react'; import { useMountedState } from 'react-use'; +import uPlot from 'uplot'; + +import { DataFrame, DataFrameFieldIndex } from '@grafana/data'; + import { UPlotConfigBuilder } from '../config/UPlotConfigBuilder'; + import { Marker } from './Marker'; import { XYCanvas } from './XYCanvas'; -import uPlot from 'uplot'; interface EventsCanvasProps { id: string; diff --git a/packages/grafana-ui/src/components/uPlot/geometries/XYCanvas.tsx b/packages/grafana-ui/src/components/uPlot/geometries/XYCanvas.tsx index 1d5a3d015c7..34fc8ba3d26 100644 --- a/packages/grafana-ui/src/components/uPlot/geometries/XYCanvas.tsx +++ b/packages/grafana-ui/src/components/uPlot/geometries/XYCanvas.tsx @@ -1,5 +1,5 @@ -import React, { useMemo } from 'react'; import { css } from '@emotion/css'; +import React, { useMemo } from 'react'; interface XYCanvasProps { top: number; // css pxls diff --git a/packages/grafana-ui/src/components/uPlot/geometries/index.ts b/packages/grafana-ui/src/components/uPlot/geometries/index.ts index 15b670d70c5..1fe6ab579a1 100644 --- a/packages/grafana-ui/src/components/uPlot/geometries/index.ts +++ b/packages/grafana-ui/src/components/uPlot/geometries/index.ts @@ -1,4 +1,4 @@ -import { XYCanvas } from './XYCanvas'; -import { Marker } from './Marker'; import { EventsCanvas } from './EventsCanvas'; +import { Marker } from './Marker'; +import { XYCanvas } from './XYCanvas'; export { XYCanvas, Marker, EventsCanvas }; diff --git a/packages/grafana-ui/src/components/uPlot/plugins/KeyboardPlugin.tsx b/packages/grafana-ui/src/components/uPlot/plugins/KeyboardPlugin.tsx index 975f3b8dab2..053e99e4b08 100644 --- a/packages/grafana-ui/src/components/uPlot/plugins/KeyboardPlugin.tsx +++ b/packages/grafana-ui/src/components/uPlot/plugins/KeyboardPlugin.tsx @@ -1,6 +1,7 @@ -import React, { useLayoutEffect } from 'react'; import { clamp } from 'lodash'; +import React, { useLayoutEffect } from 'react'; import uPlot from 'uplot'; + import { UPlotConfigBuilder } from '../config/UPlotConfigBuilder'; interface KeyboardPluginProps { diff --git a/packages/grafana-ui/src/components/uPlot/plugins/TooltipPlugin.tsx b/packages/grafana-ui/src/components/uPlot/plugins/TooltipPlugin.tsx index 15032a07a90..4b9d0ea5120 100644 --- a/packages/grafana-ui/src/components/uPlot/plugins/TooltipPlugin.tsx +++ b/packages/grafana-ui/src/components/uPlot/plugins/TooltipPlugin.tsx @@ -1,6 +1,7 @@ import React, { useEffect, useLayoutEffect, useRef, useState } from 'react'; import { useMountedState } from 'react-use'; import uPlot from 'uplot'; + import { arrayUtils, CartesianCoords2D, @@ -14,6 +15,7 @@ import { TimeZone, } from '@grafana/data'; import { TooltipDisplayMode, SortOrder } from '@grafana/schema'; + import { useTheme2 } from '../../../themes/ThemeContext'; import { Portal } from '../../Portal/Portal'; import { SeriesTable, SeriesTableRowProps, VizTooltipContainer } from '../../VizTooltip'; diff --git a/packages/grafana-ui/src/components/uPlot/plugins/ZoomPlugin.tsx b/packages/grafana-ui/src/components/uPlot/plugins/ZoomPlugin.tsx index 83308f6489c..681adb8c223 100644 --- a/packages/grafana-ui/src/components/uPlot/plugins/ZoomPlugin.tsx +++ b/packages/grafana-ui/src/components/uPlot/plugins/ZoomPlugin.tsx @@ -1,7 +1,8 @@ import React, { useEffect, useLayoutEffect, useState } from 'react'; + import { UPlotConfigBuilder } from '../config/UPlotConfigBuilder'; -import { pluginLog } from '../utils'; import { PlotSelection } from '../types'; +import { pluginLog } from '../utils'; interface ZoomPluginProps { onZoom: (range: { from: number; to: number }) => void; diff --git a/packages/grafana-ui/src/components/uPlot/types.ts b/packages/grafana-ui/src/components/uPlot/types.ts index 8095b9bd262..89646a5bfc6 100755 --- a/packages/grafana-ui/src/components/uPlot/types.ts +++ b/packages/grafana-ui/src/components/uPlot/types.ts @@ -1,6 +1,8 @@ import React from 'react'; import uPlot, { Options, AlignedData } from 'uplot'; + import { TimeRange } from '@grafana/data'; + import { UPlotConfigBuilder } from './config/UPlotConfigBuilder'; export type PlotConfig = Pick< diff --git a/packages/grafana-ui/src/components/uPlot/utils.test.ts b/packages/grafana-ui/src/components/uPlot/utils.test.ts index 3ccb288de24..09df64ff81c 100644 --- a/packages/grafana-ui/src/components/uPlot/utils.test.ts +++ b/packages/grafana-ui/src/components/uPlot/utils.test.ts @@ -1,7 +1,9 @@ -import { getStackingGroups, preparePlotData2, timeFormatToTemplate } from './utils'; +import Units from 'ol/proj/Units'; + import { FieldType, MutableDataFrame } from '@grafana/data'; import { BarAlignment, GraphDrawStyle, GraphTransform, LineInterpolation, StackingMode } from '@grafana/schema'; -import Units from 'ol/proj/Units'; + +import { getStackingGroups, preparePlotData2, timeFormatToTemplate } from './utils'; describe('timeFormatToTemplate', () => { it.each` diff --git a/packages/grafana-ui/src/components/uPlot/utils.ts b/packages/grafana-ui/src/components/uPlot/utils.ts index 4bdaadc8b8d..9c76ed929a3 100755 --- a/packages/grafana-ui/src/components/uPlot/utils.ts +++ b/packages/grafana-ui/src/components/uPlot/utils.ts @@ -1,6 +1,8 @@ +import uPlot, { AlignedData, Options, PaddingSide } from 'uplot'; + import { DataFrame, ensureTimeField, FieldType } from '@grafana/data'; import { BarAlignment, GraphDrawStyle, GraphTransform, LineInterpolation, StackingMode } from '@grafana/schema'; -import uPlot, { AlignedData, Options, PaddingSide } from 'uplot'; + import { attachDebugger } from '../../utils'; import { createLogger } from '../../utils/logger'; import { buildScaleKey } from '../GraphNG/utils'; diff --git a/packages/grafana-ui/src/options/builder/axis.tsx b/packages/grafana-ui/src/options/builder/axis.tsx index 5a65beceaef..bd8e7145a30 100644 --- a/packages/grafana-ui/src/options/builder/axis.tsx +++ b/packages/grafana-ui/src/options/builder/axis.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { FieldConfigEditorBuilder, FieldOverrideEditorProps, @@ -6,9 +7,10 @@ import { identityOverrideProcessor, SelectableValue, } from '@grafana/data'; -import { graphFieldOptions, Select, HorizontalGroup, RadioButtonGroup } from '../../index'; import { AxisConfig, AxisPlacement, ScaleDistribution, ScaleDistributionConfig } from '@grafana/schema'; +import { graphFieldOptions, Select, HorizontalGroup, RadioButtonGroup } from '../../index'; + /** * @alpha */ diff --git a/packages/grafana-ui/src/options/builder/hideSeries.tsx b/packages/grafana-ui/src/options/builder/hideSeries.tsx index efc1dd96851..5add4daad95 100644 --- a/packages/grafana-ui/src/options/builder/hideSeries.tsx +++ b/packages/grafana-ui/src/options/builder/hideSeries.tsx @@ -1,9 +1,11 @@ -import React, { useCallback } from 'react'; import { startCase } from 'lodash'; -import { FilterPill, HorizontalGroup } from '../../index'; +import React, { useCallback } from 'react'; + import { FieldConfigEditorBuilder, FieldConfigEditorProps } from '@grafana/data'; import { HideableFieldConfig, HideSeriesConfig } from '@grafana/schema'; +import { FilterPill, HorizontalGroup } from '../../index'; + const SeriesConfigEditor: React.FC> = (props) => { const { value, onChange } = props; diff --git a/packages/grafana-ui/src/options/builder/stacking.tsx b/packages/grafana-ui/src/options/builder/stacking.tsx index 21c279448bc..cbe21614474 100644 --- a/packages/grafana-ui/src/options/builder/stacking.tsx +++ b/packages/grafana-ui/src/options/builder/stacking.tsx @@ -1,10 +1,13 @@ +import React from 'react'; + import { FieldConfigEditorBuilder, FieldOverrideEditorProps, FieldType, identityOverrideProcessor, } from '@grafana/data'; -import React from 'react'; +import { StackingConfig, StackingMode } from '@grafana/schema'; + import { GraphFieldConfig, graphFieldOptions, @@ -14,7 +17,6 @@ import { RadioButtonGroup, Tooltip, } from '../..'; -import { StackingConfig, StackingMode } from '@grafana/schema'; export const StackingEditor: React.FC> = ({ value, diff --git a/packages/grafana-ui/src/options/builder/text.tsx b/packages/grafana-ui/src/options/builder/text.tsx index fe7243bba2f..d6ecba45ebc 100644 --- a/packages/grafana-ui/src/options/builder/text.tsx +++ b/packages/grafana-ui/src/options/builder/text.tsx @@ -1,5 +1,5 @@ -import { OptionsWithTextFormatting } from '@grafana/schema'; import { PanelOptionsEditorBuilder } from '@grafana/data'; +import { OptionsWithTextFormatting } from '@grafana/schema'; /** * Adds common text control options to a visualization options diff --git a/packages/grafana-ui/src/options/builder/tooltip.tsx b/packages/grafana-ui/src/options/builder/tooltip.tsx index 3136c77ef2f..c58f565cecf 100644 --- a/packages/grafana-ui/src/options/builder/tooltip.tsx +++ b/packages/grafana-ui/src/options/builder/tooltip.tsx @@ -1,5 +1,5 @@ -import { OptionsWithTooltip, TooltipDisplayMode, SortOrder } from '@grafana/schema'; import { PanelOptionsEditorBuilder } from '@grafana/data'; +import { OptionsWithTooltip, TooltipDisplayMode, SortOrder } from '@grafana/schema'; export function addTooltipOptions( builder: PanelOptionsEditorBuilder, diff --git a/packages/grafana-ui/src/slate-plugins/braces.test.tsx b/packages/grafana-ui/src/slate-plugins/braces.test.tsx index ecd55b7f503..680e26f3a32 100644 --- a/packages/grafana-ui/src/slate-plugins/braces.test.tsx +++ b/packages/grafana-ui/src/slate-plugins/braces.test.tsx @@ -1,7 +1,9 @@ +import { shallow } from 'enzyme'; import React from 'react'; import Plain from 'slate-plain-serializer'; + import { Editor } from '@grafana/slate-react'; -import { shallow } from 'enzyme'; + import { BracesPlugin } from './braces'; declare global { diff --git a/packages/grafana-ui/src/slate-plugins/braces.ts b/packages/grafana-ui/src/slate-plugins/braces.ts index dae974be82b..a98071c9bf8 100644 --- a/packages/grafana-ui/src/slate-plugins/braces.ts +++ b/packages/grafana-ui/src/slate-plugins/braces.ts @@ -1,7 +1,8 @@ -import { Plugin } from '@grafana/slate-react'; import { Editor as CoreEditor, Annotation } from 'slate'; import { v4 as uuidv4 } from 'uuid'; +import { Plugin } from '@grafana/slate-react'; + const BRACES: any = { '[': ']', '{': '}', diff --git a/packages/grafana-ui/src/slate-plugins/clear.test.tsx b/packages/grafana-ui/src/slate-plugins/clear.test.tsx index d1643010806..20f5bc2893c 100644 --- a/packages/grafana-ui/src/slate-plugins/clear.test.tsx +++ b/packages/grafana-ui/src/slate-plugins/clear.test.tsx @@ -1,7 +1,9 @@ -import Plain from 'slate-plain-serializer'; -import React from 'react'; -import { Editor } from '@grafana/slate-react'; import { shallow } from 'enzyme'; +import React from 'react'; +import Plain from 'slate-plain-serializer'; + +import { Editor } from '@grafana/slate-react'; + import { ClearPlugin } from './clear'; describe('clear', () => { diff --git a/packages/grafana-ui/src/slate-plugins/clear.ts b/packages/grafana-ui/src/slate-plugins/clear.ts index c711f68aff1..208aa088e8f 100644 --- a/packages/grafana-ui/src/slate-plugins/clear.ts +++ b/packages/grafana-ui/src/slate-plugins/clear.ts @@ -1,6 +1,7 @@ -import { Plugin } from '@grafana/slate-react'; import { Editor as CoreEditor } from 'slate'; +import { Plugin } from '@grafana/slate-react'; + // Clears the rest of the line after the caret export function ClearPlugin(): Plugin { return { diff --git a/packages/grafana-ui/src/slate-plugins/clipboard.ts b/packages/grafana-ui/src/slate-plugins/clipboard.ts index ee558b288b4..6a20e4d4a5c 100644 --- a/packages/grafana-ui/src/slate-plugins/clipboard.ts +++ b/packages/grafana-ui/src/slate-plugins/clipboard.ts @@ -1,6 +1,7 @@ -import { Plugin } from '@grafana/slate-react'; import { Editor as CoreEditor } from 'slate'; +import { Plugin } from '@grafana/slate-react'; + const getCopiedText = (textBlocks: string[], startOffset: number, endOffset: number) => { if (!textBlocks.length) { return undefined; diff --git a/packages/grafana-ui/src/slate-plugins/indentation.ts b/packages/grafana-ui/src/slate-plugins/indentation.ts index b848ccfd82f..41a941c9ef6 100644 --- a/packages/grafana-ui/src/slate-plugins/indentation.ts +++ b/packages/grafana-ui/src/slate-plugins/indentation.ts @@ -1,6 +1,7 @@ -import { RangeJSON, Range as SlateRange, Editor as CoreEditor } from 'slate'; -import { Plugin } from '@grafana/slate-react'; import { isKeyHotkey } from 'is-hotkey'; +import { RangeJSON, Range as SlateRange, Editor as CoreEditor } from 'slate'; + +import { Plugin } from '@grafana/slate-react'; const isIndentLeftHotkey = isKeyHotkey('mod+['); const isShiftTabHotkey = isKeyHotkey('shift+tab'); diff --git a/packages/grafana-ui/src/slate-plugins/newline.ts b/packages/grafana-ui/src/slate-plugins/newline.ts index b987b485917..62c1dc1d485 100644 --- a/packages/grafana-ui/src/slate-plugins/newline.ts +++ b/packages/grafana-ui/src/slate-plugins/newline.ts @@ -1,6 +1,7 @@ -import { Plugin } from '@grafana/slate-react'; import { Editor as CoreEditor } from 'slate'; +import { Plugin } from '@grafana/slate-react'; + function getIndent(text: string) { let offset = text.length - text.trimLeft().length; if (offset) { diff --git a/packages/grafana-ui/src/slate-plugins/runner.test.tsx b/packages/grafana-ui/src/slate-plugins/runner.test.tsx index 6041d1bc5d5..aa482f9b1bf 100644 --- a/packages/grafana-ui/src/slate-plugins/runner.test.tsx +++ b/packages/grafana-ui/src/slate-plugins/runner.test.tsx @@ -1,7 +1,9 @@ -import Plain from 'slate-plain-serializer'; -import React from 'react'; -import { Editor } from '@grafana/slate-react'; import { shallow } from 'enzyme'; +import React from 'react'; +import Plain from 'slate-plain-serializer'; + +import { Editor } from '@grafana/slate-react'; + import { RunnerPlugin } from './runner'; describe('runner', () => { diff --git a/packages/grafana-ui/src/slate-plugins/runner.ts b/packages/grafana-ui/src/slate-plugins/runner.ts index a326af8d252..9c21f7b466e 100644 --- a/packages/grafana-ui/src/slate-plugins/runner.ts +++ b/packages/grafana-ui/src/slate-plugins/runner.ts @@ -1,6 +1,7 @@ -import { Plugin } from '@grafana/slate-react'; import { Editor as CoreEditor } from 'slate'; +import { Plugin } from '@grafana/slate-react'; + export function RunnerPlugin({ handler }: any): Plugin { return { onKeyDown(event: Event, editor: CoreEditor, next: Function) { diff --git a/packages/grafana-ui/src/slate-plugins/selection_shortcuts.ts b/packages/grafana-ui/src/slate-plugins/selection_shortcuts.ts index 23211f356ab..54af62f3a24 100644 --- a/packages/grafana-ui/src/slate-plugins/selection_shortcuts.ts +++ b/packages/grafana-ui/src/slate-plugins/selection_shortcuts.ts @@ -1,7 +1,7 @@ -import { Plugin } from '@grafana/slate-react'; +import { isKeyHotkey } from 'is-hotkey'; import { Editor as CoreEditor } from 'slate'; -import { isKeyHotkey } from 'is-hotkey'; +import { Plugin } from '@grafana/slate-react'; const isSelectLineHotkey = isKeyHotkey('mod+l'); diff --git a/packages/grafana-ui/src/slate-plugins/slate-prism/index.ts b/packages/grafana-ui/src/slate-plugins/slate-prism/index.ts index 475ffd33d83..2062d9347f5 100644 --- a/packages/grafana-ui/src/slate-plugins/slate-prism/index.ts +++ b/packages/grafana-ui/src/slate-plugins/slate-prism/index.ts @@ -1,8 +1,10 @@ import Prism, { LanguageMap } from 'prismjs'; import { Block, Text, Decoration } from 'slate'; + import { Plugin } from '@grafana/slate-react'; -import Options, { OptionsFormat } from './options'; + import TOKEN_MARK from './TOKEN_MARK'; +import Options, { OptionsFormat } from './options'; export interface Token { content: string; diff --git a/packages/grafana-ui/src/slate-plugins/slate-prism/options.tsx b/packages/grafana-ui/src/slate-plugins/slate-prism/options.tsx index cc95ddbd3c9..c698f29cf42 100644 --- a/packages/grafana-ui/src/slate-plugins/slate-prism/options.tsx +++ b/packages/grafana-ui/src/slate-plugins/slate-prism/options.tsx @@ -1,7 +1,8 @@ +import { Record } from 'immutable'; import React from 'react'; import { Mark, Node, Decoration } from 'slate'; + import { Editor } from '@grafana/slate-react'; -import { Record } from 'immutable'; import TOKEN_MARK from './TOKEN_MARK'; diff --git a/packages/grafana-ui/src/slate-plugins/suggestions.test.tsx b/packages/grafana-ui/src/slate-plugins/suggestions.test.tsx index 36b6a688bae..aed96f1e346 100644 --- a/packages/grafana-ui/src/slate-plugins/suggestions.test.tsx +++ b/packages/grafana-ui/src/slate-plugins/suggestions.test.tsx @@ -1,11 +1,13 @@ -import { SearchFunctionMap } from '../utils/searchFunctions'; import { render } from 'enzyme'; -import { SuggestionsPlugin } from './suggestions'; +import _ from 'lodash'; // eslint-disable-line lodash/import-scope + import { Plugin as SlatePlugin } from '@grafana/slate-react'; -import { SearchFunctionType } from '../utils'; + import { CompletionItemGroup, SuggestionsState } from '../types'; -// eslint-disable-next-line lodash/import-scope -import _ from 'lodash'; +import { SearchFunctionType } from '../utils'; +import { SearchFunctionMap } from '../utils/searchFunctions'; + +import { SuggestionsPlugin } from './suggestions'; jest.spyOn(_, 'debounce').mockImplementation((func: (...args: any) => any) => { return Object.assign(func, { cancel: jest.fn(), flush: jest.fn() }); diff --git a/packages/grafana-ui/src/slate-plugins/suggestions.tsx b/packages/grafana-ui/src/slate-plugins/suggestions.tsx index d04155bdf72..20ccb852262 100644 --- a/packages/grafana-ui/src/slate-plugins/suggestions.tsx +++ b/packages/grafana-ui/src/slate-plugins/suggestions.tsx @@ -1,15 +1,16 @@ -import React from 'react'; import { debounce, sortBy } from 'lodash'; - +import React from 'react'; import { Editor as CoreEditor } from 'slate'; + import { Plugin as SlatePlugin } from '@grafana/slate-react'; -import TOKEN_MARK from './slate-prism/TOKEN_MARK'; import { Typeahead } from '../components/Typeahead/Typeahead'; import { CompletionItem, SuggestionsState, TypeaheadInput, TypeaheadOutput } from '../types'; import { makeFragment, SearchFunctionType } from '../utils'; import { SearchFunctionMap } from '../utils/searchFunctions'; +import TOKEN_MARK from './slate-prism/TOKEN_MARK'; + export const TYPEAHEAD_DEBOUNCE = 250; // Commands added to the editor by this plugin. diff --git a/packages/grafana-ui/src/themes/GlobalStyles/GlobalStyles.tsx b/packages/grafana-ui/src/themes/GlobalStyles/GlobalStyles.tsx index 6ac89b14bc1..fb95b5efdca 100644 --- a/packages/grafana-ui/src/themes/GlobalStyles/GlobalStyles.tsx +++ b/packages/grafana-ui/src/themes/GlobalStyles/GlobalStyles.tsx @@ -1,11 +1,13 @@ -import React from 'react'; import { Global } from '@emotion/react'; +import React from 'react'; + import { useTheme2 } from '..'; -import { getElementStyles } from './elements'; -import { getCardStyles } from './card'; + import { getAgularPanelStyles } from './angularPanelStyles'; -import { getPageStyles } from './page'; +import { getCardStyles } from './card'; +import { getElementStyles } from './elements'; import { getMarkdownStyles } from './markdownStyles'; +import { getPageStyles } from './page'; /** @internal */ export function GlobalStyles() { diff --git a/packages/grafana-ui/src/themes/GlobalStyles/angularPanelStyles.ts b/packages/grafana-ui/src/themes/GlobalStyles/angularPanelStyles.ts index 1e9608e89c0..adb3088ac45 100644 --- a/packages/grafana-ui/src/themes/GlobalStyles/angularPanelStyles.ts +++ b/packages/grafana-ui/src/themes/GlobalStyles/angularPanelStyles.ts @@ -1,4 +1,5 @@ import { css } from '@emotion/react'; + import { GrafanaTheme2 } from '@grafana/data'; export function getAgularPanelStyles(theme: GrafanaTheme2) { diff --git a/packages/grafana-ui/src/themes/GlobalStyles/card.ts b/packages/grafana-ui/src/themes/GlobalStyles/card.ts index b3d820d2910..35b356f5e9f 100644 --- a/packages/grafana-ui/src/themes/GlobalStyles/card.ts +++ b/packages/grafana-ui/src/themes/GlobalStyles/card.ts @@ -1,4 +1,5 @@ import { css } from '@emotion/react'; + import { GrafanaTheme2 } from '@grafana/data'; export function getCardStyles(theme: GrafanaTheme2) { diff --git a/packages/grafana-ui/src/themes/GlobalStyles/elements.ts b/packages/grafana-ui/src/themes/GlobalStyles/elements.ts index 8f2580de8bb..c987a5e55e2 100644 --- a/packages/grafana-ui/src/themes/GlobalStyles/elements.ts +++ b/packages/grafana-ui/src/themes/GlobalStyles/elements.ts @@ -1,5 +1,7 @@ import { css } from '@emotion/react'; + import { GrafanaTheme2, ThemeTypographyVariant } from '@grafana/data'; + import { getFocusStyles } from '../mixins'; export function getElementStyles(theme: GrafanaTheme2) { diff --git a/packages/grafana-ui/src/themes/GlobalStyles/markdownStyles.ts b/packages/grafana-ui/src/themes/GlobalStyles/markdownStyles.ts index 41ae1a23ea9..67c096075e7 100644 --- a/packages/grafana-ui/src/themes/GlobalStyles/markdownStyles.ts +++ b/packages/grafana-ui/src/themes/GlobalStyles/markdownStyles.ts @@ -1,4 +1,5 @@ import { css } from '@emotion/react'; + import { GrafanaTheme2 } from '@grafana/data'; export function getMarkdownStyles(theme: GrafanaTheme2) { diff --git a/packages/grafana-ui/src/themes/GlobalStyles/page.ts b/packages/grafana-ui/src/themes/GlobalStyles/page.ts index 1be34dcb752..b0b961da430 100644 --- a/packages/grafana-ui/src/themes/GlobalStyles/page.ts +++ b/packages/grafana-ui/src/themes/GlobalStyles/page.ts @@ -1,4 +1,5 @@ import { css } from '@emotion/react'; + import { GrafanaTheme2 } from '@grafana/data'; export function getPageStyles(theme: GrafanaTheme2) { diff --git a/packages/grafana-ui/src/themes/ThemeContext.test.tsx b/packages/grafana-ui/src/themes/ThemeContext.test.tsx index a95f5b1c4f8..098dee97c9e 100644 --- a/packages/grafana-ui/src/themes/ThemeContext.test.tsx +++ b/packages/grafana-ui/src/themes/ThemeContext.test.tsx @@ -1,8 +1,9 @@ -import React from 'react'; -import { renderHook } from '@testing-library/react-hooks'; import { css } from '@emotion/css'; -import { mockThemeContext, useStyles } from './ThemeContext'; import { render } from '@testing-library/react'; +import { renderHook } from '@testing-library/react-hooks'; +import React from 'react'; + +import { mockThemeContext, useStyles } from './ThemeContext'; describe('useStyles', () => { it('memoizes the passed in function correctly', () => { diff --git a/packages/grafana-ui/src/themes/ThemeContext.tsx b/packages/grafana-ui/src/themes/ThemeContext.tsx index 1e0ef779ff8..be6d0f4785b 100644 --- a/packages/grafana-ui/src/themes/ThemeContext.tsx +++ b/packages/grafana-ui/src/themes/ThemeContext.tsx @@ -1,7 +1,10 @@ -import { createTheme, GrafanaTheme, GrafanaTheme2 } from '@grafana/data'; import hoistNonReactStatics from 'hoist-non-react-statics'; import React, { useContext } from 'react'; + +import { createTheme, GrafanaTheme, GrafanaTheme2 } from '@grafana/data'; + import { Themeable, Themeable2 } from '../types/theme'; + import { stylesFactory } from './stylesFactory'; type Omit = Pick>; diff --git a/packages/grafana-ui/src/themes/_variables.dark.scss.tmpl.ts b/packages/grafana-ui/src/themes/_variables.dark.scss.tmpl.ts index e4ee63b4af2..50c4b052857 100644 --- a/packages/grafana-ui/src/themes/_variables.dark.scss.tmpl.ts +++ b/packages/grafana-ui/src/themes/_variables.dark.scss.tmpl.ts @@ -1,6 +1,7 @@ /* eslint-disable max-len */ import { GrafanaTheme2 } from '@grafana/data'; + import { renderGeneratedFileBanner } from '../utils/generatedFileBanner'; export const darkThemeVarsTemplate = (theme: GrafanaTheme2) => diff --git a/packages/grafana-ui/src/themes/_variables.light.scss.tmpl.ts b/packages/grafana-ui/src/themes/_variables.light.scss.tmpl.ts index 196faabe1df..bd8887c9889 100644 --- a/packages/grafana-ui/src/themes/_variables.light.scss.tmpl.ts +++ b/packages/grafana-ui/src/themes/_variables.light.scss.tmpl.ts @@ -1,9 +1,11 @@ /* eslint-disable max-len */ -import { renderGeneratedFileBanner } from '../utils/generatedFileBanner'; -import { styleMixins } from '.'; import { GrafanaTheme2 } from '@grafana/data'; +import { renderGeneratedFileBanner } from '../utils/generatedFileBanner'; + +import { styleMixins } from '.'; + export const lightThemeVarsTemplate = (theme: GrafanaTheme2) => `${renderGeneratedFileBanner('grafana-ui/src/themes/light.ts', 'grafana-ui/src/themes/_variable.light.scss.tmpl.ts')} // Global values diff --git a/packages/grafana-ui/src/themes/_variables.scss.tmpl.ts b/packages/grafana-ui/src/themes/_variables.scss.tmpl.ts index dab9f57cc79..6d6d4cde84a 100644 --- a/packages/grafana-ui/src/themes/_variables.scss.tmpl.ts +++ b/packages/grafana-ui/src/themes/_variables.scss.tmpl.ts @@ -1,6 +1,7 @@ /* eslint-disable max-len */ import { GrafanaTheme2 } from '@grafana/data'; + import { renderGeneratedFileBanner } from '../utils/generatedFileBanner'; export const commonThemeVarsTemplate = (theme: GrafanaTheme2) => diff --git a/packages/grafana-ui/src/themes/mixins.ts b/packages/grafana-ui/src/themes/mixins.ts index 243e582f42c..b57cdbe8b21 100644 --- a/packages/grafana-ui/src/themes/mixins.ts +++ b/packages/grafana-ui/src/themes/mixins.ts @@ -1,7 +1,8 @@ import { CSSObject } from '@emotion/css'; -import { GrafanaTheme, GrafanaTheme2 } from '@grafana/data'; import tinycolor from 'tinycolor2'; +import { GrafanaTheme, GrafanaTheme2 } from '@grafana/data'; + export function cardChrome(theme: GrafanaTheme2): string { return ` background: ${theme.colors.background.secondary}; diff --git a/packages/grafana-ui/src/themes/selectThemeVariant.test.ts b/packages/grafana-ui/src/themes/selectThemeVariant.test.ts index 4057488320f..974e3cc8889 100644 --- a/packages/grafana-ui/src/themes/selectThemeVariant.test.ts +++ b/packages/grafana-ui/src/themes/selectThemeVariant.test.ts @@ -1,5 +1,7 @@ import { GrafanaThemeType } from '@grafana/data'; + import { selectThemeVariant } from './selectThemeVariant'; + import { mockTheme } from './index'; const lightThemeMock = { diff --git a/packages/grafana-ui/src/types/completion.ts b/packages/grafana-ui/src/types/completion.ts index 1855889ff1e..f8e012eab81 100644 --- a/packages/grafana-ui/src/types/completion.ts +++ b/packages/grafana-ui/src/types/completion.ts @@ -1,4 +1,5 @@ import { Value, Editor as CoreEditor } from 'slate'; + import { SearchFunctionType } from '../utils'; /** diff --git a/packages/grafana-ui/src/types/icon.ts b/packages/grafana-ui/src/types/icon.ts index 870cf8b2d82..0aee8ac145e 100644 --- a/packages/grafana-ui/src/types/icon.ts +++ b/packages/grafana-ui/src/types/icon.ts @@ -1,4 +1,5 @@ import { Field, FieldType } from '@grafana/data'; + import { ComponentSize } from './size'; export type IconType = 'mono' | 'default' | 'solid'; export type IconSize = ComponentSize | 'xl' | 'xxl' | 'xxxl'; diff --git a/packages/grafana-ui/src/utils/dataLinks.ts b/packages/grafana-ui/src/utils/dataLinks.ts index b99e50e089d..42c57622e08 100644 --- a/packages/grafana-ui/src/utils/dataLinks.ts +++ b/packages/grafana-ui/src/utils/dataLinks.ts @@ -1,4 +1,5 @@ import { LinkModel } from '@grafana/data'; + import { MenuItemProps } from '../components/Menu/MenuItem'; import { IconName } from '../types'; diff --git a/packages/grafana-ui/src/utils/fuzzy.ts b/packages/grafana-ui/src/utils/fuzzy.ts index 69d47d5167f..418a9efe182 100644 --- a/packages/grafana-ui/src/utils/fuzzy.ts +++ b/packages/grafana-ui/src/utils/fuzzy.ts @@ -1,6 +1,7 @@ -import { HighlightPart } from '../types'; import { last } from 'lodash'; +import { HighlightPart } from '../types'; + type FuzzyMatch = { /** * Total number of unmatched letters between matched letters diff --git a/packages/grafana-ui/src/utils/index.ts b/packages/grafana-ui/src/utils/index.ts index cecdb086f2b..b4ec365d717 100644 --- a/packages/grafana-ui/src/utils/index.ts +++ b/packages/grafana-ui/src/utils/index.ts @@ -1,3 +1,6 @@ +import * as DOMUtil from './dom'; // includes Element.closest polyfill +import * as ReactUtils from './reactUtils'; + export * from './colors'; export * from './validate'; export * from './slate'; @@ -10,7 +13,6 @@ export * from './useForceUpdate'; export { SearchFunctionType } from './searchFunctions'; export { ansicolor } from 'ansicolor'; -import * as DOMUtil from './dom'; // includes Element.closest polyfill export { DOMUtil }; export { createLogger } from './logger'; @@ -18,6 +20,4 @@ export { attachDebugger } from './debug'; export * from './nodeGraph'; export { fuzzyMatch } from './fuzzy'; -// React utils -import * as ReactUtils from './reactUtils'; export { ReactUtils }; diff --git a/packages/grafana-ui/src/utils/searchFunctions.ts b/packages/grafana-ui/src/utils/searchFunctions.ts index 677b2d06454..02cce0ff35f 100644 --- a/packages/grafana-ui/src/utils/searchFunctions.ts +++ b/packages/grafana-ui/src/utils/searchFunctions.ts @@ -1,4 +1,5 @@ import { CompletionItem, SearchFunction } from '../types'; + import { fuzzyMatch } from './fuzzy'; /** diff --git a/packages/grafana-ui/src/utils/standardEditors.tsx b/packages/grafana-ui/src/utils/standardEditors.tsx index 065c1812113..07948c2ae54 100644 --- a/packages/grafana-ui/src/utils/standardEditors.tsx +++ b/packages/grafana-ui/src/utils/standardEditors.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { DataLink, dataLinksOverrideProcessor, @@ -19,7 +20,6 @@ import { FieldNamePickerConfigSettings, } from '@grafana/data'; -import { Switch } from '../components/Switch/Switch'; import { NumberValueEditor, SliderValueEditor, @@ -30,12 +30,13 @@ import { MultiSelectValueEditor, TimeZonePicker, } from '../components'; -import { UnitValueEditor } from '../components/OptionsUI/units'; -import { DataLinksValueEditor } from '../components/OptionsUI/links'; +import { FieldNamePicker } from '../components/MatchersUI/FieldNamePicker'; import { ColorValueEditor } from '../components/OptionsUI/color'; import { FieldColorEditor } from '../components/OptionsUI/fieldColor'; +import { DataLinksValueEditor } from '../components/OptionsUI/links'; import { StatsPickerEditor } from '../components/OptionsUI/stats'; -import { FieldNamePicker } from '../components/MatchersUI/FieldNamePicker'; +import { UnitValueEditor } from '../components/OptionsUI/units'; +import { Switch } from '../components/Switch/Switch'; /** * Returns collection of common field config properties definitions diff --git a/packages/grafana-ui/src/utils/storybook/DashboardStoryCanvas.tsx b/packages/grafana-ui/src/utils/storybook/DashboardStoryCanvas.tsx index 9a7adfdfc9a..435d1158c3d 100644 --- a/packages/grafana-ui/src/utils/storybook/DashboardStoryCanvas.tsx +++ b/packages/grafana-ui/src/utils/storybook/DashboardStoryCanvas.tsx @@ -1,5 +1,6 @@ -import React, { FC } from 'react'; import { css } from '@emotion/css'; +import React, { FC } from 'react'; + import { useTheme } from '../../themes'; export interface Props { diff --git a/packages/grafana-ui/src/utils/storybook/StoryExample.tsx b/packages/grafana-ui/src/utils/storybook/StoryExample.tsx index 432cd7ddb50..192d4130357 100644 --- a/packages/grafana-ui/src/utils/storybook/StoryExample.tsx +++ b/packages/grafana-ui/src/utils/storybook/StoryExample.tsx @@ -1,5 +1,6 @@ -import React, { FC } from 'react'; import { css } from '@emotion/css'; +import React, { FC } from 'react'; + import { useTheme } from '../../themes/ThemeContext'; export interface Props { diff --git a/packages/grafana-ui/src/utils/storybook/ThemedDocsContainer.tsx b/packages/grafana-ui/src/utils/storybook/ThemedDocsContainer.tsx index 9fffdc9cbf4..095d1f3ed25 100644 --- a/packages/grafana-ui/src/utils/storybook/ThemedDocsContainer.tsx +++ b/packages/grafana-ui/src/utils/storybook/ThemedDocsContainer.tsx @@ -1,8 +1,9 @@ // This is a temporary workaround to allow theme switching storybook docs // see https://github.com/storybookjs/storybook/issues/10523 for further details -import React from 'react'; import { DocsContainer } from '@storybook/addon-docs/blocks'; +import React from 'react'; import { useDarkMode } from 'storybook-dark-mode'; + import { GrafanaLight, GrafanaDark } from '../../../.storybook/storybookTheme'; type Props = { diff --git a/packages/grafana-ui/src/utils/storybook/UseState.tsx b/packages/grafana-ui/src/utils/storybook/UseState.tsx index 7e8340b979e..69d6667d135 100644 --- a/packages/grafana-ui/src/utils/storybook/UseState.tsx +++ b/packages/grafana-ui/src/utils/storybook/UseState.tsx @@ -1,5 +1,5 @@ -import React from 'react'; import { action } from '@storybook/addon-actions'; +import React from 'react'; interface StateHolderProps { logState?: boolean; diff --git a/packages/grafana-ui/src/utils/storybook/knobs.ts b/packages/grafana-ui/src/utils/storybook/knobs.ts index 03f729bbb3e..f9fe8152b69 100644 --- a/packages/grafana-ui/src/utils/storybook/knobs.ts +++ b/packages/grafana-ui/src/utils/storybook/knobs.ts @@ -1,4 +1,5 @@ import { select } from '@storybook/addon-knobs'; + import { getAvailableIcons } from '../../types'; const VISUAL_GROUP = 'Visual options'; diff --git a/packages/grafana-ui/src/utils/storybook/withCenteredStory.tsx b/packages/grafana-ui/src/utils/storybook/withCenteredStory.tsx index a30350c96ab..c8937f5c648 100644 --- a/packages/grafana-ui/src/utils/storybook/withCenteredStory.tsx +++ b/packages/grafana-ui/src/utils/storybook/withCenteredStory.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { RenderFunction } from '../../types'; interface CenteredStoryProps { diff --git a/packages/grafana-ui/src/utils/storybook/withPaddedStory.tsx b/packages/grafana-ui/src/utils/storybook/withPaddedStory.tsx index f5778b35814..a26f6f4f3ce 100644 --- a/packages/grafana-ui/src/utils/storybook/withPaddedStory.tsx +++ b/packages/grafana-ui/src/utils/storybook/withPaddedStory.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { GlobalStyles, useTheme2 } from '../../themes'; import { RenderFunction } from '../../types'; diff --git a/packages/grafana-ui/src/utils/storybook/withRightAlignedStory.tsx b/packages/grafana-ui/src/utils/storybook/withRightAlignedStory.tsx index 44e238e6eb9..9168ad1014b 100644 --- a/packages/grafana-ui/src/utils/storybook/withRightAlignedStory.tsx +++ b/packages/grafana-ui/src/utils/storybook/withRightAlignedStory.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { RenderFunction } from '../../types'; const RightAlignedStory: React.FunctionComponent<{}> = ({ children }) => { diff --git a/packages/grafana-ui/src/utils/storybook/withStoryContainer.tsx b/packages/grafana-ui/src/utils/storybook/withStoryContainer.tsx index b13c0ecd42a..ac836367e4b 100644 --- a/packages/grafana-ui/src/utils/storybook/withStoryContainer.tsx +++ b/packages/grafana-ui/src/utils/storybook/withStoryContainer.tsx @@ -1,7 +1,8 @@ -import React from 'react'; import { css, cx } from '@emotion/css'; -import { RenderFunction } from '../../types'; import { StoryContext } from '@storybook/react'; +import React from 'react'; + +import { RenderFunction } from '../../types'; const StoryContainer: React.FC<{ width?: number; height?: number; showBoundaries: boolean }> = ({ children, diff --git a/packages/grafana-ui/src/utils/storybook/withTheme.tsx b/packages/grafana-ui/src/utils/storybook/withTheme.tsx index b6a23326e6f..2580acf3b6b 100644 --- a/packages/grafana-ui/src/utils/storybook/withTheme.tsx +++ b/packages/grafana-ui/src/utils/storybook/withTheme.tsx @@ -1,9 +1,11 @@ import React from 'react'; -import { ThemeContext } from '../../themes/ThemeContext'; -import { createTheme, GrafanaTheme2 } from '@grafana/data'; -import { RenderFunction } from '../../types'; import { useDarkMode } from 'storybook-dark-mode'; + +import { createTheme, GrafanaTheme2 } from '@grafana/data'; + import { GlobalStyles } from '../../themes/GlobalStyles/GlobalStyles'; +import { ThemeContext } from '../../themes/ThemeContext'; +import { RenderFunction } from '../../types'; type SassThemeChangeHandler = (theme: GrafanaTheme2) => void; const ThemeableStory: React.FunctionComponent<{ handleSassThemeChange: SassThemeChangeHandler }> = ({ diff --git a/packages/grafana-ui/src/utils/table.ts b/packages/grafana-ui/src/utils/table.ts index b70bc6af1bc..80d346ab27c 100644 --- a/packages/grafana-ui/src/utils/table.ts +++ b/packages/grafana-ui/src/utils/table.ts @@ -1,7 +1,8 @@ -import { Field, LinkModel } from '@grafana/data'; import { MouseEventHandler } from 'react'; import { Row } from 'react-table'; +import { Field, LinkModel } from '@grafana/data'; + /** * @internal */ diff --git a/packages/grafana-ui/src/utils/typeahead.ts b/packages/grafana-ui/src/utils/typeahead.ts index 980cbe63a61..856b4f8d305 100644 --- a/packages/grafana-ui/src/utils/typeahead.ts +++ b/packages/grafana-ui/src/utils/typeahead.ts @@ -1,7 +1,9 @@ import { default as calculateSize } from 'calculate-size'; -import { CompletionItemGroup, CompletionItem, CompletionItemKind } from '../types/completion'; + import { GrafanaTheme } from '@grafana/data'; +import { CompletionItemGroup, CompletionItem, CompletionItemKind } from '../types/completion'; + export const flattenGroupItems = (groupedItems: CompletionItemGroup[]): CompletionItem[] => { return groupedItems.reduce((all: CompletionItem[], { items, label }) => { all.push({ diff --git a/packages/grafana-ui/src/utils/useDelayedSwitch.story.internal.tsx b/packages/grafana-ui/src/utils/useDelayedSwitch.story.internal.tsx index ef26cf70384..df5204f74b7 100644 --- a/packages/grafana-ui/src/utils/useDelayedSwitch.story.internal.tsx +++ b/packages/grafana-ui/src/utils/useDelayedSwitch.story.internal.tsx @@ -1,8 +1,8 @@ +import { Story } from '@storybook/react'; import React from 'react'; import { withCenteredStory } from './storybook/withCenteredStory'; import { useDelayedSwitch } from './useDelayedSwitch'; -import { Story } from '@storybook/react'; export default { title: 'useDelayedSwitch', diff --git a/packages/jaeger-ui-components/src/ScrollManager.test.js b/packages/jaeger-ui-components/src/ScrollManager.test.js index 273b3b9d3e1..f09cebe7c25 100644 --- a/packages/jaeger-ui-components/src/ScrollManager.test.js +++ b/packages/jaeger-ui-components/src/ScrollManager.test.js @@ -14,8 +14,8 @@ jest.mock('./scroll-page'); -import { scrollBy, scrollTo } from './scroll-page'; import ScrollManager from './ScrollManager'; +import { scrollBy, scrollTo } from './scroll-page'; const SPAN_HEIGHT = 2; diff --git a/packages/jaeger-ui-components/src/Theme.tsx b/packages/jaeger-ui-components/src/Theme.tsx index 45cc4847a63..e0213d6ba0f 100644 --- a/packages/jaeger-ui-components/src/Theme.tsx +++ b/packages/jaeger-ui-components/src/Theme.tsx @@ -13,6 +13,7 @@ // limitations under the License. import tinycolor from 'tinycolor2'; + import { GrafanaTheme2 } from '@grafana/data'; /** diff --git a/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/CanvasSpanGraph.test.js b/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/CanvasSpanGraph.test.js index 6799d5290e6..cdb5e943cf0 100644 --- a/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/CanvasSpanGraph.test.js +++ b/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/CanvasSpanGraph.test.js @@ -12,8 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; import { shallow } from 'enzyme'; +import React from 'react'; + import { createTheme } from '@grafana/data'; import { UnthemedCanvasSpanGraph } from './CanvasSpanGraph'; diff --git a/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/CanvasSpanGraph.tsx b/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/CanvasSpanGraph.tsx index 2e62d4ad3b8..a0454c80009 100644 --- a/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/CanvasSpanGraph.tsx +++ b/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/CanvasSpanGraph.tsx @@ -12,16 +12,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -import * as React from 'react'; import { css } from '@emotion/css'; +import * as React from 'react'; -import renderIntoCanvas from './render-into-canvas'; -import { getRgbColorByKey } from '../../utils/color-generator'; -import { TNil } from '../../types'; +import { GrafanaTheme2 } from '@grafana/data'; +import { withTheme2, stylesFactory } from '@grafana/ui'; import { autoColor } from '../../Theme'; -import { withTheme2, stylesFactory } from '@grafana/ui'; -import { GrafanaTheme2 } from '@grafana/data'; +import { TNil } from '../../types'; +import { getRgbColorByKey } from '../../utils/color-generator'; + +import renderIntoCanvas from './render-into-canvas'; const getStyles = stylesFactory((theme: GrafanaTheme2) => { return { diff --git a/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/GraphTicks.test.js b/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/GraphTicks.test.js index 9f1352dfcb2..77736bee6e0 100644 --- a/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/GraphTicks.test.js +++ b/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/GraphTicks.test.js @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; import { shallow } from 'enzyme'; +import React from 'react'; import GraphTicks from './GraphTicks'; diff --git a/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/GraphTicks.tsx b/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/GraphTicks.tsx index d69c82e17ad..145db1bf459 100644 --- a/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/GraphTicks.tsx +++ b/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/GraphTicks.tsx @@ -12,8 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; import { css } from '@emotion/css'; +import React from 'react'; + import { useStyles2 } from '@grafana/ui'; const getStyles = () => { diff --git a/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/Scrubber.test.js b/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/Scrubber.test.js index afe6525f464..88943f3dd27 100644 --- a/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/Scrubber.test.js +++ b/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/Scrubber.test.js @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; import { shallow } from 'enzyme'; +import React from 'react'; import sinon from 'sinon'; import Scrubber, { getStyles } from './Scrubber'; diff --git a/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/Scrubber.tsx b/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/Scrubber.tsx index 9242819e1fa..b4cd86699d4 100644 --- a/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/Scrubber.tsx +++ b/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/Scrubber.tsx @@ -12,9 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; -import cx from 'classnames'; import { css } from '@emotion/css'; +import cx from 'classnames'; +import React from 'react'; + import { useStyles2 } from '@grafana/ui'; export const getStyles = () => { diff --git a/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/TickLabels.test.js b/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/TickLabels.test.js index 619a0ee8b9d..595b5da7586 100644 --- a/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/TickLabels.test.js +++ b/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/TickLabels.test.js @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; import { shallow } from 'enzyme'; +import React from 'react'; import TickLabels from './TickLabels'; diff --git a/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/TickLabels.tsx b/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/TickLabels.tsx index 188b36cc900..6a81881a257 100644 --- a/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/TickLabels.tsx +++ b/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/TickLabels.tsx @@ -12,8 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; import { css } from '@emotion/css'; +import React from 'react'; + import { useStyles2 } from '@grafana/ui'; import { formatDuration } from '../../utils/date'; diff --git a/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/ViewingLayer.test.js b/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/ViewingLayer.test.js index 3530d9602a3..b65184021ed 100644 --- a/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/ViewingLayer.test.js +++ b/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/ViewingLayer.test.js @@ -14,13 +14,15 @@ import { shallow } from 'enzyme'; import React from 'react'; + import { createTheme } from '@grafana/data'; +import { EUpdateTypes } from '../../utils/DraggableManager'; +import { polyfill as polyfillAnimationFrame } from '../../utils/test/requestAnimationFrame'; + import GraphTicks from './GraphTicks'; import Scrubber from './Scrubber'; import ViewingLayer, { dragTypes, getStyles } from './ViewingLayer'; -import { EUpdateTypes } from '../../utils/DraggableManager'; -import { polyfill as polyfillAnimationFrame } from '../../utils/test/requestAnimationFrame'; function getViewRange(viewStart, viewEnd) { return { diff --git a/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/ViewingLayer.tsx b/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/ViewingLayer.tsx index 722fbc8a7d9..e4090032a4c 100644 --- a/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/ViewingLayer.tsx +++ b/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/ViewingLayer.tsx @@ -12,18 +12,20 @@ // See the License for the specific language governing permissions and // limitations under the License. +import { css } from '@emotion/css'; import cx from 'classnames'; import * as React from 'react'; -import { css } from '@emotion/css'; + import { GrafanaTheme2 } from '@grafana/data'; import { withTheme2, stylesFactory, Button } from '@grafana/ui'; -import GraphTicks from './GraphTicks'; -import Scrubber from './Scrubber'; import { TUpdateViewRangeTimeFunction, ViewRange, ViewRangeTimeUpdate, TNil } from '../..'; import { autoColor } from '../../Theme'; import DraggableManager, { DraggableBounds, DraggingUpdate, EUpdateTypes } from '../../utils/DraggableManager'; +import GraphTicks from './GraphTicks'; +import Scrubber from './Scrubber'; + export const getStyles = stylesFactory((theme: GrafanaTheme2) => { // Need this cause emotion will merge emotion generated classes into single className if used with cx from emotion // package and the selector won't work diff --git a/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/index.test.js b/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/index.test.js index 4ef74638ee6..d76f4aab944 100644 --- a/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/index.test.js +++ b/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/index.test.js @@ -12,17 +12,19 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; import { shallow } from 'enzyme'; +import React from 'react'; -import CanvasSpanGraph from './CanvasSpanGraph'; -import SpanGraph from './index'; -import TickLabels from './TickLabels'; -import ViewingLayer from './ViewingLayer'; import traceGenerator from '../../demo/trace-generators'; import transformTraceData from '../../model/transform-trace-data'; import { polyfill as polyfillAnimationFrame } from '../../utils/test/requestAnimationFrame'; +import CanvasSpanGraph from './CanvasSpanGraph'; +import TickLabels from './TickLabels'; +import ViewingLayer from './ViewingLayer'; + +import SpanGraph from './index'; + describe('', () => { polyfillAnimationFrame(window); diff --git a/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/index.tsx b/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/index.tsx index 4ddae074538..6bab52a4b67 100644 --- a/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/index.tsx +++ b/packages/jaeger-ui-components/src/TracePageHeader/SpanGraph/index.tsx @@ -12,16 +12,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -import * as React from 'react'; import cx from 'classnames'; import memoizeOne from 'memoize-one'; +import * as React from 'react'; + +import { TUpdateViewRangeTimeFunction, ViewRange, ViewRangeTimeUpdate } from '../..'; +import { TraceSpan, Trace } from '../../types/trace'; +import { ubPb2, ubPx2, ubRelative } from '../../uberUtilityStyles'; import CanvasSpanGraph from './CanvasSpanGraph'; import TickLabels from './TickLabels'; import ViewingLayer from './ViewingLayer'; -import { TUpdateViewRangeTimeFunction, ViewRange, ViewRangeTimeUpdate } from '../..'; -import { TraceSpan, Trace } from '../../types/trace'; -import { ubPb2, ubPx2, ubRelative } from '../../uberUtilityStyles'; const DEFAULT_HEIGHT = 60; const TIMELINE_TICK_INTERVAL = 4; diff --git a/packages/jaeger-ui-components/src/TracePageHeader/TracePageHeader.test.js b/packages/jaeger-ui-components/src/TracePageHeader/TracePageHeader.test.js index e455fa1f360..e5542b5ea76 100644 --- a/packages/jaeger-ui-components/src/TracePageHeader/TracePageHeader.test.js +++ b/packages/jaeger-ui-components/src/TracePageHeader/TracePageHeader.test.js @@ -12,16 +12,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; import { shallow, mount } from 'enzyme'; +import React from 'react'; -import SpanGraph from './SpanGraph'; -import TracePageHeader, { HEADER_ITEMS } from './TracePageHeader'; import LabeledList from '../common/LabeledList'; import traceGenerator from '../demo/trace-generators'; import { getTraceName } from '../model/trace-viewer'; import transformTraceData from '../model/transform-trace-data'; +import SpanGraph from './SpanGraph'; +import TracePageHeader, { HEADER_ITEMS } from './TracePageHeader'; + describe('', () => { const trace = transformTraceData(traceGenerator.trace({})); const defaultProps = { diff --git a/packages/jaeger-ui-components/src/TracePageHeader/TracePageHeader.tsx b/packages/jaeger-ui-components/src/TracePageHeader/TracePageHeader.tsx index 2deb6921592..dd476a85046 100644 --- a/packages/jaeger-ui-components/src/TracePageHeader/TracePageHeader.tsx +++ b/packages/jaeger-ui-components/src/TracePageHeader/TracePageHeader.tsx @@ -12,25 +12,26 @@ // See the License for the specific language governing permissions and // limitations under the License. -import * as React from 'react'; -import { get as _get, maxBy as _maxBy, values as _values } from 'lodash'; -import MdKeyboardArrowRight from 'react-icons/lib/md/keyboard-arrow-right'; import { css } from '@emotion/css'; import cx from 'classnames'; +import { get as _get, maxBy as _maxBy, values as _values } from 'lodash'; +import * as React from 'react'; +import MdKeyboardArrowRight from 'react-icons/lib/md/keyboard-arrow-right'; + import { dateTimeFormat, GrafanaTheme2, TimeZone } from '@grafana/data'; import { useStyles2 } from '@grafana/ui'; -import SpanGraph from './SpanGraph'; import { autoColor, TUpdateViewRangeTimeFunction, ViewRange, ViewRangeTimeUpdate } from '..'; +import ExternalLinks from '../common/ExternalLinks'; import LabeledList from '../common/LabeledList'; import TraceName from '../common/TraceName'; +import { getTraceLinks } from '../model/link-patterns'; import { getTraceName } from '../model/trace-viewer'; import { Trace } from '../types/trace'; -import { formatDuration } from '../utils/date'; -import { getTraceLinks } from '../model/link-patterns'; - -import ExternalLinks from '../common/ExternalLinks'; import { uTxMuted } from '../uberUtilityStyles'; +import { formatDuration } from '../utils/date'; + +import SpanGraph from './SpanGraph'; const getStyles = (theme: GrafanaTheme2) => { return { diff --git a/packages/jaeger-ui-components/src/TracePageHeader/TracePageSearchBar.test.js b/packages/jaeger-ui-components/src/TracePageHeader/TracePageSearchBar.test.js index 47b4e916cde..d7cf4baff07 100644 --- a/packages/jaeger-ui-components/src/TracePageHeader/TracePageSearchBar.test.js +++ b/packages/jaeger-ui-components/src/TracePageHeader/TracePageSearchBar.test.js @@ -12,14 +12,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; import { shallow } from 'enzyme'; +import React from 'react'; + import { createTheme } from '@grafana/data'; -import * as markers from './TracePageSearchBar.markers'; -import TracePageSearchBar, { getStyles } from './TracePageSearchBar'; import UiFindInput from '../common/UiFindInput'; +import TracePageSearchBar, { getStyles } from './TracePageSearchBar'; +import * as markers from './TracePageSearchBar.markers'; + const defaultProps = { forwardedRef: React.createRef(), navigable: true, diff --git a/packages/jaeger-ui-components/src/TracePageHeader/TracePageSearchBar.tsx b/packages/jaeger-ui-components/src/TracePageHeader/TracePageSearchBar.tsx index 4eef52b5ef0..cfa1e99a544 100644 --- a/packages/jaeger-ui-components/src/TracePageHeader/TracePageSearchBar.tsx +++ b/packages/jaeger-ui-components/src/TracePageHeader/TracePageSearchBar.tsx @@ -12,18 +12,19 @@ // See the License for the specific language governing permissions and // limitations under the License. -import * as React from 'react'; -import cx from 'classnames'; import { css } from '@emotion/css'; +import cx from 'classnames'; +import * as React from 'react'; +import { memo } from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; import { Button, useStyles2 } from '@grafana/ui'; -import * as markers from './TracePageSearchBar.markers'; import UiFindInput from '../common/UiFindInput'; - import { ubFlexAuto, ubJustifyEnd } from '../uberUtilityStyles'; + +import * as markers from './TracePageSearchBar.markers'; // eslint-disable-next-line no-duplicate-imports -import { memo } from 'react'; -import { GrafanaTheme2 } from '@grafana/data'; export const getStyles = (theme: GrafanaTheme2) => { return { diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/ListView/index.test.js b/packages/jaeger-ui-components/src/TraceTimelineViewer/ListView/index.test.js index e7da72adffa..55fa6848dfa 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/ListView/index.test.js +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/ListView/index.test.js @@ -12,11 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; import { mount, shallow } from 'enzyme'; +import React from 'react'; + +import { polyfill as polyfillAnimationFrame } from '../../utils/test/requestAnimationFrame'; import ListView from './index'; -import { polyfill as polyfillAnimationFrame } from '../../utils/test/requestAnimationFrame'; // Util to get list of all callbacks added to an event emitter by event type. // jest adds "error" event listeners to window, this util makes it easier to diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/ListView/index.tsx b/packages/jaeger-ui-components/src/TraceTimelineViewer/ListView/index.tsx index 810a6218784..57bd8f51c92 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/ListView/index.tsx +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/ListView/index.tsx @@ -14,9 +14,10 @@ import * as React from 'react'; -import Positions from './Positions'; import { TNil } from '../../types'; +import Positions from './Positions'; + type TWrapperProps = { style: React.CSSProperties; ref: (elm: HTMLDivElement) => void; diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/ReferencesButton.test.js b/packages/jaeger-ui-components/src/TraceTimelineViewer/ReferencesButton.test.js index c3c85134c44..bb464b2388a 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/ReferencesButton.test.js +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/ReferencesButton.test.js @@ -12,15 +12,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; import { shallow } from 'enzyme'; +import React from 'react'; + import { Tooltip } from '@grafana/ui'; -import ReferencesButton, { getStyles } from './ReferencesButton'; -import transformTraceData from '../model/transform-trace-data'; import traceGenerator from '../demo/trace-generators'; +import transformTraceData from '../model/transform-trace-data'; import ReferenceLink from '../url/ReferenceLink'; +import ReferencesButton, { getStyles } from './ReferencesButton'; + describe(ReferencesButton, () => { const trace = transformTraceData(traceGenerator.trace({ numberOfSpans: 10 })); const oneReference = trace.spans[1].references; diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/ReferencesButton.tsx b/packages/jaeger-ui-components/src/TraceTimelineViewer/ReferencesButton.tsx index f48b86a243b..96456f43cf7 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/ReferencesButton.tsx +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/ReferencesButton.tsx @@ -12,8 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; import { css } from '@emotion/css'; +import React from 'react'; + import { Tooltip, useStyles2 } from '@grafana/ui'; import { TraceSpanReference } from '../types/trace'; diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanBar.test.js b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanBar.test.js index 70cc7b87420..70c745183f6 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanBar.test.js +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanBar.test.js @@ -12,9 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; import { mount } from 'enzyme'; +import React from 'react'; import { act } from 'react-dom/test-utils'; + import { Popover } from '../common/Popover'; import SpanBar from './SpanBar'; diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanBar.tsx b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanBar.tsx index 097bd362bda..ed41d2c4416 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanBar.tsx +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanBar.tsx @@ -12,18 +12,21 @@ // See the License for the specific language governing permissions and // limitations under the License. -import cx from 'classnames'; import { css } from '@emotion/css'; +import cx from 'classnames'; import { groupBy as _groupBy } from 'lodash'; import React, { useState } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { useStyles2 } from '@grafana/ui'; + import { autoColor } from '../Theme'; -import { TraceSpan } from '../types/trace'; +import { Popover } from '../common/Popover'; import { TNil } from '../types'; +import { TraceSpan } from '../types/trace'; + import AccordianLogs from './SpanDetail/AccordianLogs'; import { ViewedBoundsFunctionType } from './utils'; -import { Popover } from '../common/Popover'; const getStyles = (theme: GrafanaTheme2) => { return { diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanBarRow.test.js b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanBarRow.test.js index 6c6c2ff78c3..104bdb2a02a 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanBarRow.test.js +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanBarRow.test.js @@ -12,12 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; import { mount, shallow } from 'enzyme'; +import React from 'react'; +import ReferencesButton from './ReferencesButton'; import SpanBarRow from './SpanBarRow'; import SpanTreeOffset from './SpanTreeOffset'; -import ReferencesButton from './ReferencesButton'; jest.mock('./SpanTreeOffset', () => { // eslint-disable-next-line react/display-name diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanBarRow.tsx b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanBarRow.tsx index 10321578de1..9239a0e1f32 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanBarRow.tsx +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanBarRow.tsx @@ -12,26 +12,26 @@ // See the License for the specific language governing permissions and // limitations under the License. +import { css, keyframes } from '@emotion/css'; +import cx from 'classnames'; import * as React from 'react'; - import IoAlert from 'react-icons/lib/io/alert'; import IoArrowRightA from 'react-icons/lib/io/arrow-right-a'; import MdFileUpload from 'react-icons/lib/md/file-upload'; -import { css, keyframes } from '@emotion/css'; -import cx from 'classnames'; -import { Icon, stylesFactory, withTheme2 } from '@grafana/ui'; + import { GrafanaTheme2 } from '@grafana/data'; +import { Icon, stylesFactory, withTheme2 } from '@grafana/ui'; -import ReferencesButton from './ReferencesButton'; -import TimelineRow from './TimelineRow'; -import { formatDuration, ViewedBoundsFunctionType } from './utils'; -import SpanTreeOffset from './SpanTreeOffset'; -import SpanBar from './SpanBar'; -import Ticks from './Ticks'; - +import { autoColor } from '../Theme'; import { SpanLinkFunc, TNil } from '../types'; import { TraceSpan } from '../types/trace'; -import { autoColor } from '../Theme'; + +import ReferencesButton from './ReferencesButton'; +import SpanBar from './SpanBar'; +import SpanTreeOffset from './SpanTreeOffset'; +import Ticks from './Ticks'; +import TimelineRow from './TimelineRow'; +import { formatDuration, ViewedBoundsFunctionType } from './utils'; const spanBarClassName = 'spanBar'; const spanBarLabelClassName = 'spanBarLabel'; diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianKeyValues.test.js b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianKeyValues.test.js index 047cfd114df..c5661b11986 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianKeyValues.test.js +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianKeyValues.test.js @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; import { shallow } from 'enzyme'; +import React from 'react'; import AccordianKeyValues, { KeyValuesSummary } from './AccordianKeyValues'; import * as markers from './AccordianKeyValues.markers'; diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianKeyValues.tsx b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianKeyValues.tsx index 909b5c3f366..87ee8a16987 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianKeyValues.tsx +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianKeyValues.tsx @@ -12,20 +12,22 @@ // See the License for the specific language governing permissions and // limitations under the License. +import { css } from '@emotion/css'; +import cx from 'classnames'; import * as React from 'react'; import IoIosArrowDown from 'react-icons/lib/io/ios-arrow-down'; import IoIosArrowRight from 'react-icons/lib/io/ios-arrow-right'; -import { css } from '@emotion/css'; -import cx from 'classnames'; + +import { GrafanaTheme2 } from '@grafana/data'; +import { useStyles2 } from '@grafana/ui'; + +import { autoColor } from '../../Theme'; +import { TNil } from '../../types'; +import { TraceKeyValuePair, TraceLink } from '../../types/trace'; +import { uAlignIcon, uTxEllipsis } from '../../uberUtilityStyles'; import * as markers from './AccordianKeyValues.markers'; import KeyValuesTable from './KeyValuesTable'; -import { TNil } from '../../types'; -import { TraceKeyValuePair, TraceLink } from '../../types/trace'; -import { autoColor } from '../../Theme'; -import { uAlignIcon, uTxEllipsis } from '../../uberUtilityStyles'; -import { useStyles2 } from '@grafana/ui'; -import { GrafanaTheme2 } from '@grafana/data'; export const getStyles = (theme: GrafanaTheme2) => { return { diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianLogs.test.js b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianLogs.test.js index c1d37ed98ba..3d05c9505d5 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianLogs.test.js +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianLogs.test.js @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; import { shallow } from 'enzyme'; +import React from 'react'; import AccordianKeyValues from './AccordianKeyValues'; import AccordianLogs from './AccordianLogs'; diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianLogs.tsx b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianLogs.tsx index 1a0c812dd7f..268f617802b 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianLogs.tsx +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianLogs.tsx @@ -12,20 +12,22 @@ // See the License for the specific language governing permissions and // limitations under the License. -import * as React from 'react'; +import { css } from '@emotion/css'; import { sortBy as _sortBy } from 'lodash'; +import * as React from 'react'; import IoIosArrowDown from 'react-icons/lib/io/ios-arrow-down'; import IoIosArrowRight from 'react-icons/lib/io/ios-arrow-right'; -import { css } from '@emotion/css'; + import { GrafanaTheme2 } from '@grafana/data'; import { useStyles2 } from '@grafana/ui'; -import AccordianKeyValues from './AccordianKeyValues'; -import { formatDuration } from '../utils'; +import { autoColor } from '../../Theme'; import { TNil } from '../../types'; import { TraceLog, TraceKeyValuePair, TraceLink } from '../../types/trace'; -import { autoColor } from '../../Theme'; import { uAlignIcon, ubMb1 } from '../../uberUtilityStyles'; +import { formatDuration } from '../utils'; + +import AccordianKeyValues from './AccordianKeyValues'; const getStyles = (theme: GrafanaTheme2) => { return { diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianReferences.test.js b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianReferences.test.js index b69fda5e9e2..956125c6479 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianReferences.test.js +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianReferences.test.js @@ -12,11 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; import { shallow } from 'enzyme'; -import AccordianReferences, { References } from './AccordianReferences'; +import React from 'react'; + import ReferenceLink from '../../url/ReferenceLink'; +import AccordianReferences, { References } from './AccordianReferences'; + const traceID = 'trace1'; const references = [ { diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianReferences.tsx b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianReferences.tsx index cf5d11a36e5..7018b61692f 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianReferences.tsx +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianReferences.tsx @@ -12,18 +12,20 @@ // See the License for the specific language governing permissions and // limitations under the License. -import * as React from 'react'; import { css, cx } from '@emotion/css'; -import { Icon, useStyles2 } from '@grafana/ui'; - -import AccordianKeyValues from './AccordianKeyValues'; +import * as React from 'react'; import IoIosArrowDown from 'react-icons/lib/io/ios-arrow-down'; import IoIosArrowRight from 'react-icons/lib/io/ios-arrow-right'; -import { TraceSpanReference } from '../../types/trace'; -import ReferenceLink from '../../url/ReferenceLink'; -import { uAlignIcon, ubMb1 } from '../../uberUtilityStyles'; + import { GrafanaTheme2 } from '@grafana/data'; +import { Icon, useStyles2 } from '@grafana/ui'; + import { autoColor } from '../../Theme'; +import { TraceSpanReference } from '../../types/trace'; +import { uAlignIcon, ubMb1 } from '../../uberUtilityStyles'; +import ReferenceLink from '../../url/ReferenceLink'; + +import AccordianKeyValues from './AccordianKeyValues'; const getStyles = (theme: GrafanaTheme2) => { return { diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianText.test.js b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianText.test.js index ce48a3ce162..54803bf11ba 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianText.test.js +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianText.test.js @@ -12,8 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; import { mount } from 'enzyme'; +import React from 'react'; + import AccordianText from './AccordianText'; import TextList from './TextList'; diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianText.tsx b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianText.tsx index f2bc2b74620..9af61f1375d 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianText.tsx +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/AccordianText.tsx @@ -12,20 +12,22 @@ // See the License for the specific language governing permissions and // limitations under the License. -import * as React from 'react'; import { css } from '@emotion/css'; import cx from 'classnames'; +import * as React from 'react'; import IoIosArrowDown from 'react-icons/lib/io/ios-arrow-down'; import IoIosArrowRight from 'react-icons/lib/io/ios-arrow-right'; -import { useStyles2 } from '@grafana/ui'; -import { GrafanaTheme2 } from '@grafana/data'; -import TextList from './TextList'; -import { TNil } from '../../types'; -import { getStyles as getAccordianKeyValuesStyles } from './AccordianKeyValues'; +import { GrafanaTheme2 } from '@grafana/data'; +import { useStyles2 } from '@grafana/ui'; + import { autoColor } from '../../Theme'; +import { TNil } from '../../types'; import { uAlignIcon } from '../../uberUtilityStyles'; +import { getStyles as getAccordianKeyValuesStyles } from './AccordianKeyValues'; +import TextList from './TextList'; + const getStyles = (theme: GrafanaTheme2) => { return { header: css` diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/KeyValuesTable.test.js b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/KeyValuesTable.test.js index c03b0c2bf0b..4f2ec783abd 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/KeyValuesTable.test.js +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/KeyValuesTable.test.js @@ -12,13 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; import { shallow } from 'enzyme'; +import React from 'react'; import CopyIcon from '../../common/CopyIcon'; +import { ubInlineBlock } from '../../uberUtilityStyles'; import KeyValuesTable, { LinkValue } from './KeyValuesTable'; -import { ubInlineBlock } from '../../uberUtilityStyles'; describe('LinkValue', () => { const title = 'titleValue'; diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/KeyValuesTable.tsx b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/KeyValuesTable.tsx index 3945e4a8b7b..9e17ff31070 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/KeyValuesTable.tsx +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/KeyValuesTable.tsx @@ -12,17 +12,18 @@ // See the License for the specific language governing permissions and // limitations under the License. -import * as React from 'react'; -import jsonMarkup from 'json-markup'; import { css } from '@emotion/css'; import cx from 'classnames'; -import { Icon, useStyles2 } from '@grafana/ui'; -import { GrafanaTheme2 } from '@grafana/data'; +import jsonMarkup from 'json-markup'; +import * as React from 'react'; +import { GrafanaTheme2 } from '@grafana/data'; +import { Icon, useStyles2 } from '@grafana/ui'; + +import { autoColor } from '../../Theme'; import CopyIcon from '../../common/CopyIcon'; import { TNil } from '../../types'; import { TraceKeyValuePair, TraceLink } from '../../types/trace'; -import { autoColor } from '../../Theme'; import { ubInlineBlock, uWidth100 } from '../../uberUtilityStyles'; const copyIconClassName = 'copyIcon'; diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/TextList.test.js b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/TextList.test.js index 7a9043a57f1..207e186cb77 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/TextList.test.js +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/TextList.test.js @@ -12,8 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; import { shallow } from 'enzyme'; +import React from 'react'; + import TextList from './TextList'; describe('', () => { diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/TextList.tsx b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/TextList.tsx index 6a79a69ca67..a46685ca7e9 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/TextList.tsx +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/TextList.tsx @@ -12,9 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -import * as React from 'react'; import { css } from '@emotion/css'; import cx from 'classnames'; +import * as React from 'react'; + import { useStyles2 } from '@grafana/ui'; const getStyles = () => { diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/index.test.js b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/index.test.js index b63b2bfcad5..f1ca85e7fd8 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/index.test.js +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/index.test.js @@ -14,17 +14,19 @@ jest.mock('../utils'); -import React from 'react'; import { shallow } from 'enzyme'; +import React from 'react'; + +import LabeledList from '../../common/LabeledList'; +import traceGenerator from '../../demo/trace-generators'; +import transformTraceData from '../../model/transform-trace-data'; +import { formatDuration } from '../utils'; import AccordianKeyValues from './AccordianKeyValues'; import AccordianLogs from './AccordianLogs'; import DetailState from './DetailState'; + import SpanDetail from './index'; -import { formatDuration } from '../utils'; -import LabeledList from '../../common/LabeledList'; -import traceGenerator from '../../demo/trace-generators'; -import transformTraceData from '../../model/transform-trace-data'; describe('', () => { let wrapper; diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/index.tsx b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/index.tsx index 729b645e095..7f445a19f08 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/index.tsx +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/index.tsx @@ -12,25 +12,27 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; import { css } from '@emotion/css'; import cx from 'classnames'; -import { DataLinkButton, TextArea, useStyles2 } from '@grafana/ui'; -import { GrafanaTheme2, LinkModel } from '@grafana/data'; +import React from 'react'; import IoLink from 'react-icons/lib/io/link'; -import AccordianKeyValues from './AccordianKeyValues'; -import AccordianLogs from './AccordianLogs'; -import AccordianText from './AccordianText'; -import DetailState from './DetailState'; -import { formatDuration } from '../utils'; +import { GrafanaTheme2, LinkModel } from '@grafana/data'; +import { DataLinkButton, TextArea, useStyles2 } from '@grafana/ui'; + +import { autoColor } from '../../Theme'; +import { Divider } from '../../common/Divider'; import LabeledList from '../../common/LabeledList'; import { SpanLinkFunc, TNil } from '../../types'; import { TraceKeyValuePair, TraceLink, TraceLog, TraceSpan, TraceSpanReference } from '../../types/trace'; -import AccordianReferences from './AccordianReferences'; -import { autoColor } from '../../Theme'; import { uAlignIcon, ubM0, ubMb1, ubMy1, ubTxRightAlign } from '../../uberUtilityStyles'; -import { Divider } from '../../common/Divider'; +import { formatDuration } from '../utils'; + +import AccordianKeyValues from './AccordianKeyValues'; +import AccordianLogs from './AccordianLogs'; +import AccordianReferences from './AccordianReferences'; +import AccordianText from './AccordianText'; +import DetailState from './DetailState'; const getStyles = (theme: GrafanaTheme2) => { return { diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetailRow.test.js b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetailRow.test.js index cdfe935b52d..c06156dc950 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetailRow.test.js +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetailRow.test.js @@ -12,13 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; import { shallow } from 'enzyme'; +import React from 'react'; + import { createTheme } from '@grafana/data'; -import { UnthemedSpanDetailRow } from './SpanDetailRow'; import SpanDetail from './SpanDetail'; import DetailState from './SpanDetail/DetailState'; +import { UnthemedSpanDetailRow } from './SpanDetailRow'; import SpanTreeOffset from './SpanTreeOffset'; jest.mock('./SpanTreeOffset'); diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetailRow.tsx b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetailRow.tsx index c82ca42087f..8414405044a 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetailRow.tsx +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetailRow.tsx @@ -12,19 +12,20 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; import { css } from '@emotion/css'; +import React from 'react'; + +import { GrafanaTheme2, LinkModel } from '@grafana/data'; +import { stylesFactory, withTheme2 } from '@grafana/ui'; + +import { autoColor } from '../Theme'; +import { SpanLinkFunc } from '../types'; +import { TraceLog, TraceSpan, TraceKeyValuePair, TraceLink, TraceSpanReference } from '../types/trace'; import SpanDetail from './SpanDetail'; import DetailState from './SpanDetail/DetailState'; import SpanTreeOffset from './SpanTreeOffset'; import TimelineRow from './TimelineRow'; -import { autoColor } from '../Theme'; -import { stylesFactory, withTheme2 } from '@grafana/ui'; -import { GrafanaTheme2, LinkModel } from '@grafana/data'; - -import { TraceLog, TraceSpan, TraceKeyValuePair, TraceLink, TraceSpanReference } from '../types/trace'; -import { SpanLinkFunc } from '../types'; const getStyles = stylesFactory((theme: GrafanaTheme2) => { return { diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanTreeOffset.test.js b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanTreeOffset.test.js index ca2539dff1b..b0c69b9570e 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanTreeOffset.test.js +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanTreeOffset.test.js @@ -16,11 +16,13 @@ import { shallow } from 'enzyme'; import React from 'react'; import IoChevronRight from 'react-icons/lib/io/chevron-right'; import IoIosArrowDown from 'react-icons/lib/io/ios-arrow-down'; + import { createTheme } from '@grafana/data'; -import SpanTreeOffset, { getStyles } from './SpanTreeOffset'; import spanAncestorIdsSpy from '../utils/span-ancestor-ids'; +import SpanTreeOffset, { getStyles } from './SpanTreeOffset'; + jest.mock('../utils/span-ancestor-ids'); describe('SpanTreeOffset', () => { diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanTreeOffset.tsx b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanTreeOffset.tsx index 741dd06655f..5dbc6d8aee6 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanTreeOffset.tsx +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/SpanTreeOffset.tsx @@ -12,18 +12,19 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; -import { get as _get } from 'lodash'; -import IoChevronRight from 'react-icons/lib/io/chevron-right'; -import IoIosArrowDown from 'react-icons/lib/io/ios-arrow-down'; import { css } from '@emotion/css'; import cx from 'classnames'; +import { get as _get } from 'lodash'; +import React from 'react'; +import IoChevronRight from 'react-icons/lib/io/chevron-right'; +import IoIosArrowDown from 'react-icons/lib/io/ios-arrow-down'; + import { GrafanaTheme2 } from '@grafana/data'; import { stylesFactory, withTheme2 } from '@grafana/ui'; +import { autoColor } from '../Theme'; import { TraceSpan } from '../types/trace'; import spanAncestorIds from '../utils/span-ancestor-ids'; -import { autoColor } from '../Theme'; export const getStyles = stylesFactory((theme: GrafanaTheme2) => { return { diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/Ticks.test.js b/packages/jaeger-ui-components/src/TraceTimelineViewer/Ticks.test.js index 7a2bf3d267d..6c99b32c633 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/Ticks.test.js +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/Ticks.test.js @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; import { shallow } from 'enzyme'; +import React from 'react'; import Ticks from './Ticks'; diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/Ticks.tsx b/packages/jaeger-ui-components/src/TraceTimelineViewer/Ticks.tsx index 952b8d2b1e9..b2eace5fcff 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/Ticks.tsx +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/Ticks.tsx @@ -12,15 +12,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -import * as React from 'react'; import { css } from '@emotion/css'; import cx from 'classnames'; -import { useStyles2 } from '@grafana/ui'; +import * as React from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; +import { useStyles2 } from '@grafana/ui'; + +import { autoColor } from '../Theme'; +import { TNil } from '../types'; import { formatDuration } from './utils'; -import { TNil } from '../types'; -import { autoColor } from '../Theme'; const getStyles = (theme: GrafanaTheme2) => { return { diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineCollapser.test.js b/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineCollapser.test.js index 322e197cc7f..842ebd484c5 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineCollapser.test.js +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineCollapser.test.js @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; import { shallow } from 'enzyme'; +import React from 'react'; import { TimelineCollapser } from './TimelineCollapser'; diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineCollapser.tsx b/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineCollapser.tsx index 5a4e407fef8..06043008504 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineCollapser.tsx +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineCollapser.tsx @@ -12,10 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { IconButton, useStyles2 } from '@grafana/ui'; import { css } from '@emotion/css'; import React from 'react'; +import { IconButton, useStyles2 } from '@grafana/ui'; + const getStyles = () => { return { TimelineCollapser: css` diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineColumnResizer.test.js b/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineColumnResizer.test.js index 8c838a59d1c..3a3432c1fae 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineColumnResizer.test.js +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineColumnResizer.test.js @@ -12,9 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; -import { mount } from 'enzyme'; import cx from 'classnames'; +import { mount } from 'enzyme'; +import React from 'react'; import TimelineColumnResizer, { getStyles } from './TimelineColumnResizer'; diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineColumnResizer.tsx b/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineColumnResizer.tsx index 72f41ea852a..0d7395d5f7b 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineColumnResizer.tsx +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineColumnResizer.tsx @@ -12,9 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -import * as React from 'react'; import { css } from '@emotion/css'; import cx from 'classnames'; +import * as React from 'react'; + import { stylesFactory } from '@grafana/ui'; import { TNil } from '../../types'; diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineHeaderRow.test.js b/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineHeaderRow.test.js index 95b2f5eef9e..700dfbe2df9 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineHeaderRow.test.js +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineHeaderRow.test.js @@ -12,14 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; import { shallow } from 'enzyme'; +import React from 'react'; -import TimelineHeaderRow from './TimelineHeaderRow'; -import TimelineColumnResizer from './TimelineColumnResizer'; -import TimelineViewingLayer from './TimelineViewingLayer'; import Ticks from '../Ticks'; + import { TimelineCollapser } from './TimelineCollapser'; +import TimelineColumnResizer from './TimelineColumnResizer'; +import TimelineHeaderRow from './TimelineHeaderRow'; +import TimelineViewingLayer from './TimelineViewingLayer'; describe('', () => { let wrapper; diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineHeaderRow.tsx b/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineHeaderRow.tsx index b973ec1fbd5..fb197e0c279 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineHeaderRow.tsx +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineHeaderRow.tsx @@ -12,20 +12,22 @@ // See the License for the specific language governing permissions and // limitations under the License. -import * as React from 'react'; import { css } from '@emotion/css'; import cx from 'classnames'; -import { useStyles2 } from '@grafana/ui'; +import * as React from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; +import { useStyles2 } from '@grafana/ui'; + +import { autoColor } from '../../Theme'; +import { ubFlex, ubPx2 } from '../../uberUtilityStyles'; +import Ticks from '../Ticks'; +import TimelineRow from '../TimelineRow'; +import { TUpdateViewRangeTimeFunction, ViewRangeTime, ViewRangeTimeUpdate } from '../types'; import { TimelineCollapser } from './TimelineCollapser'; import TimelineColumnResizer from './TimelineColumnResizer'; import TimelineViewingLayer from './TimelineViewingLayer'; -import Ticks from '../Ticks'; -import TimelineRow from '../TimelineRow'; -import { TUpdateViewRangeTimeFunction, ViewRangeTime, ViewRangeTimeUpdate } from '../types'; -import { autoColor } from '../../Theme'; -import { ubFlex, ubPx2 } from '../../uberUtilityStyles'; const getStyles = (theme: GrafanaTheme2) => { return { diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineViewingLayer.test.js b/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineViewingLayer.test.js index 43657567d40..d8c18bf163e 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineViewingLayer.test.js +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineViewingLayer.test.js @@ -12,9 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; -import { mount } from 'enzyme'; import { cx } from '@emotion/css'; +import { mount } from 'enzyme'; +import React from 'react'; import TimelineViewingLayer, { getStyles } from './TimelineViewingLayer'; diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineViewingLayer.tsx b/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineViewingLayer.tsx index 7c066b8db42..d786338983e 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineViewingLayer.tsx +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineHeaderRow/TimelineViewingLayer.tsx @@ -12,12 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -import * as React from 'react'; import { css, cx } from '@emotion/css'; +import * as React from 'react'; + import { stylesFactory } from '@grafana/ui'; -import { TUpdateViewRangeTimeFunction, ViewRangeTime, ViewRangeTimeUpdate } from '../types'; + import { TNil } from '../../types'; import DraggableManager, { DraggableBounds, DraggingUpdate } from '../../utils/DraggableManager'; +import { TUpdateViewRangeTimeFunction, ViewRangeTime, ViewRangeTimeUpdate } from '../types'; // exported for testing export const getStyles = stylesFactory(() => { diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineRow.tsx b/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineRow.tsx index 95bcd4deffe..f1d0b046874 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineRow.tsx +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/TimelineRow.tsx @@ -12,10 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -import * as React from 'react'; import { css } from '@emotion/css'; import cx from 'classnames'; +import * as React from 'react'; + import { useStyles2 } from '@grafana/ui'; + import { ubRelative } from '../uberUtilityStyles'; const getStyles = () => { diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/VirtualizedTraceView.test.js b/packages/jaeger-ui-components/src/TraceTimelineViewer/VirtualizedTraceView.test.js index c47bd1bfe92..ee5186ac162 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/VirtualizedTraceView.test.js +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/VirtualizedTraceView.test.js @@ -11,17 +11,18 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; import { shallow, mount } from 'enzyme'; +import React from 'react'; + +import traceGenerator from '../demo/trace-generators'; +import transformTraceData from '../model/transform-trace-data'; import ListView from './ListView'; import SpanBarRow from './SpanBarRow'; import DetailState from './SpanDetail/DetailState'; import SpanDetailRow from './SpanDetailRow'; -import VirtualizedTraceView, { DEFAULT_HEIGHTS } from './VirtualizedTraceView'; -import traceGenerator from '../demo/trace-generators'; -import transformTraceData from '../model/transform-trace-data'; import SpanTreeOffset from './SpanTreeOffset'; +import VirtualizedTraceView, { DEFAULT_HEIGHTS } from './VirtualizedTraceView'; jest.mock('./SpanTreeOffset'); diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/VirtualizedTraceView.tsx b/packages/jaeger-ui-components/src/TraceTimelineViewer/VirtualizedTraceView.tsx index b365fcc9919..4fa87f1628f 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/VirtualizedTraceView.tsx +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/VirtualizedTraceView.tsx @@ -12,13 +12,21 @@ // See the License for the specific language governing permissions and // limitations under the License. -import * as React from 'react'; import { css } from '@emotion/css'; - import { isEqual } from 'lodash'; import memoizeOne from 'memoize-one'; -import { stylesFactory, withTheme2, ToolbarButton } from '@grafana/ui'; +import * as React from 'react'; +import { createRef, RefObject } from 'react'; + import { GrafanaTheme2, LinkModel } from '@grafana/data'; +import { stylesFactory, withTheme2, ToolbarButton } from '@grafana/ui'; + +import { Accessors } from '../ScrollManager'; +import { PEER_SERVICE } from '../constants/tag-keys'; +import { SpanLinkFunc, TNil } from '../types'; +import TTraceTimeline from '../types/TTraceTimeline'; +import { TraceLog, TraceSpan, Trace, TraceKeyValuePair, TraceLink, TraceSpanReference } from '../types/trace'; +import { getColorByKey } from '../utils/color-generator'; import ListView from './ListView'; import SpanBarRow from './SpanBarRow'; @@ -32,13 +40,6 @@ import { spanContainsErredSpan, ViewedBoundsFunctionType, } from './utils'; -import { Accessors } from '../ScrollManager'; -import { getColorByKey } from '../utils/color-generator'; -import { SpanLinkFunc, TNil } from '../types'; -import { TraceLog, TraceSpan, Trace, TraceKeyValuePair, TraceLink, TraceSpanReference } from '../types/trace'; -import TTraceTimeline from '../types/TTraceTimeline'; -import { PEER_SERVICE } from '../constants/tag-keys'; -import { createRef, RefObject } from 'react'; type TExtractUiFindFromStateReturn = { uiFind: string | undefined; diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/index.test.js b/packages/jaeger-ui-components/src/TraceTimelineViewer/index.test.js index 4f85a6f1c3c..77f47586d93 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/index.test.js +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/index.test.js @@ -12,15 +12,18 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; import { shallow } from 'enzyme'; +import React from 'react'; + import { createTheme } from '@grafana/data'; -import TraceTimelineViewer from './index'; import traceGenerator from '../demo/trace-generators'; import transformTraceData from '../model/transform-trace-data'; + import TimelineHeaderRow from './TimelineHeaderRow'; +import TraceTimelineViewer from './index'; + describe('', () => { const trace = transformTraceData(traceGenerator.trace({})); const props = { diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/index.tsx b/packages/jaeger-ui-components/src/TraceTimelineViewer/index.tsx index 0f1d4a1450e..7e7fd880395 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/index.tsx +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/index.tsx @@ -12,21 +12,23 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React, { RefObject } from 'react'; import { css } from '@emotion/css'; +import React, { RefObject } from 'react'; + import { GrafanaTheme2, LinkModel } from '@grafana/data'; import { stylesFactory, withTheme2 } from '@grafana/ui'; +import { Accessors } from '../ScrollManager'; +import { autoColor } from '../Theme'; +import { merge as mergeShortcuts } from '../keyboard-shortcuts'; +import { SpanLinkFunc, TNil } from '../types'; +import TTraceTimeline from '../types/TTraceTimeline'; +import { TraceSpan, Trace, TraceLog, TraceKeyValuePair, TraceLink, TraceSpanReference } from '../types/trace'; +import ExternalLinkContext from '../url/externalLinkContext'; + import TimelineHeaderRow from './TimelineHeaderRow'; import VirtualizedTraceView from './VirtualizedTraceView'; -import { merge as mergeShortcuts } from '../keyboard-shortcuts'; -import { Accessors } from '../ScrollManager'; import { TUpdateViewRangeTimeFunction, ViewRange, ViewRangeTimeUpdate } from './types'; -import { SpanLinkFunc, TNil } from '../types'; -import { TraceSpan, Trace, TraceLog, TraceKeyValuePair, TraceLink, TraceSpanReference } from '../types/trace'; -import TTraceTimeline from '../types/TTraceTimeline'; -import { autoColor } from '../Theme'; -import ExternalLinkContext from '../url/externalLinkContext'; type TExtractUiFindFromStateReturn = { uiFind: string | undefined; diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/utils.test.js b/packages/jaeger-ui-components/src/TraceTimelineViewer/utils.test.js index a8ad75f111f..3f6b2c0cb34 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/utils.test.js +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/utils.test.js @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +import traceGenerator from '../demo/trace-generators'; + import { findServerChildSpan, createViewedBoundsFunc, @@ -23,8 +25,6 @@ import { formatNumber, } from './utils'; -import traceGenerator from '../demo/trace-generators'; - describe('TraceTimelineViewer/utils', () => { describe('getViewedBounds()', () => { it('works for the full range', () => { diff --git a/packages/jaeger-ui-components/src/common/BreakableText.tsx b/packages/jaeger-ui-components/src/common/BreakableText.tsx index 4e2f077046a..ad8c4cecb6d 100644 --- a/packages/jaeger-ui-components/src/common/BreakableText.tsx +++ b/packages/jaeger-ui-components/src/common/BreakableText.tsx @@ -12,8 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -import * as React from 'react'; import { css } from '@emotion/css'; +import * as React from 'react'; + import { useStyles2 } from '@grafana/ui'; const getStyles = () => { diff --git a/packages/jaeger-ui-components/src/common/CopyIcon.test.js b/packages/jaeger-ui-components/src/common/CopyIcon.test.js index 79cfa916b8a..10ea26789c2 100644 --- a/packages/jaeger-ui-components/src/common/CopyIcon.test.js +++ b/packages/jaeger-ui-components/src/common/CopyIcon.test.js @@ -12,10 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; -import { shallow } from 'enzyme'; import * as copy from 'copy-to-clipboard'; +import { shallow } from 'enzyme'; +import React from 'react'; + import { Button, Tooltip } from '@grafana/ui'; + import CopyIcon from './CopyIcon'; jest.mock('copy-to-clipboard'); diff --git a/packages/jaeger-ui-components/src/common/CopyIcon.tsx b/packages/jaeger-ui-components/src/common/CopyIcon.tsx index e4a91c7ff9e..6c674713045 100644 --- a/packages/jaeger-ui-components/src/common/CopyIcon.tsx +++ b/packages/jaeger-ui-components/src/common/CopyIcon.tsx @@ -12,10 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -import * as React from 'react'; import { css } from '@emotion/css'; import cx from 'classnames'; import copy from 'copy-to-clipboard'; +import * as React from 'react'; + import { Button, IconName, stylesFactory, Tooltip } from '@grafana/ui'; const getStyles = stylesFactory(() => { diff --git a/packages/jaeger-ui-components/src/common/Divider.tsx b/packages/jaeger-ui-components/src/common/Divider.tsx index 9977191cdd9..9eab10a61e2 100644 --- a/packages/jaeger-ui-components/src/common/Divider.tsx +++ b/packages/jaeger-ui-components/src/common/Divider.tsx @@ -1,7 +1,9 @@ -import React from 'react'; import { css, cx } from '@emotion/css'; -import { useStyles2 } from '@grafana/ui'; +import React from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; +import { useStyles2 } from '@grafana/ui'; + import { autoColor } from '../Theme'; const getStyles = (theme: GrafanaTheme2) => { diff --git a/packages/jaeger-ui-components/src/common/ExternalLinks.tsx b/packages/jaeger-ui-components/src/common/ExternalLinks.tsx index 2f82e4e7c47..96e388aff48 100644 --- a/packages/jaeger-ui-components/src/common/ExternalLinks.tsx +++ b/packages/jaeger-ui-components/src/common/ExternalLinks.tsx @@ -13,6 +13,7 @@ // limitations under the License. import * as React from 'react'; + import NewWindowIcon from './NewWindowIcon'; type Link = { diff --git a/packages/jaeger-ui-components/src/common/LabeledList.tsx b/packages/jaeger-ui-components/src/common/LabeledList.tsx index a66358dc002..7ce89630e02 100644 --- a/packages/jaeger-ui-components/src/common/LabeledList.tsx +++ b/packages/jaeger-ui-components/src/common/LabeledList.tsx @@ -12,11 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -import * as React from 'react'; import { css } from '@emotion/css'; import cx from 'classnames'; -import { useStyles2 } from '@grafana/ui'; +import * as React from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; +import { useStyles2 } from '@grafana/ui'; + import { autoColor } from '../Theme'; const getStyles = (divider: boolean) => (theme: GrafanaTheme2) => { diff --git a/packages/jaeger-ui-components/src/common/NewWindowIcon.test.js b/packages/jaeger-ui-components/src/common/NewWindowIcon.test.js index d18aae61caa..160d4c2b0bd 100644 --- a/packages/jaeger-ui-components/src/common/NewWindowIcon.test.js +++ b/packages/jaeger-ui-components/src/common/NewWindowIcon.test.js @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; import { shallow } from 'enzyme'; +import React from 'react'; import NewWindowIcon, { getStyles } from './NewWindowIcon'; diff --git a/packages/jaeger-ui-components/src/common/NewWindowIcon.tsx b/packages/jaeger-ui-components/src/common/NewWindowIcon.tsx index 57256c75faf..1f5185d5df5 100644 --- a/packages/jaeger-ui-components/src/common/NewWindowIcon.tsx +++ b/packages/jaeger-ui-components/src/common/NewWindowIcon.tsx @@ -12,10 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; -import cx from 'classnames'; -import IoAndroidOpen from 'react-icons/lib/io/android-open'; import { css } from '@emotion/css'; +import cx from 'classnames'; +import React from 'react'; +import IoAndroidOpen from 'react-icons/lib/io/android-open'; + import { useStyles2 } from '@grafana/ui'; export const getStyles = () => { diff --git a/packages/jaeger-ui-components/src/common/Popover.tsx b/packages/jaeger-ui-components/src/common/Popover.tsx index c055a3306c7..cfd1ee9e15e 100644 --- a/packages/jaeger-ui-components/src/common/Popover.tsx +++ b/packages/jaeger-ui-components/src/common/Popover.tsx @@ -1,4 +1,5 @@ import React, { ReactElement, useRef } from 'react'; + import { Popover as GrafanaPopover, PopoverController } from '@grafana/ui'; export type PopoverProps = { diff --git a/packages/jaeger-ui-components/src/common/TraceName.tsx b/packages/jaeger-ui-components/src/common/TraceName.tsx index cf13140e394..1b8af164ce4 100644 --- a/packages/jaeger-ui-components/src/common/TraceName.tsx +++ b/packages/jaeger-ui-components/src/common/TraceName.tsx @@ -12,16 +12,18 @@ // See the License for the specific language governing permissions and // limitations under the License. -import * as React from 'react'; import { css } from '@emotion/css'; import cx from 'classnames'; +import * as React from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; import { useStyles2 } from '@grafana/ui'; -import { GrafanaTheme2 } from '@grafana/data'; -import BreakableText from './BreakableText'; import { FALLBACK_TRACE_NAME } from '../constants'; import { TNil } from '../types'; +import BreakableText from './BreakableText'; + const getStyles = (theme: GrafanaTheme2) => { return { TraceName: css` diff --git a/packages/jaeger-ui-components/src/common/UiFindInput.test.js b/packages/jaeger-ui-components/src/common/UiFindInput.test.js index de5ecf72301..e918af42cb8 100644 --- a/packages/jaeger-ui-components/src/common/UiFindInput.test.js +++ b/packages/jaeger-ui-components/src/common/UiFindInput.test.js @@ -12,10 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -import * as React from 'react'; import { shallow } from 'enzyme'; // eslint-disable-next-line lodash/import-scope import _ from 'lodash'; +import * as React from 'react'; + import { Input } from '@grafana/ui'; import UiFindInput from './UiFindInput'; diff --git a/packages/jaeger-ui-components/src/common/UiFindInput.tsx b/packages/jaeger-ui-components/src/common/UiFindInput.tsx index f2f176c83a6..b6ca9fff3fe 100644 --- a/packages/jaeger-ui-components/src/common/UiFindInput.tsx +++ b/packages/jaeger-ui-components/src/common/UiFindInput.tsx @@ -12,9 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { IconButton, Input } from '@grafana/ui'; import * as React from 'react'; +import { IconButton, Input } from '@grafana/ui'; + import { TNil } from '../types/index'; type Props = { diff --git a/packages/jaeger-ui-components/src/keyboard-shortcuts.tsx b/packages/jaeger-ui-components/src/keyboard-shortcuts.tsx index 92d2243615e..692935f7940 100644 --- a/packages/jaeger-ui-components/src/keyboard-shortcuts.tsx +++ b/packages/jaeger-ui-components/src/keyboard-shortcuts.tsx @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -import * as React from 'react'; import Combokeys from 'combokeys'; +import * as React from 'react'; import keyboardMappings from './keyboard-mappings'; diff --git a/packages/jaeger-ui-components/src/model/link-patterns.tsx b/packages/jaeger-ui-components/src/model/link-patterns.tsx index ee750905464..6031ddfdb1c 100644 --- a/packages/jaeger-ui-components/src/model/link-patterns.tsx +++ b/packages/jaeger-ui-components/src/model/link-patterns.tsx @@ -14,10 +14,12 @@ import { uniq as _uniq } from 'lodash'; import memoize from 'lru-memoize'; -import { getConfigValue } from '../utils/config/get-config'; -import { getParent } from './span'; + import { TNil } from '../types'; import { TraceSpan, TraceLink, TraceKeyValuePair, Trace } from '../types/trace'; +import { getConfigValue } from '../utils/config/get-config'; + +import { getParent } from './span'; const parameterRegExp = /#\{([^{}]*)\}/g; diff --git a/packages/jaeger-ui-components/src/model/transform-trace-data.tsx b/packages/jaeger-ui-components/src/model/transform-trace-data.tsx index 1174a2e260b..18fe5917311 100644 --- a/packages/jaeger-ui-components/src/model/transform-trace-data.tsx +++ b/packages/jaeger-ui-components/src/model/transform-trace-data.tsx @@ -16,10 +16,11 @@ import { isEqual as _isEqual } from 'lodash'; // @ts-ignore import { getTraceSpanIdsAsTree } from '../selectors/trace'; -import { getConfigValue } from '../utils/config/get-config'; import { TraceKeyValuePair, TraceSpan, Trace, TraceResponse } from '../types/trace'; // @ts-ignore import TreeNode from '../utils/TreeNode'; +import { getConfigValue } from '../utils/config/get-config'; + import { getTraceName } from './trace-viewer'; // exported for tests diff --git a/packages/jaeger-ui-components/src/scroll-page.test.js b/packages/jaeger-ui-components/src/scroll-page.test.js index 3b60f1d0bed..a697fd9ce4f 100644 --- a/packages/jaeger-ui-components/src/scroll-page.test.js +++ b/packages/jaeger-ui-components/src/scroll-page.test.js @@ -14,8 +14,8 @@ jest.mock('./Tween'); -import { scrollBy, scrollTo, cancel } from './scroll-page'; import Tween from './Tween'; +import { scrollBy, scrollTo, cancel } from './scroll-page'; // keep track of instances, manually // https://github.com/facebook/jest/issues/5019 diff --git a/packages/jaeger-ui-components/src/selectors/process.test.js b/packages/jaeger-ui-components/src/selectors/process.test.js index 0326198fc97..9edc171fd23 100644 --- a/packages/jaeger-ui-components/src/selectors/process.test.js +++ b/packages/jaeger-ui-components/src/selectors/process.test.js @@ -12,9 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -import * as processSelectors from './process'; import traceGenerator from '../demo/trace-generators'; +import * as processSelectors from './process'; + const generatedTrace = traceGenerator.trace({ numberOfSpans: 45 }); it('getProcessServiceName() should return the serviceName of the process', () => { diff --git a/packages/jaeger-ui-components/src/selectors/span.js b/packages/jaeger-ui-components/src/selectors/span.js index f528e65a182..cd0a827dc4c 100644 --- a/packages/jaeger-ui-components/src/selectors/span.js +++ b/packages/jaeger-ui-components/src/selectors/span.js @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { createSelector } from 'reselect'; import fuzzy from 'fuzzy'; +import { createSelector } from 'reselect'; import { getProcessServiceName } from './process'; diff --git a/packages/jaeger-ui-components/src/selectors/span.test.js b/packages/jaeger-ui-components/src/selectors/span.test.js index 11e2e28c388..12893f81628 100644 --- a/packages/jaeger-ui-components/src/selectors/span.test.js +++ b/packages/jaeger-ui-components/src/selectors/span.test.js @@ -12,9 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -import * as spanSelectors from './span'; import traceGenerator from '../demo/trace-generators'; +import * as spanSelectors from './span'; + const generatedTrace = traceGenerator.trace({ numberOfSpans: 45 }); it('getSpanId() should return the name of the span', () => { diff --git a/packages/jaeger-ui-components/src/selectors/trace.js b/packages/jaeger-ui-components/src/selectors/trace.js index ea93313960e..35776aef0df 100644 --- a/packages/jaeger-ui-components/src/selectors/trace.js +++ b/packages/jaeger-ui-components/src/selectors/trace.js @@ -14,6 +14,11 @@ import { createSelector, createStructuredSelector } from 'reselect'; +import TreeNode from '../utils/TreeNode'; +import { formatMillisecondTime, formatSecondTime, ONE_SECOND } from '../utils/date'; +import { numberSortComparator } from '../utils/sort'; + +import { getProcessServiceName } from './process'; import { getSpanId, getSpanName, @@ -22,10 +27,6 @@ import { getSpanDuration, getSpanProcessId, } from './span'; -import { getProcessServiceName } from './process'; -import { formatMillisecondTime, formatSecondTime, ONE_SECOND } from '../utils/date'; -import { numberSortComparator } from '../utils/sort'; -import TreeNode from '../utils/TreeNode'; export const getTraceId = (trace) => trace.traceID; diff --git a/packages/jaeger-ui-components/src/selectors/trace.test.js b/packages/jaeger-ui-components/src/selectors/trace.test.js index 234130c40f4..3e20f4d7060 100644 --- a/packages/jaeger-ui-components/src/selectors/trace.test.js +++ b/packages/jaeger-ui-components/src/selectors/trace.test.js @@ -14,7 +14,9 @@ import { values as _values } from 'lodash'; -import { followsFromRef } from './trace.fixture'; +import traceGenerator from '../demo/trace-generators'; +import { numberSortComparator } from '../utils/sort'; + import { getSpanId, getSpanName, @@ -25,8 +27,7 @@ import { getSpanTimestamp, } from './span'; import * as traceSelectors from './trace'; -import traceGenerator from '../demo/trace-generators'; -import { numberSortComparator } from '../utils/sort'; +import { followsFromRef } from './trace.fixture'; const generatedTrace = traceGenerator.trace({ numberOfSpans: 45 }); diff --git a/packages/jaeger-ui-components/src/types/TDdgState.tsx b/packages/jaeger-ui-components/src/types/TDdgState.tsx index 4540714a790..f1aba58ac7c 100644 --- a/packages/jaeger-ui-components/src/types/TDdgState.tsx +++ b/packages/jaeger-ui-components/src/types/TDdgState.tsx @@ -12,10 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { ApiError } from './api-error'; import { fetchedState } from '../constants'; import { TDdgModel } from '../model/ddg/types'; +import { ApiError } from './api-error'; + export type TDdgStateEntry = | { state: typeof fetchedState.LOADING; diff --git a/packages/jaeger-ui-components/src/types/TTraceTimeline.tsx b/packages/jaeger-ui-components/src/types/TTraceTimeline.tsx index 1fd1f4300b5..2441cc05af5 100644 --- a/packages/jaeger-ui-components/src/types/TTraceTimeline.tsx +++ b/packages/jaeger-ui-components/src/types/TTraceTimeline.tsx @@ -13,6 +13,7 @@ // limitations under the License. import DetailState from '../TraceTimelineViewer/SpanDetail/DetailState'; + import TNil from './TNil'; type TTraceTimeline = { diff --git a/packages/jaeger-ui-components/src/types/links.ts b/packages/jaeger-ui-components/src/types/links.ts index 58448dcb302..10d7d9dc4f5 100644 --- a/packages/jaeger-ui-components/src/types/links.ts +++ b/packages/jaeger-ui-components/src/types/links.ts @@ -1,6 +1,7 @@ -import { TraceSpan } from './trace'; import React from 'react'; +import { TraceSpan } from './trace'; + export type SpanLinkDef = { href: string; onClick?: (event: any) => void; diff --git a/packages/jaeger-ui-components/src/url/ReferenceLink.test.js b/packages/jaeger-ui-components/src/url/ReferenceLink.test.js index 63522aaeb77..1334f8b980c 100644 --- a/packages/jaeger-ui-components/src/url/ReferenceLink.test.js +++ b/packages/jaeger-ui-components/src/url/ReferenceLink.test.js @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react'; import { shallow, mount } from 'enzyme'; +import React from 'react'; import ReferenceLink from './ReferenceLink'; import ExternalLinkContext from './externalLinkContext'; diff --git a/packages/jaeger-ui-components/src/url/ReferenceLink.tsx b/packages/jaeger-ui-components/src/url/ReferenceLink.tsx index 631cd86e2b1..9841e9874df 100644 --- a/packages/jaeger-ui-components/src/url/ReferenceLink.tsx +++ b/packages/jaeger-ui-components/src/url/ReferenceLink.tsx @@ -13,7 +13,9 @@ // limitations under the License. import React from 'react'; + import { TraceSpanReference } from '../types/trace'; + import ExternalLinkContext from './externalLinkContext'; type ReferenceLinkProps = { diff --git a/packages/jaeger-ui-components/src/utils/DraggableManager/DraggableManager.tsx b/packages/jaeger-ui-components/src/utils/DraggableManager/DraggableManager.tsx index a1401dc19d2..f338288798e 100644 --- a/packages/jaeger-ui-components/src/utils/DraggableManager/DraggableManager.tsx +++ b/packages/jaeger-ui-components/src/utils/DraggableManager/DraggableManager.tsx @@ -14,9 +14,10 @@ import { get as _get } from 'lodash'; +import { TNil } from '../../types'; + import EUpdateTypes from './EUpdateTypes'; import { DraggableBounds, DraggingUpdate } from './types'; -import { TNil } from '../../types'; const LEFT_MOUSE_BUTTON = 0; diff --git a/packages/jaeger-ui-components/src/utils/DraggableManager/demo/DividerDemo.tsx b/packages/jaeger-ui-components/src/utils/DraggableManager/demo/DividerDemo.tsx index e1a73acc297..ca8ce693956 100644 --- a/packages/jaeger-ui-components/src/utils/DraggableManager/demo/DividerDemo.tsx +++ b/packages/jaeger-ui-components/src/utils/DraggableManager/demo/DividerDemo.tsx @@ -15,8 +15,8 @@ import React from 'react'; import { DraggableBounds, DraggingUpdate } from '..'; -import DraggableManager from '../DraggableManager'; import TNil from '../../../types/TNil'; +import DraggableManager from '../DraggableManager'; import './DividerDemo.css'; diff --git a/packages/jaeger-ui-components/src/utils/DraggableManager/demo/DraggableManagerDemo.tsx b/packages/jaeger-ui-components/src/utils/DraggableManager/demo/DraggableManagerDemo.tsx index 0cf45ae6b94..439a7b5c7e2 100644 --- a/packages/jaeger-ui-components/src/utils/DraggableManager/demo/DraggableManagerDemo.tsx +++ b/packages/jaeger-ui-components/src/utils/DraggableManager/demo/DraggableManagerDemo.tsx @@ -14,9 +14,10 @@ import React from 'react'; +import { TNil } from '../../../types'; + import DividerDemo from './DividerDemo'; import RegionDemo from './RegionDemo'; -import { TNil } from '../../../types'; import './DraggableManagerDemo.css'; diff --git a/packages/jaeger-ui-components/src/utils/DraggableManager/types.tsx b/packages/jaeger-ui-components/src/utils/DraggableManager/types.tsx index 16ab7948d4e..b10c4581199 100644 --- a/packages/jaeger-ui-components/src/utils/DraggableManager/types.tsx +++ b/packages/jaeger-ui-components/src/utils/DraggableManager/types.tsx @@ -14,9 +14,10 @@ import * as React from 'react'; +import { TNil } from '../../types'; + import DraggableManager from './DraggableManager'; import EUpdateTypes from './EUpdateTypes'; -import { TNil } from '../../types'; export type DraggableBounds = { clientXLeft: number; diff --git a/packages/jaeger-ui-components/src/utils/color-generator.test.js b/packages/jaeger-ui-components/src/utils/color-generator.test.js index d211220bbb1..894dd69ab81 100644 --- a/packages/jaeger-ui-components/src/utils/color-generator.test.js +++ b/packages/jaeger-ui-components/src/utils/color-generator.test.js @@ -12,9 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { getColorByKey, clear } from './color-generator'; import { createTheme } from '@grafana/data'; +import { getColorByKey, clear } from './color-generator'; + it('gives the same color for the same key', () => { clear(); const colorOne = getColorByKey('serviceA', createTheme()); diff --git a/packages/jaeger-ui-components/src/utils/color-generator.tsx b/packages/jaeger-ui-components/src/utils/color-generator.tsx index c4d7ef614d9..aa5bc87dfd6 100644 --- a/packages/jaeger-ui-components/src/utils/color-generator.tsx +++ b/packages/jaeger-ui-components/src/utils/color-generator.tsx @@ -13,6 +13,7 @@ // limitations under the License. import memoizeOne from 'memoize-one'; + import { GrafanaTheme2 } from '@grafana/data'; import { colors } from '@grafana/ui'; diff --git a/packages/jaeger-ui-components/src/utils/date.tsx b/packages/jaeger-ui-components/src/utils/date.tsx index eb5aa6a795a..1a0277f189f 100644 --- a/packages/jaeger-ui-components/src/utils/date.tsx +++ b/packages/jaeger-ui-components/src/utils/date.tsx @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -import moment from 'moment-timezone'; import { round as _round, dropWhile as _dropWhile } from 'lodash'; +import moment from 'moment-timezone'; import { toFloatPrecision } from './number'; diff --git a/packages/jaeger-ui-components/src/utils/filter-spans.tsx b/packages/jaeger-ui-components/src/utils/filter-spans.tsx index 6647201bf37..699d8996487 100644 --- a/packages/jaeger-ui-components/src/utils/filter-spans.tsx +++ b/packages/jaeger-ui-components/src/utils/filter-spans.tsx @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { TraceKeyValuePair, TraceSpan } from '../types/trace'; import { TNil } from '../types'; +import { TraceKeyValuePair, TraceSpan } from '../types/trace'; export default function filterSpans(textFilter: string, spans: TraceSpan[] | TNil) { if (!spans) { diff --git a/plugins-bundled/internal/input-datasource/src/InputConfigEditor.tsx b/plugins-bundled/internal/input-datasource/src/InputConfigEditor.tsx index 975bea26e1f..e79558da14c 100644 --- a/plugins-bundled/internal/input-datasource/src/InputConfigEditor.tsx +++ b/plugins-bundled/internal/input-datasource/src/InputConfigEditor.tsx @@ -2,10 +2,10 @@ import React, { PureComponent } from 'react'; // Types -import { InputOptions } from './types'; - -import { TableInputCSV } from '@grafana/ui'; import { DataSourcePluginOptionsEditorProps, DataFrame, MutableDataFrame } from '@grafana/data'; +import { TableInputCSV } from '@grafana/ui'; + +import { InputOptions } from './types'; import { dataFrameToCSV } from './utils'; interface Props extends DataSourcePluginOptionsEditorProps {} diff --git a/plugins-bundled/internal/input-datasource/src/InputDatasource.test.ts b/plugins-bundled/internal/input-datasource/src/InputDatasource.test.ts index 1f20fede1c1..bc8f1f43f56 100644 --- a/plugins-bundled/internal/input-datasource/src/InputDatasource.test.ts +++ b/plugins-bundled/internal/input-datasource/src/InputDatasource.test.ts @@ -1,5 +1,3 @@ -import InputDatasource, { describeDataFrame } from './InputDatasource'; -import { InputOptions, InputQuery } from './types'; import { DataFrame, DataFrameDTO, @@ -9,7 +7,9 @@ import { readCSV, } from '@grafana/data'; +import InputDatasource, { describeDataFrame } from './InputDatasource'; import { getQueryOptions } from './testHelpers'; +import { InputOptions, InputQuery } from './types'; describe('InputDatasource', () => { const data = readCSV('a,b,c\n1,2,3\n4,5,6'); diff --git a/plugins-bundled/internal/input-datasource/src/InputQueryEditor.tsx b/plugins-bundled/internal/input-datasource/src/InputQueryEditor.tsx index e48b89ac31e..a8e3fcf9442 100644 --- a/plugins-bundled/internal/input-datasource/src/InputQueryEditor.tsx +++ b/plugins-bundled/internal/input-datasource/src/InputQueryEditor.tsx @@ -2,12 +2,11 @@ import React, { PureComponent } from 'react'; // Types +import { DataFrame, toCSV, SelectableValue, MutableDataFrame, QueryEditorProps } from '@grafana/data'; +import { Select, TableInputCSV, LinkButton, Icon, InlineField } from '@grafana/ui'; + import { InputDatasource, describeDataFrame } from './InputDatasource'; import { InputQuery, InputOptions } from './types'; - -import { Select, TableInputCSV, LinkButton, Icon, InlineField } from '@grafana/ui'; -import { DataFrame, toCSV, SelectableValue, MutableDataFrame, QueryEditorProps } from '@grafana/data'; - import { dataFrameToCSV } from './utils'; type Props = QueryEditorProps; diff --git a/plugins-bundled/internal/input-datasource/src/module.ts b/plugins-bundled/internal/input-datasource/src/module.ts index 708c95a841e..66765d458c5 100644 --- a/plugins-bundled/internal/input-datasource/src/module.ts +++ b/plugins-bundled/internal/input-datasource/src/module.ts @@ -1,9 +1,8 @@ import { DataSourcePlugin } from '@grafana/data'; -import { InputDatasource } from './InputDatasource'; - -import { InputQueryEditor } from './InputQueryEditor'; import { InputConfigEditor } from './InputConfigEditor'; +import { InputDatasource } from './InputDatasource'; +import { InputQueryEditor } from './InputQueryEditor'; import { InputOptions, InputQuery } from './types'; export const plugin = new DataSourcePlugin(InputDatasource) diff --git a/public/app/AppWrapper.tsx b/public/app/AppWrapper.tsx index f31867db17f..812e57c72e0 100644 --- a/public/app/AppWrapper.tsx +++ b/public/app/AppWrapper.tsx @@ -1,25 +1,27 @@ -import React, { ComponentType } from 'react'; -import { Router, Route, Redirect, Switch } from 'react-router-dom'; -import { config, locationService, navigationLogger, reportInteraction } from '@grafana/runtime'; -import { Provider } from 'react-redux'; -import { store } from 'app/store/store'; -import { ErrorBoundaryAlert, GlobalStyles, ModalRoot, ModalsProvider, PortalContainer } from '@grafana/ui'; -import { GrafanaApp } from './app'; -import { getAppRoutes } from 'app/routes/routes'; -import { ConfigContext, ThemeProvider } from './core/utils/ConfigProvider'; -import { RouteDescriptor } from './core/navigation/types'; -import { contextSrv } from './core/services/context_srv'; -import { NavBar } from './core/components/NavBar/NavBar'; -import { NavBarNext } from './core/components/NavBar/Next/NavBarNext'; -import { GrafanaRoute } from './core/navigation/GrafanaRoute'; -import { AppNotificationList } from './core/components/AppNotifications/AppNotificationList'; -import { SearchWrapper } from 'app/features/search'; -import { LiveConnectionWarning } from './features/live/LiveConnectionWarning'; import { Action, KBarProvider } from 'kbar'; -import { CommandPalette } from './features/commandPalette/CommandPalette'; -import { I18nProvider } from './core/localisation'; +import React, { ComponentType } from 'react'; +import { Provider } from 'react-redux'; +import { Router, Route, Redirect, Switch } from 'react-router-dom'; + +import { config, locationService, navigationLogger, reportInteraction } from '@grafana/runtime'; +import { ErrorBoundaryAlert, GlobalStyles, ModalRoot, ModalsProvider, PortalContainer } from '@grafana/ui'; +import { SearchWrapper } from 'app/features/search'; +import { getAppRoutes } from 'app/routes/routes'; +import { store } from 'app/store/store'; + import { AngularRoot } from './angular/AngularRoot'; import { loadAndInitAngularIfEnabled } from './angular/loadAndInitAngularIfEnabled'; +import { GrafanaApp } from './app'; +import { AppNotificationList } from './core/components/AppNotifications/AppNotificationList'; +import { NavBar } from './core/components/NavBar/NavBar'; +import { NavBarNext } from './core/components/NavBar/Next/NavBarNext'; +import { I18nProvider } from './core/localisation'; +import { GrafanaRoute } from './core/navigation/GrafanaRoute'; +import { RouteDescriptor } from './core/navigation/types'; +import { contextSrv } from './core/services/context_srv'; +import { ConfigContext, ThemeProvider } from './core/utils/ConfigProvider'; +import { CommandPalette } from './features/commandPalette/CommandPalette'; +import { LiveConnectionWarning } from './features/live/LiveConnectionWarning'; interface AppWrapperProps { app: GrafanaApp; diff --git a/public/app/angular/AngularApp.ts b/public/app/angular/AngularApp.ts index 29977589ea9..7bbdeba9768 100644 --- a/public/app/angular/AngularApp.ts +++ b/public/app/angular/AngularApp.ts @@ -1,24 +1,28 @@ -import angular from 'angular'; +import 'angular'; import 'angular-route'; import 'angular-sanitize'; import 'angular-bindonce'; import 'vendor/bootstrap/bootstrap'; import 'vendor/angular-other/angular-strap'; -import { config } from 'app/core/config'; + +import angular from 'angular'; // eslint-disable-line no-duplicate-imports +import { extend } from 'lodash'; + +import { getTemplateSrv } from '@grafana/runtime'; import coreModule, { angularModules } from 'app/angular/core_module'; +import appEvents from 'app/core/app_events'; +import { config } from 'app/core/config'; +import { contextSrv } from 'app/core/services/context_srv'; import { DashboardLoaderSrv } from 'app/features/dashboard/services/DashboardLoaderSrv'; +import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv'; +import { exposeToPlugin } from 'app/features/plugins/plugin_loader'; +import * as sdk from 'app/plugins/sdk'; + import { registerAngularDirectives } from './angular_wrappers'; import { initAngularRoutingBridge } from './bridgeReactAngularRouting'; import { monkeyPatchInjectorWithPreAssignedBindings } from './injectorMonkeyPatch'; -import { extend } from 'lodash'; -import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv'; -import { getTemplateSrv } from '@grafana/runtime'; -import { registerComponents } from './registerComponents'; -import { exposeToPlugin } from 'app/features/plugins/plugin_loader'; -import appEvents from 'app/core/app_events'; -import { contextSrv } from 'app/core/services/context_srv'; -import * as sdk from 'app/plugins/sdk'; import { promiseToDigest } from './promiseToDigest'; +import { registerComponents } from './registerComponents'; export class AngularApp { ngModuleDependencies: any[]; diff --git a/public/app/angular/AngularLocationWrapper.test.ts b/public/app/angular/AngularLocationWrapper.test.ts index fb5358d57fc..613e570af37 100644 --- a/public/app/angular/AngularLocationWrapper.test.ts +++ b/public/app/angular/AngularLocationWrapper.test.ts @@ -1,6 +1,7 @@ -import { AngularLocationWrapper } from './AngularLocationWrapper'; import { HistoryWrapper, locationService, setLocationService } from '@grafana/runtime'; +import { AngularLocationWrapper } from './AngularLocationWrapper'; + // The methods in this file are deprecated // Stub the deprecation warning here to prevent polluting the test output jest.mock('@grafana/data', () => ({ diff --git a/public/app/angular/AngularLocationWrapper.ts b/public/app/angular/AngularLocationWrapper.ts index 4c6f5c133c2..3da42635bd2 100644 --- a/public/app/angular/AngularLocationWrapper.ts +++ b/public/app/angular/AngularLocationWrapper.ts @@ -1,5 +1,5 @@ -import { locationSearchToObject, locationService, navigationLogger } from '@grafana/runtime'; import { deprecationWarning, urlUtil } from '@grafana/data'; +import { locationSearchToObject, locationService, navigationLogger } from '@grafana/runtime'; // Ref: https://github.com/angular/angular.js/blob/ae8e903edf88a83fedd116ae02c0628bf72b150c/src/ng/location.js#L5 const DEFAULT_PORTS: Record = { http: 80, https: 443, ftp: 21 }; diff --git a/public/app/angular/GrafanaCtrl.ts b/public/app/angular/GrafanaCtrl.ts index 0b2b9b88d5c..405c6729613 100644 --- a/public/app/angular/GrafanaCtrl.ts +++ b/public/app/angular/GrafanaCtrl.ts @@ -1,23 +1,19 @@ -// Libraries -// eslint-disable-next-line lodash/import-scope -import _ from 'lodash'; -import $ from 'jquery'; - -// Utils and servies -import { colors } from '@grafana/ui'; -import { setLegacyAngularInjector, setAppEvents, setAngularLoader } from '@grafana/runtime'; -import config from 'app/core/config'; -import coreModule from 'app/angular/core_module'; -import appEvents from 'app/core/app_events'; -import { AngularLoader } from 'app/angular/services/AngularLoader'; - -// Types -import { CoreEvents, AppEventEmitter, AppEventConsumer } from 'app/types'; -import { UtilSrv } from './services/UtilSrv'; -import { ContextSrv } from 'app/core/services/context_srv'; import { IRootScopeService, IAngularEvent, auto } from 'angular'; +import $ from 'jquery'; +import _ from 'lodash'; // eslint-disable-line lodash/import-scope + import { AppEvent } from '@grafana/data'; +import { setLegacyAngularInjector, setAppEvents, setAngularLoader } from '@grafana/runtime'; +import { colors } from '@grafana/ui'; +import coreModule from 'app/angular/core_module'; +import { AngularLoader } from 'app/angular/services/AngularLoader'; +import appEvents from 'app/core/app_events'; +import config from 'app/core/config'; +import { ContextSrv } from 'app/core/services/context_srv'; import { initGrafanaLive } from 'app/features/live'; +import { CoreEvents, AppEventEmitter, AppEventConsumer } from 'app/types'; + +import { UtilSrv } from './services/UtilSrv'; export type GrafanaRootScope = IRootScopeService & AppEventEmitter & AppEventConsumer & { colors: string[] }; diff --git a/public/app/angular/angular_wrappers.ts b/public/app/angular/angular_wrappers.ts index e70b00537cc..6827c913d8d 100644 --- a/public/app/angular/angular_wrappers.ts +++ b/public/app/angular/angular_wrappers.ts @@ -1,11 +1,3 @@ -import { react2AngularDirective } from 'app/angular/react2angular'; -import { QueryEditor as CloudMonitoringQueryEditor } from 'app/plugins/datasource/cloud-monitoring/components/QueryEditor'; -import { AnnotationQueryEditor as CloudMonitoringAnnotationQueryEditor } from 'app/plugins/datasource/cloud-monitoring/components/AnnotationQueryEditor'; -import { AnnotationQueryEditor as CloudWatchAnnotationQueryEditor } from 'app/plugins/datasource/cloudwatch/components/AnnotationQueryEditor'; -import PageHeader from '../core/components/PageHeader/PageHeader'; -import EmptyListCTA from '../core/components/EmptyListCTA/EmptyListCTA'; -import { TagFilter } from '../core/components/TagFilter/TagFilter'; -import { MetricSelect } from '../core/components/Select/MetricSelect'; import { ClipboardButton, ColorPicker, @@ -18,14 +10,23 @@ import { Spinner, UnitPicker, } from '@grafana/ui'; -import { LokiAnnotationsQueryEditor } from '../plugins/datasource/loki/components/AnnotationsQueryEditor'; -import { HelpModal } from '../core/components/help/HelpModal'; -import { Footer } from '../core/components/Footer/Footer'; +import { react2AngularDirective } from 'app/angular/react2angular'; import { FolderPicker } from 'app/core/components/Select/FolderPicker'; -import { SearchField, SearchResults, SearchResultsFilter } from '../features/search'; import { TimePickerSettings } from 'app/features/dashboard/components/DashboardSettings/TimePickerSettings'; +import { AnnotationQueryEditor as CloudMonitoringAnnotationQueryEditor } from 'app/plugins/datasource/cloud-monitoring/components/AnnotationQueryEditor'; +import { QueryEditor as CloudMonitoringQueryEditor } from 'app/plugins/datasource/cloud-monitoring/components/QueryEditor'; +import { AnnotationQueryEditor as CloudWatchAnnotationQueryEditor } from 'app/plugins/datasource/cloudwatch/components/AnnotationQueryEditor'; import QueryEditor from 'app/plugins/datasource/grafana-azure-monitor-datasource/components/QueryEditor/QueryEditor'; +import EmptyListCTA from '../core/components/EmptyListCTA/EmptyListCTA'; +import { Footer } from '../core/components/Footer/Footer'; +import PageHeader from '../core/components/PageHeader/PageHeader'; +import { MetricSelect } from '../core/components/Select/MetricSelect'; +import { TagFilter } from '../core/components/TagFilter/TagFilter'; +import { HelpModal } from '../core/components/help/HelpModal'; +import { SearchField, SearchResults, SearchResultsFilter } from '../features/search'; +import { LokiAnnotationsQueryEditor } from '../plugins/datasource/loki/components/AnnotationsQueryEditor'; + const { SecretFormField } = LegacyForms; export function registerAngularDirectives() { diff --git a/public/app/angular/array_join.ts b/public/app/angular/array_join.ts index b81d3596760..b57e1157b5f 100644 --- a/public/app/angular/array_join.ts +++ b/public/app/angular/array_join.ts @@ -1,4 +1,5 @@ import { isArray } from 'lodash'; + import coreModule from './core_module'; export function arrayJoin() { diff --git a/public/app/angular/bridgeReactAngularRouting.ts b/public/app/angular/bridgeReactAngularRouting.ts index bdfd5c09e28..1b10ce4da95 100644 --- a/public/app/angular/bridgeReactAngularRouting.ts +++ b/public/app/angular/bridgeReactAngularRouting.ts @@ -1,8 +1,10 @@ -import { coreModule } from './core_module'; -import { RouteProvider } from '../core/navigation/patch/RouteProvider'; -import { RouteParamsProvider } from '../core/navigation/patch/RouteParamsProvider'; import { ILocationService } from 'angular'; + +import { RouteParamsProvider } from '../core/navigation/patch/RouteParamsProvider'; +import { RouteProvider } from '../core/navigation/patch/RouteProvider'; + import { AngularLocationWrapper } from './AngularLocationWrapper'; +import { coreModule } from './core_module'; // Neutralizing Angular’s location tampering // https://stackoverflow.com/a/19825756 diff --git a/public/app/angular/components/form_dropdown/form_dropdown.ts b/public/app/angular/components/form_dropdown/form_dropdown.ts index 3fbec41def6..3f22ac329f7 100644 --- a/public/app/angular/components/form_dropdown/form_dropdown.ts +++ b/public/app/angular/components/form_dropdown/form_dropdown.ts @@ -1,6 +1,7 @@ -import { debounce, find, indexOf, map, isObject, escape, unescape } from 'lodash'; -import coreModule from '../../core_module'; import { ISCEService } from 'angular'; +import { debounce, find, indexOf, map, isObject, escape, unescape } from 'lodash'; + +import coreModule from '../../core_module'; import { promiseToDigest } from '../../promiseToDigest'; function typeaheadMatcher(this: any, item: string) { diff --git a/public/app/angular/components/info_popover.ts b/public/app/angular/components/info_popover.ts index 37fe61de5ba..41417f5a680 100644 --- a/public/app/angular/components/info_popover.ts +++ b/public/app/angular/components/info_popover.ts @@ -1,8 +1,9 @@ import { each } from 'lodash'; -import coreModule from 'app/angular/core_module'; // @ts-ignore import Drop from 'tether-drop'; +import coreModule from 'app/angular/core_module'; + export function infoPopover() { return { restrict: 'E', diff --git a/public/app/angular/components/jsontree.ts b/public/app/angular/components/jsontree.ts index 1628de803f0..4721ffcccaa 100644 --- a/public/app/angular/components/jsontree.ts +++ b/public/app/angular/components/jsontree.ts @@ -1,5 +1,5 @@ -import coreModule from 'app/angular/core_module'; import { JsonExplorer } from '@grafana/ui'; +import coreModule from 'app/angular/core_module'; coreModule.directive('jsonTree', [ function jsonTreeDirective() { diff --git a/public/app/angular/components/plugin_component.ts b/public/app/angular/components/plugin_component.ts index be9b7a8e450..0e6bd400d4f 100644 --- a/public/app/angular/components/plugin_component.ts +++ b/public/app/angular/components/plugin_component.ts @@ -1,12 +1,12 @@ import angular, { ILocationService } from 'angular'; import { each } from 'lodash'; -import config from 'app/core/config'; -import coreModule from 'app/angular/core_module'; - import { DataSourceApi, PanelEvents } from '@grafana/data'; -import { importDataSourcePlugin, importAppPlugin } from '../../features/plugins/plugin_loader'; +import coreModule from 'app/angular/core_module'; +import config from 'app/core/config'; + import { importPanelPlugin } from '../../features/plugins/importPanelPlugin'; +import { importDataSourcePlugin, importAppPlugin } from '../../features/plugins/plugin_loader'; /** @ngInject */ function pluginDirectiveLoader($compile: any, $http: any, $templateCache: any, $location: ILocationService) { diff --git a/public/app/angular/components/query_part_editor.ts b/public/app/angular/components/query_part_editor.ts index 3f85e55498b..e6235609de7 100644 --- a/public/app/angular/components/query_part_editor.ts +++ b/public/app/angular/components/query_part_editor.ts @@ -1,6 +1,8 @@ -import { debounce, each, map, partial, escape, unescape } from 'lodash'; import $ from 'jquery'; +import { debounce, each, map, partial, escape, unescape } from 'lodash'; + import coreModule from 'app/angular/core_module'; + import { promiseToDigest } from '../promiseToDigest'; const template = ` diff --git a/public/app/angular/components/scroll.ts b/public/app/angular/components/scroll.ts index 961241a1068..c9fbe69a515 100644 --- a/public/app/angular/components/scroll.ts +++ b/public/app/angular/components/scroll.ts @@ -1,6 +1,7 @@ -import $ from 'jquery'; // @ts-ignore import baron from 'baron'; +import $ from 'jquery'; + import coreModule from 'app/angular/core_module'; const scrollBarHTML = ` diff --git a/public/app/angular/components/sql_part/sql_part_editor.ts b/public/app/angular/components/sql_part/sql_part_editor.ts index 29bf91e9ca5..4f5c38c404b 100644 --- a/public/app/angular/components/sql_part/sql_part_editor.ts +++ b/public/app/angular/components/sql_part/sql_part_editor.ts @@ -1,5 +1,6 @@ -import { debounce, each, indexOf, map, partial, escape, unescape } from 'lodash'; import $ from 'jquery'; +import { debounce, each, indexOf, map, partial, escape, unescape } from 'lodash'; + import coreModule from 'app/angular/core_module'; const template = ` diff --git a/public/app/angular/diff-view.ts b/public/app/angular/diff-view.ts index 664edd0f381..d9b8c000d5b 100644 --- a/public/app/angular/diff-view.ts +++ b/public/app/angular/diff-view.ts @@ -1,7 +1,9 @@ import angular from 'angular'; -import coreModule from './core_module'; + import { GrafanaRootScope } from 'app/angular/GrafanaCtrl'; +import coreModule from './core_module'; + export class DeltaCtrl { observer: any; diff --git a/public/app/angular/dropdown_typeahead.ts b/public/app/angular/dropdown_typeahead.ts index c824c1a4bf8..8c803473029 100644 --- a/public/app/angular/dropdown_typeahead.ts +++ b/public/app/angular/dropdown_typeahead.ts @@ -1,5 +1,6 @@ -import { each, reduce } from 'lodash'; import $ from 'jquery'; +import { each, reduce } from 'lodash'; + import coreModule from './core_module'; /** @ngInject */ diff --git a/public/app/angular/filters/filters.ts b/public/app/angular/filters/filters.ts index c06d15547f2..3f8c7521ac4 100644 --- a/public/app/angular/filters/filters.ts +++ b/public/app/angular/filters/filters.ts @@ -1,8 +1,10 @@ -import { isArray, isNull, isObject, isUndefined } from 'lodash'; import angular from 'angular'; -import coreModule from '../core_module'; -import { getTemplateSrv, TemplateSrv } from 'app/features/templating/template_srv'; +import { isArray, isNull, isObject, isUndefined } from 'lodash'; + import { dateTime } from '@grafana/data'; +import { getTemplateSrv, TemplateSrv } from 'app/features/templating/template_srv'; + +import coreModule from '../core_module'; coreModule.filter('stringSort', () => { return (input: any) => { diff --git a/public/app/angular/jquery_extended.ts b/public/app/angular/jquery_extended.ts index e0fb3b9da5a..d878c87d188 100644 --- a/public/app/angular/jquery_extended.ts +++ b/public/app/angular/jquery_extended.ts @@ -1,5 +1,5 @@ -import $ from 'jquery'; import angular from 'angular'; +import $ from 'jquery'; import { extend } from 'lodash'; const $win = $(window); diff --git a/public/app/angular/metric_segment.ts b/public/app/angular/metric_segment.ts index d9a31182e55..cb171ac144e 100644 --- a/public/app/angular/metric_segment.ts +++ b/public/app/angular/metric_segment.ts @@ -1,8 +1,10 @@ -import { debounce, find, indexOf, map, escape, unescape } from 'lodash'; import $ from 'jquery'; -import coreModule from './core_module'; +import { debounce, find, indexOf, map, escape, unescape } from 'lodash'; + import { TemplateSrv } from 'app/features/templating/template_srv'; +import coreModule from './core_module'; + /** @ngInject */ export function metricSegment($compile: any, $sce: any, templateSrv: TemplateSrv) { const inputTemplate = diff --git a/public/app/angular/misc.ts b/public/app/angular/misc.ts index bd31ad80fdf..20899014740 100644 --- a/public/app/angular/misc.ts +++ b/public/app/angular/misc.ts @@ -1,4 +1,5 @@ import angular from 'angular'; + import coreModule from './core_module'; /** @ngInject */ diff --git a/public/app/angular/ng_model_on_blur.ts b/public/app/angular/ng_model_on_blur.ts index d79c60a9f3a..bd730cfc48b 100644 --- a/public/app/angular/ng_model_on_blur.ts +++ b/public/app/angular/ng_model_on_blur.ts @@ -1,6 +1,7 @@ -import coreModule from './core_module'; import { rangeUtil } from '@grafana/data'; +import coreModule from './core_module'; + function ngModelOnBlur() { return { restrict: 'A', diff --git a/public/app/angular/panel/metrics_panel_ctrl.ts b/public/app/angular/panel/metrics_panel_ctrl.ts index 530e945c8fb..a8f3b444181 100644 --- a/public/app/angular/panel/metrics_panel_ctrl.ts +++ b/public/app/angular/panel/metrics_panel_ctrl.ts @@ -1,7 +1,6 @@ import { isArray } from 'lodash'; -import { PanelCtrl } from 'app/angular/panel/panel_ctrl'; -import { applyPanelTimeOverrides } from 'app/features/dashboard/utils/panel'; -import { ContextSrv } from 'app/core/services/context_srv'; +import { Unsubscribable } from 'rxjs'; + import { DataFrame, DataQueryResponse, @@ -14,8 +13,11 @@ import { toDataFrameDTO, toLegacyResponseData, } from '@grafana/data'; -import { Unsubscribable } from 'rxjs'; +import { PanelCtrl } from 'app/angular/panel/panel_ctrl'; +import { ContextSrv } from 'app/core/services/context_srv'; import { PanelModel } from 'app/features/dashboard/state'; +import { applyPanelTimeOverrides } from 'app/features/dashboard/utils/panel'; + import { PanelQueryRunner } from '../../features/query/state/PanelQueryRunner'; class MetricsPanelCtrl extends PanelCtrl { diff --git a/public/app/angular/panel/panel_ctrl.ts b/public/app/angular/panel/panel_ctrl.ts index 2abb1c49531..249bb84c41b 100644 --- a/public/app/angular/panel/panel_ctrl.ts +++ b/public/app/angular/panel/panel_ctrl.ts @@ -1,7 +1,6 @@ -import { isString } from 'lodash'; -import config from 'app/core/config'; -import { profiler } from 'app/core/core'; import { auto } from 'angular'; +import { isString } from 'lodash'; + import { AppEvent, PanelEvents, @@ -10,8 +9,11 @@ import { EventBusExtended, EventBusSrv, } from '@grafana/data'; -import { DashboardModel } from '../../features/dashboard/state'; import { AngularLocationWrapper } from 'app/angular/AngularLocationWrapper'; +import config from 'app/core/config'; +import { profiler } from 'app/core/core'; + +import { DashboardModel } from '../../features/dashboard/state'; export class PanelCtrl { panel: any; diff --git a/public/app/angular/panel/panel_directive.ts b/public/app/angular/panel/panel_directive.ts index 81e18557961..44cc10856db 100644 --- a/public/app/angular/panel/panel_directive.ts +++ b/public/app/angular/panel/panel_directive.ts @@ -1,12 +1,15 @@ // @ts-ignore import baron from 'baron'; -import { PanelEvents } from '@grafana/data'; -import { PanelModel } from '../../features/dashboard/state'; -import { PanelCtrl } from './panel_ctrl'; import { Subscription } from 'rxjs'; -import { PanelDirectiveReadyEvent, RenderEvent } from 'app/types/events'; -import { coreModule } from 'app/angular/core_module'; + +import { PanelEvents } from '@grafana/data'; import { RefreshEvent } from '@grafana/runtime'; +import { coreModule } from 'app/angular/core_module'; +import { PanelDirectiveReadyEvent, RenderEvent } from 'app/types/events'; + +import { PanelModel } from '../../features/dashboard/state'; + +import { PanelCtrl } from './panel_ctrl'; const panelTemplate = ` diff --git a/public/app/angular/panel/query_ctrl.ts b/public/app/angular/panel/query_ctrl.ts index 8f1bea4e6cb..1a02ba248bf 100644 --- a/public/app/angular/panel/query_ctrl.ts +++ b/public/app/angular/panel/query_ctrl.ts @@ -1,5 +1,5 @@ -import { indexOf } from 'lodash'; import { auto } from 'angular'; +import { indexOf } from 'lodash'; export class QueryCtrl { target!: T; diff --git a/public/app/angular/panel/specs/metrics_panel_ctrl.test.ts b/public/app/angular/panel/specs/metrics_panel_ctrl.test.ts index bbef5517f5f..12b281be6ff 100644 --- a/public/app/angular/panel/specs/metrics_panel_ctrl.test.ts +++ b/public/app/angular/panel/specs/metrics_panel_ctrl.test.ts @@ -18,6 +18,7 @@ jest.mock('app/core/config', () => { }); import { PanelModel } from 'app/features/dashboard/state/PanelModel'; + import { MetricsPanelCtrl } from '../metrics_panel_ctrl'; describe('MetricsPanelCtrl', () => { diff --git a/public/app/angular/promiseToDigest.test.ts b/public/app/angular/promiseToDigest.test.ts index e2961a7ac76..3bc81b36b31 100644 --- a/public/app/angular/promiseToDigest.test.ts +++ b/public/app/angular/promiseToDigest.test.ts @@ -1,4 +1,5 @@ import { IScope } from 'angular'; + import { promiseToDigest } from './promiseToDigest'; describe('promiseToDigest', () => { diff --git a/public/app/angular/rebuild_on_change.ts b/public/app/angular/rebuild_on_change.ts index 243aacfe0b6..33cb1c01a1b 100644 --- a/public/app/angular/rebuild_on_change.ts +++ b/public/app/angular/rebuild_on_change.ts @@ -1,4 +1,5 @@ import $ from 'jquery'; + import coreModule from './core_module'; function getBlockNodes(nodes: any[]) { diff --git a/public/app/angular/registerComponents.ts b/public/app/angular/registerComponents.ts index c0fda500ad5..d5a142b9d87 100644 --- a/public/app/angular/registerComponents.ts +++ b/public/app/angular/registerComponents.ts @@ -3,9 +3,10 @@ import { contextSrv } from 'app/core/core'; import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv'; import { validationSrv } from 'app/features/manage-dashboards/services/ValidationSrv'; import { getLinkSrv } from 'app/features/panel/panellinks/link_srv'; + import coreModule from './core_module'; -import { AnnotationsSrv } from './services/annotations_srv'; import { UtilSrv } from './services/UtilSrv'; +import { AnnotationsSrv } from './services/annotations_srv'; export function registerComponents() { coreModule.factory('backendSrv', () => getBackendSrv()); diff --git a/public/app/angular/services/AngularLoader.ts b/public/app/angular/services/AngularLoader.ts index 438da88cc88..b6449330c2e 100644 --- a/public/app/angular/services/AngularLoader.ts +++ b/public/app/angular/services/AngularLoader.ts @@ -1,9 +1,9 @@ import angular from 'angular'; -import coreModule from 'app/angular/core_module'; import { assign } from 'lodash'; import { AngularComponent, AngularLoader as AngularLoaderInterface } from '@grafana/runtime'; import { GrafanaRootScope } from 'app/angular/GrafanaCtrl'; +import coreModule from 'app/angular/core_module'; export class AngularLoader implements AngularLoaderInterface { /** @ngInject */ diff --git a/public/app/angular/services/UtilSrv.ts b/public/app/angular/services/UtilSrv.ts index 6d2a970aa27..af45b08cc7a 100644 --- a/public/app/angular/services/UtilSrv.ts +++ b/public/app/angular/services/UtilSrv.ts @@ -1,8 +1,9 @@ -import { GrafanaRootScope } from 'app/angular/GrafanaCtrl'; -import { HideModalEvent, ShowModalEvent } from '../../types/events'; import { deprecationWarning } from '@grafana/data'; +import { GrafanaRootScope } from 'app/angular/GrafanaCtrl'; import { appEvents } from 'app/core/app_events'; +import { HideModalEvent, ShowModalEvent } from '../../types/events'; + /** * Old legacy utilSrv exposed to angular services and handles angular modals. * Not used by any core or known external plugin. diff --git a/public/app/angular/services/annotations_srv.ts b/public/app/angular/services/annotations_srv.ts index 3e90ee3e594..711becaf505 100644 --- a/public/app/angular/services/annotations_srv.ts +++ b/public/app/angular/services/annotations_srv.ts @@ -1,6 +1,6 @@ import { cloneDeep } from 'lodash'; -import { AnnotationEvent, deprecationWarning } from '@grafana/data'; +import { AnnotationEvent, deprecationWarning } from '@grafana/data'; import { deleteAnnotation, saveAnnotation, updateAnnotation } from 'app/features/annotations/api'; import { AnnotationQueryOptions } from 'app/features/annotations/types'; diff --git a/public/app/angular/services/dynamic_directive_srv.ts b/public/app/angular/services/dynamic_directive_srv.ts index 30c4c860240..c85c232a72c 100644 --- a/public/app/angular/services/dynamic_directive_srv.ts +++ b/public/app/angular/services/dynamic_directive_srv.ts @@ -1,4 +1,5 @@ import angular from 'angular'; + import coreModule from '../core_module'; class DynamicDirectiveSrv { diff --git a/public/app/angular/services/nav_model_srv.ts b/public/app/angular/services/nav_model_srv.ts index f5431849cea..73506625130 100644 --- a/public/app/angular/services/nav_model_srv.ts +++ b/public/app/angular/services/nav_model_srv.ts @@ -1,6 +1,6 @@ +import { NavModel, NavModelItem } from '@grafana/data'; import coreModule from 'app/angular/core_module'; import config from 'app/core/config'; -import { NavModel, NavModelItem } from '@grafana/data'; interface Nav { breadcrumbs: NavModelItem[]; diff --git a/public/app/angular/services/ng_react.ts b/public/app/angular/services/ng_react.ts index 92871463bd9..8f33ea560cf 100644 --- a/public/app/angular/services/ng_react.ts +++ b/public/app/angular/services/ng_react.ts @@ -9,10 +9,10 @@ // - reactComponent (generic directive for delegating off to React Components) // - reactDirective (factory for creating specific directives that correspond to reactComponent directives) +import angular, { auto } from 'angular'; import { kebabCase } from 'lodash'; import React, { ComponentType } from 'react'; import ReactDOM from 'react-dom'; -import angular, { auto } from 'angular'; // get a react component from name (components can be an angular injectable e.g. value, factory or // available on window diff --git a/public/app/angular/services/popover_srv.ts b/public/app/angular/services/popover_srv.ts index e84c0975f33..1d96e118ccd 100644 --- a/public/app/angular/services/popover_srv.ts +++ b/public/app/angular/services/popover_srv.ts @@ -1,8 +1,9 @@ import { extend } from 'lodash'; -import coreModule from 'app/angular/core_module'; // @ts-ignore import Drop from 'tether-drop'; + import { GrafanaRootScope } from 'app/angular/GrafanaCtrl'; +import coreModule from 'app/angular/core_module'; /** @ngInject */ function popoverSrv(this: any, $compile: any, $rootScope: GrafanaRootScope, $timeout: any) { diff --git a/public/app/angular/services/segment_srv.ts b/public/app/angular/services/segment_srv.ts index b0c37eee45c..434593adc9c 100644 --- a/public/app/angular/services/segment_srv.ts +++ b/public/app/angular/services/segment_srv.ts @@ -1,4 +1,5 @@ import { each, isString, map } from 'lodash'; + import coreModule from '../core_module'; /** @ngInject */ diff --git a/public/app/angular/services/timer.ts b/public/app/angular/services/timer.ts index 177b3fc156c..8d12b8361cc 100644 --- a/public/app/angular/services/timer.ts +++ b/public/app/angular/services/timer.ts @@ -1,6 +1,7 @@ -import { without, each } from 'lodash'; -import coreModule from 'app/angular/core_module'; import { ITimeoutService } from 'angular'; +import { without, each } from 'lodash'; + +import coreModule from 'app/angular/core_module'; // This service really just tracks a list of $timeout promises to give us a // method for canceling them all when we need to diff --git a/public/app/angular/tags.ts b/public/app/angular/tags.ts index aad0db6e6e2..f5c840500e9 100644 --- a/public/app/angular/tags.ts +++ b/public/app/angular/tags.ts @@ -1,6 +1,8 @@ import angular from 'angular'; -import { getTagColorsFromName } from '@grafana/ui'; import $ from 'jquery'; + +import { getTagColorsFromName } from '@grafana/ui'; + import coreModule from './core_module'; import 'vendor/tagsinput/bootstrap-tagsinput.js'; diff --git a/public/app/app.ts b/public/app/app.ts index 1ca8c0435d7..f0b7ee0337e 100644 --- a/public/app/app.ts +++ b/public/app/app.ts @@ -7,12 +7,12 @@ import './polyfills/old-mediaquerylist'; // Safari < 14 does not have mql.addEve import 'file-saver'; import 'jquery'; -// eslint-disable-next-line lodash/import-scope -import _ from 'lodash'; -import ReactDOM from 'react-dom'; +import 'app/features/all'; + +import _ from 'lodash'; // eslint-disable-line lodash/import-scope import React from 'react'; -import config from 'app/core/config'; -// @ts-ignore ignoring this for now, otherwise we would have to extend _ interface with move +import ReactDOM from 'react-dom'; + import { locationUtil, monacoLanguageRegistry, @@ -23,8 +23,6 @@ import { standardFieldConfigEditorRegistry, standardTransformersRegistry, } from '@grafana/data'; -import { arrayMove } from 'app/core/utils/arrayMove'; -import { preloadPlugins } from './features/plugins/pluginPreloader'; import { locationService, registerEchoBackend, @@ -34,44 +32,48 @@ import { setLocationSrv, setQueryRunnerFactory, } from '@grafana/runtime'; +import { setPanelDataErrorView } from '@grafana/runtime/src/components/PanelDataErrorView'; +import { setPanelRenderer } from '@grafana/runtime/src/components/PanelRenderer'; +import { getScrollbarWidth } from '@grafana/ui'; +import config from 'app/core/config'; +import { arrayMove } from 'app/core/utils/arrayMove'; +import { getStandardTransformers } from 'app/features/transformers/standardTransformers'; + +import getDefaultMonacoLanguages from '../lib/monaco-languages'; + +import { AppWrapper } from './AppWrapper'; +import { getAllOptionEditors, getAllStandardFieldConfigs } from './core/components/editors/registry'; +import { interceptLinkClicks } from './core/navigation/patch/interceptLinkClicks'; +import { ModalManager } from './core/services/ModalManager'; +import { backendSrv } from './core/services/backend_srv'; +import { contextSrv } from './core/services/context_srv'; import { Echo } from './core/services/echo/Echo'; import { reportPerformance } from './core/services/echo/EchoSrv'; import { PerformanceBackend } from './core/services/echo/backends/PerformanceBackend'; -import 'app/features/all'; -import { getScrollbarWidth } from '@grafana/ui'; -import { variableAdapters } from './features/variables/adapters'; -import { initDevFeatures } from './dev'; -import { getStandardTransformers } from 'app/features/transformers/standardTransformers'; -import { SentryEchoBackend } from './core/services/echo/backends/sentry/SentryBackend'; -import { setVariableQueryRunner, VariableQueryRunner } from './features/variables/query/VariableQueryRunner'; -import { configureStore } from './store/configureStore'; -import { AppWrapper } from './AppWrapper'; -import { interceptLinkClicks } from './core/navigation/patch/interceptLinkClicks'; -import { PanelRenderer } from './features/panel/components/PanelRenderer'; -import { QueryRunner } from './features/query/state/QueryRunner'; -import { getTimeSrv } from './features/dashboard/services/TimeSrv'; -import { getVariablesUrlParams } from './features/variables/getAllVariableValuesForUrl'; -import getDefaultMonacoLanguages from '../lib/monaco-languages'; -import { contextSrv } from './core/services/context_srv'; -import { GAEchoBackend } from './core/services/echo/backends/analytics/GABackend'; import { ApplicationInsightsBackend } from './core/services/echo/backends/analytics/ApplicationInsightsBackend'; +import { GAEchoBackend } from './core/services/echo/backends/analytics/GABackend'; import { RudderstackBackend } from './core/services/echo/backends/analytics/RudderstackBackend'; -import { getAllOptionEditors, getAllStandardFieldConfigs } from './core/components/editors/registry'; -import { backendSrv } from './core/services/backend_srv'; -import { setPanelRenderer } from '@grafana/runtime/src/components/PanelRenderer'; +import { SentryEchoBackend } from './core/services/echo/backends/sentry/SentryBackend'; +import { initDevFeatures } from './dev'; +import { getTimeSrv } from './features/dashboard/services/TimeSrv'; import { PanelDataErrorView } from './features/panel/components/PanelDataErrorView'; -import { setPanelDataErrorView } from '@grafana/runtime/src/components/PanelDataErrorView'; +import { PanelRenderer } from './features/panel/components/PanelRenderer'; import { DatasourceSrv } from './features/plugins/datasource_srv'; -import { ModalManager } from './core/services/ModalManager'; +import { preloadPlugins } from './features/plugins/pluginPreloader'; +import { QueryRunner } from './features/query/state/QueryRunner'; import { initWindowRuntime } from './features/runtime/init'; -import { createQueryVariableAdapter } from './features/variables/query/adapter'; -import { createCustomVariableAdapter } from './features/variables/custom/adapter'; -import { createTextBoxVariableAdapter } from './features/variables/textbox/adapter'; -import { createConstantVariableAdapter } from './features/variables/constant/adapter'; -import { createDataSourceVariableAdapter } from './features/variables/datasource/adapter'; -import { createIntervalVariableAdapter } from './features/variables/interval/adapter'; +import { variableAdapters } from './features/variables/adapters'; import { createAdHocVariableAdapter } from './features/variables/adhoc/adapter'; +import { createConstantVariableAdapter } from './features/variables/constant/adapter'; +import { createCustomVariableAdapter } from './features/variables/custom/adapter'; +import { createDataSourceVariableAdapter } from './features/variables/datasource/adapter'; +import { getVariablesUrlParams } from './features/variables/getAllVariableValuesForUrl'; +import { createIntervalVariableAdapter } from './features/variables/interval/adapter'; +import { setVariableQueryRunner, VariableQueryRunner } from './features/variables/query/VariableQueryRunner'; +import { createQueryVariableAdapter } from './features/variables/query/adapter'; import { createSystemVariableAdapter } from './features/variables/system/adapter'; +import { createTextBoxVariableAdapter } from './features/variables/textbox/adapter'; +import { configureStore } from './store/configureStore'; // add move to lodash for backward compatabilty with plugins // @ts-ignore diff --git a/public/app/core/components/AccessControl/AddPermission.tsx b/public/app/core/components/AccessControl/AddPermission.tsx index aef87a20de6..48ecd803555 100644 --- a/public/app/core/components/AccessControl/AddPermission.tsx +++ b/public/app/core/components/AccessControl/AddPermission.tsx @@ -1,9 +1,11 @@ import React, { useEffect, useMemo, useState } from 'react'; -import { UserPicker } from 'app/core/components/Select/UserPicker'; -import { TeamPicker } from 'app/core/components/Select/TeamPicker'; + import { Alert, Button, Form, HorizontalGroup, Input, Select } from '@grafana/ui'; -import { OrgRole } from 'app/types/acl'; import { CloseButton } from 'app/core/components/CloseButton/CloseButton'; +import { TeamPicker } from 'app/core/components/Select/TeamPicker'; +import { UserPicker } from 'app/core/components/Select/UserPicker'; +import { OrgRole } from 'app/types/acl'; + import { Assignments, PermissionTarget, SetPermission } from './types'; export interface Props { diff --git a/public/app/core/components/AccessControl/PermissionList.tsx b/public/app/core/components/AccessControl/PermissionList.tsx index 9b1fb961235..2deed480de7 100644 --- a/public/app/core/components/AccessControl/PermissionList.tsx +++ b/public/app/core/components/AccessControl/PermissionList.tsx @@ -1,6 +1,7 @@ import React from 'react'; -import { ResourcePermission } from './types'; + import { PermissionListItem } from './PermissionListItem'; +import { ResourcePermission } from './types'; interface Props { title: string; diff --git a/public/app/core/components/AccessControl/PermissionListItem.tsx b/public/app/core/components/AccessControl/PermissionListItem.tsx index ca88d08a5d8..6744c7ca167 100644 --- a/public/app/core/components/AccessControl/PermissionListItem.tsx +++ b/public/app/core/components/AccessControl/PermissionListItem.tsx @@ -1,7 +1,9 @@ import React from 'react'; -import { ResourcePermission } from './types'; + import { Button, Icon, Select, Tooltip } from '@grafana/ui'; +import { ResourcePermission } from './types'; + interface Props { item: ResourcePermission; permissionLevels: string[]; diff --git a/public/app/core/components/AccessControl/Permissions.tsx b/public/app/core/components/AccessControl/Permissions.tsx index b8dd561382d..b7fb44aaefa 100644 --- a/public/app/core/components/AccessControl/Permissions.tsx +++ b/public/app/core/components/AccessControl/Permissions.tsx @@ -1,9 +1,10 @@ -import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { sortBy } from 'lodash'; -import { getBackendSrv } from 'app/core/services/backend_srv'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { Button } from '@grafana/ui'; import { SlideDown } from 'app/core/components/Animations/SlideDown'; +import { getBackendSrv } from 'app/core/services/backend_srv'; + import { AddPermission } from './AddPermission'; import { PermissionList } from './PermissionList'; import { PermissionTarget, ResourcePermission, SetPermission, Description } from './types'; diff --git a/public/app/core/components/AppNotifications/AppNotificationItem.tsx b/public/app/core/components/AppNotifications/AppNotificationItem.tsx index 4b309a5b775..3ec1a2b59a2 100644 --- a/public/app/core/components/AppNotifications/AppNotificationItem.tsx +++ b/public/app/core/components/AppNotifications/AppNotificationItem.tsx @@ -1,8 +1,9 @@ +import { css } from '@emotion/css'; import React from 'react'; import { useEffectOnce } from 'react-use'; -import { css } from '@emotion/css'; -import { Alert, useStyles2 } from '@grafana/ui'; + import { GrafanaTheme2 } from '@grafana/data'; +import { Alert, useStyles2 } from '@grafana/ui'; import { AppNotification, timeoutMap } from 'app/types'; interface Props { diff --git a/public/app/core/components/AppNotifications/AppNotificationList.tsx b/public/app/core/components/AppNotifications/AppNotificationList.tsx index d9aba49843a..82723c43cb6 100644 --- a/public/app/core/components/AppNotifications/AppNotificationList.tsx +++ b/public/app/core/components/AppNotifications/AppNotificationList.tsx @@ -1,7 +1,10 @@ import React, { PureComponent } from 'react'; -import appEvents from 'app/core/app_events'; -import AppNotificationItem from './AppNotificationItem'; +import { connect, ConnectedProps } from 'react-redux'; + +import { AppEvents } from '@grafana/data'; +import { VerticalGroup } from '@grafana/ui'; import { notifyApp, hideAppNotification } from 'app/core/actions'; +import appEvents from 'app/core/app_events'; import { selectVisible } from 'app/core/reducers/appNotification'; import { StoreState } from 'app/types'; @@ -10,9 +13,8 @@ import { createSuccessNotification, createWarningNotification, } from '../../copy/appNotification'; -import { AppEvents } from '@grafana/data'; -import { connect, ConnectedProps } from 'react-redux'; -import { VerticalGroup } from '@grafana/ui'; + +import AppNotificationItem from './AppNotificationItem'; export interface OwnProps {} diff --git a/public/app/core/components/AppNotifications/StoredNotificationItem.tsx b/public/app/core/components/AppNotifications/StoredNotificationItem.tsx index ea044c362b8..d6fe2992b5a 100644 --- a/public/app/core/components/AppNotifications/StoredNotificationItem.tsx +++ b/public/app/core/components/AppNotifications/StoredNotificationItem.tsx @@ -1,9 +1,10 @@ -import React, { ReactNode } from 'react'; -import { formatDistanceToNow } from 'date-fns'; import { css } from '@emotion/css'; +import { formatDistanceToNow } from 'date-fns'; +import React, { ReactNode } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; -import { getIconFromSeverity } from '@grafana/ui/src/components/Alert/Alert'; import { Icon, IconButton, IconName, useTheme2 } from '@grafana/ui'; +import { getIconFromSeverity } from '@grafana/ui/src/components/Alert/Alert'; export type AlertVariant = 'success' | 'warning' | 'error' | 'info'; diff --git a/public/app/core/components/Branding/Branding.tsx b/public/app/core/components/Branding/Branding.tsx index 15035264f15..4968330dd59 100644 --- a/public/app/core/components/Branding/Branding.tsx +++ b/public/app/core/components/Branding/Branding.tsx @@ -1,7 +1,8 @@ -import React, { FC } from 'react'; import { css, cx } from '@emotion/css'; -import { useTheme2, styleMixins } from '@grafana/ui'; +import React, { FC } from 'react'; + import { colorManipulator } from '@grafana/data'; +import { useTheme2, styleMixins } from '@grafana/ui'; export interface BrandComponentProps { className?: string; diff --git a/public/app/core/components/CardButton.tsx b/public/app/core/components/CardButton.tsx index 45d87b600c4..d8a73799e12 100644 --- a/public/app/core/components/CardButton.tsx +++ b/public/app/core/components/CardButton.tsx @@ -1,5 +1,6 @@ -import React, { HTMLAttributes } from 'react'; import { css } from '@emotion/css'; +import React, { HTMLAttributes } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { Icon, IconName, useStyles2 } from '@grafana/ui'; diff --git a/public/app/core/components/CloseButton/CloseButton.tsx b/public/app/core/components/CloseButton/CloseButton.tsx index d9cd78f1783..1a6d000a12b 100644 --- a/public/app/core/components/CloseButton/CloseButton.tsx +++ b/public/app/core/components/CloseButton/CloseButton.tsx @@ -1,7 +1,8 @@ -import React from 'react'; import { css } from '@emotion/css'; -import { IconButton, useStyles2 } from '@grafana/ui'; +import React from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; +import { IconButton, useStyles2 } from '@grafana/ui'; type Props = { onClick: () => void; diff --git a/public/app/core/components/ColorScale/ColorScale.tsx b/public/app/core/components/ColorScale/ColorScale.tsx index 31080de26bd..ba9ece2581d 100644 --- a/public/app/core/components/ColorScale/ColorScale.tsx +++ b/public/app/core/components/ColorScale/ColorScale.tsx @@ -1,5 +1,6 @@ -import React, { useState, useEffect } from 'react'; import { css } from '@emotion/css'; +import React, { useState, useEffect } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { useTheme2 } from '@grafana/ui'; diff --git a/public/app/core/components/DynamicImports/ErrorLoadingChunk.tsx b/public/app/core/components/DynamicImports/ErrorLoadingChunk.tsx index a235c9a415d..927ce787251 100644 --- a/public/app/core/components/DynamicImports/ErrorLoadingChunk.tsx +++ b/public/app/core/components/DynamicImports/ErrorLoadingChunk.tsx @@ -1,6 +1,7 @@ -import React, { FunctionComponent } from 'react'; -import { Button, stylesFactory } from '@grafana/ui'; import { css } from '@emotion/css'; +import React, { FunctionComponent } from 'react'; + +import { Button, stylesFactory } from '@grafana/ui'; import { useUrlParams } from 'app/core/navigation/hooks'; const getStyles = stylesFactory(() => { diff --git a/public/app/core/components/DynamicImports/LoadingChunkPlaceHolder.tsx b/public/app/core/components/DynamicImports/LoadingChunkPlaceHolder.tsx index a5813a03252..220310882a2 100644 --- a/public/app/core/components/DynamicImports/LoadingChunkPlaceHolder.tsx +++ b/public/app/core/components/DynamicImports/LoadingChunkPlaceHolder.tsx @@ -1,4 +1,5 @@ import React, { FunctionComponent } from 'react'; + import { LoadingPlaceholder } from '@grafana/ui'; export const LoadingChunkPlaceHolder: FunctionComponent = React.memo(() => ( diff --git a/public/app/core/components/DynamicImports/SafeDynamicImport.test.tsx b/public/app/core/components/DynamicImports/SafeDynamicImport.test.tsx index 2b4a99d0f2e..6cd3ffd23ad 100644 --- a/public/app/core/components/DynamicImports/SafeDynamicImport.test.tsx +++ b/public/app/core/components/DynamicImports/SafeDynamicImport.test.tsx @@ -1,7 +1,8 @@ import React from 'react'; -import { loadComponentHandler } from './SafeDynamicImport'; + import { ErrorLoadingChunk } from './ErrorLoadingChunk'; import { LoadingChunkPlaceHolder } from './LoadingChunkPlaceHolder'; +import { loadComponentHandler } from './SafeDynamicImport'; describe('loadComponentHandler', () => { describe('when there is no error and pastDelay is false', () => { diff --git a/public/app/core/components/DynamicImports/SafeDynamicImport.tsx b/public/app/core/components/DynamicImports/SafeDynamicImport.tsx index 4544d88a5f1..193ed6712c4 100644 --- a/public/app/core/components/DynamicImports/SafeDynamicImport.tsx +++ b/public/app/core/components/DynamicImports/SafeDynamicImport.tsx @@ -1,9 +1,11 @@ import React from 'react'; import Loadable from 'react-loadable'; -import { LoadingChunkPlaceHolder } from './LoadingChunkPlaceHolder'; -import { ErrorLoadingChunk } from './ErrorLoadingChunk'; + import { GrafanaRouteComponent } from 'app/core/navigation/types'; +import { ErrorLoadingChunk } from './ErrorLoadingChunk'; +import { LoadingChunkPlaceHolder } from './LoadingChunkPlaceHolder'; + export const loadComponentHandler = (props: { error: Error; pastDelay: boolean }) => { const { error, pastDelay } = props; diff --git a/public/app/core/components/EmptyListCTA/EmptyListCTA.tsx b/public/app/core/components/EmptyListCTA/EmptyListCTA.tsx index 9dd81f6c69d..40ca25574b7 100644 --- a/public/app/core/components/EmptyListCTA/EmptyListCTA.tsx +++ b/public/app/core/components/EmptyListCTA/EmptyListCTA.tsx @@ -1,7 +1,8 @@ import { css } from '@emotion/css'; +import React, { MouseEvent } from 'react'; + import { selectors } from '@grafana/e2e-selectors'; import { Button, CallToActionCard, Icon, IconName, LinkButton } from '@grafana/ui'; -import React, { MouseEvent } from 'react'; export interface Props { title: string; diff --git a/public/app/core/components/ErrorPage/ErrorPage.tsx b/public/app/core/components/ErrorPage/ErrorPage.tsx index d12637698de..8fe3e4c645e 100644 --- a/public/app/core/components/ErrorPage/ErrorPage.tsx +++ b/public/app/core/components/ErrorPage/ErrorPage.tsx @@ -1,12 +1,14 @@ import React, { PureComponent } from 'react'; import { connect, MapStateToProps } from 'react-redux'; + import { NavModel } from '@grafana/data'; import { config } from '@grafana/runtime'; import { Icon } from '@grafana/ui'; -import Page from '../Page/Page'; import { getNavModel } from 'app/core/selectors/navModel'; import { StoreState } from 'app/types'; +import Page from '../Page/Page'; + interface ConnectedProps { navModel: NavModel; } diff --git a/public/app/core/components/FolderFilter/FolderFilter.tsx b/public/app/core/components/FolderFilter/FolderFilter.tsx index 8d149451713..795b3af7990 100644 --- a/public/app/core/components/FolderFilter/FolderFilter.tsx +++ b/public/app/core/components/FolderFilter/FolderFilter.tsx @@ -1,11 +1,11 @@ -import React, { useCallback, useMemo, useState } from 'react'; import { css } from '@emotion/css'; import debounce from 'debounce-promise'; -import { AsyncMultiSelect, Icon, Button, useStyles2 } from '@grafana/ui'; -import { GrafanaTheme2, SelectableValue } from '@grafana/data'; +import React, { useCallback, useMemo, useState } from 'react'; -import { FolderInfo, PermissionLevelString } from 'app/types'; +import { GrafanaTheme2, SelectableValue } from '@grafana/data'; +import { AsyncMultiSelect, Icon, Button, useStyles2 } from '@grafana/ui'; import { getBackendSrv } from 'app/core/services/backend_srv'; +import { FolderInfo, PermissionLevelString } from 'app/types'; export interface FolderFilterProps { onChange: (folder: FolderInfo[]) => void; diff --git a/public/app/core/components/Footer/Footer.tsx b/public/app/core/components/Footer/Footer.tsx index b3c045e2a37..4fa437b7913 100644 --- a/public/app/core/components/Footer/Footer.tsx +++ b/public/app/core/components/Footer/Footer.tsx @@ -1,4 +1,5 @@ import React, { FC } from 'react'; + import { config } from '@grafana/runtime'; import { Icon, IconName } from '@grafana/ui'; diff --git a/public/app/core/components/ForgottenPassword/ChangePassword.tsx b/public/app/core/components/ForgottenPassword/ChangePassword.tsx index 69c813b4a50..3a014973cb4 100644 --- a/public/app/core/components/ForgottenPassword/ChangePassword.tsx +++ b/public/app/core/components/ForgottenPassword/ChangePassword.tsx @@ -1,6 +1,8 @@ import React, { FC, SyntheticEvent } from 'react'; -import { Tooltip, Form, Field, VerticalGroup, Button } from '@grafana/ui'; + import { selectors } from '@grafana/e2e-selectors'; +import { Tooltip, Form, Field, VerticalGroup, Button } from '@grafana/ui'; + import { submitButton } from '../Login/LoginForm'; import { PasswordField } from '../PasswordField/PasswordField'; interface Props { diff --git a/public/app/core/components/ForgottenPassword/ChangePasswordPage.test.tsx b/public/app/core/components/ForgottenPassword/ChangePasswordPage.test.tsx index 0c558f6eadd..6df0b66cefb 100644 --- a/public/app/core/components/ForgottenPassword/ChangePasswordPage.test.tsx +++ b/public/app/core/components/ForgottenPassword/ChangePasswordPage.test.tsx @@ -1,6 +1,7 @@ -import React from 'react'; import { fireEvent, render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import React from 'react'; + import { getRouteComponentProps } from 'app/core/navigation/__mocks__/routeProps'; import { ChangePasswordPage, Props } from './ChangePasswordPage'; diff --git a/public/app/core/components/ForgottenPassword/ChangePasswordPage.tsx b/public/app/core/components/ForgottenPassword/ChangePasswordPage.tsx index 55bb5da34f3..70fe1ab4c06 100644 --- a/public/app/core/components/ForgottenPassword/ChangePasswordPage.tsx +++ b/public/app/core/components/ForgottenPassword/ChangePasswordPage.tsx @@ -1,9 +1,12 @@ import React, { FC } from 'react'; -import { LoginLayout, InnerBox } from '../Login/LoginLayout'; -import { ChangePassword } from './ChangePassword'; -import LoginCtrl from '../Login/LoginCtrl'; + import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; +import LoginCtrl from '../Login/LoginCtrl'; +import { LoginLayout, InnerBox } from '../Login/LoginLayout'; + +import { ChangePassword } from './ChangePassword'; + export interface Props extends GrafanaRouteComponentProps<{}, { code: string }> {} export const ChangePasswordPage: FC = (props) => { diff --git a/public/app/core/components/ForgottenPassword/ForgottenPassword.tsx b/public/app/core/components/ForgottenPassword/ForgottenPassword.tsx index 94b4f0b2ea8..c375b9bcff1 100644 --- a/public/app/core/components/ForgottenPassword/ForgottenPassword.tsx +++ b/public/app/core/components/ForgottenPassword/ForgottenPassword.tsx @@ -1,8 +1,9 @@ -import React, { FC, useState } from 'react'; -import { Form, Field, Input, Button, Legend, Container, useStyles, HorizontalGroup, LinkButton } from '@grafana/ui'; -import { getBackendSrv } from '@grafana/runtime'; import { css } from '@emotion/css'; +import React, { FC, useState } from 'react'; + import { GrafanaTheme } from '@grafana/data'; +import { getBackendSrv } from '@grafana/runtime'; +import { Form, Field, Input, Button, Legend, Container, useStyles, HorizontalGroup, LinkButton } from '@grafana/ui'; import config from 'app/core/config'; interface EmailDTO { diff --git a/public/app/core/components/ForgottenPassword/SendResetMailPage.test.tsx b/public/app/core/components/ForgottenPassword/SendResetMailPage.test.tsx index ff50fde844f..57da0cd1029 100644 --- a/public/app/core/components/ForgottenPassword/SendResetMailPage.test.tsx +++ b/public/app/core/components/ForgottenPassword/SendResetMailPage.test.tsx @@ -1,6 +1,6 @@ -import React from 'react'; import { fireEvent, render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import React from 'react'; import { SendResetMailPage } from './SendResetMailPage'; diff --git a/public/app/core/components/ForgottenPassword/SendResetMailPage.tsx b/public/app/core/components/ForgottenPassword/SendResetMailPage.tsx index 1ab5a36ff35..8c0e4797884 100644 --- a/public/app/core/components/ForgottenPassword/SendResetMailPage.tsx +++ b/public/app/core/components/ForgottenPassword/SendResetMailPage.tsx @@ -1,6 +1,7 @@ import React, { FC } from 'react'; import { LoginLayout, InnerBox } from '../Login/LoginLayout'; + import { ForgottenPassword } from './ForgottenPassword'; export const SendResetMailPage: FC = () => ( diff --git a/public/app/core/components/Layers/AddLayerButton.tsx b/public/app/core/components/Layers/AddLayerButton.tsx index 272735285ad..7bf53be8ba6 100644 --- a/public/app/core/components/Layers/AddLayerButton.tsx +++ b/public/app/core/components/Layers/AddLayerButton.tsx @@ -1,7 +1,7 @@ import React from 'react'; -import { ValuePicker } from '@grafana/ui'; import { SelectableValue } from '@grafana/data'; +import { ValuePicker } from '@grafana/ui'; type AddLayerButtonProps = { onChange: (sel: SelectableValue) => void; diff --git a/public/app/core/components/Layers/LayerDragDropList.tsx b/public/app/core/components/Layers/LayerDragDropList.tsx index 282ed0be587..d4ceae1dc90 100644 --- a/public/app/core/components/Layers/LayerDragDropList.tsx +++ b/public/app/core/components/Layers/LayerDragDropList.tsx @@ -1,9 +1,10 @@ +import { css, cx } from '@emotion/css'; import React from 'react'; import { DragDropContext, Draggable, Droppable, DropResult } from 'react-beautiful-dnd'; -import { css, cx } from '@emotion/css'; -import { Icon, IconButton, stylesFactory } from '@grafana/ui'; + import { GrafanaTheme } from '@grafana/data'; import { config } from '@grafana/runtime'; +import { Icon, IconButton, stylesFactory } from '@grafana/ui'; import { LayerName } from './LayerName'; import { LayerElement } from './types'; diff --git a/public/app/core/components/Layers/LayerName.test.tsx b/public/app/core/components/Layers/LayerName.test.tsx index 0fda27cf1ad..bd367d36174 100644 --- a/public/app/core/components/Layers/LayerName.test.tsx +++ b/public/app/core/components/Layers/LayerName.test.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { fireEvent, render, screen } from '@testing-library/react'; +import React from 'react'; + import { LayerNameProps, LayerName } from './LayerName'; describe('LayerName', () => { diff --git a/public/app/core/components/Layers/LayerName.tsx b/public/app/core/components/Layers/LayerName.tsx index c229d7f0099..dbf1c42bb1b 100644 --- a/public/app/core/components/Layers/LayerName.tsx +++ b/public/app/core/components/Layers/LayerName.tsx @@ -1,7 +1,8 @@ -import React, { useState } from 'react'; import { css, cx } from '@emotion/css'; -import { Icon, Input, FieldValidationMessage, useStyles } from '@grafana/ui'; +import React, { useState } from 'react'; + import { GrafanaTheme } from '@grafana/data'; +import { Icon, Input, FieldValidationMessage, useStyles } from '@grafana/ui'; export interface LayerNameProps { name: string; diff --git a/public/app/core/components/LocalStorageValueProvider/LocalStorageValueProvider.tsx b/public/app/core/components/LocalStorageValueProvider/LocalStorageValueProvider.tsx index c8923f3e1f6..621405329e8 100644 --- a/public/app/core/components/LocalStorageValueProvider/LocalStorageValueProvider.tsx +++ b/public/app/core/components/LocalStorageValueProvider/LocalStorageValueProvider.tsx @@ -1,4 +1,5 @@ import React, { PureComponent } from 'react'; + import store from '../../store'; export interface Props { diff --git a/public/app/core/components/Login/LoginCtrl.tsx b/public/app/core/components/Login/LoginCtrl.tsx index aa969a8d729..c7277237833 100644 --- a/public/app/core/components/Login/LoginCtrl.tsx +++ b/public/app/core/components/Login/LoginCtrl.tsx @@ -1,8 +1,9 @@ import React, { PureComponent } from 'react'; -import config from 'app/core/config'; + +import { AppEvents } from '@grafana/data'; import { getBackendSrv } from '@grafana/runtime'; import appEvents from 'app/core/app_events'; -import { AppEvents } from '@grafana/data'; +import config from 'app/core/config'; const isOauthEnabled = () => { return !!config.oauth && Object.keys(config.oauth).length > 0; diff --git a/public/app/core/components/Login/LoginForm.tsx b/public/app/core/components/Login/LoginForm.tsx index e7dc1d4d589..9364c5a0c13 100644 --- a/public/app/core/components/Login/LoginForm.tsx +++ b/public/app/core/components/Login/LoginForm.tsx @@ -1,10 +1,12 @@ +import { css } from '@emotion/css'; import React, { FC, ReactElement } from 'react'; + import { selectors } from '@grafana/e2e-selectors'; +import { Button, Form, Input, Field } from '@grafana/ui'; + +import { PasswordField } from '../PasswordField/PasswordField'; import { FormModel } from './LoginCtrl'; -import { Button, Form, Input, Field } from '@grafana/ui'; -import { css } from '@emotion/css'; -import { PasswordField } from '../PasswordField/PasswordField'; interface Props { children: ReactElement; diff --git a/public/app/core/components/Login/LoginLayout.tsx b/public/app/core/components/Login/LoginLayout.tsx index c2e5f44821d..5380f7b49c7 100644 --- a/public/app/core/components/Login/LoginLayout.tsx +++ b/public/app/core/components/Login/LoginLayout.tsx @@ -1,8 +1,10 @@ -import React, { FC, useEffect, useState } from 'react'; import { cx, css, keyframes } from '@emotion/css'; -import { useStyles2, styleMixins } from '@grafana/ui'; -import { Branding } from '../Branding/Branding'; +import React, { FC, useEffect, useState } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; +import { useStyles2, styleMixins } from '@grafana/ui'; + +import { Branding } from '../Branding/Branding'; import { Footer } from '../Footer/Footer'; interface InnerBoxProps { diff --git a/public/app/core/components/Login/LoginPage.test.tsx b/public/app/core/components/Login/LoginPage.test.tsx index 3791f5dac87..dbbf6ec4c9e 100644 --- a/public/app/core/components/Login/LoginPage.test.tsx +++ b/public/app/core/components/Login/LoginPage.test.tsx @@ -1,10 +1,11 @@ -import React from 'react'; import { fireEvent, render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { LoginPage } from './LoginPage'; +import React from 'react'; import * as runtimeMock from '@grafana/runtime'; +import { LoginPage } from './LoginPage'; + const postMock = jest.fn(); jest.mock('@grafana/runtime', () => ({ __esModule: true, diff --git a/public/app/core/components/Login/LoginPage.tsx b/public/app/core/components/Login/LoginPage.tsx index 581e248980e..bb49378ce60 100644 --- a/public/app/core/components/Login/LoginPage.tsx +++ b/public/app/core/components/Login/LoginPage.tsx @@ -1,17 +1,19 @@ // Libraries -import React, { FC } from 'react'; import { css } from '@emotion/css'; +import React, { FC } from 'react'; // Components -import { UserSignup } from './UserSignup'; -import { LoginServiceButtons } from './LoginServiceButtons'; +import { HorizontalGroup, LinkButton } from '@grafana/ui'; +import { Branding } from 'app/core/components/Branding/Branding'; +import config from 'app/core/config'; + +import { ChangePassword } from '../ForgottenPassword/ChangePassword'; + import LoginCtrl from './LoginCtrl'; import { LoginForm } from './LoginForm'; -import { ChangePassword } from '../ForgottenPassword/ChangePassword'; -import { Branding } from 'app/core/components/Branding/Branding'; -import { HorizontalGroup, LinkButton } from '@grafana/ui'; import { LoginLayout, InnerBox } from './LoginLayout'; -import config from 'app/core/config'; +import { LoginServiceButtons } from './LoginServiceButtons'; +import { UserSignup } from './UserSignup'; const forgottenPasswordStyles = css` padding: 0; diff --git a/public/app/core/components/Login/LoginServiceButtons.tsx b/public/app/core/components/Login/LoginServiceButtons.tsx index ab8a648aad7..69571d7241d 100644 --- a/public/app/core/components/Login/LoginServiceButtons.tsx +++ b/public/app/core/components/Login/LoginServiceButtons.tsx @@ -1,9 +1,10 @@ -import React from 'react'; -import config from 'app/core/config'; import { css, cx } from '@emotion/css'; -import { Icon, IconName, LinkButton, useStyles, useTheme2, VerticalGroup } from '@grafana/ui'; -import { GrafanaTheme, GrafanaTheme2, DEFAULT_SAML_NAME } from '@grafana/data'; import { pickBy } from 'lodash'; +import React from 'react'; + +import { GrafanaTheme, GrafanaTheme2, DEFAULT_SAML_NAME } from '@grafana/data'; +import { Icon, IconName, LinkButton, useStyles, useTheme2, VerticalGroup } from '@grafana/ui'; +import config from 'app/core/config'; export interface LoginService { bgColor: string; diff --git a/public/app/core/components/Login/UserSignup.tsx b/public/app/core/components/Login/UserSignup.tsx index 3f80b49b1fa..56113665b6d 100644 --- a/public/app/core/components/Login/UserSignup.tsx +++ b/public/app/core/components/Login/UserSignup.tsx @@ -1,6 +1,7 @@ -import React, { FC } from 'react'; -import { LinkButton, VerticalGroup } from '@grafana/ui'; import { css } from '@emotion/css'; +import React, { FC } from 'react'; + +import { LinkButton, VerticalGroup } from '@grafana/ui'; import { getConfig } from 'app/core/config'; export const UserSignup: FC<{}> = () => { diff --git a/public/app/core/components/NavBar/NavBar.test.tsx b/public/app/core/components/NavBar/NavBar.test.tsx index 94b89e36b35..39e2949a651 100644 --- a/public/app/core/components/NavBar/NavBar.test.tsx +++ b/public/app/core/components/NavBar/NavBar.test.tsx @@ -1,10 +1,13 @@ +import { render, screen } from '@testing-library/react'; import React from 'react'; import { Provider } from 'react-redux'; import { Router } from 'react-router-dom'; -import { render, screen } from '@testing-library/react'; + import { locationService } from '@grafana/runtime'; import { configureStore } from 'app/store/configureStore'; + import TestProvider from '../../../../test/helpers/TestProvider'; + import { NavBar } from './NavBar'; jest.mock('app/core/services/context_srv', () => ({ diff --git a/public/app/core/components/NavBar/NavBar.tsx b/public/app/core/components/NavBar/NavBar.tsx index a2c155df816..deb4a58b24e 100644 --- a/public/app/core/components/NavBar/NavBar.tsx +++ b/public/app/core/components/NavBar/NavBar.tsx @@ -1,21 +1,24 @@ +import { css, cx } from '@emotion/css'; +import { cloneDeep } from 'lodash'; import React, { useState } from 'react'; import { connect, ConnectedProps } from 'react-redux'; import { useLocation } from 'react-router-dom'; -import { css, cx } from '@emotion/css'; -import { cloneDeep } from 'lodash'; + import { GrafanaTheme2, NavModelItem, NavSection } from '@grafana/data'; -import { Icon, IconName, useTheme2 } from '@grafana/ui'; import { locationService } from '@grafana/runtime'; +import { Icon, IconName, useTheme2 } from '@grafana/ui'; import { Branding } from 'app/core/components/Branding/Branding'; import config from 'app/core/config'; import { getKioskMode } from 'app/core/navigation/kiosk'; import { KioskMode, StoreState } from 'app/types'; -import { enrichConfigItems, getActiveItem, isMatchOrChildMatch, isSearchActive, SEARCH_ITEM_ID } from './utils'; + import { OrgSwitcher } from '../OrgSwitcher'; + import NavBarItem from './NavBarItem'; -import { NavBarSection } from './NavBarSection'; -import { NavBarMenu } from './NavBarMenu'; import { NavBarItemWithoutMenu } from './NavBarItemWithoutMenu'; +import { NavBarMenu } from './NavBarMenu'; +import { NavBarSection } from './NavBarSection'; +import { enrichConfigItems, getActiveItem, isMatchOrChildMatch, isSearchActive, SEARCH_ITEM_ID } from './utils'; const homeUrl = config.appSubUrl || '/'; diff --git a/public/app/core/components/NavBar/NavBarItem.test.tsx b/public/app/core/components/NavBar/NavBarItem.test.tsx index dd11a26d8ac..1f72a08b4ee 100644 --- a/public/app/core/components/NavBar/NavBarItem.test.tsx +++ b/public/app/core/components/NavBar/NavBarItem.test.tsx @@ -1,9 +1,11 @@ -import React from 'react'; import { render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import React from 'react'; import { BrowserRouter } from 'react-router-dom'; + import { locationUtil } from '@grafana/data'; import { config, setLocationService } from '@grafana/runtime'; + import TestProvider from '../../../../test/helpers/TestProvider'; // Need to mock createBrowserHistory here to avoid errors diff --git a/public/app/core/components/NavBar/NavBarItem.tsx b/public/app/core/components/NavBar/NavBarItem.tsx index cf91ade17a4..55c2b339b0d 100644 --- a/public/app/core/components/NavBar/NavBarItem.tsx +++ b/public/app/core/components/NavBar/NavBarItem.tsx @@ -1,17 +1,18 @@ -import React, { ReactNode } from 'react'; -import { Item } from '@react-stately/collections'; import { css, cx } from '@emotion/css'; -import { GrafanaTheme2, locationUtil, NavMenuItemType, NavModelItem } from '@grafana/data'; -import { IconName, useTheme2 } from '@grafana/ui'; -import { locationService } from '@grafana/runtime'; - -import { NavBarMenuItem } from './NavBarMenuItem'; -import { getNavBarItemWithoutMenuStyles, NavBarItemWithoutMenu } from './NavBarItemWithoutMenu'; -import { NavBarItemMenuTrigger } from './NavBarItemMenuTrigger'; -import { NavBarItemMenu } from './NavBarItemMenu'; -import { getNavModelItemKey } from './utils'; import { useLingui } from '@lingui/react'; +import { Item } from '@react-stately/collections'; +import React, { ReactNode } from 'react'; + +import { GrafanaTheme2, locationUtil, NavMenuItemType, NavModelItem } from '@grafana/data'; +import { locationService } from '@grafana/runtime'; +import { IconName, useTheme2 } from '@grafana/ui'; + +import { NavBarItemMenu } from './NavBarItemMenu'; +import { NavBarItemMenuTrigger } from './NavBarItemMenuTrigger'; +import { getNavBarItemWithoutMenuStyles, NavBarItemWithoutMenu } from './NavBarItemWithoutMenu'; +import { NavBarMenuItem } from './NavBarMenuItem'; import menuItemTranslations from './navBarItem-translations'; +import { getNavModelItemKey } from './utils'; export interface Props { isActive?: boolean; diff --git a/public/app/core/components/NavBar/NavBarItemMenu.tsx b/public/app/core/components/NavBar/NavBarItemMenu.tsx index bff23a204a1..0fe05ead0ab 100644 --- a/public/app/core/components/NavBar/NavBarItemMenu.tsx +++ b/public/app/core/components/NavBar/NavBarItemMenu.tsx @@ -1,15 +1,16 @@ -import React, { ReactElement, useEffect, useRef } from 'react'; import { css } from '@emotion/css'; -import { useTheme2 } from '@grafana/ui'; -import { GrafanaTheme2, NavMenuItemType, NavModelItem } from '@grafana/data'; -import { SpectrumMenuProps } from '@react-types/menu'; import { useMenu } from '@react-aria/menu'; -import { useTreeState } from '@react-stately/tree'; import { mergeProps } from '@react-aria/utils'; +import { useTreeState } from '@react-stately/tree'; +import { SpectrumMenuProps } from '@react-types/menu'; +import React, { ReactElement, useEffect, useRef } from 'react'; + +import { GrafanaTheme2, NavMenuItemType, NavModelItem } from '@grafana/data'; +import { useTheme2 } from '@grafana/ui'; -import { getNavModelItemKey } from './utils'; -import { useNavBarItemMenuContext } from './context'; import { NavBarItemMenuItem } from './NavBarItemMenuItem'; +import { useNavBarItemMenuContext } from './context'; +import { getNavModelItemKey } from './utils'; export interface NavBarItemMenuProps extends SpectrumMenuProps { onNavigate: (item: NavModelItem) => void; diff --git a/public/app/core/components/NavBar/NavBarItemMenuItem.tsx b/public/app/core/components/NavBar/NavBarItemMenuItem.tsx index 4508e7f171c..ce1878789af 100644 --- a/public/app/core/components/NavBar/NavBarItemMenuItem.tsx +++ b/public/app/core/components/NavBar/NavBarItemMenuItem.tsx @@ -1,12 +1,13 @@ -import React, { ReactElement, useRef, useState } from 'react'; import { css } from '@emotion/css'; -import { useTheme2 } from '@grafana/ui'; -import { GrafanaTheme2, NavModelItem } from '@grafana/data'; -import { useMenuItem } from '@react-aria/menu'; import { useFocus, useKeyboard } from '@react-aria/interactions'; -import { TreeState } from '@react-stately/tree'; +import { useMenuItem } from '@react-aria/menu'; import { mergeProps } from '@react-aria/utils'; +import { TreeState } from '@react-stately/tree'; import { Node } from '@react-types/shared'; +import React, { ReactElement, useRef, useState } from 'react'; + +import { GrafanaTheme2, NavModelItem } from '@grafana/data'; +import { useTheme2 } from '@grafana/ui'; import { useNavBarItemMenuContext } from './context'; diff --git a/public/app/core/components/NavBar/NavBarItemMenuTrigger.tsx b/public/app/core/components/NavBar/NavBarItemMenuTrigger.tsx index a38fac31ede..cabdb29c934 100644 --- a/public/app/core/components/NavBar/NavBarItemMenuTrigger.tsx +++ b/public/app/core/components/NavBar/NavBarItemMenuTrigger.tsx @@ -1,19 +1,20 @@ -import React, { ReactElement, useEffect, useState } from 'react'; import { css, cx } from '@emotion/css'; -import { Icon, IconName, Link, useTheme2 } from '@grafana/ui'; -import { GrafanaTheme2, NavModelItem } from '@grafana/data'; -import { MenuTriggerProps } from '@react-types/menu'; -import { useMenuTriggerState } from '@react-stately/menu'; -import { useMenuTrigger } from '@react-aria/menu'; -import { useFocusWithin, useHover, useKeyboard } from '@react-aria/interactions'; import { useButton } from '@react-aria/button'; import { useDialog } from '@react-aria/dialog'; -import { DismissButton, useOverlay } from '@react-aria/overlays'; import { FocusScope } from '@react-aria/focus'; +import { useFocusWithin, useHover, useKeyboard } from '@react-aria/interactions'; +import { useMenuTrigger } from '@react-aria/menu'; +import { DismissButton, useOverlay } from '@react-aria/overlays'; +import { useMenuTriggerState } from '@react-stately/menu'; +import { MenuTriggerProps } from '@react-types/menu'; +import React, { ReactElement, useEffect, useState } from 'react'; -import { NavBarItemMenuContext } from './context'; -import { NavFeatureHighlight } from './NavFeatureHighlight'; +import { GrafanaTheme2, NavModelItem } from '@grafana/data'; import { reportExperimentView } from '@grafana/runtime'; +import { Icon, IconName, Link, useTheme2 } from '@grafana/ui'; + +import { NavFeatureHighlight } from './NavFeatureHighlight'; +import { NavBarItemMenuContext } from './context'; export interface NavBarItemMenuTriggerProps extends MenuTriggerProps { children: ReactElement; diff --git a/public/app/core/components/NavBar/NavBarItemWithoutMenu.tsx b/public/app/core/components/NavBar/NavBarItemWithoutMenu.tsx index e76f828e93d..3bbe1e4603a 100644 --- a/public/app/core/components/NavBar/NavBarItemWithoutMenu.tsx +++ b/public/app/core/components/NavBar/NavBarItemWithoutMenu.tsx @@ -1,7 +1,9 @@ -import React, { ReactNode } from 'react'; import { css, cx } from '@emotion/css'; +import React, { ReactNode } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { Link, useTheme2 } from '@grafana/ui'; + import { NavFeatureHighlight } from './NavFeatureHighlight'; export interface NavBarItemWithoutMenuProps { diff --git a/public/app/core/components/NavBar/NavBarMenu.test.tsx b/public/app/core/components/NavBar/NavBarMenu.test.tsx index ce87a514863..34059b553ff 100644 --- a/public/app/core/components/NavBar/NavBarMenu.test.tsx +++ b/public/app/core/components/NavBar/NavBarMenu.test.tsx @@ -1,8 +1,10 @@ -import React from 'react'; import { screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { NavModelItem } from '@grafana/data'; +import React from 'react'; import { render } from 'test/redux-rtl'; + +import { NavModelItem } from '@grafana/data'; + import { NavBarMenu } from './NavBarMenu'; describe('NavBarMenu', () => { diff --git a/public/app/core/components/NavBar/NavBarMenu.tsx b/public/app/core/components/NavBar/NavBarMenu.tsx index 91317e753e9..6cd7becbb61 100644 --- a/public/app/core/components/NavBar/NavBarMenu.tsx +++ b/public/app/core/components/NavBar/NavBarMenu.tsx @@ -1,10 +1,12 @@ +import { css } from '@emotion/css'; +import { useDialog } from '@react-aria/dialog'; +import { FocusScope } from '@react-aria/focus'; +import { useOverlay } from '@react-aria/overlays'; import React, { useRef } from 'react'; + import { GrafanaTheme2, NavModelItem } from '@grafana/data'; import { CustomScrollbar, Icon, IconButton, IconName, useTheme2 } from '@grafana/ui'; -import { FocusScope } from '@react-aria/focus'; -import { useDialog } from '@react-aria/dialog'; -import { useOverlay } from '@react-aria/overlays'; -import { css } from '@emotion/css'; + import { NavBarMenuItem } from './NavBarMenuItem'; export interface Props { diff --git a/public/app/core/components/NavBar/NavBarMenuItem.test.tsx b/public/app/core/components/NavBar/NavBarMenuItem.test.tsx index 64fa8e530dd..42e308bc047 100644 --- a/public/app/core/components/NavBar/NavBarMenuItem.test.tsx +++ b/public/app/core/components/NavBar/NavBarMenuItem.test.tsx @@ -1,6 +1,7 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; +import React from 'react'; import { BrowserRouter } from 'react-router-dom'; + import { NavBarMenuItem } from './NavBarMenuItem'; describe('NavBarMenuItem', () => { diff --git a/public/app/core/components/NavBar/NavBarMenuItem.tsx b/public/app/core/components/NavBar/NavBarMenuItem.tsx index b978cffc30e..3c84f54a806 100644 --- a/public/app/core/components/NavBar/NavBarMenuItem.tsx +++ b/public/app/core/components/NavBar/NavBarMenuItem.tsx @@ -1,7 +1,8 @@ +import { css } from '@emotion/css'; import React from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { Icon, IconName, Link, useTheme2 } from '@grafana/ui'; -import { css } from '@emotion/css'; export interface Props { icon?: IconName; diff --git a/public/app/core/components/NavBar/NavBarSection.tsx b/public/app/core/components/NavBar/NavBarSection.tsx index 55413be0d12..f4409b1e2a8 100644 --- a/public/app/core/components/NavBar/NavBarSection.tsx +++ b/public/app/core/components/NavBar/NavBarSection.tsx @@ -1,5 +1,6 @@ -import React, { ReactNode } from 'react'; import { css, cx } from '@emotion/css'; +import React, { ReactNode } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { useTheme2 } from '@grafana/ui'; diff --git a/public/app/core/components/NavBar/NavFeatureHighlight.tsx b/public/app/core/components/NavBar/NavFeatureHighlight.tsx index c698e959516..c51e322ace1 100644 --- a/public/app/core/components/NavBar/NavFeatureHighlight.tsx +++ b/public/app/core/components/NavBar/NavFeatureHighlight.tsx @@ -1,7 +1,8 @@ -import React from 'react'; import { css } from '@emotion/css'; -import { useStyles2 } from '@grafana/ui'; +import React from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; +import { useStyles2 } from '@grafana/ui'; export interface Props { children: JSX.Element; diff --git a/public/app/core/components/NavBar/Next/NavBarItem.tsx b/public/app/core/components/NavBar/Next/NavBarItem.tsx index 844686b6e00..8abff2d09df 100644 --- a/public/app/core/components/NavBar/Next/NavBarItem.tsx +++ b/public/app/core/components/NavBar/Next/NavBarItem.tsx @@ -1,18 +1,20 @@ -import React, { ReactNode } from 'react'; -import { Item } from '@react-stately/collections'; import { css, cx } from '@emotion/css'; -import { GrafanaTheme2, locationUtil, NavMenuItemType, NavModelItem } from '@grafana/data'; -import { IconName, useTheme2 } from '@grafana/ui'; -import { locationService } from '@grafana/runtime'; - -import { NavBarMenuItem } from './NavBarMenuItem'; -import { getNavBarItemWithoutMenuStyles, NavBarItemWithoutMenu } from './NavBarItemWithoutMenu'; -import { NavBarItemMenuTrigger } from './NavBarItemMenuTrigger'; -import { NavBarItemMenu } from './NavBarItemMenu'; -import { getNavModelItemKey } from '../utils'; import { useLingui } from '@lingui/react'; -import menuItemTranslations from '../navBarItem-translations'; +import { Item } from '@react-stately/collections'; +import React, { ReactNode } from 'react'; + +import { GrafanaTheme2, locationUtil, NavMenuItemType, NavModelItem } from '@grafana/data'; +import { locationService } from '@grafana/runtime'; +import { IconName, useTheme2 } from '@grafana/ui'; + import { useNavBarContext } from '../context'; +import menuItemTranslations from '../navBarItem-translations'; +import { getNavModelItemKey } from '../utils'; + +import { NavBarItemMenu } from './NavBarItemMenu'; +import { NavBarItemMenuTrigger } from './NavBarItemMenuTrigger'; +import { getNavBarItemWithoutMenuStyles, NavBarItemWithoutMenu } from './NavBarItemWithoutMenu'; +import { NavBarMenuItem } from './NavBarMenuItem'; export interface Props { isActive?: boolean; diff --git a/public/app/core/components/NavBar/Next/NavBarItemMenu.tsx b/public/app/core/components/NavBar/Next/NavBarItemMenu.tsx index 6b902ea6f03..bcc3b3863f3 100644 --- a/public/app/core/components/NavBar/Next/NavBarItemMenu.tsx +++ b/public/app/core/components/NavBar/Next/NavBarItemMenu.tsx @@ -1,15 +1,16 @@ -import React, { ReactElement, useEffect, useRef } from 'react'; import { css } from '@emotion/css'; -import { useTheme2 } from '@grafana/ui'; -import { GrafanaTheme2, NavMenuItemType, NavModelItem } from '@grafana/data'; -import { SpectrumMenuProps } from '@react-types/menu'; import { useMenu } from '@react-aria/menu'; -import { useTreeState } from '@react-stately/tree'; import { mergeProps } from '@react-aria/utils'; +import { useTreeState } from '@react-stately/tree'; +import { SpectrumMenuProps } from '@react-types/menu'; +import React, { ReactElement, useEffect, useRef } from 'react'; + +import { GrafanaTheme2, NavMenuItemType, NavModelItem } from '@grafana/data'; +import { useTheme2 } from '@grafana/ui'; -import { getNavModelItemKey } from '../utils'; -import { useNavBarItemMenuContext } from '../context'; import { NavBarItemMenuItem } from '../NavBarItemMenuItem'; +import { useNavBarItemMenuContext } from '../context'; +import { getNavModelItemKey } from '../utils'; export interface NavBarItemMenuProps extends SpectrumMenuProps { onNavigate: (item: NavModelItem) => void; diff --git a/public/app/core/components/NavBar/Next/NavBarItemMenuTrigger.tsx b/public/app/core/components/NavBar/Next/NavBarItemMenuTrigger.tsx index 30e44e6d463..b2d148439b7 100644 --- a/public/app/core/components/NavBar/Next/NavBarItemMenuTrigger.tsx +++ b/public/app/core/components/NavBar/Next/NavBarItemMenuTrigger.tsx @@ -1,19 +1,21 @@ -import React, { ReactElement, useEffect, useState } from 'react'; import { css, cx } from '@emotion/css'; -import { Icon, IconName, Link, useTheme2 } from '@grafana/ui'; -import { GrafanaTheme2, NavModelItem } from '@grafana/data'; -import { MenuTriggerProps } from '@react-types/menu'; -import { useMenuTriggerState } from '@react-stately/menu'; -import { useMenuTrigger } from '@react-aria/menu'; -import { useFocusWithin, useHover, useKeyboard } from '@react-aria/interactions'; import { useButton } from '@react-aria/button'; import { useDialog } from '@react-aria/dialog'; -import { DismissButton, OverlayContainer, useOverlay, useOverlayPosition } from '@react-aria/overlays'; import { FocusScope } from '@react-aria/focus'; +import { useFocusWithin, useHover, useKeyboard } from '@react-aria/interactions'; +import { useMenuTrigger } from '@react-aria/menu'; +import { DismissButton, OverlayContainer, useOverlay, useOverlayPosition } from '@react-aria/overlays'; +import { useMenuTriggerState } from '@react-stately/menu'; +import { MenuTriggerProps } from '@react-types/menu'; +import React, { ReactElement, useEffect, useState } from 'react'; -import { NavBarItemMenuContext, useNavBarContext } from '../context'; -import { NavFeatureHighlight } from '../NavFeatureHighlight'; +import { GrafanaTheme2, NavModelItem } from '@grafana/data'; import { reportExperimentView } from '@grafana/runtime'; +import { Icon, IconName, Link, useTheme2 } from '@grafana/ui'; + +import { NavFeatureHighlight } from '../NavFeatureHighlight'; +import { NavBarItemMenuContext, useNavBarContext } from '../context'; + import { getNavMenuPortalContainer } from './NavBarMenuPortalContainer'; export interface NavBarItemMenuTriggerProps extends MenuTriggerProps { diff --git a/public/app/core/components/NavBar/Next/NavBarItemWithoutMenu.tsx b/public/app/core/components/NavBar/Next/NavBarItemWithoutMenu.tsx index a8dd795fb10..160cc967e35 100644 --- a/public/app/core/components/NavBar/Next/NavBarItemWithoutMenu.tsx +++ b/public/app/core/components/NavBar/Next/NavBarItemWithoutMenu.tsx @@ -1,7 +1,9 @@ -import React, { ReactNode } from 'react'; import { css, cx } from '@emotion/css'; +import React, { ReactNode } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { Link, useTheme2 } from '@grafana/ui'; + import { NavFeatureHighlight } from '../NavFeatureHighlight'; export interface NavBarItemWithoutMenuProps { diff --git a/public/app/core/components/NavBar/Next/NavBarMenu.tsx b/public/app/core/components/NavBar/Next/NavBarMenu.tsx index c6e5cefd2b4..aab4a5d4343 100644 --- a/public/app/core/components/NavBar/Next/NavBarMenu.tsx +++ b/public/app/core/components/NavBar/Next/NavBarMenu.tsx @@ -1,17 +1,20 @@ +import { css, cx } from '@emotion/css'; +import { useDialog } from '@react-aria/dialog'; +import { FocusScope } from '@react-aria/focus'; +import { OverlayContainer, useOverlay } from '@react-aria/overlays'; import React, { useRef } from 'react'; import CSSTransition from 'react-transition-group/CSSTransition'; +import { useLocalStorage } from 'react-use'; + import { GrafanaTheme2, NavModelItem } from '@grafana/data'; import { CollapsableSection, CustomScrollbar, Icon, IconButton, IconName, useStyles2, useTheme2 } from '@grafana/ui'; -import { FocusScope } from '@react-aria/focus'; -import { useDialog } from '@react-aria/dialog'; -import { OverlayContainer, useOverlay } from '@react-aria/overlays'; -import { Branding } from 'app/core/components/Branding/Branding'; -import { css, cx } from '@emotion/css'; -import { NavBarMenuItem } from './NavBarMenuItem'; -import { NavBarItemWithoutMenu } from './NavBarItemWithoutMenu'; + +import { Branding } from '../../Branding/Branding'; import { isMatchOrChildMatch } from '../utils'; + +import { NavBarItemWithoutMenu } from './NavBarItemWithoutMenu'; +import { NavBarMenuItem } from './NavBarMenuItem'; import { NavBarToggle } from './NavBarToggle'; -import { useLocalStorage } from 'react-use'; export interface Props { activeItem?: NavModelItem; diff --git a/public/app/core/components/NavBar/Next/NavBarMenuItem.tsx b/public/app/core/components/NavBar/Next/NavBarMenuItem.tsx index 4b63b03fb49..08f54daeb99 100644 --- a/public/app/core/components/NavBar/Next/NavBarMenuItem.tsx +++ b/public/app/core/components/NavBar/Next/NavBarMenuItem.tsx @@ -1,7 +1,8 @@ +import { css, cx } from '@emotion/css'; import React from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { Icon, IconName, Link, useTheme2 } from '@grafana/ui'; -import { css, cx } from '@emotion/css'; export interface Props { icon?: IconName; diff --git a/public/app/core/components/NavBar/Next/NavBarMenuPortalContainer.tsx b/public/app/core/components/NavBar/Next/NavBarMenuPortalContainer.tsx index 7597f8f78b4..5d51ff0af89 100644 --- a/public/app/core/components/NavBar/Next/NavBarMenuPortalContainer.tsx +++ b/public/app/core/components/NavBar/Next/NavBarMenuPortalContainer.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { css } from '@emotion/css'; +import React from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { useTheme2 } from '@grafana/ui'; diff --git a/public/app/core/components/NavBar/Next/NavBarNext.test.tsx b/public/app/core/components/NavBar/Next/NavBarNext.test.tsx index c7d21ddfa81..5d0788750b9 100644 --- a/public/app/core/components/NavBar/Next/NavBarNext.test.tsx +++ b/public/app/core/components/NavBar/Next/NavBarNext.test.tsx @@ -1,10 +1,13 @@ +import { render, screen } from '@testing-library/react'; import React from 'react'; import { Provider } from 'react-redux'; import { Router } from 'react-router-dom'; -import { render, screen } from '@testing-library/react'; + import { locationService } from '@grafana/runtime'; import { configureStore } from 'app/store/configureStore'; + import TestProvider from '../../../../../test/helpers/TestProvider'; + import { NavBarNext } from './NavBarNext'; jest.mock('app/core/services/context_srv', () => ({ diff --git a/public/app/core/components/NavBar/Next/NavBarNext.tsx b/public/app/core/components/NavBar/Next/NavBarNext.tsx index 3a9410d8e15..4e9992e98d7 100644 --- a/public/app/core/components/NavBar/Next/NavBarNext.tsx +++ b/public/app/core/components/NavBar/Next/NavBarNext.tsx @@ -1,23 +1,26 @@ -import React, { useState } from 'react'; -import { useLocation } from 'react-router-dom'; import { css, cx } from '@emotion/css'; -import { cloneDeep } from 'lodash'; -import { GrafanaTheme2, NavModelItem, NavSection } from '@grafana/data'; -import { CustomScrollbar, Icon, IconName, useTheme2 } from '@grafana/ui'; -import { config, locationService } from '@grafana/runtime'; -import { getKioskMode } from 'app/core/navigation/kiosk'; -import { Branding } from 'app/core/components/Branding/Branding'; -import { KioskMode, StoreState } from 'app/types'; -import { enrichConfigItems, getActiveItem, isMatchOrChildMatch, isSearchActive, SEARCH_ITEM_ID } from '../utils'; -import { OrgSwitcher } from '../../OrgSwitcher'; -import { NavBarMenu } from './NavBarMenu'; -import NavBarItem from './NavBarItem'; -import { useSelector } from 'react-redux'; -import { NavBarItemWithoutMenu } from './NavBarItemWithoutMenu'; -import { NavBarContext } from '../context'; -import { NavBarToggle } from './NavBarToggle'; -import { NavBarMenuPortalContainer } from './NavBarMenuPortalContainer'; import { FocusScope } from '@react-aria/focus'; +import { cloneDeep } from 'lodash'; +import React, { useState } from 'react'; +import { useSelector } from 'react-redux'; +import { useLocation } from 'react-router-dom'; + +import { GrafanaTheme2, NavModelItem, NavSection } from '@grafana/data'; +import { config, locationService } from '@grafana/runtime'; +import { CustomScrollbar, Icon, IconName, useTheme2 } from '@grafana/ui'; +import { Branding } from 'app/core/components/Branding/Branding'; +import { getKioskMode } from 'app/core/navigation/kiosk'; +import { KioskMode, StoreState } from 'app/types'; + +import { OrgSwitcher } from '../../OrgSwitcher'; +import { NavBarContext } from '../context'; +import { enrichConfigItems, getActiveItem, isMatchOrChildMatch, isSearchActive, SEARCH_ITEM_ID } from '../utils'; + +import NavBarItem from './NavBarItem'; +import { NavBarItemWithoutMenu } from './NavBarItemWithoutMenu'; +import { NavBarMenu } from './NavBarMenu'; +import { NavBarMenuPortalContainer } from './NavBarMenuPortalContainer'; +import { NavBarToggle } from './NavBarToggle'; const onOpenSearch = () => { locationService.partial({ search: 'open' }); diff --git a/public/app/core/components/NavBar/Next/NavBarToggle.tsx b/public/app/core/components/NavBar/Next/NavBarToggle.tsx index 3d923604257..c913464e4b4 100644 --- a/public/app/core/components/NavBar/Next/NavBarToggle.tsx +++ b/public/app/core/components/NavBar/Next/NavBarToggle.tsx @@ -1,8 +1,9 @@ -import React from 'react'; -import { IconButton, useTheme2 } from '@grafana/ui'; -import { GrafanaTheme2 } from '@grafana/data'; import { css } from '@emotion/css'; import classnames from 'classnames'; +import React from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; +import { IconButton, useTheme2 } from '@grafana/ui'; export interface Props { className?: string; diff --git a/public/app/core/components/NavBar/navBarItem-translations.ts b/public/app/core/components/NavBar/navBarItem-translations.ts index d602a7584b8..51fbb29f32d 100644 --- a/public/app/core/components/NavBar/navBarItem-translations.ts +++ b/public/app/core/components/NavBar/navBarItem-translations.ts @@ -1,5 +1,5 @@ -import { defineMessage } from '@lingui/macro'; import { MessageDescriptor } from '@lingui/core'; +import { defineMessage } from '@lingui/macro'; // Maps the ID of the nav item to a translated phrase to later pass to // Because the navigation content is dynamic (defined in the backend), we can not use diff --git a/public/app/core/components/NavBar/utils.test.ts b/public/app/core/components/NavBar/utils.test.ts index 8da0b6bc565..23ac4adb156 100644 --- a/public/app/core/components/NavBar/utils.test.ts +++ b/public/app/core/components/NavBar/utils.test.ts @@ -1,7 +1,10 @@ import { Location } from 'history'; + import { NavModelItem } from '@grafana/data'; import { ContextSrv, setContextSrv } from 'app/core/services/context_srv'; + import { getConfig, updateConfig } from '../../config'; + import { enrichConfigItems, getActiveItem, getForcedLoginUrl, isMatchOrChildMatch, isSearchActive } from './utils'; jest.mock('../../app_events', () => ({ diff --git a/public/app/core/components/NavBar/utils.ts b/public/app/core/components/NavBar/utils.ts index 21bc5add093..83bc8705c44 100644 --- a/public/app/core/components/NavBar/utils.ts +++ b/public/app/core/components/NavBar/utils.ts @@ -1,7 +1,9 @@ import { Location } from 'history'; + import { NavModelItem, NavSection } from '@grafana/data'; import { getConfig } from 'app/core/config'; import { contextSrv } from 'app/core/services/context_srv'; + import { ShowModalReactEvent } from '../../../types/events'; import appEvents from '../../app_events'; import { getFooterLinks } from '../Footer/Footer'; diff --git a/public/app/core/components/NodeGraphSettings.tsx b/public/app/core/components/NodeGraphSettings.tsx index 669376a947e..6f305d4d7c3 100644 --- a/public/app/core/components/NodeGraphSettings.tsx +++ b/public/app/core/components/NodeGraphSettings.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { css } from '@emotion/css'; +import React from 'react'; + import { DataSourceJsonData, DataSourcePluginOptionsEditorProps, diff --git a/public/app/core/components/OrgSwitcher.tsx b/public/app/core/components/OrgSwitcher.tsx index 79189a12b56..1b89d7b0a14 100644 --- a/public/app/core/components/OrgSwitcher.tsx +++ b/public/app/core/components/OrgSwitcher.tsx @@ -1,12 +1,13 @@ -import React, { ReactElement } from 'react'; import { css } from '@emotion/css'; +import React, { ReactElement } from 'react'; +import { useAsync } from 'react-use'; + import { UserOrgDTO } from '@grafana/data'; import { Button, CustomScrollbar, Modal } from '@grafana/ui'; - -import { contextSrv } from 'app/core/services/context_srv'; import config from 'app/core/config'; +import { contextSrv } from 'app/core/services/context_srv'; + import { api } from '../../features/profile/api'; -import { useAsync } from 'react-use'; interface Props { onDismiss: () => void; diff --git a/public/app/core/components/Page/Page.tsx b/public/app/core/components/Page/Page.tsx index 0fdecd751b7..121b9ba1548 100644 --- a/public/app/core/components/Page/Page.tsx +++ b/public/app/core/components/Page/Page.tsx @@ -1,15 +1,17 @@ // Libraries +import { css, cx } from '@emotion/css'; import React, { FC, HTMLAttributes, useEffect } from 'react'; + +import { GrafanaTheme2, NavModel } from '@grafana/data'; +import { CustomScrollbar, useStyles2 } from '@grafana/ui'; import { getTitleFromNavModel } from 'app/core/selectors/navModel'; // Components -import PageHeader from '../PageHeader/PageHeader'; -import { Footer } from '../Footer/Footer'; -import { PageContents } from './PageContents'; -import { CustomScrollbar, useStyles2 } from '@grafana/ui'; -import { GrafanaTheme2, NavModel } from '@grafana/data'; import { Branding } from '../Branding/Branding'; -import { css, cx } from '@emotion/css'; +import { Footer } from '../Footer/Footer'; +import PageHeader from '../PageHeader/PageHeader'; + +import { PageContents } from './PageContents'; interface Props extends HTMLAttributes { children: React.ReactNode; diff --git a/public/app/core/components/Page/PageContents.tsx b/public/app/core/components/Page/PageContents.tsx index edfc9a019a6..cfbd1b850c6 100644 --- a/public/app/core/components/Page/PageContents.tsx +++ b/public/app/core/components/Page/PageContents.tsx @@ -1,6 +1,6 @@ // Libraries -import React, { FC } from 'react'; import { cx } from '@emotion/css'; +import React, { FC } from 'react'; // Components import PageLoader from '../PageLoader/PageLoader'; diff --git a/public/app/core/components/PageActionBar/PageActionBar.test.tsx b/public/app/core/components/PageActionBar/PageActionBar.test.tsx index 93f35b7100b..9e68addc3a2 100644 --- a/public/app/core/components/PageActionBar/PageActionBar.test.tsx +++ b/public/app/core/components/PageActionBar/PageActionBar.test.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { shallow } from 'enzyme'; +import React from 'react'; + import PageActionBar, { Props } from './PageActionBar'; const setup = (propOverrides?: object) => { diff --git a/public/app/core/components/PageActionBar/PageActionBar.tsx b/public/app/core/components/PageActionBar/PageActionBar.tsx index a3471875063..eac3fcc8f3c 100644 --- a/public/app/core/components/PageActionBar/PageActionBar.tsx +++ b/public/app/core/components/PageActionBar/PageActionBar.tsx @@ -1,4 +1,5 @@ import React, { PureComponent } from 'react'; + import { LinkButton, FilterInput } from '@grafana/ui'; export interface Props { diff --git a/public/app/core/components/PageHeader/PageHeader.test.tsx b/public/app/core/components/PageHeader/PageHeader.test.tsx index 03ac4b58663..2965d007142 100644 --- a/public/app/core/components/PageHeader/PageHeader.test.tsx +++ b/public/app/core/components/PageHeader/PageHeader.test.tsx @@ -1,6 +1,7 @@ -import React from 'react'; -import PageHeader from './PageHeader'; import { render, screen } from '@testing-library/react'; +import React from 'react'; + +import PageHeader from './PageHeader'; describe('PageHeader', () => { describe('when the nav tree has a node with a title', () => { diff --git a/public/app/core/components/PageHeader/PageHeader.tsx b/public/app/core/components/PageHeader/PageHeader.tsx index 8d770f6f051..116ff8186dd 100644 --- a/public/app/core/components/PageHeader/PageHeader.tsx +++ b/public/app/core/components/PageHeader/PageHeader.tsx @@ -1,8 +1,10 @@ -import React, { FC } from 'react'; import { css } from '@emotion/css'; -import { Tab, TabsBar, Icon, IconName, useStyles2 } from '@grafana/ui'; +import React, { FC } from 'react'; + import { NavModel, NavModelItem, NavModelBreadcrumb, GrafanaTheme2 } from '@grafana/data'; +import { Tab, TabsBar, Icon, IconName, useStyles2 } from '@grafana/ui'; import { PanelHeaderMenuItem } from 'app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenuItem'; + import { ProBadge } from '../Upgrade/ProBadge'; export interface Props { diff --git a/public/app/core/components/PageLoader/PageLoader.tsx b/public/app/core/components/PageLoader/PageLoader.tsx index ff4f4dc4c20..d7aee52c271 100644 --- a/public/app/core/components/PageLoader/PageLoader.tsx +++ b/public/app/core/components/PageLoader/PageLoader.tsx @@ -1,4 +1,5 @@ import React, { FC } from 'react'; + import { LoadingPlaceholder } from '@grafana/ui'; interface Props { diff --git a/public/app/core/components/PanelTypeFilter/PanelTypeFilter.tsx b/public/app/core/components/PanelTypeFilter/PanelTypeFilter.tsx index a0cd6362a56..5e8a27c8b1b 100644 --- a/public/app/core/components/PanelTypeFilter/PanelTypeFilter.tsx +++ b/public/app/core/components/PanelTypeFilter/PanelTypeFilter.tsx @@ -1,8 +1,9 @@ -import React, { useCallback, useMemo, useState } from 'react'; -import { GrafanaTheme2, PanelPluginMeta, SelectableValue } from '@grafana/data'; -import { getAllPanelPluginMeta } from 'app/features/panel/state/util'; -import { Icon, Button, MultiSelect, useStyles2 } from '@grafana/ui'; import { css } from '@emotion/css'; +import React, { useCallback, useMemo, useState } from 'react'; + +import { GrafanaTheme2, PanelPluginMeta, SelectableValue } from '@grafana/data'; +import { Icon, Button, MultiSelect, useStyles2 } from '@grafana/ui'; +import { getAllPanelPluginMeta } from 'app/features/panel/state/util'; export interface Props { onChange: (plugins: PanelPluginMeta[]) => void; diff --git a/public/app/core/components/PasswordField/PasswordField.test.tsx b/public/app/core/components/PasswordField/PasswordField.test.tsx index 98af3c901ba..3b985730768 100644 --- a/public/app/core/components/PasswordField/PasswordField.test.tsx +++ b/public/app/core/components/PasswordField/PasswordField.test.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { fireEvent, render, screen } from '@testing-library/react'; +import React from 'react'; + import { PasswordField } from './PasswordField'; describe('PasswordField', () => { diff --git a/public/app/core/components/PasswordField/PasswordField.tsx b/public/app/core/components/PasswordField/PasswordField.tsx index ec32963c364..1571f17186d 100644 --- a/public/app/core/components/PasswordField/PasswordField.tsx +++ b/public/app/core/components/PasswordField/PasswordField.tsx @@ -1,6 +1,6 @@ import React, { FC, useState } from 'react'; -import { selectors } from '@grafana/e2e-selectors'; +import { selectors } from '@grafana/e2e-selectors'; import { Input, IconButton } from '@grafana/ui'; export interface Props { diff --git a/public/app/core/components/PermissionList/AddPermission.tsx b/public/app/core/components/PermissionList/AddPermission.tsx index 3555c6ef4db..1095e782622 100644 --- a/public/app/core/components/PermissionList/AddPermission.tsx +++ b/public/app/core/components/PermissionList/AddPermission.tsx @@ -1,10 +1,11 @@ -import React, { Component } from 'react'; import { css } from '@emotion/css'; -import config from 'app/core/config'; -import { UserPicker } from 'app/core/components/Select/UserPicker'; -import { TeamPicker } from 'app/core/components/Select/TeamPicker'; -import { Button, Form, HorizontalGroup, Select, stylesFactory } from '@grafana/ui'; +import React, { Component } from 'react'; + import { GrafanaTheme, SelectableValue } from '@grafana/data'; +import { Button, Form, HorizontalGroup, Select, stylesFactory } from '@grafana/ui'; +import { TeamPicker } from 'app/core/components/Select/TeamPicker'; +import { UserPicker } from 'app/core/components/Select/UserPicker'; +import config from 'app/core/config'; import { OrgUser, Team } from 'app/types'; import { dashboardPermissionLevels, @@ -14,6 +15,7 @@ import { NewDashboardAclItem, OrgRole, } from 'app/types/acl'; + import { CloseButton } from '../CloseButton/CloseButton'; export interface Props { diff --git a/public/app/core/components/PermissionList/DisabledPermissionListItem.tsx b/public/app/core/components/PermissionList/DisabledPermissionListItem.tsx index a278cc29db0..2a96b8a25fd 100644 --- a/public/app/core/components/PermissionList/DisabledPermissionListItem.tsx +++ b/public/app/core/components/PermissionList/DisabledPermissionListItem.tsx @@ -1,4 +1,5 @@ import React, { Component } from 'react'; + import { Select, Icon, Button } from '@grafana/ui'; import { dashboardPermissionLevels } from 'app/types/acl'; diff --git a/public/app/core/components/PermissionList/PermissionList.tsx b/public/app/core/components/PermissionList/PermissionList.tsx index 043edc4bd27..02f4aee63fa 100644 --- a/public/app/core/components/PermissionList/PermissionList.tsx +++ b/public/app/core/components/PermissionList/PermissionList.tsx @@ -1,9 +1,11 @@ import React, { PureComponent } from 'react'; -import PermissionsListItem from './PermissionListItem'; -import DisabledPermissionsListItem from './DisabledPermissionListItem'; + import { FolderInfo } from 'app/types'; import { DashboardAcl } from 'app/types/acl'; +import DisabledPermissionsListItem from './DisabledPermissionListItem'; +import PermissionsListItem from './PermissionListItem'; + export interface Props { items: DashboardAcl[]; onRemoveItem: (item: DashboardAcl) => void; diff --git a/public/app/core/components/PermissionList/PermissionListItem.tsx b/public/app/core/components/PermissionList/PermissionListItem.tsx index e7ecf725494..35462db0b04 100644 --- a/public/app/core/components/PermissionList/PermissionListItem.tsx +++ b/public/app/core/components/PermissionList/PermissionListItem.tsx @@ -1,8 +1,9 @@ import React, { PureComponent } from 'react'; -import { Select, Icon, Button } from '@grafana/ui'; + import { SelectableValue } from '@grafana/data'; -import { dashboardPermissionLevels, DashboardAcl, PermissionLevel } from 'app/types/acl'; +import { Select, Icon, Button } from '@grafana/ui'; import { FolderInfo } from 'app/types'; +import { dashboardPermissionLevels, DashboardAcl, PermissionLevel } from 'app/types/acl'; const setClassNameHelper = (inherited: boolean) => { return inherited ? 'gf-form-disabled' : ''; diff --git a/public/app/core/components/PluginHelp/PluginHelp.tsx b/public/app/core/components/PluginHelp/PluginHelp.tsx index cf55ac09ee3..7ead1046e22 100644 --- a/public/app/core/components/PluginHelp/PluginHelp.tsx +++ b/public/app/core/components/PluginHelp/PluginHelp.tsx @@ -1,4 +1,5 @@ import React, { PureComponent } from 'react'; + import { renderMarkdown } from '@grafana/data'; import { getBackendSrv } from '@grafana/runtime'; diff --git a/public/app/core/components/QueryOperationRow/OperationRowHelp.tsx b/public/app/core/components/QueryOperationRow/OperationRowHelp.tsx index 874e900038e..9283db39cc7 100644 --- a/public/app/core/components/QueryOperationRow/OperationRowHelp.tsx +++ b/public/app/core/components/QueryOperationRow/OperationRowHelp.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { css, cx } from '@emotion/css'; +import React from 'react'; + import { GrafanaTheme2, renderMarkdown } from '@grafana/data'; import { useStyles2 } from '@grafana/ui'; diff --git a/public/app/core/components/QueryOperationRow/QueryOperationAction.test.tsx b/public/app/core/components/QueryOperationRow/QueryOperationAction.test.tsx index f61b06c0de6..1b6c4b328f6 100644 --- a/public/app/core/components/QueryOperationRow/QueryOperationAction.test.tsx +++ b/public/app/core/components/QueryOperationRow/QueryOperationAction.test.tsx @@ -1,6 +1,7 @@ -import React from 'react'; -import { QueryOperationAction } from './QueryOperationAction'; import { shallow } from 'enzyme'; +import React from 'react'; + +import { QueryOperationAction } from './QueryOperationAction'; describe('QueryOperationAction', () => { it('renders', () => { diff --git a/public/app/core/components/QueryOperationRow/QueryOperationAction.tsx b/public/app/core/components/QueryOperationRow/QueryOperationAction.tsx index 3f7f25806be..4c59c1ad952 100644 --- a/public/app/core/components/QueryOperationRow/QueryOperationAction.tsx +++ b/public/app/core/components/QueryOperationRow/QueryOperationAction.tsx @@ -1,8 +1,9 @@ -import { IconButton, IconName, useStyles2 } from '@grafana/ui'; -import React from 'react'; import { css, cx } from '@emotion/css'; +import React from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; +import { IconButton, IconName, useStyles2 } from '@grafana/ui'; interface QueryOperationActionProps { icon: IconName; diff --git a/public/app/core/components/QueryOperationRow/QueryOperationRow.test.tsx b/public/app/core/components/QueryOperationRow/QueryOperationRow.test.tsx index 400cc554ae5..afcccbf93fb 100644 --- a/public/app/core/components/QueryOperationRow/QueryOperationRow.test.tsx +++ b/public/app/core/components/QueryOperationRow/QueryOperationRow.test.tsx @@ -1,8 +1,9 @@ -import React from 'react'; -import { QueryOperationRow } from './QueryOperationRow'; import { mount, shallow } from 'enzyme'; +import React from 'react'; import { act } from 'react-dom/test-utils'; +import { QueryOperationRow } from './QueryOperationRow'; + describe('QueryOperationRow', () => { it('renders', () => { expect(() => diff --git a/public/app/core/components/QueryOperationRow/QueryOperationRow.tsx b/public/app/core/components/QueryOperationRow/QueryOperationRow.tsx index 4004424e07f..85f32fdfa08 100644 --- a/public/app/core/components/QueryOperationRow/QueryOperationRow.tsx +++ b/public/app/core/components/QueryOperationRow/QueryOperationRow.tsx @@ -1,10 +1,11 @@ -import React, { useCallback, useState } from 'react'; -import { Icon, ReactUtils, stylesFactory, useTheme } from '@grafana/ui'; -import { GrafanaTheme } from '@grafana/data'; import { css, cx } from '@emotion/css'; -import { useUpdateEffect } from 'react-use'; +import React, { useCallback, useState } from 'react'; import { Draggable } from 'react-beautiful-dnd'; +import { useUpdateEffect } from 'react-use'; + +import { GrafanaTheme } from '@grafana/data'; import { reportInteraction } from '@grafana/runtime'; +import { Icon, ReactUtils, stylesFactory, useTheme } from '@grafana/ui'; interface QueryOperationRowProps { index: number; diff --git a/public/app/core/components/RolePicker/RolePicker.tsx b/public/app/core/components/RolePicker/RolePicker.tsx index 7e31e4fb1d3..a916ed9a1d2 100644 --- a/public/app/core/components/RolePicker/RolePicker.tsx +++ b/public/app/core/components/RolePicker/RolePicker.tsx @@ -1,9 +1,11 @@ import React, { FormEvent, useCallback, useEffect, useState } from 'react'; + import { ClickOutsideWrapper, HorizontalGroup, Spinner } from '@grafana/ui'; -import { RolePickerMenu } from './RolePickerMenu'; -import { RolePickerInput } from './RolePickerInput'; import { Role, OrgRole } from 'app/types'; +import { RolePickerInput } from './RolePickerInput'; +import { RolePickerMenu } from './RolePickerMenu'; + export interface Props { builtInRole?: OrgRole; appliedRoles: Role[]; diff --git a/public/app/core/components/RolePicker/RolePickerInput.tsx b/public/app/core/components/RolePicker/RolePickerInput.tsx index 3108e2c0b2e..b650439532d 100644 --- a/public/app/core/components/RolePicker/RolePickerInput.tsx +++ b/public/app/core/components/RolePicker/RolePickerInput.tsx @@ -1,10 +1,13 @@ -import React, { FormEvent, HTMLProps, useEffect, useRef } from 'react'; import { css, cx } from '@emotion/css'; -import { useStyles2, getInputStyles, sharedInputStyle, styleMixins, Tooltip, Icon } from '@grafana/ui'; +import React, { FormEvent, HTMLProps, useEffect, useRef } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; -import { ValueContainer } from './ValueContainer'; +import { useStyles2, getInputStyles, sharedInputStyle, styleMixins, Tooltip, Icon } from '@grafana/ui'; + import { Role } from '../../../types'; +import { ValueContainer } from './ValueContainer'; + const stopPropagation = (event: React.MouseEvent) => event.stopPropagation(); interface InputProps extends HTMLProps { diff --git a/public/app/core/components/RolePicker/RolePickerMenu.tsx b/public/app/core/components/RolePicker/RolePickerMenu.tsx index 74c66a4aa0e..6ecc86fe487 100644 --- a/public/app/core/components/RolePicker/RolePickerMenu.tsx +++ b/public/app/core/components/RolePicker/RolePickerMenu.tsx @@ -1,5 +1,7 @@ -import React, { FormEvent, useEffect, useRef, useState } from 'react'; import { css, cx } from '@emotion/css'; +import React, { FormEvent, useEffect, useRef, useState } from 'react'; + +import { GrafanaTheme2, SelectableValue } from '@grafana/data'; import { Button, Checkbox, @@ -12,7 +14,6 @@ import { useStyles2, useTheme2, } from '@grafana/ui'; -import { GrafanaTheme2, SelectableValue } from '@grafana/data'; import { getSelectStyles } from '@grafana/ui/src/components/Select/getSelectStyles'; import { OrgRole, Role } from 'app/types'; diff --git a/public/app/core/components/RolePicker/TeamRolePicker.tsx b/public/app/core/components/RolePicker/TeamRolePicker.tsx index 3c35a342b82..dafbd3e78ab 100644 --- a/public/app/core/components/RolePicker/TeamRolePicker.tsx +++ b/public/app/core/components/RolePicker/TeamRolePicker.tsx @@ -1,6 +1,8 @@ import React, { FC, useEffect } from 'react'; import { useAsyncFn } from 'react-use'; + import { Role } from 'app/types'; + import { RolePicker } from './RolePicker'; import { fetchTeamRoles, updateTeamRoles } from './api'; diff --git a/public/app/core/components/RolePicker/UserRolePicker.tsx b/public/app/core/components/RolePicker/UserRolePicker.tsx index 5e5e1d2ffeb..e32bcb746ae 100644 --- a/public/app/core/components/RolePicker/UserRolePicker.tsx +++ b/public/app/core/components/RolePicker/UserRolePicker.tsx @@ -1,7 +1,9 @@ import React, { FC, useEffect } from 'react'; import { useAsyncFn } from 'react-use'; + import { contextSrv } from 'app/core/core'; import { Role, OrgRole, AccessControlAction } from 'app/types'; + import { RolePicker } from './RolePicker'; import { fetchUserRoles, updateUserRoles } from './api'; diff --git a/public/app/core/components/RolePicker/ValueContainer.tsx b/public/app/core/components/RolePicker/ValueContainer.tsx index 844819364e0..32c409892ac 100644 --- a/public/app/core/components/RolePicker/ValueContainer.tsx +++ b/public/app/core/components/RolePicker/ValueContainer.tsx @@ -1,7 +1,8 @@ -import React, { ReactNode } from 'react'; import { css, cx } from '@emotion/css'; -import { getInputStyles, Icon, IconName, useStyles2, getSelectStyles } from '@grafana/ui'; +import React, { ReactNode } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; +import { getInputStyles, Icon, IconName, useStyles2, getSelectStyles } from '@grafana/ui'; export interface Props { children: ReactNode; diff --git a/public/app/core/components/Select/DashboardPicker.tsx b/public/app/core/components/Select/DashboardPicker.tsx index cc74304e69f..fdec6a5cb83 100644 --- a/public/app/core/components/Select/DashboardPicker.tsx +++ b/public/app/core/components/Select/DashboardPicker.tsx @@ -1,9 +1,10 @@ -import React, { useCallback, useEffect, useState } from 'react'; import debounce from 'debounce-promise'; +import React, { useCallback, useEffect, useState } from 'react'; + import { SelectableValue } from '@grafana/data'; -import { DashboardSearchHit } from 'app/features/search/types'; -import { backendSrv } from 'app/core/services/backend_srv'; import { AsyncSelectProps, AsyncSelect } from '@grafana/ui'; +import { backendSrv } from 'app/core/services/backend_srv'; +import { DashboardSearchHit } from 'app/features/search/types'; import { DashboardDTO } from 'app/types'; interface Props diff --git a/public/app/core/components/Select/FolderPicker.test.tsx b/public/app/core/components/Select/FolderPicker.test.tsx index 43ad88e7902..2ccfdc3e467 100644 --- a/public/app/core/components/Select/FolderPicker.test.tsx +++ b/public/app/core/components/Select/FolderPicker.test.tsx @@ -1,9 +1,11 @@ -import React from 'react'; import { shallow } from 'enzyme'; +import React from 'react'; + +import * as api from 'app/features/manage-dashboards/state/actions'; + +import { DashboardSearchHit } from '../../../features/search/types'; import { FolderPicker, getInitialValues } from './FolderPicker'; -import * as api from 'app/features/manage-dashboards/state/actions'; -import { DashboardSearchHit } from '../../../features/search/types'; describe('FolderPicker', () => { it('should render', () => { diff --git a/public/app/core/components/Select/FolderPicker.tsx b/public/app/core/components/Select/FolderPicker.tsx index d877ac93afb..9c74b208868 100644 --- a/public/app/core/components/Select/FolderPicker.tsx +++ b/public/app/core/components/Select/FolderPicker.tsx @@ -1,13 +1,14 @@ -import React, { PureComponent } from 'react'; import { debounce } from 'lodash'; -import { AsyncSelect } from '@grafana/ui'; +import React, { PureComponent } from 'react'; + import { AppEvents, SelectableValue } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; - -import appEvents from '../../app_events'; +import { AsyncSelect } from '@grafana/ui'; import { contextSrv } from 'app/core/services/context_srv'; import { createFolder, getFolderById, searchFolders } from 'app/features/manage-dashboards/state/actions'; + import { AccessControlAction, PermissionLevelString } from '../../../types'; +import appEvents from '../../app_events'; export interface Props { onChange: ($folder: { title: string; id: number }) => void; diff --git a/public/app/core/components/Select/MetricSelect.test.tsx b/public/app/core/components/Select/MetricSelect.test.tsx index fef81075285..7dc5066a78b 100644 --- a/public/app/core/components/Select/MetricSelect.test.tsx +++ b/public/app/core/components/Select/MetricSelect.test.tsx @@ -1,9 +1,12 @@ -import React from 'react'; import { shallow } from 'enzyme'; -import { MetricSelect } from './MetricSelect'; +import React from 'react'; + import { LegacyForms } from '@grafana/ui'; + import { expect } from '../../../../test/lib/common'; +import { MetricSelect } from './MetricSelect'; + const { Select } = LegacyForms; describe('MetricSelect', () => { diff --git a/public/app/core/components/Select/MetricSelect.tsx b/public/app/core/components/Select/MetricSelect.tsx index cafc9e6d4ef..bfd0f54c88c 100644 --- a/public/app/core/components/Select/MetricSelect.tsx +++ b/public/app/core/components/Select/MetricSelect.tsx @@ -1,8 +1,8 @@ -import React, { useMemo, useCallback, FC } from 'react'; import { flatten } from 'lodash'; +import React, { useMemo, useCallback, FC } from 'react'; -import { LegacyForms } from '@grafana/ui'; import { SelectableValue } from '@grafana/data'; +import { LegacyForms } from '@grafana/ui'; import { Variable } from 'app/types/templates'; const { Select } = LegacyForms; diff --git a/public/app/core/components/Select/OrgPicker.tsx b/public/app/core/components/Select/OrgPicker.tsx index b30d24015f3..ed2c2c43524 100644 --- a/public/app/core/components/Select/OrgPicker.tsx +++ b/public/app/core/components/Select/OrgPicker.tsx @@ -1,9 +1,10 @@ import React, { useEffect } from 'react'; +import { useAsyncFn } from 'react-use'; + +import { SelectableValue } from '@grafana/data'; import { AsyncSelect } from '@grafana/ui'; import { getBackendSrv } from 'app/core/services/backend_srv'; import { Organization } from 'app/types'; -import { SelectableValue } from '@grafana/data'; -import { useAsyncFn } from 'react-use'; export type OrgSelectItem = SelectableValue; diff --git a/public/app/core/components/Select/ReadonlyFolderPicker/ReadonlyFolderPicker.test.tsx b/public/app/core/components/Select/ReadonlyFolderPicker/ReadonlyFolderPicker.test.tsx index 9a1ad8feb5d..ac78be8ca21 100644 --- a/public/app/core/components/Select/ReadonlyFolderPicker/ReadonlyFolderPicker.test.tsx +++ b/public/app/core/components/Select/ReadonlyFolderPicker/ReadonlyFolderPicker.test.tsx @@ -1,14 +1,16 @@ -import React from 'react'; -import { SelectableValue } from '@grafana/data'; import { render, waitFor, within } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import React from 'react'; import { byTestId } from 'testing-library-selector'; -import * as api from './api'; -import { FolderInfo, PermissionLevelString } from '../../../../types'; -import { ALL_FOLDER, GENERAL_FOLDER, ReadonlyFolderPicker, ReadonlyFolderPickerProps } from './ReadonlyFolderPicker'; +import { SelectableValue } from '@grafana/data'; import { selectors as e2eSelectors } from '@grafana/e2e-selectors'; +import { FolderInfo, PermissionLevelString } from '../../../../types'; + +import { ALL_FOLDER, GENERAL_FOLDER, ReadonlyFolderPicker, ReadonlyFolderPickerProps } from './ReadonlyFolderPicker'; +import * as api from './api'; + const FOLDERS = [ { value: GENERAL_FOLDER, label: GENERAL_FOLDER.title }, { value: { id: 1, title: 'Test' }, label: 'Test' }, diff --git a/public/app/core/components/Select/ReadonlyFolderPicker/ReadonlyFolderPicker.tsx b/public/app/core/components/Select/ReadonlyFolderPicker/ReadonlyFolderPicker.tsx index f3c0265d813..1a9dbf764bb 100644 --- a/public/app/core/components/Select/ReadonlyFolderPicker/ReadonlyFolderPicker.tsx +++ b/public/app/core/components/Select/ReadonlyFolderPicker/ReadonlyFolderPicker.tsx @@ -1,13 +1,15 @@ -import React, { ReactElement, useCallback, useState } from 'react'; import debouncePromise from 'debounce-promise'; +import React, { ReactElement, useCallback, useState } from 'react'; + import { SelectableValue } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; import { AsyncSelect } from '@grafana/ui'; +import { GENERAL_FOLDER_ID, GENERAL_FOLDER_TITLE } from '../../../../features/search/constants'; import { FolderInfo, PermissionLevelString } from '../../../../types'; + import { findOptionWithId, getFolderAsOption, getFoldersAsOptions } from './api'; import { PermissionLevel } from './types'; -import { GENERAL_FOLDER_ID, GENERAL_FOLDER_TITLE } from '../../../../features/search/constants'; export const ALL_FOLDER: FolderInfo = { id: undefined, title: 'All' }; export const GENERAL_FOLDER: FolderInfo = { id: GENERAL_FOLDER_ID, title: GENERAL_FOLDER_TITLE }; diff --git a/public/app/core/components/Select/ReadonlyFolderPicker/api.test.ts b/public/app/core/components/Select/ReadonlyFolderPicker/api.test.ts index e94176af7f5..46ab7d3adb8 100644 --- a/public/app/core/components/Select/ReadonlyFolderPicker/api.test.ts +++ b/public/app/core/components/Select/ReadonlyFolderPicker/api.test.ts @@ -1,9 +1,10 @@ +import { silenceConsoleOutput } from '../../../../../test/core/utils/silenceConsoleOutput'; import * as api from '../../../../features/manage-dashboards/state/actions'; -import { getFolderAsOption, getFoldersAsOptions } from './api'; import { DashboardSearchHit } from '../../../../features/search/types'; import { PermissionLevelString } from '../../../../types'; + import { ALL_FOLDER, GENERAL_FOLDER } from './ReadonlyFolderPicker'; -import { silenceConsoleOutput } from '../../../../../test/core/utils/silenceConsoleOutput'; +import { getFolderAsOption, getFoldersAsOptions } from './api'; function getTestContext( searchHits: DashboardSearchHit[] = [], diff --git a/public/app/core/components/Select/ReadonlyFolderPicker/api.ts b/public/app/core/components/Select/ReadonlyFolderPicker/api.ts index 06a84c4bbb4..8641fd9a6fd 100644 --- a/public/app/core/components/Select/ReadonlyFolderPicker/api.ts +++ b/public/app/core/components/Select/ReadonlyFolderPicker/api.ts @@ -1,7 +1,8 @@ import { SelectableValue } from '@grafana/data'; -import { FolderInfo, PermissionLevelString } from '../../../../types'; import { getFolderById, searchFolders } from '../../../../features/manage-dashboards/state/actions'; +import { FolderInfo, PermissionLevelString } from '../../../../types'; + import { PermissionLevel } from './types'; interface GetFoldersArgs { diff --git a/public/app/core/components/Select/SortPicker.tsx b/public/app/core/components/Select/SortPicker.tsx index e2f2a682939..98175eb0f55 100644 --- a/public/app/core/components/Select/SortPicker.tsx +++ b/public/app/core/components/Select/SortPicker.tsx @@ -1,8 +1,10 @@ import React, { FC } from 'react'; import { useAsync } from 'react-use'; -import { Icon, Select } from '@grafana/ui'; + import { SelectableValue } from '@grafana/data'; +import { Icon, Select } from '@grafana/ui'; import { DEFAULT_SORT } from 'app/features/search/constants'; + import { SearchSrv } from '../../services/search_srv'; const searchSrv = new SearchSrv(); diff --git a/public/app/core/components/Select/TeamPicker.test.tsx b/public/app/core/components/Select/TeamPicker.test.tsx index c24e25324d0..1ade476e68b 100644 --- a/public/app/core/components/Select/TeamPicker.test.tsx +++ b/public/app/core/components/Select/TeamPicker.test.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; +import React from 'react'; + import { TeamPicker } from './TeamPicker'; jest.mock('@grafana/runtime', () => ({ diff --git a/public/app/core/components/Select/TeamPicker.tsx b/public/app/core/components/Select/TeamPicker.tsx index db17af605d4..79079c21d75 100644 --- a/public/app/core/components/Select/TeamPicker.tsx +++ b/public/app/core/components/Select/TeamPicker.tsx @@ -1,8 +1,9 @@ -import React, { Component } from 'react'; import { debounce, isNil } from 'lodash'; -import { AsyncSelect } from '@grafana/ui'; +import React, { Component } from 'react'; + import { SelectableValue } from '@grafana/data'; import { getBackendSrv } from '@grafana/runtime'; +import { AsyncSelect } from '@grafana/ui'; import { Team } from 'app/types'; export interface Props { diff --git a/public/app/core/components/Select/UserPicker.test.tsx b/public/app/core/components/Select/UserPicker.test.tsx index d63fbda5868..00efa56b10f 100644 --- a/public/app/core/components/Select/UserPicker.test.tsx +++ b/public/app/core/components/Select/UserPicker.test.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; +import React from 'react'; + import { UserPicker } from './UserPicker'; jest.mock('@grafana/runtime', () => ({ diff --git a/public/app/core/components/Select/UserPicker.tsx b/public/app/core/components/Select/UserPicker.tsx index 4b28cb6eadf..ac09157bfe2 100644 --- a/public/app/core/components/Select/UserPicker.tsx +++ b/public/app/core/components/Select/UserPicker.tsx @@ -1,16 +1,10 @@ -// Libraries -import React, { Component } from 'react'; import { debounce, isNil } from 'lodash'; +import React, { Component } from 'react'; -// Components -import { AsyncSelect } from '@grafana/ui'; - -// Utils & Services -import { getBackendSrv } from '@grafana/runtime'; - -// Types -import { OrgUser } from 'app/types'; import { SelectableValue } from '@grafana/data'; +import { getBackendSrv } from '@grafana/runtime'; +import { AsyncSelect } from '@grafana/ui'; +import { OrgUser } from 'app/types'; export interface Props { onSelected: (user: SelectableValue) => void; diff --git a/public/app/core/components/SharedPreferences/SharedPreferences.tsx b/public/app/core/components/SharedPreferences/SharedPreferences.tsx index c6b885c453b..0b347a3601a 100644 --- a/public/app/core/components/SharedPreferences/SharedPreferences.tsx +++ b/public/app/core/components/SharedPreferences/SharedPreferences.tsx @@ -1,6 +1,9 @@ -import React, { PureComponent } from 'react'; import { css } from '@emotion/css'; +import { t, Trans } from '@lingui/macro'; +import React, { PureComponent } from 'react'; +import { SelectableValue } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; import { Button, Field, @@ -15,13 +18,9 @@ import { Tooltip, WeekStartPicker, } from '@grafana/ui'; -import { SelectableValue } from '@grafana/data'; -import { selectors } from '@grafana/e2e-selectors'; - -import { DashboardSearchHit, DashboardSearchItemType } from 'app/features/search/types'; -import { backendSrv } from 'app/core/services/backend_srv'; import { PreferencesService } from 'app/core/services/PreferencesService'; -import { t, Trans } from '@lingui/macro'; +import { backendSrv } from 'app/core/services/backend_srv'; +import { DashboardSearchHit, DashboardSearchItemType } from 'app/features/search/types'; export interface Props { resourceUri: string; diff --git a/public/app/core/components/Signup/SignupPage.test.tsx b/public/app/core/components/Signup/SignupPage.test.tsx index 1a7be5066a2..9d3c8675632 100644 --- a/public/app/core/components/Signup/SignupPage.test.tsx +++ b/public/app/core/components/Signup/SignupPage.test.tsx @@ -1,7 +1,8 @@ -import React from 'react'; import { fireEvent, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import React from 'react'; import { render } from 'test/redux-rtl'; + import { getRouteComponentProps } from 'app/core/navigation/__mocks__/routeProps'; import { SignupPage } from './SignupPage'; diff --git a/public/app/core/components/Signup/SignupPage.tsx b/public/app/core/components/Signup/SignupPage.tsx index 4eab139d56b..3d6a6188475 100644 --- a/public/app/core/components/Signup/SignupPage.tsx +++ b/public/app/core/components/Signup/SignupPage.tsx @@ -1,9 +1,11 @@ import React, { FC } from 'react'; -import { Form, Field, Input, Button, HorizontalGroup, LinkButton, FormAPI } from '@grafana/ui'; + import { getBackendSrv } from '@grafana/runtime'; +import { Form, Field, Input, Button, HorizontalGroup, LinkButton, FormAPI } from '@grafana/ui'; import { getConfig } from 'app/core/config'; -import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; import { useAppNotification } from 'app/core/copy/appNotification'; +import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; + import { InnerBox, LoginLayout } from '../Login/LoginLayout'; import { PasswordField } from '../PasswordField/PasswordField'; diff --git a/public/app/core/components/Signup/VerifyEmail.tsx b/public/app/core/components/Signup/VerifyEmail.tsx index ff49e1e8ff2..81eab2cc66b 100644 --- a/public/app/core/components/Signup/VerifyEmail.tsx +++ b/public/app/core/components/Signup/VerifyEmail.tsx @@ -1,6 +1,7 @@ import React, { FC, useState } from 'react'; -import { Form, Field, Input, Button, Legend, Container, HorizontalGroup, LinkButton } from '@grafana/ui'; + import { getBackendSrv } from '@grafana/runtime'; +import { Form, Field, Input, Button, Legend, Container, HorizontalGroup, LinkButton } from '@grafana/ui'; import { getConfig } from 'app/core/config'; import { useAppNotification } from 'app/core/copy/appNotification'; diff --git a/public/app/core/components/Signup/VerifyEmailPage.test.tsx b/public/app/core/components/Signup/VerifyEmailPage.test.tsx index 637f43ee75a..00dbb378a4d 100644 --- a/public/app/core/components/Signup/VerifyEmailPage.test.tsx +++ b/public/app/core/components/Signup/VerifyEmailPage.test.tsx @@ -1,7 +1,7 @@ -import React from 'react'; import { fireEvent, screen, waitFor } from '@testing-library/react'; -import { render } from 'test/redux-rtl'; import userEvent from '@testing-library/user-event'; +import React from 'react'; +import { render } from 'test/redux-rtl'; import { VerifyEmailPage } from './VerifyEmailPage'; diff --git a/public/app/core/components/Signup/VerifyEmailPage.tsx b/public/app/core/components/Signup/VerifyEmailPage.tsx index 3583fca4924..8a3eacd13e1 100644 --- a/public/app/core/components/Signup/VerifyEmailPage.tsx +++ b/public/app/core/components/Signup/VerifyEmailPage.tsx @@ -1,6 +1,7 @@ import React, { FC } from 'react'; import { LoginLayout, InnerBox } from '../Login/LoginLayout'; + import { VerifyEmail } from './VerifyEmail'; export const VerifyEmailPage: FC = () => { diff --git a/public/app/core/components/SplitPaneWrapper/SplitPaneWrapper.tsx b/public/app/core/components/SplitPaneWrapper/SplitPaneWrapper.tsx index 4efc15bc8da..09f53bf7f32 100644 --- a/public/app/core/components/SplitPaneWrapper/SplitPaneWrapper.tsx +++ b/public/app/core/components/SplitPaneWrapper/SplitPaneWrapper.tsx @@ -1,6 +1,7 @@ +import { css, cx } from '@emotion/css'; import React, { createRef, MutableRefObject, PureComponent, ReactNode } from 'react'; import SplitPane from 'react-split-pane'; -import { css, cx } from '@emotion/css'; + import { GrafanaTheme } from '@grafana/data'; import { stylesFactory } from '@grafana/ui'; import { config } from 'app/core/config'; diff --git a/public/app/core/components/TagFilter/TagBadge.tsx b/public/app/core/components/TagFilter/TagBadge.tsx index 1d071464ff4..fa184f0b9f3 100644 --- a/public/app/core/components/TagFilter/TagBadge.tsx +++ b/public/app/core/components/TagFilter/TagBadge.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { getTagColorsFromName, Icon } from '@grafana/ui'; export interface Props { diff --git a/public/app/core/components/TagFilter/TagFilter.tsx b/public/app/core/components/TagFilter/TagFilter.tsx index c419f6a8db7..ed262ec9974 100644 --- a/public/app/core/components/TagFilter/TagFilter.tsx +++ b/public/app/core/components/TagFilter/TagFilter.tsx @@ -1,11 +1,12 @@ -import React, { FC, useCallback, useEffect, useMemo, useState } from 'react'; import { css } from '@emotion/css'; +import React, { FC, useCallback, useEffect, useMemo, useState } from 'react'; import { components } from 'react-select'; -import { Icon, MultiSelect, useStyles2 } from '@grafana/ui'; -import { escapeStringForRegex, GrafanaTheme2 } from '@grafana/data'; -import { TagOption } from './TagOption'; +import { escapeStringForRegex, GrafanaTheme2 } from '@grafana/data'; +import { Icon, MultiSelect, useStyles2 } from '@grafana/ui'; + import { TagBadge } from './TagBadge'; +import { TagOption } from './TagOption'; export interface TermCount { term: string; diff --git a/public/app/core/components/TagFilter/TagOption.tsx b/public/app/core/components/TagFilter/TagOption.tsx index 3505e958764..c7ad15fcb18 100644 --- a/public/app/core/components/TagFilter/TagOption.tsx +++ b/public/app/core/components/TagFilter/TagOption.tsx @@ -1,9 +1,10 @@ -import React, { FC } from 'react'; import { css, cx } from '@emotion/css'; -import { useTheme, stylesFactory } from '@grafana/ui'; -import { GrafanaTheme } from '@grafana/data'; - +import React, { FC } from 'react'; import { OptionProps } from 'react-select'; + +import { GrafanaTheme } from '@grafana/data'; +import { useTheme, stylesFactory } from '@grafana/ui'; + import { TagBadge } from './TagBadge'; // https://github.com/JedWatson/react-select/issues/3038 diff --git a/public/app/core/components/TagFilter/TagValue.tsx b/public/app/core/components/TagFilter/TagValue.tsx index 0406ead16a6..530e43dcc12 100644 --- a/public/app/core/components/TagFilter/TagValue.tsx +++ b/public/app/core/components/TagFilter/TagValue.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { TagBadge } from './TagBadge'; export interface Props { diff --git a/public/app/core/components/TimePicker/TimePickerWithHistory.tsx b/public/app/core/components/TimePicker/TimePickerWithHistory.tsx index 2306922ba70..85ccd92df81 100644 --- a/public/app/core/components/TimePicker/TimePickerWithHistory.tsx +++ b/public/app/core/components/TimePicker/TimePickerWithHistory.tsx @@ -1,8 +1,10 @@ import React from 'react'; -import { LocalStorageValueProvider } from '../LocalStorageValueProvider'; + import { TimeRange, isDateTime, toUtc } from '@grafana/data'; import { TimeRangePickerProps, TimeRangePicker } from '@grafana/ui'; +import { LocalStorageValueProvider } from '../LocalStorageValueProvider'; + const LOCAL_STORAGE_KEY = 'grafana.dashboard.timepicker.history'; interface Props extends Omit {} diff --git a/public/app/core/components/TraceToLogs/KeyValueInput.tsx b/public/app/core/components/TraceToLogs/KeyValueInput.tsx index 40258a93874..45934073fdb 100644 --- a/public/app/core/components/TraceToLogs/KeyValueInput.tsx +++ b/public/app/core/components/TraceToLogs/KeyValueInput.tsx @@ -1,7 +1,8 @@ import { css } from '@emotion/css'; +import React from 'react'; + import { GrafanaTheme, KeyValue } from '@grafana/data'; import { SegmentInput, useStyles, InlineLabel, Icon } from '@grafana/ui'; -import React from 'react'; const EQ_WIDTH = 3; // = 24px in inline label diff --git a/public/app/core/components/TraceToLogs/TraceToLogsSettings.tsx b/public/app/core/components/TraceToLogs/TraceToLogsSettings.tsx index 871a967f2bf..9df3adefe7a 100644 --- a/public/app/core/components/TraceToLogs/TraceToLogsSettings.tsx +++ b/public/app/core/components/TraceToLogs/TraceToLogsSettings.tsx @@ -1,4 +1,6 @@ import { css } from '@emotion/css'; +import React from 'react'; + import { DataSourceJsonData, DataSourceInstanceSettings, @@ -9,7 +11,7 @@ import { } from '@grafana/data'; import { DataSourcePicker } from '@grafana/runtime'; import { InlineField, InlineFieldRow, Input, TagsInput, useStyles, InlineSwitch } from '@grafana/ui'; -import React from 'react'; + import KeyValueInput from './KeyValueInput'; export interface TraceToLogsOptions { diff --git a/public/app/core/components/Upgrade/ProBadge.tsx b/public/app/core/components/Upgrade/ProBadge.tsx index 1dfd81f8211..c886cc7e295 100644 --- a/public/app/core/components/Upgrade/ProBadge.tsx +++ b/public/app/core/components/Upgrade/ProBadge.tsx @@ -1,8 +1,9 @@ -import React, { HTMLAttributes, useEffect } from 'react'; import { css, cx } from '@emotion/css'; -import { useStyles2 } from '@grafana/ui'; +import React, { HTMLAttributes, useEffect } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { reportExperimentView } from '@grafana/runtime'; +import { useStyles2 } from '@grafana/ui'; export interface Props extends HTMLAttributes { text?: string; diff --git a/public/app/core/components/Upgrade/UpgradeBox.tsx b/public/app/core/components/Upgrade/UpgradeBox.tsx index aa712c8bf19..c4b1abb9912 100644 --- a/public/app/core/components/Upgrade/UpgradeBox.tsx +++ b/public/app/core/components/Upgrade/UpgradeBox.tsx @@ -1,8 +1,9 @@ -import React, { HTMLAttributes, useEffect } from 'react'; import { css, cx } from '@emotion/css'; -import { Button, Icon, LinkButton, useStyles2 } from '@grafana/ui'; +import React, { HTMLAttributes, useEffect } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { reportExperimentView } from '@grafana/runtime/src'; +import { Button, Icon, LinkButton, useStyles2 } from '@grafana/ui'; type ComponentSize = 'sm' | 'md'; diff --git a/public/app/core/components/connectWithCleanUp.tsx b/public/app/core/components/connectWithCleanUp.tsx index 712d4e8c5b8..6c1cc95ab6b 100644 --- a/public/app/core/components/connectWithCleanUp.tsx +++ b/public/app/core/components/connectWithCleanUp.tsx @@ -1,7 +1,8 @@ -import { connect, MapDispatchToPropsParam, MapStateToPropsParam, useDispatch } from 'react-redux'; -import { cleanUpAction, StateSelector } from '../actions/cleanUp'; -import React, { ComponentType, FunctionComponent, useEffect } from 'react'; import hoistNonReactStatics from 'hoist-non-react-statics'; +import React, { ComponentType, FunctionComponent, useEffect } from 'react'; +import { connect, MapDispatchToPropsParam, MapStateToPropsParam, useDispatch } from 'react-redux'; + +import { cleanUpAction, StateSelector } from '../actions/cleanUp'; export const connectWithCleanUp = < diff --git a/public/app/core/components/editors/DashboardPicker.tsx b/public/app/core/components/editors/DashboardPicker.tsx index 51192d9c0f8..2baaf4d46d4 100644 --- a/public/app/core/components/editors/DashboardPicker.tsx +++ b/public/app/core/components/editors/DashboardPicker.tsx @@ -1,4 +1,5 @@ import React, { FC, useCallback } from 'react'; + import { SelectableValue, StandardEditorProps } from '@grafana/data'; import { DashboardPicker as BasePicker, DashboardPickerDTO } from 'app/core/components/Select/DashboardPicker'; diff --git a/public/app/core/components/editors/DashboardPickerByID.tsx b/public/app/core/components/editors/DashboardPickerByID.tsx index c79ef4f4b8c..7bcc9bee8fb 100644 --- a/public/app/core/components/editors/DashboardPickerByID.tsx +++ b/public/app/core/components/editors/DashboardPickerByID.tsx @@ -1,8 +1,9 @@ -import React, { FC } from 'react'; import debounce from 'debounce-promise'; +import React, { FC } from 'react'; + +import { SelectableValue } from '@grafana/data'; import { AsyncSelect } from '@grafana/ui'; import { backendSrv } from 'app/core/services/backend_srv'; -import { SelectableValue } from '@grafana/data'; /** * @deprecated prefer using dashboard uid rather than id diff --git a/public/app/core/components/editors/registry.tsx b/public/app/core/components/editors/registry.tsx index d9e80595205..19220e2a35b 100644 --- a/public/app/core/components/editors/registry.tsx +++ b/public/app/core/components/editors/registry.tsx @@ -1,5 +1,3 @@ -import { DashboardPicker, DashboardPickerOptions } from './DashboardPicker'; -import { getStandardFieldConfigs, getStandardOptionEditors } from '@grafana/ui'; import { FieldConfigPropertyItem, FieldType, @@ -13,8 +11,11 @@ import { ValueMappingFieldConfigSettings, valueMappingsOverrideProcessor, } from '@grafana/data'; -import { ValueMappingsEditor } from 'app/features/dimensions/editors/ValueMappingsEditor/ValueMappingsEditor'; +import { getStandardFieldConfigs, getStandardOptionEditors } from '@grafana/ui'; import { ThresholdsValueEditor } from 'app/features/dimensions/editors/ThresholdsEditor/thresholds'; +import { ValueMappingsEditor } from 'app/features/dimensions/editors/ValueMappingsEditor/ValueMappingsEditor'; + +import { DashboardPicker, DashboardPickerOptions } from './DashboardPicker'; /** * Returns collection of standard option editors definitions diff --git a/public/app/core/components/help/HelpModal.tsx b/public/app/core/components/help/HelpModal.tsx index 70d9fda91e8..7722dbc2dcf 100644 --- a/public/app/core/components/help/HelpModal.tsx +++ b/public/app/core/components/help/HelpModal.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { css } from '@emotion/css'; +import React from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { Modal, useStyles2 } from '@grafana/ui'; diff --git a/public/app/core/components/modals/AngularModalProxy.tsx b/public/app/core/components/modals/AngularModalProxy.tsx index 70ed905b4c3..2231f856ef4 100644 --- a/public/app/core/components/modals/AngularModalProxy.tsx +++ b/public/app/core/components/modals/AngularModalProxy.tsx @@ -1,7 +1,9 @@ -import { connectWithProvider } from '../../utils/connectWithReduxStore'; -import { ModalRoot, ModalsProvider } from '@grafana/ui'; import React from 'react'; +import { ModalRoot, ModalsProvider } from '@grafana/ui'; + +import { connectWithProvider } from '../../utils/connectWithReduxStore'; + /** * Component that enables rendering React modals from Angular */ diff --git a/public/app/core/config.ts b/public/app/core/config.ts index fcd399c9d30..db165baf96b 100644 --- a/public/app/core/config.ts +++ b/public/app/core/config.ts @@ -1,5 +1,5 @@ -import { config, GrafanaBootConfig } from '@grafana/runtime'; import { PluginState } from '@grafana/data'; +import { config, GrafanaBootConfig } from '@grafana/runtime'; // Legacy binding paths export { config, GrafanaBootConfig as Settings }; diff --git a/public/app/core/copy/appNotification.ts b/public/app/core/copy/appNotification.ts index 987f7194eeb..485cdc6d4c6 100644 --- a/public/app/core/copy/appNotification.ts +++ b/public/app/core/copy/appNotification.ts @@ -1,7 +1,9 @@ import { useMemo } from 'react'; -import { AppNotification, AppNotificationSeverity, useDispatch } from 'app/types'; -import { getMessageFromError } from 'app/core/utils/errors'; import { v4 as uuidv4 } from 'uuid'; + +import { getMessageFromError } from 'app/core/utils/errors'; +import { AppNotification, AppNotificationSeverity, useDispatch } from 'app/types'; + import { notifyApp } from '../actions'; const defaultSuccessNotification = { diff --git a/public/app/core/core.ts b/public/app/core/core.ts index 38e3808619d..0833d4a58f4 100644 --- a/public/app/core/core.ts +++ b/public/app/core/core.ts @@ -1,10 +1,11 @@ import { colors, JsonExplorer } from '@grafana/ui/'; + import appEvents from './app_events'; -import { assignModelProperties } from './utils/model_utils'; +import { profiler } from './profiler'; import { contextSrv } from './services/context_srv'; import { KeybindingSrv } from './services/keybindingSrv'; -import { profiler } from './profiler'; import TimeSeries, { updateLegendValues } from './time_series2'; +import { assignModelProperties } from './utils/model_utils'; export { profiler, diff --git a/public/app/core/history/RichHistoryLocalStorage.test.ts b/public/app/core/history/RichHistoryLocalStorage.test.ts index 747b6720935..c587c07a927 100644 --- a/public/app/core/history/RichHistoryLocalStorage.test.ts +++ b/public/app/core/history/RichHistoryLocalStorage.test.ts @@ -1,12 +1,14 @@ -import RichHistoryLocalStorage, { MAX_HISTORY_ITEMS } from './RichHistoryLocalStorage'; -import store from 'app/core/store'; -import { RichHistoryQuery } from '../../types'; import { DataQuery } from '@grafana/data'; +import store from 'app/core/store'; + import { afterEach, beforeEach } from '../../../test/lib/common'; -import { RichHistoryStorageWarning } from './RichHistoryStorage'; +import { RichHistoryQuery } from '../../types'; import { backendSrv } from '../services/backend_srv'; import { RichHistorySettings } from '../utils/richHistoryTypes'; +import RichHistoryLocalStorage, { MAX_HISTORY_ITEMS } from './RichHistoryLocalStorage'; +import { RichHistoryStorageWarning } from './RichHistoryStorage'; + const key = 'grafana.explore.richHistory'; jest.mock('@grafana/runtime', () => ({ diff --git a/public/app/core/history/RichHistoryLocalStorage.ts b/public/app/core/history/RichHistoryLocalStorage.ts index ca98b0c6a45..44e943e6468 100644 --- a/public/app/core/history/RichHistoryLocalStorage.ts +++ b/public/app/core/history/RichHistoryLocalStorage.ts @@ -1,12 +1,15 @@ -import RichHistoryStorage, { RichHistoryServiceError, RichHistoryStorageWarning } from './RichHistoryStorage'; +import { find, isEqual, omit } from 'lodash'; + +import { DataQuery } from '@grafana/data'; + import { RichHistoryQuery } from '../../types'; import store from '../store'; -import { DataQuery } from '@grafana/data'; -import { find, isEqual, omit } from 'lodash'; -import { createRetentionPeriodBoundary, RICH_HISTORY_SETTING_KEYS } from './richHistoryLocalStorageUtils'; -import { fromDTO, toDTO } from './localStorageConverter'; import { RichHistorySettings } from '../utils/richHistoryTypes'; +import RichHistoryStorage, { RichHistoryServiceError, RichHistoryStorageWarning } from './RichHistoryStorage'; +import { fromDTO, toDTO } from './localStorageConverter'; +import { createRetentionPeriodBoundary, RICH_HISTORY_SETTING_KEYS } from './richHistoryLocalStorageUtils'; + export const RICH_HISTORY_KEY = 'grafana.explore.richHistory'; export const MAX_HISTORY_ITEMS = 10000; diff --git a/public/app/core/history/localStorageConverter.test.ts b/public/app/core/history/localStorageConverter.test.ts index 5a18d27747e..9a7e7ff4cd4 100644 --- a/public/app/core/history/localStorageConverter.test.ts +++ b/public/app/core/history/localStorageConverter.test.ts @@ -1,7 +1,8 @@ -import { backendSrv } from '../services/backend_srv'; -import { fromDTO, toDTO } from './localStorageConverter'; import { RichHistoryQuery } from '../../types'; +import { backendSrv } from '../services/backend_srv'; + import { RichHistoryLocalStorageDTO } from './RichHistoryLocalStorage'; +import { fromDTO, toDTO } from './localStorageConverter'; jest.mock('@grafana/runtime', () => ({ ...(jest.requireActual('@grafana/runtime') as unknown as object), diff --git a/public/app/core/history/localStorageConverter.ts b/public/app/core/history/localStorageConverter.ts index e8569969449..8e480ffc8d6 100644 --- a/public/app/core/history/localStorageConverter.ts +++ b/public/app/core/history/localStorageConverter.ts @@ -1,9 +1,12 @@ import { find } from 'lodash'; + import { DataSourceInstanceSettings } from '@grafana/data'; import { getDataSourceSrv } from '@grafana/runtime'; -import { RichHistoryLocalStorageDTO } from './RichHistoryLocalStorage'; + import { RichHistoryQuery } from '../../types'; +import { RichHistoryLocalStorageDTO } from './RichHistoryLocalStorage'; + export const fromDTO = (dto: RichHistoryLocalStorageDTO): RichHistoryQuery => { const datasource = find( getDataSourceSrv().getList(), diff --git a/public/app/core/history/richHistoryLocalStorageUtils.ts b/public/app/core/history/richHistoryLocalStorageUtils.ts index 67b644f496c..096b366da50 100644 --- a/public/app/core/history/richHistoryLocalStorageUtils.ts +++ b/public/app/core/history/richHistoryLocalStorageUtils.ts @@ -1,5 +1,6 @@ -import { RichHistoryQuery } from '../../types'; import { omit } from 'lodash'; + +import { RichHistoryQuery } from '../../types'; import { SortOrder } from '../utils/richHistoryTypes'; /** diff --git a/public/app/core/hooks/useCleanup.ts b/public/app/core/hooks/useCleanup.ts index b7940c9d474..33b16150cbf 100644 --- a/public/app/core/hooks/useCleanup.ts +++ b/public/app/core/hooks/useCleanup.ts @@ -1,5 +1,6 @@ import { useEffect, useRef } from 'react'; import { useDispatch } from 'react-redux'; + import { cleanUpAction, StateSelector } from '../actions/cleanUp'; export function useCleanup(stateSelector: StateSelector) { diff --git a/public/app/core/hooks/useNavModel.ts b/public/app/core/hooks/useNavModel.ts index 18bb07d6c8b..99917e14262 100644 --- a/public/app/core/hooks/useNavModel.ts +++ b/public/app/core/hooks/useNavModel.ts @@ -1,7 +1,9 @@ import { useSelector } from 'react-redux'; -import { StoreState } from 'app/types/store'; -import { getNavModel } from '../selectors/navModel'; + import { NavModel } from '@grafana/data'; +import { StoreState } from 'app/types/store'; + +import { getNavModel } from '../selectors/navModel'; export const useNavModel = (id: string): NavModel => { const navIndex = useSelector((state: StoreState) => state.navIndex); diff --git a/public/app/core/hooks/useQueryParams.ts b/public/app/core/hooks/useQueryParams.ts index 8ee53b8fcd2..907f039e1e5 100644 --- a/public/app/core/hooks/useQueryParams.ts +++ b/public/app/core/hooks/useQueryParams.ts @@ -1,8 +1,9 @@ -import { UrlQueryMap } from '@grafana/data'; -import { locationSearchToObject, locationService } from '@grafana/runtime'; import { useCallback, useMemo } from 'react'; import { useLocation } from 'react-router-dom'; +import { UrlQueryMap } from '@grafana/data'; +import { locationSearchToObject, locationService } from '@grafana/runtime'; + export function useQueryParams(): [UrlQueryMap, (values: UrlQueryMap, replace?: boolean) => void] { const { search } = useLocation(); const queryParams = useMemo(() => locationSearchToObject(search || ''), [search]); diff --git a/public/app/core/localisation.tsx b/public/app/core/localisation.tsx index f979e61c4e8..c7626b68698 100644 --- a/public/app/core/localisation.tsx +++ b/public/app/core/localisation.tsx @@ -1,6 +1,6 @@ -import React, { useState } from 'react'; import { I18n, i18n } from '@lingui/core'; import { I18nProvider as LinguiI18nProvider } from '@lingui/react'; +import React, { useState } from 'react'; import { messages } from '../../locales/en/messages'; diff --git a/public/app/core/logs_model.test.ts b/public/app/core/logs_model.test.ts index e09b6205849..34ffa4d5671 100644 --- a/public/app/core/logs_model.test.ts +++ b/public/app/core/logs_model.test.ts @@ -1,3 +1,5 @@ +import { Observable } from 'rxjs'; + import { ArrayVector, DataFrame, @@ -14,6 +16,9 @@ import { MutableDataFrame, toDataFrame, } from '@grafana/data'; + +import { MockObservableDataSourceApi } from '../../test/mocks/datasource_srv'; + import { COMMON_LABELS, dataFrameToLogsModel, @@ -24,8 +29,6 @@ import { logSeriesToLogsModel, queryLogsVolume, } from './logs_model'; -import { Observable } from 'rxjs'; -import { MockObservableDataSourceApi } from '../../test/mocks/datasource_srv'; describe('dedupLogRows()', () => { test('should return rows as is when dedup is set to none', () => { diff --git a/public/app/core/logs_model.ts b/public/app/core/logs_model.ts index 36316d6a85e..bde1bd525a0 100644 --- a/public/app/core/logs_model.ts +++ b/public/app/core/logs_model.ts @@ -1,6 +1,5 @@ import { size } from 'lodash'; -import { BarAlignment, GraphDrawStyle, StackingMode } from '@grafana/schema'; -import { ansicolor, colors } from '@grafana/ui'; +import { Observable } from 'rxjs'; import { AbsoluteTimeRange, @@ -37,9 +36,10 @@ import { toDataFrame, toUtc, } from '@grafana/data'; -import { getThemeColor } from 'app/core/utils/colors'; import { SIPrefix } from '@grafana/data/src/valueFormats/symbolFormatters'; -import { Observable } from 'rxjs'; +import { BarAlignment, GraphDrawStyle, StackingMode } from '@grafana/schema'; +import { ansicolor, colors } from '@grafana/ui'; +import { getThemeColor } from 'app/core/utils/colors'; export const LIMIT_LABEL = 'Line limit'; export const COMMON_LABELS = 'Common labels'; diff --git a/public/app/core/navigation/GrafanaRoute.test.tsx b/public/app/core/navigation/GrafanaRoute.test.tsx index 6b434645d25..514e38dbf45 100644 --- a/public/app/core/navigation/GrafanaRoute.test.tsx +++ b/public/app/core/navigation/GrafanaRoute.test.tsx @@ -1,9 +1,12 @@ -import React from 'react'; import { render } from '@testing-library/react'; -import { GrafanaRoute } from './GrafanaRoute'; +import React from 'react'; + import { setEchoSrv } from '@grafana/runtime'; + import { Echo } from '../services/echo/Echo'; +import { GrafanaRoute } from './GrafanaRoute'; + describe('GrafanaRoute', () => { beforeEach(() => { setEchoSrv(new Echo()); diff --git a/public/app/core/navigation/GrafanaRoute.tsx b/public/app/core/navigation/GrafanaRoute.tsx index 500218812cb..3ff44bc54bf 100644 --- a/public/app/core/navigation/GrafanaRoute.tsx +++ b/public/app/core/navigation/GrafanaRoute.tsx @@ -1,10 +1,13 @@ import React from 'react'; // @ts-ignore import Drop from 'tether-drop'; -import { GrafanaRouteComponentProps } from './types'; + import { locationSearchToObject, navigationLogger, reportPageview } from '@grafana/runtime'; + import { keybindingSrv } from '../services/keybindingSrv'; +import { GrafanaRouteComponentProps } from './types'; + export interface Props extends Omit {} export class GrafanaRoute extends React.Component { diff --git a/public/app/core/navigation/RouterDebugger.tsx b/public/app/core/navigation/RouterDebugger.tsx index 2a177379f26..49d621ea7f9 100644 --- a/public/app/core/navigation/RouterDebugger.tsx +++ b/public/app/core/navigation/RouterDebugger.tsx @@ -1,7 +1,9 @@ import React from 'react'; import { Link } from 'react-router-dom'; + import { getAppRoutes } from '../../routes/routes'; import { PageContents } from '../components/Page/PageContents'; + import { RouteDescriptor } from './types'; export const RouterDebugger: React.FC = () => { diff --git a/public/app/core/navigation/__mocks__/routeProps.ts b/public/app/core/navigation/__mocks__/routeProps.ts index 6c3ff25ecd8..0b22e1d2449 100644 --- a/public/app/core/navigation/__mocks__/routeProps.ts +++ b/public/app/core/navigation/__mocks__/routeProps.ts @@ -1,7 +1,8 @@ -import { GrafanaRouteComponentProps } from '../types'; import { createMemoryHistory } from 'history'; import { merge } from 'lodash'; +import { GrafanaRouteComponentProps } from '../types'; + export function getRouteComponentProps = {}>( overrides: Partial = {} ): GrafanaRouteComponentProps { diff --git a/public/app/core/navigation/hooks.ts b/public/app/core/navigation/hooks.ts index 5c30ac06688..566c5e3f50e 100644 --- a/public/app/core/navigation/hooks.ts +++ b/public/app/core/navigation/hooks.ts @@ -1,6 +1,7 @@ -import { locationService } from '@grafana/runtime'; import { useLocation } from 'react-router-dom'; +import { locationService } from '@grafana/runtime'; + export type UseUrlParamsResult = [URLSearchParams, (params: Record, replace?: boolean) => void]; /** @internal experimental */ diff --git a/public/app/core/navigation/kiosk.ts b/public/app/core/navigation/kiosk.ts index b041d1f5272..61f36656c61 100644 --- a/public/app/core/navigation/kiosk.ts +++ b/public/app/core/navigation/kiosk.ts @@ -1,7 +1,8 @@ import { AppEvents } from '@grafana/data'; import { locationService } from '@grafana/runtime'; -import appEvents from '../app_events'; + import { KioskMode } from '../../types'; +import appEvents from '../app_events'; export function toggleKioskMode() { let kiosk = locationService.getSearchObject().kiosk; diff --git a/public/app/core/navigation/testRoutes.tsx b/public/app/core/navigation/testRoutes.tsx index c7087d16485..6a5dc26e442 100644 --- a/public/app/core/navigation/testRoutes.tsx +++ b/public/app/core/navigation/testRoutes.tsx @@ -1,5 +1,6 @@ import React from 'react'; import { Link, NavLink } from 'react-router-dom'; + import { RouterDebugger } from './RouterDebugger'; import { RouteDescriptor } from './types'; diff --git a/public/app/core/navigation/types.ts b/public/app/core/navigation/types.ts index a88d082a297..aed3b16a62f 100644 --- a/public/app/core/navigation/types.ts +++ b/public/app/core/navigation/types.ts @@ -1,7 +1,8 @@ -import { UrlQueryMap } from '@grafana/data'; import React from 'react'; import { RouteComponentProps } from 'react-router-dom'; +import { UrlQueryMap } from '@grafana/data'; + export interface GrafanaRouteComponentProps extends RouteComponentProps { route: RouteDescriptor; queryParams: Q; diff --git a/public/app/core/reducers/appNotification.test.ts b/public/app/core/reducers/appNotification.test.ts index d0228683d14..33a12aa5f46 100644 --- a/public/app/core/reducers/appNotification.test.ts +++ b/public/app/core/reducers/appNotification.test.ts @@ -1,6 +1,7 @@ -import { appNotificationsReducer, clearNotification, notifyApp } from './appNotification'; import { AppNotificationSeverity, AppNotificationsState } from 'app/types/'; +import { appNotificationsReducer, clearNotification, notifyApp } from './appNotification'; + const timestamp = 1649849468889; describe('clear alert', () => { it('should filter alert', () => { diff --git a/public/app/core/reducers/appNotification.ts b/public/app/core/reducers/appNotification.ts index ff78a4bf14a..eff7f50c4a4 100644 --- a/public/app/core/reducers/appNotification.ts +++ b/public/app/core/reducers/appNotification.ts @@ -1,5 +1,6 @@ -import { config } from '@grafana/runtime'; import { createSlice, PayloadAction } from '@reduxjs/toolkit'; + +import { config } from '@grafana/runtime'; import { AppNotification, AppNotificationSeverity, AppNotificationsState } from 'app/types/'; export const STORAGE_KEY = 'notifications'; diff --git a/public/app/core/reducers/index.ts b/public/app/core/reducers/index.ts index 8787fb2e440..6482f26c932 100644 --- a/public/app/core/reducers/index.ts +++ b/public/app/core/reducers/index.ts @@ -1,6 +1,6 @@ -import { navIndexReducer as navIndex } from './navModel'; -import { navTreeReducer as navBarTree } from './navBarTree'; import { appNotificationsReducer as appNotifications } from './appNotification'; +import { navTreeReducer as navBarTree } from './navBarTree'; +import { navIndexReducer as navIndex } from './navModel'; export default { navBarTree, diff --git a/public/app/core/reducers/navBarTree.ts b/public/app/core/reducers/navBarTree.ts index 61fbbd3dd13..3611e2501e4 100644 --- a/public/app/core/reducers/navBarTree.ts +++ b/public/app/core/reducers/navBarTree.ts @@ -1,4 +1,5 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit'; + import { NavModelItem } from '@grafana/data'; import config from 'app/core/config'; diff --git a/public/app/core/reducers/navModel.test.ts b/public/app/core/reducers/navModel.test.ts index b13874baa1f..38424eff8a5 100644 --- a/public/app/core/reducers/navModel.test.ts +++ b/public/app/core/reducers/navModel.test.ts @@ -1,7 +1,9 @@ -import { reducerTester } from '../../../test/core/redux/reducerTester'; -import { navIndexReducer, updateNavIndex, updateConfigurationSubtitle } from './navModel'; import { NavIndex } from '@grafana/data'; +import { reducerTester } from '../../../test/core/redux/reducerTester'; + +import { navIndexReducer, updateNavIndex, updateConfigurationSubtitle } from './navModel'; + describe('navModelReducer', () => { describe('when updateNavIndex is dispatched', () => { it('then state should be correct', () => { diff --git a/public/app/core/reducers/navModel.ts b/public/app/core/reducers/navModel.ts index 0e8ca795b84..bdb256bfe1a 100644 --- a/public/app/core/reducers/navModel.ts +++ b/public/app/core/reducers/navModel.ts @@ -1,6 +1,6 @@ import { AnyAction, createAction } from '@reduxjs/toolkit'; -import { NavIndex, NavModel, NavModelItem } from '@grafana/data'; +import { NavIndex, NavModel, NavModelItem } from '@grafana/data'; import config from 'app/core/config'; export function buildInitialState(): NavIndex { diff --git a/public/app/core/reducers/root.test.ts b/public/app/core/reducers/root.test.ts index 1f1de65851b..13b685c79f7 100644 --- a/public/app/core/reducers/root.test.ts +++ b/public/app/core/reducers/root.test.ts @@ -1,10 +1,11 @@ -import { createRootReducer, recursiveCleanState } from './root'; -import { describe, expect } from '../../../test/lib/common'; import { reducerTester } from '../../../test/core/redux/reducerTester'; -import { StoreState } from '../../types/store'; -import { Team } from '../../types'; -import { cleanUpAction } from '../actions/cleanUp'; +import { describe, expect } from '../../../test/lib/common'; import { initialTeamsState, teamsLoaded } from '../../features/teams/state/reducers'; +import { Team } from '../../types'; +import { StoreState } from '../../types/store'; +import { cleanUpAction } from '../actions/cleanUp'; + +import { createRootReducer, recursiveCleanState } from './root'; jest.mock('@grafana/runtime', () => ({ ...(jest.requireActual('@grafana/runtime') as unknown as object), diff --git a/public/app/core/reducers/root.ts b/public/app/core/reducers/root.ts index fe0d22f773c..bab29a9acad 100644 --- a/public/app/core/reducers/root.ts +++ b/public/app/core/reducers/root.ts @@ -1,25 +1,27 @@ import { AnyAction, combineReducers } from 'redux'; -import { CleanUp, cleanUpAction } from '../actions/cleanUp'; + import sharedReducers from 'app/core/reducers'; -import alertingReducers from 'app/features/alerting/state/reducers'; -import teamsReducers from 'app/features/teams/state/reducers'; -import apiKeysReducers from 'app/features/api-keys/state/reducers'; -import foldersReducers from 'app/features/folders/state/reducers'; -import dashboardReducers from 'app/features/dashboard/state/reducers'; -import exploreReducers from 'app/features/explore/state/main'; -import { reducer as pluginsReducer } from 'app/features/plugins/admin/state/reducer'; -import dataSourcesReducers from 'app/features/datasources/state/reducers'; -import usersReducers from 'app/features/users/state/reducers'; -import invitesReducers from 'app/features/invites/state/reducers'; -import userReducers from 'app/features/profile/state/reducers'; -import organizationReducers from 'app/features/org/state/reducers'; import ldapReducers from 'app/features/admin/state/reducers'; -import importDashboardReducers from 'app/features/manage-dashboards/state/reducers'; +import alertingReducers from 'app/features/alerting/state/reducers'; +import apiKeysReducers from 'app/features/api-keys/state/reducers'; import panelEditorReducers from 'app/features/dashboard/components/PanelEditor/state/reducers'; +import dashboardReducers from 'app/features/dashboard/state/reducers'; +import dataSourcesReducers from 'app/features/datasources/state/reducers'; +import exploreReducers from 'app/features/explore/state/main'; +import foldersReducers from 'app/features/folders/state/reducers'; +import invitesReducers from 'app/features/invites/state/reducers'; +import importDashboardReducers from 'app/features/manage-dashboards/state/reducers'; +import organizationReducers from 'app/features/org/state/reducers'; import panelsReducers from 'app/features/panel/state/reducers'; +import { reducer as pluginsReducer } from 'app/features/plugins/admin/state/reducer'; +import userReducers from 'app/features/profile/state/reducers'; import serviceAccountsReducer from 'app/features/serviceaccounts/state/reducers'; +import teamsReducers from 'app/features/teams/state/reducers'; +import usersReducers from 'app/features/users/state/reducers'; import templatingReducers from 'app/features/variables/state/keyedVariablesReducer'; +import { CleanUp, cleanUpAction } from '../actions/cleanUp'; + const rootReducers = { ...sharedReducers, ...alertingReducers, diff --git a/public/app/core/services/FetchQueue.test.ts b/public/app/core/services/FetchQueue.test.ts index d0ab7b93548..79c7aa4fa77 100644 --- a/public/app/core/services/FetchQueue.test.ts +++ b/public/app/core/services/FetchQueue.test.ts @@ -1,5 +1,6 @@ import { Observable } from 'rxjs'; import { take } from 'rxjs/operators'; + import { BackendSrvRequest } from '@grafana/runtime'; import { FetchQueue, FetchQueueUpdate, FetchStatus } from './FetchQueue'; diff --git a/public/app/core/services/FetchQueueWorker.test.ts b/public/app/core/services/FetchQueueWorker.test.ts index 73682f1c93e..6f1d5dedb7b 100644 --- a/public/app/core/services/FetchQueueWorker.test.ts +++ b/public/app/core/services/FetchQueueWorker.test.ts @@ -1,11 +1,13 @@ import { Subject } from 'rxjs'; -import { FetchQueue, FetchQueueUpdate, FetchStatus } from './FetchQueue'; -import { ResponseQueue } from './ResponseQueue'; -import { FetchQueueWorker } from './FetchQueueWorker'; -import { expect } from '../../../test/lib/common'; import { GrafanaBootConfig } from '@grafana/runtime'; +import { expect } from '../../../test/lib/common'; + +import { FetchQueue, FetchQueueUpdate, FetchStatus } from './FetchQueue'; +import { FetchQueueWorker } from './FetchQueueWorker'; +import { ResponseQueue } from './ResponseQueue'; + const getTestContext = (http2Enabled = false) => { const config: GrafanaBootConfig = { http2Enabled } as unknown as GrafanaBootConfig; const dataUrl = 'http://localhost:3000/api/ds/query?=abc'; diff --git a/public/app/core/services/FetchQueueWorker.ts b/public/app/core/services/FetchQueueWorker.ts index 6ddaba7ed04..72c3c210943 100644 --- a/public/app/core/services/FetchQueueWorker.ts +++ b/public/app/core/services/FetchQueueWorker.ts @@ -1,8 +1,10 @@ import { concatMap, filter } from 'rxjs/operators'; -import { FetchQueue, FetchStatus } from './FetchQueue'; import { BackendSrvRequest, GrafanaBootConfig } from '@grafana/runtime'; + import { isDataQuery } from '../utils/query'; + +import { FetchQueue, FetchStatus } from './FetchQueue'; import { ResponseQueue } from './ResponseQueue'; interface WorkerEntry { diff --git a/public/app/core/services/ModalManager.ts b/public/app/core/services/ModalManager.ts index 395378c4e85..cdd756f8f36 100644 --- a/public/app/core/services/ModalManager.ts +++ b/public/app/core/services/ModalManager.ts @@ -1,15 +1,16 @@ import React from 'react'; import ReactDOM from 'react-dom'; -import appEvents from 'app/core/app_events'; -import { AngularModalProxy } from '../components/modals/AngularModalProxy'; -import { provideTheme } from '../utils/ConfigProvider'; -import { ShowConfirmModalEvent, ShowConfirmModalPayload, ShowModalReactEvent } from '../../types/events'; -import { ConfirmModal, ConfirmModalProps } from '@grafana/ui'; import { textUtil } from '@grafana/data'; import { CopyPanelEvent } from '@grafana/runtime'; +import { ConfirmModal, ConfirmModalProps } from '@grafana/ui'; +import appEvents from 'app/core/app_events'; import { copyPanel } from 'app/features/dashboard/utils/panel'; +import { ShowConfirmModalEvent, ShowConfirmModalPayload, ShowModalReactEvent } from '../../types/events'; +import { AngularModalProxy } from '../components/modals/AngularModalProxy'; +import { provideTheme } from '../utils/ConfigProvider'; + export class ModalManager { reactModalRoot = document.body; reactModalNode = document.createElement('div'); diff --git a/public/app/core/services/PreferencesService.ts b/public/app/core/services/PreferencesService.ts index 174e3dd7d5b..d2ab11e23cd 100644 --- a/public/app/core/services/PreferencesService.ts +++ b/public/app/core/services/PreferencesService.ts @@ -1,4 +1,5 @@ import { UserPreferencesDTO } from 'app/types'; + import { backendSrv } from './backend_srv'; export class PreferencesService { diff --git a/public/app/core/services/ResponseQueue.test.ts b/public/app/core/services/ResponseQueue.test.ts index 29e9fd580de..5c8c19c4675 100644 --- a/public/app/core/services/ResponseQueue.test.ts +++ b/public/app/core/services/ResponseQueue.test.ts @@ -1,12 +1,14 @@ import { of } from 'rxjs'; import { first } from 'rxjs/operators'; + import { BackendSrvRequest } from '@grafana/runtime'; -import { FetchQueue, FetchQueueUpdate } from './FetchQueue'; -import { ResponseQueue } from './ResponseQueue'; -import { subscribeTester } from './FetchQueue.test'; import { describe, expect } from '../../../test/lib/common'; +import { FetchQueue, FetchQueueUpdate } from './FetchQueue'; +import { subscribeTester } from './FetchQueue.test'; +import { ResponseQueue } from './ResponseQueue'; + const getTestContext = () => { const id = 'id'; const options: BackendSrvRequest = { url: 'http://someurl' }; diff --git a/public/app/core/services/ResponseQueue.ts b/public/app/core/services/ResponseQueue.ts index 9f5c7769641..567263bd8bd 100644 --- a/public/app/core/services/ResponseQueue.ts +++ b/public/app/core/services/ResponseQueue.ts @@ -1,6 +1,8 @@ import { Observable, Subject } from 'rxjs'; import { filter } from 'rxjs/operators'; + import { BackendSrvRequest, FetchResponse } from '@grafana/runtime'; + import { FetchQueue } from './FetchQueue'; interface FetchWorkEntry { diff --git a/public/app/core/services/__mocks__/backend_srv.ts b/public/app/core/services/__mocks__/backend_srv.ts index 2c79192a372..f43e5b77d4d 100644 --- a/public/app/core/services/__mocks__/backend_srv.ts +++ b/public/app/core/services/__mocks__/backend_srv.ts @@ -1,7 +1,9 @@ import 'whatwg-fetch'; // fetch polyfill needed for Headers -import { BackendSrvRequest, FetchResponse } from '@grafana/runtime'; import { of } from 'rxjs'; + +import { BackendSrvRequest, FetchResponse } from '@grafana/runtime'; + import { BackendSrv } from '../backend_srv'; /** diff --git a/public/app/core/services/backend_srv.ts b/public/app/core/services/backend_srv.ts index 6da5e10f6d2..74855d0600a 100644 --- a/public/app/core/services/backend_srv.ts +++ b/public/app/core/services/backend_srv.ts @@ -9,17 +9,19 @@ import { Subscription, throwError, } from 'rxjs'; -import { catchError, filter, map, mergeMap, retryWhen, share, takeUntil, tap, throwIfEmpty } from 'rxjs/operators'; import { fromFetch } from 'rxjs/fetch'; +import { catchError, filter, map, mergeMap, retryWhen, share, takeUntil, tap, throwIfEmpty } from 'rxjs/operators'; import { v4 as uuidv4 } from 'uuid'; -import { BackendSrv as BackendService, BackendSrvRequest, FetchError, FetchResponse } from '@grafana/runtime'; -import { AppEvents, DataQueryErrorType } from '@grafana/data'; +import { AppEvents, DataQueryErrorType } from '@grafana/data'; +import { BackendSrv as BackendService, BackendSrvRequest, FetchError, FetchResponse } from '@grafana/runtime'; import appEvents from 'app/core/app_events'; import { getConfig } from 'app/core/config'; import { DashboardSearchHit } from 'app/features/search/types'; +import { TokenRevokedModal } from 'app/features/users/TokenRevokedModal'; import { DashboardDTO, FolderDTO } from 'app/types'; -import { ContextSrv, contextSrv } from './context_srv'; + +import { ShowModalReactEvent } from '../../types/events'; import { isContentTypeApplicationJson, parseInitFromOptions, @@ -27,11 +29,11 @@ import { parseUrlFromOptions, } from '../utils/fetch'; import { isDataQuery, isLocalUrl } from '../utils/query'; + import { FetchQueue } from './FetchQueue'; -import { ResponseQueue } from './ResponseQueue'; import { FetchQueueWorker } from './FetchQueueWorker'; -import { TokenRevokedModal } from 'app/features/users/TokenRevokedModal'; -import { ShowModalReactEvent } from '../../types/events'; +import { ResponseQueue } from './ResponseQueue'; +import { ContextSrv, contextSrv } from './context_srv'; const CANCEL_ALL_REQUESTS_REQUEST_ID = 'cancel_all_requests_request_id'; diff --git a/public/app/core/services/context_srv.ts b/public/app/core/services/context_srv.ts index ecee561f4a0..6930600ad3d 100644 --- a/public/app/core/services/context_srv.ts +++ b/public/app/core/services/context_srv.ts @@ -1,10 +1,12 @@ -import config from '../../core/config'; import { extend } from 'lodash'; + import { OrgRole, rangeUtil, WithAccessControlMetadata } from '@grafana/data'; -import { AccessControlAction, UserPermission } from 'app/types'; import { featureEnabled, getBackendSrv } from '@grafana/runtime'; +import { AccessControlAction, UserPermission } from 'app/types'; import { CurrentUserInternal } from 'app/types/config'; +import config from '../../core/config'; + export class User implements CurrentUserInternal { isSignedIn: boolean; id: number; diff --git a/public/app/core/services/echo/Echo.ts b/public/app/core/services/echo/Echo.ts index 92d24d470f9..755576922e2 100644 --- a/public/app/core/services/echo/Echo.ts +++ b/public/app/core/services/echo/Echo.ts @@ -1,5 +1,7 @@ import { EchoBackend, EchoMeta, EchoEvent, EchoSrv } from '@grafana/runtime'; + import { contextSrv } from '../context_srv'; + import { echoLog } from './utils'; interface EchoConfig { diff --git a/public/app/core/services/echo/EchoSrv.ts b/public/app/core/services/echo/EchoSrv.ts index 1f230eca4a5..1f91e09fd79 100644 --- a/public/app/core/services/echo/EchoSrv.ts +++ b/public/app/core/services/echo/EchoSrv.ts @@ -1,5 +1,7 @@ -import { getEchoSrv, EchoEventType } from '@grafana/runtime'; import { captureException } from '@sentry/browser'; + +import { getEchoSrv, EchoEventType } from '@grafana/runtime'; + import { PerformanceEvent } from './backends/PerformanceBackend'; export const reportPerformance = (metric: string, value: number) => { diff --git a/public/app/core/services/echo/backends/PerformanceBackend.ts b/public/app/core/services/echo/backends/PerformanceBackend.ts index 5cc0385ab66..5b3d9af2830 100644 --- a/public/app/core/services/echo/backends/PerformanceBackend.ts +++ b/public/app/core/services/echo/backends/PerformanceBackend.ts @@ -1,4 +1,5 @@ import { EchoBackend, EchoEvent, EchoEventType } from '@grafana/runtime'; + import { backendSrv } from '../../backend_srv'; export interface PerformanceEventPayload { diff --git a/public/app/core/services/echo/backends/analytics/ApplicationInsightsBackend.ts b/public/app/core/services/echo/backends/analytics/ApplicationInsightsBackend.ts index 96dacbc9081..caaef40fe51 100644 --- a/public/app/core/services/echo/backends/analytics/ApplicationInsightsBackend.ts +++ b/public/app/core/services/echo/backends/analytics/ApplicationInsightsBackend.ts @@ -1,4 +1,5 @@ import $ from 'jquery'; + import { EchoBackend, EchoEventType, diff --git a/public/app/core/services/echo/backends/analytics/GABackend.ts b/public/app/core/services/echo/backends/analytics/GABackend.ts index 6a6401f73e3..dd65adf32d9 100644 --- a/public/app/core/services/echo/backends/analytics/GABackend.ts +++ b/public/app/core/services/echo/backends/analytics/GABackend.ts @@ -1,4 +1,5 @@ import $ from 'jquery'; + import { EchoBackend, EchoEventType, PageviewEchoEvent } from '@grafana/runtime'; export interface GAEchoBackendOptions { diff --git a/public/app/core/services/echo/backends/analytics/RudderstackBackend.ts b/public/app/core/services/echo/backends/analytics/RudderstackBackend.ts index 0f3b16c4923..f18362393d8 100644 --- a/public/app/core/services/echo/backends/analytics/RudderstackBackend.ts +++ b/public/app/core/services/echo/backends/analytics/RudderstackBackend.ts @@ -1,4 +1,6 @@ import $ from 'jquery'; + +import { CurrentUserDTO } from '@grafana/data'; import { EchoBackend, EchoEventType, @@ -7,7 +9,7 @@ import { isPageviewEvent, PageviewEchoEvent, } from '@grafana/runtime'; -import { CurrentUserDTO } from '@grafana/data'; + import { getUserIdentifier } from '../../utils'; export interface RudderstackBackendOptions { diff --git a/public/app/core/services/echo/backends/sentry/SentryBackend.test.ts b/public/app/core/services/echo/backends/sentry/SentryBackend.test.ts index a11380a68a1..62b1cd7c5ae 100644 --- a/public/app/core/services/echo/backends/sentry/SentryBackend.test.ts +++ b/public/app/core/services/echo/backends/sentry/SentryBackend.test.ts @@ -1,14 +1,17 @@ import { init as initSentry, setUser as sentrySetUser, Event as SentryEvent } from '@sentry/browser'; -import { SentryEchoBackend, SentryEchoBackendOptions } from './SentryBackend'; -import { BuildInfo } from '@grafana/data'; import { FetchTransport } from '@sentry/browser/dist/transports'; +import { waitFor } from '@testing-library/react'; + +import { BuildInfo } from '@grafana/data'; +import { GrafanaEdition } from '@grafana/data/src/types/config'; +import { EchoBackend, EchoEventType, EchoMeta, setEchoSrv } from '@grafana/runtime'; + +import { Echo } from '../../Echo'; + +import { SentryEchoBackend, SentryEchoBackendOptions } from './SentryBackend'; import { CustomEndpointTransport } from './transports/CustomEndpointTransport'; import { EchoSrvTransport } from './transports/EchoSrvTransport'; import { SentryEchoEvent } from './types'; -import { EchoBackend, EchoEventType, EchoMeta, setEchoSrv } from '@grafana/runtime'; -import { waitFor } from '@testing-library/react'; -import { Echo } from '../../Echo'; -import { GrafanaEdition } from '@grafana/data/src/types/config'; jest.mock('@sentry/browser'); diff --git a/public/app/core/services/echo/backends/sentry/SentryBackend.ts b/public/app/core/services/echo/backends/sentry/SentryBackend.ts index 00753252a56..08211be9d82 100644 --- a/public/app/core/services/echo/backends/sentry/SentryBackend.ts +++ b/public/app/core/services/echo/backends/sentry/SentryBackend.ts @@ -1,10 +1,12 @@ -import { EchoBackend, EchoEventType } from '@grafana/runtime'; -import { SentryConfig } from '@grafana/data/src/types/config'; import { BrowserOptions, init as initSentry, setUser as sentrySetUser } from '@sentry/browser'; import { FetchTransport } from '@sentry/browser/dist/transports'; + +import { BuildInfo } from '@grafana/data'; +import { SentryConfig } from '@grafana/data/src/types/config'; +import { EchoBackend, EchoEventType } from '@grafana/runtime'; + import { CustomEndpointTransport } from './transports/CustomEndpointTransport'; import { EchoSrvTransport } from './transports/EchoSrvTransport'; -import { BuildInfo } from '@grafana/data'; import { SentryEchoEvent, User, BaseTransport } from './types'; export interface SentryEchoBackendOptions extends SentryConfig { diff --git a/public/app/core/services/echo/backends/sentry/transports/CustomEndpointTransport.test.ts b/public/app/core/services/echo/backends/sentry/transports/CustomEndpointTransport.test.ts index 16f6e484f4e..c38ff48c919 100644 --- a/public/app/core/services/echo/backends/sentry/transports/CustomEndpointTransport.test.ts +++ b/public/app/core/services/echo/backends/sentry/transports/CustomEndpointTransport.test.ts @@ -1,4 +1,5 @@ import { Event, Severity } from '@sentry/browser'; + import { CustomEndpointTransport } from './CustomEndpointTransport'; describe('CustomEndpointTransport', () => { diff --git a/public/app/core/services/echo/backends/sentry/transports/CustomEndpointTransport.ts b/public/app/core/services/echo/backends/sentry/transports/CustomEndpointTransport.ts index afe300c6ad4..cf828758a8b 100644 --- a/public/app/core/services/echo/backends/sentry/transports/CustomEndpointTransport.ts +++ b/public/app/core/services/echo/backends/sentry/transports/CustomEndpointTransport.ts @@ -1,4 +1,5 @@ import { Event, Severity } from '@sentry/browser'; +import { Response } from '@sentry/types'; import { logger, makePromiseBuffer, @@ -7,7 +8,7 @@ import { supportsReferrerPolicy, SyncPromise, } from '@sentry/utils'; -import { Response } from '@sentry/types'; + import { BaseTransport } from '../types'; export interface CustomEndpointTransportOptions { diff --git a/public/app/core/services/echo/backends/sentry/transports/EchoSrvTransport.ts b/public/app/core/services/echo/backends/sentry/transports/EchoSrvTransport.ts index b3555b17568..4d3db59eca7 100644 --- a/public/app/core/services/echo/backends/sentry/transports/EchoSrvTransport.ts +++ b/public/app/core/services/echo/backends/sentry/transports/EchoSrvTransport.ts @@ -1,8 +1,9 @@ -import { getEchoSrv, EchoEventType } from '@grafana/runtime'; -import { BaseTransport } from '@sentry/browser/dist/transports'; import { Event } from '@sentry/browser'; +import { BaseTransport } from '@sentry/browser/dist/transports'; import { EventStatus, Request, Session, Response } from '@sentry/types'; +import { getEchoSrv, EchoEventType } from '@grafana/runtime'; + export class EchoSrvTransport extends BaseTransport { sendEvent(event: Event) { getEchoSrv().addEvent({ diff --git a/public/app/core/services/echo/backends/sentry/types.ts b/public/app/core/services/echo/backends/sentry/types.ts index 9d5906a2d53..a19fe3c0856 100644 --- a/public/app/core/services/echo/backends/sentry/types.ts +++ b/public/app/core/services/echo/backends/sentry/types.ts @@ -1,7 +1,8 @@ -import { EchoEvent, EchoEventType } from '@grafana/runtime'; import { Event as SentryEvent } from '@sentry/browser'; import { Response } from '@sentry/types'; +import { EchoEvent, EchoEventType } from '@grafana/runtime'; + export interface BaseTransport { sendEvent(event: SentryEvent): PromiseLike; } diff --git a/public/app/core/services/echo/utils.test.ts b/public/app/core/services/echo/utils.test.ts index 0b646cd8363..06406970ab5 100644 --- a/public/app/core/services/echo/utils.test.ts +++ b/public/app/core/services/echo/utils.test.ts @@ -1,4 +1,5 @@ import { CurrentUserDTO, OrgRole } from '@grafana/data'; + import { getUserIdentifier } from './utils'; const baseUser: CurrentUserDTO = { diff --git a/public/app/core/services/echo/utils.ts b/public/app/core/services/echo/utils.ts index edcfe096d77..a8a75d92953 100644 --- a/public/app/core/services/echo/utils.ts +++ b/public/app/core/services/echo/utils.ts @@ -1,6 +1,5 @@ -import { attachDebugger, createLogger } from '@grafana/ui'; - import { CurrentUserDTO } from '@grafana/data'; +import { attachDebugger, createLogger } from '@grafana/ui'; /** * Returns an opaque identifier for a user, for reporting purposes. diff --git a/public/app/core/services/impression_srv.ts b/public/app/core/services/impression_srv.ts index 95c1acf36f3..f26b85dc542 100644 --- a/public/app/core/services/impression_srv.ts +++ b/public/app/core/services/impression_srv.ts @@ -1,6 +1,7 @@ -import store from 'app/core/store'; import { filter, isArray, isNumber } from 'lodash'; + import config from 'app/core/config'; +import store from 'app/core/store'; export class ImpressionSrv { constructor() {} diff --git a/public/app/core/services/keybindingSrv.ts b/public/app/core/services/keybindingSrv.ts index 598f8448fc6..0e9755af3a8 100644 --- a/public/app/core/services/keybindingSrv.ts +++ b/public/app/core/services/keybindingSrv.ts @@ -1,14 +1,17 @@ import Mousetrap from 'mousetrap'; + import 'mousetrap-global-bind'; import 'mousetrap/plugins/global-bind/mousetrap-global-bind'; import { LegacyGraphHoverClearEvent, locationUtil } from '@grafana/data'; +import { locationService } from '@grafana/runtime'; import appEvents from 'app/core/app_events'; import { getExploreUrl } from 'app/core/utils/explore'; -import { DashboardModel } from 'app/features/dashboard/state'; -import { ShareModal } from 'app/features/dashboard/components/ShareModal'; import { SaveDashboardProxy } from 'app/features/dashboard/components/SaveDashboard/SaveDashboardProxy'; -import { locationService } from '@grafana/runtime'; -import { exitKioskMode, toggleKioskMode } from '../navigation/kiosk'; +import { ShareModal } from 'app/features/dashboard/components/ShareModal'; +import { DashboardModel } from 'app/features/dashboard/state'; + +import { getTimeSrv } from '../../features/dashboard/services/TimeSrv'; +import { getDatasourceSrv } from '../../features/plugins/datasource_srv'; import { RemovePanelEvent, ShiftTimeEvent, @@ -17,12 +20,12 @@ import { ZoomOutEvent, AbsoluteTimeEvent, } from '../../types/events'; +import { HelpModal } from '../components/help/HelpModal'; import { contextSrv } from '../core'; -import { getDatasourceSrv } from '../../features/plugins/datasource_srv'; -import { getTimeSrv } from '../../features/dashboard/services/TimeSrv'; +import { exitKioskMode, toggleKioskMode } from '../navigation/kiosk'; + import { toggleTheme } from './toggleTheme'; import { withFocusedPanel } from './withFocusedPanelId'; -import { HelpModal } from '../components/help/HelpModal'; export class KeybindingSrv { reset() { diff --git a/public/app/core/services/search_srv.ts b/public/app/core/services/search_srv.ts index 581a90f662c..a5030a3c22a 100644 --- a/public/app/core/services/search_srv.ts +++ b/public/app/core/services/search_srv.ts @@ -1,10 +1,12 @@ import { clone, keys, sortBy, take, values } from 'lodash'; + +import { contextSrv } from 'app/core/services/context_srv'; import impressionSrv from 'app/core/services/impression_srv'; import store from 'app/core/store'; -import { contextSrv } from 'app/core/services/context_srv'; -import { hasFilters } from 'app/features/search/utils'; import { SECTION_STORAGE_KEY } from 'app/features/search/constants'; import { DashboardSection, DashboardSearchItemType, DashboardSearchHit, SearchLayout } from 'app/features/search/types'; +import { hasFilters } from 'app/features/search/utils'; + import { backendSrv } from './backend_srv'; interface Sections { diff --git a/public/app/core/services/toggleTheme.ts b/public/app/core/services/toggleTheme.ts index 2cb4d1b7770..6aeca20546a 100644 --- a/public/app/core/services/toggleTheme.ts +++ b/public/app/core/services/toggleTheme.ts @@ -1,9 +1,11 @@ +import { createTheme } from '@grafana/data'; import { ThemeChangedEvent } from '@grafana/runtime'; + import appEvents from '../app_events'; import { config } from '../config'; -import { PreferencesService } from './PreferencesService'; import { contextSrv } from '../core'; -import { createTheme } from '@grafana/data'; + +import { PreferencesService } from './PreferencesService'; export async function toggleTheme(runtimeOnly: boolean) { const currentTheme = config.theme; diff --git a/public/app/core/specs/OrgSwitcher.test.tsx b/public/app/core/specs/OrgSwitcher.test.tsx index b99b44de1da..cb612259ec3 100644 --- a/public/app/core/specs/OrgSwitcher.test.tsx +++ b/public/app/core/specs/OrgSwitcher.test.tsx @@ -1,10 +1,10 @@ -import React from 'react'; import { render, screen, waitFor, within } from '@testing-library/react'; - -import { OrgSwitcher } from '../components/OrgSwitcher'; -import { api } from '../../features/profile/api'; import userEvent from '@testing-library/user-event'; +import React from 'react'; + +import { api } from '../../features/profile/api'; import { OrgRole } from '../../types'; +import { OrgSwitcher } from '../components/OrgSwitcher'; jest.mock('@grafana/runtime', () => ({ config: { diff --git a/public/app/core/specs/backend_srv.test.ts b/public/app/core/specs/backend_srv.test.ts index 5176f4959d0..e9c5c095101 100644 --- a/public/app/core/specs/backend_srv.test.ts +++ b/public/app/core/specs/backend_srv.test.ts @@ -1,13 +1,14 @@ import 'whatwg-fetch'; // fetch polyfill needed for PhantomJs rendering import { Observable, of } from 'rxjs'; import { delay } from 'rxjs/operators'; -import { AppEvents, DataQueryErrorType, EventBusExtended } from '@grafana/data'; -import { BackendSrv } from '../services/backend_srv'; -import { ContextSrv, User } from '../services/context_srv'; +import { AppEvents, DataQueryErrorType, EventBusExtended } from '@grafana/data'; import { BackendSrvRequest, FetchError } from '@grafana/runtime'; + import { TokenRevokedModal } from '../../features/users/TokenRevokedModal'; import { ShowModalReactEvent } from '../../types/events'; +import { BackendSrv } from '../services/backend_srv'; +import { ContextSrv, User } from '../services/context_srv'; const getTestContext = (overides?: object) => { const defaults = { diff --git a/public/app/core/specs/search_srv.test.ts b/public/app/core/specs/search_srv.test.ts index 1a03c1f96d2..5fe30ef2df1 100644 --- a/public/app/core/specs/search_srv.test.ts +++ b/public/app/core/specs/search_srv.test.ts @@ -1,7 +1,9 @@ -import { SearchSrv } from 'app/core/services/search_srv'; -import impressionSrv from 'app/core/services/impression_srv'; -import { contextSrv } from 'app/core/services/context_srv'; import { beforeEach } from 'test/lib/common'; + +import { contextSrv } from 'app/core/services/context_srv'; +import impressionSrv from 'app/core/services/impression_srv'; +import { SearchSrv } from 'app/core/services/search_srv'; + import { backendSrv } from '../services/backend_srv'; jest.mock('app/core/store', () => { diff --git a/public/app/core/table_model.ts b/public/app/core/table_model.ts index f2c83e40aa2..901345ce562 100644 --- a/public/app/core/table_model.ts +++ b/public/app/core/table_model.ts @@ -1,4 +1,5 @@ import { findIndex } from 'lodash'; + import { Column, TableData, QueryResultMeta } from '@grafana/data'; /** diff --git a/public/app/core/time_series2.ts b/public/app/core/time_series2.ts index 8a9a515d489..e2c301d50a9 100644 --- a/public/app/core/time_series2.ts +++ b/public/app/core/time_series2.ts @@ -1,4 +1,5 @@ import { isNumber, isFinite, escape } from 'lodash'; + import { DecimalCount, formattedValueToString, getValueFormat, stringToJsRegex, ValueFormatter } from '@grafana/data'; function matchSeriesOverride(aliasOrRegex: string, seriesAlias: string) { diff --git a/public/app/core/utils/ConfigProvider.tsx b/public/app/core/utils/ConfigProvider.tsx index fe9e64d28bb..e714ab27b09 100644 --- a/public/app/core/utils/ConfigProvider.tsx +++ b/public/app/core/utils/ConfigProvider.tsx @@ -1,8 +1,10 @@ import React, { useEffect, useState } from 'react'; + +import { createTheme } from '@grafana/data'; import { config, GrafanaBootConfig, ThemeChangedEvent } from '@grafana/runtime'; import { ThemeContext } from '@grafana/ui'; + import { appEvents } from '../core'; -import { createTheme } from '@grafana/data'; export const ConfigContext = React.createContext(config); export const ConfigConsumer = ConfigContext.Consumer; diff --git a/public/app/core/utils/connectWithReduxStore.tsx b/public/app/core/utils/connectWithReduxStore.tsx index c7dc4591b9b..83f3b519fd3 100644 --- a/public/app/core/utils/connectWithReduxStore.tsx +++ b/public/app/core/utils/connectWithReduxStore.tsx @@ -1,5 +1,6 @@ import React from 'react'; import { connect, Provider } from 'react-redux'; + import { store } from '../../store/store'; export function connectWithStore(WrappedComponent: any, ...args: any[]) { diff --git a/public/app/core/utils/explore.test.ts b/public/app/core/utils/explore.test.ts index 7b1a4d2b999..49bccf92632 100644 --- a/public/app/core/utils/explore.test.ts +++ b/public/app/core/utils/explore.test.ts @@ -1,3 +1,10 @@ +import { dateTime, ExploreUrlState, LogsSortOrder } from '@grafana/data'; +import { serializeStateToUrlParam } from '@grafana/data/src/utils/url'; +import { RefreshPicker } from '@grafana/ui'; +import store from 'app/core/store'; + +import { ExploreId } from '../../types'; + import { buildQueryTransaction, clearHistory, @@ -13,11 +20,6 @@ import { getTimeRangeFromUrl, getTimeRange, } from './explore'; -import store from 'app/core/store'; -import { dateTime, ExploreUrlState, LogsSortOrder } from '@grafana/data'; -import { RefreshPicker } from '@grafana/ui'; -import { serializeStateToUrlParam } from '@grafana/data/src/utils/url'; -import { ExploreId } from '../../types'; const DEFAULT_EXPLORE_STATE: ExploreUrlState = { datasource: '', diff --git a/public/app/core/utils/explore.ts b/public/app/core/utils/explore.ts index d4181c25086..a28a58909bb 100644 --- a/public/app/core/utils/explore.ts +++ b/public/app/core/utils/explore.ts @@ -1,7 +1,7 @@ -// Libraries import { flatten, omit, uniq } from 'lodash'; import { Unsubscribable } from 'rxjs'; -// Services & Utils +import { v4 as uuidv4 } from 'uuid'; + import { CoreApp, DataQuery, @@ -24,16 +24,16 @@ import { toUtc, urlUtil, } from '@grafana/data'; -import store from 'app/core/store'; -import { v4 as uuidv4 } from 'uuid'; -import { getNextRefIdChar } from './query'; -// Types -import { RefreshPicker } from '@grafana/ui'; -import { EXPLORE_GRAPH_STYLES, ExploreGraphStyle, ExploreId, QueryOptions, QueryTransaction } from 'app/types/explore'; -import { config } from '../config'; -import { TimeSrv } from 'app/features/dashboard/services/TimeSrv'; import { DataSourceSrv } from '@grafana/runtime'; +import { RefreshPicker } from '@grafana/ui'; +import store from 'app/core/store'; +import { TimeSrv } from 'app/features/dashboard/services/TimeSrv'; import { PanelModel } from 'app/features/dashboard/state'; +import { EXPLORE_GRAPH_STYLES, ExploreGraphStyle, ExploreId, QueryOptions, QueryTransaction } from 'app/types/explore'; + +import { config } from '../config'; + +import { getNextRefIdChar } from './query'; export const DEFAULT_RANGE = { from: 'now-1h', diff --git a/public/app/core/utils/fetch.ts b/public/app/core/utils/fetch.ts index fb77a6d1a7d..c4b00d2034e 100644 --- a/public/app/core/utils/fetch.ts +++ b/public/app/core/utils/fetch.ts @@ -1,6 +1,7 @@ -import { BackendSrvRequest } from '@grafana/runtime'; import { omitBy } from 'lodash'; + import { deprecationWarning } from '@grafana/data'; +import { BackendSrvRequest } from '@grafana/runtime'; export const parseInitFromOptions = (options: BackendSrvRequest): RequestInit => { const method = options.method; diff --git a/public/app/core/utils/kbn.test.ts b/public/app/core/utils/kbn.test.ts index 1ebae32ecc1..6e291f3d1b2 100644 --- a/public/app/core/utils/kbn.test.ts +++ b/public/app/core/utils/kbn.test.ts @@ -1,6 +1,7 @@ -import kbn from './kbn'; import { DecimalCount, TimeZone } from '@grafana/data'; +import kbn from './kbn'; + // Most of the methods in this file are deprecated // Stub the deprecation warning here to prevent polluting the test output jest.mock('@grafana/data', () => ({ diff --git a/public/app/core/utils/query.test.ts b/public/app/core/utils/query.test.ts index 00c69667432..4b2028ce544 100644 --- a/public/app/core/utils/query.test.ts +++ b/public/app/core/utils/query.test.ts @@ -1,4 +1,5 @@ import { DataQuery } from '@grafana/data'; + import { getNextRefIdChar } from './query'; function dataQueryHelper(ids: string[]): DataQuery[] { diff --git a/public/app/core/utils/richHistory.test.ts b/public/app/core/utils/richHistory.test.ts index cd6b12a58ac..446362f9a72 100644 --- a/public/app/core/utils/richHistory.test.ts +++ b/public/app/core/utils/richHistory.test.ts @@ -1,3 +1,9 @@ +import { dateTime, DataQuery } from '@grafana/data'; +import store from 'app/core/store'; + +import { RichHistoryQuery } from '../../types'; +import RichHistoryStorage, { RichHistoryStorageWarning } from '../history/RichHistoryStorage'; + import { addToRichHistory, updateStarredInRichHistory, @@ -10,10 +16,6 @@ import { filterAndSortQueries, SortOrder, } from './richHistory'; -import store from 'app/core/store'; -import { dateTime, DataQuery } from '@grafana/data'; -import RichHistoryStorage, { RichHistoryStorageWarning } from '../history/RichHistoryStorage'; -import { RichHistoryQuery } from '../../types'; const richHistoryStorageMock: RichHistoryStorage = {} as RichHistoryStorage; diff --git a/public/app/core/utils/richHistory.ts b/public/app/core/utils/richHistory.ts index 5e08a4fa046..2cb8efe0365 100644 --- a/public/app/core/utils/richHistory.ts +++ b/public/app/core/utils/richHistory.ts @@ -1,28 +1,26 @@ -// Libraries import { omit } from 'lodash'; -// Services & Utils import { DataQuery, DataSourceApi, dateTimeFormat, ExploreUrlState, urlUtil } from '@grafana/data'; -import { dispatch } from 'app/store/store'; -import { notifyApp } from 'app/core/actions'; -import { createErrorNotification, createWarningNotification } from 'app/core/copy/appNotification'; - -// Types -import { RichHistoryQuery } from 'app/types/explore'; import { serializeStateToUrlParam } from '@grafana/data/src/utils/url'; import { getDataSourceSrv } from '@grafana/runtime'; -import { getRichHistoryStorage } from '../history/richHistoryStorageProvider'; -import { - RichHistoryServiceError, - RichHistoryStorageWarning, - RichHistoryStorageWarningDetails, -} from '../history/RichHistoryStorage'; +import { notifyApp } from 'app/core/actions'; +import { createErrorNotification, createWarningNotification } from 'app/core/copy/appNotification'; import { filterQueriesByDataSource, filterQueriesBySearchFilter, filterQueriesByTime, sortQueries, } from 'app/core/history/richHistoryLocalStorageUtils'; +import { dispatch } from 'app/store/store'; +import { RichHistoryQuery } from 'app/types/explore'; + +import { + RichHistoryServiceError, + RichHistoryStorageWarning, + RichHistoryStorageWarningDetails, +} from '../history/RichHistoryStorage'; +import { getRichHistoryStorage } from '../history/richHistoryStorageProvider'; + import { RichHistorySettings, SortOrder } from './richHistoryTypes'; export { SortOrder }; diff --git a/public/app/core/utils/shortLinks.ts b/public/app/core/utils/shortLinks.ts index 07430542dc8..30b6beb1c24 100644 --- a/public/app/core/utils/shortLinks.ts +++ b/public/app/core/utils/shortLinks.ts @@ -1,9 +1,11 @@ import memoizeOne from 'memoize-one'; + import { getBackendSrv, config } from '@grafana/runtime'; -import { copyStringToClipboard } from './explore'; -import { dispatch } from 'app/store/store'; import { notifyApp } from 'app/core/actions'; import { createErrorNotification, createSuccessNotification } from 'app/core/copy/appNotification'; +import { dispatch } from 'app/store/store'; + +import { copyStringToClipboard } from './explore'; function buildHostUrl() { return `${window.location.protocol}//${window.location.host}${config.appSubUrl}`; diff --git a/public/app/features/admin/AdminEditOrgPage.tsx b/public/app/features/admin/AdminEditOrgPage.tsx index bad9182189c..9afb7c4484c 100644 --- a/public/app/features/admin/AdminEditOrgPage.tsx +++ b/public/app/features/admin/AdminEditOrgPage.tsx @@ -1,17 +1,19 @@ -import React, { useState, useEffect } from 'react'; -import Page from 'app/core/components/Page/Page'; -import { useSelector } from 'react-redux'; -import { StoreState, OrgUser, AccessControlAction } from 'app/types'; -import { getNavModel } from 'app/core/selectors/navModel'; -import UsersTable from '../users/UsersTable'; -import { useAsyncFn } from 'react-use'; -import { getBackendSrv } from '@grafana/runtime'; -import { UrlQueryValue } from '@grafana/data'; -import { Form, Field, Input, Button, Legend, Alert } from '@grafana/ui'; import { css } from '@emotion/css'; -import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; +import React, { useState, useEffect } from 'react'; +import { useSelector } from 'react-redux'; +import { useAsyncFn } from 'react-use'; + +import { UrlQueryValue } from '@grafana/data'; +import { getBackendSrv } from '@grafana/runtime'; +import { Form, Field, Input, Button, Legend, Alert } from '@grafana/ui'; +import Page from 'app/core/components/Page/Page'; import { contextSrv } from 'app/core/core'; +import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; +import { getNavModel } from 'app/core/selectors/navModel'; import { accessControlQueryParam } from 'app/core/utils/accessControl'; +import { StoreState, OrgUser, AccessControlAction } from 'app/types'; + +import UsersTable from '../users/UsersTable'; interface OrgNameDTO { orgName: string; diff --git a/public/app/features/admin/AdminListOrgsPage.tsx b/public/app/features/admin/AdminListOrgsPage.tsx index f9e70493822..6fff515aa09 100644 --- a/public/app/features/admin/AdminListOrgsPage.tsx +++ b/public/app/features/admin/AdminListOrgsPage.tsx @@ -1,14 +1,16 @@ import React, { useEffect } from 'react'; -import { getNavModel } from 'app/core/selectors/navModel'; -import Page from 'app/core/components/Page/Page'; import { useSelector } from 'react-redux'; -import { StoreState } from 'app/types/store'; -import { LinkButton } from '@grafana/ui'; -import { getBackendSrv } from '@grafana/runtime'; -import { AdminOrgsTable } from './AdminOrgsTable'; import useAsyncFn from 'react-use/lib/useAsyncFn'; + +import { getBackendSrv } from '@grafana/runtime'; +import { LinkButton } from '@grafana/ui'; +import Page from 'app/core/components/Page/Page'; +import { getNavModel } from 'app/core/selectors/navModel'; import { contextSrv } from 'app/core/services/context_srv'; import { AccessControlAction } from 'app/types'; +import { StoreState } from 'app/types/store'; + +import { AdminOrgsTable } from './AdminOrgsTable'; const deleteOrg = async (orgId: number) => { return await getBackendSrv().delete('/api/orgs/' + orgId); diff --git a/public/app/features/admin/AdminOrgsTable.tsx b/public/app/features/admin/AdminOrgsTable.tsx index f8c9003d80d..6a042ca6af2 100644 --- a/public/app/features/admin/AdminOrgsTable.tsx +++ b/public/app/features/admin/AdminOrgsTable.tsx @@ -1,7 +1,8 @@ import React, { useState } from 'react'; -import { AccessControlAction, Organization } from 'app/types'; + import { Button, ConfirmModal } from '@grafana/ui'; import { contextSrv } from 'app/core/core'; +import { AccessControlAction, Organization } from 'app/types'; interface Props { orgs: Organization[]; diff --git a/public/app/features/admin/AdminSettings.tsx b/public/app/features/admin/AdminSettings.tsx index d54470c49cc..e2e2a0c7ecb 100644 --- a/public/app/features/admin/AdminSettings.tsx +++ b/public/app/features/admin/AdminSettings.tsx @@ -1,12 +1,12 @@ import React from 'react'; import { connect } from 'react-redux'; import { useAsync } from 'react-use'; -import { getBackendSrv } from '@grafana/runtime'; -import { NavModel } from '@grafana/data'; -import { StoreState } from 'app/types'; -import { getNavModel } from 'app/core/selectors/navModel'; +import { NavModel } from '@grafana/data'; +import { getBackendSrv } from '@grafana/runtime'; import Page from 'app/core/components/Page/Page'; +import { getNavModel } from 'app/core/selectors/navModel'; +import { StoreState } from 'app/types'; type Settings = { [key: string]: { [key: string]: string } }; diff --git a/public/app/features/admin/CrawlerStartButton.tsx b/public/app/features/admin/CrawlerStartButton.tsx index 1035eac199e..3cceb47b7f3 100644 --- a/public/app/features/admin/CrawlerStartButton.tsx +++ b/public/app/features/admin/CrawlerStartButton.tsx @@ -1,8 +1,9 @@ -import React, { useState } from 'react'; import { css } from '@emotion/css'; -import { Button, CodeEditor, Modal, useTheme2 } from '@grafana/ui'; +import React, { useState } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { getBackendSrv, config } from '@grafana/runtime'; +import { Button, CodeEditor, Modal, useTheme2 } from '@grafana/ui'; export const CrawlerStartButton = () => { const styles = getStyles(useTheme2()); diff --git a/public/app/features/admin/CrawlerStatus.tsx b/public/app/features/admin/CrawlerStatus.tsx index 50dd9f97cdf..5880f43ec39 100644 --- a/public/app/features/admin/CrawlerStatus.tsx +++ b/public/app/features/admin/CrawlerStatus.tsx @@ -1,8 +1,10 @@ -import React, { useEffect, useState } from 'react'; import { css } from '@emotion/css'; -import { Button, useTheme2 } from '@grafana/ui'; +import React, { useEffect, useState } from 'react'; + import { GrafanaTheme2, isLiveChannelMessageEvent, isLiveChannelStatusEvent, LiveChannelScope } from '@grafana/data'; import { getBackendSrv, getGrafanaLiveSrv } from '@grafana/runtime'; +import { Button, useTheme2 } from '@grafana/ui'; + import { CrawlerStartButton } from './CrawlerStartButton'; interface CrawlerStatusMessage { diff --git a/public/app/features/admin/LicenseChrome.tsx b/public/app/features/admin/LicenseChrome.tsx index 1acf09e3696..ada9a83935d 100644 --- a/public/app/features/admin/LicenseChrome.tsx +++ b/public/app/features/admin/LicenseChrome.tsx @@ -1,7 +1,8 @@ -import React from 'react'; -import { stylesFactory, useTheme } from '@grafana/ui'; import { css } from '@emotion/css'; +import React from 'react'; + import { GrafanaTheme } from '@grafana/data'; +import { stylesFactory, useTheme } from '@grafana/ui'; const title = { fontWeight: 500, fontSize: '26px', lineHeight: '123%' }; diff --git a/public/app/features/admin/OrgRolePicker.tsx b/public/app/features/admin/OrgRolePicker.tsx index 88e30c8a547..ef6a158e4a5 100644 --- a/public/app/features/admin/OrgRolePicker.tsx +++ b/public/app/features/admin/OrgRolePicker.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { OrgRole } from '@grafana/data'; import { Select } from '@grafana/ui'; diff --git a/public/app/features/admin/ServerStats.test.tsx b/public/app/features/admin/ServerStats.test.tsx index 4f777c22e0a..eddea4f6068 100644 --- a/public/app/features/admin/ServerStats.test.tsx +++ b/public/app/features/admin/ServerStats.test.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; +import React from 'react'; + import { ServerStats } from './ServerStats'; import { ServerStat } from './state/apis'; diff --git a/public/app/features/admin/ServerStats.tsx b/public/app/features/admin/ServerStats.tsx index c883750e161..672d1ba2746 100644 --- a/public/app/features/admin/ServerStats.tsx +++ b/public/app/features/admin/ServerStats.tsx @@ -1,13 +1,16 @@ -import React, { useEffect, useState } from 'react'; import { css } from '@emotion/css'; -import { CardContainer, LinkButton, useStyles2 } from '@grafana/ui'; +import React, { useEffect, useState } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; +import { config } from '@grafana/runtime'; +import { CardContainer, LinkButton, useStyles2 } from '@grafana/ui'; import { AccessControlAction } from 'app/types'; -import { getServerStats, ServerStat } from './state/apis'; + import { contextSrv } from '../../core/services/context_srv'; import { Loader } from '../plugins/admin/components/Loader'; -import { config } from '@grafana/runtime'; + import { CrawlerStatus } from './CrawlerStatus'; +import { getServerStats, ServerStat } from './state/apis'; export const ServerStats = () => { const [stats, setStats] = useState(null); diff --git a/public/app/features/admin/UpgradePage.tsx b/public/app/features/admin/UpgradePage.tsx index a2bdc527c9a..3678cb244c6 100644 --- a/public/app/features/admin/UpgradePage.tsx +++ b/public/app/features/admin/UpgradePage.tsx @@ -1,12 +1,15 @@ +import { css } from '@emotion/css'; import React from 'react'; import { connect } from 'react-redux'; -import { css } from '@emotion/css'; -import { LinkButton, useStyles2 } from '@grafana/ui'; + import { GrafanaTheme2, NavModel } from '@grafana/data'; +import { LinkButton, useStyles2 } from '@grafana/ui'; + import Page from '../../core/components/Page/Page'; import { getNavModel } from '../../core/selectors/navModel'; -import { LicenseChrome } from './LicenseChrome'; import { StoreState } from '../../types'; + +import { LicenseChrome } from './LicenseChrome'; import { ServerStats } from './ServerStats'; interface Props { diff --git a/public/app/features/admin/UserAdminPage.tsx b/public/app/features/admin/UserAdminPage.tsx index 5a4d9c789fc..264e9ce943a 100644 --- a/public/app/features/admin/UserAdminPage.tsx +++ b/public/app/features/admin/UserAdminPage.tsx @@ -1,14 +1,19 @@ import React, { PureComponent } from 'react'; import { connect, ConnectedProps } from 'react-redux'; + import { NavModel } from '@grafana/data'; -import { getNavModel } from 'app/core/selectors/navModel'; import { featureEnabled } from '@grafana/runtime'; import Page from 'app/core/components/Page/Page'; -import { UserProfile } from './UserProfile'; -import { UserPermissions } from './UserPermissions'; -import { UserSessions } from './UserSessions'; -import { UserLdapSyncInfo } from './UserLdapSyncInfo'; +import { contextSrv } from 'app/core/core'; +import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; +import { getNavModel } from 'app/core/selectors/navModel'; import { StoreState, UserDTO, UserOrg, UserSession, SyncInfo, UserAdminError, AccessControlAction } from 'app/types'; + +import { UserLdapSyncInfo } from './UserLdapSyncInfo'; +import { UserOrgs } from './UserOrgs'; +import { UserPermissions } from './UserPermissions'; +import { UserProfile } from './UserProfile'; +import { UserSessions } from './UserSessions'; import { loadAdminUserPage, revokeSession, @@ -24,9 +29,6 @@ import { deleteOrgUser, syncLdapUser, } from './state/actions'; -import { UserOrgs } from './UserOrgs'; -import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; -import { contextSrv } from 'app/core/core'; interface OwnProps extends GrafanaRouteComponentProps<{ id: string }> { navModel: NavModel; diff --git a/public/app/features/admin/UserCreatePage.tsx b/public/app/features/admin/UserCreatePage.tsx index 86a0c5f2b48..b98e82a3e6a 100644 --- a/public/app/features/admin/UserCreatePage.tsx +++ b/public/app/features/admin/UserCreatePage.tsx @@ -1,12 +1,14 @@ import React, { useCallback } from 'react'; import { connect } from 'react-redux'; -import { Form, Button, Input, Field } from '@grafana/ui'; +import { useHistory } from 'react-router-dom'; + import { NavModel } from '@grafana/data'; import { getBackendSrv } from '@grafana/runtime'; -import { StoreState } from '../../types'; -import { getNavModel } from '../../core/selectors/navModel'; +import { Form, Button, Input, Field } from '@grafana/ui'; import Page from 'app/core/components/Page/Page'; -import { useHistory } from 'react-router-dom'; + +import { getNavModel } from '../../core/selectors/navModel'; +import { StoreState } from '../../types'; interface UserCreatePageProps { navModel: NavModel; diff --git a/public/app/features/admin/UserLdapSyncInfo.tsx b/public/app/features/admin/UserLdapSyncInfo.tsx index 6ba53378e4b..7605ef90873 100644 --- a/public/app/features/admin/UserLdapSyncInfo.tsx +++ b/public/app/features/admin/UserLdapSyncInfo.tsx @@ -1,8 +1,9 @@ import React, { PureComponent } from 'react'; + import { dateTimeFormat } from '@grafana/data'; -import { AccessControlAction, SyncInfo, UserDTO } from 'app/types'; import { Button, LinkButton } from '@grafana/ui'; import { contextSrv } from 'app/core/core'; +import { AccessControlAction, SyncInfo, UserDTO } from 'app/types'; interface Props { ldapSyncInfo: SyncInfo; diff --git a/public/app/features/admin/UserListAdminPage.tsx b/public/app/features/admin/UserListAdminPage.tsx index dfb7864ca73..7fa5809ae4f 100644 --- a/public/app/features/admin/UserListAdminPage.tsx +++ b/public/app/features/admin/UserListAdminPage.tsx @@ -1,6 +1,8 @@ -import React, { ComponentType, useEffect, useMemo, memo } from 'react'; import { css, cx } from '@emotion/css'; +import React, { ComponentType, useEffect, useMemo, memo } from 'react'; import { connect, ConnectedProps } from 'react-redux'; + +import { GrafanaTheme2 } from '@grafana/data'; import { Icon, IconName, @@ -11,14 +13,15 @@ import { useStyles2, FilterInput, } from '@grafana/ui'; -import { GrafanaTheme2 } from '@grafana/data'; import Page from 'app/core/components/Page/Page'; import { TagBadge } from 'app/core/components/TagFilter/TagBadge'; import { contextSrv } from 'app/core/core'; + +import PageLoader from '../../core/components/PageLoader/PageLoader'; import { getNavModel } from '../../core/selectors/navModel'; import { AccessControlAction, StoreState, Unit, UserDTO, UserFilter } from '../../types'; + import { changeFilter, changePage, changeQuery, fetchUsers } from './state/actions'; -import PageLoader from '../../core/components/PageLoader/PageLoader'; export interface FilterProps { filters: UserFilter[]; diff --git a/public/app/features/admin/UserOrgs.tsx b/public/app/features/admin/UserOrgs.tsx index ae9b8a21405..1531ab70df4 100644 --- a/public/app/features/admin/UserOrgs.tsx +++ b/public/app/features/admin/UserOrgs.tsx @@ -1,5 +1,7 @@ -import React, { PureComponent, ReactElement } from 'react'; import { css, cx } from '@emotion/css'; +import React, { PureComponent, ReactElement } from 'react'; + +import { GrafanaTheme, GrafanaTheme2 } from '@grafana/data'; import { Button, ConfirmButton, @@ -14,13 +16,13 @@ import { useTheme, withTheme, } from '@grafana/ui'; -import { GrafanaTheme, GrafanaTheme2 } from '@grafana/data'; -import { AccessControlAction, Organization, OrgRole, UserDTO, UserOrg } from 'app/types'; -import { OrgPicker, OrgSelectItem } from 'app/core/components/Select/OrgPicker'; -import { OrgRolePicker } from './OrgRolePicker'; -import { contextSrv } from 'app/core/core'; import { UserRolePicker } from 'app/core/components/RolePicker/UserRolePicker'; import { fetchRoleOptions } from 'app/core/components/RolePicker/api'; +import { OrgPicker, OrgSelectItem } from 'app/core/components/Select/OrgPicker'; +import { contextSrv } from 'app/core/core'; +import { AccessControlAction, Organization, OrgRole, UserDTO, UserOrg } from 'app/types'; + +import { OrgRolePicker } from './OrgRolePicker'; interface Props { orgs: UserOrg[]; diff --git a/public/app/features/admin/UserPermissions.tsx b/public/app/features/admin/UserPermissions.tsx index f1888f1a739..41f6ac321ca 100644 --- a/public/app/features/admin/UserPermissions.tsx +++ b/public/app/features/admin/UserPermissions.tsx @@ -1,7 +1,8 @@ import React, { useState } from 'react'; + import { ConfirmButton, RadioButtonGroup, Icon } from '@grafana/ui'; -import { AccessControlAction } from 'app/types'; import { contextSrv } from 'app/core/core'; +import { AccessControlAction } from 'app/types'; interface Props { isGrafanaAdmin: boolean; diff --git a/public/app/features/admin/UserProfile.tsx b/public/app/features/admin/UserProfile.tsx index 64f37b0e76b..fe9b7646db5 100644 --- a/public/app/features/admin/UserProfile.tsx +++ b/public/app/features/admin/UserProfile.tsx @@ -1,10 +1,11 @@ -import React, { FC, PureComponent, useRef, useState } from 'react'; -import { AccessControlAction, UserDTO } from 'app/types'; import { css, cx } from '@emotion/css'; -import { config } from 'app/core/config'; +import React, { FC, PureComponent, useRef, useState } from 'react'; + import { GrafanaTheme } from '@grafana/data'; import { Button, ConfirmButton, ConfirmModal, Input, LegacyInputStatus, stylesFactory } from '@grafana/ui'; +import { config } from 'app/core/config'; import { contextSrv } from 'app/core/core'; +import { AccessControlAction, UserDTO } from 'app/types'; interface Props { user: UserDTO; diff --git a/public/app/features/admin/UserSessions.tsx b/public/app/features/admin/UserSessions.tsx index cd7b52a7b62..4eccd8241ed 100644 --- a/public/app/features/admin/UserSessions.tsx +++ b/public/app/features/admin/UserSessions.tsx @@ -1,9 +1,10 @@ -import React, { PureComponent } from 'react'; import { css } from '@emotion/css'; -import { ConfirmButton, ConfirmModal, Button } from '@grafana/ui'; -import { AccessControlAction, UserSession } from 'app/types'; -import { contextSrv } from 'app/core/core'; import { withI18n, withI18nProps } from '@lingui/react'; +import React, { PureComponent } from 'react'; + +import { ConfirmButton, ConfirmModal, Button } from '@grafana/ui'; +import { contextSrv } from 'app/core/core'; +import { AccessControlAction, UserSession } from 'app/types'; interface Props extends withI18nProps { sessions: UserSession[]; diff --git a/public/app/features/admin/ldap/LdapConnectionStatus.tsx b/public/app/features/admin/ldap/LdapConnectionStatus.tsx index 1e79ecd80c9..6fbed0a9909 100644 --- a/public/app/features/admin/ldap/LdapConnectionStatus.tsx +++ b/public/app/features/admin/ldap/LdapConnectionStatus.tsx @@ -1,4 +1,5 @@ import React, { FC } from 'react'; + import { Alert, Icon } from '@grafana/ui'; import { AppNotificationSeverity, LdapConnectionInfo, LdapServerInfo } from 'app/types'; diff --git a/public/app/features/admin/ldap/LdapPage.tsx b/public/app/features/admin/ldap/LdapPage.tsx index de23eba550b..28adbdc13ad 100644 --- a/public/app/features/admin/ldap/LdapPage.tsx +++ b/public/app/features/admin/ldap/LdapPage.tsx @@ -1,14 +1,14 @@ import React, { PureComponent } from 'react'; import { connect, ConnectedProps } from 'react-redux'; + import { NavModel } from '@grafana/data'; import { featureEnabled } from '@grafana/runtime'; import { Alert, Button, LegacyForms } from '@grafana/ui'; const { FormField } = LegacyForms; -import { getNavModel } from 'app/core/selectors/navModel'; import Page from 'app/core/components/Page/Page'; -import { LdapConnectionStatus } from './LdapConnectionStatus'; -import { LdapSyncInfo } from './LdapSyncInfo'; -import { LdapUserInfo } from './LdapUserInfo'; +import { contextSrv } from 'app/core/core'; +import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; +import { getNavModel } from 'app/core/selectors/navModel'; import { AppNotificationSeverity, LdapError, @@ -18,6 +18,7 @@ import { LdapConnectionInfo, AccessControlAction, } from 'app/types'; + import { loadLdapState, loadLdapSyncStatus, @@ -25,8 +26,10 @@ import { clearUserError, clearUserMappingInfo, } from '../state/actions'; -import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; -import { contextSrv } from 'app/core/core'; + +import { LdapConnectionStatus } from './LdapConnectionStatus'; +import { LdapSyncInfo } from './LdapSyncInfo'; +import { LdapUserInfo } from './LdapUserInfo'; interface OwnProps extends GrafanaRouteComponentProps<{}, { username?: string }> { navModel: NavModel; diff --git a/public/app/features/admin/ldap/LdapSyncInfo.tsx b/public/app/features/admin/ldap/LdapSyncInfo.tsx index 91a89073bc3..aabcd79358b 100644 --- a/public/app/features/admin/ldap/LdapSyncInfo.tsx +++ b/public/app/features/admin/ldap/LdapSyncInfo.tsx @@ -1,4 +1,5 @@ import React, { PureComponent } from 'react'; + import { dateTimeFormat } from '@grafana/data'; import { Button, Spinner } from '@grafana/ui'; import { SyncInfo } from 'app/types'; diff --git a/public/app/features/admin/ldap/LdapUserGroups.tsx b/public/app/features/admin/ldap/LdapUserGroups.tsx index b0b7da6c153..0fa361acbb5 100644 --- a/public/app/features/admin/ldap/LdapUserGroups.tsx +++ b/public/app/features/admin/ldap/LdapUserGroups.tsx @@ -1,4 +1,5 @@ import React, { FC } from 'react'; + import { Tooltip, Icon } from '@grafana/ui'; import { LdapRole } from 'app/types'; diff --git a/public/app/features/admin/ldap/LdapUserInfo.tsx b/public/app/features/admin/ldap/LdapUserInfo.tsx index c1c3298ccb1..51228b7d4e5 100644 --- a/public/app/features/admin/ldap/LdapUserInfo.tsx +++ b/public/app/features/admin/ldap/LdapUserInfo.tsx @@ -1,9 +1,11 @@ import React, { FC } from 'react'; + +import { LdapUser } from 'app/types'; + +import { LdapUserGroups } from './LdapUserGroups'; import { LdapUserMappingInfo } from './LdapUserMappingInfo'; import { LdapUserPermissions } from './LdapUserPermissions'; -import { LdapUserGroups } from './LdapUserGroups'; import { LdapUserTeams } from './LdapUserTeams'; -import { LdapUser } from 'app/types'; interface Props { ldapUser: LdapUser; diff --git a/public/app/features/admin/ldap/LdapUserMappingInfo.tsx b/public/app/features/admin/ldap/LdapUserMappingInfo.tsx index 26998042faf..8376ba74a07 100644 --- a/public/app/features/admin/ldap/LdapUserMappingInfo.tsx +++ b/public/app/features/admin/ldap/LdapUserMappingInfo.tsx @@ -1,4 +1,5 @@ import React, { FC } from 'react'; + import { LdapUserInfo } from 'app/types'; interface Props { diff --git a/public/app/features/admin/ldap/LdapUserPermissions.tsx b/public/app/features/admin/ldap/LdapUserPermissions.tsx index 3ee94d86fdb..526d4299f77 100644 --- a/public/app/features/admin/ldap/LdapUserPermissions.tsx +++ b/public/app/features/admin/ldap/LdapUserPermissions.tsx @@ -1,6 +1,7 @@ import React, { FC } from 'react'; -import { LdapPermissions } from 'app/types'; + import { Icon } from '@grafana/ui'; +import { LdapPermissions } from 'app/types'; interface Props { permissions: LdapPermissions; diff --git a/public/app/features/admin/ldap/LdapUserTeams.tsx b/public/app/features/admin/ldap/LdapUserTeams.tsx index 38a76e66542..08c601c9159 100644 --- a/public/app/features/admin/ldap/LdapUserTeams.tsx +++ b/public/app/features/admin/ldap/LdapUserTeams.tsx @@ -1,4 +1,5 @@ import React, { FC } from 'react'; + import { Tooltip, Icon } from '@grafana/ui'; import { LdapTeam } from 'app/types'; diff --git a/public/app/features/admin/state/actions.ts b/public/app/features/admin/state/actions.ts index 2297783226d..d21672fce71 100644 --- a/public/app/features/admin/state/actions.ts +++ b/public/app/features/admin/state/actions.ts @@ -1,6 +1,10 @@ -import config from 'app/core/config'; +import { debounce } from 'lodash'; + import { dateTimeFormatTimeAgo } from '@grafana/data'; import { featureEnabled, getBackendSrv, locationService } from '@grafana/runtime'; +import config from 'app/core/config'; +import { contextSrv } from 'app/core/core'; +import { accessControlQueryParam } from 'app/core/utils/accessControl'; import { ThunkResult, LdapUser, UserSession, UserDTO, AccessControlAction, UserFilter } from 'app/types'; import { @@ -23,9 +27,6 @@ import { usersFetchBegin, usersFetchEnd, } from './reducers'; -import { debounce } from 'lodash'; -import { contextSrv } from 'app/core/core'; -import { accessControlQueryParam } from 'app/core/utils/accessControl'; // UserAdminPage export function loadAdminUserPage(userId: number): ThunkResult { diff --git a/public/app/features/admin/state/reducers.test.ts b/public/app/features/admin/state/reducers.test.ts index ea8a804ef2a..ac9b7f37ae7 100644 --- a/public/app/features/admin/state/reducers.test.ts +++ b/public/app/features/admin/state/reducers.test.ts @@ -1,4 +1,7 @@ import { reducerTester } from 'test/core/redux/reducerTester'; + +import { LdapState, LdapUser, UserAdminState, UserDTO, UserListAdminState } from 'app/types'; + import { clearUserMappingInfoAction, ldapConnectionInfoLoadedAction, @@ -14,7 +17,6 @@ import { queryChanged, filterChanged, } from './reducers'; -import { LdapState, LdapUser, UserAdminState, UserDTO, UserListAdminState } from 'app/types'; const makeInitialLdapState = (): LdapState => ({ connectionInfo: [], diff --git a/public/app/features/admin/state/reducers.ts b/public/app/features/admin/state/reducers.ts index 7c3d6ffd2e7..025f95807aa 100644 --- a/public/app/features/admin/state/reducers.ts +++ b/public/app/features/admin/state/reducers.ts @@ -1,4 +1,5 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit'; + import { LdapConnectionInfo, LdapError, diff --git a/public/app/features/alerting/AlertHowToModal.tsx b/public/app/features/alerting/AlertHowToModal.tsx index c4bcbda7db1..4ebddb0c089 100644 --- a/public/app/features/alerting/AlertHowToModal.tsx +++ b/public/app/features/alerting/AlertHowToModal.tsx @@ -1,6 +1,7 @@ -import { Modal, VerticalGroup } from '@grafana/ui'; import React from 'react'; +import { Modal, VerticalGroup } from '@grafana/ui'; + export interface AlertHowToModalProps { onDismiss: () => void; } diff --git a/public/app/features/alerting/AlertRuleItem.test.tsx b/public/app/features/alerting/AlertRuleItem.test.tsx index e619e713334..a779b48c74b 100644 --- a/public/app/features/alerting/AlertRuleItem.test.tsx +++ b/public/app/features/alerting/AlertRuleItem.test.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { render, screen, fireEvent } from '@testing-library/react'; +import React from 'react'; + import AlertRuleItem, { Props } from './AlertRuleItem'; const setup = (propOverrides?: object) => { diff --git a/public/app/features/alerting/AlertRuleItem.tsx b/public/app/features/alerting/AlertRuleItem.tsx index 53468797393..a1b1f93e2bc 100644 --- a/public/app/features/alerting/AlertRuleItem.tsx +++ b/public/app/features/alerting/AlertRuleItem.tsx @@ -1,7 +1,9 @@ import React, { useCallback } from 'react'; // @ts-ignore import Highlighter from 'react-highlight-words'; + import { Icon, IconName, Button, LinkButton, Card } from '@grafana/ui'; + import { AlertRule } from '../../types'; export interface Props { diff --git a/public/app/features/alerting/AlertRuleList.test.tsx b/public/app/features/alerting/AlertRuleList.test.tsx index 935b3d309db..ffa28f2cef2 100644 --- a/public/app/features/alerting/AlertRuleList.test.tsx +++ b/public/app/features/alerting/AlertRuleList.test.tsx @@ -1,15 +1,18 @@ -import React from 'react'; import { shallow } from 'enzyme'; -import { AlertRuleListUnconnected, Props } from './AlertRuleList'; -import { AlertRule } from '../../types'; -import appEvents from '../../core/app_events'; -import { NavModel } from '@grafana/data'; -import { setSearchQuery } from './state/reducers'; +import React from 'react'; import { mockToolkitActionCreator } from 'test/core/redux/mocks'; -import { getRouteComponentProps } from 'app/core/navigation/__mocks__/routeProps'; + +import { NavModel } from '@grafana/data'; import { locationService } from '@grafana/runtime'; +import { getRouteComponentProps } from 'app/core/navigation/__mocks__/routeProps'; + +import appEvents from '../../core/app_events'; +import { AlertRule } from '../../types'; import { ShowModalReactEvent } from '../../types/events'; + import { AlertHowToModal } from './AlertHowToModal'; +import { AlertRuleListUnconnected, Props } from './AlertRuleList'; +import { setSearchQuery } from './state/reducers'; jest.mock('../../core/app_events', () => ({ publish: jest.fn(), diff --git a/public/app/features/alerting/AlertRuleList.tsx b/public/app/features/alerting/AlertRuleList.tsx index 2085c76b96d..72349521f84 100644 --- a/public/app/features/alerting/AlertRuleList.tsx +++ b/public/app/features/alerting/AlertRuleList.tsx @@ -1,20 +1,23 @@ import React, { PureComponent } from 'react'; import { connect, ConnectedProps } from 'react-redux'; -import Page from 'app/core/components/Page/Page'; -import AlertRuleItem from './AlertRuleItem'; -import appEvents from 'app/core/app_events'; -import { getNavModel } from 'app/core/selectors/navModel'; -import { AlertRule, StoreState } from 'app/types'; -import { getAlertRulesAsync, togglePauseAlertRule } from './state/actions'; -import { getAlertRuleItems, getSearchQuery } from './state/selectors'; + import { SelectableValue } from '@grafana/data'; import { config, locationService } from '@grafana/runtime'; -import { setSearchQuery } from './state/reducers'; import { Button, FilterInput, LinkButton, Select, VerticalGroup } from '@grafana/ui'; +import appEvents from 'app/core/app_events'; +import Page from 'app/core/components/Page/Page'; import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; +import { getNavModel } from 'app/core/selectors/navModel'; +import { AlertRule, StoreState } from 'app/types'; + import { ShowModalReactEvent } from '../../types/events'; + import { AlertHowToModal } from './AlertHowToModal'; +import AlertRuleItem from './AlertRuleItem'; import { UnifiedAlertingPromotion } from './components/UnifiedAlertingPromotion'; +import { getAlertRulesAsync, togglePauseAlertRule } from './state/actions'; +import { setSearchQuery } from './state/reducers'; +import { getAlertRuleItems, getSearchQuery } from './state/selectors'; function mapStateToProps(state: StoreState) { return { diff --git a/public/app/features/alerting/AlertTab.tsx b/public/app/features/alerting/AlertTab.tsx index 2c75d68fc49..0c2c8f1f408 100644 --- a/public/app/features/alerting/AlertTab.tsx +++ b/public/app/features/alerting/AlertTab.tsx @@ -1,19 +1,22 @@ import React, { PureComponent } from 'react'; import { connect, MapDispatchToProps, MapStateToProps } from 'react-redux'; -import { Alert, Button, ConfirmModal, Container, CustomScrollbar, HorizontalGroup, IconName, Modal } from '@grafana/ui'; + +import { EventBusSrv } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; import { AngularComponent, config, getAngularLoader, getDataSourceSrv } from '@grafana/runtime'; -import { getAlertingValidationMessage } from './getAlertingValidationMessage'; +import { Alert, Button, ConfirmModal, Container, CustomScrollbar, HorizontalGroup, IconName, Modal } from '@grafana/ui'; import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA'; -import StateHistory from './StateHistory'; +import { getPanelStateForModel } from 'app/features/panel/state/selectors'; +import { AppNotificationSeverity, StoreState } from 'app/types'; + +import { AlertState } from '../../plugins/datasource/alertmanager/types'; +import { PanelNotSupported } from '../dashboard/components/PanelEditor/PanelNotSupported'; import { DashboardModel } from '../dashboard/state/DashboardModel'; import { PanelModel } from '../dashboard/state/PanelModel'; + +import StateHistory from './StateHistory'; import { TestRuleResult } from './TestRuleResult'; -import { AppNotificationSeverity, StoreState } from 'app/types'; -import { PanelNotSupported } from '../dashboard/components/PanelEditor/PanelNotSupported'; -import { AlertState } from '../../plugins/datasource/alertmanager/types'; -import { EventBusSrv } from '@grafana/data'; -import { getPanelStateForModel } from 'app/features/panel/state/selectors'; +import { getAlertingValidationMessage } from './getAlertingValidationMessage'; interface AngularPanelController { _enableAlert: () => void; diff --git a/public/app/features/alerting/AlertTabCtrl.ts b/public/app/features/alerting/AlertTabCtrl.ts index 804490fe994..df717f79ee7 100644 --- a/public/app/features/alerting/AlertTabCtrl.ts +++ b/public/app/features/alerting/AlertTabCtrl.ts @@ -1,19 +1,22 @@ import { find, map, reduce, remove } from 'lodash'; -import coreModule from 'app/angular/core_module'; -import { ThresholdMapper } from './state/ThresholdMapper'; -import { QueryPart } from 'app/features/alerting/state/query_part'; -import alertDef from './state/alertDef'; -import config from 'app/core/config'; -import appEvents from 'app/core/app_events'; + +import { DataQuery, DataSourceApi, rangeUtil } from '@grafana/data'; import { getBackendSrv } from '@grafana/runtime'; +import coreModule from 'app/angular/core_module'; +import { promiseToDigest } from 'app/angular/promiseToDigest'; +import appEvents from 'app/core/app_events'; +import config from 'app/core/config'; +import { QueryPart } from 'app/features/alerting/state/query_part'; +import { PanelModel } from 'app/features/dashboard/state'; +import { CoreEvents } from 'app/types'; + +import { ShowConfirmModalEvent } from '../../types/events'; import { DashboardSrv } from '../dashboard/services/DashboardSrv'; import { DatasourceSrv } from '../plugins/datasource_srv'; -import { DataQuery, DataSourceApi, rangeUtil } from '@grafana/data'; -import { PanelModel } from 'app/features/dashboard/state'; + import { getDefaultCondition } from './getAlertingValidationMessage'; -import { CoreEvents } from 'app/types'; -import { promiseToDigest } from 'app/angular/promiseToDigest'; -import { ShowConfirmModalEvent } from '../../types/events'; +import { ThresholdMapper } from './state/ThresholdMapper'; +import alertDef from './state/alertDef'; export class AlertTabCtrl { panel: PanelModel; diff --git a/public/app/features/alerting/AlertTabIndex.tsx b/public/app/features/alerting/AlertTabIndex.tsx index e1e1ec95c7f..ec815490849 100644 --- a/public/app/features/alerting/AlertTabIndex.tsx +++ b/public/app/features/alerting/AlertTabIndex.tsx @@ -1,4 +1,5 @@ import { config } from '@grafana/runtime'; + import { AlertTab } from './AlertTab'; import { PanelAlertTabContent } from './unified/PanelAlertTabContent'; diff --git a/public/app/features/alerting/EditNotificationChannelPage.tsx b/public/app/features/alerting/EditNotificationChannelPage.tsx index dbbce7e46f0..45aba248222 100644 --- a/public/app/features/alerting/EditNotificationChannelPage.tsx +++ b/public/app/features/alerting/EditNotificationChannelPage.tsx @@ -1,17 +1,19 @@ import React, { PureComponent } from 'react'; import { MapDispatchToProps, MapStateToProps } from 'react-redux'; + import { NavModel } from '@grafana/data'; import { config } from '@grafana/runtime'; import { Form, Spinner } from '@grafana/ui'; import Page from 'app/core/components/Page/Page'; import { connectWithCleanUp } from 'app/core/components/connectWithCleanUp'; +import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; +import { getNavModel } from 'app/core/selectors/navModel'; +import { NotificationChannelType, NotificationChannelDTO, StoreState } from 'app/types'; + import { NotificationChannelForm } from './components/NotificationChannelForm'; import { loadNotificationChannel, testNotificationChannel, updateNotificationChannel } from './state/actions'; -import { getNavModel } from 'app/core/selectors/navModel'; -import { mapChannelsToSelectableValue, transformSubmitData, transformTestData } from './utils/notificationChannels'; -import { NotificationChannelType, NotificationChannelDTO, StoreState } from 'app/types'; import { resetSecureField } from './state/reducers'; -import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; +import { mapChannelsToSelectableValue, transformSubmitData, transformTestData } from './utils/notificationChannels'; interface OwnProps extends GrafanaRouteComponentProps<{ id: string }> {} diff --git a/public/app/features/alerting/FeatureTogglePage.tsx b/public/app/features/alerting/FeatureTogglePage.tsx index 57fb28b554a..63f62796f94 100644 --- a/public/app/features/alerting/FeatureTogglePage.tsx +++ b/public/app/features/alerting/FeatureTogglePage.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import Page from 'app/core/components/Page/Page'; import { useNavModel } from 'app/core/hooks/useNavModel'; diff --git a/public/app/features/alerting/NewNotificationChannelPage.tsx b/public/app/features/alerting/NewNotificationChannelPage.tsx index 247b5641bff..418029fb2e5 100644 --- a/public/app/features/alerting/NewNotificationChannelPage.tsx +++ b/public/app/features/alerting/NewNotificationChannelPage.tsx @@ -1,19 +1,22 @@ import React, { PureComponent } from 'react'; import { connect, ConnectedProps } from 'react-redux'; + import { config } from '@grafana/runtime'; import { Form } from '@grafana/ui'; import Page from 'app/core/components/Page/Page'; +import { getNavModel } from 'app/core/selectors/navModel'; + +import { NotificationChannelDTO, StoreState } from '../../types'; + import { NotificationChannelForm } from './components/NotificationChannelForm'; +import { createNotificationChannel, loadNotificationTypes, testNotificationChannel } from './state/actions'; +import { resetSecureField } from './state/reducers'; import { defaultValues, mapChannelsToSelectableValue, transformSubmitData, transformTestData, } from './utils/notificationChannels'; -import { getNavModel } from 'app/core/selectors/navModel'; -import { createNotificationChannel, loadNotificationTypes, testNotificationChannel } from './state/actions'; -import { NotificationChannelDTO, StoreState } from '../../types'; -import { resetSecureField } from './state/reducers'; class NewNotificationChannelPage extends PureComponent { componentDidMount() { diff --git a/public/app/features/alerting/NotificationsListPage.tsx b/public/app/features/alerting/NotificationsListPage.tsx index e391e11a875..9a5e5b3f4eb 100644 --- a/public/app/features/alerting/NotificationsListPage.tsx +++ b/public/app/features/alerting/NotificationsListPage.tsx @@ -1,12 +1,14 @@ import React, { useState, FC, useEffect } from 'react'; +import { useAsyncFn } from 'react-use'; + +import { getBackendSrv } from '@grafana/runtime'; +import { HorizontalGroup, Button, LinkButton } from '@grafana/ui'; import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA'; import Page from 'app/core/components/Page/Page'; -import { getBackendSrv } from '@grafana/runtime'; -import { useAsyncFn } from 'react-use'; import { appEvents } from 'app/core/core'; import { useNavModel } from 'app/core/hooks/useNavModel'; -import { HorizontalGroup, Button, LinkButton } from '@grafana/ui'; import { AlertNotification } from 'app/types/alerting'; + import { ShowConfirmModalEvent } from '../../types/events'; const NotificationsListPage: FC = () => { diff --git a/public/app/features/alerting/StateHistory.tsx b/public/app/features/alerting/StateHistory.tsx index c6fc1a2bed2..158cc30fad6 100644 --- a/public/app/features/alerting/StateHistory.tsx +++ b/public/app/features/alerting/StateHistory.tsx @@ -1,10 +1,12 @@ +import { css } from '@emotion/css'; import React, { PureComponent } from 'react'; + import { getBackendSrv } from '@grafana/runtime'; import { Icon, ConfirmButton, Button } from '@grafana/ui'; -import alertDef from './state/alertDef'; import { DashboardModel } from '../dashboard/state/DashboardModel'; -import { css } from '@emotion/css'; + +import alertDef from './state/alertDef'; interface Props { dashboard: DashboardModel; diff --git a/public/app/features/alerting/TestRuleResult.test.tsx b/public/app/features/alerting/TestRuleResult.test.tsx index 984ea78c36e..46ac94f248f 100644 --- a/public/app/features/alerting/TestRuleResult.test.tsx +++ b/public/app/features/alerting/TestRuleResult.test.tsx @@ -1,7 +1,9 @@ -import React from 'react'; -import { TestRuleResult, Props } from './TestRuleResult'; -import { DashboardModel, PanelModel } from '../dashboard/state'; import { shallow } from 'enzyme'; +import React from 'react'; + +import { DashboardModel, PanelModel } from '../dashboard/state'; + +import { TestRuleResult, Props } from './TestRuleResult'; jest.mock('@grafana/runtime', () => { const original = jest.requireActual('@grafana/runtime'); diff --git a/public/app/features/alerting/TestRuleResult.tsx b/public/app/features/alerting/TestRuleResult.tsx index 76669a9db90..bbed594e7d3 100644 --- a/public/app/features/alerting/TestRuleResult.tsx +++ b/public/app/features/alerting/TestRuleResult.tsx @@ -1,9 +1,11 @@ import React, { PureComponent } from 'react'; + +import { AppEvents } from '@grafana/data'; +import { getBackendSrv } from '@grafana/runtime'; import { LoadingPlaceholder, JSONFormatter, Icon, HorizontalGroup, ClipboardButton } from '@grafana/ui'; import appEvents from 'app/core/app_events'; + import { DashboardModel, PanelModel } from '../dashboard/state'; -import { getBackendSrv } from '@grafana/runtime'; -import { AppEvents } from '@grafana/data'; export interface Props { dashboard: DashboardModel; diff --git a/public/app/features/alerting/components/BasicSettings.tsx b/public/app/features/alerting/components/BasicSettings.tsx index 75ccb993c60..dc65562ba0f 100644 --- a/public/app/features/alerting/components/BasicSettings.tsx +++ b/public/app/features/alerting/components/BasicSettings.tsx @@ -1,10 +1,13 @@ import React, { FC } from 'react'; + import { SelectableValue } from '@grafana/data'; import { Field, Input, InputControl, Select } from '@grafana/ui'; -import { NotificationChannelOptions } from './NotificationChannelOptions'; -import { NotificationSettingsProps } from './NotificationChannelForm'; + import { NotificationChannelSecureFields, NotificationChannelType } from '../../../types'; +import { NotificationSettingsProps } from './NotificationChannelForm'; +import { NotificationChannelOptions } from './NotificationChannelOptions'; + interface Props extends NotificationSettingsProps { selectedChannel: NotificationChannelType; channels: Array>; diff --git a/public/app/features/alerting/components/ChannelSettings.tsx b/public/app/features/alerting/components/ChannelSettings.tsx index 9aa90aa87d8..292110d723d 100644 --- a/public/app/features/alerting/components/ChannelSettings.tsx +++ b/public/app/features/alerting/components/ChannelSettings.tsx @@ -1,9 +1,12 @@ import React, { FC } from 'react'; + import { Alert, CollapsableSection } from '@grafana/ui'; -import { NotificationChannelOptions } from './NotificationChannelOptions'; -import { NotificationSettingsProps } from './NotificationChannelForm'; + import { NotificationChannelSecureFields, NotificationChannelType } from '../../../types'; +import { NotificationSettingsProps } from './NotificationChannelForm'; +import { NotificationChannelOptions } from './NotificationChannelOptions'; + interface Props extends NotificationSettingsProps { selectedChannel: NotificationChannelType; secureFields: NotificationChannelSecureFields; diff --git a/public/app/features/alerting/components/NotificationChannelForm.tsx b/public/app/features/alerting/components/NotificationChannelForm.tsx index e05cf8e5bbd..ba471a9eee5 100644 --- a/public/app/features/alerting/components/NotificationChannelForm.tsx +++ b/public/app/features/alerting/components/NotificationChannelForm.tsx @@ -1,13 +1,15 @@ -import React, { FC, useEffect } from 'react'; import { css } from '@emotion/css'; +import React, { FC, useEffect } from 'react'; + import { GrafanaTheme, SelectableValue } from '@grafana/data'; import { Button, FormAPI, HorizontalGroup, stylesFactory, useTheme, Spinner } from '@grafana/ui'; +import config from 'app/core/config'; + import { NotificationChannelType, NotificationChannelDTO, NotificationChannelSecureFields } from '../../../types'; -import { NotificationSettings } from './NotificationSettings'; + import { BasicSettings } from './BasicSettings'; import { ChannelSettings } from './ChannelSettings'; - -import config from 'app/core/config'; +import { NotificationSettings } from './NotificationSettings'; interface Props extends Pick, 'control' | 'errors' | 'register' | 'watch' | 'getValues'> { diff --git a/public/app/features/alerting/components/NotificationChannelOptions.tsx b/public/app/features/alerting/components/NotificationChannelOptions.tsx index 9cdb59a61d5..2bd4cb7918b 100644 --- a/public/app/features/alerting/components/NotificationChannelOptions.tsx +++ b/public/app/features/alerting/components/NotificationChannelOptions.tsx @@ -1,9 +1,12 @@ import React, { FC } from 'react'; + import { SelectableValue } from '@grafana/data'; import { Button, Checkbox, Field, Input } from '@grafana/ui'; -import { OptionElement } from './OptionElement'; + import { NotificationChannelDTO, NotificationChannelOption, NotificationChannelSecureFields } from '../../../types'; + import { NotificationSettingsProps } from './NotificationChannelForm'; +import { OptionElement } from './OptionElement'; interface Props extends NotificationSettingsProps { selectedChannelOptions: NotificationChannelOption[]; diff --git a/public/app/features/alerting/components/NotificationSettings.tsx b/public/app/features/alerting/components/NotificationSettings.tsx index 9972becc5b8..2e9ea0629e4 100644 --- a/public/app/features/alerting/components/NotificationSettings.tsx +++ b/public/app/features/alerting/components/NotificationSettings.tsx @@ -1,5 +1,7 @@ import React, { FC } from 'react'; + import { Checkbox, CollapsableSection, Field, InfoBox, Input } from '@grafana/ui'; + import { NotificationSettingsProps } from './NotificationChannelForm'; interface Props extends NotificationSettingsProps { diff --git a/public/app/features/alerting/components/OptionElement.tsx b/public/app/features/alerting/components/OptionElement.tsx index 4c949202de5..aa0de6ad70d 100644 --- a/public/app/features/alerting/components/OptionElement.tsx +++ b/public/app/features/alerting/components/OptionElement.tsx @@ -1,5 +1,7 @@ import React, { FC } from 'react'; + import { FormAPI, Input, InputControl, Select, TextArea } from '@grafana/ui'; + import { NotificationChannelOption } from '../../../types'; interface Props extends Pick, 'register' | 'control'> { diff --git a/public/app/features/alerting/components/UnifiedAlertingPromotion.test.tsx b/public/app/features/alerting/components/UnifiedAlertingPromotion.test.tsx index 3fa5f2a330a..b6d03473696 100644 --- a/public/app/features/alerting/components/UnifiedAlertingPromotion.test.tsx +++ b/public/app/features/alerting/components/UnifiedAlertingPromotion.test.tsx @@ -1,7 +1,7 @@ -import React from 'react'; - import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import React from 'react'; + import { UnifiedAlertingPromotion, LOCAL_STORAGE_KEY } from './UnifiedAlertingPromotion'; describe('Unified Alerting promotion', () => { diff --git a/public/app/features/alerting/components/UnifiedAlertingPromotion.tsx b/public/app/features/alerting/components/UnifiedAlertingPromotion.tsx index d3a369494c9..2d89487dd42 100644 --- a/public/app/features/alerting/components/UnifiedAlertingPromotion.tsx +++ b/public/app/features/alerting/components/UnifiedAlertingPromotion.tsx @@ -1,7 +1,7 @@ import React, { FC } from 'react'; +import { useLocalStorage } from 'react-use'; import { Alert } from '@grafana/ui'; -import { useLocalStorage } from 'react-use'; export const LOCAL_STORAGE_KEY = 'grafana.legacyalerting.unifiedalertingpromo'; diff --git a/public/app/features/alerting/getAlertingValidationMessage.test.ts b/public/app/features/alerting/getAlertingValidationMessage.test.ts index 7b55785ca99..3b62e2ea13f 100644 --- a/public/app/features/alerting/getAlertingValidationMessage.test.ts +++ b/public/app/features/alerting/getAlertingValidationMessage.test.ts @@ -1,4 +1,3 @@ -import { DataSourceSrv } from '@grafana/runtime'; import { DataSourceApi, PluginMeta, @@ -6,8 +5,10 @@ import { DataSourceInstanceSettings, DataSourceRef, } from '@grafana/data'; +import { DataSourceSrv } from '@grafana/runtime'; import { ElasticsearchQuery } from '../../plugins/datasource/elasticsearch/types'; + import { getAlertingValidationMessage } from './getAlertingValidationMessage'; describe('getAlertingValidationMessage', () => { diff --git a/public/app/features/alerting/routes.tsx b/public/app/features/alerting/routes.tsx index d8eaa9cd338..333a5cbce42 100644 --- a/public/app/features/alerting/routes.tsx +++ b/public/app/features/alerting/routes.tsx @@ -1,11 +1,13 @@ +import { uniq } from 'lodash'; +import React from 'react'; +import { Redirect } from 'react-router-dom'; + import { OrgRole } from '@grafana/data'; import { SafeDynamicImport } from 'app/core/components/DynamicImports/SafeDynamicImport'; import { config } from 'app/core/config'; import { RouteDescriptor } from 'app/core/navigation/types'; import { AccessControlAction } from 'app/types'; -import { uniq } from 'lodash'; -import React from 'react'; -import { Redirect } from 'react-router-dom'; + import { evaluateAccess } from './unified/utils/access-control'; const commonRoutes: RouteDescriptor[] = [ diff --git a/public/app/features/alerting/state/actions.ts b/public/app/features/alerting/state/actions.ts index 56b7877fc80..11634d3620a 100644 --- a/public/app/features/alerting/state/actions.ts +++ b/public/app/features/alerting/state/actions.ts @@ -1,8 +1,9 @@ import { getBackendSrv, locationService } from '@grafana/runtime'; -import { loadAlertRules, loadedAlertRules, notificationChannelLoaded, setNotificationChannels } from './reducers'; -import { AlertRuleDTO, NotifierDTO, ThunkResult } from 'app/types'; -import { createErrorNotification, createSuccessNotification } from 'app/core/copy/appNotification'; import { notifyApp } from 'app/core/actions'; +import { createErrorNotification, createSuccessNotification } from 'app/core/copy/appNotification'; +import { AlertRuleDTO, NotifierDTO, ThunkResult } from 'app/types'; + +import { loadAlertRules, loadedAlertRules, notificationChannelLoaded, setNotificationChannels } from './reducers'; export function getAlertRulesAsync(options: { state: string }): ThunkResult { return async (dispatch) => { diff --git a/public/app/features/alerting/state/alertDef.ts b/public/app/features/alerting/state/alertDef.ts index 4851974b39e..de4f61cf7a6 100644 --- a/public/app/features/alerting/state/alertDef.ts +++ b/public/app/features/alerting/state/alertDef.ts @@ -1,4 +1,5 @@ import { isArray, reduce } from 'lodash'; + import { QueryPartDef, QueryPart } from 'app/features/alerting/state/query_part'; const alertQueryDef = new QueryPartDef({ diff --git a/public/app/features/alerting/state/reducers.test.ts b/public/app/features/alerting/state/reducers.test.ts index 5fe86af7b9c..a0e2f8d174f 100644 --- a/public/app/features/alerting/state/reducers.test.ts +++ b/public/app/features/alerting/state/reducers.test.ts @@ -1,4 +1,8 @@ import { dateTime } from '@grafana/data'; +import { AlertRuleDTO, AlertRulesState, NotificationChannelState, NotifierDTO } from 'app/types'; + +import { reducerTester } from '../../../../test/core/redux/reducerTester'; + import { alertRulesReducer, initialChannelState, @@ -9,8 +13,6 @@ import { setSearchQuery, notificationChannelLoaded, } from './reducers'; -import { AlertRuleDTO, AlertRulesState, NotificationChannelState, NotifierDTO } from 'app/types'; -import { reducerTester } from '../../../../test/core/redux/reducerTester'; describe('Alert rules', () => { const realDateNow = Date.now.bind(global.Date); diff --git a/public/app/features/alerting/state/reducers.ts b/public/app/features/alerting/state/reducers.ts index cee611ab40e..1cbe4d91541 100644 --- a/public/app/features/alerting/state/reducers.ts +++ b/public/app/features/alerting/state/reducers.ts @@ -1,6 +1,6 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit'; + import { dateTime } from '@grafana/data'; -import alertDef from './alertDef'; import { AlertRule, AlertRuleDTO, @@ -9,8 +9,11 @@ import { NotificationChannelState, NotifierDTO, } from 'app/types'; + import unifiedAlertingReducer from '../unified/state/reducers'; +import alertDef from './alertDef'; + export const initialState: AlertRulesState = { items: [], searchQuery: '', diff --git a/public/app/features/alerting/unified/Admin.tsx b/public/app/features/alerting/unified/Admin.tsx index 21a534cdca6..28a2a518763 100644 --- a/public/app/features/alerting/unified/Admin.tsx +++ b/public/app/features/alerting/unified/Admin.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { AlertingPageWrapper } from './components/AlertingPageWrapper'; import AlertmanagerConfig from './components/admin/AlertmanagerConfig'; import { ExternalAlertmanagers } from './components/admin/ExternalAlertmanagers'; diff --git a/public/app/features/alerting/unified/AlertGroups.test.tsx b/public/app/features/alerting/unified/AlertGroups.test.tsx index 40fecd2d7bf..0c46f97e58d 100644 --- a/public/app/features/alerting/unified/AlertGroups.test.tsx +++ b/public/app/features/alerting/unified/AlertGroups.test.tsx @@ -1,15 +1,17 @@ -import React from 'react'; -import { locationService, setDataSourceSrv } from '@grafana/runtime'; import { render, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import React from 'react'; import { Provider } from 'react-redux'; import { Router } from 'react-router-dom'; -import { fetchAlertGroups } from './api/alertmanager'; import { byRole, byTestId, byText } from 'testing-library-selector'; + +import { locationService, setDataSourceSrv } from '@grafana/runtime'; import { configureStore } from 'app/store/configureStore'; + import AlertGroups from './AlertGroups'; +import { fetchAlertGroups } from './api/alertmanager'; import { mockAlertGroup, mockAlertmanagerAlert, mockDataSource, MockDataSourceSrv } from './mocks'; import { DataSourceType } from './utils/datasource'; -import userEvent from '@testing-library/user-event'; jest.mock('./api/alertmanager'); jest.mock('app/core/services/context_srv', () => ({ diff --git a/public/app/features/alerting/unified/AlertGroups.tsx b/public/app/features/alerting/unified/AlertGroups.tsx index b009207fd28..2513f9788eb 100644 --- a/public/app/features/alerting/unified/AlertGroups.tsx +++ b/public/app/features/alerting/unified/AlertGroups.tsx @@ -1,23 +1,22 @@ +import { css } from '@emotion/css'; import React, { useEffect } from 'react'; import { useDispatch } from 'react-redux'; -import { Alert, LoadingPlaceholder, useStyles2 } from '@grafana/ui'; + import { GrafanaTheme2 } from '@grafana/data'; +import { Alert, LoadingPlaceholder, useStyles2 } from '@grafana/ui'; import { useQueryParams } from 'app/core/hooks/useQueryParams'; import { AlertingPageWrapper } from './components/AlertingPageWrapper'; import { AlertGroup } from './components/alert-groups/AlertGroup'; import { AlertGroupFilter } from './components/alert-groups/AlertGroupFilter'; -import { fetchAlertGroupsAction } from './state/actions'; - -import { initialAsyncRequestState } from './utils/redux'; -import { getFiltersFromUrlParams } from './utils/misc'; -import { NOTIFICATIONS_POLL_INTERVAL_MS } from './utils/constants'; - import { useAlertManagerSourceName } from './hooks/useAlertManagerSourceName'; -import { useUnifiedAlertingSelector } from './hooks/useUnifiedAlertingSelector'; -import { useGroupedAlerts } from './hooks/useGroupedAlerts'; import { useFilteredAmGroups } from './hooks/useFilteredAmGroups'; -import { css } from '@emotion/css'; +import { useGroupedAlerts } from './hooks/useGroupedAlerts'; +import { useUnifiedAlertingSelector } from './hooks/useUnifiedAlertingSelector'; +import { fetchAlertGroupsAction } from './state/actions'; +import { NOTIFICATIONS_POLL_INTERVAL_MS } from './utils/constants'; +import { getFiltersFromUrlParams } from './utils/misc'; +import { initialAsyncRequestState } from './utils/redux'; const AlertGroups = () => { const [alertManagerSourceName] = useAlertManagerSourceName(); diff --git a/public/app/features/alerting/unified/AlertsFolderView.test.tsx b/public/app/features/alerting/unified/AlertsFolderView.test.tsx index 39793a96677..bb28d3984ec 100644 --- a/public/app/features/alerting/unified/AlertsFolderView.test.tsx +++ b/public/app/features/alerting/unified/AlertsFolderView.test.tsx @@ -1,12 +1,14 @@ import { render } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { configureStore } from 'app/store/configureStore'; -import { FolderState } from 'app/types'; -import { CombinedRuleNamespace } from 'app/types/unified-alerting'; import React from 'react'; import { Provider } from 'react-redux'; import { MemoryRouter } from 'react-router-dom'; import { byTestId } from 'testing-library-selector'; + +import { configureStore } from 'app/store/configureStore'; +import { FolderState } from 'app/types'; +import { CombinedRuleNamespace } from 'app/types/unified-alerting'; + import { AlertsFolderView } from './AlertsFolderView'; import { mockCombinedRule } from './mocks'; import { GRAFANA_RULES_SOURCE_NAME } from './utils/datasource'; diff --git a/public/app/features/alerting/unified/AlertsFolderView.tsx b/public/app/features/alerting/unified/AlertsFolderView.tsx index 1109dc3c9c6..77124c6a01b 100644 --- a/public/app/features/alerting/unified/AlertsFolderView.tsx +++ b/public/app/features/alerting/unified/AlertsFolderView.tsx @@ -1,4 +1,9 @@ import { css } from '@emotion/css'; +import { isEqual, orderBy, uniqWith } from 'lodash'; +import React, { useEffect, useState } from 'react'; +import { useDispatch } from 'react-redux'; +import { useDebounce } from 'react-use'; + import { GrafanaTheme2, SelectableValue } from '@grafana/data'; import { Stack } from '@grafana/experimental'; import { Card, FilterInput, Icon, Pagination, Select, TagList, useStyles2 } from '@grafana/ui'; @@ -6,10 +11,7 @@ import { DEFAULT_PER_PAGE_PAGINATION } from 'app/core/constants'; import { getQueryParamValue } from 'app/core/utils/query'; import { FolderState } from 'app/types'; import { CombinedRule } from 'app/types/unified-alerting'; -import { isEqual, orderBy, uniqWith } from 'lodash'; -import React, { useEffect, useState } from 'react'; -import { useDispatch } from 'react-redux'; -import { useDebounce } from 'react-use'; + import { useCombinedRuleNamespaces } from './hooks/useCombinedRuleNamespaces'; import { usePagination } from './hooks/usePagination'; import { useURLSearchParams } from './hooks/useURLSearchParams'; diff --git a/public/app/features/alerting/unified/AmRoutes.test.tsx b/public/app/features/alerting/unified/AmRoutes.test.tsx index 414f90b6cf4..1157269c68d 100644 --- a/public/app/features/alerting/unified/AmRoutes.test.tsx +++ b/public/app/features/alerting/unified/AmRoutes.test.tsx @@ -1,8 +1,13 @@ -import React from 'react'; -import { locationService, setDataSourceSrv } from '@grafana/runtime'; import { render, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import React from 'react'; import { Provider } from 'react-redux'; import { Router } from 'react-router-dom'; +import { byLabelText, byRole, byTestId, byText } from 'testing-library-selector'; + +import { locationService, setDataSourceSrv } from '@grafana/runtime'; +import { selectOptionInTest } from '@grafana/ui'; +import { contextSrv } from 'app/core/services/context_srv'; import { AlertManagerCortexConfig, AlertManagerDataSourceJsonData, @@ -11,17 +16,14 @@ import { Route, } from 'app/plugins/datasource/alertmanager/types'; import { configureStore } from 'app/store/configureStore'; -import { byLabelText, byRole, byTestId, byText } from 'testing-library-selector'; +import { AccessControlAction } from 'app/types'; + import AmRoutes from './AmRoutes'; import { fetchAlertManagerConfig, fetchStatus, updateAlertManagerConfig } from './api/alertmanager'; import { mockDataSource, MockDataSourceSrv, someCloudAlertManagerConfig, someCloudAlertManagerStatus } from './mocks'; import { getAllDataSources } from './utils/config'; -import { DataSourceType, GRAFANA_RULES_SOURCE_NAME } from './utils/datasource'; -import userEvent from '@testing-library/user-event'; -import { selectOptionInTest } from '@grafana/ui'; import { ALERTMANAGER_NAME_QUERY_KEY } from './utils/constants'; -import { contextSrv } from 'app/core/services/context_srv'; -import { AccessControlAction } from 'app/types'; +import { DataSourceType, GRAFANA_RULES_SOURCE_NAME } from './utils/datasource'; jest.mock('./api/alertmanager'); jest.mock('./utils/config'); diff --git a/public/app/features/alerting/unified/AmRoutes.tsx b/public/app/features/alerting/unified/AmRoutes.tsx index 8bcdaa7e184..489de5941dc 100644 --- a/public/app/features/alerting/unified/AmRoutes.tsx +++ b/public/app/features/alerting/unified/AmRoutes.tsx @@ -1,23 +1,26 @@ -import React, { FC, useCallback, useEffect, useMemo, useState } from 'react'; import { css } from '@emotion/css'; -import { GrafanaTheme2 } from '@grafana/data'; -import { Alert, LoadingPlaceholder, useStyles2, withErrorBoundary } from '@grafana/ui'; +import React, { FC, useCallback, useEffect, useMemo, useState } from 'react'; import { useDispatch } from 'react-redux'; import { Redirect } from 'react-router-dom'; + +import { GrafanaTheme2 } from '@grafana/data'; +import { Alert, LoadingPlaceholder, useStyles2, withErrorBoundary } from '@grafana/ui'; import { Receiver } from 'app/plugins/datasource/alertmanager/types'; + import { useCleanup } from '../../../core/hooks/useCleanup'; -import { AlertingPageWrapper } from './components/AlertingPageWrapper'; + import { AlertManagerPicker } from './components/AlertManagerPicker'; +import { AlertingPageWrapper } from './components/AlertingPageWrapper'; import { AmRootRoute } from './components/amroutes/AmRootRoute'; import { AmSpecificRouting } from './components/amroutes/AmSpecificRouting'; +import { MuteTimingsTable } from './components/amroutes/MuteTimingsTable'; import { useAlertManagerSourceName } from './hooks/useAlertManagerSourceName'; import { useUnifiedAlertingSelector } from './hooks/useUnifiedAlertingSelector'; import { fetchAlertManagerConfigAction, updateAlertManagerConfigAction } from './state/actions'; import { AmRouteReceiver, FormAmRoute } from './types/amroutes'; import { amRouteToFormAmRoute, formAmRouteToAmRoute, stringsToSelectableValues } from './utils/amroutes'; -import { initialAsyncRequestState } from './utils/redux'; import { isVanillaPrometheusAlertManagerDataSource } from './utils/datasource'; -import { MuteTimingsTable } from './components/amroutes/MuteTimingsTable'; +import { initialAsyncRequestState } from './utils/redux'; const AmRoutes: FC = () => { const dispatch = useDispatch(); diff --git a/public/app/features/alerting/unified/MuteTimings.test.tsx b/public/app/features/alerting/unified/MuteTimings.test.tsx index 0a8c494d2c4..7c7895ab757 100644 --- a/public/app/features/alerting/unified/MuteTimings.test.tsx +++ b/public/app/features/alerting/unified/MuteTimings.test.tsx @@ -1,18 +1,18 @@ -import React from 'react'; import { render, waitFor, fireEvent } from '@testing-library/react'; -import { locationService, setDataSourceSrv } from '@grafana/runtime'; - +import userEvent from '@testing-library/user-event'; +import React from 'react'; import { Provider } from 'react-redux'; import { Router } from 'react-router-dom'; -import { fetchAlertManagerConfig, updateAlertManagerConfig } from './api/alertmanager'; +import { byRole, byTestId, byText } from 'testing-library-selector'; + +import { locationService, setDataSourceSrv } from '@grafana/runtime'; +import { AlertManagerCortexConfig, MuteTimeInterval } from 'app/plugins/datasource/alertmanager/types'; import { configureStore } from 'app/store/configureStore'; +import MuteTimings from './MuteTimings'; +import { fetchAlertManagerConfig, updateAlertManagerConfig } from './api/alertmanager'; import { mockDataSource, MockDataSourceSrv } from './mocks'; import { DataSourceType } from './utils/datasource'; -import { AlertManagerCortexConfig, MuteTimeInterval } from 'app/plugins/datasource/alertmanager/types'; -import { byRole, byTestId, byText } from 'testing-library-selector'; -import userEvent from '@testing-library/user-event'; -import MuteTimings from './MuteTimings'; jest.mock('./api/alertmanager'); diff --git a/public/app/features/alerting/unified/MuteTimings.tsx b/public/app/features/alerting/unified/MuteTimings.tsx index 0087a3900d6..97221db287e 100644 --- a/public/app/features/alerting/unified/MuteTimings.tsx +++ b/public/app/features/alerting/unified/MuteTimings.tsx @@ -1,14 +1,16 @@ import React, { useCallback, useEffect } from 'react'; +import { useDispatch } from 'react-redux'; import { Route, Redirect, Switch } from 'react-router-dom'; + +import { Alert, LoadingPlaceholder } from '@grafana/ui'; +import { useQueryParams } from 'app/core/hooks/useQueryParams'; +import { MuteTimeInterval } from 'app/plugins/datasource/alertmanager/types'; + import MuteTimingForm from './components/amroutes/MuteTimingForm'; import { useAlertManagerSourceName } from './hooks/useAlertManagerSourceName'; -import { useDispatch } from 'react-redux'; import { useUnifiedAlertingSelector } from './hooks/useUnifiedAlertingSelector'; import { fetchAlertManagerConfigAction } from './state/actions'; import { initialAsyncRequestState } from './utils/redux'; -import { MuteTimeInterval } from 'app/plugins/datasource/alertmanager/types'; -import { Alert, LoadingPlaceholder } from '@grafana/ui'; -import { useQueryParams } from 'app/core/hooks/useQueryParams'; const MuteTimings = () => { const [queryParams] = useQueryParams(); diff --git a/public/app/features/alerting/unified/PanelAlertTab.tsx b/public/app/features/alerting/unified/PanelAlertTab.tsx index cb45af4cd13..cbdf52eec11 100644 --- a/public/app/features/alerting/unified/PanelAlertTab.tsx +++ b/public/app/features/alerting/unified/PanelAlertTab.tsx @@ -1,6 +1,8 @@ +import React, { FC } from 'react'; + import { Tab, TabProps } from '@grafana/ui/src/components/Tabs/Tab'; import { DashboardModel, PanelModel } from 'app/features/dashboard/state'; -import React, { FC } from 'react'; + import { usePanelCombinedRules } from './hooks/usePanelCombinedRules'; interface Props extends Omit { diff --git a/public/app/features/alerting/unified/PanelAlertTabContent.test.tsx b/public/app/features/alerting/unified/PanelAlertTabContent.test.tsx index 659d9076f79..ce77abe5a0c 100644 --- a/public/app/features/alerting/unified/PanelAlertTabContent.test.tsx +++ b/public/app/features/alerting/unified/PanelAlertTabContent.test.tsx @@ -1,11 +1,21 @@ +import { render, act } from '@testing-library/react'; import React from 'react'; -import { locationService, setDataSourceSrv } from '@grafana/runtime'; -import { configureStore } from 'app/store/configureStore'; import { Provider } from 'react-redux'; import { Router } from 'react-router-dom'; -import { render, act } from '@testing-library/react'; -import { PanelAlertTabContent } from './PanelAlertTabContent'; +import { byTestId } from 'testing-library-selector'; + +import { DataSourceApi } from '@grafana/data'; +import { locationService, setDataSourceSrv } from '@grafana/runtime'; +import { ExpressionDatasourceRef } from '@grafana/runtime/src/utils/DataSourceWithBackend'; import { DashboardModel, PanelModel } from 'app/features/dashboard/state'; +import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; +import { PrometheusDatasource } from 'app/plugins/datasource/prometheus/datasource'; +import { PromOptions } from 'app/plugins/datasource/prometheus/types'; +import { configureStore } from 'app/store/configureStore'; + +import { PanelAlertTabContent } from './PanelAlertTabContent'; +import { fetchRules } from './api/prometheus'; +import { fetchRulerRules } from './api/ruler'; import { mockDataSource, MockDataSourceSrv, @@ -14,17 +24,9 @@ import { mockPromRuleNamespace, mockRulerGrafanaRule, } from './mocks'; -import { DataSourceType, GRAFANA_RULES_SOURCE_NAME } from './utils/datasource'; import { getAllDataSources } from './utils/config'; -import { fetchRules } from './api/prometheus'; -import { fetchRulerRules } from './api/ruler'; import { Annotation } from './utils/constants'; -import { byTestId } from 'testing-library-selector'; -import { PrometheusDatasource } from 'app/plugins/datasource/prometheus/datasource'; -import { DataSourceApi } from '@grafana/data'; -import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; -import { PromOptions } from 'app/plugins/datasource/prometheus/types'; -import { ExpressionDatasourceRef } from '@grafana/runtime/src/utils/DataSourceWithBackend'; +import { DataSourceType, GRAFANA_RULES_SOURCE_NAME } from './utils/datasource'; jest.mock('./api/prometheus'); jest.mock('./api/ruler'); diff --git a/public/app/features/alerting/unified/PanelAlertTabContent.tsx b/public/app/features/alerting/unified/PanelAlertTabContent.tsx index 6832a62b200..a8b99dbc0de 100644 --- a/public/app/features/alerting/unified/PanelAlertTabContent.tsx +++ b/public/app/features/alerting/unified/PanelAlertTabContent.tsx @@ -1,14 +1,16 @@ import { css } from '@emotion/css'; -import { GrafanaTheme2 } from '@grafana/data'; -import { Alert, CustomScrollbar, LoadingPlaceholder, useStyles2 } from '@grafana/ui'; -import { DashboardModel, PanelModel } from 'app/features/dashboard/state'; import React, { FC } from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; +import { Alert, CustomScrollbar, LoadingPlaceholder, useStyles2 } from '@grafana/ui'; +import { contextSrv } from 'app/core/services/context_srv'; +import { DashboardModel, PanelModel } from 'app/features/dashboard/state'; + import { NewRuleFromPanelButton } from './components/panel-alerts-tab/NewRuleFromPanelButton'; import { RulesTable } from './components/rules/RulesTable'; import { usePanelCombinedRules } from './hooks/usePanelCombinedRules'; -import { selectors } from '@grafana/e2e-selectors'; import { getRulesPermissions } from './utils/access-control'; -import { contextSrv } from 'app/core/services/context_srv'; interface Props { dashboard: DashboardModel; diff --git a/public/app/features/alerting/unified/Receivers.test.tsx b/public/app/features/alerting/unified/Receivers.test.tsx index 0f5c6af28bf..fc85f31a484 100644 --- a/public/app/features/alerting/unified/Receivers.test.tsx +++ b/public/app/features/alerting/unified/Receivers.test.tsx @@ -1,12 +1,22 @@ -import { configureStore } from 'app/store/configureStore'; +import { render, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import React from 'react'; import { Provider } from 'react-redux'; import { Router } from 'react-router-dom'; -import Receivers from './Receivers'; -import React from 'react'; +import { byLabelText, byPlaceholderText, byRole, byTestId, byText } from 'testing-library-selector'; + import { locationService, setDataSourceSrv } from '@grafana/runtime'; -import { render, waitFor } from '@testing-library/react'; -import { getAllDataSources } from './utils/config'; +import { selectOptionInTest } from '@grafana/ui'; +import { interceptLinkClicks } from 'app/core/navigation/patch/interceptLinkClicks'; +import { contextSrv } from 'app/core/services/context_srv'; +import store from 'app/core/store'; +import { AlertManagerDataSourceJsonData, AlertManagerImplementation } from 'app/plugins/datasource/alertmanager/types'; +import { configureStore } from 'app/store/configureStore'; +import { AccessControlAction } from 'app/types'; + +import Receivers from './Receivers'; import { updateAlertManagerConfig, fetchAlertManagerConfig, fetchStatus, testReceivers } from './api/alertmanager'; +import { fetchNotifiers } from './api/grafana'; import { mockDataSource, MockDataSourceSrv, @@ -14,18 +24,10 @@ import { someCloudAlertManagerStatus, someGrafanaAlertManagerConfig, } from './mocks'; -import { DataSourceType, GRAFANA_RULES_SOURCE_NAME } from './utils/datasource'; -import { fetchNotifiers } from './api/grafana'; import { grafanaNotifiersMock } from './mocks/grafana-notifiers'; -import { byLabelText, byPlaceholderText, byRole, byTestId, byText } from 'testing-library-selector'; -import userEvent from '@testing-library/user-event'; +import { getAllDataSources } from './utils/config'; import { ALERTMANAGER_NAME_LOCAL_STORAGE_KEY, ALERTMANAGER_NAME_QUERY_KEY } from './utils/constants'; -import store from 'app/core/store'; -import { contextSrv } from 'app/core/services/context_srv'; -import { selectOptionInTest } from '@grafana/ui'; -import { AlertManagerDataSourceJsonData, AlertManagerImplementation } from 'app/plugins/datasource/alertmanager/types'; -import { interceptLinkClicks } from 'app/core/navigation/patch/interceptLinkClicks'; -import { AccessControlAction } from 'app/types'; +import { DataSourceType, GRAFANA_RULES_SOURCE_NAME } from './utils/datasource'; jest.mock('./api/alertmanager'); jest.mock('./api/grafana'); diff --git a/public/app/features/alerting/unified/Receivers.tsx b/public/app/features/alerting/unified/Receivers.tsx index cf503117041..3335aa988ee 100644 --- a/public/app/features/alerting/unified/Receivers.tsx +++ b/public/app/features/alerting/unified/Receivers.tsx @@ -1,9 +1,11 @@ -import { Alert, LoadingPlaceholder, withErrorBoundary } from '@grafana/ui'; import React, { FC, useEffect } from 'react'; import { useDispatch } from 'react-redux'; import { Redirect, Route, RouteChildrenProps, Switch, useLocation } from 'react-router-dom'; -import { AlertingPageWrapper } from './components/AlertingPageWrapper'; + +import { Alert, LoadingPlaceholder, withErrorBoundary } from '@grafana/ui'; + import { AlertManagerPicker } from './components/AlertManagerPicker'; +import { AlertingPageWrapper } from './components/AlertingPageWrapper'; import { EditReceiverView } from './components/receivers/EditReceiverView'; import { EditTemplateView } from './components/receivers/EditTemplateView'; import { GlobalConfigForm } from './components/receivers/GlobalConfigForm'; diff --git a/public/app/features/alerting/unified/RedirectToRuleViewer.test.tsx b/public/app/features/alerting/unified/RedirectToRuleViewer.test.tsx index cbd358bd935..dc6298d1dc2 100644 --- a/public/app/features/alerting/unified/RedirectToRuleViewer.test.tsx +++ b/public/app/features/alerting/unified/RedirectToRuleViewer.test.tsx @@ -1,14 +1,17 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; +import React from 'react'; import { Provider } from 'react-redux'; import { Router } from 'react-router-dom'; + import { DataSourceJsonData, PluginMeta } from '@grafana/data'; import { locationService } from '@grafana/runtime'; -import { RedirectToRuleViewer } from './RedirectToRuleViewer'; import { configureStore } from 'app/store/configureStore'; -import { useCombinedRulesMatching } from './hooks/useCombinedRule'; + import { CombinedRule, Rule } from '../../../types/unified-alerting'; import { PromRuleType } from '../../../types/unified-alerting-dto'; + +import { RedirectToRuleViewer } from './RedirectToRuleViewer'; +import { useCombinedRulesMatching } from './hooks/useCombinedRule'; import { getRulesSourceByName } from './utils/datasource'; jest.mock('./hooks/useCombinedRule'); diff --git a/public/app/features/alerting/unified/RedirectToRuleViewer.tsx b/public/app/features/alerting/unified/RedirectToRuleViewer.tsx index 51c6f21275e..c2290067538 100644 --- a/public/app/features/alerting/unified/RedirectToRuleViewer.tsx +++ b/public/app/features/alerting/unified/RedirectToRuleViewer.tsx @@ -1,14 +1,16 @@ +import { css } from '@emotion/css'; import React from 'react'; import { Redirect } from 'react-router-dom'; -import { css } from '@emotion/css'; + import { GrafanaTheme2 } from '@grafana/data'; import { Alert, Card, Icon, LoadingPlaceholder, useStyles2, withErrorBoundary } from '@grafana/ui'; import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; -import { useCombinedRulesMatching } from './hooks/useCombinedRule'; -import { createViewLink } from './utils/misc'; -import { getRulesSourceByName } from './utils/datasource'; -import { RuleViewerLayout } from './components/rule-viewer/RuleViewerLayout'; + import { AlertLabels } from './components/AlertLabels'; +import { RuleViewerLayout } from './components/rule-viewer/RuleViewerLayout'; +import { useCombinedRulesMatching } from './hooks/useCombinedRule'; +import { getRulesSourceByName } from './utils/datasource'; +import { createViewLink } from './utils/misc'; type RedirectToRuleViewerProps = GrafanaRouteComponentProps<{ name?: string; sourceName?: string }>; const pageTitle = 'Alerting / Find rule'; diff --git a/public/app/features/alerting/unified/RuleEditor.test.tsx b/public/app/features/alerting/unified/RuleEditor.test.tsx index dc1fa82d5ef..b3908041160 100644 --- a/public/app/features/alerting/unified/RuleEditor.test.tsx +++ b/public/app/features/alerting/unified/RuleEditor.test.tsx @@ -1,25 +1,28 @@ import { Matcher, render, waitFor, screen } from '@testing-library/react'; -import { Provider } from 'react-redux'; -import { BackendSrv, locationService, setBackendSrv, setDataSourceSrv } from '@grafana/runtime'; -import { configureStore } from 'app/store/configureStore'; -import RuleEditor from './RuleEditor'; -import { Route, Router } from 'react-router-dom'; +import userEvent, { PointerEventsCheckLevel } from '@testing-library/user-event'; import React from 'react'; +import { Provider } from 'react-redux'; +import { Route, Router } from 'react-router-dom'; import { byLabelText, byRole, byTestId, byText } from 'testing-library-selector'; + +import { DataSourceInstanceSettings } from '@grafana/data'; +import { BackendSrv, locationService, setBackendSrv, setDataSourceSrv } from '@grafana/runtime'; import { selectOptionInTest } from '@grafana/ui'; import { contextSrv } from 'app/core/services/context_srv'; -import { mockDataSource, MockDataSourceSrv } from './mocks'; -import userEvent, { PointerEventsCheckLevel } from '@testing-library/user-event'; -import { DataSourceInstanceSettings } from '@grafana/data'; -import { getAllDataSources } from './utils/config'; -import { fetchRulerRules, fetchRulerRulesGroup, fetchRulerRulesNamespace, setRulerRuleGroup } from './api/ruler'; -import { DataSourceType, GRAFANA_RULES_SOURCE_NAME } from './utils/datasource'; import { DashboardSearchHit } from 'app/features/search/types'; -import { getDefaultQueries } from './utils/rule-form'; -import { ExpressionEditorProps } from './components/rule-editor/ExpressionEditor'; -import { searchFolders } from '../../../../app/features/manage-dashboards/state/actions'; +import { configureStore } from 'app/store/configureStore'; import { GrafanaAlertStateDecision, PromApplication } from 'app/types/unified-alerting-dto'; + +import { searchFolders } from '../../../../app/features/manage-dashboards/state/actions'; + +import RuleEditor from './RuleEditor'; import { fetchBuildInfo } from './api/buildInfo'; +import { fetchRulerRules, fetchRulerRulesGroup, fetchRulerRulesNamespace, setRulerRuleGroup } from './api/ruler'; +import { ExpressionEditorProps } from './components/rule-editor/ExpressionEditor'; +import { mockDataSource, MockDataSourceSrv } from './mocks'; +import { getAllDataSources } from './utils/config'; +import { DataSourceType, GRAFANA_RULES_SOURCE_NAME } from './utils/datasource'; +import { getDefaultQueries } from './utils/rule-form'; jest.mock('./components/rule-editor/ExpressionEditor', () => ({ // eslint-disable-next-line react/display-name diff --git a/public/app/features/alerting/unified/RuleEditor.tsx b/public/app/features/alerting/unified/RuleEditor.tsx index 8fbd3315bc3..3b29811a926 100644 --- a/public/app/features/alerting/unified/RuleEditor.tsx +++ b/public/app/features/alerting/unified/RuleEditor.tsx @@ -1,13 +1,15 @@ import { css } from '@emotion/css'; +import React, { FC, useEffect } from 'react'; +import { useDispatch } from 'react-redux'; +import { useAsync } from 'react-use'; + import { GrafanaTheme2 } from '@grafana/data'; import { Alert, LinkButton, LoadingPlaceholder, useStyles2, withErrorBoundary } from '@grafana/ui'; import Page from 'app/core/components/Page/Page'; import { useCleanup } from 'app/core/hooks/useCleanup'; import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; import { RuleIdentifier } from 'app/types/unified-alerting'; -import React, { FC, useEffect } from 'react'; -import { useDispatch } from 'react-redux'; -import { useAsync } from 'react-use'; + import { AlertRuleForm } from './components/rule-editor/AlertRuleForm'; import { useIsRuleEditable } from './hooks/useIsRuleEditable'; import { useUnifiedAlertingSelector } from './hooks/useUnifiedAlertingSelector'; diff --git a/public/app/features/alerting/unified/RuleList.test.tsx b/public/app/features/alerting/unified/RuleList.test.tsx index 3a198bc403c..2b3bcb17330 100644 --- a/public/app/features/alerting/unified/RuleList.test.tsx +++ b/public/app/features/alerting/unified/RuleList.test.tsx @@ -1,12 +1,18 @@ -import React from 'react'; +import { SerializedError } from '@reduxjs/toolkit'; import { render, waitFor } from '@testing-library/react'; -import { configureStore } from 'app/store/configureStore'; +import userEvent from '@testing-library/user-event'; +import React from 'react'; import { Provider } from 'react-redux'; -import RuleList from './RuleList'; +import { Router } from 'react-router-dom'; import { byLabelText, byRole, byTestId, byText } from 'testing-library-selector'; -import { getAllDataSources } from './utils/config'; -import { fetchRules } from './api/prometheus'; + +import { locationService, setDataSourceSrv } from '@grafana/runtime'; +import { configureStore } from 'app/store/configureStore'; +import { PromAlertingRuleState, PromApplication } from 'app/types/unified-alerting-dto'; + +import RuleList from './RuleList'; import { fetchBuildInfo } from './api/buildInfo'; +import { fetchRules } from './api/prometheus'; import { fetchRulerRules, deleteRulerRulesGroup, deleteNamespace, setRulerRuleGroup } from './api/ruler'; import { mockDataSource, @@ -19,12 +25,8 @@ import { somePromRules, someRulerRules, } from './mocks'; +import { getAllDataSources } from './utils/config'; import { DataSourceType, GRAFANA_RULES_SOURCE_NAME } from './utils/datasource'; -import { SerializedError } from '@reduxjs/toolkit'; -import { PromAlertingRuleState, PromApplication } from 'app/types/unified-alerting-dto'; -import userEvent from '@testing-library/user-event'; -import { locationService, setDataSourceSrv } from '@grafana/runtime'; -import { Router } from 'react-router-dom'; jest.mock('./api/buildInfo'); jest.mock('./api/prometheus'); diff --git a/public/app/features/alerting/unified/RuleList.tsx b/public/app/features/alerting/unified/RuleList.tsx index 3ca8b91ca73..cb299fdfc3e 100644 --- a/public/app/features/alerting/unified/RuleList.tsx +++ b/public/app/features/alerting/unified/RuleList.tsx @@ -1,17 +1,19 @@ import { css } from '@emotion/css'; -import { GrafanaTheme2, urlUtil } from '@grafana/data'; -import { Button, LinkButton, useStyles2, withErrorBoundary } from '@grafana/ui'; -import { useQueryParams } from 'app/core/hooks/useQueryParams'; import React, { useEffect, useMemo, useState } from 'react'; import { useDispatch } from 'react-redux'; import { useLocation } from 'react-router-dom'; + +import { GrafanaTheme2, urlUtil } from '@grafana/data'; +import { Button, LinkButton, useStyles2, withErrorBoundary } from '@grafana/ui'; +import { useQueryParams } from 'app/core/hooks/useQueryParams'; + import { AlertingPageWrapper } from './components/AlertingPageWrapper'; import { NoRulesSplash } from './components/rules/NoRulesCTA'; import { RuleListErrors } from './components/rules/RuleListErrors'; import { RuleListGroupView } from './components/rules/RuleListGroupView'; import { RuleListStateView } from './components/rules/RuleListStateView'; -import RulesFilter from './components/rules/RulesFilter'; import { RuleStats } from './components/rules/RuleStats'; +import RulesFilter from './components/rules/RulesFilter'; import { useCombinedRuleNamespaces } from './hooks/useCombinedRuleNamespaces'; import { useFilteredRules } from './hooks/useFilteredRules'; import { useUnifiedAlertingSelector } from './hooks/useUnifiedAlertingSelector'; diff --git a/public/app/features/alerting/unified/RuleViewer.test.tsx b/public/app/features/alerting/unified/RuleViewer.test.tsx index e63364cb97b..df068a9952b 100644 --- a/public/app/features/alerting/unified/RuleViewer.test.tsx +++ b/public/app/features/alerting/unified/RuleViewer.test.tsx @@ -1,17 +1,19 @@ -import React from 'react'; import { act, render, screen } from '@testing-library/react'; +import React from 'react'; import { Provider } from 'react-redux'; import { Router } from 'react-router-dom'; + import { DataSourceJsonData, PluginMeta } from '@grafana/data'; import { locationService } from '@grafana/runtime'; -import { RuleViewer } from './RuleViewer'; -import { configureStore } from 'app/store/configureStore'; -import { useCombinedRule } from './hooks/useCombinedRule'; import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; -import { GRAFANA_RULES_SOURCE_NAME } from './utils/datasource'; +import { configureStore } from 'app/store/configureStore'; import { CombinedRule } from 'app/types/unified-alerting'; import { GrafanaAlertStateDecision } from 'app/types/unified-alerting-dto'; +import { RuleViewer } from './RuleViewer'; +import { useCombinedRule } from './hooks/useCombinedRule'; +import { GRAFANA_RULES_SOURCE_NAME } from './utils/datasource'; + jest.mock('./hooks/useCombinedRule'); jest.mock('@grafana/runtime', () => ({ ...(jest.requireActual('@grafana/runtime') as any), diff --git a/public/app/features/alerting/unified/RuleViewer.tsx b/public/app/features/alerting/unified/RuleViewer.tsx index 105e078bc4a..647795709f7 100644 --- a/public/app/features/alerting/unified/RuleViewer.tsx +++ b/public/app/features/alerting/unified/RuleViewer.tsx @@ -1,4 +1,7 @@ import { css } from '@emotion/css'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import { useObservable } from 'react-use'; + import { GrafanaTheme2, LoadingState, PanelData } from '@grafana/data'; import { Alert, @@ -11,9 +14,9 @@ import { withErrorBoundary, } from '@grafana/ui'; import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; -import React, { useCallback, useEffect, useMemo, useState } from 'react'; -import { useObservable } from 'react-use'; + import { AlertQuery } from '../../../types/unified-alerting-dto'; + import { AlertLabels } from './components/AlertLabels'; import { DetailsField } from './components/DetailsField'; import { RuleViewerLayout, RuleViewerLayoutContent } from './components/rule-viewer/RuleViewerLayout'; diff --git a/public/app/features/alerting/unified/Silences.test.tsx b/public/app/features/alerting/unified/Silences.test.tsx index 1b3b01bd9b1..d3f1fe9b1a5 100644 --- a/public/app/features/alerting/unified/Silences.test.tsx +++ b/public/app/features/alerting/unified/Silences.test.tsx @@ -1,21 +1,23 @@ -import React from 'react'; import { render, waitFor } from '@testing-library/react'; -import { locationService, setDataSourceSrv } from '@grafana/runtime'; -import { dateTime } from '@grafana/data'; +import userEvent, { PointerEventsCheckLevel } from '@testing-library/user-event'; +import React from 'react'; import { Provider } from 'react-redux'; import { Router } from 'react-router-dom'; -import { fetchSilences, fetchAlerts, createOrUpdateSilence } from './api/alertmanager'; -import { configureStore } from 'app/store/configureStore'; -import Silences from './Silences'; -import { mockAlertmanagerAlert, mockDataSource, MockDataSourceSrv, mockSilence } from './mocks'; -import { DataSourceType } from './utils/datasource'; -import { parseMatchers } from './utils/alertmanager'; -import { AlertState, MatcherOperator } from 'app/plugins/datasource/alertmanager/types'; import { byLabelText, byPlaceholderText, byRole, byTestId, byText } from 'testing-library-selector'; -import userEvent, { PointerEventsCheckLevel } from '@testing-library/user-event'; + +import { dateTime } from '@grafana/data'; +import { locationService, setDataSourceSrv } from '@grafana/runtime'; import { contextSrv } from 'app/core/services/context_srv'; +import { AlertState, MatcherOperator } from 'app/plugins/datasource/alertmanager/types'; +import { configureStore } from 'app/store/configureStore'; import { AccessControlAction } from 'app/types'; +import Silences from './Silences'; +import { fetchSilences, fetchAlerts, createOrUpdateSilence } from './api/alertmanager'; +import { mockAlertmanagerAlert, mockDataSource, MockDataSourceSrv, mockSilence } from './mocks'; +import { parseMatchers } from './utils/alertmanager'; +import { DataSourceType } from './utils/datasource'; + jest.mock('./api/alertmanager'); jest.mock('app/core/services/context_srv'); diff --git a/public/app/features/alerting/unified/Silences.tsx b/public/app/features/alerting/unified/Silences.tsx index 475e919c3f8..828a26a23df 100644 --- a/public/app/features/alerting/unified/Silences.tsx +++ b/public/app/features/alerting/unified/Silences.tsx @@ -1,20 +1,21 @@ import React, { FC, useEffect, useCallback } from 'react'; -import { Alert, LoadingPlaceholder, withErrorBoundary } from '@grafana/ui'; - import { useDispatch } from 'react-redux'; import { Redirect, Route, RouteChildrenProps, Switch, useLocation } from 'react-router-dom'; + +import { Alert, LoadingPlaceholder, withErrorBoundary } from '@grafana/ui'; +import { Silence } from 'app/plugins/datasource/alertmanager/types'; +import { AccessControlAction } from 'app/types'; + +import { AlertManagerPicker } from './components/AlertManagerPicker'; import { AlertingPageWrapper } from './components/AlertingPageWrapper'; +import { Authorize } from './components/Authorize'; +import SilencesEditor from './components/silences/SilencesEditor'; import SilencesTable from './components/silences/SilencesTable'; import { useAlertManagerSourceName } from './hooks/useAlertManagerSourceName'; import { useUnifiedAlertingSelector } from './hooks/useUnifiedAlertingSelector'; import { fetchAmAlertsAction, fetchSilencesAction } from './state/actions'; import { SILENCES_POLL_INTERVAL_MS } from './utils/constants'; import { AsyncRequestState, initialAsyncRequestState } from './utils/redux'; -import SilencesEditor from './components/silences/SilencesEditor'; -import { AlertManagerPicker } from './components/AlertManagerPicker'; -import { Silence } from 'app/plugins/datasource/alertmanager/types'; -import { AccessControlAction } from 'app/types'; -import { Authorize } from './components/Authorize'; const Silences: FC = () => { const [alertManagerSourceName, setAlertManagerSourceName] = useAlertManagerSourceName(); diff --git a/public/app/features/alerting/unified/api/alertmanager.ts b/public/app/features/alerting/unified/api/alertmanager.ts index 9986590701c..fe73d3fd655 100644 --- a/public/app/features/alerting/unified/api/alertmanager.ts +++ b/public/app/features/alerting/unified/api/alertmanager.ts @@ -1,3 +1,5 @@ +import { lastValueFrom } from 'rxjs'; + import { urlUtil } from '@grafana/data'; import { getBackendSrv } from '@grafana/runtime'; import { @@ -15,9 +17,9 @@ import { TestReceiversResult, ExternalAlertmanagerConfig, } from 'app/plugins/datasource/alertmanager/types'; -import { lastValueFrom } from 'rxjs'; -import { getDatasourceAPIId, GRAFANA_RULES_SOURCE_NAME } from '../utils/datasource'; + import { isFetchError } from '../utils/alertmanager'; +import { getDatasourceAPIId, GRAFANA_RULES_SOURCE_NAME } from '../utils/datasource'; // "grafana" for grafana-managed, otherwise a datasource name export async function fetchAlertManagerConfig(alertManagerSourceName: string): Promise { diff --git a/public/app/features/alerting/unified/api/annotations.test.ts b/public/app/features/alerting/unified/api/annotations.test.ts index 183c103f58c..ae8cece3be5 100644 --- a/public/app/features/alerting/unified/api/annotations.test.ts +++ b/public/app/features/alerting/unified/api/annotations.test.ts @@ -1,7 +1,8 @@ import '@grafana/runtime'; -import { fetchAnnotations, sortStateHistory } from './annotations'; import { StateHistoryItem } from 'app/types/unified-alerting'; +import { fetchAnnotations, sortStateHistory } from './annotations'; + const get = jest.fn(() => { return new Promise((resolve) => { resolve(undefined); diff --git a/public/app/features/alerting/unified/api/buildInfo.test.ts b/public/app/features/alerting/unified/api/buildInfo.test.ts index 099390e8293..48ea249e8bc 100644 --- a/public/app/features/alerting/unified/api/buildInfo.test.ts +++ b/public/app/features/alerting/unified/api/buildInfo.test.ts @@ -1,5 +1,7 @@ -import { PromApplication } from 'app/types/unified-alerting-dto'; import { of, throwError } from 'rxjs'; + +import { PromApplication } from 'app/types/unified-alerting-dto'; + import { fetchDataSourceBuildInfo } from './buildInfo'; import { fetchRules } from './prometheus'; import { fetchTestRulerRulesGroup } from './ruler'; diff --git a/public/app/features/alerting/unified/api/buildInfo.ts b/public/app/features/alerting/unified/api/buildInfo.ts index 465908f6a95..39ef33d5940 100644 --- a/public/app/features/alerting/unified/api/buildInfo.ts +++ b/public/app/features/alerting/unified/api/buildInfo.ts @@ -1,9 +1,12 @@ +import { lastValueFrom } from 'rxjs'; + import { getBackendSrv } from '@grafana/runtime'; import { PromApplication, PromBuildInfo, PromBuildInfoResponse } from 'app/types/unified-alerting-dto'; -import { lastValueFrom } from 'rxjs'; + import { isFetchError } from '../utils/alertmanager'; import { RULER_NOT_SUPPORTED_MSG } from '../utils/constants'; import { getDataSourceByName } from '../utils/datasource'; + import { fetchRules } from './prometheus'; import { fetchTestRulerRulesGroup } from './ruler'; diff --git a/public/app/features/alerting/unified/api/preview.ts b/public/app/features/alerting/unified/api/preview.ts index 2d51276fced..20ba91453b9 100644 --- a/public/app/features/alerting/unified/api/preview.ts +++ b/public/app/features/alerting/unified/api/preview.ts @@ -1,3 +1,6 @@ +import { Observable, of } from 'rxjs'; +import { catchError, map, share } from 'rxjs/operators'; + import { dataFrameFromJSON, DataFrameJSON, @@ -7,8 +10,7 @@ import { withLoadingIndicator, } from '@grafana/data'; import { getBackendSrv, toDataQueryError } from '@grafana/runtime'; -import { Observable, of } from 'rxjs'; -import { catchError, map, share } from 'rxjs/operators'; + import { CloudPreviewRuleRequest, GrafanaPreviewRuleRequest, diff --git a/public/app/features/alerting/unified/api/prometheus.ts b/public/app/features/alerting/unified/api/prometheus.ts index db3598f04bc..acb42bd3678 100644 --- a/public/app/features/alerting/unified/api/prometheus.ts +++ b/public/app/features/alerting/unified/api/prometheus.ts @@ -1,8 +1,9 @@ import { lastValueFrom } from 'rxjs'; -import { getBackendSrv } from '@grafana/runtime'; +import { getBackendSrv } from '@grafana/runtime'; import { RuleNamespace } from 'app/types/unified-alerting'; import { PromRulesResponse } from 'app/types/unified-alerting-dto'; + import { getDatasourceAPIId, GRAFANA_RULES_SOURCE_NAME } from '../utils/datasource'; export interface FetchPromRulesFilter { diff --git a/public/app/features/alerting/unified/api/ruler.test.ts b/public/app/features/alerting/unified/api/ruler.test.ts index 1e1ec9ed62c..2713d0e975b 100644 --- a/public/app/features/alerting/unified/api/ruler.test.ts +++ b/public/app/features/alerting/unified/api/ruler.test.ts @@ -1,5 +1,7 @@ import { RulerDataSourceConfig } from 'app/types/unified-alerting'; + import { getDatasourceAPIId } from '../utils/datasource'; + import { rulerUrlBuilder } from './ruler'; jest.mock('../utils/datasource'); diff --git a/public/app/features/alerting/unified/api/ruler.ts b/public/app/features/alerting/unified/api/ruler.ts index c5c82f6317e..51af85a77e1 100644 --- a/public/app/features/alerting/unified/api/ruler.ts +++ b/public/app/features/alerting/unified/api/ruler.ts @@ -1,10 +1,12 @@ import { lastValueFrom } from 'rxjs'; -import { FetchResponse, getBackendSrv } from '@grafana/runtime'; -import { PostableRulerRuleGroupDTO, RulerRuleGroupDTO, RulerRulesConfigDTO } from 'app/types/unified-alerting-dto'; -import { getDatasourceAPIId, GRAFANA_RULES_SOURCE_NAME } from '../utils/datasource'; -import { RULER_NOT_SUPPORTED_MSG } from '../utils/constants'; +import { FetchResponse, getBackendSrv } from '@grafana/runtime'; import { RulerDataSourceConfig } from 'app/types/unified-alerting'; +import { PostableRulerRuleGroupDTO, RulerRuleGroupDTO, RulerRulesConfigDTO } from 'app/types/unified-alerting-dto'; + +import { RULER_NOT_SUPPORTED_MSG } from '../utils/constants'; +import { getDatasourceAPIId, GRAFANA_RULES_SOURCE_NAME } from '../utils/datasource'; + import { prepareRulesFilterQueryParams } from './prometheus'; interface ErrorResponseMessage { diff --git a/public/app/features/alerting/unified/components/AlertLabel.tsx b/public/app/features/alerting/unified/components/AlertLabel.tsx index 984e57a3492..5f77b5cf126 100644 --- a/public/app/features/alerting/unified/components/AlertLabel.tsx +++ b/public/app/features/alerting/unified/components/AlertLabel.tsx @@ -1,7 +1,8 @@ -import React, { FC } from 'react'; -import { IconButton, useStyles } from '@grafana/ui'; -import { GrafanaTheme } from '@grafana/data'; import { css } from '@emotion/css'; +import React, { FC } from 'react'; + +import { GrafanaTheme } from '@grafana/data'; +import { IconButton, useStyles } from '@grafana/ui'; interface Props { labelKey: string; diff --git a/public/app/features/alerting/unified/components/AlertLabels.tsx b/public/app/features/alerting/unified/components/AlertLabels.tsx index 4397e56fd9e..e6fda61b93a 100644 --- a/public/app/features/alerting/unified/components/AlertLabels.tsx +++ b/public/app/features/alerting/unified/components/AlertLabels.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { TagList } from '@grafana/ui'; type Props = { labels: Record; className?: string }; diff --git a/public/app/features/alerting/unified/components/AlertManagerPicker.tsx b/public/app/features/alerting/unified/components/AlertManagerPicker.tsx index e0107dbc575..19302227d16 100644 --- a/public/app/features/alerting/unified/components/AlertManagerPicker.tsx +++ b/public/app/features/alerting/unified/components/AlertManagerPicker.tsx @@ -1,9 +1,11 @@ -import { SelectableValue, GrafanaTheme2 } from '@grafana/data'; -import { DataSourceType, GRAFANA_RULES_SOURCE_NAME } from '../utils/datasource'; -import React, { FC, useMemo } from 'react'; -import { Field, Select, useStyles2 } from '@grafana/ui'; -import { getAllDataSources } from '../utils/config'; import { css } from '@emotion/css'; +import React, { FC, useMemo } from 'react'; + +import { SelectableValue, GrafanaTheme2 } from '@grafana/data'; +import { Field, Select, useStyles2 } from '@grafana/ui'; + +import { getAllDataSources } from '../utils/config'; +import { DataSourceType, GRAFANA_RULES_SOURCE_NAME } from '../utils/datasource'; interface Props { onChange: (alertManagerSourceName: string) => void; diff --git a/public/app/features/alerting/unified/components/AlertingPageWrapper.tsx b/public/app/features/alerting/unified/components/AlertingPageWrapper.tsx index db50e173e1d..21a7826139e 100644 --- a/public/app/features/alerting/unified/components/AlertingPageWrapper.tsx +++ b/public/app/features/alerting/unified/components/AlertingPageWrapper.tsx @@ -1,7 +1,8 @@ import React, { FC } from 'react'; +import { useSelector } from 'react-redux'; + import Page from 'app/core/components/Page/Page'; import { getNavModel } from 'app/core/selectors/navModel'; -import { useSelector } from 'react-redux'; import { StoreState } from 'app/types/store'; interface Props { diff --git a/public/app/features/alerting/unified/components/AnnotationDetailsField.tsx b/public/app/features/alerting/unified/components/AnnotationDetailsField.tsx index ed27208dec9..5d8061c220c 100644 --- a/public/app/features/alerting/unified/components/AnnotationDetailsField.tsx +++ b/public/app/features/alerting/unified/components/AnnotationDetailsField.tsx @@ -1,11 +1,14 @@ -import React, { FC } from 'react'; -import { Well } from './Well'; -import { GrafanaTheme } from '@grafana/data'; import { css } from '@emotion/css'; +import React, { FC } from 'react'; + +import { GrafanaTheme } from '@grafana/data'; import { Tooltip, useStyles } from '@grafana/ui'; -import { DetailsField } from './DetailsField'; + import { Annotation, annotationLabels } from '../utils/constants'; +import { DetailsField } from './DetailsField'; +import { Well } from './Well'; + const wellableAnnotationKeys = ['message', 'description']; interface Props { diff --git a/public/app/features/alerting/unified/components/Authorize.tsx b/public/app/features/alerting/unified/components/Authorize.tsx index d283a0454e8..20506481e89 100644 --- a/public/app/features/alerting/unified/components/Authorize.tsx +++ b/public/app/features/alerting/unified/components/Authorize.tsx @@ -1,6 +1,7 @@ import React, { FC } from 'react'; -import { AccessControlAction } from 'app/types'; + import { contextSrv } from 'app/core/services/context_srv'; +import { AccessControlAction } from 'app/types'; type Props = { actions: AccessControlAction[]; diff --git a/public/app/features/alerting/unified/components/CollapseToggle.test.tsx b/public/app/features/alerting/unified/components/CollapseToggle.test.tsx index 384da5879fd..9bdb1cf191b 100644 --- a/public/app/features/alerting/unified/components/CollapseToggle.test.tsx +++ b/public/app/features/alerting/unified/components/CollapseToggle.test.tsx @@ -1,6 +1,7 @@ import { render, screen } from '@testing-library/react'; import { noop } from 'lodash'; import React from 'react'; + import { CollapseToggle } from './CollapseToggle'; describe('TestToggle', () => { diff --git a/public/app/features/alerting/unified/components/CollapseToggle.tsx b/public/app/features/alerting/unified/components/CollapseToggle.tsx index 3e670a396be..d5ae0433b00 100644 --- a/public/app/features/alerting/unified/components/CollapseToggle.tsx +++ b/public/app/features/alerting/unified/components/CollapseToggle.tsx @@ -1,5 +1,6 @@ -import React, { FC, HTMLAttributes } from 'react'; import { css, cx } from '@emotion/css'; +import React, { FC, HTMLAttributes } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { IconSize, useStyles2, Button } from '@grafana/ui'; diff --git a/public/app/features/alerting/unified/components/DetailsField.tsx b/public/app/features/alerting/unified/components/DetailsField.tsx index 50c06c29724..28359475592 100644 --- a/public/app/features/alerting/unified/components/DetailsField.tsx +++ b/public/app/features/alerting/unified/components/DetailsField.tsx @@ -1,5 +1,6 @@ -import React, { FC } from 'react'; import { css, cx } from '@emotion/css'; +import React, { FC } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { useStyles2 } from '@grafana/ui'; diff --git a/public/app/features/alerting/unified/components/DynamicTable.tsx b/public/app/features/alerting/unified/components/DynamicTable.tsx index 5ff067820a2..9c5e0b4544c 100644 --- a/public/app/features/alerting/unified/components/DynamicTable.tsx +++ b/public/app/features/alerting/unified/components/DynamicTable.tsx @@ -1,5 +1,6 @@ -import React, { ReactNode, useState } from 'react'; import { css, cx } from '@emotion/css'; +import React, { ReactNode, useState } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { IconButton, useStyles2 } from '@grafana/ui'; diff --git a/public/app/features/alerting/unified/components/DynamicTableWithGuidelines.tsx b/public/app/features/alerting/unified/components/DynamicTableWithGuidelines.tsx index 65f98b1524b..ad75ae1a53b 100644 --- a/public/app/features/alerting/unified/components/DynamicTableWithGuidelines.tsx +++ b/public/app/features/alerting/unified/components/DynamicTableWithGuidelines.tsx @@ -1,7 +1,9 @@ import { css, cx } from '@emotion/css'; +import React from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { useStyles2 } from '@grafana/ui'; -import React from 'react'; + import { DynamicTable, DynamicTableProps } from './DynamicTable'; export type DynamicTableWithGuidelinesProps = Omit, 'renderPrefixHeader, renderPrefixCell'>; diff --git a/public/app/features/alerting/unified/components/EmptyArea.tsx b/public/app/features/alerting/unified/components/EmptyArea.tsx index 6482547d906..d0129033d24 100644 --- a/public/app/features/alerting/unified/components/EmptyArea.tsx +++ b/public/app/features/alerting/unified/components/EmptyArea.tsx @@ -1,5 +1,6 @@ -import React, { FC } from 'react'; import { css } from '@emotion/css'; +import React, { FC } from 'react'; + import { GrafanaTheme } from '@grafana/data'; import { useStyles } from '@grafana/ui'; diff --git a/public/app/features/alerting/unified/components/EmptyAreaWithCTA.tsx b/public/app/features/alerting/unified/components/EmptyAreaWithCTA.tsx index a1c8d834104..a0dc2bbf1fe 100644 --- a/public/app/features/alerting/unified/components/EmptyAreaWithCTA.tsx +++ b/public/app/features/alerting/unified/components/EmptyAreaWithCTA.tsx @@ -1,7 +1,9 @@ -import React, { ButtonHTMLAttributes, FC } from 'react'; import { css } from '@emotion/css'; +import React, { ButtonHTMLAttributes, FC } from 'react'; + import { GrafanaTheme } from '@grafana/data'; import { Button, ButtonVariant, IconName, LinkButton, useStyles } from '@grafana/ui'; + import { EmptyArea } from './EmptyArea'; export interface EmptyAreaWithCTAProps { diff --git a/public/app/features/alerting/unified/components/Expression.tsx b/public/app/features/alerting/unified/components/Expression.tsx index f04683fc7a5..239ea13043d 100644 --- a/public/app/features/alerting/unified/components/Expression.tsx +++ b/public/app/features/alerting/unified/components/Expression.tsx @@ -1,13 +1,16 @@ -import { Editor } from '@grafana/slate-react'; -import React, { FC, useMemo } from 'react'; -import PromqlSyntax from 'app/plugins/datasource/prometheus/promql'; -import LogqlSyntax from 'app/plugins/datasource/loki/syntax'; -import { LanguageMap, languages as prismLanguages } from 'prismjs'; -import { makeValue, SlatePrism, useStyles } from '@grafana/ui'; import { css, cx } from '@emotion/css'; +import { LanguageMap, languages as prismLanguages } from 'prismjs'; +import React, { FC, useMemo } from 'react'; + import { GrafanaTheme } from '@grafana/data'; +import { Editor } from '@grafana/slate-react'; +import { makeValue, SlatePrism, useStyles } from '@grafana/ui'; +import LogqlSyntax from 'app/plugins/datasource/loki/syntax'; +import PromqlSyntax from 'app/plugins/datasource/prometheus/promql'; import { RulesSource } from 'app/types/unified-alerting'; + import { DataSourceType, isCloudRulesSource } from '../utils/datasource'; + import { Well } from './Well'; interface Props { diff --git a/public/app/features/alerting/unified/components/PanelPluginsButtonGroup.tsx b/public/app/features/alerting/unified/components/PanelPluginsButtonGroup.tsx index 0f8b9b5486b..d5bada5d1fa 100644 --- a/public/app/features/alerting/unified/components/PanelPluginsButtonGroup.tsx +++ b/public/app/features/alerting/unified/components/PanelPluginsButtonGroup.tsx @@ -1,7 +1,9 @@ +import React, { useMemo } from 'react'; + import { SelectableValue } from '@grafana/data'; import { config } from '@grafana/runtime'; import { RadioButtonGroup } from '@grafana/ui'; -import React, { useMemo } from 'react'; + import { STAT, TABLE, TIMESERIES } from '../utils/constants'; export type SupportedPanelPlugins = 'timeseries' | 'table' | 'stat'; diff --git a/public/app/features/alerting/unified/components/RuleLocation.tsx b/public/app/features/alerting/unified/components/RuleLocation.tsx index c1b176e231b..74ccbf5209d 100644 --- a/public/app/features/alerting/unified/components/RuleLocation.tsx +++ b/public/app/features/alerting/unified/components/RuleLocation.tsx @@ -1,6 +1,7 @@ -import { Icon } from '@grafana/ui'; import React, { FC } from 'react'; +import { Icon } from '@grafana/ui'; + interface RuleLocationProps { namespace: string; group?: string; diff --git a/public/app/features/alerting/unified/components/StateColoredText.tsx b/public/app/features/alerting/unified/components/StateColoredText.tsx index 1a650413f23..9e36f2d2d16 100644 --- a/public/app/features/alerting/unified/components/StateColoredText.tsx +++ b/public/app/features/alerting/unified/components/StateColoredText.tsx @@ -1,8 +1,9 @@ +import { css } from '@emotion/css'; +import React, { FC } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { useStyles2 } from '@grafana/ui'; import { PromAlertingRuleState } from 'app/types/unified-alerting-dto'; -import { css } from '@emotion/css'; -import React, { FC } from 'react'; type Props = { status: PromAlertingRuleState | 'neutral'; diff --git a/public/app/features/alerting/unified/components/StateTag.tsx b/public/app/features/alerting/unified/components/StateTag.tsx index 5ca76eb73ea..3d4494fd78a 100644 --- a/public/app/features/alerting/unified/components/StateTag.tsx +++ b/public/app/features/alerting/unified/components/StateTag.tsx @@ -1,8 +1,9 @@ -import { GrafanaTheme2 } from '@grafana/data'; -import { useStyles2 } from '@grafana/ui'; import { css, cx } from '@emotion/css'; import React, { FC } from 'react'; +import { GrafanaTheme2 } from '@grafana/data'; +import { useStyles2 } from '@grafana/ui'; + export type State = 'good' | 'bad' | 'warning' | 'neutral' | 'info'; type Props = { diff --git a/public/app/features/alerting/unified/components/TimeToNow.tsx b/public/app/features/alerting/unified/components/TimeToNow.tsx index efd5955bcc9..65cfc2fd75c 100644 --- a/public/app/features/alerting/unified/components/TimeToNow.tsx +++ b/public/app/features/alerting/unified/components/TimeToNow.tsx @@ -1,6 +1,7 @@ -import { dateTimeFormatTimeAgo, DateTimeInput } from '@grafana/data'; import React, { FC, useEffect, useState } from 'react'; +import { dateTimeFormatTimeAgo, DateTimeInput } from '@grafana/data'; + export interface Props { date: DateTimeInput; } diff --git a/public/app/features/alerting/unified/components/Well.tsx b/public/app/features/alerting/unified/components/Well.tsx index 3145298ae68..0ebfed409ca 100644 --- a/public/app/features/alerting/unified/components/Well.tsx +++ b/public/app/features/alerting/unified/components/Well.tsx @@ -1,7 +1,8 @@ -import React, { FC } from 'react'; -import { useStyles } from '@grafana/ui'; import { cx, css } from '@emotion/css'; +import React, { FC } from 'react'; + import { GrafanaTheme } from '@grafana/data'; +import { useStyles } from '@grafana/ui'; type Props = React.HTMLAttributes; diff --git a/public/app/features/alerting/unified/components/admin/AddAlertManagerModal.tsx b/public/app/features/alerting/unified/components/admin/AddAlertManagerModal.tsx index aabb017f588..05cdfebf444 100644 --- a/public/app/features/alerting/unified/components/admin/AddAlertManagerModal.tsx +++ b/public/app/features/alerting/unified/components/admin/AddAlertManagerModal.tsx @@ -1,5 +1,6 @@ -import React, { FC, useMemo } from 'react'; import { css, cx } from '@emotion/css'; +import React, { FC, useMemo } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { Button, Field, FieldArray, Form, Icon, Input, Modal, useStyles2 } from '@grafana/ui'; import { AlertmanagerUrl } from 'app/plugins/datasource/alertmanager/types'; diff --git a/public/app/features/alerting/unified/components/admin/AlertmanagerConfig.test.tsx b/public/app/features/alerting/unified/components/admin/AlertmanagerConfig.test.tsx index ed43711beaa..26b683d8f7e 100644 --- a/public/app/features/alerting/unified/components/admin/AlertmanagerConfig.test.tsx +++ b/public/app/features/alerting/unified/components/admin/AlertmanagerConfig.test.tsx @@ -1,34 +1,37 @@ +import { render, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; import React from 'react'; -import { getAllDataSources } from '../../utils/config'; +import { Provider } from 'react-redux'; +import { Router } from 'react-router-dom'; +import { byLabelText, byRole, byTestId } from 'testing-library-selector'; + +import { locationService, setDataSourceSrv } from '@grafana/runtime'; +import { contextSrv } from 'app/core/services/context_srv'; +import store from 'app/core/store'; +import { + AlertManagerCortexConfig, + AlertManagerDataSourceJsonData, + AlertManagerImplementation, +} from 'app/plugins/datasource/alertmanager/types'; +import { configureStore } from 'app/store/configureStore'; + import { fetchAlertManagerConfig, deleteAlertManagerConfig, updateAlertManagerConfig, fetchStatus, } from '../../api/alertmanager'; -import { configureStore } from 'app/store/configureStore'; -import { locationService, setDataSourceSrv } from '@grafana/runtime'; -import AlertmanagerConfig from './AlertmanagerConfig'; -import { Provider } from 'react-redux'; -import { Router } from 'react-router-dom'; -import { ALERTMANAGER_NAME_LOCAL_STORAGE_KEY, ALERTMANAGER_NAME_QUERY_KEY } from '../../utils/constants'; -import { render, waitFor } from '@testing-library/react'; -import { byLabelText, byRole, byTestId } from 'testing-library-selector'; import { mockDataSource, MockDataSourceSrv, someCloudAlertManagerConfig, someCloudAlertManagerStatus, } from '../../mocks'; +import { getAllDataSources } from '../../utils/config'; +import { ALERTMANAGER_NAME_LOCAL_STORAGE_KEY, ALERTMANAGER_NAME_QUERY_KEY } from '../../utils/constants'; import { DataSourceType } from '../../utils/datasource'; -import { contextSrv } from 'app/core/services/context_srv'; -import store from 'app/core/store'; -import userEvent from '@testing-library/user-event'; -import { - AlertManagerCortexConfig, - AlertManagerDataSourceJsonData, - AlertManagerImplementation, -} from 'app/plugins/datasource/alertmanager/types'; + +import AlertmanagerConfig from './AlertmanagerConfig'; jest.mock('../../api/alertmanager'); jest.mock('../../api/grafana'); diff --git a/public/app/features/alerting/unified/components/admin/AlertmanagerConfig.tsx b/public/app/features/alerting/unified/components/admin/AlertmanagerConfig.tsx index 6a939f4372c..aaa09860c15 100644 --- a/public/app/features/alerting/unified/components/admin/AlertmanagerConfig.tsx +++ b/public/app/features/alerting/unified/components/admin/AlertmanagerConfig.tsx @@ -1,18 +1,20 @@ -import React, { useEffect, useState, useMemo } from 'react'; import { css } from '@emotion/css'; +import React, { useEffect, useState, useMemo } from 'react'; +import { useDispatch } from 'react-redux'; + import { GrafanaTheme2 } from '@grafana/data'; import { Alert, Button, ConfirmModal, TextArea, HorizontalGroup, Field, Form, useStyles2 } from '@grafana/ui'; + import { useAlertManagerSourceName } from '../../hooks/useAlertManagerSourceName'; -import { AlertManagerPicker } from '../AlertManagerPicker'; -import { GRAFANA_RULES_SOURCE_NAME, isVanillaPrometheusAlertManagerDataSource } from '../../utils/datasource'; -import { useDispatch } from 'react-redux'; +import { useUnifiedAlertingSelector } from '../../hooks/useUnifiedAlertingSelector'; import { deleteAlertManagerConfigAction, fetchAlertManagerConfigAction, updateAlertManagerConfigAction, } from '../../state/actions'; -import { useUnifiedAlertingSelector } from '../../hooks/useUnifiedAlertingSelector'; +import { GRAFANA_RULES_SOURCE_NAME, isVanillaPrometheusAlertManagerDataSource } from '../../utils/datasource'; import { initialAsyncRequestState } from '../../utils/redux'; +import { AlertManagerPicker } from '../AlertManagerPicker'; interface FormValues { configJSON: string; diff --git a/public/app/features/alerting/unified/components/admin/ExternalAlertmanagers.tsx b/public/app/features/alerting/unified/components/admin/ExternalAlertmanagers.tsx index efcbccf9ab6..f98aff36b96 100644 --- a/public/app/features/alerting/unified/components/admin/ExternalAlertmanagers.tsx +++ b/public/app/features/alerting/unified/components/admin/ExternalAlertmanagers.tsx @@ -1,6 +1,7 @@ +import { css, cx } from '@emotion/css'; import React, { useCallback, useEffect, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { css, cx } from '@emotion/css'; + import { GrafanaTheme2 } from '@grafana/data'; import { Button, @@ -14,14 +15,16 @@ import { useTheme2, } from '@grafana/ui'; import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA'; -import { AddAlertManagerModal } from './AddAlertManagerModal'; +import { StoreState } from 'app/types/store'; + +import { useExternalAmSelector } from '../../hooks/useExternalAmSelector'; import { addExternalAlertmanagersAction, fetchExternalAlertmanagersAction, fetchExternalAlertmanagersConfigAction, } from '../../state/actions'; -import { useExternalAmSelector } from '../../hooks/useExternalAmSelector'; -import { StoreState } from 'app/types/store'; + +import { AddAlertManagerModal } from './AddAlertManagerModal'; const alertmanagerChoices = [ { value: 'internal', label: 'Only Internal' }, diff --git a/public/app/features/alerting/unified/components/alert-groups/AlertDetails.tsx b/public/app/features/alerting/unified/components/alert-groups/AlertDetails.tsx index 3bf19837978..8ab58c7cbc7 100644 --- a/public/app/features/alerting/unified/components/alert-groups/AlertDetails.tsx +++ b/public/app/features/alerting/unified/components/alert-groups/AlertDetails.tsx @@ -1,10 +1,12 @@ import { css } from '@emotion/css'; +import React, { FC } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { LinkButton, useStyles2 } from '@grafana/ui'; import { contextSrv } from 'app/core/services/context_srv'; import { AlertmanagerAlert, AlertState } from 'app/plugins/datasource/alertmanager/types'; import { AccessControlAction } from 'app/types'; -import React, { FC } from 'react'; + import { getInstancesPermissions } from '../../utils/access-control'; import { isGrafanaRulesSource } from '../../utils/datasource'; import { makeAMLink, makeLabelBasedSilenceLink } from '../../utils/misc'; diff --git a/public/app/features/alerting/unified/components/alert-groups/AlertGroup.tsx b/public/app/features/alerting/unified/components/alert-groups/AlertGroup.tsx index 073732227a4..c508875b588 100644 --- a/public/app/features/alerting/unified/components/alert-groups/AlertGroup.tsx +++ b/public/app/features/alerting/unified/components/alert-groups/AlertGroup.tsx @@ -1,11 +1,14 @@ -import { AlertmanagerGroup, AlertState } from 'app/plugins/datasource/alertmanager/types'; +import { css } from '@emotion/css'; import React, { useState } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { useStyles2 } from '@grafana/ui'; -import { css } from '@emotion/css'; +import { AlertmanagerGroup, AlertState } from 'app/plugins/datasource/alertmanager/types'; + import { AlertLabels } from '../AlertLabels'; -import { AlertGroupAlertsTable } from './AlertGroupAlertsTable'; import { CollapseToggle } from '../CollapseToggle'; + +import { AlertGroupAlertsTable } from './AlertGroupAlertsTable'; import { AlertGroupHeader } from './AlertGroupHeader'; interface Props { diff --git a/public/app/features/alerting/unified/components/alert-groups/AlertGroupAlertsTable.tsx b/public/app/features/alerting/unified/components/alert-groups/AlertGroupAlertsTable.tsx index f6df855efb4..38c0caaeab6 100644 --- a/public/app/features/alerting/unified/components/alert-groups/AlertGroupAlertsTable.tsx +++ b/public/app/features/alerting/unified/components/alert-groups/AlertGroupAlertsTable.tsx @@ -1,12 +1,15 @@ -import { AlertmanagerAlert } from 'app/plugins/datasource/alertmanager/types'; -import React, { useMemo } from 'react'; -import { useStyles2 } from '@grafana/ui'; -import { GrafanaTheme2, intervalToAbbreviatedDurationString } from '@grafana/data'; import { css } from '@emotion/css'; -import { DynamicTableColumnProps, DynamicTableItemProps } from '../DynamicTable'; -import { AmAlertStateTag } from '../silences/AmAlertStateTag'; +import React, { useMemo } from 'react'; + +import { GrafanaTheme2, intervalToAbbreviatedDurationString } from '@grafana/data'; +import { useStyles2 } from '@grafana/ui'; +import { AlertmanagerAlert } from 'app/plugins/datasource/alertmanager/types'; + import { AlertLabels } from '../AlertLabels'; +import { DynamicTableColumnProps, DynamicTableItemProps } from '../DynamicTable'; import { DynamicTableWithGuidelines } from '../DynamicTableWithGuidelines'; +import { AmAlertStateTag } from '../silences/AmAlertStateTag'; + import { AlertDetails } from './AlertDetails'; interface Props { diff --git a/public/app/features/alerting/unified/components/alert-groups/AlertGroupFilter.tsx b/public/app/features/alerting/unified/components/alert-groups/AlertGroupFilter.tsx index 746f3897d9d..7af9efe0958 100644 --- a/public/app/features/alerting/unified/components/alert-groups/AlertGroupFilter.tsx +++ b/public/app/features/alerting/unified/components/alert-groups/AlertGroupFilter.tsx @@ -1,17 +1,18 @@ +import { css } from '@emotion/css'; import React, { useState } from 'react'; -import { AlertManagerPicker } from '../AlertManagerPicker'; -import { MatcherFilter } from './MatcherFilter'; -import { AlertStateFilter } from './AlertStateFilter'; -import { GroupBy } from './GroupBy'; -import { AlertmanagerGroup, AlertState } from 'app/plugins/datasource/alertmanager/types'; import { GrafanaTheme2 } from '@grafana/data'; import { Button, useStyles2 } from '@grafana/ui'; +import { useQueryParams } from 'app/core/hooks/useQueryParams'; +import { AlertmanagerGroup, AlertState } from 'app/plugins/datasource/alertmanager/types'; import { useAlertManagerSourceName } from '../../hooks/useAlertManagerSourceName'; -import { css } from '@emotion/css'; import { getFiltersFromUrlParams } from '../../utils/misc'; -import { useQueryParams } from 'app/core/hooks/useQueryParams'; +import { AlertManagerPicker } from '../AlertManagerPicker'; + +import { AlertStateFilter } from './AlertStateFilter'; +import { GroupBy } from './GroupBy'; +import { MatcherFilter } from './MatcherFilter'; interface Props { groups: AlertmanagerGroup[]; diff --git a/public/app/features/alerting/unified/components/alert-groups/AlertGroupHeader.tsx b/public/app/features/alerting/unified/components/alert-groups/AlertGroupHeader.tsx index 9f6d9fd7cdb..421bc369b53 100644 --- a/public/app/features/alerting/unified/components/alert-groups/AlertGroupHeader.tsx +++ b/public/app/features/alerting/unified/components/alert-groups/AlertGroupHeader.tsx @@ -1,8 +1,10 @@ -import { AlertmanagerGroup, AlertState } from 'app/plugins/datasource/alertmanager/types'; -import React from 'react'; -import { useStyles2 } from '@grafana/ui'; -import { getNotificationsTextColors } from '../../styles/notifications'; import pluralize from 'pluralize'; +import React from 'react'; + +import { useStyles2 } from '@grafana/ui'; +import { AlertmanagerGroup, AlertState } from 'app/plugins/datasource/alertmanager/types'; + +import { getNotificationsTextColors } from '../../styles/notifications'; interface Props { group: AlertmanagerGroup; diff --git a/public/app/features/alerting/unified/components/alert-groups/AlertStateFilter.tsx b/public/app/features/alerting/unified/components/alert-groups/AlertStateFilter.tsx index 44cc945b443..507a4d693c6 100644 --- a/public/app/features/alerting/unified/components/alert-groups/AlertStateFilter.tsx +++ b/public/app/features/alerting/unified/components/alert-groups/AlertStateFilter.tsx @@ -1,8 +1,9 @@ -import React from 'react'; -import { RadioButtonGroup, Label, useStyles2 } from '@grafana/ui'; -import { GrafanaTheme2, SelectableValue } from '@grafana/data'; -import { AlertState } from 'app/plugins/datasource/alertmanager/types'; import { css } from '@emotion/css'; +import React from 'react'; + +import { GrafanaTheme2, SelectableValue } from '@grafana/data'; +import { RadioButtonGroup, Label, useStyles2 } from '@grafana/ui'; +import { AlertState } from 'app/plugins/datasource/alertmanager/types'; interface Props { stateFilter?: AlertState; diff --git a/public/app/features/alerting/unified/components/alert-groups/GroupBy.tsx b/public/app/features/alerting/unified/components/alert-groups/GroupBy.tsx index b43b69847f3..8f4ec0845d9 100644 --- a/public/app/features/alerting/unified/components/alert-groups/GroupBy.tsx +++ b/public/app/features/alerting/unified/components/alert-groups/GroupBy.tsx @@ -1,8 +1,9 @@ -import { AlertmanagerGroup } from 'app/plugins/datasource/alertmanager/types'; -import React from 'react'; import { uniq } from 'lodash'; -import { Icon, Label, MultiSelect } from '@grafana/ui'; +import React from 'react'; + import { SelectableValue } from '@grafana/data'; +import { Icon, Label, MultiSelect } from '@grafana/ui'; +import { AlertmanagerGroup } from 'app/plugins/datasource/alertmanager/types'; interface Props { className?: string; diff --git a/public/app/features/alerting/unified/components/alert-groups/MatcherFilter.tsx b/public/app/features/alerting/unified/components/alert-groups/MatcherFilter.tsx index 3abd20de39f..c6044a11817 100644 --- a/public/app/features/alerting/unified/components/alert-groups/MatcherFilter.tsx +++ b/public/app/features/alerting/unified/components/alert-groups/MatcherFilter.tsx @@ -1,8 +1,9 @@ -import React, { FormEvent } from 'react'; -import { Label, Tooltip, Input, Icon, useStyles2 } from '@grafana/ui'; -import { GrafanaTheme2 } from '@grafana/data'; import { css } from '@emotion/css'; +import React, { FormEvent } from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; import { Stack } from '@grafana/experimental'; +import { Label, Tooltip, Input, Icon, useStyles2 } from '@grafana/ui'; interface Props { className?: string; diff --git a/public/app/features/alerting/unified/components/amroutes/AmRootRoute.tsx b/public/app/features/alerting/unified/components/amroutes/AmRootRoute.tsx index e3c1a7d7299..9b12db3a6d5 100644 --- a/public/app/features/alerting/unified/components/amroutes/AmRootRoute.tsx +++ b/public/app/features/alerting/unified/components/amroutes/AmRootRoute.tsx @@ -1,13 +1,17 @@ -import React, { FC } from 'react'; import { css } from '@emotion/css'; +import React, { FC } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { Button, useStyles2 } from '@grafana/ui'; + +import { Authorize } from '../../components/Authorize'; import { AmRouteReceiver, FormAmRoute } from '../../types/amroutes'; +import { getNotificationsPermissions } from '../../utils/access-control'; +import { isVanillaPrometheusAlertManagerDataSource } from '../../utils/datasource'; + import { AmRootRouteForm } from './AmRootRouteForm'; import { AmRootRouteRead } from './AmRootRouteRead'; -import { isVanillaPrometheusAlertManagerDataSource } from '../../utils/datasource'; -import { Authorize } from '../../components/Authorize'; -import { getNotificationsPermissions } from '../../utils/access-control'; + export interface AmRootRouteProps { isEditMode: boolean; onEnterEditMode: () => void; diff --git a/public/app/features/alerting/unified/components/amroutes/AmRootRouteForm.tsx b/public/app/features/alerting/unified/components/amroutes/AmRootRouteForm.tsx index 714b63291c1..45dcc38a16d 100644 --- a/public/app/features/alerting/unified/components/amroutes/AmRootRouteForm.tsx +++ b/public/app/features/alerting/unified/components/amroutes/AmRootRouteForm.tsx @@ -1,6 +1,8 @@ -import React, { FC, useState } from 'react'; import { cx } from '@emotion/css'; +import React, { FC, useState } from 'react'; + import { Button, Collapse, Field, Form, Input, InputControl, Link, MultiSelect, Select, useStyles2 } from '@grafana/ui'; + import { AmRouteReceiver, FormAmRoute } from '../../types/amroutes'; import { mapMultiSelectValueToStrings, @@ -11,6 +13,7 @@ import { } from '../../utils/amroutes'; import { makeAMLink } from '../../utils/misc'; import { timeOptions } from '../../utils/time'; + import { getFormStyles } from './formStyles'; export interface AmRootRouteFormProps { diff --git a/public/app/features/alerting/unified/components/amroutes/AmRootRouteRead.tsx b/public/app/features/alerting/unified/components/amroutes/AmRootRouteRead.tsx index d534bbff303..026e7c6f289 100644 --- a/public/app/features/alerting/unified/components/amroutes/AmRootRouteRead.tsx +++ b/public/app/features/alerting/unified/components/amroutes/AmRootRouteRead.tsx @@ -1,6 +1,9 @@ import React, { FC } from 'react'; + import { useStyles2 } from '@grafana/ui'; + import { FormAmRoute } from '../../types/amroutes'; + import { getGridStyles } from './gridStyles'; export interface AmRootRouteReadProps { diff --git a/public/app/features/alerting/unified/components/amroutes/AmRoutesExpandedForm.tsx b/public/app/features/alerting/unified/components/amroutes/AmRoutesExpandedForm.tsx index ae7f9a1a142..b7581741faf 100644 --- a/public/app/features/alerting/unified/components/amroutes/AmRoutesExpandedForm.tsx +++ b/public/app/features/alerting/unified/components/amroutes/AmRoutesExpandedForm.tsx @@ -1,5 +1,6 @@ -import React, { FC, useState } from 'react'; import { css, cx } from '@emotion/css'; +import React, { FC, useState } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { Button, @@ -17,7 +18,10 @@ import { Badge, VerticalGroup, } from '@grafana/ui'; + +import { useMuteTimingOptions } from '../../hooks/useMuteTimingOptions'; import { AmRouteReceiver, FormAmRoute } from '../../types/amroutes'; +import { matcherFieldOptions } from '../../utils/alertmanager'; import { emptyArrayFieldMatcher, mapMultiSelectValueToStrings, @@ -27,9 +31,8 @@ import { stringsToSelectableValues, } from '../../utils/amroutes'; import { timeOptions } from '../../utils/time'; + import { getFormStyles } from './formStyles'; -import { matcherFieldOptions } from '../../utils/alertmanager'; -import { useMuteTimingOptions } from '../../hooks/useMuteTimingOptions'; export interface AmRoutesExpandedFormProps { onCancel: () => void; diff --git a/public/app/features/alerting/unified/components/amroutes/AmRoutesExpandedRead.tsx b/public/app/features/alerting/unified/components/amroutes/AmRoutesExpandedRead.tsx index 1ea268ae584..8cfa0270a1c 100644 --- a/public/app/features/alerting/unified/components/amroutes/AmRoutesExpandedRead.tsx +++ b/public/app/features/alerting/unified/components/amroutes/AmRoutesExpandedRead.tsx @@ -1,14 +1,17 @@ import { css } from '@emotion/css'; -import { GrafanaTheme2 } from '@grafana/data'; import React, { FC, useState } from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; import { Button, useStyles2 } from '@grafana/ui'; + import { AmRouteReceiver, FormAmRoute } from '../../types/amroutes'; -import { emptyRoute } from '../../utils/amroutes'; -import { AmRoutesTable } from './AmRoutesTable'; -import { getGridStyles } from './gridStyles'; -import { MuteTimingsTable } from './MuteTimingsTable'; -import { Authorize } from '../Authorize'; import { getNotificationsPermissions } from '../../utils/access-control'; +import { emptyRoute } from '../../utils/amroutes'; +import { Authorize } from '../Authorize'; + +import { AmRoutesTable } from './AmRoutesTable'; +import { MuteTimingsTable } from './MuteTimingsTable'; +import { getGridStyles } from './gridStyles'; export interface AmRoutesExpandedReadProps { onChange: (routes: FormAmRoute) => void; diff --git a/public/app/features/alerting/unified/components/amroutes/AmRoutesTable.test.ts b/public/app/features/alerting/unified/components/amroutes/AmRoutesTable.test.ts index a7fcee29adf..c15778b1cee 100644 --- a/public/app/features/alerting/unified/components/amroutes/AmRoutesTable.test.ts +++ b/public/app/features/alerting/unified/components/amroutes/AmRoutesTable.test.ts @@ -1,6 +1,8 @@ import { MatcherOperator } from 'app/plugins/datasource/alertmanager/types'; + import { FormAmRoute } from '../../types/amroutes'; import { MatcherFieldValue } from '../../types/silence-form'; + import { deleteRoute, getFilteredRoutes, updatedRoute } from './AmRoutesTable'; const defaultAmRoute: FormAmRoute = { diff --git a/public/app/features/alerting/unified/components/amroutes/AmRoutesTable.tsx b/public/app/features/alerting/unified/components/amroutes/AmRoutesTable.tsx index 5d8db06fc1d..9da90b15ba9 100644 --- a/public/app/features/alerting/unified/components/amroutes/AmRoutesTable.tsx +++ b/public/app/features/alerting/unified/components/amroutes/AmRoutesTable.tsx @@ -1,16 +1,19 @@ +import { intersectionWith, isEqual } from 'lodash'; import React, { FC, useCallback, useEffect, useMemo, useState } from 'react'; + import { Button, ConfirmModal, HorizontalGroup, IconButton } from '@grafana/ui'; +import { contextSrv } from 'app/core/services/context_srv'; + import { AmRouteReceiver, FormAmRoute } from '../../types/amroutes'; +import { getNotificationsPermissions } from '../../utils/access-control'; +import { matcherFieldToMatcher, parseMatchers } from '../../utils/alertmanager'; import { prepareItems } from '../../utils/dynamicTable'; import { DynamicTable, DynamicTableColumnProps, DynamicTableItemProps } from '../DynamicTable'; +import { EmptyArea } from '../EmptyArea'; +import { Matchers } from '../silences/Matchers'; + import { AmRoutesExpandedForm } from './AmRoutesExpandedForm'; import { AmRoutesExpandedRead } from './AmRoutesExpandedRead'; -import { Matchers } from '../silences/Matchers'; -import { matcherFieldToMatcher, parseMatchers } from '../../utils/alertmanager'; -import { intersectionWith, isEqual } from 'lodash'; -import { EmptyArea } from '../EmptyArea'; -import { contextSrv } from 'app/core/services/context_srv'; -import { getNotificationsPermissions } from '../../utils/access-control'; export interface AmRoutesTableProps { isAddMode: boolean; diff --git a/public/app/features/alerting/unified/components/amroutes/AmSpecificRouting.tsx b/public/app/features/alerting/unified/components/amroutes/AmSpecificRouting.tsx index 7fba03bfc12..cd7dc17006d 100644 --- a/public/app/features/alerting/unified/components/amroutes/AmSpecificRouting.tsx +++ b/public/app/features/alerting/unified/components/amroutes/AmSpecificRouting.tsx @@ -1,19 +1,22 @@ import { css } from '@emotion/css'; -import { GrafanaTheme2 } from '@grafana/data'; -import { Button, Icon, Input, Label, useStyles2 } from '@grafana/ui'; import React, { FC, useState } from 'react'; import { useDebounce } from 'react-use'; + +import { GrafanaTheme2 } from '@grafana/data'; +import { Button, Icon, Input, Label, useStyles2 } from '@grafana/ui'; +import { contextSrv } from 'app/core/services/context_srv'; + +import { Authorize } from '../../components/Authorize'; import { useURLSearchParams } from '../../hooks/useURLSearchParams'; import { AmRouteReceiver, FormAmRoute } from '../../types/amroutes'; +import { getNotificationsPermissions } from '../../utils/access-control'; import { emptyArrayFieldMatcher, emptyRoute } from '../../utils/amroutes'; import { getNotificationPoliciesFilters } from '../../utils/misc'; -import { MatcherFilter } from '../alert-groups/MatcherFilter'; import { EmptyArea } from '../EmptyArea'; import { EmptyAreaWithCTA } from '../EmptyAreaWithCTA'; +import { MatcherFilter } from '../alert-groups/MatcherFilter'; + import { AmRoutesTable } from './AmRoutesTable'; -import { Authorize } from '../../components/Authorize'; -import { contextSrv } from 'app/core/services/context_srv'; -import { getNotificationsPermissions } from '../../utils/access-control'; export interface AmSpecificRoutingProps { alertManagerSourceName: string; diff --git a/public/app/features/alerting/unified/components/amroutes/MuteTimingForm.tsx b/public/app/features/alerting/unified/components/amroutes/MuteTimingForm.tsx index 99f5a6eaf48..49ff77d89d5 100644 --- a/public/app/features/alerting/unified/components/amroutes/MuteTimingForm.tsx +++ b/public/app/features/alerting/unified/components/amroutes/MuteTimingForm.tsx @@ -1,24 +1,27 @@ -import React, { useMemo } from 'react'; -import { AlertingPageWrapper } from '../AlertingPageWrapper'; -import { Alert, Field, FieldSet, Input, Button, LinkButton, useStyles2 } from '@grafana/ui'; -import { FormProvider, useForm } from 'react-hook-form'; -import { GrafanaTheme2 } from '@grafana/data'; -import { useDispatch } from 'react-redux'; import { css } from '@emotion/css'; +import React, { useMemo } from 'react'; +import { FormProvider, useForm } from 'react-hook-form'; +import { useDispatch } from 'react-redux'; + +import { GrafanaTheme2 } from '@grafana/data'; +import { Alert, Field, FieldSet, Input, Button, LinkButton, useStyles2 } from '@grafana/ui'; import { AlertmanagerConfig, AlertManagerCortexConfig, MuteTimeInterval, } from 'app/plugins/datasource/alertmanager/types'; -import { AlertManagerPicker } from '../AlertManagerPicker'; + import { useAlertManagerSourceName } from '../../hooks/useAlertManagerSourceName'; -import { updateAlertManagerConfigAction } from '../../state/actions'; import { useUnifiedAlertingSelector } from '../../hooks/useUnifiedAlertingSelector'; -import { initialAsyncRequestState } from '../../utils/redux'; +import { updateAlertManagerConfigAction } from '../../state/actions'; import { MuteTimingFields } from '../../types/mute-timing-form'; -import { createMuteTiming, defaultTimeInterval } from '../../utils/mute-timings'; -import { makeAMLink } from '../../utils/misc'; import { renameMuteTimings } from '../../utils/alertmanager'; +import { makeAMLink } from '../../utils/misc'; +import { createMuteTiming, defaultTimeInterval } from '../../utils/mute-timings'; +import { initialAsyncRequestState } from '../../utils/redux'; +import { AlertManagerPicker } from '../AlertManagerPicker'; +import { AlertingPageWrapper } from '../AlertingPageWrapper'; + import { MuteTimingTimeInterval } from './MuteTimingTimeInterval'; interface Props { diff --git a/public/app/features/alerting/unified/components/amroutes/MuteTimingTimeInterval.tsx b/public/app/features/alerting/unified/components/amroutes/MuteTimingTimeInterval.tsx index 6d23d6be091..4fab679bafd 100644 --- a/public/app/features/alerting/unified/components/amroutes/MuteTimingTimeInterval.tsx +++ b/public/app/features/alerting/unified/components/amroutes/MuteTimingTimeInterval.tsx @@ -1,10 +1,13 @@ +import { css } from '@emotion/css'; import React from 'react'; +import { useFormContext, useFieldArray } from 'react-hook-form'; + import { GrafanaTheme2 } from '@grafana/data'; import { Button, Input, Field, FieldSet, useStyles2 } from '@grafana/ui'; -import { css } from '@emotion/css'; -import { useFormContext, useFieldArray } from 'react-hook-form'; -import { DAYS_OF_THE_WEEK, MONTHS, validateArrayField, defaultTimeInterval } from '../../utils/mute-timings'; + import { MuteTimingFields } from '../../types/mute-timing-form'; +import { DAYS_OF_THE_WEEK, MONTHS, validateArrayField, defaultTimeInterval } from '../../utils/mute-timings'; + import { MuteTimingTimeRange } from './MuteTimingTimeRange'; export const MuteTimingTimeInterval = () => { diff --git a/public/app/features/alerting/unified/components/amroutes/MuteTimingTimeRange.tsx b/public/app/features/alerting/unified/components/amroutes/MuteTimingTimeRange.tsx index f48490f2263..04cba1844b8 100644 --- a/public/app/features/alerting/unified/components/amroutes/MuteTimingTimeRange.tsx +++ b/public/app/features/alerting/unified/components/amroutes/MuteTimingTimeRange.tsx @@ -1,9 +1,11 @@ +import { css } from '@emotion/css'; import React, { FC } from 'react'; import { useFieldArray, useFormContext } from 'react-hook-form'; -import { MuteTimingFields } from '../../types/mute-timing-form'; -import { Field, InlineFieldRow, InlineField, Input, Button, IconButton, useStyles2 } from '@grafana/ui'; + import { GrafanaTheme2 } from '@grafana/data'; -import { css } from '@emotion/css'; +import { Field, InlineFieldRow, InlineField, Input, Button, IconButton, useStyles2 } from '@grafana/ui'; + +import { MuteTimingFields } from '../../types/mute-timing-form'; interface Props { intervalIndex: number; diff --git a/public/app/features/alerting/unified/components/amroutes/MuteTimingsTable.tsx b/public/app/features/alerting/unified/components/amroutes/MuteTimingsTable.tsx index 04497c62d28..78c7f5bc61b 100644 --- a/public/app/features/alerting/unified/components/amroutes/MuteTimingsTable.tsx +++ b/public/app/features/alerting/unified/components/amroutes/MuteTimingsTable.tsx @@ -1,14 +1,16 @@ -import React, { FC, useMemo, useState } from 'react'; import { css } from '@emotion/css'; +import React, { FC, useMemo, useState } from 'react'; +import { useDispatch } from 'react-redux'; + import { GrafanaTheme2 } from '@grafana/data'; import { IconButton, LinkButton, Link, useStyles2, ConfirmModal } from '@grafana/ui'; +import { contextSrv } from 'app/core/services/context_srv'; import { AlertManagerCortexConfig, MuteTimeInterval, TimeInterval } from 'app/plugins/datasource/alertmanager/types'; -import { useDispatch } from 'react-redux'; + +import { Authorize } from '../../components/Authorize'; import { useUnifiedAlertingSelector } from '../../hooks/useUnifiedAlertingSelector'; import { deleteMuteTimingAction } from '../../state/actions'; -import { makeAMLink } from '../../utils/misc'; -import { AsyncRequestState, initialAsyncRequestState } from '../../utils/redux'; -import { DynamicTable, DynamicTableItemProps, DynamicTableColumnProps } from '../DynamicTable'; +import { getNotificationsPermissions } from '../../utils/access-control'; import { getTimeString, getWeekdayString, @@ -16,10 +18,10 @@ import { getMonthsString, getYearsString, } from '../../utils/alertmanager'; +import { makeAMLink } from '../../utils/misc'; +import { AsyncRequestState, initialAsyncRequestState } from '../../utils/redux'; +import { DynamicTable, DynamicTableItemProps, DynamicTableColumnProps } from '../DynamicTable'; import { EmptyAreaWithCTA } from '../EmptyAreaWithCTA'; -import { Authorize } from '../../components/Authorize'; -import { contextSrv } from 'app/core/services/context_srv'; -import { getNotificationsPermissions } from '../../utils/access-control'; interface Props { alertManagerSourceName: string; diff --git a/public/app/features/alerting/unified/components/amroutes/formStyles.ts b/public/app/features/alerting/unified/components/amroutes/formStyles.ts index 60cde9d1fb9..f61a525c080 100644 --- a/public/app/features/alerting/unified/components/amroutes/formStyles.ts +++ b/public/app/features/alerting/unified/components/amroutes/formStyles.ts @@ -1,4 +1,5 @@ import { css } from '@emotion/css'; + import { GrafanaTheme2 } from '@grafana/data'; export const getFormStyles = (theme: GrafanaTheme2) => { diff --git a/public/app/features/alerting/unified/components/amroutes/gridStyles.ts b/public/app/features/alerting/unified/components/amroutes/gridStyles.ts index 4e39d8c6ac7..b5664624545 100644 --- a/public/app/features/alerting/unified/components/amroutes/gridStyles.ts +++ b/public/app/features/alerting/unified/components/amroutes/gridStyles.ts @@ -1,4 +1,5 @@ import { css } from '@emotion/css'; + import { GrafanaTheme2 } from '@grafana/data'; export const getGridStyles = (theme: GrafanaTheme2) => { diff --git a/public/app/features/alerting/unified/components/panel-alerts-tab/NewRuleFromPanelButton.tsx b/public/app/features/alerting/unified/components/panel-alerts-tab/NewRuleFromPanelButton.tsx index 234dc3c3175..6b500e8ab46 100644 --- a/public/app/features/alerting/unified/components/panel-alerts-tab/NewRuleFromPanelButton.tsx +++ b/public/app/features/alerting/unified/components/panel-alerts-tab/NewRuleFromPanelButton.tsx @@ -1,11 +1,13 @@ -import { DashboardModel, PanelModel } from 'app/features/dashboard/state'; import React, { FC } from 'react'; -import { Alert, LinkButton, Button } from '@grafana/ui'; -import { panelToRuleFormValues } from '../../utils/rule-form'; import { useLocation } from 'react-router-dom'; -import { urlUtil } from '@grafana/data'; import { useAsync } from 'react-use'; +import { urlUtil } from '@grafana/data'; +import { Alert, LinkButton, Button } from '@grafana/ui'; +import { DashboardModel, PanelModel } from 'app/features/dashboard/state'; + +import { panelToRuleFormValues } from '../../utils/rule-form'; + interface Props { panel: PanelModel; dashboard: DashboardModel; diff --git a/public/app/features/alerting/unified/components/receivers/EditReceiverView.tsx b/public/app/features/alerting/unified/components/receivers/EditReceiverView.tsx index a40c90ffdf6..dce13077e0b 100644 --- a/public/app/features/alerting/unified/components/receivers/EditReceiverView.tsx +++ b/public/app/features/alerting/unified/components/receivers/EditReceiverView.tsx @@ -1,7 +1,10 @@ +import React, { FC } from 'react'; + import { InfoBox } from '@grafana/ui'; import { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types'; -import React, { FC } from 'react'; + import { GRAFANA_RULES_SOURCE_NAME } from '../../utils/datasource'; + import { CloudReceiverForm } from './form/CloudReceiverForm'; import { GrafanaReceiverForm } from './form/GrafanaReceiverForm'; diff --git a/public/app/features/alerting/unified/components/receivers/EditTemplateView.tsx b/public/app/features/alerting/unified/components/receivers/EditTemplateView.tsx index 7b337ab61b5..40cbc96628f 100644 --- a/public/app/features/alerting/unified/components/receivers/EditTemplateView.tsx +++ b/public/app/features/alerting/unified/components/receivers/EditTemplateView.tsx @@ -1,6 +1,8 @@ +import React, { FC } from 'react'; + import { InfoBox } from '@grafana/ui'; import { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types'; -import React, { FC } from 'react'; + import { TemplateForm } from './TemplateForm'; interface Props { diff --git a/public/app/features/alerting/unified/components/receivers/GlobalConfigForm.tsx b/public/app/features/alerting/unified/components/receivers/GlobalConfigForm.tsx index b7cdf82c130..2a80517d38a 100644 --- a/public/app/features/alerting/unified/components/receivers/GlobalConfigForm.tsx +++ b/public/app/features/alerting/unified/components/receivers/GlobalConfigForm.tsx @@ -1,18 +1,21 @@ +import { css } from '@emotion/css'; +import React, { FC } from 'react'; +import { useForm, FormProvider } from 'react-hook-form'; +import { useDispatch } from 'react-redux'; + +import { GrafanaTheme2 } from '@grafana/data'; +import { Alert, Button, HorizontalGroup, LinkButton, useStyles2 } from '@grafana/ui'; import { useCleanup } from 'app/core/hooks/useCleanup'; import { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types'; -import React, { FC } from 'react'; + import { useUnifiedAlertingSelector } from '../../hooks/useUnifiedAlertingSelector'; -import { useForm, FormProvider } from 'react-hook-form'; -import { globalConfigOptions } from '../../utils/cloud-alertmanager-notifier-types'; -import { OptionField } from './form/fields/OptionField'; -import { Alert, Button, HorizontalGroup, LinkButton, useStyles2 } from '@grafana/ui'; -import { makeAMLink } from '../../utils/misc'; -import { useDispatch } from 'react-redux'; import { updateAlertManagerConfigAction } from '../../state/actions'; -import { omitEmptyValues } from '../../utils/receiver-form'; -import { css } from '@emotion/css'; -import { GrafanaTheme2 } from '@grafana/data'; +import { globalConfigOptions } from '../../utils/cloud-alertmanager-notifier-types'; import { isVanillaPrometheusAlertManagerDataSource } from '../../utils/datasource'; +import { makeAMLink } from '../../utils/misc'; +import { omitEmptyValues } from '../../utils/receiver-form'; + +import { OptionField } from './form/fields/OptionField'; interface Props { config: AlertManagerCortexConfig; diff --git a/public/app/features/alerting/unified/components/receivers/NewReceiverView.tsx b/public/app/features/alerting/unified/components/receivers/NewReceiverView.tsx index 66a605eb97f..86dfea463e8 100644 --- a/public/app/features/alerting/unified/components/receivers/NewReceiverView.tsx +++ b/public/app/features/alerting/unified/components/receivers/NewReceiverView.tsx @@ -1,6 +1,9 @@ -import { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types'; import React, { FC } from 'react'; + +import { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types'; + import { GRAFANA_RULES_SOURCE_NAME } from '../../utils/datasource'; + import { CloudReceiverForm } from './form/CloudReceiverForm'; import { GrafanaReceiverForm } from './form/GrafanaReceiverForm'; diff --git a/public/app/features/alerting/unified/components/receivers/NewTemplateView.tsx b/public/app/features/alerting/unified/components/receivers/NewTemplateView.tsx index fb529d3427b..a7636dc6a65 100644 --- a/public/app/features/alerting/unified/components/receivers/NewTemplateView.tsx +++ b/public/app/features/alerting/unified/components/receivers/NewTemplateView.tsx @@ -1,5 +1,7 @@ -import { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types'; import React, { FC } from 'react'; + +import { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types'; + import { TemplateForm } from './TemplateForm'; interface Props { diff --git a/public/app/features/alerting/unified/components/receivers/ReceiversAndTemplatesView.tsx b/public/app/features/alerting/unified/components/receivers/ReceiversAndTemplatesView.tsx index 439b851212d..88d4533b8bf 100644 --- a/public/app/features/alerting/unified/components/receivers/ReceiversAndTemplatesView.tsx +++ b/public/app/features/alerting/unified/components/receivers/ReceiversAndTemplatesView.tsx @@ -1,12 +1,15 @@ import { css } from '@emotion/css'; +import React, { FC } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { Alert, LinkButton, useStyles2 } from '@grafana/ui'; import { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types'; import { AccessControlAction } from 'app/types'; -import React, { FC } from 'react'; + import { GRAFANA_RULES_SOURCE_NAME, isVanillaPrometheusAlertManagerDataSource } from '../../utils/datasource'; import { makeAMLink } from '../../utils/misc'; import { Authorize } from '../Authorize'; + import { ReceiversTable } from './ReceiversTable'; import { TemplatesTable } from './TemplatesTable'; diff --git a/public/app/features/alerting/unified/components/receivers/ReceiversSection.tsx b/public/app/features/alerting/unified/components/receivers/ReceiversSection.tsx index 2b5fa298445..93c14ce10cd 100644 --- a/public/app/features/alerting/unified/components/receivers/ReceiversSection.tsx +++ b/public/app/features/alerting/unified/components/receivers/ReceiversSection.tsx @@ -1,9 +1,10 @@ import { css, cx } from '@emotion/css'; -import { GrafanaTheme2 } from '@grafana/data'; -import { Button, useStyles2 } from '@grafana/ui'; import React, { FC } from 'react'; import { Link } from 'react-router-dom'; +import { GrafanaTheme2 } from '@grafana/data'; +import { Button, useStyles2 } from '@grafana/ui'; + interface Props { title: string; description: string; diff --git a/public/app/features/alerting/unified/components/receivers/ReceiversTable.test.tsx b/public/app/features/alerting/unified/components/receivers/ReceiversTable.test.tsx index fa43942699b..3f485589e34 100644 --- a/public/app/features/alerting/unified/components/receivers/ReceiversTable.test.tsx +++ b/public/app/features/alerting/unified/components/receivers/ReceiversTable.test.tsx @@ -1,18 +1,21 @@ -import React from 'react'; import { render } from '@testing-library/react'; +import React from 'react'; +import { Provider } from 'react-redux'; +import { Router } from 'react-router-dom'; +import { byRole } from 'testing-library-selector'; + +import { locationService } from '@grafana/runtime'; import { AlertManagerCortexConfig, GrafanaManagedReceiverConfig, Receiver, } from 'app/plugins/datasource/alertmanager/types'; import { configureStore } from 'app/store/configureStore'; -import { Provider } from 'react-redux'; -import { ReceiversTable } from './ReceiversTable'; -import { fetchGrafanaNotifiersAction } from '../../state/actions'; import { NotifierDTO, NotifierType } from 'app/types'; -import { byRole } from 'testing-library-selector'; -import { Router } from 'react-router-dom'; -import { locationService } from '@grafana/runtime'; + +import { fetchGrafanaNotifiersAction } from '../../state/actions'; + +import { ReceiversTable } from './ReceiversTable'; const renderReceieversTable = async (receivers: Receiver[], notifiers: NotifierDTO[]) => { const config: AlertManagerCortexConfig = { diff --git a/public/app/features/alerting/unified/components/receivers/ReceiversTable.tsx b/public/app/features/alerting/unified/components/receivers/ReceiversTable.tsx index 6a3b6761efa..b0f36628bbe 100644 --- a/public/app/features/alerting/unified/components/receivers/ReceiversTable.tsx +++ b/public/app/features/alerting/unified/components/receivers/ReceiversTable.tsx @@ -1,21 +1,24 @@ -import { Button, ConfirmModal, Modal, useStyles2 } from '@grafana/ui'; -import { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types'; +import { css } from '@emotion/css'; import React, { FC, useMemo, useState } from 'react'; +import { useDispatch } from 'react-redux'; + +import { GrafanaTheme2 } from '@grafana/data'; +import { Button, ConfirmModal, Modal, useStyles2 } from '@grafana/ui'; +import { contextSrv } from 'app/core/services/context_srv'; +import { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types'; + +import { Authorize } from '../../components/Authorize'; import { useUnifiedAlertingSelector } from '../../hooks/useUnifiedAlertingSelector'; +import { deleteReceiverAction } from '../../state/actions'; import { getAlertTableStyles } from '../../styles/table'; +import { getNotificationsPermissions } from '../../utils/access-control'; +import { isReceiverUsed } from '../../utils/alertmanager'; +import { isVanillaPrometheusAlertManagerDataSource } from '../../utils/datasource'; +import { makeAMLink } from '../../utils/misc'; import { extractNotifierTypeCounts } from '../../utils/receivers'; import { ActionIcon } from '../rules/ActionIcon'; + import { ReceiversSection } from './ReceiversSection'; -import { makeAMLink } from '../../utils/misc'; -import { GrafanaTheme2 } from '@grafana/data'; -import { css } from '@emotion/css'; -import { isReceiverUsed } from '../../utils/alertmanager'; -import { useDispatch } from 'react-redux'; -import { deleteReceiverAction } from '../../state/actions'; -import { isVanillaPrometheusAlertManagerDataSource } from '../../utils/datasource'; -import { Authorize } from '../../components/Authorize'; -import { contextSrv } from 'app/core/services/context_srv'; -import { getNotificationsPermissions } from '../../utils/access-control'; interface Props { config: AlertManagerCortexConfig; diff --git a/public/app/features/alerting/unified/components/receivers/TemplateForm.tsx b/public/app/features/alerting/unified/components/receivers/TemplateForm.tsx index 073759a560a..6d66b8ad83f 100644 --- a/public/app/features/alerting/unified/components/receivers/TemplateForm.tsx +++ b/public/app/features/alerting/unified/components/receivers/TemplateForm.tsx @@ -1,11 +1,13 @@ import { css } from '@emotion/css'; +import React, { FC } from 'react'; +import { useForm, Validate } from 'react-hook-form'; +import { useDispatch } from 'react-redux'; + import { GrafanaTheme2 } from '@grafana/data'; import { Alert, Button, Field, Input, LinkButton, TextArea, useStyles2 } from '@grafana/ui'; import { useCleanup } from 'app/core/hooks/useCleanup'; import { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types'; -import React, { FC } from 'react'; -import { useForm, Validate } from 'react-hook-form'; -import { useDispatch } from 'react-redux'; + import { useUnifiedAlertingSelector } from '../../hooks/useUnifiedAlertingSelector'; import { updateAlertManagerConfigAction } from '../../state/actions'; import { makeAMLink } from '../../utils/misc'; diff --git a/public/app/features/alerting/unified/components/receivers/TemplatesTable.tsx b/public/app/features/alerting/unified/components/receivers/TemplatesTable.tsx index b661c350a98..d49e1ab3c7b 100644 --- a/public/app/features/alerting/unified/components/receivers/TemplatesTable.tsx +++ b/public/app/features/alerting/unified/components/receivers/TemplatesTable.tsx @@ -1,17 +1,20 @@ -import { ConfirmModal, useStyles2 } from '@grafana/ui'; -import { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types'; import React, { FC, Fragment, useMemo, useState } from 'react'; +import { useDispatch } from 'react-redux'; + +import { ConfirmModal, useStyles2 } from '@grafana/ui'; +import { contextSrv } from 'app/core/services/context_srv'; +import { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types'; + +import { Authorize } from '../../components/Authorize'; +import { deleteTemplateAction } from '../../state/actions'; import { getAlertTableStyles } from '../../styles/table'; +import { getNotificationsPermissions } from '../../utils/access-control'; +import { makeAMLink } from '../../utils/misc'; import { CollapseToggle } from '../CollapseToggle'; import { DetailsField } from '../DetailsField'; import { ActionIcon } from '../rules/ActionIcon'; + import { ReceiversSection } from './ReceiversSection'; -import { makeAMLink } from '../../utils/misc'; -import { useDispatch } from 'react-redux'; -import { deleteTemplateAction } from '../../state/actions'; -import { contextSrv } from 'app/core/services/context_srv'; -import { Authorize } from '../../components/Authorize'; -import { getNotificationsPermissions } from '../../utils/access-control'; interface Props { config: AlertManagerCortexConfig; diff --git a/public/app/features/alerting/unified/components/receivers/form/ChannelOptions.tsx b/public/app/features/alerting/unified/components/receivers/form/ChannelOptions.tsx index 0e107f86e4c..9ca8b98f086 100644 --- a/public/app/features/alerting/unified/components/receivers/form/ChannelOptions.tsx +++ b/public/app/features/alerting/unified/components/receivers/form/ChannelOptions.tsx @@ -1,10 +1,13 @@ import React from 'react'; -import { Button, Field, Input } from '@grafana/ui'; -import { OptionField } from './fields/OptionField'; -import { ChannelValues, ReceiverFormValues } from '../../../types/receiver-form'; import { useFormContext, FieldError, FieldErrors, DeepMap } from 'react-hook-form'; + +import { Button, Field, Input } from '@grafana/ui'; import { NotificationChannelOption, NotificationChannelSecureFields } from 'app/types'; +import { ChannelValues, ReceiverFormValues } from '../../../types/receiver-form'; + +import { OptionField } from './fields/OptionField'; + export interface Props { defaultValues: R; selectedChannelOptions: NotificationChannelOption[]; diff --git a/public/app/features/alerting/unified/components/receivers/form/ChannelSubForm.tsx b/public/app/features/alerting/unified/components/receivers/form/ChannelSubForm.tsx index b605088aab2..02c2cfc5a6a 100644 --- a/public/app/features/alerting/unified/components/receivers/form/ChannelSubForm.tsx +++ b/public/app/features/alerting/unified/components/receivers/form/ChannelSubForm.tsx @@ -1,13 +1,16 @@ -import { GrafanaTheme2, SelectableValue } from '@grafana/data'; -import { NotifierDTO } from 'app/types'; -import React, { useEffect, useMemo, useState } from 'react'; import { css } from '@emotion/css'; -import { Alert, Button, Field, InputControl, Select, useStyles2 } from '@grafana/ui'; +import React, { useEffect, useMemo, useState } from 'react'; import { useFormContext, FieldErrors } from 'react-hook-form'; + +import { GrafanaTheme2, SelectableValue } from '@grafana/data'; +import { Alert, Button, Field, InputControl, Select, useStyles2 } from '@grafana/ui'; +import { NotifierDTO } from 'app/types'; + +import { useUnifiedAlertingSelector } from '../../../hooks/useUnifiedAlertingSelector'; import { ChannelValues, CommonSettingsComponentType } from '../../../types/receiver-form'; + import { ChannelOptions } from './ChannelOptions'; import { CollapsibleSection } from './CollapsibleSection'; -import { useUnifiedAlertingSelector } from '../../../hooks/useUnifiedAlertingSelector'; interface Props { defaultValues: R; diff --git a/public/app/features/alerting/unified/components/receivers/form/CloudCommonChannelSettings.tsx b/public/app/features/alerting/unified/components/receivers/form/CloudCommonChannelSettings.tsx index 53e48f12c33..fc8c56e5202 100644 --- a/public/app/features/alerting/unified/components/receivers/form/CloudCommonChannelSettings.tsx +++ b/public/app/features/alerting/unified/components/receivers/form/CloudCommonChannelSettings.tsx @@ -1,8 +1,10 @@ -import { Checkbox, Field } from '@grafana/ui'; import React, { FC } from 'react'; -import { CommonSettingsComponentProps } from '../../../types/receiver-form'; import { useFormContext } from 'react-hook-form'; +import { Checkbox, Field } from '@grafana/ui'; + +import { CommonSettingsComponentProps } from '../../../types/receiver-form'; + export const CloudCommonChannelSettings: FC = ({ pathPrefix, className, diff --git a/public/app/features/alerting/unified/components/receivers/form/CloudReceiverForm.tsx b/public/app/features/alerting/unified/components/receivers/form/CloudReceiverForm.tsx index 15c8b97ec1d..1b9bebabbb3 100644 --- a/public/app/features/alerting/unified/components/receivers/form/CloudReceiverForm.tsx +++ b/public/app/features/alerting/unified/components/receivers/form/CloudReceiverForm.tsx @@ -1,7 +1,9 @@ -import { Alert } from '@grafana/ui'; -import { AlertManagerCortexConfig, Receiver } from 'app/plugins/datasource/alertmanager/types'; import React, { FC, useMemo } from 'react'; import { useDispatch } from 'react-redux'; + +import { Alert } from '@grafana/ui'; +import { AlertManagerCortexConfig, Receiver } from 'app/plugins/datasource/alertmanager/types'; + import { updateAlertManagerConfigAction } from '../../../state/actions'; import { CloudChannelValues, ReceiverFormValues, CloudChannelMap } from '../../../types/receiver-form'; import { cloudNotifierTypes } from '../../../utils/cloud-alertmanager-notifier-types'; @@ -12,6 +14,7 @@ import { formValuesToCloudReceiver, updateConfigWithReceiver, } from '../../../utils/receiver-form'; + import { CloudCommonChannelSettings } from './CloudCommonChannelSettings'; import { ReceiverForm } from './ReceiverForm'; diff --git a/public/app/features/alerting/unified/components/receivers/form/CollapsibleSection.tsx b/public/app/features/alerting/unified/components/receivers/form/CollapsibleSection.tsx index ff80c184290..03972c6b410 100644 --- a/public/app/features/alerting/unified/components/receivers/form/CollapsibleSection.tsx +++ b/public/app/features/alerting/unified/components/receivers/form/CollapsibleSection.tsx @@ -1,7 +1,9 @@ import { css, cx } from '@emotion/css'; +import React, { FC, useState } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { IconSize, useStyles2 } from '@grafana/ui'; -import React, { FC, useState } from 'react'; + import { CollapseToggle } from '../../CollapseToggle'; interface Props { diff --git a/public/app/features/alerting/unified/components/receivers/form/GrafanaCommonChannelSettings.tsx b/public/app/features/alerting/unified/components/receivers/form/GrafanaCommonChannelSettings.tsx index 1fa79e294f3..f43af3a100b 100644 --- a/public/app/features/alerting/unified/components/receivers/form/GrafanaCommonChannelSettings.tsx +++ b/public/app/features/alerting/unified/components/receivers/form/GrafanaCommonChannelSettings.tsx @@ -1,8 +1,10 @@ -import { Checkbox, Field } from '@grafana/ui'; import React, { FC } from 'react'; -import { CommonSettingsComponentProps } from '../../../types/receiver-form'; import { useFormContext } from 'react-hook-form'; +import { Checkbox, Field } from '@grafana/ui'; + +import { CommonSettingsComponentProps } from '../../../types/receiver-form'; + export const GrafanaCommonChannelSettings: FC = ({ pathPrefix, className }) => { const { register } = useFormContext(); return ( diff --git a/public/app/features/alerting/unified/components/receivers/form/GrafanaReceiverForm.tsx b/public/app/features/alerting/unified/components/receivers/form/GrafanaReceiverForm.tsx index 36528cebe9d..71eaae86162 100644 --- a/public/app/features/alerting/unified/components/receivers/form/GrafanaReceiverForm.tsx +++ b/public/app/features/alerting/unified/components/receivers/form/GrafanaReceiverForm.tsx @@ -1,3 +1,6 @@ +import React, { FC, useEffect, useMemo, useState } from 'react'; +import { useDispatch } from 'react-redux'; + import { LoadingPlaceholder } from '@grafana/ui'; import { AlertManagerCortexConfig, @@ -5,8 +8,7 @@ import { Receiver, TestReceiversAlert, } from 'app/plugins/datasource/alertmanager/types'; -import React, { FC, useEffect, useMemo, useState } from 'react'; -import { useDispatch } from 'react-redux'; + import { useUnifiedAlertingSelector } from '../../../hooks/useUnifiedAlertingSelector'; import { fetchGrafanaNotifiersAction, @@ -21,6 +23,7 @@ import { grafanaReceiverToFormValues, updateConfigWithReceiver, } from '../../../utils/receiver-form'; + import { GrafanaCommonChannelSettings } from './GrafanaCommonChannelSettings'; import { ReceiverForm } from './ReceiverForm'; import { TestContactPointModal } from './TestContactPointModal'; diff --git a/public/app/features/alerting/unified/components/receivers/form/ReceiverForm.tsx b/public/app/features/alerting/unified/components/receivers/form/ReceiverForm.tsx index 553a6e13c86..bfde9156c91 100644 --- a/public/app/features/alerting/unified/components/receivers/form/ReceiverForm.tsx +++ b/public/app/features/alerting/unified/components/receivers/form/ReceiverForm.tsx @@ -1,19 +1,22 @@ import { css } from '@emotion/css'; +import React, { useCallback } from 'react'; +import { useForm, FormProvider, FieldErrors, Validate } from 'react-hook-form'; + import { GrafanaTheme2 } from '@grafana/data'; import { Alert, Button, Field, Input, LinkButton, useStyles2 } from '@grafana/ui'; +import { useAppNotification } from 'app/core/copy/appNotification'; import { useCleanup } from 'app/core/hooks/useCleanup'; import { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types'; import { NotifierDTO } from 'app/types'; -import React, { useCallback } from 'react'; -import { useForm, FormProvider, FieldErrors, Validate } from 'react-hook-form'; + import { useControlledFieldArray } from '../../../hooks/useControlledFieldArray'; import { useUnifiedAlertingSelector } from '../../../hooks/useUnifiedAlertingSelector'; import { ChannelValues, CommonSettingsComponentType, ReceiverFormValues } from '../../../types/receiver-form'; +import { isVanillaPrometheusAlertManagerDataSource } from '../../../utils/datasource'; import { makeAMLink } from '../../../utils/misc'; + import { ChannelSubForm } from './ChannelSubForm'; import { DeletedSubForm } from './fields/DeletedSubform'; -import { isVanillaPrometheusAlertManagerDataSource } from '../../../utils/datasource'; -import { useAppNotification } from 'app/core/copy/appNotification'; interface Props { config: AlertManagerCortexConfig; diff --git a/public/app/features/alerting/unified/components/receivers/form/TestContactPointModal.tsx b/public/app/features/alerting/unified/components/receivers/form/TestContactPointModal.tsx index 1c580b64902..a552329b90e 100644 --- a/public/app/features/alerting/unified/components/receivers/form/TestContactPointModal.tsx +++ b/public/app/features/alerting/unified/components/receivers/form/TestContactPointModal.tsx @@ -1,12 +1,14 @@ -import React, { useState } from 'react'; -import { Modal, Button, Label, useStyles2, RadioButtonGroup } from '@grafana/ui'; -import { GrafanaTheme2 } from '@grafana/data'; -import { useForm, FormProvider } from 'react-hook-form'; -import { TestReceiversAlert } from 'app/plugins/datasource/alertmanager/types'; import { css } from '@emotion/css'; +import React, { useState } from 'react'; +import { useForm, FormProvider } from 'react-hook-form'; + +import { GrafanaTheme2 } from '@grafana/data'; +import { Modal, Button, Label, useStyles2, RadioButtonGroup } from '@grafana/ui'; +import { TestReceiversAlert } from 'app/plugins/datasource/alertmanager/types'; +import { Annotations, Labels } from 'app/types/unified-alerting-dto'; + import AnnotationsField from '../../rule-editor/AnnotationsField'; import LabelsField from '../../rule-editor/LabelsField'; -import { Annotations, Labels } from 'app/types/unified-alerting-dto'; interface Props { isOpen: boolean; diff --git a/public/app/features/alerting/unified/components/receivers/form/fields/KeyValueMapInput.tsx b/public/app/features/alerting/unified/components/receivers/form/fields/KeyValueMapInput.tsx index 91a5b5e7f86..4bf2dda0b50 100644 --- a/public/app/features/alerting/unified/components/receivers/form/fields/KeyValueMapInput.tsx +++ b/public/app/features/alerting/unified/components/receivers/form/fields/KeyValueMapInput.tsx @@ -1,7 +1,9 @@ -import React, { FC, useEffect, useState } from 'react'; -import { GrafanaTheme2 } from '@grafana/data'; import { css } from '@emotion/css'; +import React, { FC, useEffect, useState } from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; import { Button, Input, useStyles2 } from '@grafana/ui'; + import { ActionIcon } from '../../../rules/ActionIcon'; interface Props { diff --git a/public/app/features/alerting/unified/components/receivers/form/fields/OptionField.tsx b/public/app/features/alerting/unified/components/receivers/form/fields/OptionField.tsx index 4ed2456f06d..f0f12519d6d 100644 --- a/public/app/features/alerting/unified/components/receivers/form/fields/OptionField.tsx +++ b/public/app/features/alerting/unified/components/receivers/form/fields/OptionField.tsx @@ -1,13 +1,15 @@ -import React, { FC, useEffect } from 'react'; -import { Checkbox, Field, Input, InputControl, Select, TextArea } from '@grafana/ui'; -import { isEmpty } from 'lodash'; -import { NotificationChannelOption } from 'app/types'; -import { useFormContext, FieldError, DeepMap } from 'react-hook-form'; -import { SubformField } from './SubformField'; import { css } from '@emotion/css'; +import { isEmpty } from 'lodash'; +import React, { FC, useEffect } from 'react'; +import { useFormContext, FieldError, DeepMap } from 'react-hook-form'; + +import { Checkbox, Field, Input, InputControl, Select, TextArea } from '@grafana/ui'; +import { NotificationChannelOption } from 'app/types'; + import { KeyValueMapInput } from './KeyValueMapInput'; -import { SubformArrayField } from './SubformArrayField'; import { StringArrayInput } from './StringArrayInput'; +import { SubformArrayField } from './SubformArrayField'; +import { SubformField } from './SubformField'; interface Props { defaultValue: any; diff --git a/public/app/features/alerting/unified/components/receivers/form/fields/StringArrayInput.tsx b/public/app/features/alerting/unified/components/receivers/form/fields/StringArrayInput.tsx index 8ff879e9b25..a752fea4482 100644 --- a/public/app/features/alerting/unified/components/receivers/form/fields/StringArrayInput.tsx +++ b/public/app/features/alerting/unified/components/receivers/form/fields/StringArrayInput.tsx @@ -1,7 +1,9 @@ -import React, { FC } from 'react'; -import { GrafanaTheme2 } from '@grafana/data'; import { css } from '@emotion/css'; +import React, { FC } from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; import { Button, Input, useStyles2 } from '@grafana/ui'; + import { ActionIcon } from '../../../rules/ActionIcon'; interface Props { diff --git a/public/app/features/alerting/unified/components/receivers/form/fields/SubformArrayField.tsx b/public/app/features/alerting/unified/components/receivers/form/fields/SubformArrayField.tsx index 935118e7594..103b35f8563 100644 --- a/public/app/features/alerting/unified/components/receivers/form/fields/SubformArrayField.tsx +++ b/public/app/features/alerting/unified/components/receivers/form/fields/SubformArrayField.tsx @@ -1,11 +1,14 @@ import React, { FC } from 'react'; -import { NotificationChannelOption } from 'app/types'; import { FieldError, DeepMap, useFormContext } from 'react-hook-form'; + import { Button, useStyles2 } from '@grafana/ui'; -import { CollapsibleSection } from '../CollapsibleSection'; -import { ActionIcon } from '../../../rules/ActionIcon'; -import { OptionField } from './OptionField'; import { useControlledFieldArray } from 'app/features/alerting/unified/hooks/useControlledFieldArray'; +import { NotificationChannelOption } from 'app/types'; + +import { ActionIcon } from '../../../rules/ActionIcon'; +import { CollapsibleSection } from '../CollapsibleSection'; + +import { OptionField } from './OptionField'; import { getReceiverFormFieldStyles } from './styles'; interface Props { diff --git a/public/app/features/alerting/unified/components/receivers/form/fields/SubformField.tsx b/public/app/features/alerting/unified/components/receivers/form/fields/SubformField.tsx index 7707b9f4e99..626c859cb57 100644 --- a/public/app/features/alerting/unified/components/receivers/form/fields/SubformField.tsx +++ b/public/app/features/alerting/unified/components/receivers/form/fields/SubformField.tsx @@ -1,9 +1,12 @@ import React, { FC, useState } from 'react'; -import { NotificationChannelOption } from 'app/types'; import { FieldError, DeepMap, useFormContext } from 'react-hook-form'; -import { OptionField } from './OptionField'; + import { Button, useStyles2 } from '@grafana/ui'; +import { NotificationChannelOption } from 'app/types'; + import { ActionIcon } from '../../../rules/ActionIcon'; + +import { OptionField } from './OptionField'; import { getReceiverFormFieldStyles } from './styles'; interface Props { diff --git a/public/app/features/alerting/unified/components/receivers/form/fields/styles.ts b/public/app/features/alerting/unified/components/receivers/form/fields/styles.ts index 28709bf3223..baae5279258 100644 --- a/public/app/features/alerting/unified/components/receivers/form/fields/styles.ts +++ b/public/app/features/alerting/unified/components/receivers/form/fields/styles.ts @@ -1,6 +1,7 @@ -import { GrafanaTheme2 } from '@grafana/data'; import { css } from '@emotion/css'; +import { GrafanaTheme2 } from '@grafana/data'; + export const getReceiverFormFieldStyles = (theme: GrafanaTheme2) => ({ collapsibleSection: css` margin: 0; diff --git a/public/app/features/alerting/unified/components/rule-editor/AlertRuleForm.tsx b/public/app/features/alerting/unified/components/rule-editor/AlertRuleForm.tsx index ee51d1bba84..cd536a9f80b 100644 --- a/public/app/features/alerting/unified/components/rule-editor/AlertRuleForm.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/AlertRuleForm.tsx @@ -1,28 +1,28 @@ +import { css } from '@emotion/css'; import React, { FC, useMemo, useState } from 'react'; +import { useForm, FormProvider, UseFormWatch } from 'react-hook-form'; +import { useDispatch } from 'react-redux'; +import { Link } from 'react-router-dom'; + import { GrafanaTheme2 } from '@grafana/data'; import { PageToolbar, Button, useStyles2, CustomScrollbar, Spinner, ConfirmModal } from '@grafana/ui'; -import { css } from '@emotion/css'; +import { useAppNotification } from 'app/core/copy/appNotification'; +import { useCleanup } from 'app/core/hooks/useCleanup'; +import { useQueryParams } from 'app/core/hooks/useQueryParams'; +import { RuleWithLocation } from 'app/types/unified-alerting'; + +import { useUnifiedAlertingSelector } from '../../hooks/useUnifiedAlertingSelector'; +import { deleteRuleAction, saveRuleFormAction } from '../../state/actions'; +import { RuleFormType, RuleFormValues } from '../../types/rule-form'; +import { initialAsyncRequestState } from '../../utils/redux'; +import { rulerRuleToFormValues, getDefaultFormValues, getDefaultQueries } from '../../utils/rule-form'; +import * as ruleId from '../../utils/rule-id'; import { AlertTypeStep } from './AlertTypeStep'; -import { DetailsStep } from './DetailsStep'; -import { QueryStep } from './QueryStep'; -import { useForm, FormProvider, UseFormWatch } from 'react-hook-form'; - -import { RuleFormType, RuleFormValues } from '../../types/rule-form'; -import { useUnifiedAlertingSelector } from '../../hooks/useUnifiedAlertingSelector'; -import { initialAsyncRequestState } from '../../utils/redux'; -import { deleteRuleAction, saveRuleFormAction } from '../../state/actions'; -import { RuleWithLocation } from 'app/types/unified-alerting'; -import { useDispatch } from 'react-redux'; -import { useCleanup } from 'app/core/hooks/useCleanup'; -import { rulerRuleToFormValues, getDefaultFormValues, getDefaultQueries } from '../../utils/rule-form'; -import { Link } from 'react-router-dom'; -import { useQueryParams } from 'app/core/hooks/useQueryParams'; -import { useAppNotification } from 'app/core/copy/appNotification'; - import { CloudConditionsStep } from './CloudConditionsStep'; +import { DetailsStep } from './DetailsStep'; import { GrafanaConditionsStep } from './GrafanaConditionsStep'; -import * as ruleId from '../../utils/rule-id'; +import { QueryStep } from './QueryStep'; import { RuleInspector } from './RuleInspector'; type Props = { diff --git a/public/app/features/alerting/unified/components/rule-editor/AlertTypeStep.test.tsx b/public/app/features/alerting/unified/components/rule-editor/AlertTypeStep.test.tsx index aee2d02d774..8ddf07be1c1 100644 --- a/public/app/features/alerting/unified/components/rule-editor/AlertTypeStep.test.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/AlertTypeStep.test.tsx @@ -1,11 +1,13 @@ import { render } from '@testing-library/react'; -import { contextSrv } from 'app/core/services/context_srv'; -import { configureStore } from 'app/store/configureStore'; -import { AccessControlAction } from 'app/types'; import React from 'react'; import { FormProvider, useForm } from 'react-hook-form'; import { Provider } from 'react-redux'; import { byText } from 'testing-library-selector'; + +import { contextSrv } from 'app/core/services/context_srv'; +import { configureStore } from 'app/store/configureStore'; +import { AccessControlAction } from 'app/types'; + import { AlertTypeStep } from './AlertTypeStep'; const ui = { diff --git a/public/app/features/alerting/unified/components/rule-editor/AlertTypeStep.tsx b/public/app/features/alerting/unified/components/rule-editor/AlertTypeStep.tsx index 5a926a0a3f0..e1d6963590b 100644 --- a/public/app/features/alerting/unified/components/rule-editor/AlertTypeStep.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/AlertTypeStep.tsx @@ -1,18 +1,21 @@ -import React, { FC } from 'react'; -import { DataSourceInstanceSettings, GrafanaTheme2 } from '@grafana/data'; -import { Field, Icon, Input, InputControl, Label, Tooltip, useStyles2 } from '@grafana/ui'; import { css } from '@emotion/css'; -import { RuleEditorSection } from './RuleEditorSection'; +import React, { FC } from 'react'; import { useFormContext } from 'react-hook-form'; -import { RuleFormType, RuleFormValues } from '../../types/rule-form'; -import { Folder, RuleFolderPicker } from './RuleFolderPicker'; -import { GroupAndNamespaceFields } from './GroupAndNamespaceFields'; -import { CloudRulesSourcePicker } from './CloudRulesSourcePicker'; -import { checkForPathSeparator } from './util'; -import { RuleTypePicker } from './rule-types/RuleTypePicker'; + +import { DataSourceInstanceSettings, GrafanaTheme2 } from '@grafana/data'; +import { Stack } from '@grafana/experimental'; +import { Field, Icon, Input, InputControl, Label, Tooltip, useStyles2 } from '@grafana/ui'; import { contextSrv } from 'app/core/services/context_srv'; import { AccessControlAction } from 'app/types'; -import { Stack } from '@grafana/experimental'; + +import { RuleFormType, RuleFormValues } from '../../types/rule-form'; + +import { CloudRulesSourcePicker } from './CloudRulesSourcePicker'; +import { GroupAndNamespaceFields } from './GroupAndNamespaceFields'; +import { RuleEditorSection } from './RuleEditorSection'; +import { Folder, RuleFolderPicker } from './RuleFolderPicker'; +import { RuleTypePicker } from './rule-types/RuleTypePicker'; +import { checkForPathSeparator } from './util'; interface Props { editingExistingRule: boolean; diff --git a/public/app/features/alerting/unified/components/rule-editor/AnnotationKeyInput.tsx b/public/app/features/alerting/unified/components/rule-editor/AnnotationKeyInput.tsx index 7451454b145..f9c433ce397 100644 --- a/public/app/features/alerting/unified/components/rule-editor/AnnotationKeyInput.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/AnnotationKeyInput.tsx @@ -1,8 +1,11 @@ -import { SelectableValue } from '@grafana/data'; import React, { FC, useMemo } from 'react'; -import { SelectWithAdd } from './SelectWIthAdd'; + +import { SelectableValue } from '@grafana/data'; + import { Annotation, annotationLabels } from '../../utils/constants'; +import { SelectWithAdd } from './SelectWIthAdd'; + interface Props { onChange: (value: string) => void; existingKeys: string[]; diff --git a/public/app/features/alerting/unified/components/rule-editor/AnnotationsField.tsx b/public/app/features/alerting/unified/components/rule-editor/AnnotationsField.tsx index da1b3aef463..1fce0edf88e 100644 --- a/public/app/features/alerting/unified/components/rule-editor/AnnotationsField.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/AnnotationsField.tsx @@ -1,9 +1,12 @@ -import React, { FC, useCallback } from 'react'; -import { Button, Field, FieldArray, Input, InputControl, Label, TextArea, useStyles } from '@grafana/ui'; -import { GrafanaTheme } from '@grafana/data'; import { css, cx } from '@emotion/css'; +import React, { FC, useCallback } from 'react'; import { useFormContext } from 'react-hook-form'; + +import { GrafanaTheme } from '@grafana/data'; +import { Button, Field, FieldArray, Input, InputControl, Label, TextArea, useStyles } from '@grafana/ui'; + import { RuleFormValues } from '../../types/rule-form'; + import { AnnotationKeyInput } from './AnnotationKeyInput'; const AnnotationsField: FC = () => { diff --git a/public/app/features/alerting/unified/components/rule-editor/CloudConditionsStep.tsx b/public/app/features/alerting/unified/components/rule-editor/CloudConditionsStep.tsx index 91cc9fcc1d4..3323d9b4c15 100644 --- a/public/app/features/alerting/unified/components/rule-editor/CloudConditionsStep.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/CloudConditionsStep.tsx @@ -1,12 +1,15 @@ -import React, { FC } from 'react'; import { css } from '@emotion/css'; +import React, { FC } from 'react'; +import { useFormContext } from 'react-hook-form'; + import { GrafanaTheme } from '@grafana/data'; import { Field, Input, InputControl, Select, useStyles } from '@grafana/ui'; -import { useFormContext } from 'react-hook-form'; + import { RuleFormType, RuleFormValues } from '../../types/rule-form'; import { timeOptions } from '../../utils/time'; -import { RuleEditorSection } from './RuleEditorSection'; + import { PreviewRule } from './PreviewRule'; +import { RuleEditorSection } from './RuleEditorSection'; export const CloudConditionsStep: FC = () => { const styles = useStyles(getStyles); diff --git a/public/app/features/alerting/unified/components/rule-editor/CloudRulesSourcePicker.tsx b/public/app/features/alerting/unified/components/rule-editor/CloudRulesSourcePicker.tsx index 7668d836af3..b995cdfdd49 100644 --- a/public/app/features/alerting/unified/components/rule-editor/CloudRulesSourcePicker.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/CloudRulesSourcePicker.tsx @@ -1,6 +1,8 @@ import React, { useCallback } from 'react'; + import { DataSourceInstanceSettings } from '@grafana/data'; import { DataSourcePicker } from '@grafana/runtime'; + import { useRulesSourcesWithRuler } from '../../hooks/useRuleSourcesWithRuler'; interface Props { diff --git a/public/app/features/alerting/unified/components/rule-editor/ConditionField.tsx b/public/app/features/alerting/unified/components/rule-editor/ConditionField.tsx index f4341f35132..9c45e41bf51 100644 --- a/public/app/features/alerting/unified/components/rule-editor/ConditionField.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/ConditionField.tsx @@ -1,8 +1,10 @@ +import React, { FC, useEffect, useMemo } from 'react'; +import { useFormContext } from 'react-hook-form'; + import { SelectableValue } from '@grafana/data'; import { Field, InputControl, Select } from '@grafana/ui'; import { ExpressionDatasourceUID } from 'app/features/expressions/ExpressionDatasource'; -import React, { FC, useEffect, useMemo } from 'react'; -import { useFormContext } from 'react-hook-form'; + import { RuleFormValues } from '../../types/rule-form'; export const ConditionField: FC = () => { diff --git a/public/app/features/alerting/unified/components/rule-editor/DetailsStep.tsx b/public/app/features/alerting/unified/components/rule-editor/DetailsStep.tsx index 2f727086285..6cecff78b31 100644 --- a/public/app/features/alerting/unified/components/rule-editor/DetailsStep.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/DetailsStep.tsx @@ -1,10 +1,12 @@ import React, { FC } from 'react'; -import LabelsField from './LabelsField'; -import AnnotationsField from './AnnotationsField'; -import { RuleEditorSection } from './RuleEditorSection'; import { useFormContext } from 'react-hook-form'; + import { RuleFormType, RuleFormValues } from '../../types/rule-form'; +import AnnotationsField from './AnnotationsField'; +import LabelsField from './LabelsField'; +import { RuleEditorSection } from './RuleEditorSection'; + export const DetailsStep: FC = () => { const { watch } = useFormContext(); diff --git a/public/app/features/alerting/unified/components/rule-editor/ExpressionEditor.tsx b/public/app/features/alerting/unified/components/rule-editor/ExpressionEditor.tsx index 626e1f58114..e17ce8b6c6a 100644 --- a/public/app/features/alerting/unified/components/rule-editor/ExpressionEditor.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/ExpressionEditor.tsx @@ -1,10 +1,11 @@ -import React, { FC, useCallback, useMemo, useState } from 'react'; import { noop } from 'lodash'; +import React, { FC, useCallback, useMemo, useState } from 'react'; +import { useAsync } from 'react-use'; + import { CoreApp, DataQuery } from '@grafana/data'; import { getDataSourceSrv } from '@grafana/runtime'; -import { useAsync } from 'react-use'; -import { PromQuery } from 'app/plugins/datasource/prometheus/types'; import { LokiQuery } from 'app/plugins/datasource/loki/types'; +import { PromQuery } from 'app/plugins/datasource/prometheus/types'; export interface ExpressionEditorProps { value?: string; diff --git a/public/app/features/alerting/unified/components/rule-editor/GrafanaAlertStatePicker.tsx b/public/app/features/alerting/unified/components/rule-editor/GrafanaAlertStatePicker.tsx index 42eab78203a..664306d2a34 100644 --- a/public/app/features/alerting/unified/components/rule-editor/GrafanaAlertStatePicker.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/GrafanaAlertStatePicker.tsx @@ -1,8 +1,9 @@ +import React, { FC, useMemo } from 'react'; + import { SelectableValue } from '@grafana/data'; import { Select } from '@grafana/ui'; import { SelectBaseProps } from '@grafana/ui/src/components/Select/types'; import { GrafanaAlertStateDecision } from 'app/types/unified-alerting-dto'; -import React, { FC, useMemo } from 'react'; type Props = Omit, 'options'> & { includeNoData: boolean; diff --git a/public/app/features/alerting/unified/components/rule-editor/GrafanaConditionEvalWarning.tsx b/public/app/features/alerting/unified/components/rule-editor/GrafanaConditionEvalWarning.tsx index a51b350516c..0de1c1d6122 100644 --- a/public/app/features/alerting/unified/components/rule-editor/GrafanaConditionEvalWarning.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/GrafanaConditionEvalWarning.tsx @@ -1,8 +1,10 @@ -import { durationToMilliseconds, parseDuration } from '@grafana/data'; -import { Alert } from '@grafana/ui'; import { isEmpty } from 'lodash'; import React, { FC } from 'react'; import { useFormContext } from 'react-hook-form'; + +import { durationToMilliseconds, parseDuration } from '@grafana/data'; +import { Alert } from '@grafana/ui'; + import { RuleFormValues } from '../../types/rule-form'; // a warning that will be shown if a problematic yet technically valid combination of "evaluate every" and "evaluate for" is enetered diff --git a/public/app/features/alerting/unified/components/rule-editor/GrafanaConditionsStep.tsx b/public/app/features/alerting/unified/components/rule-editor/GrafanaConditionsStep.tsx index 782b18d8887..f5cd8533662 100644 --- a/public/app/features/alerting/unified/components/rule-editor/GrafanaConditionsStep.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/GrafanaConditionsStep.tsx @@ -1,16 +1,19 @@ -import React, { FC, useState } from 'react'; import { css } from '@emotion/css'; +import React, { FC, useState } from 'react'; +import { useFormContext, RegisterOptions } from 'react-hook-form'; + import { parseDuration, durationToMilliseconds, GrafanaTheme2 } from '@grafana/data'; import { Field, InlineLabel, Input, InputControl, useStyles2 } from '@grafana/ui'; -import { useFormContext, RegisterOptions } from 'react-hook-form'; + import { RuleFormValues } from '../../types/rule-form'; import { positiveDurationValidationPattern, durationValidationPattern } from '../../utils/time'; +import { CollapseToggle } from '../CollapseToggle'; + import { ConditionField } from './ConditionField'; import { GrafanaAlertStatePicker } from './GrafanaAlertStatePicker'; -import { RuleEditorSection } from './RuleEditorSection'; -import { PreviewRule } from './PreviewRule'; import { GrafanaConditionEvalWarning } from './GrafanaConditionEvalWarning'; -import { CollapseToggle } from '../CollapseToggle'; +import { PreviewRule } from './PreviewRule'; +import { RuleEditorSection } from './RuleEditorSection'; const MIN_TIME_RANGE_STEP_S = 10; // 10 seconds diff --git a/public/app/features/alerting/unified/components/rule-editor/GroupAndNamespaceFields.tsx b/public/app/features/alerting/unified/components/rule-editor/GroupAndNamespaceFields.tsx index 16cb1fa0ac4..149cfb2361f 100644 --- a/public/app/features/alerting/unified/components/rule-editor/GroupAndNamespaceFields.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/GroupAndNamespaceFields.tsx @@ -1,13 +1,16 @@ +import { css } from '@emotion/css'; import React, { FC, useEffect, useMemo, useState } from 'react'; +import { useFormContext } from 'react-hook-form'; import { useDispatch } from 'react-redux'; + +import { GrafanaTheme2, SelectableValue } from '@grafana/data'; +import { Field, InputControl, useStyles2 } from '@grafana/ui'; + import { useUnifiedAlertingSelector } from '../../hooks/useUnifiedAlertingSelector'; import { fetchRulerRulesAction } from '../../state/actions'; import { RuleFormValues } from '../../types/rule-form'; -import { useFormContext } from 'react-hook-form'; -import { GrafanaTheme2, SelectableValue } from '@grafana/data'; + import { SelectWithAdd } from './SelectWIthAdd'; -import { Field, InputControl, useStyles2 } from '@grafana/ui'; -import { css } from '@emotion/css'; import { checkForPathSeparator } from './util'; interface Props { diff --git a/public/app/features/alerting/unified/components/rule-editor/LabelsField.tsx b/public/app/features/alerting/unified/components/rule-editor/LabelsField.tsx index d6e764bc1c3..34eb8cbebe8 100644 --- a/public/app/features/alerting/unified/components/rule-editor/LabelsField.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/LabelsField.tsx @@ -1,9 +1,10 @@ -import React, { FC } from 'react'; -import { Button, Field, FieldArray, Input, InlineLabel, Label, useStyles } from '@grafana/ui'; -import { GrafanaTheme } from '@grafana/data'; import { css, cx } from '@emotion/css'; +import React, { FC } from 'react'; import { useFormContext } from 'react-hook-form'; +import { GrafanaTheme } from '@grafana/data'; +import { Button, Field, FieldArray, Input, InlineLabel, Label, useStyles } from '@grafana/ui'; + interface Props { className?: string; } diff --git a/public/app/features/alerting/unified/components/rule-editor/PreviewRule.tsx b/public/app/features/alerting/unified/components/rule-editor/PreviewRule.tsx index 4b2bf6a9510..8ff4bbb30da 100644 --- a/public/app/features/alerting/unified/components/rule-editor/PreviewRule.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/PreviewRule.tsx @@ -1,14 +1,17 @@ import { css } from '@emotion/css'; -import { dateTimeFormatISO, GrafanaTheme2, LoadingState } from '@grafana/data'; -import { Alert, Button, HorizontalGroup, useStyles2 } from '@grafana/ui'; import React, { useCallback, useState } from 'react'; import { useFormContext } from 'react-hook-form'; import { useMountedState } from 'react-use'; import { takeWhile } from 'rxjs/operators'; + +import { dateTimeFormatISO, GrafanaTheme2, LoadingState } from '@grafana/data'; +import { Alert, Button, HorizontalGroup, useStyles2 } from '@grafana/ui'; + import { previewAlertRule } from '../../api/preview'; import { useAlertQueriesStatus } from '../../hooks/useAlertQueriesStatus'; import { PreviewRuleRequest, PreviewRuleResponse } from '../../types/preview'; import { RuleFormType, RuleFormValues } from '../../types/rule-form'; + import { PreviewRuleResult } from './PreviewRuleResult'; const fields: Array = ['type', 'dataSourceName', 'condition', 'queries', 'expression']; diff --git a/public/app/features/alerting/unified/components/rule-editor/PreviewRuleResult.tsx b/public/app/features/alerting/unified/components/rule-editor/PreviewRuleResult.tsx index 0e77dbe8e67..94b22e376b9 100644 --- a/public/app/features/alerting/unified/components/rule-editor/PreviewRuleResult.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/PreviewRuleResult.tsx @@ -1,9 +1,11 @@ -import React from 'react'; import { css } from '@emotion/css'; +import React from 'react'; import AutoSizer from 'react-virtualized-auto-sizer'; -import { TableCellDisplayMode, useStyles2 } from '@grafana/ui'; -import { PanelRenderer } from '@grafana/runtime'; + import { FieldConfigSource, FieldMatcherID, GrafanaTheme2, LoadingState } from '@grafana/data'; +import { PanelRenderer } from '@grafana/runtime'; +import { TableCellDisplayMode, useStyles2 } from '@grafana/ui'; + import { PreviewRuleResponse } from '../../types/preview'; import { RuleFormType } from '../../types/rule-form'; import { messageFromError } from '../../utils/redux'; diff --git a/public/app/features/alerting/unified/components/rule-editor/QueryEditor.tsx b/public/app/features/alerting/unified/components/rule-editor/QueryEditor.tsx index 3eb91a9d545..66226f41c57 100644 --- a/public/app/features/alerting/unified/components/rule-editor/QueryEditor.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/QueryEditor.tsx @@ -1,5 +1,6 @@ -import React, { PureComponent } from 'react'; import { css } from '@emotion/css'; +import React, { PureComponent } from 'react'; + import { DataQuery, getDefaultRelativeTimeRange, @@ -9,20 +10,22 @@ import { RelativeTimeRange, } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; -import { Button, HorizontalGroup, stylesFactory } from '@grafana/ui'; import { config } from '@grafana/runtime'; -import { QueryRows } from './QueryRows'; +import { Button, HorizontalGroup, stylesFactory } from '@grafana/ui'; +import { getNextRefIdChar } from 'app/core/utils/query'; import { dataSource as expressionDatasource, ExpressionDatasourceUID, } from 'app/features/expressions/ExpressionDatasource'; -import { getNextRefIdChar } from 'app/core/utils/query'; -import { defaultCondition } from 'app/features/expressions/utils/expressionTypes'; -import { ExpressionQueryType } from 'app/features/expressions/types'; -import { AlertQuery } from 'app/types/unified-alerting-dto'; -import { AlertingQueryRunner } from '../../state/AlertingQueryRunner'; -import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; import { isExpressionQuery } from 'app/features/expressions/guards'; +import { ExpressionQueryType } from 'app/features/expressions/types'; +import { defaultCondition } from 'app/features/expressions/utils/expressionTypes'; +import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; +import { AlertQuery } from 'app/types/unified-alerting-dto'; + +import { AlertingQueryRunner } from '../../state/AlertingQueryRunner'; + +import { QueryRows } from './QueryRows'; interface Props { value?: AlertQuery[]; diff --git a/public/app/features/alerting/unified/components/rule-editor/QueryRows.tsx b/public/app/features/alerting/unified/components/rule-editor/QueryRows.tsx index d6d7a653dc4..17a7140bc80 100644 --- a/public/app/features/alerting/unified/components/rule-editor/QueryRows.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/QueryRows.tsx @@ -1,5 +1,7 @@ +import { omit } from 'lodash'; import React, { PureComponent, useState } from 'react'; import { DragDropContext, Droppable, DropResult } from 'react-beautiful-dnd'; + import { DataQuery, DataSourceInstanceSettings, @@ -10,14 +12,14 @@ import { ThresholdsMode, } from '@grafana/data'; import { config, getDataSourceSrv } from '@grafana/runtime'; -import { EmptyQueryWrapper, QueryWrapper } from './QueryWrapper'; -import { AlertDataQuery, AlertQuery } from 'app/types/unified-alerting-dto'; -import { isExpressionQuery } from 'app/features/expressions/guards'; -import { queriesWithUpdatedReferences } from './util'; import { Button, Card, Icon } from '@grafana/ui'; import { QueryOperationRow } from 'app/core/components/QueryOperationRow/QueryOperationRow'; +import { isExpressionQuery } from 'app/features/expressions/guards'; import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; -import { omit } from 'lodash'; +import { AlertDataQuery, AlertQuery } from 'app/types/unified-alerting-dto'; + +import { EmptyQueryWrapper, QueryWrapper } from './QueryWrapper'; +import { queriesWithUpdatedReferences } from './util'; interface Props { // The query configuration diff --git a/public/app/features/alerting/unified/components/rule-editor/QueryStep.tsx b/public/app/features/alerting/unified/components/rule-editor/QueryStep.tsx index e55f4d5d549..3f896e9a18e 100644 --- a/public/app/features/alerting/unified/components/rule-editor/QueryStep.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/QueryStep.tsx @@ -1,10 +1,13 @@ import React, { FC } from 'react'; import { useFormContext } from 'react-hook-form'; + import { Field, InputControl } from '@grafana/ui'; -import { ExpressionEditor } from './ExpressionEditor'; -import { RuleEditorSection } from './RuleEditorSection'; + import { RuleFormType, RuleFormValues } from '../../types/rule-form'; + +import { ExpressionEditor } from './ExpressionEditor'; import { QueryEditor } from './QueryEditor'; +import { RuleEditorSection } from './RuleEditorSection'; export const QueryStep: FC = () => { const { diff --git a/public/app/features/alerting/unified/components/rule-editor/QueryWrapper.tsx b/public/app/features/alerting/unified/components/rule-editor/QueryWrapper.tsx index 5c7148e77ee..8a95fa6087c 100644 --- a/public/app/features/alerting/unified/components/rule-editor/QueryWrapper.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/QueryWrapper.tsx @@ -1,6 +1,7 @@ -import React, { FC, ReactNode, useState } from 'react'; import { css } from '@emotion/css'; import { cloneDeep } from 'lodash'; +import React, { FC, ReactNode, useState } from 'react'; + import { CoreApp, DataQuery, @@ -13,12 +14,14 @@ import { ThresholdsConfig, } from '@grafana/data'; import { RelativeTimeRangePicker, useStyles2 } from '@grafana/ui'; -import { QueryEditorRow } from 'app/features/query/components/QueryEditorRow'; -import { VizWrapper } from './VizWrapper'; import { isExpressionQuery } from 'app/features/expressions/guards'; +import { QueryEditorRow } from 'app/features/query/components/QueryEditorRow'; +import { AlertQuery } from 'app/types/unified-alerting-dto'; + import { TABLE, TIMESERIES } from '../../utils/constants'; import { SupportedPanelPlugins } from '../PanelPluginsButtonGroup'; -import { AlertQuery } from 'app/types/unified-alerting-dto'; + +import { VizWrapper } from './VizWrapper'; interface Props { data: PanelData; diff --git a/public/app/features/alerting/unified/components/rule-editor/RuleEditorSection.tsx b/public/app/features/alerting/unified/components/rule-editor/RuleEditorSection.tsx index 220e314cd76..23943eb4034 100644 --- a/public/app/features/alerting/unified/components/rule-editor/RuleEditorSection.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/RuleEditorSection.tsx @@ -1,7 +1,8 @@ import { css } from '@emotion/css'; +import React, { FC } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { FieldSet, useStyles2 } from '@grafana/ui'; -import React, { FC } from 'react'; export interface RuleEditorSectionProps { title: string; diff --git a/public/app/features/alerting/unified/components/rule-editor/RuleFolderPicker.tsx b/public/app/features/alerting/unified/components/rule-editor/RuleFolderPicker.tsx index c608bec4b64..1e65372a238 100644 --- a/public/app/features/alerting/unified/components/rule-editor/RuleFolderPicker.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/RuleFolderPicker.tsx @@ -1,4 +1,5 @@ import React, { FC } from 'react'; + import { FolderPicker, Props as FolderPickerProps } from 'app/core/components/Select/FolderPicker'; export interface Folder { diff --git a/public/app/features/alerting/unified/components/rule-editor/RuleInspector.tsx b/public/app/features/alerting/unified/components/rule-editor/RuleInspector.tsx index 02803227f10..1b50995dc61 100644 --- a/public/app/features/alerting/unified/components/rule-editor/RuleInspector.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/RuleInspector.tsx @@ -1,10 +1,12 @@ +import { css } from '@emotion/css'; +import { dump, load } from 'js-yaml'; import React, { FC, useState } from 'react'; import { useFormContext } from 'react-hook-form'; -import { dump, load } from 'js-yaml'; -import { css } from '@emotion/css'; import AutoSizer from 'react-virtualized-auto-sizer'; + import { GrafanaTheme2 } from '@grafana/data'; import { Button, CodeEditor, Drawer, Tab, TabsBar, useStyles2 } from '@grafana/ui'; + import { RuleFormValues } from '../../types/rule-form'; interface Props { diff --git a/public/app/features/alerting/unified/components/rule-editor/SelectWIthAdd.tsx b/public/app/features/alerting/unified/components/rule-editor/SelectWIthAdd.tsx index 2c99cf8add0..056310630b0 100644 --- a/public/app/features/alerting/unified/components/rule-editor/SelectWIthAdd.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/SelectWIthAdd.tsx @@ -1,6 +1,7 @@ +import React, { FC, useEffect, useMemo, useState } from 'react'; + import { SelectableValue } from '@grafana/data'; import { Input, Select } from '@grafana/ui'; -import React, { FC, useEffect, useMemo, useState } from 'react'; interface Props { onChange: (value: string) => void; diff --git a/public/app/features/alerting/unified/components/rule-editor/VizWrapper.tsx b/public/app/features/alerting/unified/components/rule-editor/VizWrapper.tsx index d826ec6439f..09541382bcd 100644 --- a/public/app/features/alerting/unified/components/rule-editor/VizWrapper.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/VizWrapper.tsx @@ -1,14 +1,16 @@ +import { css } from '@emotion/css'; import React, { FC, useEffect, useMemo, useState } from 'react'; import AutoSizer from 'react-virtualized-auto-sizer'; -import { css } from '@emotion/css'; + import { FieldConfigSource, GrafanaTheme2, PanelData, ThresholdsConfig } from '@grafana/data'; import { PanelRenderer } from '@grafana/runtime'; -import { PanelContext, PanelContextProvider, useStyles2 } from '@grafana/ui'; import { GraphFieldConfig, GraphTresholdsStyleMode } from '@grafana/schema'; +import { PanelContext, PanelContextProvider, useStyles2 } from '@grafana/ui'; +import appEvents from 'app/core/app_events'; import { PanelOptions } from 'app/plugins/panel/table/models.gen'; + import { useVizHeight } from '../../hooks/useVizHeight'; import { SupportedPanelPlugins, PanelPluginsButtonGroup } from '../PanelPluginsButtonGroup'; -import appEvents from 'app/core/app_events'; interface Props { data: PanelData; diff --git a/public/app/features/alerting/unified/components/rule-editor/rule-types/DisabledTooltip.tsx b/public/app/features/alerting/unified/components/rule-editor/rule-types/DisabledTooltip.tsx index 25110586a46..db6699e4617 100644 --- a/public/app/features/alerting/unified/components/rule-editor/rule-types/DisabledTooltip.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/rule-types/DisabledTooltip.tsx @@ -1,4 +1,5 @@ import React, { FC } from 'react'; + import { Tooltip } from '@grafana/ui'; type Props = { diff --git a/public/app/features/alerting/unified/components/rule-editor/rule-types/GrafanaManagedAlert.tsx b/public/app/features/alerting/unified/components/rule-editor/rule-types/GrafanaManagedAlert.tsx index 0c565856472..b1558560c96 100644 --- a/public/app/features/alerting/unified/components/rule-editor/rule-types/GrafanaManagedAlert.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/rule-types/GrafanaManagedAlert.tsx @@ -1,7 +1,9 @@ import React, { FC } from 'react'; -import { RuleType, SharedProps } from './RuleType'; + import { RuleFormType } from '../../../types/rule-form'; +import { RuleType, SharedProps } from './RuleType'; + const GrafanaManagedRuleType: FC = ({ selected = false, disabled, onClick }) => { return ( void; } diff --git a/public/app/features/alerting/unified/components/rule-editor/rule-types/MimirOrLokiRecordingRule.tsx b/public/app/features/alerting/unified/components/rule-editor/rule-types/MimirOrLokiRecordingRule.tsx index d07836555e4..05519e7dcd1 100644 --- a/public/app/features/alerting/unified/components/rule-editor/rule-types/MimirOrLokiRecordingRule.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/rule-types/MimirOrLokiRecordingRule.tsx @@ -1,8 +1,10 @@ import React, { FC } from 'react'; -import { RuleType, SharedProps } from './RuleType'; -import { DisabledTooltip } from './DisabledTooltip'; + import { RuleFormType } from '../../../types/rule-form'; +import { DisabledTooltip } from './DisabledTooltip'; +import { RuleType, SharedProps } from './RuleType'; + const RecordingRuleType: FC = ({ selected = false, disabled = false, onClick }) => { return ( diff --git a/public/app/features/alerting/unified/components/rule-editor/rule-types/RuleType.tsx b/public/app/features/alerting/unified/components/rule-editor/rule-types/RuleType.tsx index 066e000e7cf..258617c1730 100644 --- a/public/app/features/alerting/unified/components/rule-editor/rule-types/RuleType.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/rule-types/RuleType.tsx @@ -1,7 +1,9 @@ import { css, cx } from '@emotion/css'; +import React, { FC, ReactNode } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { Card, useStyles2 } from '@grafana/ui'; -import React, { FC, ReactNode } from 'react'; + import { RuleFormType } from '../../../types/rule-form'; interface Props extends SharedProps { diff --git a/public/app/features/alerting/unified/components/rule-editor/rule-types/RuleTypePicker.tsx b/public/app/features/alerting/unified/components/rule-editor/rule-types/RuleTypePicker.tsx index e9dcc0c3450..f92eaede6a1 100644 --- a/public/app/features/alerting/unified/components/rule-editor/rule-types/RuleTypePicker.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/rule-types/RuleTypePicker.tsx @@ -1,11 +1,14 @@ import { css } from '@emotion/css'; +import { isEmpty } from 'lodash'; +import React, { FC } from 'react'; + import { GrafanaTheme2 } from '@grafana/data/src'; import { Stack } from '@grafana/experimental'; import { useStyles2 } from '@grafana/ui'; -import { isEmpty } from 'lodash'; -import React, { FC } from 'react'; + import { useRulesSourcesWithRuler } from '../../../hooks/useRuleSourcesWithRuler'; import { RuleFormType } from '../../../types/rule-form'; + import { GrafanaManagedRuleType } from './GrafanaManagedAlert'; import { MimirFlavoredType } from './MimirOrLokiAlert'; import { RecordingRuleType } from './MimirOrLokiRecordingRule'; diff --git a/public/app/features/alerting/unified/components/rule-editor/util.test.ts b/public/app/features/alerting/unified/components/rule-editor/util.test.ts index 33643e09b65..2dec00d720a 100644 --- a/public/app/features/alerting/unified/components/rule-editor/util.test.ts +++ b/public/app/features/alerting/unified/components/rule-editor/util.test.ts @@ -1,7 +1,8 @@ +import { ExpressionDatasourceRef } from '@grafana/runtime/src/utils/DataSourceWithBackend'; import { ClassicCondition, ExpressionQuery } from 'app/features/expressions/types'; import { AlertQuery } from 'app/types/unified-alerting-dto'; + import { checkForPathSeparator, queriesWithUpdatedReferences, updateMathExpressionRefs } from './util'; -import { ExpressionDatasourceRef } from '@grafana/runtime/src/utils/DataSourceWithBackend'; describe('rule-editor', () => { const dataSource: AlertQuery = { diff --git a/public/app/features/alerting/unified/components/rule-editor/util.ts b/public/app/features/alerting/unified/components/rule-editor/util.ts index a6921c956f6..b623941723f 100644 --- a/public/app/features/alerting/unified/components/rule-editor/util.ts +++ b/public/app/features/alerting/unified/components/rule-editor/util.ts @@ -1,6 +1,7 @@ +import { ValidateResult } from 'react-hook-form'; + import { isExpressionQuery } from 'app/features/expressions/guards'; import { AlertQuery } from 'app/types/unified-alerting-dto'; -import { ValidateResult } from 'react-hook-form'; export function queriesWithUpdatedReferences( queries: AlertQuery[], diff --git a/public/app/features/alerting/unified/components/rule-viewer/RuleViewerLayout.tsx b/public/app/features/alerting/unified/components/rule-viewer/RuleViewerLayout.tsx index 1dff5a1807d..1306b7566f4 100644 --- a/public/app/features/alerting/unified/components/rule-viewer/RuleViewerLayout.tsx +++ b/public/app/features/alerting/unified/components/rule-viewer/RuleViewerLayout.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { css } from '@emotion/css'; +import React from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { locationService } from '@grafana/runtime'; import { PageToolbar, useStyles2 } from '@grafana/ui'; diff --git a/public/app/features/alerting/unified/components/rule-viewer/RuleViewerVisualization.tsx b/public/app/features/alerting/unified/components/rule-viewer/RuleViewerVisualization.tsx index 5d419399fcc..4739f2e526b 100644 --- a/public/app/features/alerting/unified/components/rule-viewer/RuleViewerVisualization.tsx +++ b/public/app/features/alerting/unified/components/rule-viewer/RuleViewerVisualization.tsx @@ -1,16 +1,18 @@ -import React, { useCallback, useState } from 'react'; import { css } from '@emotion/css'; +import React, { useCallback, useState } from 'react'; +import AutoSizer from 'react-virtualized-auto-sizer'; + import { DataSourceInstanceSettings, DateTime, dateTime, GrafanaTheme2, PanelData, urlUtil } from '@grafana/data'; import { config, getDataSourceSrv, PanelRenderer } from '@grafana/runtime'; import { Alert, CodeEditor, DateTimePicker, LinkButton, useStyles2, useTheme2 } from '@grafana/ui'; import { isExpressionQuery } from 'app/features/expressions/guards'; import { PanelOptions } from 'app/plugins/panel/table/models.gen'; +import { AccessControlAction } from 'app/types'; import { AlertQuery } from 'app/types/unified-alerting-dto'; -import AutoSizer from 'react-virtualized-auto-sizer'; -import { PanelPluginsButtonGroup, SupportedPanelPlugins } from '../PanelPluginsButtonGroup'; + import { TABLE, TIMESERIES } from '../../utils/constants'; import { Authorize } from '../Authorize'; -import { AccessControlAction } from 'app/types'; +import { PanelPluginsButtonGroup, SupportedPanelPlugins } from '../PanelPluginsButtonGroup'; type RuleViewerVisualizationProps = { data?: PanelData; diff --git a/public/app/features/alerting/unified/components/rules/ActionButton.tsx b/public/app/features/alerting/unified/components/rules/ActionButton.tsx index e87de470c54..d1650a92e25 100644 --- a/public/app/features/alerting/unified/components/rules/ActionButton.tsx +++ b/public/app/features/alerting/unified/components/rules/ActionButton.tsx @@ -1,8 +1,9 @@ -import { Button, ButtonProps } from '@grafana/ui/src/components/Button'; -import React, { FC } from 'react'; import { css, cx } from '@emotion/css'; +import React, { FC } from 'react'; + import { GrafanaTheme } from '@grafana/data'; import { useStyles } from '@grafana/ui'; +import { Button, ButtonProps } from '@grafana/ui/src/components/Button'; type Props = Omit; diff --git a/public/app/features/alerting/unified/components/rules/ActionIcon.tsx b/public/app/features/alerting/unified/components/rules/ActionIcon.tsx index e8000c98a88..8eb72d2c768 100644 --- a/public/app/features/alerting/unified/components/rules/ActionIcon.tsx +++ b/public/app/features/alerting/unified/components/rules/ActionIcon.tsx @@ -1,6 +1,7 @@ +import React, { FC } from 'react'; + import { IconName, Tooltip, LinkButton, Button } from '@grafana/ui'; import { PopoverContent, TooltipPlacement } from '@grafana/ui/src/components/Tooltip'; -import React, { FC } from 'react'; interface Props { tooltip: PopoverContent; diff --git a/public/app/features/alerting/unified/components/rules/AlertInstanceDetails.tsx b/public/app/features/alerting/unified/components/rules/AlertInstanceDetails.tsx index 6d4443da42d..fafd89a7466 100644 --- a/public/app/features/alerting/unified/components/rules/AlertInstanceDetails.tsx +++ b/public/app/features/alerting/unified/components/rules/AlertInstanceDetails.tsx @@ -1,5 +1,7 @@ -import { Alert } from 'app/types/unified-alerting'; import React, { FC } from 'react'; + +import { Alert } from 'app/types/unified-alerting'; + import { AnnotationDetailsField } from '../AnnotationDetailsField'; import { DetailsField } from '../DetailsField'; diff --git a/public/app/features/alerting/unified/components/rules/AlertInstanceStateFilter.tsx b/public/app/features/alerting/unified/components/rules/AlertInstanceStateFilter.tsx index c1152853582..4cbc939d434 100644 --- a/public/app/features/alerting/unified/components/rules/AlertInstanceStateFilter.tsx +++ b/public/app/features/alerting/unified/components/rules/AlertInstanceStateFilter.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { RadioButtonGroup, Label } from '@grafana/ui'; import { GrafanaAlertState } from 'app/types/unified-alerting-dto'; diff --git a/public/app/features/alerting/unified/components/rules/AlertInstancesTable.tsx b/public/app/features/alerting/unified/components/rules/AlertInstancesTable.tsx index cccace4b931..d3350d95877 100644 --- a/public/app/features/alerting/unified/components/rules/AlertInstancesTable.tsx +++ b/public/app/features/alerting/unified/components/rules/AlertInstancesTable.tsx @@ -1,12 +1,15 @@ -import { GrafanaTheme2 } from '@grafana/data'; -import { Alert } from 'app/types/unified-alerting'; import { css } from '@emotion/css'; import React, { FC, useMemo } from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; +import { Alert } from 'app/types/unified-alerting'; + import { alertInstanceKey } from '../../utils/rules'; import { AlertLabels } from '../AlertLabels'; +import { DynamicTable, DynamicTableColumnProps, DynamicTableItemProps } from '../DynamicTable'; + import { AlertInstanceDetails } from './AlertInstanceDetails'; import { AlertStateTag } from './AlertStateTag'; -import { DynamicTable, DynamicTableColumnProps, DynamicTableItemProps } from '../DynamicTable'; interface Props { instances: Alert[]; diff --git a/public/app/features/alerting/unified/components/rules/AlertStateTag.tsx b/public/app/features/alerting/unified/components/rules/AlertStateTag.tsx index efeaa6596dd..b8b9127cd3e 100644 --- a/public/app/features/alerting/unified/components/rules/AlertStateTag.tsx +++ b/public/app/features/alerting/unified/components/rules/AlertStateTag.tsx @@ -1,6 +1,8 @@ +import React, { FC } from 'react'; + import { AlertState } from '@grafana/data'; import { GrafanaAlertState, PromAlertingRuleState } from 'app/types/unified-alerting-dto'; -import React, { FC } from 'react'; + import { alertStateToReadable, alertStateToState } from '../../utils/rules'; import { StateTag } from '../StateTag'; interface Props { diff --git a/public/app/features/alerting/unified/components/rules/CloudRules.tsx b/public/app/features/alerting/unified/components/rules/CloudRules.tsx index b5015337798..1e797baac95 100644 --- a/public/app/features/alerting/unified/components/rules/CloudRules.tsx +++ b/public/app/features/alerting/unified/components/rules/CloudRules.tsx @@ -1,12 +1,15 @@ import { css } from '@emotion/css'; +import pluralize from 'pluralize'; +import React, { FC, useMemo } from 'react'; + import { GrafanaTheme } from '@grafana/data'; import { LoadingPlaceholder, useStyles } from '@grafana/ui'; -import React, { FC, useMemo } from 'react'; -import { useUnifiedAlertingSelector } from '../../hooks/useUnifiedAlertingSelector'; -import { RulesGroup } from './RulesGroup'; -import { getRulesDataSources, getRulesSourceName } from '../../utils/datasource'; import { CombinedRuleNamespace } from 'app/types/unified-alerting'; -import pluralize from 'pluralize'; + +import { useUnifiedAlertingSelector } from '../../hooks/useUnifiedAlertingSelector'; +import { getRulesDataSources, getRulesSourceName } from '../../utils/datasource'; + +import { RulesGroup } from './RulesGroup'; interface Props { namespaces: CombinedRuleNamespace[]; diff --git a/public/app/features/alerting/unified/components/rules/EditCloudGroupModal.tsx b/public/app/features/alerting/unified/components/rules/EditCloudGroupModal.tsx index 52c86b0397f..8018fef98bb 100644 --- a/public/app/features/alerting/unified/components/rules/EditCloudGroupModal.tsx +++ b/public/app/features/alerting/unified/components/rules/EditCloudGroupModal.tsx @@ -1,14 +1,16 @@ -import React, { useEffect, useMemo } from 'react'; -import { CombinedRuleGroup, CombinedRuleNamespace } from 'app/types/unified-alerting'; -import { Modal, Button, Form, Field, Input, useStyles2 } from '@grafana/ui'; -import { durationValidationPattern } from '../../utils/time'; import { css } from '@emotion/css'; +import React, { useEffect, useMemo } from 'react'; import { useDispatch } from 'react-redux'; + +import { Modal, Button, Form, Field, Input, useStyles2 } from '@grafana/ui'; +import { useCleanup } from 'app/core/hooks/useCleanup'; +import { CombinedRuleGroup, CombinedRuleNamespace } from 'app/types/unified-alerting'; + +import { useUnifiedAlertingSelector } from '../../hooks/useUnifiedAlertingSelector'; import { updateLotexNamespaceAndGroupAction } from '../../state/actions'; import { getRulesSourceName } from '../../utils/datasource'; -import { useUnifiedAlertingSelector } from '../../hooks/useUnifiedAlertingSelector'; import { initialAsyncRequestState } from '../../utils/redux'; -import { useCleanup } from 'app/core/hooks/useCleanup'; +import { durationValidationPattern } from '../../utils/time'; interface Props { namespace: CombinedRuleNamespace; diff --git a/public/app/features/alerting/unified/components/rules/GrafanaRules.tsx b/public/app/features/alerting/unified/components/rules/GrafanaRules.tsx index ab37aecab6e..99e26bf74ff 100644 --- a/public/app/features/alerting/unified/components/rules/GrafanaRules.tsx +++ b/public/app/features/alerting/unified/components/rules/GrafanaRules.tsx @@ -1,14 +1,17 @@ import { css } from '@emotion/css'; +import React, { FC } from 'react'; + import { GrafanaTheme } from '@grafana/data'; import { LoadingPlaceholder, useStyles } from '@grafana/ui'; -import React, { FC } from 'react'; -import { useUnifiedAlertingSelector } from '../../hooks/useUnifiedAlertingSelector'; -import { RulesGroup } from './RulesGroup'; -import { GRAFANA_RULES_SOURCE_NAME } from '../../utils/datasource'; -import { CombinedRuleNamespace } from 'app/types/unified-alerting'; -import { initialAsyncRequestState } from '../../utils/redux'; import { useQueryParams } from 'app/core/hooks/useQueryParams'; +import { CombinedRuleNamespace } from 'app/types/unified-alerting'; + import { flattenGrafanaManagedRules } from '../../hooks/useCombinedRuleNamespaces'; +import { useUnifiedAlertingSelector } from '../../hooks/useUnifiedAlertingSelector'; +import { GRAFANA_RULES_SOURCE_NAME } from '../../utils/datasource'; +import { initialAsyncRequestState } from '../../utils/redux'; + +import { RulesGroup } from './RulesGroup'; interface Props { namespaces: CombinedRuleNamespace[]; diff --git a/public/app/features/alerting/unified/components/rules/NoRulesCTA.tsx b/public/app/features/alerting/unified/components/rules/NoRulesCTA.tsx index 536f959e6bd..b90632070f1 100644 --- a/public/app/features/alerting/unified/components/rules/NoRulesCTA.tsx +++ b/public/app/features/alerting/unified/components/rules/NoRulesCTA.tsx @@ -1,6 +1,8 @@ +import React, { FC } from 'react'; + import { CallToActionCard } from '@grafana/ui'; import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA'; -import React, { FC } from 'react'; + import { useRulesAccess } from '../../utils/accessControlHooks'; export const NoRulesSplash: FC = () => { diff --git a/public/app/features/alerting/unified/components/rules/RuleDetails.test.tsx b/public/app/features/alerting/unified/components/rules/RuleDetails.test.tsx index 8b4aba62a0f..7fad7526137 100644 --- a/public/app/features/alerting/unified/components/rules/RuleDetails.test.tsx +++ b/public/app/features/alerting/unified/components/rules/RuleDetails.test.tsx @@ -1,15 +1,18 @@ import { render } from '@testing-library/react'; -import { contextSrv } from 'app/core/services/context_srv'; -import { configureStore } from 'app/store/configureStore'; -import { AccessControlAction } from 'app/types'; -import { CombinedRule } from 'app/types/unified-alerting'; import React from 'react'; import { Provider } from 'react-redux'; import { MemoryRouter } from 'react-router-dom'; import { byRole } from 'testing-library-selector'; -import { mockCombinedRule, mockDataSource, mockPromAlertingRule, mockRulerAlertingRule } from '../../mocks'; -import { RuleDetails } from './RuleDetails'; + +import { contextSrv } from 'app/core/services/context_srv'; +import { configureStore } from 'app/store/configureStore'; +import { AccessControlAction } from 'app/types'; +import { CombinedRule } from 'app/types/unified-alerting'; + import { useIsRuleEditable } from '../../hooks/useIsRuleEditable'; +import { mockCombinedRule, mockDataSource, mockPromAlertingRule, mockRulerAlertingRule } from '../../mocks'; + +import { RuleDetails } from './RuleDetails'; jest.mock('../../hooks/useIsRuleEditable'); diff --git a/public/app/features/alerting/unified/components/rules/RuleDetails.tsx b/public/app/features/alerting/unified/components/rules/RuleDetails.tsx index db8a5fc8e8c..74d378d52ca 100644 --- a/public/app/features/alerting/unified/components/rules/RuleDetails.tsx +++ b/public/app/features/alerting/unified/components/rules/RuleDetails.tsx @@ -1,10 +1,13 @@ import { css } from '@emotion/css'; +import React, { FC } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { useStyles2 } from '@grafana/ui'; import { CombinedRule } from 'app/types/unified-alerting'; -import React, { FC } from 'react'; + import { AlertLabels } from '../AlertLabels'; import { DetailsField } from '../DetailsField'; + import { RuleDetailsActionButtons } from './RuleDetailsActionButtons'; import { RuleDetailsAnnotations } from './RuleDetailsAnnotations'; import { RuleDetailsDataSources } from './RuleDetailsDataSources'; diff --git a/public/app/features/alerting/unified/components/rules/RuleDetailsActionButtons.tsx b/public/app/features/alerting/unified/components/rules/RuleDetailsActionButtons.tsx index 43604a68733..9c52cdd2755 100644 --- a/public/app/features/alerting/unified/components/rules/RuleDetailsActionButtons.tsx +++ b/public/app/features/alerting/unified/components/rules/RuleDetailsActionButtons.tsx @@ -1,4 +1,8 @@ import { css } from '@emotion/css'; +import React, { FC, Fragment, useState } from 'react'; +import { useDispatch } from 'react-redux'; +import { useLocation } from 'react-router-dom'; + import { GrafanaTheme2, urlUtil } from '@grafana/data'; import { config } from '@grafana/runtime'; import { Button, ClipboardButton, ConfirmModal, HorizontalGroup, LinkButton, useStyles2 } from '@grafana/ui'; @@ -7,9 +11,7 @@ import { contextSrv } from 'app/core/services/context_srv'; import { AccessControlAction } from 'app/types'; import { CombinedRule, RulesSource } from 'app/types/unified-alerting'; import { RulerGrafanaRuleDTO, RulerRuleDTO } from 'app/types/unified-alerting-dto'; -import React, { FC, Fragment, useState } from 'react'; -import { useDispatch } from 'react-redux'; -import { useLocation } from 'react-router-dom'; + import { useIsRuleEditable } from '../../hooks/useIsRuleEditable'; import { useStateHistoryModal } from '../../hooks/useStateHistoryModal'; import { deleteRuleAction } from '../../state/actions'; diff --git a/public/app/features/alerting/unified/components/rules/RuleDetailsAnnotations.tsx b/public/app/features/alerting/unified/components/rules/RuleDetailsAnnotations.tsx index 3963d88cc51..7c9691eeac3 100644 --- a/public/app/features/alerting/unified/components/rules/RuleDetailsAnnotations.tsx +++ b/public/app/features/alerting/unified/components/rules/RuleDetailsAnnotations.tsx @@ -1,6 +1,8 @@ -import React from 'react'; import { css } from '@emotion/css'; +import React from 'react'; + import { useStyles2 } from '@grafana/ui'; + import { AnnotationDetailsField } from '../AnnotationDetailsField'; type Props = { diff --git a/public/app/features/alerting/unified/components/rules/RuleDetailsDataSources.tsx b/public/app/features/alerting/unified/components/rules/RuleDetailsDataSources.tsx index fc6584d9d24..39facac253a 100644 --- a/public/app/features/alerting/unified/components/rules/RuleDetailsDataSources.tsx +++ b/public/app/features/alerting/unified/components/rules/RuleDetailsDataSources.tsx @@ -1,10 +1,12 @@ import { css } from '@emotion/css'; +import React, { useMemo } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { getDataSourceSrv } from '@grafana/runtime'; import { useStyles2 } from '@grafana/ui'; import { ExpressionDatasourceUID } from 'app/features/expressions/ExpressionDatasource'; import { CombinedRule, RulesSource } from 'app/types/unified-alerting'; -import React, { useMemo } from 'react'; + import { isCloudRulesSource } from '../../utils/datasource'; import { isGrafanaRulerRule } from '../../utils/rules'; import { DetailsField } from '../DetailsField'; diff --git a/public/app/features/alerting/unified/components/rules/RuleDetailsExpression.tsx b/public/app/features/alerting/unified/components/rules/RuleDetailsExpression.tsx index af3750a7bed..ea5cd7969cc 100644 --- a/public/app/features/alerting/unified/components/rules/RuleDetailsExpression.tsx +++ b/public/app/features/alerting/unified/components/rules/RuleDetailsExpression.tsx @@ -1,6 +1,8 @@ -import React from 'react'; import { css, cx } from '@emotion/css'; +import React from 'react'; + import { CombinedRule, RulesSource } from 'app/types/unified-alerting'; + import { isCloudRulesSource } from '../../utils/datasource'; import { DetailsField } from '../DetailsField'; import { Expression } from '../Expression'; diff --git a/public/app/features/alerting/unified/components/rules/RuleDetailsFederatedSources.tsx b/public/app/features/alerting/unified/components/rules/RuleDetailsFederatedSources.tsx index a7ca0178276..b0cd5ecfc0f 100644 --- a/public/app/features/alerting/unified/components/rules/RuleDetailsFederatedSources.tsx +++ b/public/app/features/alerting/unified/components/rules/RuleDetailsFederatedSources.tsx @@ -1,5 +1,7 @@ -import { CombinedRuleGroup } from 'app/types/unified-alerting'; import React, { FC } from 'react'; + +import { CombinedRuleGroup } from 'app/types/unified-alerting'; + import { DetailsField } from '../DetailsField'; interface Props { diff --git a/public/app/features/alerting/unified/components/rules/RuleDetailsMatchingInstances.tsx b/public/app/features/alerting/unified/components/rules/RuleDetailsMatchingInstances.tsx index 80efbc627eb..c214c4a4e4b 100644 --- a/public/app/features/alerting/unified/components/rules/RuleDetailsMatchingInstances.tsx +++ b/public/app/features/alerting/unified/components/rules/RuleDetailsMatchingInstances.tsx @@ -1,17 +1,20 @@ -import { Alert, Rule } from 'app/types/unified-alerting'; +import { css, cx } from '@emotion/css'; import React, { useMemo, useState } from 'react'; -import { isAlertingRule } from '../../utils/rules'; -import { DetailsField } from '../DetailsField'; -import { AlertInstancesTable } from './AlertInstancesTable'; -import { SortOrder } from 'app/plugins/panel/alertlist/types'; -import { GrafanaAlertState } from 'app/types/unified-alerting-dto'; + import { GrafanaTheme } from '@grafana/data'; import { useStyles } from '@grafana/ui'; -import { css, cx } from '@emotion/css'; -import { labelsMatchMatchers, parseMatchers } from 'app/features/alerting/unified/utils/alertmanager'; -import { sortAlerts } from 'app/features/alerting/unified/utils/misc'; import { MatcherFilter } from 'app/features/alerting/unified/components/alert-groups/MatcherFilter'; import { AlertInstanceStateFilter } from 'app/features/alerting/unified/components/rules/AlertInstanceStateFilter'; +import { labelsMatchMatchers, parseMatchers } from 'app/features/alerting/unified/utils/alertmanager'; +import { sortAlerts } from 'app/features/alerting/unified/utils/misc'; +import { SortOrder } from 'app/plugins/panel/alertlist/types'; +import { Alert, Rule } from 'app/types/unified-alerting'; +import { GrafanaAlertState } from 'app/types/unified-alerting-dto'; + +import { isAlertingRule } from '../../utils/rules'; +import { DetailsField } from '../DetailsField'; + +import { AlertInstancesTable } from './AlertInstancesTable'; type Props = { promRule?: Rule; diff --git a/public/app/features/alerting/unified/components/rules/RuleHealth.tsx b/public/app/features/alerting/unified/components/rules/RuleHealth.tsx index 3cb4c3d9b15..61cd9f346b7 100644 --- a/public/app/features/alerting/unified/components/rules/RuleHealth.tsx +++ b/public/app/features/alerting/unified/components/rules/RuleHealth.tsx @@ -1,8 +1,9 @@ import { css } from '@emotion/css'; +import React, { FC } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { Icon, Tooltip, useStyles2 } from '@grafana/ui'; import { Rule } from 'app/types/unified-alerting'; -import React, { FC } from 'react'; interface Prom { rule: Rule; diff --git a/public/app/features/alerting/unified/components/rules/RuleListErrors.tsx b/public/app/features/alerting/unified/components/rules/RuleListErrors.tsx index fa95540ad4a..2076fa92409 100644 --- a/public/app/features/alerting/unified/components/rules/RuleListErrors.tsx +++ b/public/app/features/alerting/unified/components/rules/RuleListErrors.tsx @@ -1,10 +1,12 @@ import { css } from '@emotion/css'; -import { DataSourceInstanceSettings, GrafanaTheme2 } from '@grafana/data'; -import { Alert, Button, Tooltip, useStyles2 } from '@grafana/ui'; import { SerializedError } from '@reduxjs/toolkit'; import pluralize from 'pluralize'; import React, { useMemo, ReactElement, useState, FC } from 'react'; import { useLocalStorage } from 'react-use'; + +import { DataSourceInstanceSettings, GrafanaTheme2 } from '@grafana/data'; +import { Alert, Button, Tooltip, useStyles2 } from '@grafana/ui'; + import { useUnifiedAlertingSelector } from '../../hooks/useUnifiedAlertingSelector'; import { getRulesDataSources, GRAFANA_RULES_SOURCE_NAME } from '../../utils/datasource'; import { isRulerNotSupportedResponse } from '../../utils/rules'; diff --git a/public/app/features/alerting/unified/components/rules/RuleListGroupView.test.tsx b/public/app/features/alerting/unified/components/rules/RuleListGroupView.test.tsx index 62d687ba212..c0c0b5a28e6 100644 --- a/public/app/features/alerting/unified/components/rules/RuleListGroupView.test.tsx +++ b/public/app/features/alerting/unified/components/rules/RuleListGroupView.test.tsx @@ -1,15 +1,18 @@ -import { locationService } from '@grafana/runtime'; import { render } from '@testing-library/react'; -import { contextSrv } from 'app/core/services/context_srv'; -import { configureStore } from 'app/store/configureStore'; -import { AccessControlAction } from 'app/types'; -import { CombinedRuleNamespace } from 'app/types/unified-alerting'; import React from 'react'; import { Provider } from 'react-redux'; import { Router } from 'react-router-dom'; import { byRole } from 'testing-library-selector'; + +import { locationService } from '@grafana/runtime'; +import { contextSrv } from 'app/core/services/context_srv'; +import { configureStore } from 'app/store/configureStore'; +import { AccessControlAction } from 'app/types'; +import { CombinedRuleNamespace } from 'app/types/unified-alerting'; + import { mockCombinedRule, mockDataSource } from '../../mocks'; import { GRAFANA_RULES_SOURCE_NAME } from '../../utils/datasource'; + import { RuleListGroupView } from './RuleListGroupView'; const ui = { diff --git a/public/app/features/alerting/unified/components/rules/RuleListGroupView.tsx b/public/app/features/alerting/unified/components/rules/RuleListGroupView.tsx index 9bb64492da7..ffd5ebc904d 100644 --- a/public/app/features/alerting/unified/components/rules/RuleListGroupView.tsx +++ b/public/app/features/alerting/unified/components/rules/RuleListGroupView.tsx @@ -1,8 +1,11 @@ +import React, { FC, useMemo } from 'react'; + import { AccessControlAction } from 'app/types'; import { CombinedRuleNamespace } from 'app/types/unified-alerting'; -import React, { FC, useMemo } from 'react'; + import { isCloudRulesSource, isGrafanaRulesSource } from '../../utils/datasource'; import { Authorize } from '../Authorize'; + import { CloudRules } from './CloudRules'; import { GrafanaRules } from './GrafanaRules'; diff --git a/public/app/features/alerting/unified/components/rules/RuleListStateSection.tsx b/public/app/features/alerting/unified/components/rules/RuleListStateSection.tsx index 3dfd9dc8c86..cc8aec8d859 100644 --- a/public/app/features/alerting/unified/components/rules/RuleListStateSection.tsx +++ b/public/app/features/alerting/unified/components/rules/RuleListStateSection.tsx @@ -1,11 +1,14 @@ import { css } from '@emotion/css'; +import React, { FC, useState } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { useStyles2 } from '@grafana/ui'; import { CombinedRule } from 'app/types/unified-alerting'; import { PromAlertingRuleState } from 'app/types/unified-alerting-dto'; -import React, { FC, useState } from 'react'; + import { alertStateToReadable } from '../../utils/rules'; import { CollapseToggle } from '../CollapseToggle'; + import { RulesTable } from './RulesTable'; interface Props { diff --git a/public/app/features/alerting/unified/components/rules/RuleListStateView.tsx b/public/app/features/alerting/unified/components/rules/RuleListStateView.tsx index f833dbba8db..3f5242cb5ed 100644 --- a/public/app/features/alerting/unified/components/rules/RuleListStateView.tsx +++ b/public/app/features/alerting/unified/components/rules/RuleListStateView.tsx @@ -1,9 +1,12 @@ +import React, { FC, useMemo } from 'react'; + import { useQueryParams } from 'app/core/hooks/useQueryParams'; import { CombinedRule, CombinedRuleNamespace } from 'app/types/unified-alerting'; import { PromAlertingRuleState } from 'app/types/unified-alerting-dto'; -import React, { FC, useMemo } from 'react'; + import { getFiltersFromUrlParams } from '../../utils/misc'; import { isAlertingRule } from '../../utils/rules'; + import { RuleListStateSection } from './RuleListStateSection'; interface Props { diff --git a/public/app/features/alerting/unified/components/rules/RuleState.tsx b/public/app/features/alerting/unified/components/rules/RuleState.tsx index 85e85a2d448..08990964c69 100644 --- a/public/app/features/alerting/unified/components/rules/RuleState.tsx +++ b/public/app/features/alerting/unified/components/rules/RuleState.tsx @@ -1,10 +1,13 @@ import { css } from '@emotion/css'; +import React, { FC, useMemo } from 'react'; + import { GrafanaTheme2, intervalToAbbreviatedDurationString } from '@grafana/data'; import { HorizontalGroup, Spinner, useStyles2 } from '@grafana/ui'; import { CombinedRule } from 'app/types/unified-alerting'; import { PromAlertingRuleState } from 'app/types/unified-alerting-dto'; -import React, { FC, useMemo } from 'react'; + import { isAlertingRule, isRecordingRule, getFirstActiveAt } from '../../utils/rules'; + import { AlertStateTag } from './AlertStateTag'; interface Props { diff --git a/public/app/features/alerting/unified/components/rules/RuleStats.tsx b/public/app/features/alerting/unified/components/rules/RuleStats.tsx index 58415d364f2..f5fb8c39d97 100644 --- a/public/app/features/alerting/unified/components/rules/RuleStats.tsx +++ b/public/app/features/alerting/unified/components/rules/RuleStats.tsx @@ -1,7 +1,9 @@ -import { CombinedRule, CombinedRuleGroup, CombinedRuleNamespace } from 'app/types/unified-alerting'; -import { PromAlertingRuleState } from 'app/types/unified-alerting-dto'; import pluralize from 'pluralize'; import React, { FC, Fragment, useMemo } from 'react'; + +import { CombinedRule, CombinedRuleGroup, CombinedRuleNamespace } from 'app/types/unified-alerting'; +import { PromAlertingRuleState } from 'app/types/unified-alerting-dto'; + import { isAlertingRule, isRecordingRule, isRecordingRulerRule } from '../../utils/rules'; import { StateColoredText } from '../StateColoredText'; diff --git a/public/app/features/alerting/unified/components/rules/RulesFilter.tsx b/public/app/features/alerting/unified/components/rules/RulesFilter.tsx index f0f38384a31..766dfaa13a6 100644 --- a/public/app/features/alerting/unified/components/rules/RulesFilter.tsx +++ b/public/app/features/alerting/unified/components/rules/RulesFilter.tsx @@ -1,15 +1,16 @@ -import React, { FormEvent, useState } from 'react'; -import { Button, Field, Icon, Input, Label, RadioButtonGroup, Tooltip, useStyles } from '@grafana/ui'; -import { DataSourceInstanceSettings, GrafanaTheme, SelectableValue } from '@grafana/data'; import { css, cx } from '@emotion/css'; import { debounce } from 'lodash'; +import React, { FormEvent, useState } from 'react'; -import { PromAlertingRuleState, PromRuleType } from 'app/types/unified-alerting-dto'; -import { useQueryParams } from 'app/core/hooks/useQueryParams'; -import { getFiltersFromUrlParams } from '../../utils/misc'; -import { DataSourcePicker } from '@grafana/runtime'; -import { alertStateToReadable } from '../../utils/rules'; +import { DataSourceInstanceSettings, GrafanaTheme, SelectableValue } from '@grafana/data'; import { Stack } from '@grafana/experimental'; +import { DataSourcePicker } from '@grafana/runtime'; +import { Button, Field, Icon, Input, Label, RadioButtonGroup, Tooltip, useStyles } from '@grafana/ui'; +import { useQueryParams } from 'app/core/hooks/useQueryParams'; +import { PromAlertingRuleState, PromRuleType } from 'app/types/unified-alerting-dto'; + +import { getFiltersFromUrlParams } from '../../utils/misc'; +import { alertStateToReadable } from '../../utils/rules'; const ViewOptions: SelectableValue[] = [ { diff --git a/public/app/features/alerting/unified/components/rules/RulesGroup.test.tsx b/public/app/features/alerting/unified/components/rules/RulesGroup.test.tsx index 79bde001d75..f9d61ecbd61 100644 --- a/public/app/features/alerting/unified/components/rules/RulesGroup.test.tsx +++ b/public/app/features/alerting/unified/components/rules/RulesGroup.test.tsx @@ -1,11 +1,14 @@ import { render } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { configureStore } from 'app/store/configureStore'; -import { CombinedRuleGroup, CombinedRuleNamespace } from 'app/types/unified-alerting'; import React from 'react'; import { Provider } from 'react-redux'; import { byTestId, byText } from 'testing-library-selector'; + +import { configureStore } from 'app/store/configureStore'; +import { CombinedRuleGroup, CombinedRuleNamespace } from 'app/types/unified-alerting'; + import { mockCombinedRule, mockDataSource } from '../../mocks'; + import { RulesGroup } from './RulesGroup'; const hasRulerMock = jest.fn(); diff --git a/public/app/features/alerting/unified/components/rules/RulesGroup.tsx b/public/app/features/alerting/unified/components/rules/RulesGroup.tsx index b8c0c442d59..d87303d3760 100644 --- a/public/app/features/alerting/unified/components/rules/RulesGroup.tsx +++ b/public/app/features/alerting/unified/components/rules/RulesGroup.tsx @@ -1,13 +1,15 @@ import { css } from '@emotion/css'; +import pluralize from 'pluralize'; +import React, { FC, useEffect, useState } from 'react'; +import { useDispatch } from 'react-redux'; + import { GrafanaTheme2 } from '@grafana/data'; import { Badge, ConfirmModal, HorizontalGroup, Icon, Spinner, Tooltip, useStyles2 } from '@grafana/ui'; import { contextSrv } from 'app/core/services/context_srv'; import kbn from 'app/core/utils/kbn'; import { AccessControlAction } from 'app/types'; import { CombinedRuleGroup, CombinedRuleNamespace } from 'app/types/unified-alerting'; -import pluralize from 'pluralize'; -import React, { FC, useEffect, useState } from 'react'; -import { useDispatch } from 'react-redux'; + import { useFolder } from '../../hooks/useFolder'; import { useHasRuler } from '../../hooks/useHasRuler'; import { deleteRulesGroupAction } from '../../state/actions'; @@ -15,10 +17,11 @@ import { GRAFANA_RULES_SOURCE_NAME, isCloudRulesSource } from '../../utils/datas import { isFederatedRuleGroup, isGrafanaRulerRule } from '../../utils/rules'; import { CollapseToggle } from '../CollapseToggle'; import { RuleLocation } from '../RuleLocation'; + import { ActionIcon } from './ActionIcon'; import { EditCloudGroupModal } from './EditCloudGroupModal'; -import { RulesTable } from './RulesTable'; import { RuleStats } from './RuleStats'; +import { RulesTable } from './RulesTable'; interface Props { namespace: CombinedRuleNamespace; diff --git a/public/app/features/alerting/unified/components/rules/RulesTable.tsx b/public/app/features/alerting/unified/components/rules/RulesTable.tsx index f638d258fcf..e6423e96dc1 100644 --- a/public/app/features/alerting/unified/components/rules/RulesTable.tsx +++ b/public/app/features/alerting/unified/components/rules/RulesTable.tsx @@ -1,17 +1,20 @@ +import { css, cx } from '@emotion/css'; +import React, { FC, useMemo } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { useStyles2 } from '@grafana/ui'; -import React, { FC, useMemo } from 'react'; -import { css, cx } from '@emotion/css'; -import { RuleDetails } from './RuleDetails'; -import { useHasRuler } from '../../hooks/useHasRuler'; import { CombinedRule } from 'app/types/unified-alerting'; + +import { useHasRuler } from '../../hooks/useHasRuler'; import { Annotation } from '../../utils/constants'; -import { RuleState } from './RuleState'; -import { RuleHealth } from './RuleHealth'; import { DynamicTable, DynamicTableColumnProps, DynamicTableItemProps } from '../DynamicTable'; import { DynamicTableWithGuidelines } from '../DynamicTableWithGuidelines'; import { RuleLocation } from '../RuleLocation'; +import { RuleDetails } from './RuleDetails'; +import { RuleHealth } from './RuleHealth'; +import { RuleState } from './RuleState'; + type RuleTableColumnProps = DynamicTableColumnProps; type RuleTableItemProps = DynamicTableItemProps; diff --git a/public/app/features/alerting/unified/components/rules/StateHistory.tsx b/public/app/features/alerting/unified/components/rules/StateHistory.tsx index f7050eb198c..49c53d93046 100644 --- a/public/app/features/alerting/unified/components/rules/StateHistory.tsx +++ b/public/app/features/alerting/unified/components/rules/StateHistory.tsx @@ -1,14 +1,17 @@ -import React, { FC } from 'react'; +import { css } from '@emotion/css'; import { uniqueId } from 'lodash'; +import React, { FC } from 'react'; + import { AlertState, dateTimeFormat, GrafanaTheme } from '@grafana/data'; import { Alert, LoadingPlaceholder, useStyles } from '@grafana/ui'; -import { css } from '@emotion/css'; import { StateHistoryItem, StateHistoryItemData } from 'app/types/unified-alerting'; -import { DynamicTable, DynamicTableColumnProps, DynamicTableItemProps } from '../DynamicTable'; -import { AlertStateTag } from './AlertStateTag'; +import { GrafanaAlertState, PromAlertingRuleState } from 'app/types/unified-alerting-dto'; + import { useManagedAlertStateHistory } from '../../hooks/useManagedAlertStateHistory'; import { AlertLabel } from '../AlertLabel'; -import { GrafanaAlertState, PromAlertingRuleState } from 'app/types/unified-alerting-dto'; +import { DynamicTable, DynamicTableColumnProps, DynamicTableItemProps } from '../DynamicTable'; + +import { AlertStateTag } from './AlertStateTag'; type StateHistoryRowItem = { id: string; diff --git a/public/app/features/alerting/unified/components/silences/AmAlertStateTag.tsx b/public/app/features/alerting/unified/components/silences/AmAlertStateTag.tsx index 66206ed07ad..96493b0b5ec 100644 --- a/public/app/features/alerting/unified/components/silences/AmAlertStateTag.tsx +++ b/public/app/features/alerting/unified/components/silences/AmAlertStateTag.tsx @@ -1,5 +1,7 @@ -import { AlertState } from 'app/plugins/datasource/alertmanager/types'; import React, { FC } from 'react'; + +import { AlertState } from 'app/plugins/datasource/alertmanager/types'; + import { State, StateTag } from '../StateTag'; const alertStateToState: Record = { diff --git a/public/app/features/alerting/unified/components/silences/MatchedSilencedRules.tsx b/public/app/features/alerting/unified/components/silences/MatchedSilencedRules.tsx index d464202f3a4..d28d9ece726 100644 --- a/public/app/features/alerting/unified/components/silences/MatchedSilencedRules.tsx +++ b/public/app/features/alerting/unified/components/silences/MatchedSilencedRules.tsx @@ -1,19 +1,21 @@ +import { css } from '@emotion/css'; import React, { useEffect, useState } from 'react'; import { useFormContext } from 'react-hook-form'; -import { useDebounce } from 'react-use'; import { useDispatch } from 'react-redux'; -import { css } from '@emotion/css'; +import { useDebounce } from 'react-use'; + import { dateTime, GrafanaTheme2 } from '@grafana/data'; import { Badge, useStyles2 } from '@grafana/ui'; -import { DynamicTable, DynamicTableColumnProps, DynamicTableItemProps } from '../DynamicTable'; -import { useCombinedRuleNamespaces } from '../../hooks/useCombinedRuleNamespaces'; -import { findAlertInstancesWithMatchers } from '../../utils/matchers'; -import { fetchAllPromAndRulerRulesAction } from '../../state/actions'; import { Alert, AlertingRule } from 'app/types/unified-alerting'; + +import { useCombinedRuleNamespaces } from '../../hooks/useCombinedRuleNamespaces'; +import { fetchAllPromAndRulerRulesAction } from '../../state/actions'; import { MatcherFieldValue, SilenceFormFields } from '../../types/silence-form'; +import { findAlertInstancesWithMatchers } from '../../utils/matchers'; import { isAlertingRule } from '../../utils/rules'; -import { AlertStateTag } from '../rules/AlertStateTag'; import { AlertLabels } from '../AlertLabels'; +import { DynamicTable, DynamicTableColumnProps, DynamicTableItemProps } from '../DynamicTable'; +import { AlertStateTag } from '../rules/AlertStateTag'; type MatchedRulesTableItemProps = DynamicTableItemProps<{ matchedInstance: Alert; diff --git a/public/app/features/alerting/unified/components/silences/Matchers.tsx b/public/app/features/alerting/unified/components/silences/Matchers.tsx index 0d686d7027f..f5b9674817e 100644 --- a/public/app/features/alerting/unified/components/silences/Matchers.tsx +++ b/public/app/features/alerting/unified/components/silences/Matchers.tsx @@ -1,7 +1,9 @@ -import React, { FC } from 'react'; import { css } from '@emotion/css'; +import React, { FC } from 'react'; + import { TagList, useStyles2 } from '@grafana/ui'; import { Matcher } from 'app/plugins/datasource/alertmanager/types'; + import { matcherToOperator } from '../../utils/alertmanager'; type MatchersProps = { matchers: Matcher[] }; diff --git a/public/app/features/alerting/unified/components/silences/MatchersField.tsx b/public/app/features/alerting/unified/components/silences/MatchersField.tsx index 7464af9ef2f..4ccf213132e 100644 --- a/public/app/features/alerting/unified/components/silences/MatchersField.tsx +++ b/public/app/features/alerting/unified/components/silences/MatchersField.tsx @@ -1,10 +1,12 @@ -import React, { FC } from 'react'; -import { Button, Field, Input, IconButton, InputControl, useStyles2, Select } from '@grafana/ui'; -import { GrafanaTheme2 } from '@grafana/data'; import { css, cx } from '@emotion/css'; +import React, { FC } from 'react'; import { useFormContext, useFieldArray } from 'react-hook-form'; -import { SilenceFormFields } from '../../types/silence-form'; + +import { GrafanaTheme2 } from '@grafana/data'; +import { Button, Field, Input, IconButton, InputControl, useStyles2, Select } from '@grafana/ui'; import { MatcherOperator } from 'app/plugins/datasource/alertmanager/types'; + +import { SilenceFormFields } from '../../types/silence-form'; import { matcherFieldOptions } from '../../utils/alertmanager'; interface Props { diff --git a/public/app/features/alerting/unified/components/silences/NoSilencesCTA.tsx b/public/app/features/alerting/unified/components/silences/NoSilencesCTA.tsx index 50df2002dc6..4c142c092a9 100644 --- a/public/app/features/alerting/unified/components/silences/NoSilencesCTA.tsx +++ b/public/app/features/alerting/unified/components/silences/NoSilencesCTA.tsx @@ -1,7 +1,9 @@ +import React, { FC } from 'react'; + import { CallToActionCard } from '@grafana/ui'; import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA'; import { contextSrv } from 'app/core/services/context_srv'; -import React, { FC } from 'react'; + import { getInstancesPermissions } from '../../utils/access-control'; import { makeAMLink } from '../../utils/misc'; diff --git a/public/app/features/alerting/unified/components/silences/SilenceDetails.tsx b/public/app/features/alerting/unified/components/silences/SilenceDetails.tsx index e519ec1e4c5..c76b79d0d66 100644 --- a/public/app/features/alerting/unified/components/silences/SilenceDetails.tsx +++ b/public/app/features/alerting/unified/components/silences/SilenceDetails.tsx @@ -1,9 +1,10 @@ import { css } from '@emotion/css'; -import { dateMath, GrafanaTheme2, intervalToAbbreviatedDurationString } from '@grafana/data'; import React from 'react'; -import { useStyles2 } from '@grafana/ui'; -import SilencedAlertsTable from './SilencedAlertsTable'; +import { dateMath, GrafanaTheme2, intervalToAbbreviatedDurationString } from '@grafana/data'; +import { useStyles2 } from '@grafana/ui'; + +import SilencedAlertsTable from './SilencedAlertsTable'; import { SilenceTableItem } from './SilencesTable'; interface Props { diff --git a/public/app/features/alerting/unified/components/silences/SilencePeriod.tsx b/public/app/features/alerting/unified/components/silences/SilencePeriod.tsx index 3542a84322b..a332f12e835 100644 --- a/public/app/features/alerting/unified/components/silences/SilencePeriod.tsx +++ b/public/app/features/alerting/unified/components/silences/SilencePeriod.tsx @@ -1,8 +1,10 @@ import { css } from '@emotion/css'; -import { dateTime, GrafanaTheme } from '@grafana/data'; -import { Field, TimeRangeInput, useStyles } from '@grafana/ui'; import React from 'react'; import { useController, useFormContext } from 'react-hook-form'; + +import { dateTime, GrafanaTheme } from '@grafana/data'; +import { Field, TimeRangeInput, useStyles } from '@grafana/ui'; + import { SilenceFormFields } from '../../types/silence-form'; export const SilencePeriod = () => { diff --git a/public/app/features/alerting/unified/components/silences/SilenceStateTag.tsx b/public/app/features/alerting/unified/components/silences/SilenceStateTag.tsx index 4b212d3c1a1..fc36282db8c 100644 --- a/public/app/features/alerting/unified/components/silences/SilenceStateTag.tsx +++ b/public/app/features/alerting/unified/components/silences/SilenceStateTag.tsx @@ -1,5 +1,7 @@ -import { SilenceState } from 'app/plugins/datasource/alertmanager/types'; import React, { FC } from 'react'; + +import { SilenceState } from 'app/plugins/datasource/alertmanager/types'; + import { State, StateTag } from '../StateTag'; const silenceStateToState: Record = { diff --git a/public/app/features/alerting/unified/components/silences/SilenceTableRow.tsx b/public/app/features/alerting/unified/components/silences/SilenceTableRow.tsx index 7f76d3c4a03..1897361de84 100644 --- a/public/app/features/alerting/unified/components/silences/SilenceTableRow.tsx +++ b/public/app/features/alerting/unified/components/silences/SilenceTableRow.tsx @@ -1,18 +1,22 @@ -import React, { FC, Fragment, useState } from 'react'; -import { dateMath, GrafanaTheme, intervalToAbbreviatedDurationString } from '@grafana/data'; import { css, cx } from '@emotion/css'; +import React, { FC, Fragment, useState } from 'react'; +import { useDispatch } from 'react-redux'; + +import { dateMath, GrafanaTheme, intervalToAbbreviatedDurationString } from '@grafana/data'; +import { useStyles, Link } from '@grafana/ui'; +import { contextSrv } from 'app/core/services/context_srv'; import { Silence, AlertmanagerAlert } from 'app/plugins/datasource/alertmanager/types'; + +import { expireSilenceAction } from '../../state/actions'; +import { makeAMLink } from '../../utils/misc'; import { CollapseToggle } from '../CollapseToggle'; import { ActionButton } from '../rules/ActionButton'; import { ActionIcon } from '../rules/ActionIcon'; -import { useStyles, Link } from '@grafana/ui'; -import SilencedAlertsTable from './SilencedAlertsTable'; -import { expireSilenceAction } from '../../state/actions'; -import { useDispatch } from 'react-redux'; + import { Matchers } from './Matchers'; import { SilenceStateTag } from './SilenceStateTag'; -import { makeAMLink } from '../../utils/misc'; -import { contextSrv } from 'app/core/services/context_srv'; +import SilencedAlertsTable from './SilencedAlertsTable'; + interface Props { className?: string; silence: Silence; diff --git a/public/app/features/alerting/unified/components/silences/SilencedAlertsTable.tsx b/public/app/features/alerting/unified/components/silences/SilencedAlertsTable.tsx index 14b08b8dc8f..94b0d802d3b 100644 --- a/public/app/features/alerting/unified/components/silences/SilencedAlertsTable.tsx +++ b/public/app/features/alerting/unified/components/silences/SilencedAlertsTable.tsx @@ -1,10 +1,13 @@ -import { AlertmanagerAlert } from 'app/plugins/datasource/alertmanager/types'; -import React, { FC } from 'react'; -import { getAlertTableStyles } from '../../styles/table'; -import { useStyles2 } from '@grafana/ui'; -import { SilencedAlertsTableRow } from './SilencedAlertsTableRow'; -import { GrafanaTheme2 } from '@grafana/data'; import { css, cx } from '@emotion/css'; +import React, { FC } from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; +import { useStyles2 } from '@grafana/ui'; +import { AlertmanagerAlert } from 'app/plugins/datasource/alertmanager/types'; + +import { getAlertTableStyles } from '../../styles/table'; + +import { SilencedAlertsTableRow } from './SilencedAlertsTableRow'; interface Props { silencedAlerts: AlertmanagerAlert[]; diff --git a/public/app/features/alerting/unified/components/silences/SilencedAlertsTableRow.tsx b/public/app/features/alerting/unified/components/silences/SilencedAlertsTableRow.tsx index 3b14a25436b..8396e48c3f9 100644 --- a/public/app/features/alerting/unified/components/silences/SilencedAlertsTableRow.tsx +++ b/public/app/features/alerting/unified/components/silences/SilencedAlertsTableRow.tsx @@ -1,8 +1,11 @@ -import { AlertmanagerAlert } from 'app/plugins/datasource/alertmanager/types'; import React, { FC, useState } from 'react'; -import { CollapseToggle } from '../CollapseToggle'; + import { intervalToAbbreviatedDurationString } from '@grafana/data'; +import { AlertmanagerAlert } from 'app/plugins/datasource/alertmanager/types'; + import { AlertLabels } from '../AlertLabels'; +import { CollapseToggle } from '../CollapseToggle'; + import { AmAlertStateTag } from './AmAlertStateTag'; interface Props { diff --git a/public/app/features/alerting/unified/components/silences/SilencesEditor.tsx b/public/app/features/alerting/unified/components/silences/SilencesEditor.tsx index dd2bcdadf64..75aac08edf2 100644 --- a/public/app/features/alerting/unified/components/silences/SilencesEditor.tsx +++ b/public/app/features/alerting/unified/components/silences/SilencesEditor.tsx @@ -1,6 +1,10 @@ -import { MatcherOperator, Silence, SilenceCreatePayload } from 'app/plugins/datasource/alertmanager/types'; +import { css, cx } from '@emotion/css'; +import { pickBy } from 'lodash'; import React, { FC, useMemo, useState } from 'react'; -import { Button, Field, FieldSet, Input, LinkButton, TextArea, useStyles2 } from '@grafana/ui'; +import { useForm, FormProvider } from 'react-hook-form'; +import { useDispatch } from 'react-redux'; +import { useDebounce } from 'react-use'; + import { DefaultTimeZone, parseDuration, @@ -10,23 +14,22 @@ import { isValidDate, GrafanaTheme2, } from '@grafana/data'; -import { useDebounce } from 'react-use'; import { config } from '@grafana/runtime'; -import { pickBy } from 'lodash'; -import MatchersField from './MatchersField'; -import { MatchedSilencedRules } from './MatchedSilencedRules'; -import { useForm, FormProvider } from 'react-hook-form'; -import { SilenceFormFields } from '../../types/silence-form'; -import { useDispatch } from 'react-redux'; -import { createOrUpdateSilenceAction } from '../../state/actions'; -import { SilencePeriod } from './SilencePeriod'; -import { css, cx } from '@emotion/css'; -import { useUnifiedAlertingSelector } from '../../hooks/useUnifiedAlertingSelector'; -import { makeAMLink } from '../../utils/misc'; +import { Button, Field, FieldSet, Input, LinkButton, TextArea, useStyles2 } from '@grafana/ui'; import { useCleanup } from 'app/core/hooks/useCleanup'; -import { parseQueryParamMatchers } from '../../utils/matchers'; -import { matcherToMatcherField, matcherFieldToMatcher } from '../../utils/alertmanager'; +import { MatcherOperator, Silence, SilenceCreatePayload } from 'app/plugins/datasource/alertmanager/types'; + import { useURLSearchParams } from '../../hooks/useURLSearchParams'; +import { useUnifiedAlertingSelector } from '../../hooks/useUnifiedAlertingSelector'; +import { createOrUpdateSilenceAction } from '../../state/actions'; +import { SilenceFormFields } from '../../types/silence-form'; +import { matcherToMatcherField, matcherFieldToMatcher } from '../../utils/alertmanager'; +import { parseQueryParamMatchers } from '../../utils/matchers'; +import { makeAMLink } from '../../utils/misc'; + +import { MatchedSilencedRules } from './MatchedSilencedRules'; +import MatchersField from './MatchersField'; +import { SilencePeriod } from './SilencePeriod'; interface Props { silence?: Silence; diff --git a/public/app/features/alerting/unified/components/silences/SilencesFilter.tsx b/public/app/features/alerting/unified/components/silences/SilencesFilter.tsx index 377a06bc63d..2d926a9fe41 100644 --- a/public/app/features/alerting/unified/components/silences/SilencesFilter.tsx +++ b/public/app/features/alerting/unified/components/silences/SilencesFilter.tsx @@ -1,13 +1,15 @@ -import React, { FormEvent, useState } from 'react'; import { css } from '@emotion/css'; -import { Label, Icon, Input, Tooltip, RadioButtonGroup, useStyles2, Button, Field } from '@grafana/ui'; -import { GrafanaTheme2, SelectableValue } from '@grafana/data'; -import { useQueryParams } from 'app/core/hooks/useQueryParams'; -import { getSilenceFiltersFromUrlParams } from '../../utils/misc'; -import { SilenceState } from 'app/plugins/datasource/alertmanager/types'; -import { parseMatchers } from '../../utils/alertmanager'; import { debounce, uniqueId } from 'lodash'; +import React, { FormEvent, useState } from 'react'; + +import { GrafanaTheme2, SelectableValue } from '@grafana/data'; import { Stack } from '@grafana/experimental'; +import { Label, Icon, Input, Tooltip, RadioButtonGroup, useStyles2, Button, Field } from '@grafana/ui'; +import { useQueryParams } from 'app/core/hooks/useQueryParams'; +import { SilenceState } from 'app/plugins/datasource/alertmanager/types'; + +import { parseMatchers } from '../../utils/alertmanager'; +import { getSilenceFiltersFromUrlParams } from '../../utils/misc'; const stateOptions: SelectableValue[] = Object.entries(SilenceState).map(([key, value]) => ({ label: key, diff --git a/public/app/features/alerting/unified/components/silences/SilencesTable.tsx b/public/app/features/alerting/unified/components/silences/SilencesTable.tsx index b70fd472166..9e7d5b44ac3 100644 --- a/public/app/features/alerting/unified/components/silences/SilencesTable.tsx +++ b/public/app/features/alerting/unified/components/silences/SilencesTable.tsx @@ -1,25 +1,28 @@ -import React, { FC, useMemo } from 'react'; -import { GrafanaTheme2, dateMath } from '@grafana/data'; -import { Icon, useStyles2, Link, Button } from '@grafana/ui'; import { css } from '@emotion/css'; -import { AlertmanagerAlert, Silence, SilenceState } from 'app/plugins/datasource/alertmanager/types'; -import { NoSilencesSplash } from './NoSilencesCTA'; -import { getSilenceFiltersFromUrlParams, makeAMLink } from '../../utils/misc'; -import { contextSrv } from 'app/core/services/context_srv'; +import React, { FC, useMemo } from 'react'; +import { useDispatch } from 'react-redux'; + +import { GrafanaTheme2, dateMath } from '@grafana/data'; +import { Stack } from '@grafana/experimental'; +import { Icon, useStyles2, Link, Button } from '@grafana/ui'; import { useQueryParams } from 'app/core/hooks/useQueryParams'; -import { SilencesFilter } from './SilencesFilter'; +import { contextSrv } from 'app/core/services/context_srv'; +import { AlertmanagerAlert, Silence, SilenceState } from 'app/plugins/datasource/alertmanager/types'; + +import { expireSilenceAction } from '../../state/actions'; +import { getInstancesPermissions } from '../../utils/access-control'; import { parseMatchers } from '../../utils/alertmanager'; +import { getSilenceFiltersFromUrlParams, makeAMLink } from '../../utils/misc'; +import { Authorize } from '../Authorize'; import { DynamicTable, DynamicTableColumnProps, DynamicTableItemProps } from '../DynamicTable'; -import { SilenceStateTag } from './SilenceStateTag'; -import { Matchers } from './Matchers'; import { ActionButton } from '../rules/ActionButton'; import { ActionIcon } from '../rules/ActionIcon'; -import { useDispatch } from 'react-redux'; -import { expireSilenceAction } from '../../state/actions'; + +import { Matchers } from './Matchers'; +import { NoSilencesSplash } from './NoSilencesCTA'; import { SilenceDetails } from './SilenceDetails'; -import { Stack } from '@grafana/experimental'; -import { Authorize } from '../Authorize'; -import { getInstancesPermissions } from '../../utils/access-control'; +import { SilenceStateTag } from './SilenceStateTag'; +import { SilencesFilter } from './SilencesFilter'; export interface SilenceTableItem extends Silence { silencedAlerts: AlertmanagerAlert[]; diff --git a/public/app/features/alerting/unified/hooks/useAlertManagerSourceName.ts b/public/app/features/alerting/unified/hooks/useAlertManagerSourceName.ts index 9ffbcd069f4..8fe2c34a600 100644 --- a/public/app/features/alerting/unified/hooks/useAlertManagerSourceName.ts +++ b/public/app/features/alerting/unified/hooks/useAlertManagerSourceName.ts @@ -1,6 +1,8 @@ +import { useCallback } from 'react'; + import { useQueryParams } from 'app/core/hooks/useQueryParams'; import store from 'app/core/store'; -import { useCallback } from 'react'; + import { ALERTMANAGER_NAME_LOCAL_STORAGE_KEY, ALERTMANAGER_NAME_QUERY_KEY } from '../utils/constants'; import { getAlertManagerDataSources, GRAFANA_RULES_SOURCE_NAME } from '../utils/datasource'; diff --git a/public/app/features/alerting/unified/hooks/useAlertQueriesStatus.ts b/public/app/features/alerting/unified/hooks/useAlertQueriesStatus.ts index b5e3c61eb05..4a7b3386a92 100644 --- a/public/app/features/alerting/unified/hooks/useAlertQueriesStatus.ts +++ b/public/app/features/alerting/unified/hooks/useAlertQueriesStatus.ts @@ -1,6 +1,7 @@ +import { useMemo } from 'react'; + import { getDataSourceSrv } from '@grafana/runtime'; import { AlertQuery } from 'app/types/unified-alerting-dto'; -import { useMemo } from 'react'; export function useAlertQueriesStatus(queries: AlertQuery[]) { const allDataSourcesAvailable = useMemo( diff --git a/public/app/features/alerting/unified/hooks/useCombinedRule.ts b/public/app/features/alerting/unified/hooks/useCombinedRule.ts index 79c517592dc..55d853abcc2 100644 --- a/public/app/features/alerting/unified/hooks/useCombinedRule.ts +++ b/public/app/features/alerting/unified/hooks/useCombinedRule.ts @@ -1,12 +1,15 @@ -import { CombinedRule, RuleIdentifier, RuleNamespace } from 'app/types/unified-alerting'; -import { RulerRulesConfigDTO } from 'app/types/unified-alerting-dto'; import { useMemo } from 'react'; import { useDispatch } from 'react-redux'; import { useAsync } from 'react-use'; + +import { CombinedRule, RuleIdentifier, RuleNamespace } from 'app/types/unified-alerting'; +import { RulerRulesConfigDTO } from 'app/types/unified-alerting-dto'; + import { fetchPromAndRulerRulesAction } from '../state/actions'; import { AsyncRequestMapSlice, AsyncRequestState, initialAsyncRequestState } from '../utils/redux'; import * as ruleId from '../utils/rule-id'; import { isRulerNotSupportedResponse } from '../utils/rules'; + import { useCombinedRuleNamespaces } from './useCombinedRuleNamespaces'; import { useUnifiedAlertingSelector } from './useUnifiedAlertingSelector'; diff --git a/public/app/features/alerting/unified/hooks/useCombinedRuleNamespaces.test.ts b/public/app/features/alerting/unified/hooks/useCombinedRuleNamespaces.test.ts index bbd6fb105f6..544b2837855 100644 --- a/public/app/features/alerting/unified/hooks/useCombinedRuleNamespaces.test.ts +++ b/public/app/features/alerting/unified/hooks/useCombinedRuleNamespaces.test.ts @@ -1,4 +1,5 @@ import { CombinedRuleGroup, CombinedRuleNamespace } from 'app/types/unified-alerting'; + import { sortRulesByName, flattenGrafanaManagedRules } from './useCombinedRuleNamespaces'; describe('flattenGrafanaManagedRules', () => { diff --git a/public/app/features/alerting/unified/hooks/useCombinedRuleNamespaces.ts b/public/app/features/alerting/unified/hooks/useCombinedRuleNamespaces.ts index 8b7afc403f5..127569f59de 100644 --- a/public/app/features/alerting/unified/hooks/useCombinedRuleNamespaces.ts +++ b/public/app/features/alerting/unified/hooks/useCombinedRuleNamespaces.ts @@ -1,3 +1,5 @@ +import { useMemo, useRef } from 'react'; + import { CombinedRule, CombinedRuleGroup, @@ -8,7 +10,7 @@ import { RulesSource, } from 'app/types/unified-alerting'; import { RulerRuleDTO, RulerRuleGroupDTO, RulerRulesConfigDTO } from 'app/types/unified-alerting-dto'; -import { useMemo, useRef } from 'react'; + import { getAllRulesSources, getRulesSourceByName, @@ -16,6 +18,7 @@ import { isGrafanaRulesSource, } from '../utils/datasource'; import { isAlertingRule, isAlertingRulerRule, isRecordingRulerRule } from '../utils/rules'; + import { useUnifiedAlertingSelector } from './useUnifiedAlertingSelector'; interface CacheValue { diff --git a/public/app/features/alerting/unified/hooks/useControlledFieldArray.ts b/public/app/features/alerting/unified/hooks/useControlledFieldArray.ts index b42831c0c36..3853c99140f 100644 --- a/public/app/features/alerting/unified/hooks/useControlledFieldArray.ts +++ b/public/app/features/alerting/unified/hooks/useControlledFieldArray.ts @@ -1,8 +1,7 @@ +import { set } from 'lodash'; import { useCallback } from 'react'; import { UseFormReturn } from 'react-hook-form'; -import { set } from 'lodash'; - interface Options { name: string; formAPI: UseFormReturn; diff --git a/public/app/features/alerting/unified/hooks/useExternalAMSelector.test.ts b/public/app/features/alerting/unified/hooks/useExternalAMSelector.test.ts index 823141fec9d..bf613686bf1 100644 --- a/public/app/features/alerting/unified/hooks/useExternalAMSelector.test.ts +++ b/public/app/features/alerting/unified/hooks/useExternalAMSelector.test.ts @@ -1,4 +1,5 @@ import * as reactRedux from 'react-redux'; + import { useExternalAmSelector } from './useExternalAmSelector'; const createMockStoreState = ( diff --git a/public/app/features/alerting/unified/hooks/useExternalAmSelector.ts b/public/app/features/alerting/unified/hooks/useExternalAmSelector.ts index 9bc63239fcb..0a87417fefc 100644 --- a/public/app/features/alerting/unified/hooks/useExternalAmSelector.ts +++ b/public/app/features/alerting/unified/hooks/useExternalAmSelector.ts @@ -1,4 +1,5 @@ import { useSelector } from 'react-redux'; + import { StoreState } from '../../../../types'; const SUFFIX_REGEX = /\/api\/v[1|2]\/alerts/i; diff --git a/public/app/features/alerting/unified/hooks/useFilteredAmGroups.ts b/public/app/features/alerting/unified/hooks/useFilteredAmGroups.ts index a47e9685979..3aa49042d93 100644 --- a/public/app/features/alerting/unified/hooks/useFilteredAmGroups.ts +++ b/public/app/features/alerting/unified/hooks/useFilteredAmGroups.ts @@ -1,6 +1,8 @@ +import { useMemo } from 'react'; + import { useQueryParams } from 'app/core/hooks/useQueryParams'; import { AlertmanagerGroup } from 'app/plugins/datasource/alertmanager/types'; -import { useMemo } from 'react'; + import { labelsMatchMatchers, parseMatchers } from '../utils/alertmanager'; import { getFiltersFromUrlParams } from '../utils/misc'; diff --git a/public/app/features/alerting/unified/hooks/useFilteredRules.ts b/public/app/features/alerting/unified/hooks/useFilteredRules.ts index b8be1dd1edb..20cf18caf17 100644 --- a/public/app/features/alerting/unified/hooks/useFilteredRules.ts +++ b/public/app/features/alerting/unified/hooks/useFilteredRules.ts @@ -1,13 +1,14 @@ import { useMemo } from 'react'; -import { CombinedRuleGroup, CombinedRuleNamespace, FilterState } from 'app/types/unified-alerting'; -import { isCloudRulesSource } from '../utils/datasource'; -import { isAlertingRule, isGrafanaRulerRule } from '../utils/rules'; -import { getFiltersFromUrlParams } from '../utils/misc'; -import { useQueryParams } from 'app/core/hooks/useQueryParams'; -import { PromRuleType, RulerGrafanaRuleDTO } from 'app/types/unified-alerting-dto'; import { getDataSourceSrv } from '@grafana/runtime'; +import { useQueryParams } from 'app/core/hooks/useQueryParams'; +import { CombinedRuleGroup, CombinedRuleNamespace, FilterState } from 'app/types/unified-alerting'; +import { PromRuleType, RulerGrafanaRuleDTO } from 'app/types/unified-alerting-dto'; + import { labelsMatchMatchers, parseMatchers } from '../utils/alertmanager'; +import { isCloudRulesSource } from '../utils/datasource'; +import { getFiltersFromUrlParams } from '../utils/misc'; +import { isAlertingRule, isGrafanaRulerRule } from '../utils/rules'; export const useFilteredRules = (namespaces: CombinedRuleNamespace[]) => { const [queryParams] = useQueryParams(); diff --git a/public/app/features/alerting/unified/hooks/useFolder.ts b/public/app/features/alerting/unified/hooks/useFolder.ts index 196c0406456..a02710b026b 100644 --- a/public/app/features/alerting/unified/hooks/useFolder.ts +++ b/public/app/features/alerting/unified/hooks/useFolder.ts @@ -1,10 +1,13 @@ -import { FolderDTO } from 'app/types'; -import { useDispatch } from 'react-redux'; -import { useUnifiedAlertingSelector } from './useUnifiedAlertingSelector'; import { useEffect } from 'react'; +import { useDispatch } from 'react-redux'; + +import { FolderDTO } from 'app/types'; + import { fetchFolderIfNotFetchedAction } from '../state/actions'; import { initialAsyncRequestState } from '../utils/redux'; +import { useUnifiedAlertingSelector } from './useUnifiedAlertingSelector'; + interface ReturnBag { folder?: FolderDTO; loading: boolean; diff --git a/public/app/features/alerting/unified/hooks/useGroupedAlerts.ts b/public/app/features/alerting/unified/hooks/useGroupedAlerts.ts index 72932587d2a..1390f21b523 100644 --- a/public/app/features/alerting/unified/hooks/useGroupedAlerts.ts +++ b/public/app/features/alerting/unified/hooks/useGroupedAlerts.ts @@ -1,7 +1,8 @@ -import { useMemo } from 'react'; -import { AlertmanagerGroup } from 'app/plugins/datasource/alertmanager/types'; -import { Labels } from '@grafana/data'; import { uniqBy } from 'lodash'; +import { useMemo } from 'react'; + +import { Labels } from '@grafana/data'; +import { AlertmanagerGroup } from 'app/plugins/datasource/alertmanager/types'; export const useGroupedAlerts = (groups: AlertmanagerGroup[], groupBy: string[]): AlertmanagerGroup[] => { return useMemo(() => { diff --git a/public/app/features/alerting/unified/hooks/useHasRuler.ts b/public/app/features/alerting/unified/hooks/useHasRuler.ts index eb326280c64..fb4d2e5960c 100644 --- a/public/app/features/alerting/unified/hooks/useHasRuler.ts +++ b/public/app/features/alerting/unified/hooks/useHasRuler.ts @@ -1,6 +1,9 @@ -import { RulesSource } from 'app/types/unified-alerting'; import { useCallback } from 'react'; + +import { RulesSource } from 'app/types/unified-alerting'; + import { GRAFANA_RULES_SOURCE_NAME } from '../utils/datasource'; + import { useUnifiedAlertingSelector } from './useUnifiedAlertingSelector'; // datasource has ruler if it's grafana managed or if we're able to load rules from it diff --git a/public/app/features/alerting/unified/hooks/useIsRuleEditable.test.tsx b/public/app/features/alerting/unified/hooks/useIsRuleEditable.test.tsx index 00812aaa472..8c2e2868787 100644 --- a/public/app/features/alerting/unified/hooks/useIsRuleEditable.test.tsx +++ b/public/app/features/alerting/unified/hooks/useIsRuleEditable.test.tsx @@ -1,10 +1,13 @@ -import React from 'react'; import { renderHook } from '@testing-library/react-hooks'; +import React from 'react'; +import { Provider } from 'react-redux'; + import { contextSrv } from 'app/core/services/context_srv'; import { configureStore } from 'app/store/configureStore'; import { AccessControlAction, FolderDTO, StoreState } from 'app/types'; -import { Provider } from 'react-redux'; + import { mockFolder, mockRulerAlertingRule, mockRulerGrafanaRule } from '../mocks'; + import { useFolder } from './useFolder'; import { useIsRuleEditable } from './useIsRuleEditable'; import { useUnifiedAlertingSelector } from './useUnifiedAlertingSelector'; diff --git a/public/app/features/alerting/unified/hooks/useIsRuleEditable.ts b/public/app/features/alerting/unified/hooks/useIsRuleEditable.ts index 5d42819b433..84ba418c685 100644 --- a/public/app/features/alerting/unified/hooks/useIsRuleEditable.ts +++ b/public/app/features/alerting/unified/hooks/useIsRuleEditable.ts @@ -1,7 +1,9 @@ import { contextSrv } from 'app/core/services/context_srv'; import { RulerRuleDTO } from 'app/types/unified-alerting-dto'; + import { getRulesPermissions } from '../utils/access-control'; import { isGrafanaRulerRule } from '../utils/rules'; + import { useFolder } from './useFolder'; import { useUnifiedAlertingSelector } from './useUnifiedAlertingSelector'; diff --git a/public/app/features/alerting/unified/hooks/useManagedAlertStateHistory.ts b/public/app/features/alerting/unified/hooks/useManagedAlertStateHistory.ts index 8fcb6a2201e..115c623a881 100644 --- a/public/app/features/alerting/unified/hooks/useManagedAlertStateHistory.ts +++ b/public/app/features/alerting/unified/hooks/useManagedAlertStateHistory.ts @@ -1,8 +1,11 @@ -import { StateHistoryItem } from 'app/types/unified-alerting'; import { useEffect } from 'react'; import { useDispatch } from 'react-redux'; + +import { StateHistoryItem } from 'app/types/unified-alerting'; + import { fetchGrafanaAnnotationsAction } from '../state/actions'; import { AsyncRequestState } from '../utils/redux'; + import { useUnifiedAlertingSelector } from './useUnifiedAlertingSelector'; export function useManagedAlertStateHistory(alertId: string) { diff --git a/public/app/features/alerting/unified/hooks/useMuteTimingOptions.ts b/public/app/features/alerting/unified/hooks/useMuteTimingOptions.ts index 650ee65ef72..843a7ec3197 100644 --- a/public/app/features/alerting/unified/hooks/useMuteTimingOptions.ts +++ b/public/app/features/alerting/unified/hooks/useMuteTimingOptions.ts @@ -1,8 +1,11 @@ +import { useMemo } from 'react'; + import { SelectableValue } from '@grafana/data'; import { AlertmanagerConfig } from 'app/plugins/datasource/alertmanager/types'; -import { useMemo } from 'react'; + import { timeIntervalToString } from '../utils/alertmanager'; import { initialAsyncRequestState } from '../utils/redux'; + import { useAlertManagerSourceName } from './useAlertManagerSourceName'; import { useUnifiedAlertingSelector } from './useUnifiedAlertingSelector'; diff --git a/public/app/features/alerting/unified/hooks/usePanelCombinedRules.ts b/public/app/features/alerting/unified/hooks/usePanelCombinedRules.ts index 7bdb4b30a72..f7d562bd647 100644 --- a/public/app/features/alerting/unified/hooks/usePanelCombinedRules.ts +++ b/public/app/features/alerting/unified/hooks/usePanelCombinedRules.ts @@ -1,14 +1,18 @@ import { SerializedError } from '@reduxjs/toolkit'; +import { useEffect, useMemo } from 'react'; +import { useDispatch } from 'react-redux'; + import { DashboardModel, PanelModel } from 'app/features/dashboard/state'; import { CombinedRule } from 'app/types/unified-alerting'; -import { useDispatch } from 'react-redux'; + import { fetchPromRulesAction, fetchRulerRulesAction } from '../state/actions'; import { Annotation, RULE_LIST_POLL_INTERVAL_MS } from '../utils/constants'; import { GRAFANA_RULES_SOURCE_NAME } from '../utils/datasource'; import { initialAsyncRequestState } from '../utils/redux'; + import { useCombinedRuleNamespaces } from './useCombinedRuleNamespaces'; import { useUnifiedAlertingSelector } from './useUnifiedAlertingSelector'; -import { useEffect, useMemo } from 'react'; + interface Options { dashboard: DashboardModel; panel: PanelModel; diff --git a/public/app/features/alerting/unified/hooks/useRuleSourcesWithRuler.ts b/public/app/features/alerting/unified/hooks/useRuleSourcesWithRuler.ts index e5d49d680ac..da9baf2d197 100644 --- a/public/app/features/alerting/unified/hooks/useRuleSourcesWithRuler.ts +++ b/public/app/features/alerting/unified/hooks/useRuleSourcesWithRuler.ts @@ -1,6 +1,8 @@ import { DataSourceInstanceSettings } from '@grafana/data'; import { PromBasedDataSource } from 'app/types/unified-alerting'; + import { getDataSourceByName } from '../utils/datasource'; + import { useUnifiedAlertingSelector } from './useUnifiedAlertingSelector'; export function useRulesSourcesWithRuler(): DataSourceInstanceSettings[] { diff --git a/public/app/features/alerting/unified/hooks/useStateHistoryModal.tsx b/public/app/features/alerting/unified/hooks/useStateHistoryModal.tsx index 980977e60e5..1e0a5a425f9 100644 --- a/public/app/features/alerting/unified/hooks/useStateHistoryModal.tsx +++ b/public/app/features/alerting/unified/hooks/useStateHistoryModal.tsx @@ -1,5 +1,7 @@ import React, { useMemo, useState } from 'react'; + import { Modal } from '@grafana/ui'; + import { StateHistory } from '../components/rules/StateHistory'; function useStateHistoryModal(alertId: string) { diff --git a/public/app/features/alerting/unified/hooks/useURLSearchParams.ts b/public/app/features/alerting/unified/hooks/useURLSearchParams.ts index 9ede7b89937..f67cecda4bb 100644 --- a/public/app/features/alerting/unified/hooks/useURLSearchParams.ts +++ b/public/app/features/alerting/unified/hooks/useURLSearchParams.ts @@ -1,5 +1,6 @@ import { useCallback, useMemo } from 'react'; import { useLocation } from 'react-router-dom'; + import { locationService } from '@grafana/runtime'; export function useURLSearchParams(): [ diff --git a/public/app/features/alerting/unified/hooks/useUnifiedAlertingSelector.ts b/public/app/features/alerting/unified/hooks/useUnifiedAlertingSelector.ts index 8593feebf97..57b335ebb47 100644 --- a/public/app/features/alerting/unified/hooks/useUnifiedAlertingSelector.ts +++ b/public/app/features/alerting/unified/hooks/useUnifiedAlertingSelector.ts @@ -1,5 +1,7 @@ -import { StoreState } from 'app/types'; import { useSelector } from 'react-redux'; + +import { StoreState } from 'app/types'; + import { UnifiedAlertingState } from '../state/reducers'; export function useUnifiedAlertingSelector( diff --git a/public/app/features/alerting/unified/hooks/useVizHeight.ts b/public/app/features/alerting/unified/hooks/useVizHeight.ts index bd3b525e735..74a6f510011 100644 --- a/public/app/features/alerting/unified/hooks/useVizHeight.ts +++ b/public/app/features/alerting/unified/hooks/useVizHeight.ts @@ -1,5 +1,6 @@ import { PanelData } from '@grafana/data'; import { useTheme2 } from '@grafana/ui'; + import { STAT, TIMESERIES } from '../utils/constants'; export function useVizHeight(data: PanelData, pluginId: string, frameIndex: number) { diff --git a/public/app/features/alerting/unified/mocks.ts b/public/app/features/alerting/unified/mocks.ts index 952037e6f44..0dcb67cca28 100644 --- a/public/app/features/alerting/unified/mocks.ts +++ b/public/app/features/alerting/unified/mocks.ts @@ -6,19 +6,8 @@ import { DataSourceRef, ScopedVars, } from '@grafana/data'; -import { - GrafanaAlertStateDecision, - GrafanaRuleDefinition, - PromAlertingRuleState, - PromRuleType, - RulerAlertingRuleDTO, - RulerGrafanaRuleDTO, - RulerRuleGroupDTO, - RulerRulesConfigDTO, -} from 'app/types/unified-alerting-dto'; -import { AlertingRule, Alert, RecordingRule, RuleGroup, RuleNamespace, CombinedRule } from 'app/types/unified-alerting'; -import { DatasourceSrv } from 'app/features/plugins/datasource_srv'; import { DataSourceSrv, GetDataSourceListFilters, config } from '@grafana/runtime'; +import { DatasourceSrv } from 'app/features/plugins/datasource_srv'; import { AlertmanagerAlert, AlertManagerCortexConfig, @@ -30,6 +19,17 @@ import { SilenceState, } from 'app/plugins/datasource/alertmanager/types'; import { FolderDTO } from 'app/types'; +import { AlertingRule, Alert, RecordingRule, RuleGroup, RuleNamespace, CombinedRule } from 'app/types/unified-alerting'; +import { + GrafanaAlertStateDecision, + GrafanaRuleDefinition, + PromAlertingRuleState, + PromRuleType, + RulerAlertingRuleDTO, + RulerGrafanaRuleDTO, + RulerRuleGroupDTO, + RulerRulesConfigDTO, +} from 'app/types/unified-alerting-dto'; let nextDataSourceId = 1; diff --git a/public/app/features/alerting/unified/state/AlertingQueryRunner.test.ts b/public/app/features/alerting/unified/state/AlertingQueryRunner.test.ts index ce5c6580251..8e716bd4153 100644 --- a/public/app/features/alerting/unified/state/AlertingQueryRunner.test.ts +++ b/public/app/features/alerting/unified/state/AlertingQueryRunner.test.ts @@ -1,3 +1,7 @@ +import { Observable, of, throwError } from 'rxjs'; +import { delay, take } from 'rxjs/operators'; +import { createFetchResponse } from 'test/helpers/createFetchResponse'; + import { ArrayVector, DataFrame, @@ -12,9 +16,7 @@ import { import { DataSourceSrv, FetchResponse } from '@grafana/runtime'; import { BackendSrv } from 'app/core/services/backend_srv'; import { AlertQuery } from 'app/types/unified-alerting-dto'; -import { Observable, of, throwError } from 'rxjs'; -import { delay, take } from 'rxjs/operators'; -import { createFetchResponse } from 'test/helpers/createFetchResponse'; + import { AlertingQueryResponse, AlertingQueryRunner } from './AlertingQueryRunner'; describe('AlertingQueryRunner', () => { diff --git a/public/app/features/alerting/unified/state/AlertingQueryRunner.ts b/public/app/features/alerting/unified/state/AlertingQueryRunner.ts index 4822898c950..7ba736c15f8 100644 --- a/public/app/features/alerting/unified/state/AlertingQueryRunner.ts +++ b/public/app/features/alerting/unified/state/AlertingQueryRunner.ts @@ -1,6 +1,7 @@ import { Observable, of, OperatorFunction, ReplaySubject, Unsubscribable } from 'rxjs'; import { catchError, map, share } from 'rxjs/operators'; import { v4 as uuidv4 } from 'uuid'; + import { dataFrameFromJSON, DataFrameJSON, @@ -13,12 +14,13 @@ import { } from '@grafana/data'; import { FetchResponse, getDataSourceSrv, toDataQueryError } from '@grafana/runtime'; import { BackendSrv, getBackendSrv } from 'app/core/services/backend_srv'; +import { isExpressionQuery } from 'app/features/expressions/guards'; +import { cancelNetworkRequestsOnUnsubscribe } from 'app/features/query/state/processing/canceler'; +import { setStructureRevision } from 'app/features/query/state/processing/revision'; import { preProcessPanelData } from 'app/features/query/state/runRequest'; import { AlertQuery } from 'app/types/unified-alerting-dto'; + import { getTimeRangeForExpression } from '../utils/timeRange'; -import { isExpressionQuery } from 'app/features/expressions/guards'; -import { setStructureRevision } from 'app/features/query/state/processing/revision'; -import { cancelNetworkRequestsOnUnsubscribe } from 'app/features/query/state/processing/canceler'; export interface AlertingQueryResult { frames: DataFrameJSON[]; diff --git a/public/app/features/alerting/unified/state/actions.ts b/public/app/features/alerting/unified/state/actions.ts index 571debd4e0b..071aefa3377 100644 --- a/public/app/features/alerting/unified/state/actions.ts +++ b/public/app/features/alerting/unified/state/actions.ts @@ -1,5 +1,7 @@ -import { getBackendSrv, locationService } from '@grafana/runtime'; import { createAsyncThunk } from '@reduxjs/toolkit'; +import { isEmpty } from 'lodash'; + +import { getBackendSrv, locationService } from '@grafana/runtime'; import { AlertmanagerAlert, AlertManagerCortexConfig, @@ -24,7 +26,7 @@ import { StateHistoryItem, } from 'app/types/unified-alerting'; import { PromApplication, RulerRulesConfigDTO } from 'app/types/unified-alerting-dto'; -import { isEmpty } from 'lodash'; + import { addAlertManagers, createOrUpdateSilence, diff --git a/public/app/features/alerting/unified/state/reducers.ts b/public/app/features/alerting/unified/state/reducers.ts index 30d2ff1d445..41d81124d22 100644 --- a/public/app/features/alerting/unified/state/reducers.ts +++ b/public/app/features/alerting/unified/state/reducers.ts @@ -1,5 +1,7 @@ import { combineReducers } from 'redux'; + import { createAsyncMapSlice, createAsyncSlice } from '../utils/redux'; + import { createOrUpdateSilenceAction, deleteAlertManagerConfigAction, diff --git a/public/app/features/alerting/unified/styles/notifications.ts b/public/app/features/alerting/unified/styles/notifications.ts index 2d5966eb4fc..162d81196f4 100644 --- a/public/app/features/alerting/unified/styles/notifications.ts +++ b/public/app/features/alerting/unified/styles/notifications.ts @@ -1,5 +1,6 @@ -import { GrafanaTheme2 } from '@grafana/data'; import { css } from '@emotion/css'; + +import { GrafanaTheme2 } from '@grafana/data'; import { AlertState } from 'app/plugins/datasource/alertmanager/types'; export const getNotificationsTextColors = (theme: GrafanaTheme2) => ({ diff --git a/public/app/features/alerting/unified/styles/table.ts b/public/app/features/alerting/unified/styles/table.ts index 8994219683e..422dd4de9a6 100644 --- a/public/app/features/alerting/unified/styles/table.ts +++ b/public/app/features/alerting/unified/styles/table.ts @@ -1,6 +1,7 @@ -import { GrafanaTheme2 } from '@grafana/data'; import { css } from '@emotion/css'; +import { GrafanaTheme2 } from '@grafana/data'; + export const getAlertTableStyles = (theme: GrafanaTheme2) => ({ table: css` width: 100%; diff --git a/public/app/features/alerting/unified/types/preview.ts b/public/app/features/alerting/unified/types/preview.ts index e94891a656c..13e6315cb92 100644 --- a/public/app/features/alerting/unified/types/preview.ts +++ b/public/app/features/alerting/unified/types/preview.ts @@ -1,5 +1,6 @@ import { PanelData } from '@grafana/data'; import { AlertQuery } from 'app/types/unified-alerting-dto'; + import { RuleFormType } from './rule-form'; export type PreviewRuleRequest = GrafanaPreviewRuleRequest | CloudPreviewRuleRequest; diff --git a/public/app/features/alerting/unified/types/receiver-form.ts b/public/app/features/alerting/unified/types/receiver-form.ts index 126dd194806..121bf6f1559 100644 --- a/public/app/features/alerting/unified/types/receiver-form.ts +++ b/public/app/features/alerting/unified/types/receiver-form.ts @@ -1,6 +1,8 @@ +import React from 'react'; + import { GrafanaManagedReceiverConfig } from 'app/plugins/datasource/alertmanager/types'; import { CloudNotifierType, NotifierType } from 'app/types'; -import React from 'react'; + import { ControlledField } from '../hooks/useControlledFieldArray'; export interface ChannelValues { diff --git a/public/app/features/alerting/unified/utils/access-control.ts b/public/app/features/alerting/unified/utils/access-control.ts index 7e9122cc636..0f03e12af10 100644 --- a/public/app/features/alerting/unified/utils/access-control.ts +++ b/public/app/features/alerting/unified/utils/access-control.ts @@ -1,6 +1,7 @@ -import { AccessControlAction } from 'app/types'; -import { isGrafanaRulesSource } from './datasource'; import { contextSrv } from 'app/core/services/context_srv'; +import { AccessControlAction } from 'app/types'; + +import { isGrafanaRulesSource } from './datasource'; type RulesSourceType = 'grafana' | 'external'; diff --git a/public/app/features/alerting/unified/utils/accessControlHooks.ts b/public/app/features/alerting/unified/utils/accessControlHooks.ts index 1181005f133..59a9b666bc6 100644 --- a/public/app/features/alerting/unified/utils/accessControlHooks.ts +++ b/public/app/features/alerting/unified/utils/accessControlHooks.ts @@ -1,4 +1,5 @@ import { useMemo } from 'react'; + import { getRulesAccess } from './access-control'; export function useRulesAccess() { diff --git a/public/app/features/alerting/unified/utils/alertmanager.test.ts b/public/app/features/alerting/unified/utils/alertmanager.test.ts index b45212275a7..bcef091a5ac 100644 --- a/public/app/features/alerting/unified/utils/alertmanager.test.ts +++ b/public/app/features/alerting/unified/utils/alertmanager.test.ts @@ -1,5 +1,6 @@ import { Matcher, MatcherOperator, Route } from 'app/plugins/datasource/alertmanager/types'; import { Labels } from 'app/types/unified-alerting-dto'; + import { parseMatcher, parseMatchers, diff --git a/public/app/features/alerting/unified/utils/alertmanager.ts b/public/app/features/alerting/unified/utils/alertmanager.ts index cf904d2dc54..d569c32442a 100644 --- a/public/app/features/alerting/unified/utils/alertmanager.ts +++ b/public/app/features/alerting/unified/utils/alertmanager.ts @@ -1,3 +1,5 @@ +import { SelectableValue } from '@grafana/data'; +import { FetchError } from '@grafana/runtime'; import { AlertManagerCortexConfig, MatcherOperator, @@ -7,11 +9,11 @@ import { TimeRange, } from 'app/plugins/datasource/alertmanager/types'; import { Labels } from 'app/types/unified-alerting-dto'; + import { MatcherFieldValue } from '../types/silence-form'; -import { SelectableValue } from '@grafana/data'; + import { getAllDataSources } from './config'; import { DataSourceType } from './datasource'; -import { FetchError } from '@grafana/runtime'; export function addDefaultsToAlertmanagerConfig(config: AlertManagerCortexConfig): AlertManagerCortexConfig { // add default receiver if it does not exist diff --git a/public/app/features/alerting/unified/utils/amroutes.ts b/public/app/features/alerting/unified/utils/amroutes.ts index 8609d24c906..39f0a31089a 100644 --- a/public/app/features/alerting/unified/utils/amroutes.ts +++ b/public/app/features/alerting/unified/utils/amroutes.ts @@ -1,12 +1,15 @@ -import { SelectableValue } from '@grafana/data'; -import { Validate } from 'react-hook-form'; -import { MatcherOperator, Route } from 'app/plugins/datasource/alertmanager/types'; -import { FormAmRoute } from '../types/amroutes'; -import { parseInterval, timeOptions } from './time'; import { isUndefined, omitBy } from 'lodash'; +import { Validate } from 'react-hook-form'; + +import { SelectableValue } from '@grafana/data'; +import { MatcherOperator, Route } from 'app/plugins/datasource/alertmanager/types'; + +import { FormAmRoute } from '../types/amroutes'; import { MatcherFieldValue } from '../types/silence-form'; + import { matcherToMatcherField, parseMatcher } from './alertmanager'; import { GRAFANA_RULES_SOURCE_NAME } from './datasource'; +import { parseInterval, timeOptions } from './time'; const defaultValueAndType: [string, string] = ['', timeOptions[0].value]; diff --git a/public/app/features/alerting/unified/utils/datasource.ts b/public/app/features/alerting/unified/utils/datasource.ts index 3d2385886fd..4a17af4c216 100644 --- a/public/app/features/alerting/unified/utils/datasource.ts +++ b/public/app/features/alerting/unified/utils/datasource.ts @@ -3,6 +3,7 @@ import { contextSrv } from 'app/core/services/context_srv'; import { AlertManagerDataSourceJsonData, AlertManagerImplementation } from 'app/plugins/datasource/alertmanager/types'; import { AccessControlAction } from 'app/types'; import { RulesSource } from 'app/types/unified-alerting'; + import { getAllDataSources } from './config'; export const GRAFANA_RULES_SOURCE_NAME = 'grafana'; diff --git a/public/app/features/alerting/unified/utils/matchers.test.ts b/public/app/features/alerting/unified/utils/matchers.test.ts index cedddfe5e55..0a073dde7c4 100644 --- a/public/app/features/alerting/unified/utils/matchers.test.ts +++ b/public/app/features/alerting/unified/utils/matchers.test.ts @@ -1,7 +1,9 @@ import { MatcherOperator } from 'app/plugins/datasource/alertmanager/types'; -import { getMatcherQueryParams, findAlertInstancesWithMatchers, parseQueryParamMatchers } from './matchers'; + import { mockPromAlert } from '../mocks'; +import { getMatcherQueryParams, findAlertInstancesWithMatchers, parseQueryParamMatchers } from './matchers'; + describe('Unified Alerting matchers', () => { describe('getMatcherQueryParams tests', () => { it('Should create an entry for each label', () => { diff --git a/public/app/features/alerting/unified/utils/matchers.ts b/public/app/features/alerting/unified/utils/matchers.ts index 619a370b40d..66fe014b2bc 100644 --- a/public/app/features/alerting/unified/utils/matchers.ts +++ b/public/app/features/alerting/unified/utils/matchers.ts @@ -1,10 +1,13 @@ -import { Matcher, MatcherOperator } from 'app/plugins/datasource/alertmanager/types'; -import { Labels } from '@grafana/data'; -import { parseMatcher } from './alertmanager'; import { uniqBy } from 'lodash'; -import { MatcherFieldValue } from '../types/silence-form'; + +import { Labels } from '@grafana/data'; +import { Matcher, MatcherOperator } from 'app/plugins/datasource/alertmanager/types'; import { Alert } from 'app/types/unified-alerting'; +import { MatcherFieldValue } from '../types/silence-form'; + +import { parseMatcher } from './alertmanager'; + // Parses a list of entries like like "['foo=bar', 'baz=~bad*']" into SilenceMatcher[] export function parseQueryParamMatchers(matcherPairs: string[]): Matcher[] { const parsedMatchers = matcherPairs.filter((x) => !!x.trim()).map((x) => parseMatcher(x.trim())); diff --git a/public/app/features/alerting/unified/utils/misc.test.ts b/public/app/features/alerting/unified/utils/misc.test.ts index c69888b374f..e07d8699771 100644 --- a/public/app/features/alerting/unified/utils/misc.test.ts +++ b/public/app/features/alerting/unified/utils/misc.test.ts @@ -1,7 +1,7 @@ import { sortAlerts } from 'app/features/alerting/unified/utils/misc'; -import { GrafanaAlertState } from 'app/types/unified-alerting-dto'; -import { Alert } from 'app/types/unified-alerting'; import { SortOrder } from 'app/plugins/panel/alertlist/types'; +import { Alert } from 'app/types/unified-alerting'; +import { GrafanaAlertState } from 'app/types/unified-alerting-dto'; function withState(state: GrafanaAlertState, labels?: {}): Alert { return { activeAt: '', annotations: {}, labels: labels || {}, state: state, value: '' }; diff --git a/public/app/features/alerting/unified/utils/misc.ts b/public/app/features/alerting/unified/utils/misc.ts index 0b61bef8ad5..71ada51cded 100644 --- a/public/app/features/alerting/unified/utils/misc.ts +++ b/public/app/features/alerting/unified/utils/misc.ts @@ -1,14 +1,16 @@ +import { sortBy } from 'lodash'; + import { urlUtil, UrlQueryMap, Labels } from '@grafana/data'; import { config } from '@grafana/runtime'; +import { alertInstanceKey } from 'app/features/alerting/unified/utils/rules'; +import { SortOrder } from 'app/plugins/panel/alertlist/types'; import { Alert, CombinedRule, FilterState, RulesSource, SilenceFilterState } from 'app/types/unified-alerting'; +import { GrafanaAlertState, PromAlertingRuleState } from 'app/types/unified-alerting-dto'; + import { ALERTMANAGER_NAME_QUERY_KEY } from './constants'; import { getRulesSourceName } from './datasource'; -import * as ruleId from './rule-id'; -import { SortOrder } from 'app/plugins/panel/alertlist/types'; -import { alertInstanceKey } from 'app/features/alerting/unified/utils/rules'; -import { sortBy } from 'lodash'; -import { GrafanaAlertState, PromAlertingRuleState } from 'app/types/unified-alerting-dto'; import { getMatcherQueryParams } from './matchers'; +import * as ruleId from './rule-id'; export function createViewLink(ruleSource: RulesSource, rule: CombinedRule, returnTo: string): string { const sourceName = getRulesSourceName(ruleSource); diff --git a/public/app/features/alerting/unified/utils/mute-timings.ts b/public/app/features/alerting/unified/utils/mute-timings.ts index c5afe46d326..47e51df4935 100644 --- a/public/app/features/alerting/unified/utils/mute-timings.ts +++ b/public/app/features/alerting/unified/utils/mute-timings.ts @@ -1,5 +1,7 @@ -import { MuteTimeInterval, TimeInterval } from 'app/plugins/datasource/alertmanager/types'; import { omitBy, isUndefined } from 'lodash'; + +import { MuteTimeInterval, TimeInterval } from 'app/plugins/datasource/alertmanager/types'; + import { MuteTimingFields, MuteTimingIntervalFields } from '../types/mute-timing-form'; export const DAYS_OF_THE_WEEK = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday']; diff --git a/public/app/features/alerting/unified/utils/query.test.ts b/public/app/features/alerting/unified/utils/query.test.ts index 185efb26870..5a593a088de 100644 --- a/public/app/features/alerting/unified/utils/query.test.ts +++ b/public/app/features/alerting/unified/utils/query.test.ts @@ -1,9 +1,10 @@ import { DataSourceJsonData, PluginMeta } from '@grafana/data'; -import { alertRuleToQueries } from './query'; -import { GRAFANA_RULES_SOURCE_NAME } from './datasource'; +import { ExpressionDatasourceUID } from 'app/features/expressions/ExpressionDatasource'; import { CombinedRule } from 'app/types/unified-alerting'; import { GrafanaAlertStateDecision } from 'app/types/unified-alerting-dto'; -import { ExpressionDatasourceUID } from 'app/features/expressions/ExpressionDatasource'; + +import { GRAFANA_RULES_SOURCE_NAME } from './datasource'; +import { alertRuleToQueries } from './query'; describe('alertRuleToQueries', () => { it('it should convert grafana alert', () => { diff --git a/public/app/features/alerting/unified/utils/query.ts b/public/app/features/alerting/unified/utils/query.ts index 835c5f33f24..7fd17d02703 100644 --- a/public/app/features/alerting/unified/utils/query.ts +++ b/public/app/features/alerting/unified/utils/query.ts @@ -3,6 +3,7 @@ import { LokiQuery } from 'app/plugins/datasource/loki/types'; import { PromQuery } from 'app/plugins/datasource/prometheus/types'; import { CombinedRule } from 'app/types/unified-alerting'; import { AlertQuery } from 'app/types/unified-alerting-dto'; + import { isCloudRulesSource, isGrafanaRulesSource } from './datasource'; import { isGrafanaRulerRule } from './rules'; diff --git a/public/app/features/alerting/unified/utils/receiver-form.ts b/public/app/features/alerting/unified/utils/receiver-form.ts index f4aa3886fa6..7c0c33dc101 100644 --- a/public/app/features/alerting/unified/utils/receiver-form.ts +++ b/public/app/features/alerting/unified/utils/receiver-form.ts @@ -1,3 +1,5 @@ +import { isArray } from 'lodash'; + import { AlertManagerCortexConfig, GrafanaManagedReceiverConfig, @@ -5,7 +7,7 @@ import { Route, } from 'app/plugins/datasource/alertmanager/types'; import { CloudNotifierType, NotifierDTO, NotifierType } from 'app/types'; -import { isArray } from 'lodash'; + import { CloudChannelConfig, CloudChannelMap, diff --git a/public/app/features/alerting/unified/utils/receivers.ts b/public/app/features/alerting/unified/utils/receivers.ts index fbde0d532ea..c599e45514b 100644 --- a/public/app/features/alerting/unified/utils/receivers.ts +++ b/public/app/features/alerting/unified/utils/receivers.ts @@ -1,7 +1,8 @@ +import { capitalize } from 'lodash'; + import { receiverTypeNames } from 'app/plugins/datasource/alertmanager/consts'; import { GrafanaManagedReceiverConfig, Receiver } from 'app/plugins/datasource/alertmanager/types'; import { NotifierDTO } from 'app/types'; -import { capitalize } from 'lodash'; // extract notifier type name to count map, eg { Slack: 1, Email: 2 } diff --git a/public/app/features/alerting/unified/utils/redux.ts b/public/app/features/alerting/unified/utils/redux.ts index 9320077dab7..d1eba541758 100644 --- a/public/app/features/alerting/unified/utils/redux.ts +++ b/public/app/features/alerting/unified/utils/redux.ts @@ -1,8 +1,9 @@ import { AsyncThunk, createSlice, Draft, isAsyncThunkAction, PayloadAction, SerializedError } from '@reduxjs/toolkit'; -import { FetchError } from '@grafana/runtime'; -import { AppEvents } from '@grafana/data'; +import { AppEvents } from '@grafana/data'; +import { FetchError } from '@grafana/runtime'; import { appEvents } from 'app/core/core'; + import { isFetchError } from './alertmanager'; export interface AsyncRequestState { diff --git a/public/app/features/alerting/unified/utils/rule-form.ts b/public/app/features/alerting/unified/utils/rule-form.ts index 36ae3b7510f..e2fe65c394c 100644 --- a/public/app/features/alerting/unified/utils/rule-form.ts +++ b/public/app/features/alerting/unified/utils/rule-form.ts @@ -23,8 +23,10 @@ import { PostableRuleGrafanaRuleDTO, RulerRuleDTO, } from 'app/types/unified-alerting-dto'; + import { EvalFunction } from '../../state/alertDef'; import { RuleFormType, RuleFormValues } from '../types/rule-form'; + import { getRulesAccess } from './access-control'; import { Annotation } from './constants'; import { isGrafanaRulesSource } from './datasource'; diff --git a/public/app/features/alerting/unified/utils/rule-id.ts b/public/app/features/alerting/unified/utils/rule-id.ts index 08454d58f12..1b580cb82d6 100644 --- a/public/app/features/alerting/unified/utils/rule-id.ts +++ b/public/app/features/alerting/unified/utils/rule-id.ts @@ -1,5 +1,6 @@ import { CombinedRule, Rule, RuleIdentifier, RuleWithLocation } from 'app/types/unified-alerting'; import { Annotations, Labels, RulerRuleDTO } from 'app/types/unified-alerting-dto'; + import { GRAFANA_RULES_SOURCE_NAME } from './datasource'; import { isAlertingRule, diff --git a/public/app/features/alerting/unified/utils/rulerClient.ts b/public/app/features/alerting/unified/utils/rulerClient.ts index 1d9c512a3dd..f8fd8ffab05 100644 --- a/public/app/features/alerting/unified/utils/rulerClient.ts +++ b/public/app/features/alerting/unified/utils/rulerClient.ts @@ -5,9 +5,11 @@ import { RulerGrafanaRuleDTO, RulerRuleGroupDTO, } from 'app/types/unified-alerting-dto'; + import { deleteRulerRulesGroup, fetchRulerRulesGroup, fetchRulerRules, setRulerRuleGroup } from '../api/ruler'; import { RuleFormValues } from '../types/rule-form'; import * as ruleId from '../utils/rule-id'; + import { GRAFANA_RULES_SOURCE_NAME } from './datasource'; import { formValuesToRulerGrafanaRuleDTO, formValuesToRulerRuleDTO } from './rule-form'; import { diff --git a/public/app/features/alerting/unified/utils/rules.ts b/public/app/features/alerting/unified/utils/rules.ts index 1e4b31a31ed..d9457c61831 100644 --- a/public/app/features/alerting/unified/utils/rules.ts +++ b/public/app/features/alerting/unified/utils/rules.ts @@ -1,13 +1,6 @@ +import { capitalize } from 'lodash'; + import { AlertState } from '@grafana/data'; -import { - GrafanaAlertState, - PromAlertingRuleState, - PromRuleType, - RulerAlertingRuleDTO, - RulerGrafanaRuleDTO, - RulerRecordingRuleDTO, - RulerRuleDTO, -} from 'app/types/unified-alerting-dto'; import { Alert, AlertingRule, @@ -21,11 +14,21 @@ import { RuleIdentifier, RuleNamespace, } from 'app/types/unified-alerting'; -import { AsyncRequestState } from './redux'; -import { RULER_NOT_SUPPORTED_MSG } from './constants'; -import { capitalize } from 'lodash'; +import { + GrafanaAlertState, + PromAlertingRuleState, + PromRuleType, + RulerAlertingRuleDTO, + RulerGrafanaRuleDTO, + RulerRecordingRuleDTO, + RulerRuleDTO, +} from 'app/types/unified-alerting-dto'; + import { State } from '../components/StateTag'; +import { RULER_NOT_SUPPORTED_MSG } from './constants'; +import { AsyncRequestState } from './redux'; + export function isAlertingRule(rule: Rule | undefined): rule is AlertingRule { return typeof rule === 'object' && rule.type === PromRuleType.Alerting; } diff --git a/public/app/features/alerting/unified/utils/time.ts b/public/app/features/alerting/unified/utils/time.ts index 7d2919bcc27..d6a18f9c634 100644 --- a/public/app/features/alerting/unified/utils/time.ts +++ b/public/app/features/alerting/unified/utils/time.ts @@ -1,4 +1,5 @@ import { describeInterval } from '@grafana/data/src/datetime/rangeutil'; + import { TimeOptions } from '../types/time'; export function parseInterval(value: string): [number, string] { diff --git a/public/app/features/alerting/unified/utils/timeRange.test.ts b/public/app/features/alerting/unified/utils/timeRange.test.ts index b3d80a3b2a0..c10535abe45 100644 --- a/public/app/features/alerting/unified/utils/timeRange.test.ts +++ b/public/app/features/alerting/unified/utils/timeRange.test.ts @@ -1,9 +1,10 @@ import { ReducerID } from '@grafana/data'; -import { getTimeRangeForExpression } from './timeRange'; -import { defaultCondition } from 'app/features/expressions/utils/expressionTypes'; import { ExpressionQuery, ExpressionQueryType } from 'app/features/expressions/types'; +import { defaultCondition } from 'app/features/expressions/utils/expressionTypes'; import { AlertQuery } from 'app/types/unified-alerting-dto'; +import { getTimeRangeForExpression } from './timeRange'; + describe('timeRange', () => { describe('getTimeRangeForExpression', () => { describe('classic condition', () => { diff --git a/public/app/features/alerting/unified/utils/timeRange.ts b/public/app/features/alerting/unified/utils/timeRange.ts index 1e335b4ebcd..10091b2c987 100644 --- a/public/app/features/alerting/unified/utils/timeRange.ts +++ b/public/app/features/alerting/unified/utils/timeRange.ts @@ -1,5 +1,6 @@ import { RelativeTimeRange } from '@grafana/data'; import { AlertQuery } from 'app/types/unified-alerting-dto'; + import { ExpressionQuery, ExpressionQueryType } from '../../../expressions/types'; const FALL_BACK_TIME_RANGE = { from: 21600, to: 0 }; diff --git a/public/app/features/alerting/utils/notificationChannel.test.ts b/public/app/features/alerting/utils/notificationChannel.test.ts index 1ef704217e0..757c9f3477f 100644 --- a/public/app/features/alerting/utils/notificationChannel.test.ts +++ b/public/app/features/alerting/utils/notificationChannel.test.ts @@ -1,6 +1,7 @@ -import { transformSubmitData } from './notificationChannels'; import { NotificationChannelDTO } from '../../../types'; +import { transformSubmitData } from './notificationChannels'; + const basicFormData: NotificationChannelDTO = { id: 1, uid: 'pX7fbbHGk', diff --git a/public/app/features/alerting/utils/notificationChannels.ts b/public/app/features/alerting/utils/notificationChannels.ts index 1aa3e36c697..7c9419ba39f 100644 --- a/public/app/features/alerting/utils/notificationChannels.ts +++ b/public/app/features/alerting/utils/notificationChannels.ts @@ -1,4 +1,5 @@ import memoizeOne from 'memoize-one'; + import { SelectableValue } from '@grafana/data'; import { config } from '@grafana/runtime'; import { NotificationChannelDTO, NotificationChannelType } from 'app/types'; diff --git a/public/app/features/annotations/api.ts b/public/app/features/annotations/api.ts index cdbaab32faf..ebb8e683650 100644 --- a/public/app/features/annotations/api.ts +++ b/public/app/features/annotations/api.ts @@ -1,5 +1,6 @@ import { AnnotationEvent } from '@grafana/data'; import { getBackendSrv } from '@grafana/runtime'; + import { AnnotationTagsResponse } from './types'; export function saveAnnotation(annotation: AnnotationEvent) { diff --git a/public/app/features/annotations/components/AnnotationResultMapper.tsx b/public/app/features/annotations/components/AnnotationResultMapper.tsx index 60fa5ad0f5d..4d7de4c4588 100644 --- a/public/app/features/annotations/components/AnnotationResultMapper.tsx +++ b/public/app/features/annotations/components/AnnotationResultMapper.tsx @@ -10,9 +10,9 @@ import { AnnotationEventFieldSource, getValueFormat, } from '@grafana/data'; +import { Select, Tooltip, Icon } from '@grafana/ui'; import { annotationEventNames, AnnotationFieldInfo } from '../standardAnnotationSupport'; -import { Select, Tooltip, Icon } from '@grafana/ui'; import { AnnotationQueryResponse } from '../types'; // const valueOptions: Array> = [ diff --git a/public/app/features/annotations/components/StandardAnnotationQueryEditor.tsx b/public/app/features/annotations/components/StandardAnnotationQueryEditor.tsx index f0937dbdac3..3cf223b504c 100644 --- a/public/app/features/annotations/components/StandardAnnotationQueryEditor.tsx +++ b/public/app/features/annotations/components/StandardAnnotationQueryEditor.tsx @@ -1,15 +1,17 @@ +import { css, cx } from '@emotion/css'; import React, { PureComponent } from 'react'; import { lastValueFrom } from 'rxjs'; -import { css, cx } from '@emotion/css'; + import { AnnotationEventMappings, AnnotationQuery, DataQuery, DataSourceApi, LoadingState } from '@grafana/data'; import { Button, Icon, IconName, Spinner } from '@grafana/ui'; - import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv'; import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv'; -import { standardAnnotationSupport } from '../standardAnnotationSupport'; -import { executeAnnotationQuery } from '../executeAnnotationQuery'; import { PanelModel } from 'app/features/dashboard/state'; + +import { executeAnnotationQuery } from '../executeAnnotationQuery'; +import { standardAnnotationSupport } from '../standardAnnotationSupport'; import { AnnotationQueryResponse } from '../types'; + import { AnnotationFieldMapper } from './AnnotationResultMapper'; interface Props { diff --git a/public/app/features/annotations/executeAnnotationQuery.ts b/public/app/features/annotations/executeAnnotationQuery.ts index 3fe88217ad3..7eab14c8cb5 100644 --- a/public/app/features/annotations/executeAnnotationQuery.ts +++ b/public/app/features/annotations/executeAnnotationQuery.ts @@ -1,11 +1,13 @@ import { Observable, of } from 'rxjs'; import { map, mergeMap } from 'rxjs/operators'; + import { CoreApp, DataQueryRequest, DataSourceApi, rangeUtil, ScopedVars } from '@grafana/data'; -import { AnnotationQueryOptions, AnnotationQueryResponse } from './types'; -import { standardAnnotationSupport } from './standardAnnotationSupport'; import { runRequest } from '../query/state/runRequest'; +import { standardAnnotationSupport } from './standardAnnotationSupport'; +import { AnnotationQueryOptions, AnnotationQueryResponse } from './types'; + let counter = 100; function getNextRequestId() { return 'AQ' + counter++; diff --git a/public/app/features/annotations/standardAnnotationSupport.test.ts b/public/app/features/annotations/standardAnnotationSupport.test.ts index 9af8c457b4e..ac57a692814 100644 --- a/public/app/features/annotations/standardAnnotationSupport.test.ts +++ b/public/app/features/annotations/standardAnnotationSupport.test.ts @@ -1,4 +1,5 @@ import { FieldType, toDataFrame } from '@grafana/data'; + import { getAnnotationsFromData } from './standardAnnotationSupport'; describe('DataFrame to annotations', () => { diff --git a/public/app/features/annotations/standardAnnotationSupport.ts b/public/app/features/annotations/standardAnnotationSupport.ts index edc6ac668ca..079a506a94b 100644 --- a/public/app/features/annotations/standardAnnotationSupport.ts +++ b/public/app/features/annotations/standardAnnotationSupport.ts @@ -1,5 +1,7 @@ +import { isString } from 'lodash'; import { Observable, of, OperatorFunction } from 'rxjs'; import { map, mergeMap } from 'rxjs/operators'; + import { AnnotationEvent, AnnotationEventFieldSource, @@ -14,8 +16,6 @@ import { standardTransformers, } from '@grafana/data'; -import { isString } from 'lodash'; - export const standardAnnotationSupport: AnnotationSupport = { /** * Assume the stored value is standard model. diff --git a/public/app/features/annotations/types.ts b/public/app/features/annotations/types.ts index 6722de3d49e..c3ee8e6d359 100644 --- a/public/app/features/annotations/types.ts +++ b/public/app/features/annotations/types.ts @@ -1,4 +1,5 @@ import { AnnotationEvent, PanelData, TimeRange } from '@grafana/data'; + import { DashboardModel, PanelModel } from '../dashboard/state'; export interface AnnotationQueryOptions { diff --git a/public/app/features/api-keys/ApiKeysActionBar.tsx b/public/app/features/api-keys/ApiKeysActionBar.tsx index ef000521a4e..ef182d1c799 100644 --- a/public/app/features/api-keys/ApiKeysActionBar.tsx +++ b/public/app/features/api-keys/ApiKeysActionBar.tsx @@ -1,4 +1,5 @@ import React, { FC } from 'react'; + import { Button, FilterInput } from '@grafana/ui'; interface Props { diff --git a/public/app/features/api-keys/ApiKeysAddedModal.test.tsx b/public/app/features/api-keys/ApiKeysAddedModal.test.tsx index 82a3d7de087..35e0a556e76 100644 --- a/public/app/features/api-keys/ApiKeysAddedModal.test.tsx +++ b/public/app/features/api-keys/ApiKeysAddedModal.test.tsx @@ -1,5 +1,6 @@ -import React from 'react'; -import { shallow } from 'enzyme'; +import { shallow } from 'enzyme'; +import React from 'react'; + import { ApiKeysAddedModal, Props } from './ApiKeysAddedModal'; const setup = (propOverrides?: object) => { diff --git a/public/app/features/api-keys/ApiKeysAddedModal.tsx b/public/app/features/api-keys/ApiKeysAddedModal.tsx index b345416b588..26bfe2b8e26 100644 --- a/public/app/features/api-keys/ApiKeysAddedModal.tsx +++ b/public/app/features/api-keys/ApiKeysAddedModal.tsx @@ -1,10 +1,12 @@ -import React, { useCallback } from 'react'; -import { css } from '@emotion/css'; -import { Alert, Field, Modal, useStyles2, Input, Icon, ClipboardButton } from '@grafana/ui'; +import { css } from '@emotion/css'; +import React, { useCallback } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; +import { Alert, Field, Modal, useStyles2, Input, Icon, ClipboardButton } from '@grafana/ui'; + import { notifyApp } from '../../core/actions'; -import { dispatch } from '../../store/store'; import { createSuccessNotification } from '../../core/copy/appNotification'; +import { dispatch } from '../../store/store'; export interface Props { onDismiss: () => void; diff --git a/public/app/features/api-keys/ApiKeysForm.tsx b/public/app/features/api-keys/ApiKeysForm.tsx index 1bf8c97c4e2..df68660ab41 100644 --- a/public/app/features/api-keys/ApiKeysForm.tsx +++ b/public/app/features/api-keys/ApiKeysForm.tsx @@ -1,10 +1,12 @@ import React, { ChangeEvent, FC, FormEvent, useEffect, useState } from 'react'; -import { EventsWithValidation, LegacyForms, ValidationEvents, Button, Select, InlineField } from '@grafana/ui'; -import { NewApiKey, OrgRole } from '../../types'; + import { rangeUtil, SelectableValue } from '@grafana/data'; -import { SlideDown } from '../../core/components/Animations/SlideDown'; +import { EventsWithValidation, LegacyForms, ValidationEvents, Button, Select, InlineField } from '@grafana/ui'; import { CloseButton } from 'app/core/components/CloseButton/CloseButton'; +import { SlideDown } from '../../core/components/Animations/SlideDown'; +import { NewApiKey, OrgRole } from '../../types'; + const { Input } = LegacyForms; const ROLE_OPTIONS: Array> = Object.keys(OrgRole).map((role) => ({ label: role, diff --git a/public/app/features/api-keys/ApiKeysPage.test.tsx b/public/app/features/api-keys/ApiKeysPage.test.tsx index eb97929c5a3..e4869316130 100644 --- a/public/app/features/api-keys/ApiKeysPage.test.tsx +++ b/public/app/features/api-keys/ApiKeysPage.test.tsx @@ -1,15 +1,18 @@ -import React from 'react'; import { render, screen, within } from '@testing-library/react'; -import { ApiKeysPageUnconnected, Props } from './ApiKeysPage'; -import { ApiKey, OrgRole } from 'app/types'; -import { NavModel } from '@grafana/data'; -import { setSearchQuery } from './state/reducers'; -import { mockToolkitActionCreator } from '../../../test/core/redux/mocks'; -import { getMultipleMockKeys } from './__mocks__/apiKeysMock'; -import { selectors } from '@grafana/e2e-selectors'; import userEvent, { PointerEventsCheckLevel } from '@testing-library/user-event'; +import React from 'react'; + +import { NavModel } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; +import { ApiKey, OrgRole } from 'app/types'; + +import { mockToolkitActionCreator } from '../../../test/core/redux/mocks'; import { silenceConsoleOutput } from '../../../test/core/utils/silenceConsoleOutput'; +import { ApiKeysPageUnconnected, Props } from './ApiKeysPage'; +import { getMultipleMockKeys } from './__mocks__/apiKeysMock'; +import { setSearchQuery } from './state/reducers'; + const setup = (propOverrides: Partial) => { const loadApiKeysMock = jest.fn(); const deleteApiKeyMock = jest.fn(); diff --git a/public/app/features/api-keys/ApiKeysPage.tsx b/public/app/features/api-keys/ApiKeysPage.tsx index 4d78f5add1f..4c95ac5db98 100644 --- a/public/app/features/api-keys/ApiKeysPage.tsx +++ b/public/app/features/api-keys/ApiKeysPage.tsx @@ -1,25 +1,27 @@ import React, { PureComponent } from 'react'; import { connect, ConnectedProps } from 'react-redux'; + // Utils -import { AccessControlAction, ApiKey, NewApiKey, StoreState } from 'app/types'; -import { getNavModel } from 'app/core/selectors/navModel'; -import { getApiKeys, getApiKeysCount, getIncludeExpired, getIncludeExpiredDisabled } from './state/selectors'; -import { addApiKey, deleteApiKey, loadApiKeys, toggleIncludeExpired } from './state/actions'; -import Page from 'app/core/components/Page/Page'; -import { ApiKeysAddedModal } from './ApiKeysAddedModal'; -import config from 'app/core/config'; +import { rangeUtil } from '@grafana/data'; +import { InlineField, InlineSwitch, VerticalGroup } from '@grafana/ui'; import appEvents from 'app/core/app_events'; import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA'; -import { InlineField, InlineSwitch, VerticalGroup } from '@grafana/ui'; -import { rangeUtil } from '@grafana/data'; -import { getTimeZone } from 'app/features/profile/state/selectors'; -import { setSearchQuery } from './state/reducers'; -import { ApiKeysForm } from './ApiKeysForm'; -import { ApiKeysActionBar } from './ApiKeysActionBar'; -import { ApiKeysTable } from './ApiKeysTable'; -import { ApiKeysController } from './ApiKeysController'; -import { ShowModalReactEvent } from 'app/types/events'; +import Page from 'app/core/components/Page/Page'; +import config from 'app/core/config'; import { contextSrv } from 'app/core/core'; +import { getNavModel } from 'app/core/selectors/navModel'; +import { getTimeZone } from 'app/features/profile/state/selectors'; +import { AccessControlAction, ApiKey, NewApiKey, StoreState } from 'app/types'; +import { ShowModalReactEvent } from 'app/types/events'; + +import { ApiKeysActionBar } from './ApiKeysActionBar'; +import { ApiKeysAddedModal } from './ApiKeysAddedModal'; +import { ApiKeysController } from './ApiKeysController'; +import { ApiKeysForm } from './ApiKeysForm'; +import { ApiKeysTable } from './ApiKeysTable'; +import { addApiKey, deleteApiKey, loadApiKeys, toggleIncludeExpired } from './state/actions'; +import { setSearchQuery } from './state/reducers'; +import { getApiKeys, getApiKeysCount, getIncludeExpired, getIncludeExpiredDisabled } from './state/selectors'; function mapStateToProps(state: StoreState) { const canRead = contextSrv.hasAccess(AccessControlAction.ActionAPIKeysRead, true); diff --git a/public/app/features/api-keys/ApiKeysTable.tsx b/public/app/features/api-keys/ApiKeysTable.tsx index ed063b1392e..b04f1e82a62 100644 --- a/public/app/features/api-keys/ApiKeysTable.tsx +++ b/public/app/features/api-keys/ApiKeysTable.tsx @@ -1,9 +1,10 @@ +import { css } from '@emotion/css'; import React, { FC } from 'react'; -import { DeleteButton, Icon, IconName, Tooltip, useTheme2 } from '@grafana/ui'; + import { dateTimeFormat, GrafanaTheme2, TimeZone } from '@grafana/data'; +import { DeleteButton, Icon, IconName, Tooltip, useTheme2 } from '@grafana/ui'; import { ApiKey } from '../../types'; -import { css } from '@emotion/css'; interface Props { apiKeys: ApiKey[]; diff --git a/public/app/features/api-keys/state/actions.ts b/public/app/features/api-keys/state/actions.ts index 22fc829866a..467f45c6f77 100644 --- a/public/app/features/api-keys/state/actions.ts +++ b/public/app/features/api-keys/state/actions.ts @@ -1,5 +1,6 @@ import { getBackendSrv } from 'app/core/services/backend_srv'; import { ApiKey, ThunkResult } from 'app/types'; + import { apiKeysLoaded, includeExpiredToggled, isFetching, setSearchQuery } from './reducers'; export function addApiKey(apiKey: ApiKey, openModal: (key: string) => void): ThunkResult { diff --git a/public/app/features/api-keys/state/reducers.test.ts b/public/app/features/api-keys/state/reducers.test.ts index 655a3d98c5b..b4048dd194f 100644 --- a/public/app/features/api-keys/state/reducers.test.ts +++ b/public/app/features/api-keys/state/reducers.test.ts @@ -1,4 +1,8 @@ -import { +import { reducerTester } from '../../../../test/core/redux/reducerTester'; +import { ApiKeysState } from '../../../types'; +import { getMultipleMockKeys } from '../__mocks__/apiKeysMock'; + +import { apiKeysLoaded, apiKeysReducer, includeExpiredToggled, @@ -6,9 +10,6 @@ isFetching, setSearchQuery, } from './reducers'; -import { getMultipleMockKeys } from '../__mocks__/apiKeysMock'; -import { reducerTester } from '../../../../test/core/redux/reducerTester'; -import { ApiKeysState } from '../../../types'; describe('API Keys reducer', () => { it('should set keys', () => { diff --git a/public/app/features/api-keys/state/selectors.test.ts b/public/app/features/api-keys/state/selectors.test.ts index 307dadeba69..e1ba2f4d0f9 100644 --- a/public/app/features/api-keys/state/selectors.test.ts +++ b/public/app/features/api-keys/state/selectors.test.ts @@ -1,6 +1,8 @@ -import { getApiKeys, getApiKeysCount, getIncludeExpired, getIncludeExpiredDisabled } from './selectors'; +import { ApiKeysState } from 'app/types'; + import { getMultipleMockKeys } from '../__mocks__/apiKeysMock'; -import { ApiKeysState } from 'app/types'; + +import { getApiKeys, getApiKeysCount, getIncludeExpired, getIncludeExpiredDisabled } from './selectors'; describe('API Keys selectors', () => { const mockKeys = getMultipleMockKeys(5); diff --git a/public/app/features/canvas/element.ts b/public/app/features/canvas/element.ts index 7a59e8aa049..16c018e023b 100644 --- a/public/app/features/canvas/element.ts +++ b/public/app/features/canvas/element.ts @@ -1,9 +1,12 @@ import { ComponentType } from 'react'; + import { RegistryItem } from '@grafana/data'; -import { BackgroundConfig, Constraint, LineConfig, Placement } from './types'; -import { DimensionContext } from '../dimensions/context'; import { PanelOptionsSupplier } from '@grafana/data/src/panel/PanelPlugin'; +import { DimensionContext } from '../dimensions/context'; + +import { BackgroundConfig, Constraint, LineConfig, Placement } from './types'; + /** * This gets saved in panel json * diff --git a/public/app/features/canvas/elements/button.tsx b/public/app/features/canvas/elements/button.tsx index 482a432b2b8..03f413012c4 100644 --- a/public/app/features/canvas/elements/button.tsx +++ b/public/app/features/canvas/elements/button.tsx @@ -1,12 +1,13 @@ import React, { PureComponent } from 'react'; -import { Button } from '@grafana/ui'; +import { Button } from '@grafana/ui'; import { DimensionContext } from 'app/features/dimensions/context'; import { TextDimensionEditor } from 'app/features/dimensions/editors/TextDimensionEditor'; import { TextDimensionConfig } from 'app/features/dimensions/types'; -import { CanvasElementItem, CanvasElementProps } from '../element'; import { APIEditor, APIEditorConfig, callApi } from 'app/plugins/panel/canvas/editor/APIEditor'; +import { CanvasElementItem, CanvasElementProps } from '../element'; + interface ButtonData { text?: string; api?: APIEditorConfig; diff --git a/public/app/features/canvas/elements/droneFront.tsx b/public/app/features/canvas/elements/droneFront.tsx index bd5a1ef9348..8de1e1b7ae9 100644 --- a/public/app/features/canvas/elements/droneFront.tsx +++ b/public/app/features/canvas/elements/droneFront.tsx @@ -1,11 +1,12 @@ -import React, { FC } from 'react'; import { css } from '@emotion/css'; +import React, { FC } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { useStyles2 } from '@grafana/ui'; - -import { ScalarDimensionEditor } from 'app/features/dimensions/editors'; -import { CanvasElementItem, CanvasElementProps } from '../element'; import { DimensionContext, ScalarDimensionConfig } from 'app/features/dimensions'; +import { ScalarDimensionEditor } from 'app/features/dimensions/editors'; + +import { CanvasElementItem, CanvasElementProps } from '../element'; interface DroneFrontData { rollAngle?: number; diff --git a/public/app/features/canvas/elements/droneSide.tsx b/public/app/features/canvas/elements/droneSide.tsx index a08577830bd..309f3673a55 100644 --- a/public/app/features/canvas/elements/droneSide.tsx +++ b/public/app/features/canvas/elements/droneSide.tsx @@ -1,11 +1,12 @@ -import React, { FC } from 'react'; import { css } from '@emotion/css'; +import React, { FC } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { useStyles2 } from '@grafana/ui'; - -import { ScalarDimensionEditor } from 'app/features/dimensions/editors'; -import { CanvasElementItem, CanvasElementProps } from '../element'; import { DimensionContext, ScalarDimensionConfig } from 'app/features/dimensions'; +import { ScalarDimensionEditor } from 'app/features/dimensions/editors'; + +import { CanvasElementItem, CanvasElementProps } from '../element'; interface DroneSideData { pitchAngle?: number; diff --git a/public/app/features/canvas/elements/droneTop.tsx b/public/app/features/canvas/elements/droneTop.tsx index 5d8eb7f6214..abac83dee8c 100644 --- a/public/app/features/canvas/elements/droneTop.tsx +++ b/public/app/features/canvas/elements/droneTop.tsx @@ -1,11 +1,12 @@ -import React, { FC } from 'react'; import { css } from '@emotion/css'; +import React, { FC } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { useStyles2 } from '@grafana/ui'; - -import { ScalarDimensionEditor } from 'app/features/dimensions/editors'; -import { CanvasElementItem, CanvasElementProps } from '../element'; import { DimensionContext, ScalarDimensionConfig } from 'app/features/dimensions'; +import { ScalarDimensionEditor } from 'app/features/dimensions/editors'; + +import { CanvasElementItem, CanvasElementProps } from '../element'; interface DroneTopData { bRightRotorRPM?: number; diff --git a/public/app/features/canvas/elements/icon.tsx b/public/app/features/canvas/elements/icon.tsx index 7a62093dbbb..fcce5a89429 100644 --- a/public/app/features/canvas/elements/icon.tsx +++ b/public/app/features/canvas/elements/icon.tsx @@ -1,20 +1,21 @@ +import { css } from '@emotion/css'; +import { isString } from 'lodash'; import React, { CSSProperties } from 'react'; +import SVG from 'react-inlinesvg'; -import { CanvasElementItem, CanvasElementProps } from '../element'; import { ColorDimensionConfig, ResourceDimensionConfig, ResourceDimensionMode, getPublicOrAbsoluteUrl, } from 'app/features/dimensions'; -import { ColorDimensionEditor, ResourceDimensionEditor } from 'app/features/dimensions/editors'; -import SVG from 'react-inlinesvg'; -import { css } from '@emotion/css'; -import { isString } from 'lodash'; -import { LineConfig } from '../types'; import { DimensionContext } from 'app/features/dimensions/context'; +import { ColorDimensionEditor, ResourceDimensionEditor } from 'app/features/dimensions/editors'; import { APIEditor, APIEditorConfig, callApi } from 'app/plugins/panel/canvas/editor/APIEditor'; +import { CanvasElementItem, CanvasElementProps } from '../element'; +import { LineConfig } from '../types'; + export interface IconConfig { path?: ResourceDimensionConfig; fill?: ColorDimensionConfig; diff --git a/public/app/features/canvas/elements/textBox.tsx b/public/app/features/canvas/elements/textBox.tsx index 477cebca0e7..e8f237a8183 100644 --- a/public/app/features/canvas/elements/textBox.tsx +++ b/public/app/features/canvas/elements/textBox.tsx @@ -1,14 +1,15 @@ +import { css } from '@emotion/css'; import React, { PureComponent } from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; +import { stylesFactory } from '@grafana/ui'; +import { config } from 'app/core/config'; +import { DimensionContext } from 'app/features/dimensions/context'; import { ColorDimensionEditor } from 'app/features/dimensions/editors/ColorDimensionEditor'; import { TextDimensionEditor } from 'app/features/dimensions/editors/TextDimensionEditor'; import { ColorDimensionConfig, TextDimensionConfig } from 'app/features/dimensions/types'; import { CanvasElementItem, CanvasElementProps } from '../element'; -import { css } from '@emotion/css'; -import { stylesFactory } from '@grafana/ui'; -import { GrafanaTheme2 } from '@grafana/data'; -import { config } from 'app/core/config'; -import { DimensionContext } from 'app/features/dimensions/context'; export enum Align { Left = 'left', diff --git a/public/app/features/canvas/elements/windTurbine.tsx b/public/app/features/canvas/elements/windTurbine.tsx index e0b636ab41f..afcf65b39f8 100644 --- a/public/app/features/canvas/elements/windTurbine.tsx +++ b/public/app/features/canvas/elements/windTurbine.tsx @@ -1,11 +1,12 @@ -import React, { FC } from 'react'; import { css } from '@emotion/css'; +import React, { FC } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { useStyles2 } from '@grafana/ui'; - -import { ScalarDimensionEditor } from 'app/features/dimensions/editors'; -import { CanvasElementItem, CanvasElementProps } from '../element'; import { DimensionContext, ScalarDimensionConfig } from 'app/features/dimensions'; +import { ScalarDimensionEditor } from 'app/features/dimensions/editors'; + +import { CanvasElementItem, CanvasElementProps } from '../element'; interface WindTurbineData { rpm?: number; diff --git a/public/app/features/canvas/registry.ts b/public/app/features/canvas/registry.ts index 6bbf24f53c7..450d0cc480f 100644 --- a/public/app/features/canvas/registry.ts +++ b/public/app/features/canvas/registry.ts @@ -1,4 +1,5 @@ import { Registry } from '@grafana/data'; + import { CanvasElementItem, CanvasElementOptions } from './element'; import { buttonItem } from './elements/button'; import { droneFrontItem } from './elements/droneFront'; diff --git a/public/app/features/canvas/runtime/element.tsx b/public/app/features/canvas/runtime/element.tsx index f8f90561e0a..17f0225a019 100644 --- a/public/app/features/canvas/runtime/element.tsx +++ b/public/app/features/canvas/runtime/element.tsx @@ -1,19 +1,21 @@ import React, { CSSProperties } from 'react'; import { OnDrag, OnResize } from 'react-moveable/declaration/types'; +import { LayerElement } from 'app/core/components/Layers/types'; import { BackgroundImageSize, CanvasElementItem, CanvasElementOptions, canvasElementRegistry, } from 'app/features/canvas'; -import { DimensionContext } from 'app/features/dimensions'; import { notFoundItem } from 'app/features/canvas/elements/notFound'; -import { GroupState } from './group'; -import { LayerElement } from 'app/core/components/Layers/types'; -import { Scene } from './scene'; +import { DimensionContext } from 'app/features/dimensions'; + import { HorizontalConstraint, Placement, VerticalConstraint } from '../types'; +import { GroupState } from './group'; +import { Scene } from './scene'; + let counter = 0; export class ElementState implements LayerElement { diff --git a/public/app/features/canvas/runtime/group.tsx b/public/app/features/canvas/runtime/group.tsx index 983c0b4986e..91e1c6a6510 100644 --- a/public/app/features/canvas/runtime/group.tsx +++ b/public/app/features/canvas/runtime/group.tsx @@ -1,15 +1,18 @@ -import React from 'react'; -import { CanvasGroupOptions, canvasElementRegistry } from 'app/features/canvas'; -import { DimensionContext } from 'app/features/dimensions'; -import { notFoundItem } from 'app/features/canvas/elements/notFound'; -import { ElementState } from './element'; -import { CanvasElementItem } from '../element'; -import { LayerActionID } from 'app/plugins/panel/canvas/types'; import { cloneDeep } from 'lodash'; -import { Scene } from './scene'; -import { RootElement } from './root'; +import React from 'react'; + +import { CanvasGroupOptions, canvasElementRegistry } from 'app/features/canvas'; +import { notFoundItem } from 'app/features/canvas/elements/notFound'; +import { DimensionContext } from 'app/features/dimensions'; +import { LayerActionID } from 'app/plugins/panel/canvas/types'; + +import { CanvasElementItem } from '../element'; import { HorizontalConstraint, Placement, VerticalConstraint } from '../types'; +import { ElementState } from './element'; +import { RootElement } from './root'; +import { Scene } from './scene'; + export const groupItemDummy: CanvasElementItem = { id: 'group', name: 'Group', diff --git a/public/app/features/canvas/runtime/root.tsx b/public/app/features/canvas/runtime/root.tsx index e5ba2f92a3b..8eebe0c01aa 100644 --- a/public/app/features/canvas/runtime/root.tsx +++ b/public/app/features/canvas/runtime/root.tsx @@ -1,4 +1,5 @@ import { CanvasGroupOptions, CanvasElementOptions } from 'app/features/canvas'; + import { GroupState } from './group'; import { Scene } from './scene'; diff --git a/public/app/features/canvas/runtime/scene.tsx b/public/app/features/canvas/runtime/scene.tsx index 809032eaf61..a0e1b934693 100644 --- a/public/app/features/canvas/runtime/scene.tsx +++ b/public/app/features/canvas/runtime/scene.tsx @@ -1,13 +1,13 @@ -import React, { CSSProperties } from 'react'; import { css } from '@emotion/css'; +import Moveable from 'moveable'; +import React, { CSSProperties } from 'react'; import { ReplaySubject, Subject } from 'rxjs'; import { first } from 'rxjs/operators'; -import Moveable from 'moveable'; import Selecto from 'selecto'; -import { config } from 'app/core/config'; import { GrafanaTheme2, PanelData } from '@grafana/data'; import { stylesFactory } from '@grafana/ui'; +import { config } from 'app/core/config'; import { CanvasGroupOptions, DEFAULT_CANVAS_ELEMENT_CONFIG } from 'app/features/canvas'; import { ColorDimensionConfig, @@ -24,11 +24,12 @@ import { getTextDimensionFromData, getScalarDimensionFromData, } from 'app/features/dimensions/utils'; -import { ElementState } from './element'; -import { RootElement } from './root'; -import { GroupState } from './group'; import { LayerActionID } from 'app/plugins/panel/canvas/types'; +import { ElementState } from './element'; +import { GroupState } from './group'; +import { RootElement } from './root'; + export interface SelectionParams { targets: Array; group?: GroupState; diff --git a/public/app/features/commandPalette/CommandPalette.tsx b/public/app/features/commandPalette/CommandPalette.tsx index 4cdcc4c069d..db0e978be14 100644 --- a/public/app/features/commandPalette/CommandPalette.tsx +++ b/public/app/features/commandPalette/CommandPalette.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react'; +import { css } from '@emotion/css'; import { KBarAnimator, KBarPortal, @@ -11,16 +11,19 @@ import { useRegisterActions, useKBar, } from 'kbar'; -import { useStyles2 } from '@grafana/ui'; -import { GrafanaTheme2 } from '@grafana/data'; -import { ResultItem } from './ResultItem'; -import getGlobalActions from './actions/global.static.actions'; -import getDashboardNavActions from './actions/dashboard.nav.actions'; +import React, { useEffect, useState } from 'react'; import { useSelector } from 'react-redux'; -import { StoreState } from 'app/types'; -import { css } from '@emotion/css'; -import { keybindingSrv } from '../../core/services/keybindingSrv'; + +import { GrafanaTheme2 } from '@grafana/data'; import { reportInteraction, locationService } from '@grafana/runtime'; +import { useStyles2 } from '@grafana/ui'; +import { StoreState } from 'app/types'; + +import { keybindingSrv } from '../../core/services/keybindingSrv'; + +import { ResultItem } from './ResultItem'; +import getDashboardNavActions from './actions/dashboard.nav.actions'; +import getGlobalActions from './actions/global.static.actions'; /** * Wrap all the components from KBar here. diff --git a/public/app/features/commandPalette/ResultItem.tsx b/public/app/features/commandPalette/ResultItem.tsx index 2b876a74f48..6f817fac456 100644 --- a/public/app/features/commandPalette/ResultItem.tsx +++ b/public/app/features/commandPalette/ResultItem.tsx @@ -1,8 +1,9 @@ -import React from 'react'; -import { ActionId, ActionImpl } from 'kbar'; -import { useTheme2 } from '@grafana/ui'; -import { GrafanaTheme2 } from '@grafana/data'; import { css } from '@emotion/css'; +import { ActionId, ActionImpl } from 'kbar'; +import React from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; +import { useTheme2 } from '@grafana/ui'; export const ResultItem = React.forwardRef( ( diff --git a/public/app/features/commandPalette/actions/dashboard.nav.actions.ts b/public/app/features/commandPalette/actions/dashboard.nav.actions.ts index 38ca11e3eb8..703b928d47c 100644 --- a/public/app/features/commandPalette/actions/dashboard.nav.actions.ts +++ b/public/app/features/commandPalette/actions/dashboard.nav.actions.ts @@ -1,6 +1,7 @@ -import { locationService, getBackendSrv } from '@grafana/runtime'; import { Action } from 'kbar'; +import { locationService, getBackendSrv } from '@grafana/runtime'; + async function getDashboardNav(parentId: string): Promise { const data: Array<{ type: string; title: string; url: string }> = await getBackendSrv().get('/api/search'); diff --git a/public/app/features/commandPalette/actions/global.static.actions.ts b/public/app/features/commandPalette/actions/global.static.actions.ts index c94f3c11c4a..ba4e745b039 100644 --- a/public/app/features/commandPalette/actions/global.static.actions.ts +++ b/public/app/features/commandPalette/actions/global.static.actions.ts @@ -1,7 +1,8 @@ -import { locationService } from '@grafana/runtime'; -import { NavModelItem } from '@grafana/data'; import { Action, Priority } from 'kbar'; +import { NavModelItem } from '@grafana/data'; +import { locationService } from '@grafana/runtime'; + export default (navBarTree: NavModelItem[]) => { const globalActions: Action[] = [ { diff --git a/public/app/features/comments/Comment.tsx b/public/app/features/comments/Comment.tsx index 7f78a65e4b3..6731fe3a656 100644 --- a/public/app/features/comments/Comment.tsx +++ b/public/app/features/comments/Comment.tsx @@ -1,8 +1,9 @@ -import React from 'react'; -import { GrafanaTheme2, renderMarkdown } from '@grafana/data'; import { css } from '@emotion/css'; -import { useStyles2 } from '@grafana/ui'; import DangerouslySetHtmlContent from 'dangerously-set-html-content'; +import React from 'react'; + +import { GrafanaTheme2, renderMarkdown } from '@grafana/data'; +import { useStyles2 } from '@grafana/ui'; import { Message } from './types'; diff --git a/public/app/features/comments/CommentManager.tsx b/public/app/features/comments/CommentManager.tsx index 3c9fce75fdb..c8d987d4885 100644 --- a/public/app/features/comments/CommentManager.tsx +++ b/public/app/features/comments/CommentManager.tsx @@ -1,7 +1,8 @@ import React, { PureComponent } from 'react'; +import { Unsubscribable } from 'rxjs'; + import { isLiveChannelMessageEvent, LiveChannelScope } from '@grafana/data'; import { getBackendSrv, getGrafanaLiveSrv } from '@grafana/runtime'; -import { Unsubscribable } from 'rxjs'; import { CommentView } from './CommentView'; import { Message, MessagePacket } from './types'; diff --git a/public/app/features/comments/CommentView.tsx b/public/app/features/comments/CommentView.tsx index 630a1621d05..a041050ae1b 100644 --- a/public/app/features/comments/CommentView.tsx +++ b/public/app/features/comments/CommentView.tsx @@ -1,5 +1,6 @@ -import React, { FormEvent, useLayoutEffect, useRef, useState } from 'react'; import { css } from '@emotion/css'; +import React, { FormEvent, useLayoutEffect, useRef, useState } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { CustomScrollbar, TextArea, useStyles2 } from '@grafana/ui'; diff --git a/public/app/features/dashboard/components/AddPanelWidget/AddPanelWidget.test.tsx b/public/app/features/dashboard/components/AddPanelWidget/AddPanelWidget.test.tsx index 4ce64244bd9..c52534ca3b0 100644 --- a/public/app/features/dashboard/components/AddPanelWidget/AddPanelWidget.test.tsx +++ b/public/app/features/dashboard/components/AddPanelWidget/AddPanelWidget.test.tsx @@ -1,8 +1,10 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; -import { AddPanelWidgetUnconnected as AddPanelWidget, Props } from './AddPanelWidget'; +import React from 'react'; + import { DashboardModel, PanelModel } from '../../state'; +import { AddPanelWidgetUnconnected as AddPanelWidget, Props } from './AddPanelWidget'; + const getTestContext = (propOverrides?: object) => { const props: Props = { dashboard: {} as DashboardModel, diff --git a/public/app/features/dashboard/components/AddPanelWidget/AddPanelWidget.tsx b/public/app/features/dashboard/components/AddPanelWidget/AddPanelWidget.tsx index a059a67818d..b3cc87dd168 100644 --- a/public/app/features/dashboard/components/AddPanelWidget/AddPanelWidget.tsx +++ b/public/app/features/dashboard/components/AddPanelWidget/AddPanelWidget.tsx @@ -1,25 +1,26 @@ -import React, { useMemo, useState } from 'react'; -import { connect, MapDispatchToProps } from 'react-redux'; import { css, cx, keyframes } from '@emotion/css'; import { chain, cloneDeep, defaults, find, sortBy } from 'lodash'; +import React, { useMemo, useState } from 'react'; +import { connect, MapDispatchToProps } from 'react-redux'; import tinycolor from 'tinycolor2'; + +import { GrafanaTheme2 } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; import { locationService, reportInteraction } from '@grafana/runtime'; import { Icon, IconButton, useStyles2 } from '@grafana/ui'; -import { selectors } from '@grafana/e2e-selectors'; -import { GrafanaTheme2 } from '@grafana/data'; - +import { CardButton } from 'app/core/components/CardButton'; import config from 'app/core/config'; +import { LS_PANEL_COPY_KEY } from 'app/core/constants'; import store from 'app/core/store'; import { addPanel } from 'app/features/dashboard/state/reducers'; -import { DashboardModel, PanelModel } from '../../state'; -import { LS_PANEL_COPY_KEY } from 'app/core/constants'; -import { LibraryElementDTO } from '../../../library-panels/types'; -import { toPanelModelLibraryPanel } from '../../../library-panels/utils'; + import { LibraryPanelsSearch, LibraryPanelsSearchVariant, } from '../../../library-panels/components/LibraryPanelsSearch/LibraryPanelsSearch'; -import { CardButton } from 'app/core/components/CardButton'; +import { LibraryElementDTO } from '../../../library-panels/types'; +import { toPanelModelLibraryPanel } from '../../../library-panels/utils'; +import { DashboardModel, PanelModel } from '../../state'; export type PanelPluginInfo = { id: any; defaults: { gridPos: { w: any; h: any }; title: any } }; diff --git a/public/app/features/dashboard/components/AnnotationSettings/AngularEditorLoader.tsx b/public/app/features/dashboard/components/AnnotationSettings/AngularEditorLoader.tsx index 0ef7279c43c..bf04402ccbb 100644 --- a/public/app/features/dashboard/components/AnnotationSettings/AngularEditorLoader.tsx +++ b/public/app/features/dashboard/components/AnnotationSettings/AngularEditorLoader.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { AnnotationQuery, DataSourceApi } from '@grafana/data'; import { AngularComponent, getAngularLoader } from '@grafana/runtime'; diff --git a/public/app/features/dashboard/components/AnnotationSettings/AnnotationSettingsEdit.tsx b/public/app/features/dashboard/components/AnnotationSettings/AnnotationSettingsEdit.tsx index 01b9c873d30..9b78743f9d2 100644 --- a/public/app/features/dashboard/components/AnnotationSettings/AnnotationSettingsEdit.tsx +++ b/public/app/features/dashboard/components/AnnotationSettings/AnnotationSettingsEdit.tsx @@ -1,12 +1,15 @@ import React, { useState } from 'react'; -import { Checkbox, CollapsableSection, ColorValueEditor, Field, HorizontalGroup, Input } from '@grafana/ui'; -import { DashboardModel } from '../../state/DashboardModel'; -import { AnnotationQuery, DataSourceInstanceSettings, getDataSourceRef } from '@grafana/data'; -import { DataSourcePicker, getDataSourceSrv } from '@grafana/runtime'; import { useAsync } from 'react-use'; -import StandardAnnotationQueryEditor from 'app/features/annotations/components/StandardAnnotationQueryEditor'; -import { AngularEditorLoader } from './AngularEditorLoader'; + +import { AnnotationQuery, DataSourceInstanceSettings, getDataSourceRef } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; +import { DataSourcePicker, getDataSourceSrv } from '@grafana/runtime'; +import { Checkbox, CollapsableSection, ColorValueEditor, Field, HorizontalGroup, Input } from '@grafana/ui'; +import StandardAnnotationQueryEditor from 'app/features/annotations/components/StandardAnnotationQueryEditor'; + +import { DashboardModel } from '../../state/DashboardModel'; + +import { AngularEditorLoader } from './AngularEditorLoader'; type Props = { editIdx: number; diff --git a/public/app/features/dashboard/components/AnnotationSettings/AnnotationSettingsList.tsx b/public/app/features/dashboard/components/AnnotationSettings/AnnotationSettingsList.tsx index e857289fc32..0e59efeb395 100644 --- a/public/app/features/dashboard/components/AnnotationSettings/AnnotationSettingsList.tsx +++ b/public/app/features/dashboard/components/AnnotationSettings/AnnotationSettingsList.tsx @@ -1,10 +1,12 @@ import React, { useState } from 'react'; -import { DeleteButton, Icon, IconButton, VerticalGroup } from '@grafana/ui'; -import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA'; -import { DashboardModel } from '../../state/DashboardModel'; -import { ListNewButton } from '../DashboardSettings/ListNewButton'; + import { arrayUtils } from '@grafana/data'; import { getDataSourceSrv } from '@grafana/runtime'; +import { DeleteButton, Icon, IconButton, VerticalGroup } from '@grafana/ui'; +import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA'; + +import { DashboardModel } from '../../state/DashboardModel'; +import { ListNewButton } from '../DashboardSettings/ListNewButton'; type Props = { dashboard: DashboardModel; diff --git a/public/app/features/dashboard/components/DashExportModal/DashboardExporter.test.ts b/public/app/features/dashboard/components/DashExportModal/DashboardExporter.test.ts index 1b8d2eda579..038812d89c6 100644 --- a/public/app/features/dashboard/components/DashExportModal/DashboardExporter.test.ts +++ b/public/app/features/dashboard/components/DashExportModal/DashboardExporter.test.ts @@ -1,13 +1,16 @@ import { find } from 'lodash'; -import config from 'app/core/config'; -import { DashboardExporter, LibraryElementExport } from './DashboardExporter'; -import { DashboardModel } from '../../state/DashboardModel'; + import { DataSourceInstanceSettings, DataSourceRef, PanelPluginMeta } from '@grafana/data'; +import config from 'app/core/config'; + +import { LibraryElementKind } from '../../../library-panels/types'; import { variableAdapters } from '../../../variables/adapters'; import { createConstantVariableAdapter } from '../../../variables/constant/adapter'; -import { createQueryVariableAdapter } from '../../../variables/query/adapter'; import { createDataSourceVariableAdapter } from '../../../variables/datasource/adapter'; -import { LibraryElementKind } from '../../../library-panels/types'; +import { createQueryVariableAdapter } from '../../../variables/query/adapter'; +import { DashboardModel } from '../../state/DashboardModel'; + +import { DashboardExporter, LibraryElementExport } from './DashboardExporter'; jest.mock('app/core/store', () => { return { diff --git a/public/app/features/dashboard/components/DashExportModal/DashboardExporter.ts b/public/app/features/dashboard/components/DashExportModal/DashboardExporter.ts index 6cc3219be7b..6fea11bd39f 100644 --- a/public/app/features/dashboard/components/DashExportModal/DashboardExporter.ts +++ b/public/app/features/dashboard/components/DashExportModal/DashboardExporter.ts @@ -1,14 +1,15 @@ import { defaults, each, sortBy } from 'lodash'; -import config from 'app/core/config'; -import { DashboardModel } from '../../state/DashboardModel'; -import { PanelModel } from 'app/features/dashboard/state'; import { PanelPluginMeta } from '@grafana/data'; import { getDataSourceSrv } from '@grafana/runtime'; -import { VariableOption, VariableRefresh } from '../../../variables/types'; -import { isConstant, isQuery } from '../../../variables/guard'; -import { LibraryElementKind } from '../../../library-panels/types'; +import config from 'app/core/config'; +import { PanelModel } from 'app/features/dashboard/state'; + import { isPanelModelLibraryPanel } from '../../../library-panels/guard'; +import { LibraryElementKind } from '../../../library-panels/types'; +import { isConstant, isQuery } from '../../../variables/guard'; +import { VariableOption, VariableRefresh } from '../../../variables/types'; +import { DashboardModel } from '../../state/DashboardModel'; interface Input { name: string; diff --git a/public/app/features/dashboard/components/DashNav/DashNav.tsx b/public/app/features/dashboard/components/DashNav/DashNav.tsx index 084e52ed1b3..558f9dacd2a 100644 --- a/public/app/features/dashboard/components/DashNav/DashNav.tsx +++ b/public/app/features/dashboard/components/DashNav/DashNav.tsx @@ -1,26 +1,24 @@ -// Libaries import React, { FC, ReactNode } from 'react'; import { connect, ConnectedProps } from 'react-redux'; import { useLocation } from 'react-router-dom'; -// Utils & Services + +import { locationUtil, textUtil } from '@grafana/data'; +import { locationService } from '@grafana/runtime'; +import { ButtonGroup, ModalsController, ToolbarButton, PageToolbar, useForceUpdate } from '@grafana/ui'; +import config from 'app/core/config'; +import { toggleKioskMode } from 'app/core/navigation/kiosk'; +import { DashboardCommentsModal } from 'app/features/dashboard/components/DashboardComments/DashboardCommentsModal'; +import { SaveDashboardProxy } from 'app/features/dashboard/components/SaveDashboard/SaveDashboardProxy'; +import { ShareModal } from 'app/features/dashboard/components/ShareModal'; import { playlistSrv } from 'app/features/playlist/PlaylistSrv'; -// Components +import { updateTimeZoneForSession } from 'app/features/profile/state/reducers'; +import { KioskMode } from 'app/types'; + +import { getDashboardSrv } from '../../services/DashboardSrv'; +import { DashboardModel } from '../../state'; + import { DashNavButton } from './DashNavButton'; import { DashNavTimeControls } from './DashNavTimeControls'; -import { ButtonGroup, ModalsController, ToolbarButton, PageToolbar, useForceUpdate } from '@grafana/ui'; -import { locationUtil, textUtil } from '@grafana/data'; -// State -import { updateTimeZoneForSession } from 'app/features/profile/state/reducers'; -// Types -import { DashboardModel } from '../../state'; -import { KioskMode } from 'app/types'; -import { ShareModal } from 'app/features/dashboard/components/ShareModal'; -import { SaveDashboardProxy } from 'app/features/dashboard/components/SaveDashboard/SaveDashboardProxy'; -import { DashboardCommentsModal } from 'app/features/dashboard/components/DashboardComments/DashboardCommentsModal'; -import { locationService } from '@grafana/runtime'; -import { toggleKioskMode } from 'app/core/navigation/kiosk'; -import { getDashboardSrv } from '../../services/DashboardSrv'; -import config from 'app/core/config'; const mapDispatchToProps = { updateTimeZoneForSession, diff --git a/public/app/features/dashboard/components/DashNav/DashNavButton.tsx b/public/app/features/dashboard/components/DashNav/DashNavButton.tsx index 5f8e3e6a2d8..48db37402ca 100644 --- a/public/app/features/dashboard/components/DashNav/DashNavButton.tsx +++ b/public/app/features/dashboard/components/DashNav/DashNavButton.tsx @@ -1,9 +1,10 @@ // Libraries -import React, { FunctionComponent, MouseEvent } from 'react'; import { css } from '@emotion/css'; +import React, { FunctionComponent, MouseEvent } from 'react'; + // Components -import { IconName, IconType, IconSize, IconButton, useTheme, stylesFactory } from '@grafana/ui'; import { GrafanaTheme } from '@grafana/data'; +import { IconName, IconType, IconSize, IconButton, useTheme, stylesFactory } from '@grafana/ui'; interface Props { icon?: IconName; diff --git a/public/app/features/dashboard/components/DashNav/DashNavTimeControls.test.tsx b/public/app/features/dashboard/components/DashNav/DashNavTimeControls.test.tsx index 29593cac102..b855f9633bb 100644 --- a/public/app/features/dashboard/components/DashNav/DashNavTimeControls.test.tsx +++ b/public/app/features/dashboard/components/DashNav/DashNavTimeControls.test.tsx @@ -1,8 +1,10 @@ -import React from 'react'; import { render } from '@testing-library/react'; -import { DashNavTimeControls } from './DashNavTimeControls'; -import { DashboardModel } from '../../state/DashboardModel'; +import React from 'react'; + import { getDashboardModel } from '../../../../../test/helpers/getDashboardModel'; +import { DashboardModel } from '../../state/DashboardModel'; + +import { DashNavTimeControls } from './DashNavTimeControls'; describe('DashNavTimeControls', () => { let dashboardModel: DashboardModel; diff --git a/public/app/features/dashboard/components/DashNav/DashNavTimeControls.tsx b/public/app/features/dashboard/components/DashNav/DashNavTimeControls.tsx index 640efa92c3a..d3f3c29a3cb 100644 --- a/public/app/features/dashboard/components/DashNav/DashNavTimeControls.tsx +++ b/public/app/features/dashboard/components/DashNav/DashNavTimeControls.tsx @@ -1,20 +1,15 @@ -// Libraries import React, { Component } from 'react'; +import { Unsubscribable } from 'rxjs'; + import { dateMath, TimeRange, TimeZone } from '@grafana/data'; import { TimeRangeUpdatedEvent } from '@grafana/runtime'; - -// Types -import { DashboardModel } from '../../state'; - -// Components import { defaultIntervals, RefreshPicker, ToolbarButtonRow } from '@grafana/ui'; import { TimePickerWithHistory } from 'app/core/components/TimePicker/TimePickerWithHistory'; - -// Utils & Services -import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv'; import { appEvents } from 'app/core/core'; +import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv'; + import { ShiftTimeEvent, ShiftTimeEventDirection, ZoomOutEvent } from '../../../../types/events'; -import { Unsubscribable } from 'rxjs'; +import { DashboardModel } from '../../state'; export interface Props { dashboard: DashboardModel; diff --git a/public/app/features/dashboard/components/DashboardComments/DashboardCommentsModal.tsx b/public/app/features/dashboard/components/DashboardComments/DashboardCommentsModal.tsx index 5f77608749c..fff48e1b531 100644 --- a/public/app/features/dashboard/components/DashboardComments/DashboardCommentsModal.tsx +++ b/public/app/features/dashboard/components/DashboardComments/DashboardCommentsModal.tsx @@ -1,9 +1,10 @@ -import React from 'react'; import { css } from '@emotion/css'; -import { Modal, useStyles2 } from '@grafana/ui'; -import { GrafanaTheme2 } from '@grafana/data'; +import React from 'react'; +import { GrafanaTheme2 } from '@grafana/data'; +import { Modal, useStyles2 } from '@grafana/ui'; import { CommentManager } from 'app/features/comments/CommentManager'; + import { DashboardModel } from '../../state/DashboardModel'; type Props = { diff --git a/public/app/features/dashboard/components/DashboardLoading/DashboardFailed.tsx b/public/app/features/dashboard/components/DashboardLoading/DashboardFailed.tsx index 4da79364423..ab6bb41f072 100644 --- a/public/app/features/dashboard/components/DashboardLoading/DashboardFailed.tsx +++ b/public/app/features/dashboard/components/DashboardLoading/DashboardFailed.tsx @@ -1,9 +1,10 @@ -import React from 'react'; import { css } from '@emotion/css'; -import { Alert, useStyles } from '@grafana/ui'; +import React from 'react'; + import { GrafanaTheme } from '@grafana/data'; -import { DashboardInitError, AppNotificationSeverity } from 'app/types'; +import { Alert, useStyles } from '@grafana/ui'; import { getMessageFromError } from 'app/core/utils/errors'; +import { DashboardInitError, AppNotificationSeverity } from 'app/types'; export interface Props { initError?: DashboardInitError; diff --git a/public/app/features/dashboard/components/DashboardLoading/DashboardLoading.tsx b/public/app/features/dashboard/components/DashboardLoading/DashboardLoading.tsx index 97ee5b5d417..0ab5f58f308 100644 --- a/public/app/features/dashboard/components/DashboardLoading/DashboardLoading.tsx +++ b/public/app/features/dashboard/components/DashboardLoading/DashboardLoading.tsx @@ -1,8 +1,9 @@ -import React from 'react'; import { css, keyframes } from '@emotion/css'; -import { Button, HorizontalGroup, Spinner, useStyles, VerticalGroup } from '@grafana/ui'; -import { locationService } from '@grafana/runtime'; +import React from 'react'; + import { GrafanaTheme } from '@grafana/data'; +import { locationService } from '@grafana/runtime'; +import { Button, HorizontalGroup, Spinner, useStyles, VerticalGroup } from '@grafana/ui'; import { DashboardInitPhase } from 'app/types'; export interface Props { diff --git a/public/app/features/dashboard/components/DashboardPermissions/AccessControlDashboardPermissions.tsx b/public/app/features/dashboard/components/DashboardPermissions/AccessControlDashboardPermissions.tsx index b43fdf49642..989786dec44 100644 --- a/public/app/features/dashboard/components/DashboardPermissions/AccessControlDashboardPermissions.tsx +++ b/public/app/features/dashboard/components/DashboardPermissions/AccessControlDashboardPermissions.tsx @@ -1,8 +1,10 @@ import React from 'react'; -import { contextSrv } from 'app/core/core'; -import { DashboardModel } from '../../state'; -import { AccessControlAction } from 'app/types'; + import { Permissions } from 'app/core/components/AccessControl'; +import { contextSrv } from 'app/core/core'; +import { AccessControlAction } from 'app/types'; + +import { DashboardModel } from '../../state'; interface Props { dashboard: DashboardModel; diff --git a/public/app/features/dashboard/components/DashboardPermissions/DashboardPermissions.tsx b/public/app/features/dashboard/components/DashboardPermissions/DashboardPermissions.tsx index 9d9488f5758..b417791bbb4 100644 --- a/public/app/features/dashboard/components/DashboardPermissions/DashboardPermissions.tsx +++ b/public/app/features/dashboard/components/DashboardPermissions/DashboardPermissions.tsx @@ -1,20 +1,22 @@ import React, { PureComponent } from 'react'; import { connect, ConnectedProps } from 'react-redux'; + import { Tooltip, Icon, Button } from '@grafana/ui'; import { SlideDown } from 'app/core/components/Animations/SlideDown'; +import AddPermission from 'app/core/components/PermissionList/AddPermission'; +import PermissionList from 'app/core/components/PermissionList/PermissionList'; +import PermissionsInfo from 'app/core/components/PermissionList/PermissionsInfo'; import { StoreState } from 'app/types'; import { DashboardAcl, PermissionLevel, NewDashboardAclItem } from 'app/types/acl'; + +import { checkFolderPermissions } from '../../../folders/state/actions'; +import { DashboardModel } from '../../state/DashboardModel'; import { getDashboardPermissions, addDashboardPermission, removeDashboardPermission, updateDashboardPermission, } from '../../state/actions'; -import { checkFolderPermissions } from '../../../folders/state/actions'; -import { DashboardModel } from '../../state/DashboardModel'; -import PermissionList from 'app/core/components/PermissionList/PermissionList'; -import AddPermission from 'app/core/components/PermissionList/AddPermission'; -import PermissionsInfo from 'app/core/components/PermissionList/PermissionsInfo'; const mapStateToProps = (state: StoreState) => ({ permissions: state.dashboard.permissions, diff --git a/public/app/features/dashboard/components/DashboardPrompt/DashboardPrompt.test.tsx b/public/app/features/dashboard/components/DashboardPrompt/DashboardPrompt.test.tsx index 6622d81152c..fc19f772d4f 100644 --- a/public/app/features/dashboard/components/DashboardPrompt/DashboardPrompt.test.tsx +++ b/public/app/features/dashboard/components/DashboardPrompt/DashboardPrompt.test.tsx @@ -1,6 +1,7 @@ +import { setContextSrv } from '../../../../core/services/context_srv'; import { DashboardModel } from '../../state/DashboardModel'; import { PanelModel } from '../../state/PanelModel'; -import { setContextSrv } from '../../../../core/services/context_srv'; + import { hasChanges, ignoreChanges } from './DashboardPrompt'; function getDefaultDashboardModel(): DashboardModel { diff --git a/public/app/features/dashboard/components/DashboardPrompt/DashboardPrompt.tsx b/public/app/features/dashboard/components/DashboardPrompt/DashboardPrompt.tsx index b6823e765e3..f694e245afe 100644 --- a/public/app/features/dashboard/components/DashboardPrompt/DashboardPrompt.tsx +++ b/public/app/features/dashboard/components/DashboardPrompt/DashboardPrompt.tsx @@ -1,19 +1,21 @@ -import { locationService } from '@grafana/runtime'; -import { contextSrv } from 'app/core/services/context_srv'; -import React, { useContext, useEffect, useState } from 'react'; -import { Prompt } from 'react-router-dom'; -import { DashboardModel } from '../../state/DashboardModel'; -import { each, filter, find } from 'lodash'; -import { UnsavedChangesModal } from '../SaveDashboard/UnsavedChangesModal'; import * as H from 'history'; -import { SaveLibraryPanelModal } from 'app/features/library-panels/components/SaveLibraryPanelModal/SaveLibraryPanelModal'; -import { PanelModelWithLibraryPanel } from 'app/features/library-panels/types'; +import { each, filter, find } from 'lodash'; +import React, { useContext, useEffect, useState } from 'react'; import { useDispatch } from 'react-redux'; -import { discardPanelChanges, exitPanelEditor } from '../PanelEditor/state/actions'; +import { Prompt } from 'react-router-dom'; + +import { locationService } from '@grafana/runtime'; import { ModalsContext } from '@grafana/ui'; import { appEvents } from 'app/core/app_events'; +import { contextSrv } from 'app/core/services/context_srv'; +import { SaveLibraryPanelModal } from 'app/features/library-panels/components/SaveLibraryPanelModal/SaveLibraryPanelModal'; +import { PanelModelWithLibraryPanel } from 'app/features/library-panels/types'; import { DashboardSavedEvent } from 'app/types/events'; +import { DashboardModel } from '../../state/DashboardModel'; +import { discardPanelChanges, exitPanelEditor } from '../PanelEditor/state/actions'; +import { UnsavedChangesModal } from '../SaveDashboard/UnsavedChangesModal'; + export interface Props { dashboard: DashboardModel; } diff --git a/public/app/features/dashboard/components/DashboardRow/DashboardRow.test.tsx b/public/app/features/dashboard/components/DashboardRow/DashboardRow.test.tsx index 9da5aa3b5b7..e35d6d1487e 100644 --- a/public/app/features/dashboard/components/DashboardRow/DashboardRow.test.tsx +++ b/public/app/features/dashboard/components/DashboardRow/DashboardRow.test.tsx @@ -1,8 +1,10 @@ -import React from 'react'; import { mount } from 'enzyme'; -import { DashboardRow } from './DashboardRow'; +import React from 'react'; + import { PanelModel } from '../../state/PanelModel'; +import { DashboardRow } from './DashboardRow'; + describe('DashboardRow', () => { let wrapper: any, panel: PanelModel, dashboardMock: any; diff --git a/public/app/features/dashboard/components/DashboardRow/DashboardRow.tsx b/public/app/features/dashboard/components/DashboardRow/DashboardRow.tsx index 6848ba1b13e..c2fbc41dbd1 100644 --- a/public/app/features/dashboard/components/DashboardRow/DashboardRow.tsx +++ b/public/app/features/dashboard/components/DashboardRow/DashboardRow.tsx @@ -1,14 +1,16 @@ -import React from 'react'; import classNames from 'classnames'; -import { Icon } from '@grafana/ui'; -import { PanelModel } from '../../state/PanelModel'; -import { DashboardModel } from '../../state/DashboardModel'; -import appEvents from 'app/core/app_events'; -import { RowOptionsButton } from '../RowOptions/RowOptionsButton'; -import { getTemplateSrv, RefreshEvent } from '@grafana/runtime'; -import { ShowConfirmModalEvent } from '../../../../types/events'; +import React from 'react'; import { Unsubscribable } from 'rxjs'; + import { selectors } from '@grafana/e2e-selectors'; +import { getTemplateSrv, RefreshEvent } from '@grafana/runtime'; +import { Icon } from '@grafana/ui'; +import appEvents from 'app/core/app_events'; + +import { ShowConfirmModalEvent } from '../../../../types/events'; +import { DashboardModel } from '../../state/DashboardModel'; +import { PanelModel } from '../../state/PanelModel'; +import { RowOptionsButton } from '../RowOptions/RowOptionsButton'; export interface DashboardRowProps { panel: PanelModel; diff --git a/public/app/features/dashboard/components/DashboardSettings/AnnotationsSettings.test.tsx b/public/app/features/dashboard/components/DashboardSettings/AnnotationsSettings.test.tsx index 8cd6ad86b25..b838b8dd479 100644 --- a/public/app/features/dashboard/components/DashboardSettings/AnnotationsSettings.test.tsx +++ b/public/app/features/dashboard/components/DashboardSettings/AnnotationsSettings.test.tsx @@ -1,13 +1,14 @@ -import React from 'react'; -import '@testing-library/jest-dom'; -import { render, screen } from '@testing-library/react'; import { within } from '@testing-library/dom'; +import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import React from 'react'; + import { selectors } from '@grafana/e2e-selectors'; import { setAngularLoader, setDataSourceSrv } from '@grafana/runtime'; -import { AnnotationsSettings } from './AnnotationsSettings'; import { mockDataSource, MockDataSourceSrv } from 'app/features/alerting/unified/mocks'; +import { AnnotationsSettings } from './AnnotationsSettings'; + describe('AnnotationsSettings', () => { let dashboard: any; diff --git a/public/app/features/dashboard/components/DashboardSettings/AnnotationsSettings.tsx b/public/app/features/dashboard/components/DashboardSettings/AnnotationsSettings.tsx index 371b6c85422..0ce57e741af 100644 --- a/public/app/features/dashboard/components/DashboardSettings/AnnotationsSettings.tsx +++ b/public/app/features/dashboard/components/DashboardSettings/AnnotationsSettings.tsx @@ -1,8 +1,11 @@ +import React, { useState } from 'react'; + import { AnnotationQuery, getDataSourceRef } from '@grafana/data'; import { getDataSourceSrv } from '@grafana/runtime'; -import React, { useState } from 'react'; + import { DashboardModel } from '../../state/DashboardModel'; import { AnnotationSettingsEdit, AnnotationSettingsList, newAnnotationName } from '../AnnotationSettings'; + import { DashboardSettingsHeader } from './DashboardSettingsHeader'; interface Props { diff --git a/public/app/features/dashboard/components/DashboardSettings/AutoRefreshIntervals.test.tsx b/public/app/features/dashboard/components/DashboardSettings/AutoRefreshIntervals.test.tsx index da52654bfb6..5f6ffb16a33 100644 --- a/public/app/features/dashboard/components/DashboardSettings/AutoRefreshIntervals.test.tsx +++ b/public/app/features/dashboard/components/DashboardSettings/AutoRefreshIntervals.test.tsx @@ -1,11 +1,13 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import React from 'react'; + import { defaultIntervals } from '@grafana/ui'; -import { AutoRefreshIntervals, getValidIntervals, Props, validateIntervals } from './AutoRefreshIntervals'; import { TimeSrv } from '../../services/TimeSrv'; +import { AutoRefreshIntervals, getValidIntervals, Props, validateIntervals } from './AutoRefreshIntervals'; + const setupTestContext = (options: Partial) => { const defaults: Props = { refreshIntervals: ['1s', '5s', '10s'], diff --git a/public/app/features/dashboard/components/DashboardSettings/AutoRefreshIntervals.tsx b/public/app/features/dashboard/components/DashboardSettings/AutoRefreshIntervals.tsx index 5554971c657..fa9ec12888b 100644 --- a/public/app/features/dashboard/components/DashboardSettings/AutoRefreshIntervals.tsx +++ b/public/app/features/dashboard/components/DashboardSettings/AutoRefreshIntervals.tsx @@ -1,4 +1,5 @@ import React, { FC, useCallback, useEffect, useMemo, useState } from 'react'; + import { Input, defaultIntervals, Field } from '@grafana/ui'; import { getTimeSrv } from '../../services/TimeSrv'; diff --git a/public/app/features/dashboard/components/DashboardSettings/DashboardSettings.tsx b/public/app/features/dashboard/components/DashboardSettings/DashboardSettings.tsx index 1a0acb63656..886716a6af1 100644 --- a/public/app/features/dashboard/components/DashboardSettings/DashboardSettings.tsx +++ b/public/app/features/dashboard/components/DashboardSettings/DashboardSettings.tsx @@ -1,25 +1,28 @@ +import { css, cx } from '@emotion/css'; +import { useDialog } from '@react-aria/dialog'; +import { FocusScope } from '@react-aria/focus'; +import { useOverlay } from '@react-aria/overlays'; import React, { useCallback, useMemo, useRef } from 'react'; import { Link } from 'react-router-dom'; -import { FocusScope } from '@react-aria/focus'; -import { useDialog } from '@react-aria/dialog'; -import { useOverlay } from '@react-aria/overlays'; -import { css, cx } from '@emotion/css'; + +import { GrafanaTheme2, locationUtil } from '@grafana/data'; +import { locationService, reportInteraction } from '@grafana/runtime'; import { Button, CustomScrollbar, Icon, IconName, PageToolbar, stylesFactory, useForceUpdate } from '@grafana/ui'; import config from 'app/core/config'; import { contextSrv } from 'app/core/services/context_srv'; -import { DashboardModel } from '../../state/DashboardModel'; -import { SaveDashboardAsButton, SaveDashboardButton } from '../SaveDashboard/SaveDashboardButton'; +import { AccessControlAction } from 'app/types'; + import { VariableEditorContainer } from '../../../variables/editor/VariableEditorContainer'; -import { DashboardPermissions } from '../DashboardPermissions/DashboardPermissions'; +import { DashboardModel } from '../../state/DashboardModel'; import { AccessControlDashboardPermissions } from '../DashboardPermissions/AccessControlDashboardPermissions'; -import { GeneralSettings } from './GeneralSettings'; +import { DashboardPermissions } from '../DashboardPermissions/DashboardPermissions'; +import { SaveDashboardAsButton, SaveDashboardButton } from '../SaveDashboard/SaveDashboardButton'; + import { AnnotationsSettings } from './AnnotationsSettings'; +import { GeneralSettings } from './GeneralSettings'; +import { JsonEditorSettings } from './JsonEditorSettings'; import { LinksSettings } from './LinksSettings'; import { VersionsSettings } from './VersionsSettings'; -import { JsonEditorSettings } from './JsonEditorSettings'; -import { GrafanaTheme2, locationUtil } from '@grafana/data'; -import { locationService, reportInteraction } from '@grafana/runtime'; -import { AccessControlAction } from 'app/types'; export interface Props { dashboard: DashboardModel; diff --git a/public/app/features/dashboard/components/DashboardSettings/DashboardSettingsHeader.tsx b/public/app/features/dashboard/components/DashboardSettings/DashboardSettingsHeader.tsx index e17ee1daa3c..4e1485f9239 100644 --- a/public/app/features/dashboard/components/DashboardSettings/DashboardSettingsHeader.tsx +++ b/public/app/features/dashboard/components/DashboardSettings/DashboardSettingsHeader.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { Icon, HorizontalGroup } from '@grafana/ui'; type Props = { diff --git a/public/app/features/dashboard/components/DashboardSettings/GeneralSettings.test.tsx b/public/app/features/dashboard/components/DashboardSettings/GeneralSettings.test.tsx index 97bf20e1f50..c7f17b17dc0 100644 --- a/public/app/features/dashboard/components/DashboardSettings/GeneralSettings.test.tsx +++ b/public/app/features/dashboard/components/DashboardSettings/GeneralSettings.test.tsx @@ -1,12 +1,14 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import React from 'react'; +import { byRole } from 'testing-library-selector'; + +import { selectors } from '@grafana/e2e-selectors'; import { selectOptionInTest } from '@grafana/ui'; -import { byRole } from 'testing-library-selector'; -import { GeneralSettingsUnconnected as GeneralSettings, Props } from './GeneralSettings'; import { DashboardModel } from '../../state'; -import { selectors } from '@grafana/e2e-selectors'; + +import { GeneralSettingsUnconnected as GeneralSettings, Props } from './GeneralSettings'; const setupTestContext = (options: Partial) => { const defaults: Props = { diff --git a/public/app/features/dashboard/components/DashboardSettings/GeneralSettings.tsx b/public/app/features/dashboard/components/DashboardSettings/GeneralSettings.tsx index 9b2d3e77c8f..1ddfc1a4cef 100644 --- a/public/app/features/dashboard/components/DashboardSettings/GeneralSettings.tsx +++ b/public/app/features/dashboard/components/DashboardSettings/GeneralSettings.tsx @@ -1,16 +1,18 @@ import React, { useState } from 'react'; import { connect, ConnectedProps } from 'react-redux'; + import { TimeZone } from '@grafana/data'; -import { CollapsableSection, Field, Input, RadioButtonGroup, TagsInput } from '@grafana/ui'; import { selectors } from '@grafana/e2e-selectors'; +import { config } from '@grafana/runtime'; +import { CollapsableSection, Field, Input, RadioButtonGroup, TagsInput } from '@grafana/ui'; import { FolderPicker } from 'app/core/components/Select/FolderPicker'; +import { updateTimeZoneDashboard, updateWeekStartDashboard } from 'app/features/dashboard/state/actions'; + import { DashboardModel } from '../../state/DashboardModel'; import { DeleteDashboardButton } from '../DeleteDashboard/DeleteDashboardButton'; -import { TimePickerSettings } from './TimePickerSettings'; -import { updateTimeZoneDashboard, updateWeekStartDashboard } from 'app/features/dashboard/state/actions'; import { PreviewSettings } from './PreviewSettings'; -import { config } from '@grafana/runtime'; +import { TimePickerSettings } from './TimePickerSettings'; interface OwnProps { dashboard: DashboardModel; diff --git a/public/app/features/dashboard/components/DashboardSettings/JsonEditorSettings.tsx b/public/app/features/dashboard/components/DashboardSettings/JsonEditorSettings.tsx index e5da865a634..55e9317942e 100644 --- a/public/app/features/dashboard/components/DashboardSettings/JsonEditorSettings.tsx +++ b/public/app/features/dashboard/components/DashboardSettings/JsonEditorSettings.tsx @@ -1,11 +1,13 @@ -import React, { useState } from 'react'; import { css } from '@emotion/css'; +import React, { useState } from 'react'; import AutoSizer from 'react-virtualized-auto-sizer'; + +import { GrafanaTheme2 } from '@grafana/data'; import { Button, CodeEditor, HorizontalGroup, useStyles2 } from '@grafana/ui'; import { dashboardWatcher } from 'app/features/live/dashboard/dashboardWatcher'; + import { getDashboardSrv } from '../../services/DashboardSrv'; import { DashboardModel } from '../../state/DashboardModel'; -import { GrafanaTheme2 } from '@grafana/data'; interface Props { dashboard: DashboardModel; diff --git a/public/app/features/dashboard/components/DashboardSettings/LinksSettings.test.tsx b/public/app/features/dashboard/components/DashboardSettings/LinksSettings.test.tsx index db38118db3a..f0156b67067 100644 --- a/public/app/features/dashboard/components/DashboardSettings/LinksSettings.test.tsx +++ b/public/app/features/dashboard/components/DashboardSettings/LinksSettings.test.tsx @@ -1,8 +1,8 @@ -import React from 'react'; -import '@testing-library/jest-dom'; -import { render, screen } from '@testing-library/react'; import { within } from '@testing-library/dom'; +import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import React from 'react'; + import { selectors } from '@grafana/e2e-selectors'; import { LinksSettings } from './LinksSettings'; diff --git a/public/app/features/dashboard/components/DashboardSettings/LinksSettings.tsx b/public/app/features/dashboard/components/DashboardSettings/LinksSettings.tsx index 4b3eebac82e..b000a62e4ae 100644 --- a/public/app/features/dashboard/components/DashboardSettings/LinksSettings.tsx +++ b/public/app/features/dashboard/components/DashboardSettings/LinksSettings.tsx @@ -1,7 +1,9 @@ import React, { useState } from 'react'; + import { DashboardModel } from '../../state/DashboardModel'; import { LinkSettingsEdit, LinkSettingsList } from '../LinksSettings'; import { newLink } from '../LinksSettings/LinkSettingsEdit'; + import { DashboardSettingsHeader } from './DashboardSettingsHeader'; interface Props { dashboard: DashboardModel; diff --git a/public/app/features/dashboard/components/DashboardSettings/ListNewButton.tsx b/public/app/features/dashboard/components/DashboardSettings/ListNewButton.tsx index be40e1ddb7f..2f16558d0b0 100644 --- a/public/app/features/dashboard/components/DashboardSettings/ListNewButton.tsx +++ b/public/app/features/dashboard/components/DashboardSettings/ListNewButton.tsx @@ -1,7 +1,8 @@ -import React, { ButtonHTMLAttributes } from 'react'; -import { Button, useStyles } from '@grafana/ui'; -import { GrafanaTheme } from '@grafana/data'; import { css } from '@emotion/css'; +import React, { ButtonHTMLAttributes } from 'react'; + +import { GrafanaTheme } from '@grafana/data'; +import { Button, useStyles } from '@grafana/ui'; export interface Props extends ButtonHTMLAttributes {} diff --git a/public/app/features/dashboard/components/DashboardSettings/PreviewSettings.tsx b/public/app/features/dashboard/components/DashboardSettings/PreviewSettings.tsx index 0e7202b0a74..407c2f96783 100644 --- a/public/app/features/dashboard/components/DashboardSettings/PreviewSettings.tsx +++ b/public/app/features/dashboard/components/DashboardSettings/PreviewSettings.tsx @@ -1,7 +1,8 @@ import React, { PureComponent } from 'react'; + import { Button, CollapsableSection, FileUpload } from '@grafana/ui'; -import { getThumbnailURL } from 'app/features/search/components/SearchCard'; import { getBackendSrv } from 'app/core/services/backend_srv'; +import { getThumbnailURL } from 'app/features/search/components/SearchCard'; interface Props { uid: string; diff --git a/public/app/features/dashboard/components/DashboardSettings/TimePickerSettings.tsx b/public/app/features/dashboard/components/DashboardSettings/TimePickerSettings.tsx index d4374ca35eb..e52c92cd2e3 100644 --- a/public/app/features/dashboard/components/DashboardSettings/TimePickerSettings.tsx +++ b/public/app/features/dashboard/components/DashboardSettings/TimePickerSettings.tsx @@ -1,8 +1,10 @@ -import React, { PureComponent } from 'react'; -import { CollapsableSection, Field, Input, Switch, TimeZonePicker, WeekStartPicker } from '@grafana/ui'; -import { rangeUtil, TimeZone } from '@grafana/data'; import { isEmpty } from 'lodash'; +import React, { PureComponent } from 'react'; + +import { rangeUtil, TimeZone } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; +import { CollapsableSection, Field, Input, Switch, TimeZonePicker, WeekStartPicker } from '@grafana/ui'; + import { AutoRefreshIntervals } from './AutoRefreshIntervals'; interface Props { diff --git a/public/app/features/dashboard/components/DashboardSettings/VersionsSettings.test.tsx b/public/app/features/dashboard/components/DashboardSettings/VersionsSettings.test.tsx index 2c312ec181c..75baf12aa16 100644 --- a/public/app/features/dashboard/components/DashboardSettings/VersionsSettings.test.tsx +++ b/public/app/features/dashboard/components/DashboardSettings/VersionsSettings.test.tsx @@ -1,12 +1,13 @@ -import React from 'react'; -import '@testing-library/jest-dom'; -import { render, screen, waitFor } from '@testing-library/react'; import { within } from '@testing-library/dom'; +import { render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import { UserEvent } from '@testing-library/user-event/dist/types/setup'; +import React from 'react'; + import { historySrv } from '../VersionHistory/HistorySrv'; + import { VersionsSettings, VERSIONS_FETCH_LIMIT } from './VersionsSettings'; import { versions, diffs } from './__mocks__/versions'; -import { UserEvent } from '@testing-library/user-event/dist/types/setup'; jest.mock('../VersionHistory/HistorySrv'); diff --git a/public/app/features/dashboard/components/DashboardSettings/VersionsSettings.tsx b/public/app/features/dashboard/components/DashboardSettings/VersionsSettings.tsx index f5702c2eb5a..448683461b9 100644 --- a/public/app/features/dashboard/components/DashboardSettings/VersionsSettings.tsx +++ b/public/app/features/dashboard/components/DashboardSettings/VersionsSettings.tsx @@ -1,5 +1,7 @@ import React, { PureComponent } from 'react'; + import { Spinner, HorizontalGroup } from '@grafana/ui'; + import { DashboardModel } from '../../state/DashboardModel'; import { historySrv, diff --git a/public/app/features/dashboard/components/DeleteDashboard/DeleteDashboardButton.tsx b/public/app/features/dashboard/components/DeleteDashboard/DeleteDashboardButton.tsx index a32207fc831..8b8ec48e753 100644 --- a/public/app/features/dashboard/components/DeleteDashboard/DeleteDashboardButton.tsx +++ b/public/app/features/dashboard/components/DeleteDashboard/DeleteDashboardButton.tsx @@ -1,8 +1,11 @@ import React from 'react'; -import { DeleteDashboardModal } from './DeleteDashboardModal'; + import { Button, ModalsController } from '@grafana/ui'; + import { DashboardModel } from '../../state'; +import { DeleteDashboardModal } from './DeleteDashboardModal'; + type Props = { dashboard: DashboardModel; }; diff --git a/public/app/features/dashboard/components/DeleteDashboard/DeleteDashboardModal.tsx b/public/app/features/dashboard/components/DeleteDashboard/DeleteDashboardModal.tsx index 97ea543fb3e..11a62a02e3d 100644 --- a/public/app/features/dashboard/components/DeleteDashboard/DeleteDashboardModal.tsx +++ b/public/app/features/dashboard/components/DeleteDashboard/DeleteDashboardModal.tsx @@ -1,12 +1,15 @@ -import React from 'react'; import { css } from '@emotion/css'; import { sumBy } from 'lodash'; -import { Modal, ConfirmModal, Button } from '@grafana/ui'; -import { DashboardModel, PanelModel } from '../../state'; -import { useDashboardDelete } from './useDashboardDelete'; +import React from 'react'; import useAsyncFn from 'react-use/lib/useAsyncFn'; + +import { Modal, ConfirmModal, Button } from '@grafana/ui'; import { config } from 'app/core/config'; +import { DashboardModel, PanelModel } from '../../state'; + +import { useDashboardDelete } from './useDashboardDelete'; + type DeleteDashboardModalProps = { hideModal(): void; dashboard: DashboardModel; diff --git a/public/app/features/dashboard/components/DeleteDashboard/useDashboardDelete.tsx b/public/app/features/dashboard/components/DeleteDashboard/useDashboardDelete.tsx index 263c45f7c1e..ed9429909c5 100644 --- a/public/app/features/dashboard/components/DeleteDashboard/useDashboardDelete.tsx +++ b/public/app/features/dashboard/components/DeleteDashboard/useDashboardDelete.tsx @@ -1,8 +1,9 @@ import { useEffect } from 'react'; import { useAsyncFn } from 'react-use'; + +import { locationService } from '@grafana/runtime'; import { useAppNotification } from 'app/core/copy/appNotification'; import { deleteDashboard } from 'app/features/manage-dashboards/state/actions'; -import { locationService } from '@grafana/runtime'; export const useDashboardDelete = (uid: string) => { const [state, onDeleteDashboard] = useAsyncFn(() => deleteDashboard(uid, false), []); diff --git a/public/app/features/dashboard/components/Inspector/InspectContent.tsx b/public/app/features/dashboard/components/Inspector/InspectContent.tsx index b9852f42821..daa3608548d 100644 --- a/public/app/features/dashboard/components/Inspector/InspectContent.tsx +++ b/public/app/features/dashboard/components/Inspector/InspectContent.tsx @@ -1,16 +1,18 @@ import React, { useState } from 'react'; + import { DataSourceApi, formattedValueToString, getValueFormat, PanelData, PanelPlugin } from '@grafana/data'; import { getTemplateSrv } from '@grafana/runtime'; import { Drawer, Tab, TabsBar } from '@grafana/ui'; -import { InspectMetadataTab } from 'app/features/inspector/InspectMetadataTab'; -import { InspectJSONTab } from 'app/features/inspector/InspectJSONTab'; -import { QueryInspector } from 'app/features/inspector/QueryInspector'; -import { InspectStatsTab } from 'app/features/inspector/InspectStatsTab'; -import { InspectErrorTab } from 'app/features/inspector/InspectErrorTab'; import { InspectDataTab } from 'app/features/inspector/InspectDataTab'; +import { InspectErrorTab } from 'app/features/inspector/InspectErrorTab'; +import { InspectJSONTab } from 'app/features/inspector/InspectJSONTab'; +import { InspectMetadataTab } from 'app/features/inspector/InspectMetadataTab'; +import { InspectStatsTab } from 'app/features/inspector/InspectStatsTab'; +import { QueryInspector } from 'app/features/inspector/QueryInspector'; import { InspectTab } from 'app/features/inspector/types'; -import { DashboardModel, PanelModel } from '../../state'; + import { GetDataOptions } from '../../../query/state/PanelQueryRunner'; +import { DashboardModel, PanelModel } from '../../state'; interface Props { dashboard: DashboardModel; diff --git a/public/app/features/dashboard/components/Inspector/PanelInspectActions.tsx b/public/app/features/dashboard/components/Inspector/PanelInspectActions.tsx index 795f7a897d0..e66449ae3f4 100644 --- a/public/app/features/dashboard/components/Inspector/PanelInspectActions.tsx +++ b/public/app/features/dashboard/components/Inspector/PanelInspectActions.tsx @@ -1,3 +1,7 @@ +import React, { ComponentType } from 'react'; + +import { PanelData } from '@grafana/data'; + import { PanelModel } from '../../state'; export interface PanelInspectActionProps { @@ -51,9 +55,6 @@ export interface PanelInspectActionSupplier { // NOTE: This is an internal/experimental API/hack and will change! // (window as any).grafanaPanelInspectActionSupplier = dummySupplier; -import React, { ComponentType } from 'react'; -import { PanelData } from '@grafana/data'; - interface InspectActionsTabProps { panel: PanelModel; data?: PanelData; diff --git a/public/app/features/dashboard/components/Inspector/PanelInspector.tsx b/public/app/features/dashboard/components/Inspector/PanelInspector.tsx index 568149226a1..f0b9cb05111 100644 --- a/public/app/features/dashboard/components/Inspector/PanelInspector.tsx +++ b/public/app/features/dashboard/components/Inspector/PanelInspector.tsx @@ -1,16 +1,19 @@ import React, { useState } from 'react'; import { connect, MapStateToProps } from 'react-redux'; -import { DashboardModel, PanelModel } from 'app/features/dashboard/state'; +import { useLocation } from 'react-router-dom'; + import { PanelPlugin } from '@grafana/data'; import { locationService } from '@grafana/runtime'; -import { StoreState } from 'app/types'; -import { GetDataOptions } from '../../../query/state/PanelQueryRunner'; -import { usePanelLatestData } from '../PanelEditor/usePanelLatestData'; -import { InspectContent } from './InspectContent'; -import { useDatasourceMetadata, useInspectTabs } from './hooks'; -import { useLocation } from 'react-router-dom'; +import { DashboardModel, PanelModel } from 'app/features/dashboard/state'; import { InspectTab } from 'app/features/inspector/types'; import { getPanelStateForModel } from 'app/features/panel/state/selectors'; +import { StoreState } from 'app/types'; + +import { GetDataOptions } from '../../../query/state/PanelQueryRunner'; +import { usePanelLatestData } from '../PanelEditor/usePanelLatestData'; + +import { InspectContent } from './InspectContent'; +import { useDatasourceMetadata, useInspectTabs } from './hooks'; interface OwnProps { dashboard: DashboardModel; diff --git a/public/app/features/dashboard/components/Inspector/hooks.ts b/public/app/features/dashboard/components/Inspector/hooks.ts index c46fd8624a4..ca38e9ebcee 100644 --- a/public/app/features/dashboard/components/Inspector/hooks.ts +++ b/public/app/features/dashboard/components/Inspector/hooks.ts @@ -1,10 +1,13 @@ -import { DataQueryError, DataSourceApi, PanelData, PanelPlugin } from '@grafana/data'; +import { useMemo } from 'react'; import useAsync from 'react-use/lib/useAsync'; + +import { DataQueryError, DataSourceApi, PanelData, PanelPlugin } from '@grafana/data'; import { getDataSourceSrv } from '@grafana/runtime'; import { DashboardModel, PanelModel } from 'app/features/dashboard/state'; -import { useMemo } from 'react'; -import { supportsDataQuery } from '../PanelEditor/utils'; import { InspectTab } from 'app/features/inspector/types'; + +import { supportsDataQuery } from '../PanelEditor/utils'; + import { PanelInspectActionSupplier } from './PanelInspectActions'; /** diff --git a/public/app/features/dashboard/components/LinksSettings/LinkSettingsEdit.tsx b/public/app/features/dashboard/components/LinksSettings/LinkSettingsEdit.tsx index ac99dca1faf..cd5b2d16236 100644 --- a/public/app/features/dashboard/components/LinksSettings/LinkSettingsEdit.tsx +++ b/public/app/features/dashboard/components/LinksSettings/LinkSettingsEdit.tsx @@ -1,6 +1,8 @@ import React, { useState } from 'react'; -import { CollapsableSection, TagsInput, Select, Field, Input, Checkbox } from '@grafana/ui'; + import { SelectableValue } from '@grafana/data'; +import { CollapsableSection, TagsInput, Select, Field, Input, Checkbox } from '@grafana/ui'; + import { DashboardLink, DashboardModel } from '../../state/DashboardModel'; export const newLink = { diff --git a/public/app/features/dashboard/components/LinksSettings/LinkSettingsList.tsx b/public/app/features/dashboard/components/LinksSettings/LinkSettingsList.tsx index f23cedc728b..4db46c6143f 100644 --- a/public/app/features/dashboard/components/LinksSettings/LinkSettingsList.tsx +++ b/public/app/features/dashboard/components/LinksSettings/LinkSettingsList.tsx @@ -1,9 +1,11 @@ import React, { useState } from 'react'; + +import { arrayUtils } from '@grafana/data'; import { DeleteButton, HorizontalGroup, Icon, IconButton, TagList } from '@grafana/ui'; import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA'; + import { DashboardModel, DashboardLink } from '../../state/DashboardModel'; import { ListNewButton } from '../DashboardSettings/ListNewButton'; -import { arrayUtils } from '@grafana/data'; type LinkSettingsListProps = { dashboard: DashboardModel; diff --git a/public/app/features/dashboard/components/PanelEditor/AngularPanelOptions.tsx b/public/app/features/dashboard/components/PanelEditor/AngularPanelOptions.tsx index 605b9573856..b625700c025 100644 --- a/public/app/features/dashboard/components/PanelEditor/AngularPanelOptions.tsx +++ b/public/app/features/dashboard/components/PanelEditor/AngularPanelOptions.tsx @@ -1,18 +1,16 @@ -// Libraries import React, { PureComponent } from 'react'; import { connect, ConnectedProps } from 'react-redux'; -// Utils and services -import { AngularComponent, getAngularLoader } from '@grafana/runtime'; - -// Types -import { PanelModel, DashboardModel } from '../../state'; import { PanelPlugin, PanelPluginMeta } from '@grafana/data'; -import { changePanelPlugin } from 'app/features/panel/state/actions'; -import { StoreState } from 'app/types'; -import { getSectionOpenState, saveSectionOpenState } from './state/utils'; +import { AngularComponent, getAngularLoader } from '@grafana/runtime'; import { PanelCtrl } from 'app/angular/panel/panel_ctrl'; +import { changePanelPlugin } from 'app/features/panel/state/actions'; import { getPanelStateForModel } from 'app/features/panel/state/selectors'; +import { StoreState } from 'app/types'; + +import { PanelModel, DashboardModel } from '../../state'; + +import { getSectionOpenState, saveSectionOpenState } from './state/utils'; interface OwnProps { panel: PanelModel; diff --git a/public/app/features/dashboard/components/PanelEditor/DynamicConfigValueEditor.tsx b/public/app/features/dashboard/components/PanelEditor/DynamicConfigValueEditor.tsx index 1af676e798a..f23f470a786 100644 --- a/public/app/features/dashboard/components/PanelEditor/DynamicConfigValueEditor.tsx +++ b/public/app/features/dashboard/components/PanelEditor/DynamicConfigValueEditor.tsx @@ -1,3 +1,8 @@ +import { css, cx } from '@emotion/css'; +import React from 'react'; +// @ts-ignore +import Highlighter from 'react-highlight-words'; + import { DynamicConfigValue, FieldConfigOptionsRegistry, @@ -5,11 +10,9 @@ import { FieldOverrideContext, GrafanaTheme, } from '@grafana/data'; -import React from 'react'; import { Counter, Field, HorizontalGroup, IconButton, Label, stylesFactory, useTheme } from '@grafana/ui'; -import { css, cx } from '@emotion/css'; + import { OptionsPaneCategory } from './OptionsPaneCategory'; -import Highlighter from 'react-highlight-words'; interface DynamicConfigValueEditorProps { property: DynamicConfigValue; diff --git a/public/app/features/dashboard/components/PanelEditor/OptionsPane.tsx b/public/app/features/dashboard/components/PanelEditor/OptionsPane.tsx index 73e73e8ee24..2a025affce4 100644 --- a/public/app/features/dashboard/components/PanelEditor/OptionsPane.tsx +++ b/public/app/features/dashboard/components/PanelEditor/OptionsPane.tsx @@ -1,15 +1,17 @@ -import React from 'react'; -import { GrafanaTheme } from '@grafana/data'; -import { useStyles } from '@grafana/ui'; import { css } from '@emotion/css'; -import { selectors } from '@grafana/e2e-selectors'; -import { VisualizationButton } from './VisualizationButton'; -import { OptionsPaneOptions } from './OptionsPaneOptions'; +import React from 'react'; import { useSelector } from 'react-redux'; + +import { GrafanaTheme } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; +import { useStyles } from '@grafana/ui'; import { StoreState } from 'app/types'; + +import { OptionsPaneOptions } from './OptionsPaneOptions'; +import { VisualizationButton } from './VisualizationButton'; import { VisualizationSelectPane } from './VisualizationSelectPane'; -import { usePanelLatestData } from './usePanelLatestData'; import { OptionPaneRenderProps } from './types'; +import { usePanelLatestData } from './usePanelLatestData'; export const OptionsPane: React.FC = ({ plugin, diff --git a/public/app/features/dashboard/components/PanelEditor/OptionsPaneCategory.tsx b/public/app/features/dashboard/components/PanelEditor/OptionsPaneCategory.tsx index 4c57d945ef4..8cfa6969013 100644 --- a/public/app/features/dashboard/components/PanelEditor/OptionsPaneCategory.tsx +++ b/public/app/features/dashboard/components/PanelEditor/OptionsPaneCategory.tsx @@ -1,13 +1,15 @@ -import React, { FC, ReactNode, useCallback, useEffect, useState, useRef } from 'react'; import { css, cx } from '@emotion/css'; -import { GrafanaTheme2 } from '@grafana/data'; -import { Counter, useStyles2 } from '@grafana/ui'; -import { PANEL_EDITOR_UI_STATE_STORAGE_KEY } from './state/reducers'; +import React, { FC, ReactNode, useCallback, useEffect, useState, useRef } from 'react'; import { useLocalStorage } from 'react-use'; + +import { GrafanaTheme2 } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; +import { Counter, useStyles2 } from '@grafana/ui'; import { useQueryParams } from 'app/core/hooks/useQueryParams'; import { CollapseToggle } from 'app/features/alerting/unified/components/CollapseToggle'; +import { PANEL_EDITOR_UI_STATE_STORAGE_KEY } from './state/reducers'; + export interface OptionsPaneCategoryProps { id: string; title?: string; diff --git a/public/app/features/dashboard/components/PanelEditor/OptionsPaneCategoryDescriptor.tsx b/public/app/features/dashboard/components/PanelEditor/OptionsPaneCategoryDescriptor.tsx index 5715aec6c47..ef887c9256e 100644 --- a/public/app/features/dashboard/components/PanelEditor/OptionsPaneCategoryDescriptor.tsx +++ b/public/app/features/dashboard/components/PanelEditor/OptionsPaneCategoryDescriptor.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { OptionsPaneCategory } from './OptionsPaneCategory'; import { OptionsPaneItemDescriptor } from './OptionsPaneItemDescriptor'; diff --git a/public/app/features/dashboard/components/PanelEditor/OptionsPaneItemDescriptor.tsx b/public/app/features/dashboard/components/PanelEditor/OptionsPaneItemDescriptor.tsx index a8f2ef53233..97906d5d2bb 100644 --- a/public/app/features/dashboard/components/PanelEditor/OptionsPaneItemDescriptor.tsx +++ b/public/app/features/dashboard/components/PanelEditor/OptionsPaneItemDescriptor.tsx @@ -1,7 +1,10 @@ +import React, { ReactNode } from 'react'; +// @ts-ignore +import Highlighter from 'react-highlight-words'; + import { selectors } from '@grafana/e2e-selectors'; import { Field, Label } from '@grafana/ui'; -import React, { ReactNode } from 'react'; -import Highlighter from 'react-highlight-words'; + import { OptionsPaneCategoryDescriptor } from './OptionsPaneCategoryDescriptor'; import { OptionsPaneItemOverrides } from './OptionsPaneItemOverrides'; import { OptionPaneItemOverrideInfo } from './types'; diff --git a/public/app/features/dashboard/components/PanelEditor/OptionsPaneItemOverrides.tsx b/public/app/features/dashboard/components/PanelEditor/OptionsPaneItemOverrides.tsx index 7e086908788..769029e32f0 100644 --- a/public/app/features/dashboard/components/PanelEditor/OptionsPaneItemOverrides.tsx +++ b/public/app/features/dashboard/components/PanelEditor/OptionsPaneItemOverrides.tsx @@ -1,7 +1,9 @@ -import React from 'react'; -import { Tooltip, useStyles2 } from '@grafana/ui'; -import { GrafanaTheme2 } from '@grafana/data'; import { css, CSSObject } from '@emotion/css'; +import React from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; +import { Tooltip, useStyles2 } from '@grafana/ui'; + import { OptionPaneItemOverrideInfo } from './types'; export interface Props { diff --git a/public/app/features/dashboard/components/PanelEditor/OptionsPaneOptions.test.tsx b/public/app/features/dashboard/components/PanelEditor/OptionsPaneOptions.test.tsx index f7f3e910936..c539c11acc3 100644 --- a/public/app/features/dashboard/components/PanelEditor/OptionsPaneOptions.test.tsx +++ b/public/app/features/dashboard/components/PanelEditor/OptionsPaneOptions.test.tsx @@ -1,5 +1,8 @@ -import React from 'react'; import { fireEvent, render, screen, within } from '@testing-library/react'; +import React from 'react'; +import { Provider } from 'react-redux'; +import configureMockStore from 'redux-mock-store'; + import { FieldConfigSource, FieldType, @@ -9,15 +12,14 @@ import { standardFieldConfigEditorRegistry, toDataFrame, } from '@grafana/data'; - import { selectors } from '@grafana/e2e-selectors'; -import { OptionsPaneOptions } from './OptionsPaneOptions'; -import { DashboardModel, PanelModel } from '../../state'; -import { Provider } from 'react-redux'; -import configureMockStore from 'redux-mock-store'; -import { getPanelPlugin } from 'app/features/plugins/__mocks__/pluginMocks'; -import { dataOverrideTooltipDescription, overrideRuleTooltipDescription } from './state/getOptionOverrides'; import { getAllOptionEditors, getAllStandardFieldConfigs } from 'app/core/components/editors/registry'; +import { getPanelPlugin } from 'app/features/plugins/__mocks__/pluginMocks'; + +import { DashboardModel, PanelModel } from '../../state'; + +import { OptionsPaneOptions } from './OptionsPaneOptions'; +import { dataOverrideTooltipDescription, overrideRuleTooltipDescription } from './state/getOptionOverrides'; standardEditorsRegistry.setInit(getAllOptionEditors); standardFieldConfigEditorRegistry.setInit(getAllStandardFieldConfigs); diff --git a/public/app/features/dashboard/components/PanelEditor/OptionsPaneOptions.tsx b/public/app/features/dashboard/components/PanelEditor/OptionsPaneOptions.tsx index 203c2095fc2..ac0bb0579fe 100644 --- a/public/app/features/dashboard/components/PanelEditor/OptionsPaneOptions.tsx +++ b/public/app/features/dashboard/components/PanelEditor/OptionsPaneOptions.tsx @@ -1,17 +1,20 @@ +import { css } from '@emotion/css'; import React, { useMemo, useState } from 'react'; + import { GrafanaTheme2, SelectableValue } from '@grafana/data'; import { CustomScrollbar, FilterInput, RadioButtonGroup, useStyles2 } from '@grafana/ui'; + +import { isPanelModelLibraryPanel } from '../../../library-panels/guard'; + +import { AngularPanelOptions } from './AngularPanelOptions'; +import { OptionsPaneCategory } from './OptionsPaneCategory'; +import { OptionsPaneCategoryDescriptor } from './OptionsPaneCategoryDescriptor'; +import { getFieldOverrideCategories } from './getFieldOverrideElements'; +import { getLibraryPanelOptionsCategory } from './getLibraryPanelOptions'; import { getPanelFrameCategory } from './getPanelFrameOptions'; import { getVisualizationOptions } from './getVisualizationOptions'; -import { css } from '@emotion/css'; -import { OptionsPaneCategory } from './OptionsPaneCategory'; -import { getFieldOverrideCategories } from './getFieldOverrideElements'; -import { OptionsPaneCategoryDescriptor } from './OptionsPaneCategoryDescriptor'; import { OptionSearchEngine } from './state/OptionSearchEngine'; -import { AngularPanelOptions } from './AngularPanelOptions'; import { getRecentOptions } from './state/getRecentOptions'; -import { isPanelModelLibraryPanel } from '../../../library-panels/guard'; -import { getLibraryPanelOptionsCategory } from './getLibraryPanelOptions'; import { OptionPaneRenderProps } from './types'; export const OptionsPaneOptions: React.FC = (props) => { diff --git a/public/app/features/dashboard/components/PanelEditor/OverrideCategoryTitle.tsx b/public/app/features/dashboard/components/PanelEditor/OverrideCategoryTitle.tsx index 3fef9023966..961868cedf6 100644 --- a/public/app/features/dashboard/components/PanelEditor/OverrideCategoryTitle.tsx +++ b/public/app/features/dashboard/components/PanelEditor/OverrideCategoryTitle.tsx @@ -1,8 +1,9 @@ +import { css } from '@emotion/css'; import React, { FC } from 'react'; + import { FieldConfigOptionsRegistry, GrafanaTheme, ConfigOverrideRule } from '@grafana/data'; import { HorizontalGroup, Icon, IconButton, useStyles } from '@grafana/ui'; import { FieldMatcherUIRegistryItem } from '@grafana/ui/src/components/MatchersUI/types'; -import { css } from '@emotion/css'; interface OverrideCategoryTitleProps { isExpanded: boolean; diff --git a/public/app/features/dashboard/components/PanelEditor/PanelEditor.tsx b/public/app/features/dashboard/components/PanelEditor/PanelEditor.tsx index 51d91021993..59c92814742 100644 --- a/public/app/features/dashboard/components/PanelEditor/PanelEditor.tsx +++ b/public/app/features/dashboard/components/PanelEditor/PanelEditor.tsx @@ -1,11 +1,12 @@ +import { css } from '@emotion/css'; import React, { PureComponent } from 'react'; import { connect, ConnectedProps } from 'react-redux'; import AutoSizer from 'react-virtualized-auto-sizer'; -import { css } from '@emotion/css'; import { Subscription } from 'rxjs'; import { FieldConfigSource, GrafanaTheme } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; +import { locationService } from '@grafana/runtime'; import { HorizontalGroup, InlineSwitch, @@ -15,34 +16,19 @@ import { stylesFactory, ToolbarButton, } from '@grafana/ui'; - +import { SplitPaneWrapper } from 'app/core/components/SplitPaneWrapper/SplitPaneWrapper'; import config from 'app/core/config'; import { appEvents } from 'app/core/core'; -import { calculatePanelSize } from './utils'; - -import { PanelEditorTabs } from './PanelEditorTabs'; -import { DashNavTimeControls } from '../DashNav/DashNavTimeControls'; -import { OptionsPane } from './OptionsPane'; import { SubMenuItems } from 'app/features/dashboard/components/SubMenu/SubMenuItems'; -import { SplitPaneWrapper } from 'app/core/components/SplitPaneWrapper/SplitPaneWrapper'; -import { SaveDashboardProxy } from '../SaveDashboard/SaveDashboardProxy'; -import { DashboardPanel } from '../../dashgrid/DashboardPanel'; - -import { discardPanelChanges, initPanelEditor, updatePanelEditorUIState } from './state/actions'; - -import { updateTimeZoneForSession } from 'app/features/profile/state/reducers'; -import { toggleTableView } from './state/reducers'; - -import { getPanelEditorTabs } from './state/selectors'; - -import { StoreState } from 'app/types'; -import { DisplayMode, displayModes, PanelEditorTab } from './types'; -import { DashboardModel, PanelModel } from '../../state'; -import { VisualizationButton } from './VisualizationButton'; -import { PanelOptionsChangedEvent, ShowModalReactEvent } from 'app/types/events'; -import { locationService } from '@grafana/runtime'; -import { UnlinkModal } from '../../../library-panels/components/UnlinkModal/UnlinkModal'; import { SaveLibraryPanelModal } from 'app/features/library-panels/components/SaveLibraryPanelModal/SaveLibraryPanelModal'; +import { PanelModelWithLibraryPanel } from 'app/features/library-panels/types'; +import { getPanelStateForModel } from 'app/features/panel/state/selectors'; +import { updateTimeZoneForSession } from 'app/features/profile/state/reducers'; +import { StoreState } from 'app/types'; +import { PanelOptionsChangedEvent, ShowModalReactEvent } from 'app/types/events'; + +import { notifyApp } from '../../../../core/actions'; +import { UnlinkModal } from '../../../library-panels/components/UnlinkModal/UnlinkModal'; import { isPanelModelLibraryPanel } from '../../../library-panels/guard'; import { getLibraryPanelConnectedDashboards } from '../../../library-panels/state/api'; import { @@ -50,11 +36,21 @@ import { createPanelLibrarySuccessNotification, saveAndRefreshLibraryPanel, } from '../../../library-panels/utils'; -import { notifyApp } from '../../../../core/actions'; -import { PanelEditorTableView } from './PanelEditorTableView'; -import { PanelModelWithLibraryPanel } from 'app/features/library-panels/types'; -import { getPanelStateForModel } from 'app/features/panel/state/selectors'; import { getVariablesByKey } from '../../../variables/state/selectors'; +import { DashboardPanel } from '../../dashgrid/DashboardPanel'; +import { DashboardModel, PanelModel } from '../../state'; +import { DashNavTimeControls } from '../DashNav/DashNavTimeControls'; +import { SaveDashboardProxy } from '../SaveDashboard/SaveDashboardProxy'; + +import { OptionsPane } from './OptionsPane'; +import { PanelEditorTableView } from './PanelEditorTableView'; +import { PanelEditorTabs } from './PanelEditorTabs'; +import { VisualizationButton } from './VisualizationButton'; +import { discardPanelChanges, initPanelEditor, updatePanelEditorUIState } from './state/actions'; +import { toggleTableView } from './state/reducers'; +import { getPanelEditorTabs } from './state/selectors'; +import { DisplayMode, displayModes, PanelEditorTab } from './types'; +import { calculatePanelSize } from './utils'; interface OwnProps { dashboard: DashboardModel; diff --git a/public/app/features/dashboard/components/PanelEditor/PanelEditorQueries.tsx b/public/app/features/dashboard/components/PanelEditor/PanelEditorQueries.tsx index 36cc2d32b88..ca3ce045036 100644 --- a/public/app/features/dashboard/components/PanelEditor/PanelEditorQueries.tsx +++ b/public/app/features/dashboard/components/PanelEditor/PanelEditorQueries.tsx @@ -1,10 +1,12 @@ import React, { PureComponent } from 'react'; -import { QueryGroup } from 'app/features/query/components/QueryGroup'; -import { PanelModel } from '../../state'; -import { locationService } from '@grafana/runtime'; -import { QueryGroupDataSource, QueryGroupOptions } from 'app/types'; + import { DataQuery, getDataSourceRef } from '@grafana/data'; +import { locationService } from '@grafana/runtime'; import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; +import { QueryGroup } from 'app/features/query/components/QueryGroup'; +import { QueryGroupDataSource, QueryGroupOptions } from 'app/types'; + +import { PanelModel } from '../../state'; interface Props { /** Current panel */ diff --git a/public/app/features/dashboard/components/PanelEditor/PanelEditorTableView.tsx b/public/app/features/dashboard/components/PanelEditor/PanelEditorTableView.tsx index 826f419ac5c..fd4958d10b4 100644 --- a/public/app/features/dashboard/components/PanelEditor/PanelEditorTableView.tsx +++ b/public/app/features/dashboard/components/PanelEditor/PanelEditorTableView.tsx @@ -1,13 +1,16 @@ -import { PanelChrome } from '@grafana/ui'; -import { PanelRenderer } from 'app/features/panel/components/PanelRenderer'; import React, { useEffect, useState } from 'react'; -import { DashboardModel, PanelModel } from '../../state'; -import { usePanelLatestData } from './usePanelLatestData'; -import { PanelOptions } from 'app/plugins/panel/table/models.gen'; + import { RefreshEvent } from '@grafana/runtime'; +import { PanelChrome } from '@grafana/ui'; import { applyPanelTimeOverrides } from 'app/features/dashboard/utils/panel'; -import { getTimeSrv } from '../../services/TimeSrv'; +import { PanelRenderer } from 'app/features/panel/components/PanelRenderer'; +import { PanelOptions } from 'app/plugins/panel/table/models.gen'; + import PanelHeaderCorner from '../../dashgrid/PanelHeader/PanelHeaderCorner'; +import { getTimeSrv } from '../../services/TimeSrv'; +import { DashboardModel, PanelModel } from '../../state'; + +import { usePanelLatestData } from './usePanelLatestData'; interface Props { width: number; diff --git a/public/app/features/dashboard/components/PanelEditor/PanelEditorTabs.tsx b/public/app/features/dashboard/components/PanelEditor/PanelEditorTabs.tsx index 8c903e3fbfa..e9c4ed1a4dc 100644 --- a/public/app/features/dashboard/components/PanelEditor/PanelEditorTabs.tsx +++ b/public/app/features/dashboard/components/PanelEditor/PanelEditorTabs.tsx @@ -1,16 +1,19 @@ -import React, { FC, useEffect } from 'react'; import { css } from '@emotion/css'; -import { IconName, Tab, TabContent, TabsBar, useForceUpdate, useStyles2 } from '@grafana/ui'; -import { TransformationsEditor } from '../TransformationsEditor/TransformationsEditor'; -import { DashboardModel, PanelModel } from '../../state'; -import { PanelEditorTab, PanelEditorTabId } from './types'; +import React, { FC, useEffect } from 'react'; import { Subscription } from 'rxjs'; -import { PanelQueriesChangedEvent, PanelTransformationsChangedEvent } from 'app/types/events'; -import { PanelEditorQueries } from './PanelEditorQueries'; + import { GrafanaTheme2 } from '@grafana/data'; import { config } from '@grafana/runtime'; +import { IconName, Tab, TabContent, TabsBar, useForceUpdate, useStyles2 } from '@grafana/ui'; import AlertTabIndex from 'app/features/alerting/AlertTabIndex'; import { PanelAlertTab } from 'app/features/alerting/unified/PanelAlertTab'; +import { PanelQueriesChangedEvent, PanelTransformationsChangedEvent } from 'app/types/events'; + +import { DashboardModel, PanelModel } from '../../state'; +import { TransformationsEditor } from '../TransformationsEditor/TransformationsEditor'; + +import { PanelEditorQueries } from './PanelEditorQueries'; +import { PanelEditorTab, PanelEditorTabId } from './types'; interface PanelEditorTabsProps { panel: PanelModel; diff --git a/public/app/features/dashboard/components/PanelEditor/PanelNotSupported.test.tsx b/public/app/features/dashboard/components/PanelEditor/PanelNotSupported.test.tsx index 7c61a20373d..b5e6f9ed926 100644 --- a/public/app/features/dashboard/components/PanelEditor/PanelNotSupported.test.tsx +++ b/public/app/features/dashboard/components/PanelEditor/PanelNotSupported.test.tsx @@ -1,7 +1,9 @@ -import { locationService } from '@grafana/runtime'; import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; + +import { locationService } from '@grafana/runtime'; + import { PanelNotSupported, Props } from './PanelNotSupported'; import { PanelEditorTabId } from './types'; diff --git a/public/app/features/dashboard/components/PanelEditor/PanelNotSupported.tsx b/public/app/features/dashboard/components/PanelEditor/PanelNotSupported.tsx index 3c0bcdcc0a6..ea60c728c8f 100644 --- a/public/app/features/dashboard/components/PanelEditor/PanelNotSupported.tsx +++ b/public/app/features/dashboard/components/PanelEditor/PanelNotSupported.tsx @@ -1,9 +1,10 @@ import React, { useCallback } from 'react'; -import { Button, VerticalGroup } from '@grafana/ui'; -import { Layout } from '@grafana/ui/src/components/Layout/Layout'; -import { PanelEditorTabId } from './types'; import { locationService } from '@grafana/runtime'; +import { Button, VerticalGroup } from '@grafana/ui'; +import { Layout } from '@grafana/ui/src/components/Layout/Layout'; + +import { PanelEditorTabId } from './types'; export interface Props { message: string; diff --git a/public/app/features/dashboard/components/PanelEditor/VisualizationButton.tsx b/public/app/features/dashboard/components/PanelEditor/VisualizationButton.tsx index 8e705bbd8f2..476f77a3f3f 100644 --- a/public/app/features/dashboard/components/PanelEditor/VisualizationButton.tsx +++ b/public/app/features/dashboard/components/PanelEditor/VisualizationButton.tsx @@ -1,14 +1,17 @@ -import React, { FC } from 'react'; import { css } from '@emotion/css'; +import React, { FC } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; + import { GrafanaTheme } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; import { ToolbarButton, ButtonGroup, useStyles } from '@grafana/ui'; import { StoreState } from 'app/types'; -import { useDispatch, useSelector } from 'react-redux'; -import { setPanelEditorUIState, toggleVizPicker } from './state/reducers'; -import { selectors } from '@grafana/e2e-selectors'; + import { PanelModel } from '../../state'; import { getPanelPluginWithFallback } from '../../state/selectors'; +import { setPanelEditorUIState, toggleVizPicker } from './state/reducers'; + type Props = { panel: PanelModel; }; diff --git a/public/app/features/dashboard/components/PanelEditor/VisualizationSelectPane.tsx b/public/app/features/dashboard/components/PanelEditor/VisualizationSelectPane.tsx index ca2e2e18f40..db9a56901c9 100644 --- a/public/app/features/dashboard/components/PanelEditor/VisualizationSelectPane.tsx +++ b/public/app/features/dashboard/components/PanelEditor/VisualizationSelectPane.tsx @@ -1,21 +1,24 @@ -import React, { FC, useCallback, useEffect, useRef, useState } from 'react'; import { css } from '@emotion/css'; +import React, { FC, useCallback, useEffect, useRef, useState } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import { useLocalStorage } from 'react-use'; + import { GrafanaTheme, PanelData, SelectableValue } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; import { Button, CustomScrollbar, FilterInput, RadioButtonGroup, useStyles } from '@grafana/ui'; +import { Field } from '@grafana/ui/src/components/Forms/Field'; +import { LS_VISUALIZATION_SELECT_TAB_KEY } from 'app/core/constants'; +import { PanelLibraryOptionsGroup } from 'app/features/library-panels/components/PanelLibraryOptionsGroup/PanelLibraryOptionsGroup'; +import { VisualizationSuggestions } from 'app/features/panel/components/VizTypePicker/VisualizationSuggestions'; +import { VizTypeChangeDetails } from 'app/features/panel/components/VizTypePicker/types'; + +import { VizTypePicker } from '../../../panel/components/VizTypePicker/VizTypePicker'; import { changePanelPlugin } from '../../../panel/state/actions'; import { PanelModel } from '../../state/PanelModel'; -import { useDispatch, useSelector } from 'react-redux'; -import { VizTypePicker } from '../../../panel/components/VizTypePicker/VizTypePicker'; -import { Field } from '@grafana/ui/src/components/Forms/Field'; -import { PanelLibraryOptionsGroup } from 'app/features/library-panels/components/PanelLibraryOptionsGroup/PanelLibraryOptionsGroup'; -import { toggleVizPicker } from './state/reducers'; -import { selectors } from '@grafana/e2e-selectors'; import { getPanelPluginWithFallback } from '../../state/selectors'; -import { VizTypeChangeDetails } from 'app/features/panel/components/VizTypePicker/types'; -import { VisualizationSuggestions } from 'app/features/panel/components/VizTypePicker/VisualizationSuggestions'; -import { useLocalStorage } from 'react-use'; + +import { toggleVizPicker } from './state/reducers'; import { VisualizationSelectPaneTab } from './types'; -import { LS_VISUALIZATION_SELECT_TAB_KEY } from 'app/core/constants'; interface Props { panel: PanelModel; diff --git a/public/app/features/dashboard/components/PanelEditor/getFieldOverrideElements.tsx b/public/app/features/dashboard/components/PanelEditor/getFieldOverrideElements.tsx index 43af045b55e..9ca84fdf48a 100644 --- a/public/app/features/dashboard/components/PanelEditor/getFieldOverrideElements.tsx +++ b/public/app/features/dashboard/components/PanelEditor/getFieldOverrideElements.tsx @@ -1,5 +1,7 @@ -import React from 'react'; +import { css } from '@emotion/css'; import { cloneDeep } from 'lodash'; +import React from 'react'; + import { FieldConfigOptionsRegistry, SelectableValue, @@ -10,13 +12,13 @@ import { GrafanaTheme2, } from '@grafana/data'; import { fieldMatchersUI, useStyles2, ValuePicker } from '@grafana/ui'; -import { OptionPaneRenderProps } from './types'; -import { OptionsPaneItemDescriptor } from './OptionsPaneItemDescriptor'; -import { OptionsPaneCategoryDescriptor } from './OptionsPaneCategoryDescriptor'; -import { DynamicConfigValueEditor } from './DynamicConfigValueEditor'; import { getDataLinksVariableSuggestions } from 'app/features/panel/panellinks/link_srv'; + +import { DynamicConfigValueEditor } from './DynamicConfigValueEditor'; +import { OptionsPaneCategoryDescriptor } from './OptionsPaneCategoryDescriptor'; +import { OptionsPaneItemDescriptor } from './OptionsPaneItemDescriptor'; import { OverrideCategoryTitle } from './OverrideCategoryTitle'; -import { css } from '@emotion/css'; +import { OptionPaneRenderProps } from './types'; export function getFieldOverrideCategories( props: OptionPaneRenderProps, diff --git a/public/app/features/dashboard/components/PanelEditor/getLibraryPanelOptions.tsx b/public/app/features/dashboard/components/PanelEditor/getLibraryPanelOptions.tsx index d92669f3f72..8f1036efcb4 100644 --- a/public/app/features/dashboard/components/PanelEditor/getLibraryPanelOptions.tsx +++ b/public/app/features/dashboard/components/PanelEditor/getLibraryPanelOptions.tsx @@ -1,11 +1,14 @@ -import { Input } from '@grafana/ui'; import React from 'react'; -import { OptionsPaneItemDescriptor } from './OptionsPaneItemDescriptor'; -import { OptionsPaneCategoryDescriptor } from './OptionsPaneCategoryDescriptor'; -import { OptionPaneRenderProps } from './types'; -import { isPanelModelLibraryPanel } from '../../../library-panels/guard'; + +import { Input } from '@grafana/ui'; import { LibraryPanelInformation } from 'app/features/library-panels/components/LibraryPanelInfo/LibraryPanelInfo'; +import { isPanelModelLibraryPanel } from '../../../library-panels/guard'; + +import { OptionsPaneCategoryDescriptor } from './OptionsPaneCategoryDescriptor'; +import { OptionsPaneItemDescriptor } from './OptionsPaneItemDescriptor'; +import { OptionPaneRenderProps } from './types'; + export function getLibraryPanelOptionsCategory(props: OptionPaneRenderProps): OptionsPaneCategoryDescriptor { const { panel, onPanelConfigChange, dashboard } = props; const descriptor = new OptionsPaneCategoryDescriptor({ diff --git a/public/app/features/dashboard/components/PanelEditor/getPanelFrameOptions.tsx b/public/app/features/dashboard/components/PanelEditor/getPanelFrameOptions.tsx index 5cd1e34348b..20e4a7a69b7 100644 --- a/public/app/features/dashboard/components/PanelEditor/getPanelFrameOptions.tsx +++ b/public/app/features/dashboard/components/PanelEditor/getPanelFrameOptions.tsx @@ -1,9 +1,12 @@ +import React from 'react'; + import { DataLinksInlineEditor, Input, RadioButtonGroup, Select, Switch, TextArea } from '@grafana/ui'; import { getPanelLinksVariableSuggestions } from 'app/features/panel/panellinks/link_srv'; -import React from 'react'; + import { RepeatRowSelect } from '../RepeatRowSelect/RepeatRowSelect'; -import { OptionsPaneItemDescriptor } from './OptionsPaneItemDescriptor'; + import { OptionsPaneCategoryDescriptor } from './OptionsPaneCategoryDescriptor'; +import { OptionsPaneItemDescriptor } from './OptionsPaneItemDescriptor'; import { OptionPaneRenderProps } from './types'; export function getPanelFrameCategory(props: OptionPaneRenderProps): OptionsPaneCategoryDescriptor { diff --git a/public/app/features/dashboard/components/PanelEditor/getVisualizationOptions.test.ts b/public/app/features/dashboard/components/PanelEditor/getVisualizationOptions.test.ts index 3d3c461f6f8..01f12b81f1c 100644 --- a/public/app/features/dashboard/components/PanelEditor/getVisualizationOptions.test.ts +++ b/public/app/features/dashboard/components/PanelEditor/getVisualizationOptions.test.ts @@ -1,4 +1,5 @@ import { EventBusSrv, FieldType, getDefaultTimeRange, LoadingState, toDataFrame } from '@grafana/data'; + import { getStandardEditorContext } from './getVisualizationOptions'; describe('getStandardEditorContext', () => { diff --git a/public/app/features/dashboard/components/PanelEditor/getVisualizationOptions.tsx b/public/app/features/dashboard/components/PanelEditor/getVisualizationOptions.tsx index be266ae7e9b..a3fa3263e73 100644 --- a/public/app/features/dashboard/components/PanelEditor/getVisualizationOptions.tsx +++ b/public/app/features/dashboard/components/PanelEditor/getVisualizationOptions.tsx @@ -1,4 +1,6 @@ +import { get as lodashGet } from 'lodash'; import React from 'react'; + import { EventBus, InterpolateFunction, @@ -6,19 +8,19 @@ import { StandardEditorContext, VariableSuggestionsScope, } from '@grafana/data'; -import { get as lodashGet } from 'lodash'; -import { getDataLinksVariableSuggestions } from 'app/features/panel/panellinks/link_srv'; -import { OptionPaneRenderProps } from './types'; -import { setOptionImmutably, updateDefaultFieldConfigValue } from './utils'; -import { OptionsPaneItemDescriptor } from './OptionsPaneItemDescriptor'; -import { OptionsPaneCategoryDescriptor } from './OptionsPaneCategoryDescriptor'; +import { PanelOptionsSupplier } from '@grafana/data/src/panel/PanelPlugin'; import { isNestedPanelOptions, NestedValueAccess, PanelOptionsEditorBuilder, } from '@grafana/data/src/utils/OptionsUIBuilders'; -import { PanelOptionsSupplier } from '@grafana/data/src/panel/PanelPlugin'; +import { getDataLinksVariableSuggestions } from 'app/features/panel/panellinks/link_srv'; + +import { OptionsPaneCategoryDescriptor } from './OptionsPaneCategoryDescriptor'; +import { OptionsPaneItemDescriptor } from './OptionsPaneItemDescriptor'; import { getOptionOverrides } from './state/getOptionOverrides'; +import { OptionPaneRenderProps } from './types'; +import { setOptionImmutably, updateDefaultFieldConfigValue } from './utils'; type categoryGetter = (categoryNames?: string[]) => OptionsPaneCategoryDescriptor; diff --git a/public/app/features/dashboard/components/PanelEditor/state/OptionSearchEngine.test.ts b/public/app/features/dashboard/components/PanelEditor/state/OptionSearchEngine.test.ts index bb9d42bc0d7..43787af8f58 100644 --- a/public/app/features/dashboard/components/PanelEditor/state/OptionSearchEngine.test.ts +++ b/public/app/features/dashboard/components/PanelEditor/state/OptionSearchEngine.test.ts @@ -1,5 +1,6 @@ import { OptionsPaneCategoryDescriptor } from '../OptionsPaneCategoryDescriptor'; import { OptionsPaneItemDescriptor } from '../OptionsPaneItemDescriptor'; + import { OptionSearchEngine } from './OptionSearchEngine'; describe('OptionSearchEngine', () => { diff --git a/public/app/features/dashboard/components/PanelEditor/state/OptionSearchEngine.ts b/public/app/features/dashboard/components/PanelEditor/state/OptionSearchEngine.ts index c29f8399949..c861806702d 100644 --- a/public/app/features/dashboard/components/PanelEditor/state/OptionSearchEngine.ts +++ b/public/app/features/dashboard/components/PanelEditor/state/OptionSearchEngine.ts @@ -1,5 +1,5 @@ -import { OptionsPaneItemDescriptor } from '../OptionsPaneItemDescriptor'; import { OptionsPaneCategoryDescriptor } from '../OptionsPaneCategoryDescriptor'; +import { OptionsPaneItemDescriptor } from '../OptionsPaneItemDescriptor'; export interface OptionSearchResults { optionHits: OptionsPaneItemDescriptor[]; diff --git a/public/app/features/dashboard/components/PanelEditor/state/actions.test.ts b/public/app/features/dashboard/components/PanelEditor/state/actions.test.ts index 1e864f160ac..b52df7d3ae9 100644 --- a/public/app/features/dashboard/components/PanelEditor/state/actions.test.ts +++ b/public/app/features/dashboard/components/PanelEditor/state/actions.test.ts @@ -1,10 +1,12 @@ -import { thunkTester } from '../../../../../../test/core/thunk/thunkTester'; -import { closeEditor, initialState, PanelEditorState } from './reducers'; -import { exitPanelEditor, initPanelEditor, skipPanelUpdate } from './actions'; import { panelModelAndPluginReady, removePanel } from 'app/features/panel/state/reducers'; -import { DashboardModel, PanelModel } from '../../../state'; import { getPanelPlugin } from 'app/features/plugins/__mocks__/pluginMocks'; +import { thunkTester } from '../../../../../../test/core/thunk/thunkTester'; +import { DashboardModel, PanelModel } from '../../../state'; + +import { exitPanelEditor, initPanelEditor, skipPanelUpdate } from './actions'; +import { closeEditor, initialState, PanelEditorState } from './reducers'; + describe('panelEditor actions', () => { describe('initPanelEditor', () => { it('initPanelEditor should create edit panel model as clone', async () => { diff --git a/public/app/features/dashboard/components/PanelEditor/state/actions.ts b/public/app/features/dashboard/components/PanelEditor/state/actions.ts index 7093dd47cdc..a2c037843eb 100644 --- a/public/app/features/dashboard/components/PanelEditor/state/actions.ts +++ b/public/app/features/dashboard/components/PanelEditor/state/actions.ts @@ -1,8 +1,12 @@ import { pick } from 'lodash'; -import { ThunkResult } from 'app/types'; + import store from 'app/core/store'; -import { panelModelAndPluginReady } from 'app/features/panel/state/reducers'; import { cleanUpPanelState, initPanelState } from 'app/features/panel/state/actions'; +import { panelModelAndPluginReady } from 'app/features/panel/state/reducers'; +import { ThunkResult } from 'app/types'; + +import { DashboardModel, PanelModel } from '../../../state'; + import { closeEditor, PANEL_EDITOR_UI_STATE_STORAGE_KEY, @@ -11,7 +15,6 @@ import { setPanelEditorUIState, updateEditorInitState, } from './reducers'; -import { DashboardModel, PanelModel } from '../../../state'; export function initPanelEditor(sourcePanel: PanelModel, dashboard: DashboardModel): ThunkResult { return async (dispatch) => { diff --git a/public/app/features/dashboard/components/PanelEditor/state/getOptionOverrides.ts b/public/app/features/dashboard/components/PanelEditor/state/getOptionOverrides.ts index 7160401a861..0ce4e9ce71b 100644 --- a/public/app/features/dashboard/components/PanelEditor/state/getOptionOverrides.ts +++ b/public/app/features/dashboard/components/PanelEditor/state/getOptionOverrides.ts @@ -1,5 +1,7 @@ -import { DataFrame, FieldConfigPropertyItem, FieldConfigSource } from '@grafana/data'; import { get as lodashGet } from 'lodash'; + +import { DataFrame, FieldConfigPropertyItem, FieldConfigSource } from '@grafana/data'; + import { OptionPaneItemOverrideInfo } from '../types'; export const dataOverrideTooltipDescription = diff --git a/public/app/features/dashboard/components/PanelEditor/state/reducers.ts b/public/app/features/dashboard/components/PanelEditor/state/reducers.ts index b8e77139e78..9a366235f2f 100644 --- a/public/app/features/dashboard/components/PanelEditor/state/reducers.ts +++ b/public/app/features/dashboard/components/PanelEditor/state/reducers.ts @@ -1,8 +1,10 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit'; -import { PanelModel } from '../../../state/PanelModel'; + import { getDefaultTimeRange, LoadingState, PanelData } from '@grafana/data'; -import { DisplayMode } from '../types'; + import store from '../../../../../core/store'; +import { PanelModel } from '../../../state/PanelModel'; +import { DisplayMode } from '../types'; export const PANEL_EDITOR_UI_STATE_STORAGE_KEY = 'grafana.dashboard.editor.ui'; diff --git a/public/app/features/dashboard/components/PanelEditor/state/selectors.test.ts b/public/app/features/dashboard/components/PanelEditor/state/selectors.test.ts index 0bab17d32f9..86f37cb761a 100644 --- a/public/app/features/dashboard/components/PanelEditor/state/selectors.test.ts +++ b/public/app/features/dashboard/components/PanelEditor/state/selectors.test.ts @@ -1,9 +1,11 @@ -import { getPanelEditorTabs } from './selectors'; import { PanelPlugin } from '@grafana/data'; -import { PanelEditorTabId } from '../types'; -import { updateConfig } from '../../../../../core/config'; import { contextSrv } from 'app/core/services/context_srv'; +import { updateConfig } from '../../../../../core/config'; +import { PanelEditorTabId } from '../types'; + +import { getPanelEditorTabs } from './selectors'; + jest.mock('app/core/services/context_srv'); const mocks = { diff --git a/public/app/features/dashboard/components/PanelEditor/state/selectors.ts b/public/app/features/dashboard/components/PanelEditor/state/selectors.ts index 007945700da..7627bcbcf07 100644 --- a/public/app/features/dashboard/components/PanelEditor/state/selectors.ts +++ b/public/app/features/dashboard/components/PanelEditor/state/selectors.ts @@ -1,11 +1,13 @@ import memoizeOne from 'memoize-one'; + import { PanelPlugin } from '@grafana/data'; -import { PanelEditorTab, PanelEditorTabId } from '../types'; import { getConfig } from 'app/core/config'; -import { getRulesPermissions } from 'app/features/alerting/unified/utils/access-control'; import { contextSrv } from 'app/core/services/context_srv'; +import { getRulesPermissions } from 'app/features/alerting/unified/utils/access-control'; import { GRAFANA_RULES_SOURCE_NAME } from 'app/features/alerting/unified/utils/datasource'; +import { PanelEditorTab, PanelEditorTabId } from '../types'; + export const getPanelEditorTabs = memoizeOne((tab?: string, plugin?: PanelPlugin) => { const tabs: PanelEditorTab[] = []; diff --git a/public/app/features/dashboard/components/PanelEditor/types.ts b/public/app/features/dashboard/components/PanelEditor/types.ts index 6e4b2306637..39d8f6409bd 100644 --- a/public/app/features/dashboard/components/PanelEditor/types.ts +++ b/public/app/features/dashboard/components/PanelEditor/types.ts @@ -1,4 +1,5 @@ import { DataFrame, FieldConfigSource, PanelData, PanelPlugin } from '@grafana/data'; + import { DashboardModel, PanelModel } from '../../state'; export interface PanelEditorTab { diff --git a/public/app/features/dashboard/components/PanelEditor/usePanelLatestData.ts b/public/app/features/dashboard/components/PanelEditor/usePanelLatestData.ts index 625642f43a5..f3e2aa5f2d2 100644 --- a/public/app/features/dashboard/components/PanelEditor/usePanelLatestData.ts +++ b/public/app/features/dashboard/components/PanelEditor/usePanelLatestData.ts @@ -1,8 +1,10 @@ -import { DataQueryError, LoadingState, PanelData } from '@grafana/data'; import { useEffect, useRef, useState } from 'react'; -import { PanelModel } from '../../state'; import { Unsubscribable } from 'rxjs'; + +import { DataQueryError, LoadingState, PanelData } from '@grafana/data'; + import { GetDataOptions } from '../../../query/state/PanelQueryRunner'; +import { PanelModel } from '../../state'; interface UsePanelLatestData { data?: PanelData; diff --git a/public/app/features/dashboard/components/PanelEditor/utils.test.ts b/public/app/features/dashboard/components/PanelEditor/utils.test.ts index ba19f093308..b2efaa7aa7f 100644 --- a/public/app/features/dashboard/components/PanelEditor/utils.test.ts +++ b/public/app/features/dashboard/components/PanelEditor/utils.test.ts @@ -1,4 +1,5 @@ import { FieldConfig, FieldConfigSource, PanelPlugin, standardFieldConfigEditorRegistry } from '@grafana/data'; + import { setOptionImmutably, supportsDataQuery, updateDefaultFieldConfigValue } from './utils'; describe('standardFieldConfigEditorRegistry', () => { diff --git a/public/app/features/dashboard/components/PanelEditor/utils.ts b/public/app/features/dashboard/components/PanelEditor/utils.ts index 868476b6241..d5a3342e668 100644 --- a/public/app/features/dashboard/components/PanelEditor/utils.ts +++ b/public/app/features/dashboard/components/PanelEditor/utils.ts @@ -1,9 +1,12 @@ import { omit } from 'lodash'; + import { FieldConfigSource, PanelPlugin } from '@grafana/data'; -import { PanelModel } from '../../state/PanelModel'; -import { DisplayMode } from './types'; import { GRID_CELL_HEIGHT, GRID_CELL_VMARGIN, GRID_COLUMN_COUNT } from 'app/core/constants'; +import { PanelModel } from '../../state/PanelModel'; + +import { DisplayMode } from './types'; + export function calculatePanelSize(mode: DisplayMode, width: number, height: number, panel: PanelModel) { if (mode === DisplayMode.Fill) { return { width, height }; diff --git a/public/app/features/dashboard/components/RepeatRowSelect/RepeatRowSelect.tsx b/public/app/features/dashboard/components/RepeatRowSelect/RepeatRowSelect.tsx index 0ad229d26df..596dd425654 100644 --- a/public/app/features/dashboard/components/RepeatRowSelect/RepeatRowSelect.tsx +++ b/public/app/features/dashboard/components/RepeatRowSelect/RepeatRowSelect.tsx @@ -1,10 +1,11 @@ import React, { FC, useCallback, useMemo } from 'react'; import { useSelector } from 'react-redux'; -import { Select } from '@grafana/ui'; -import { SelectableValue } from '@grafana/data'; -import { getLastKey, getVariablesByKey } from '../../../variables/state/selectors'; +import { SelectableValue } from '@grafana/data'; +import { Select } from '@grafana/ui'; + import { StoreState } from '../../../../types'; +import { getLastKey, getVariablesByKey } from '../../../variables/state/selectors'; export interface Props { id?: string; diff --git a/public/app/features/dashboard/components/RowOptions/RowOptionsButton.tsx b/public/app/features/dashboard/components/RowOptions/RowOptionsButton.tsx index 417eeb3a795..fa49740bc0e 100644 --- a/public/app/features/dashboard/components/RowOptions/RowOptionsButton.tsx +++ b/public/app/features/dashboard/components/RowOptions/RowOptionsButton.tsx @@ -1,8 +1,9 @@ import React, { FC } from 'react'; + import { Icon, ModalsController } from '@grafana/ui'; -import { RowOptionsModal } from './RowOptionsModal'; import { OnRowOptionsUpdate } from './RowOptionsForm'; +import { RowOptionsModal } from './RowOptionsModal'; export interface RowOptionsButtonProps { title: string; diff --git a/public/app/features/dashboard/components/RowOptions/RowOptionsForm.tsx b/public/app/features/dashboard/components/RowOptions/RowOptionsForm.tsx index 1f841528a90..40b9aafaabb 100644 --- a/public/app/features/dashboard/components/RowOptions/RowOptionsForm.tsx +++ b/public/app/features/dashboard/components/RowOptions/RowOptionsForm.tsx @@ -1,4 +1,5 @@ import React, { FC, useCallback, useState } from 'react'; + import { Button, Field, Form, Modal, Input } from '@grafana/ui'; import { RepeatRowSelect } from '../RepeatRowSelect/RepeatRowSelect'; diff --git a/public/app/features/dashboard/components/RowOptions/RowOptionsModal.tsx b/public/app/features/dashboard/components/RowOptions/RowOptionsModal.tsx index 7e0555b3744..785d10f89f2 100644 --- a/public/app/features/dashboard/components/RowOptions/RowOptionsModal.tsx +++ b/public/app/features/dashboard/components/RowOptions/RowOptionsModal.tsx @@ -1,6 +1,7 @@ -import React, { FC } from 'react'; -import { Modal, stylesFactory } from '@grafana/ui'; import { css } from '@emotion/css'; +import React, { FC } from 'react'; + +import { Modal, stylesFactory } from '@grafana/ui'; import { OnRowOptionsUpdate, RowOptionsForm } from './RowOptionsForm'; diff --git a/public/app/features/dashboard/components/SaveDashboard/SaveDashboardAsModal.tsx b/public/app/features/dashboard/components/SaveDashboard/SaveDashboardAsModal.tsx index ca9c0364b7c..785ee7b45ed 100644 --- a/public/app/features/dashboard/components/SaveDashboard/SaveDashboardAsModal.tsx +++ b/public/app/features/dashboard/components/SaveDashboard/SaveDashboardAsModal.tsx @@ -1,10 +1,12 @@ -import React, { useState } from 'react'; import { css } from '@emotion/css'; +import React, { useState } from 'react'; + import { Modal } from '@grafana/ui'; -import { SaveDashboardAsForm } from './forms/SaveDashboardAsForm'; + import { SaveDashboardErrorProxy } from './SaveDashboardErrorProxy'; -import { useDashboardSave } from './useDashboardSave'; +import { SaveDashboardAsForm } from './forms/SaveDashboardAsForm'; import { SaveDashboardModalProps } from './types'; +import { useDashboardSave } from './useDashboardSave'; export const SaveDashboardAsModal: React.FC< SaveDashboardModalProps & { diff --git a/public/app/features/dashboard/components/SaveDashboard/SaveDashboardButton.tsx b/public/app/features/dashboard/components/SaveDashboard/SaveDashboardButton.tsx index d754fe352a4..75d09010f9a 100644 --- a/public/app/features/dashboard/components/SaveDashboard/SaveDashboardButton.tsx +++ b/public/app/features/dashboard/components/SaveDashboard/SaveDashboardButton.tsx @@ -1,8 +1,10 @@ import React from 'react'; + +import { selectors } from '@grafana/e2e-selectors'; import { Button, ButtonVariant, ModalsController, FullWidthButtonContainer } from '@grafana/ui'; import { DashboardModel } from 'app/features/dashboard/state'; + import { SaveDashboardProxy } from './SaveDashboardProxy'; -import { selectors } from '@grafana/e2e-selectors'; interface SaveDashboardButtonProps { dashboard: DashboardModel; diff --git a/public/app/features/dashboard/components/SaveDashboard/SaveDashboardDiff.tsx b/public/app/features/dashboard/components/SaveDashboard/SaveDashboardDiff.tsx index ba26e0ba1b2..6deb43117f4 100644 --- a/public/app/features/dashboard/components/SaveDashboard/SaveDashboardDiff.tsx +++ b/public/app/features/dashboard/components/SaveDashboard/SaveDashboardDiff.tsx @@ -1,11 +1,13 @@ -import React from 'react'; import { css } from '@emotion/css'; +import React from 'react'; +import { useAsync } from 'react-use'; + +import { GrafanaTheme2 } from '@grafana/data'; import { Spinner, useStyles2 } from '@grafana/ui'; -import { Diffs } from '../VersionHistory/utils'; + import { DiffGroup } from '../VersionHistory/DiffGroup'; import { DiffViewer } from '../VersionHistory/DiffViewer'; -import { GrafanaTheme2 } from '@grafana/data'; -import { useAsync } from 'react-use'; +import { Diffs } from '../VersionHistory/utils'; interface SaveDashboardDiffProps { oldValue?: any; diff --git a/public/app/features/dashboard/components/SaveDashboard/SaveDashboardDrawer.tsx b/public/app/features/dashboard/components/SaveDashboard/SaveDashboardDrawer.tsx index 798dd6a333e..5c37e6389d6 100644 --- a/public/app/features/dashboard/components/SaveDashboard/SaveDashboardDrawer.tsx +++ b/public/app/features/dashboard/components/SaveDashboard/SaveDashboardDrawer.tsx @@ -1,15 +1,18 @@ import React, { useMemo, useState } from 'react'; -import { Drawer, Tab, TabsBar } from '@grafana/ui'; -import { SaveDashboardData, SaveDashboardModalProps, SaveDashboardOptions } from './types'; -import { jsonDiff } from '../VersionHistory/utils'; import { useAsync } from 'react-use'; + +import { Drawer, Tab, TabsBar } from '@grafana/ui'; import { backendSrv } from 'app/core/services/backend_srv'; -import { useDashboardSave } from './useDashboardSave'; -import { SaveProvisionedDashboardForm } from './forms/SaveProvisionedDashboardForm'; + +import { jsonDiff } from '../VersionHistory/utils'; + +import { SaveDashboardDiff } from './SaveDashboardDiff'; import { SaveDashboardErrorProxy } from './SaveDashboardErrorProxy'; import { SaveDashboardAsForm } from './forms/SaveDashboardAsForm'; import { SaveDashboardForm } from './forms/SaveDashboardForm'; -import { SaveDashboardDiff } from './SaveDashboardDiff'; +import { SaveProvisionedDashboardForm } from './forms/SaveProvisionedDashboardForm'; +import { SaveDashboardData, SaveDashboardModalProps, SaveDashboardOptions } from './types'; +import { useDashboardSave } from './useDashboardSave'; export const SaveDashboardDrawer = ({ dashboard, onDismiss, onSaveSuccess, isCopy }: SaveDashboardModalProps) => { const [options, setOptions] = useState({}); diff --git a/public/app/features/dashboard/components/SaveDashboard/SaveDashboardErrorProxy.tsx b/public/app/features/dashboard/components/SaveDashboard/SaveDashboardErrorProxy.tsx index a1c1df7425f..cde2d55f1a1 100644 --- a/public/app/features/dashboard/components/SaveDashboard/SaveDashboardErrorProxy.tsx +++ b/public/app/features/dashboard/components/SaveDashboard/SaveDashboardErrorProxy.tsx @@ -1,11 +1,13 @@ -import React, { useEffect } from 'react'; -import { Button, ConfirmModal, Modal, stylesFactory, useTheme } from '@grafana/ui'; -import { GrafanaTheme } from '@grafana/data'; import { css } from '@emotion/css'; +import React, { useEffect } from 'react'; + +import { GrafanaTheme } from '@grafana/data'; +import { Button, ConfirmModal, Modal, stylesFactory, useTheme } from '@grafana/ui'; import { DashboardModel } from 'app/features/dashboard/state'; -import { useDashboardSave } from './useDashboardSave'; -import { SaveDashboardModalProps } from './types'; + import { SaveDashboardAsButton } from './SaveDashboardButton'; +import { SaveDashboardModalProps } from './types'; +import { useDashboardSave } from './useDashboardSave'; interface SaveDashboardErrorProxyProps { /** original dashboard */ diff --git a/public/app/features/dashboard/components/SaveDashboard/SaveDashboardModal.tsx b/public/app/features/dashboard/components/SaveDashboard/SaveDashboardModal.tsx index 42d4ac53a99..231d1d5021a 100644 --- a/public/app/features/dashboard/components/SaveDashboard/SaveDashboardModal.tsx +++ b/public/app/features/dashboard/components/SaveDashboard/SaveDashboardModal.tsx @@ -1,10 +1,12 @@ -import React, { useMemo, useState } from 'react'; -import { Modal } from '@grafana/ui'; import { css } from '@emotion/css'; -import { SaveDashboardForm } from './forms/SaveDashboardForm'; +import React, { useMemo, useState } from 'react'; + +import { Modal } from '@grafana/ui'; + import { SaveDashboardErrorProxy } from './SaveDashboardErrorProxy'; -import { useDashboardSave } from './useDashboardSave'; +import { SaveDashboardForm } from './forms/SaveDashboardForm'; import { SaveDashboardModalProps, SaveDashboardOptions, SaveDashboardData } from './types'; +import { useDashboardSave } from './useDashboardSave'; export const SaveDashboardModal: React.FC = ({ dashboard, onDismiss, onSaveSuccess }) => { const { state, onDashboardSave } = useDashboardSave(dashboard); diff --git a/public/app/features/dashboard/components/SaveDashboard/SaveDashboardProxy.tsx b/public/app/features/dashboard/components/SaveDashboard/SaveDashboardProxy.tsx index ba9288672b4..50d149bfce3 100644 --- a/public/app/features/dashboard/components/SaveDashboard/SaveDashboardProxy.tsx +++ b/public/app/features/dashboard/components/SaveDashboard/SaveDashboardProxy.tsx @@ -1,10 +1,12 @@ import React from 'react'; -import { SaveProvisionedDashboard } from './SaveProvisionedDashboard'; -import { SaveDashboardAsModal } from './SaveDashboardAsModal'; -import { SaveDashboardModalProps } from './types'; -import { SaveDashboardModal } from './SaveDashboardModal'; + import { config } from '@grafana/runtime'; + +import { SaveDashboardAsModal } from './SaveDashboardAsModal'; import { SaveDashboardDrawer } from './SaveDashboardDrawer'; +import { SaveDashboardModal } from './SaveDashboardModal'; +import { SaveProvisionedDashboard } from './SaveProvisionedDashboard'; +import { SaveDashboardModalProps } from './types'; export const SaveDashboardProxy: React.FC = ({ dashboard, diff --git a/public/app/features/dashboard/components/SaveDashboard/SaveProvisionedDashboard.tsx b/public/app/features/dashboard/components/SaveDashboard/SaveProvisionedDashboard.tsx index 135825fe910..cedb83c9948 100644 --- a/public/app/features/dashboard/components/SaveDashboard/SaveProvisionedDashboard.tsx +++ b/public/app/features/dashboard/components/SaveDashboard/SaveProvisionedDashboard.tsx @@ -1,5 +1,7 @@ import React from 'react'; + import { Modal } from '@grafana/ui'; + import { SaveProvisionedDashboardForm } from './forms/SaveProvisionedDashboardForm'; import { SaveDashboardModalProps } from './types'; diff --git a/public/app/features/dashboard/components/SaveDashboard/UnsavedChangesModal.tsx b/public/app/features/dashboard/components/SaveDashboard/UnsavedChangesModal.tsx index fa0eaa4cf19..e7b63939af9 100644 --- a/public/app/features/dashboard/components/SaveDashboard/UnsavedChangesModal.tsx +++ b/public/app/features/dashboard/components/SaveDashboard/UnsavedChangesModal.tsx @@ -1,8 +1,11 @@ -import React from 'react'; -import { Button, Modal } from '@grafana/ui'; -import { SaveDashboardButton } from './SaveDashboardButton'; -import { DashboardModel } from '../../state'; import { css } from '@emotion/css'; +import React from 'react'; + +import { Button, Modal } from '@grafana/ui'; + +import { DashboardModel } from '../../state'; + +import { SaveDashboardButton } from './SaveDashboardButton'; interface UnsavedChangesModalProps { dashboard: DashboardModel; diff --git a/public/app/features/dashboard/components/SaveDashboard/forms/SaveDashboardAsForm.test.tsx b/public/app/features/dashboard/components/SaveDashboard/forms/SaveDashboardAsForm.test.tsx index d58801a2c68..4a36443114c 100644 --- a/public/app/features/dashboard/components/SaveDashboard/forms/SaveDashboardAsForm.test.tsx +++ b/public/app/features/dashboard/components/SaveDashboard/forms/SaveDashboardAsForm.test.tsx @@ -1,10 +1,12 @@ -import React from 'react'; import { mount } from 'enzyme'; -import { SaveDashboardAsForm, SaveDashboardAsFormProps } from './SaveDashboardAsForm'; -import { DashboardModel } from 'app/features/dashboard/state'; +import React from 'react'; import { act } from 'react-dom/test-utils'; + +import { DashboardModel } from 'app/features/dashboard/state'; import * as api from 'app/features/manage-dashboards/state/actions'; +import { SaveDashboardAsForm, SaveDashboardAsFormProps } from './SaveDashboardAsForm'; + jest.mock('app/features/plugins/datasource_srv', () => ({})); jest.mock('app/features/expressions/ExpressionDatasource', () => ({})); jest.mock('app/features/manage-dashboards/services/ValidationSrv', () => ({ diff --git a/public/app/features/dashboard/components/SaveDashboard/forms/SaveDashboardAsForm.tsx b/public/app/features/dashboard/components/SaveDashboard/forms/SaveDashboardAsForm.tsx index a17b651089a..b1176a0808e 100644 --- a/public/app/features/dashboard/components/SaveDashboard/forms/SaveDashboardAsForm.tsx +++ b/public/app/features/dashboard/components/SaveDashboard/forms/SaveDashboardAsForm.tsx @@ -1,10 +1,12 @@ import React from 'react'; + import { Button, Input, Switch, Form, Field, InputControl, HorizontalGroup } from '@grafana/ui'; -import { DashboardModel, PanelModel } from 'app/features/dashboard/state'; import { FolderPicker } from 'app/core/components/Select/FolderPicker'; -import { SaveDashboardFormProps } from '../types'; +import { DashboardModel, PanelModel } from 'app/features/dashboard/state'; import { validationSrv } from 'app/features/manage-dashboards/services/ValidationSrv'; +import { SaveDashboardFormProps } from '../types'; + interface SaveDashboardAsFormDTO { title: string; $folder: { id?: number; title?: string }; diff --git a/public/app/features/dashboard/components/SaveDashboard/forms/SaveDashboardForm.test.tsx b/public/app/features/dashboard/components/SaveDashboard/forms/SaveDashboardForm.test.tsx index ff7a020d637..8a5b60159d9 100644 --- a/public/app/features/dashboard/components/SaveDashboard/forms/SaveDashboardForm.test.tsx +++ b/public/app/features/dashboard/components/SaveDashboard/forms/SaveDashboardForm.test.tsx @@ -1,10 +1,13 @@ -import React from 'react'; import { mount } from 'enzyme'; +import React from 'react'; import { act } from 'react-dom/test-utils'; + import { DashboardModel } from 'app/features/dashboard/state'; -import { SaveDashboardForm } from './SaveDashboardForm'; + import { SaveDashboardOptions } from '../types'; +import { SaveDashboardForm } from './SaveDashboardForm'; + const prepareDashboardMock = ( timeChanged: boolean, variableValuesChanged: boolean, diff --git a/public/app/features/dashboard/components/SaveDashboard/forms/SaveDashboardForm.tsx b/public/app/features/dashboard/components/SaveDashboard/forms/SaveDashboardForm.tsx index 37463b0c85e..1bae42d0dab 100644 --- a/public/app/features/dashboard/components/SaveDashboard/forms/SaveDashboardForm.tsx +++ b/public/app/features/dashboard/components/SaveDashboard/forms/SaveDashboardForm.tsx @@ -1,11 +1,11 @@ import React, { useMemo, useState } from 'react'; -import { Button, Checkbox, Form, TextArea } from '@grafana/ui'; import { selectors } from '@grafana/e2e-selectors'; - -import { DashboardModel } from 'app/features/dashboard/state'; -import { SaveDashboardData, SaveDashboardOptions } from '../types'; import { Stack } from '@grafana/experimental'; +import { Button, Checkbox, Form, TextArea } from '@grafana/ui'; +import { DashboardModel } from 'app/features/dashboard/state'; + +import { SaveDashboardData, SaveDashboardOptions } from '../types'; interface FormDTO { message: string; diff --git a/public/app/features/dashboard/components/SaveDashboard/forms/SaveProvisionedDashboardForm.tsx b/public/app/features/dashboard/components/SaveDashboard/forms/SaveProvisionedDashboardForm.tsx index da03cbf3ce2..8fc0075998e 100644 --- a/public/app/features/dashboard/components/SaveDashboard/forms/SaveProvisionedDashboardForm.tsx +++ b/public/app/features/dashboard/components/SaveDashboard/forms/SaveProvisionedDashboardForm.tsx @@ -1,11 +1,13 @@ -import React, { useCallback, useState } from 'react'; import { css } from '@emotion/css'; import { saveAs } from 'file-saver'; -import { Button, ClipboardButton, HorizontalGroup, stylesFactory, TextArea, useTheme } from '@grafana/ui'; -import { SaveDashboardFormProps } from '../types'; +import React, { useCallback, useState } from 'react'; + import { GrafanaTheme } from '@grafana/data'; -import { useAppNotification } from 'app/core/copy/appNotification'; import { Stack } from '@grafana/experimental'; +import { Button, ClipboardButton, HorizontalGroup, stylesFactory, TextArea, useTheme } from '@grafana/ui'; +import { useAppNotification } from 'app/core/copy/appNotification'; + +import { SaveDashboardFormProps } from '../types'; export const SaveProvisionedDashboardForm: React.FC = ({ dashboard, onCancel }) => { const theme = useTheme(); diff --git a/public/app/features/dashboard/components/SaveDashboard/types.ts b/public/app/features/dashboard/components/SaveDashboard/types.ts index a8783ff6b69..e0ab7e9c8c5 100644 --- a/public/app/features/dashboard/components/SaveDashboard/types.ts +++ b/public/app/features/dashboard/components/SaveDashboard/types.ts @@ -1,4 +1,5 @@ import { CloneOptions, DashboardModel } from 'app/features/dashboard/state/DashboardModel'; + import { Diffs } from '../VersionHistory/utils'; export interface SaveDashboardData { diff --git a/public/app/features/dashboard/components/SaveDashboard/useDashboardSave.tsx b/public/app/features/dashboard/components/SaveDashboard/useDashboardSave.tsx index d6675c9dd97..6c4237f855f 100644 --- a/public/app/features/dashboard/components/SaveDashboard/useDashboardSave.tsx +++ b/public/app/features/dashboard/components/SaveDashboard/useDashboardSave.tsx @@ -1,15 +1,17 @@ import { useEffect } from 'react'; import useAsyncFn from 'react-use/lib/useAsyncFn'; + import { locationUtil } from '@grafana/data'; -import { SaveDashboardOptions } from './types'; +import { locationService, reportInteraction } from '@grafana/runtime'; import appEvents from 'app/core/app_events'; -import { contextSrv } from 'app/core/core'; import { useAppNotification } from 'app/core/copy/appNotification'; +import { contextSrv } from 'app/core/core'; import { DashboardModel } from 'app/features/dashboard/state'; import { saveDashboard as saveDashboardApiCall } from 'app/features/manage-dashboards/state/actions'; -import { locationService, reportInteraction } from '@grafana/runtime'; import { DashboardSavedEvent } from 'app/types/events'; +import { SaveDashboardOptions } from './types'; + const saveDashboard = async (saveModel: any, options: SaveDashboardOptions, dashboard: DashboardModel) => { let folderId = options.folderId; if (folderId === undefined) { diff --git a/public/app/features/dashboard/components/ShareModal/ShareEmbed.test.tsx b/public/app/features/dashboard/components/ShareModal/ShareEmbed.test.tsx index 22d9e22ad75..ac1293a487c 100644 --- a/public/app/features/dashboard/components/ShareModal/ShareEmbed.test.tsx +++ b/public/app/features/dashboard/components/ShareModal/ShareEmbed.test.tsx @@ -1,9 +1,12 @@ -import React from 'react'; -import { ShareEmbed } from './ShareEmbed'; import { render, screen } from '@testing-library/react'; +import React from 'react'; + import config from 'app/core/config'; + import { DashboardModel, PanelModel } from '../../state'; +import { ShareEmbed } from './ShareEmbed'; + jest.mock('app/features/dashboard/services/TimeSrv', () => ({ getTimeSrv: () => ({ timeRange: () => { diff --git a/public/app/features/dashboard/components/ShareModal/ShareEmbed.tsx b/public/app/features/dashboard/components/ShareModal/ShareEmbed.tsx index f1c97a727a8..1262ee2dfde 100644 --- a/public/app/features/dashboard/components/ShareModal/ShareEmbed.tsx +++ b/public/app/features/dashboard/components/ShareModal/ShareEmbed.tsx @@ -1,9 +1,11 @@ import React, { FormEvent, PureComponent } from 'react'; -import { ClipboardButton, Field, Modal, RadioButtonGroup, Switch, TextArea } from '@grafana/ui'; + import { AppEvents, SelectableValue } from '@grafana/data'; +import { ClipboardButton, Field, Modal, RadioButtonGroup, Switch, TextArea } from '@grafana/ui'; import { appEvents } from 'app/core/core'; -import { buildIframeHtml } from './utils'; + import { ShareModalTabProps } from './types'; +import { buildIframeHtml } from './utils'; const themeOptions: Array> = [ { label: 'Current', value: 'current' }, diff --git a/public/app/features/dashboard/components/ShareModal/ShareExport.tsx b/public/app/features/dashboard/components/ShareModal/ShareExport.tsx index c687a86f89a..934b233eda1 100644 --- a/public/app/features/dashboard/components/ShareModal/ShareExport.tsx +++ b/public/app/features/dashboard/components/ShareModal/ShareExport.tsx @@ -1,12 +1,14 @@ -import React, { PureComponent } from 'react'; import { saveAs } from 'file-saver'; -import { getBackendSrv } from 'app/core/services/backend_srv'; -import { Button, Field, Modal, Switch } from '@grafana/ui'; -import { DashboardExporter } from 'app/features/dashboard/components/DashExportModal'; -import { appEvents } from 'app/core/core'; -import { ShowModalReactEvent } from 'app/types/events'; -import { ViewJsonModal } from './ViewJsonModal'; +import React, { PureComponent } from 'react'; + import { config } from '@grafana/runtime'; +import { Button, Field, Modal, Switch } from '@grafana/ui'; +import { appEvents } from 'app/core/core'; +import { getBackendSrv } from 'app/core/services/backend_srv'; +import { DashboardExporter } from 'app/features/dashboard/components/DashExportModal'; +import { ShowModalReactEvent } from 'app/types/events'; + +import { ViewJsonModal } from './ViewJsonModal'; import { ShareModalTabProps } from './types'; interface Props extends ShareModalTabProps {} diff --git a/public/app/features/dashboard/components/ShareModal/ShareLibraryPanel.tsx b/public/app/features/dashboard/components/ShareModal/ShareLibraryPanel.tsx index a9b5ace06c9..db91c703b43 100644 --- a/public/app/features/dashboard/components/ShareModal/ShareLibraryPanel.tsx +++ b/public/app/features/dashboard/components/ShareModal/ShareLibraryPanel.tsx @@ -1,5 +1,7 @@ import React from 'react'; + import { AddLibraryPanelContents } from 'app/features/library-panels/components/AddLibraryPanelModal/AddLibraryPanelModal'; + import { ShareModalTabProps } from './types'; interface Props extends ShareModalTabProps { diff --git a/public/app/features/dashboard/components/ShareModal/ShareLink.test.tsx b/public/app/features/dashboard/components/ShareModal/ShareLink.test.tsx index b8ec81aa3d3..a8c1ac5ea84 100644 --- a/public/app/features/dashboard/components/ShareModal/ShareLink.test.tsx +++ b/public/app/features/dashboard/components/ShareModal/ShareLink.test.tsx @@ -1,13 +1,16 @@ -import React from 'react'; import { shallow, ShallowWrapper } from 'enzyme'; +import React from 'react'; + +import { getDefaultTimeRange } from '@grafana/data'; import { setTemplateSrv } from '@grafana/runtime'; import config from 'app/core/config'; -import { Props, ShareLink, State } from './ShareLink'; + import { initTemplateSrv } from '../../../../../test/helpers/initTemplateSrv'; import { variableAdapters } from '../../../variables/adapters'; import { createQueryVariableAdapter } from '../../../variables/query/adapter'; import { DashboardModel, PanelModel } from '../../state'; -import { getDefaultTimeRange } from '@grafana/data'; + +import { Props, ShareLink, State } from './ShareLink'; jest.mock('app/features/dashboard/services/TimeSrv', () => ({ getTimeSrv: () => ({ diff --git a/public/app/features/dashboard/components/ShareModal/ShareLink.tsx b/public/app/features/dashboard/components/ShareModal/ShareLink.tsx index b14b485a0cc..0b937f4cf6b 100644 --- a/public/app/features/dashboard/components/ShareModal/ShareLink.tsx +++ b/public/app/features/dashboard/components/ShareModal/ShareLink.tsx @@ -1,11 +1,13 @@ import React, { PureComponent } from 'react'; + +import { AppEvents, SelectableValue } from '@grafana/data'; import { selectors as e2eSelectors } from '@grafana/e2e-selectors'; import { Alert, ClipboardButton, Field, FieldSet, Icon, Input, RadioButtonGroup, Switch } from '@grafana/ui'; -import { AppEvents, SelectableValue } from '@grafana/data'; -import { buildImageUrl, buildShareUrl } from './utils'; -import { appEvents } from 'app/core/core'; import config from 'app/core/config'; +import { appEvents } from 'app/core/core'; + import { ShareModalTabProps } from './types'; +import { buildImageUrl, buildShareUrl } from './utils'; const themeOptions: Array> = [ { label: 'Current', value: 'current' }, diff --git a/public/app/features/dashboard/components/ShareModal/ShareModal.tsx b/public/app/features/dashboard/components/ShareModal/ShareModal.tsx index 984d77ce8bf..bc4945f416a 100644 --- a/public/app/features/dashboard/components/ShareModal/ShareModal.tsx +++ b/public/app/features/dashboard/components/ShareModal/ShareModal.tsx @@ -1,14 +1,16 @@ import React from 'react'; + import { Modal, ModalTabsHeader, TabContent } from '@grafana/ui'; +import { contextSrv } from 'app/core/core'; import { DashboardModel, PanelModel } from 'app/features/dashboard/state'; import { isPanelModelLibraryPanel } from 'app/features/library-panels/guard'; + +import { ShareEmbed } from './ShareEmbed'; +import { ShareExport } from './ShareExport'; +import { ShareLibraryPanel } from './ShareLibraryPanel'; import { ShareLink } from './ShareLink'; import { ShareSnapshot } from './ShareSnapshot'; -import { ShareExport } from './ShareExport'; -import { ShareEmbed } from './ShareEmbed'; import { ShareModalTabModel } from './types'; -import { contextSrv } from 'app/core/core'; -import { ShareLibraryPanel } from './ShareLibraryPanel'; const customDashboardTabs: ShareModalTabModel[] = []; const customPanelTabs: ShareModalTabModel[] = []; diff --git a/public/app/features/dashboard/components/ShareModal/ShareSnapshot.tsx b/public/app/features/dashboard/components/ShareModal/ShareSnapshot.tsx index 1ac5b0d4d19..91d552a0195 100644 --- a/public/app/features/dashboard/components/ShareModal/ShareSnapshot.tsx +++ b/public/app/features/dashboard/components/ShareModal/ShareSnapshot.tsx @@ -1,11 +1,14 @@ import React, { PureComponent } from 'react'; -import { Button, ClipboardButton, Field, Icon, Input, LinkButton, Modal, Select, Spinner } from '@grafana/ui'; + import { AppEvents, SelectableValue } from '@grafana/data'; import { getBackendSrv } from '@grafana/runtime'; -import { DashboardModel, PanelModel } from 'app/features/dashboard/state'; -import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv'; +import { Button, ClipboardButton, Field, Icon, Input, LinkButton, Modal, Select, Spinner } from '@grafana/ui'; import { appEvents } from 'app/core/core'; +import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv'; +import { DashboardModel, PanelModel } from 'app/features/dashboard/state'; + import { VariableRefresh } from '../../../variables/types'; + import { ShareModalTabProps } from './types'; const snapshotApiUrl = '/api/snapshots'; diff --git a/public/app/features/dashboard/components/ShareModal/ViewJsonModal.tsx b/public/app/features/dashboard/components/ShareModal/ViewJsonModal.tsx index 272d60057e1..fc5f35cb7fe 100644 --- a/public/app/features/dashboard/components/ShareModal/ViewJsonModal.tsx +++ b/public/app/features/dashboard/components/ShareModal/ViewJsonModal.tsx @@ -1,10 +1,11 @@ import React, { useCallback } from 'react'; +import AutoSizer from 'react-virtualized-auto-sizer'; + import { ClipboardButton, CodeEditor, Modal } from '@grafana/ui'; -import AutoSizer from 'react-virtualized-auto-sizer'; import { notifyApp } from '../../../../core/actions'; -import { dispatch } from '../../../../store/store'; import { createSuccessNotification } from '../../../../core/copy/appNotification'; +import { dispatch } from '../../../../store/store'; export interface ViewJsonModalProps { json: string; diff --git a/public/app/features/dashboard/components/ShareModal/types.ts b/public/app/features/dashboard/components/ShareModal/types.ts index 42d45c9ea89..558bd0fa8a9 100644 --- a/public/app/features/dashboard/components/ShareModal/types.ts +++ b/public/app/features/dashboard/components/ShareModal/types.ts @@ -1,4 +1,5 @@ import React from 'react'; + import { NavModelItem } from '@grafana/data'; import { DashboardModel, PanelModel } from 'app/features/dashboard/state'; diff --git a/public/app/features/dashboard/components/ShareModal/utils.test.ts b/public/app/features/dashboard/components/ShareModal/utils.test.ts index 5b359e1ea2a..8e2a42d553a 100644 --- a/public/app/features/dashboard/components/ShareModal/utils.test.ts +++ b/public/app/features/dashboard/components/ShareModal/utils.test.ts @@ -1,6 +1,7 @@ -import { buildParams } from './utils'; import { TimeRange } from '@grafana/data'; +import { buildParams } from './utils'; + describe('buildParams', () => { it.each` search | useCurrentTimeRange | selectedTheme | panel | expected diff --git a/public/app/features/dashboard/components/ShareModal/utils.ts b/public/app/features/dashboard/components/ShareModal/utils.ts index 4667ec23ae1..fb350ce464a 100644 --- a/public/app/features/dashboard/components/ShareModal/utils.ts +++ b/public/app/features/dashboard/components/ShareModal/utils.ts @@ -1,7 +1,7 @@ -import { config } from '@grafana/runtime'; -import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv'; -import { createShortLink } from 'app/core/utils/shortLinks'; import { dateTime, locationUtil, PanelModel, TimeRange, urlUtil } from '@grafana/data'; +import { config } from '@grafana/runtime'; +import { createShortLink } from 'app/core/utils/shortLinks'; +import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv'; export interface BuildParamsArgs { useCurrentTimeRange: boolean; diff --git a/public/app/features/dashboard/components/SubMenu/AnnotationPicker.tsx b/public/app/features/dashboard/components/SubMenu/AnnotationPicker.tsx index dda2461e908..ed9a0b3f38c 100644 --- a/public/app/features/dashboard/components/SubMenu/AnnotationPicker.tsx +++ b/public/app/features/dashboard/components/SubMenu/AnnotationPicker.tsx @@ -1,10 +1,12 @@ -import { AnnotationQuery, EventBus, GrafanaTheme2 } from '@grafana/data'; +import { css } from '@emotion/css'; import React, { useEffect, useState } from 'react'; -import { getDashboardQueryRunner } from '../../../query/state/DashboardQueryRunner/DashboardQueryRunner'; -import { AnnotationQueryFinished, AnnotationQueryStarted } from '../../../../types/events'; + +import { AnnotationQuery, EventBus, GrafanaTheme2 } from '@grafana/data'; import { InlineField, InlineFieldRow, InlineSwitch, useStyles2 } from '@grafana/ui'; import { LoadingIndicator } from '@grafana/ui/src/components/PanelChrome/LoadingIndicator'; -import { css } from '@emotion/css'; + +import { AnnotationQueryFinished, AnnotationQueryStarted } from '../../../../types/events'; +import { getDashboardQueryRunner } from '../../../query/state/DashboardQueryRunner/DashboardQueryRunner'; export interface AnnotationPickerProps { events: EventBus; diff --git a/public/app/features/dashboard/components/SubMenu/Annotations.tsx b/public/app/features/dashboard/components/SubMenu/Annotations.tsx index 8f0d30afe5d..a08f235341a 100644 --- a/public/app/features/dashboard/components/SubMenu/Annotations.tsx +++ b/public/app/features/dashboard/components/SubMenu/Annotations.tsx @@ -1,5 +1,7 @@ import React, { FunctionComponent, useEffect, useState } from 'react'; + import { AnnotationQuery, EventBus } from '@grafana/data'; + import { AnnotationPicker } from './AnnotationPicker'; interface Props { diff --git a/public/app/features/dashboard/components/SubMenu/DashboardLinks.tsx b/public/app/features/dashboard/components/SubMenu/DashboardLinks.tsx index 2cc9bd5b752..b86b66651c8 100644 --- a/public/app/features/dashboard/components/SubMenu/DashboardLinks.tsx +++ b/public/app/features/dashboard/components/SubMenu/DashboardLinks.tsx @@ -1,15 +1,17 @@ import React, { FC } from 'react'; -import { Icon, IconName, Tooltip, useForceUpdate } from '@grafana/ui'; -import { sanitizeUrl } from '@grafana/data/src/text/sanitize'; -import { DashboardLinksDashboard } from './DashboardLinksDashboard'; -import { getLinkSrv } from '../../../panel/panellinks/link_srv'; +import { useEffectOnce } from 'react-use'; +import { sanitizeUrl } from '@grafana/data/src/text/sanitize'; +import { selectors } from '@grafana/e2e-selectors'; +import { TimeRangeUpdatedEvent } from '@grafana/runtime'; +import { Icon, IconName, Tooltip, useForceUpdate } from '@grafana/ui'; + +import { getLinkSrv } from '../../../panel/panellinks/link_srv'; import { DashboardModel } from '../../state'; import { DashboardLink } from '../../state/DashboardModel'; import { linkIconMap } from '../LinksSettings/LinkSettingsEdit'; -import { useEffectOnce } from 'react-use'; -import { selectors } from '@grafana/e2e-selectors'; -import { TimeRangeUpdatedEvent } from '@grafana/runtime'; + +import { DashboardLinksDashboard } from './DashboardLinksDashboard'; export interface Props { dashboard: DashboardModel; diff --git a/public/app/features/dashboard/components/SubMenu/DashboardLinksDashboard.test.tsx b/public/app/features/dashboard/components/SubMenu/DashboardLinksDashboard.test.tsx index 23d17ef61da..8586b726640 100644 --- a/public/app/features/dashboard/components/SubMenu/DashboardLinksDashboard.test.tsx +++ b/public/app/features/dashboard/components/SubMenu/DashboardLinksDashboard.test.tsx @@ -1,7 +1,8 @@ -import { DashboardLink } from '../../state/DashboardModel'; -import { DashboardSearchHit, DashboardSearchItemType } from '../../../search/types'; -import { resolveLinks, searchForTags } from './DashboardLinksDashboard'; import { describe, expect } from '../../../../../test/lib/common'; +import { DashboardSearchHit, DashboardSearchItemType } from '../../../search/types'; +import { DashboardLink } from '../../state/DashboardModel'; + +import { resolveLinks, searchForTags } from './DashboardLinksDashboard'; describe('searchForTags', () => { const setupTestContext = () => { diff --git a/public/app/features/dashboard/components/SubMenu/DashboardLinksDashboard.tsx b/public/app/features/dashboard/components/SubMenu/DashboardLinksDashboard.tsx index 203af35cf60..53ccd630a0b 100644 --- a/public/app/features/dashboard/components/SubMenu/DashboardLinksDashboard.tsx +++ b/public/app/features/dashboard/components/SubMenu/DashboardLinksDashboard.tsx @@ -1,13 +1,15 @@ +import { css, cx } from '@emotion/css'; import React, { useRef, useState, useLayoutEffect } from 'react'; -import { Icon, ToolbarButton, Tooltip, useStyles2 } from '@grafana/ui'; +import { useAsync } from 'react-use'; + import { sanitize, sanitizeUrl } from '@grafana/data/src/text/sanitize'; +import { selectors } from '@grafana/e2e-selectors'; +import { Icon, ToolbarButton, Tooltip, useStyles2 } from '@grafana/ui'; import { getBackendSrv } from 'app/core/services/backend_srv'; +import { DashboardSearchHit } from 'app/features/search/types'; + import { getLinkSrv } from '../../../panel/panellinks/link_srv'; import { DashboardLink } from '../../state/DashboardModel'; -import { DashboardSearchHit } from 'app/features/search/types'; -import { selectors } from '@grafana/e2e-selectors'; -import { useAsync } from 'react-use'; -import { css, cx } from '@emotion/css'; interface Props { link: DashboardLink; diff --git a/public/app/features/dashboard/components/SubMenu/SubMenu.tsx b/public/app/features/dashboard/components/SubMenu/SubMenu.tsx index 14839796da0..a22a3e4a280 100644 --- a/public/app/features/dashboard/components/SubMenu/SubMenu.tsx +++ b/public/app/features/dashboard/components/SubMenu/SubMenu.tsx @@ -1,15 +1,18 @@ +import { css } from '@emotion/css'; import React, { PureComponent } from 'react'; import { connect, MapStateToProps } from 'react-redux'; + +import { AnnotationQuery } from '@grafana/data'; + import { StoreState } from '../../../../types'; import { getSubMenuVariables, getVariablesState } from '../../../variables/state/selectors'; import { VariableModel } from '../../../variables/types'; import { DashboardModel } from '../../state'; -import { DashboardLinks } from './DashboardLinks'; -import { Annotations } from './Annotations'; -import { SubMenuItems } from './SubMenuItems'; import { DashboardLink } from '../../state/DashboardModel'; -import { AnnotationQuery } from '@grafana/data'; -import { css } from '@emotion/css'; + +import { Annotations } from './Annotations'; +import { DashboardLinks } from './DashboardLinks'; +import { SubMenuItems } from './SubMenuItems'; interface OwnProps { dashboard: DashboardModel; diff --git a/public/app/features/dashboard/components/SubMenu/SubMenuItems.tsx b/public/app/features/dashboard/components/SubMenu/SubMenuItems.tsx index 72f15ba4db8..7bc29f1721a 100644 --- a/public/app/features/dashboard/components/SubMenu/SubMenuItems.tsx +++ b/public/app/features/dashboard/components/SubMenu/SubMenuItems.tsx @@ -1,7 +1,9 @@ import React, { FunctionComponent, useEffect, useState } from 'react'; -import { VariableHide, VariableModel } from '../../../variables/types'; + import { selectors } from '@grafana/e2e-selectors'; + import { PickerRenderer } from '../../../variables/pickers/PickerRenderer'; +import { VariableHide, VariableModel } from '../../../variables/types'; interface Props { variables: VariableModel[]; diff --git a/public/app/features/dashboard/components/TransformationsEditor/TransformationEditor.tsx b/public/app/features/dashboard/components/TransformationsEditor/TransformationEditor.tsx index 64b626a5a1b..f1d99bd708c 100644 --- a/public/app/features/dashboard/components/TransformationsEditor/TransformationEditor.tsx +++ b/public/app/features/dashboard/components/TransformationsEditor/TransformationEditor.tsx @@ -1,7 +1,7 @@ +import { css } from '@emotion/css'; import React, { useEffect, useMemo, useState } from 'react'; import { mergeMap } from 'rxjs/operators'; -import { css } from '@emotion/css'; -import { Icon, JSONFormatter, useStyles } from '@grafana/ui'; + import { DataFrame, DataTransformerConfig, @@ -10,6 +10,7 @@ import { TransformerRegistryItem, } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; +import { Icon, JSONFormatter, useStyles } from '@grafana/ui'; import { TransformationsEditorTransformation } from './types'; diff --git a/public/app/features/dashboard/components/TransformationsEditor/TransformationOperationRow.tsx b/public/app/features/dashboard/components/TransformationsEditor/TransformationOperationRow.tsx index c2d82b330d7..71eeb0200e1 100644 --- a/public/app/features/dashboard/components/TransformationsEditor/TransformationOperationRow.tsx +++ b/public/app/features/dashboard/components/TransformationsEditor/TransformationOperationRow.tsx @@ -1,17 +1,18 @@ import React, { useCallback } from 'react'; +import { useToggle } from 'react-use'; + import { DataFrame, DataTransformerConfig, TransformerRegistryItem } from '@grafana/data'; import { HorizontalGroup } from '@grafana/ui'; - -import { TransformationEditor } from './TransformationEditor'; +import { OperationRowHelp } from 'app/core/components/QueryOperationRow/OperationRowHelp'; +import { QueryOperationAction } from 'app/core/components/QueryOperationRow/QueryOperationAction'; import { QueryOperationRow, QueryOperationRowRenderProps, } from 'app/core/components/QueryOperationRow/QueryOperationRow'; -import { QueryOperationAction } from 'app/core/components/QueryOperationRow/QueryOperationAction'; -import { TransformationsEditorTransformation } from './types'; import { PluginStateInfo } from 'app/features/plugins/components/PluginStateInfo'; -import { useToggle } from 'react-use'; -import { OperationRowHelp } from 'app/core/components/QueryOperationRow/OperationRowHelp'; + +import { TransformationEditor } from './TransformationEditor'; +import { TransformationsEditorTransformation } from './types'; interface TransformationOperationRowProps { id: string; diff --git a/public/app/features/dashboard/components/TransformationsEditor/TransformationOperationRows.tsx b/public/app/features/dashboard/components/TransformationsEditor/TransformationOperationRows.tsx index 6477e0ee920..c9849c755d5 100644 --- a/public/app/features/dashboard/components/TransformationsEditor/TransformationOperationRows.tsx +++ b/public/app/features/dashboard/components/TransformationsEditor/TransformationOperationRows.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { DataFrame, DataTransformerConfig, standardTransformersRegistry } from '@grafana/data'; import { TransformationOperationRow } from './TransformationOperationRow'; diff --git a/public/app/features/dashboard/components/TransformationsEditor/TransformationsEditor.test.tsx b/public/app/features/dashboard/components/TransformationsEditor/TransformationsEditor.test.tsx index 617d4f9f86b..83586953eb1 100644 --- a/public/app/features/dashboard/components/TransformationsEditor/TransformationsEditor.test.tsx +++ b/public/app/features/dashboard/components/TransformationsEditor/TransformationsEditor.test.tsx @@ -1,11 +1,14 @@ -import React from 'react'; -import { DataTransformerConfig, standardTransformersRegistry } from '@grafana/data'; import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { TransformationsEditor } from './TransformationsEditor'; -import { PanelModel } from '../../state'; -import { getStandardTransformers } from 'app/features/transformers/standardTransformers'; +import React from 'react'; + +import { DataTransformerConfig, standardTransformersRegistry } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; +import { getStandardTransformers } from 'app/features/transformers/standardTransformers'; + +import { PanelModel } from '../../state'; + +import { TransformationsEditor } from './TransformationsEditor'; const setup = (transformations: DataTransformerConfig[] = []) => { const panel = new PanelModel({}); diff --git a/public/app/features/dashboard/components/TransformationsEditor/TransformationsEditor.tsx b/public/app/features/dashboard/components/TransformationsEditor/TransformationsEditor.tsx index 5450522ce61..8e9c99230ed 100644 --- a/public/app/features/dashboard/components/TransformationsEditor/TransformationsEditor.tsx +++ b/public/app/features/dashboard/components/TransformationsEditor/TransformationsEditor.tsx @@ -1,4 +1,19 @@ +import { css } from '@emotion/css'; import React, { ChangeEvent } from 'react'; +import { DragDropContext, Droppable, DropResult } from 'react-beautiful-dnd'; +import { Unsubscribable } from 'rxjs'; + +import { + DataFrame, + DataTransformerConfig, + DocsId, + GrafanaTheme2, + PanelData, + SelectableValue, + standardTransformersRegistry, + TransformerRegistryItem, +} from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; import { Alert, Button, @@ -12,28 +27,16 @@ import { useStyles2, Card, } from '@grafana/ui'; -import { - DataFrame, - DataTransformerConfig, - DocsId, - GrafanaTheme2, - PanelData, - SelectableValue, - standardTransformersRegistry, - TransformerRegistryItem, -} from '@grafana/data'; -import { css } from '@emotion/css'; -import { selectors } from '@grafana/e2e-selectors'; -import { Unsubscribable } from 'rxjs'; -import { PanelModel } from '../../state'; +import { LocalStorageValueProvider } from 'app/core/components/LocalStorageValueProvider'; import { getDocsLink } from 'app/core/utils/docsLinks'; -import { DragDropContext, Droppable, DropResult } from 'react-beautiful-dnd'; +import { PluginStateInfo } from 'app/features/plugins/components/PluginStateInfo'; + +import { AppNotificationSeverity } from '../../../../types'; +import { PanelModel } from '../../state'; +import { PanelNotSupported } from '../PanelEditor/PanelNotSupported'; + import { TransformationOperationRows } from './TransformationOperationRows'; import { TransformationsEditorTransformation } from './types'; -import { PanelNotSupported } from '../PanelEditor/PanelNotSupported'; -import { AppNotificationSeverity } from '../../../../types'; -import { LocalStorageValueProvider } from 'app/core/components/LocalStorageValueProvider'; -import { PluginStateInfo } from 'app/features/plugins/components/PluginStateInfo'; const LOCAL_STORAGE_KEY = 'dashboard.components.TransformationEditor.featureInfoBox.isDismissed'; diff --git a/public/app/features/dashboard/components/VersionHistory/DiffGroup.tsx b/public/app/features/dashboard/components/VersionHistory/DiffGroup.tsx index cfe61de8e7f..487d43c8d37 100644 --- a/public/app/features/dashboard/components/VersionHistory/DiffGroup.tsx +++ b/public/app/features/dashboard/components/VersionHistory/DiffGroup.tsx @@ -1,8 +1,10 @@ -import React from 'react'; -import { last } from 'lodash'; -import { useStyles } from '@grafana/ui'; -import { GrafanaTheme } from '@grafana/data'; import { css } from '@emotion/css'; +import { last } from 'lodash'; +import React from 'react'; + +import { GrafanaTheme } from '@grafana/data'; +import { useStyles } from '@grafana/ui'; + import { DiffTitle } from './DiffTitle'; import { DiffValues } from './DiffValues'; import { Diff, getDiffText } from './utils'; diff --git a/public/app/features/dashboard/components/VersionHistory/DiffTitle.tsx b/public/app/features/dashboard/components/VersionHistory/DiffTitle.tsx index 1637b4b76b0..e62157343d9 100644 --- a/public/app/features/dashboard/components/VersionHistory/DiffTitle.tsx +++ b/public/app/features/dashboard/components/VersionHistory/DiffTitle.tsx @@ -1,9 +1,11 @@ -import React from 'react'; -import { useStyles, Icon } from '@grafana/ui'; -import { GrafanaTheme } from '@grafana/data'; import { css } from '@emotion/css'; -import { Diff, getDiffText } from './utils'; +import React from 'react'; + +import { GrafanaTheme } from '@grafana/data'; +import { useStyles, Icon } from '@grafana/ui'; + import { DiffValues } from './DiffValues'; +import { Diff, getDiffText } from './utils'; type DiffTitleProps = { diff?: Diff; diff --git a/public/app/features/dashboard/components/VersionHistory/DiffValues.tsx b/public/app/features/dashboard/components/VersionHistory/DiffValues.tsx index f7e901213f9..c59207bf466 100644 --- a/public/app/features/dashboard/components/VersionHistory/DiffValues.tsx +++ b/public/app/features/dashboard/components/VersionHistory/DiffValues.tsx @@ -1,8 +1,10 @@ -import React from 'react'; -import { isArray, isObject, isUndefined } from 'lodash'; -import { useStyles2, Icon } from '@grafana/ui'; -import { GrafanaTheme2 } from '@grafana/data'; import { css } from '@emotion/css'; +import { isArray, isObject, isUndefined } from 'lodash'; +import React from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; +import { useStyles2, Icon } from '@grafana/ui'; + import { Diff } from './utils'; type DiffProps = { diff --git a/public/app/features/dashboard/components/VersionHistory/DiffViewer.tsx b/public/app/features/dashboard/components/VersionHistory/DiffViewer.tsx index fcf0cfc7ca4..52490961500 100644 --- a/public/app/features/dashboard/components/VersionHistory/DiffViewer.tsx +++ b/public/app/features/dashboard/components/VersionHistory/DiffViewer.tsx @@ -1,9 +1,10 @@ -import React from 'react'; import { css } from '@emotion/css'; +import React from 'react'; import ReactDiffViewer, { ReactDiffViewerProps, DiffMethod } from 'react-diff-viewer'; -import { useTheme } from '@grafana/ui'; import tinycolor from 'tinycolor2'; +import { useTheme } from '@grafana/ui'; + export const DiffViewer: React.FC = ({ oldValue, newValue }) => { const theme = useTheme(); diff --git a/public/app/features/dashboard/components/VersionHistory/HistorySrv.test.ts b/public/app/features/dashboard/components/VersionHistory/HistorySrv.test.ts index fd36f7b2a37..8502085fad7 100644 --- a/public/app/features/dashboard/components/VersionHistory/HistorySrv.test.ts +++ b/public/app/features/dashboard/components/VersionHistory/HistorySrv.test.ts @@ -1,7 +1,8 @@ -import { restore, versions } from './__mocks__/dashboardHistoryMocks'; -import { HistorySrv } from './HistorySrv'; import { DashboardModel } from '../../state/DashboardModel'; +import { HistorySrv } from './HistorySrv'; +import { restore, versions } from './__mocks__/dashboardHistoryMocks'; + const getMock = jest.fn().mockResolvedValue({}); const postMock = jest.fn().mockResolvedValue({}); diff --git a/public/app/features/dashboard/components/VersionHistory/HistorySrv.ts b/public/app/features/dashboard/components/VersionHistory/HistorySrv.ts index 5bcd302ffac..0c9db504b01 100644 --- a/public/app/features/dashboard/components/VersionHistory/HistorySrv.ts +++ b/public/app/features/dashboard/components/VersionHistory/HistorySrv.ts @@ -1,7 +1,9 @@ import { isNumber } from 'lodash'; -import { DashboardModel } from '../../state/DashboardModel'; + import { getBackendSrv } from '@grafana/runtime'; +import { DashboardModel } from '../../state/DashboardModel'; + export interface HistoryListOpts { limit: number; start: number; diff --git a/public/app/features/dashboard/components/VersionHistory/RevertDashboardModal.tsx b/public/app/features/dashboard/components/VersionHistory/RevertDashboardModal.tsx index f4f2641d5e0..0420131e03a 100644 --- a/public/app/features/dashboard/components/VersionHistory/RevertDashboardModal.tsx +++ b/public/app/features/dashboard/components/VersionHistory/RevertDashboardModal.tsx @@ -1,5 +1,7 @@ import React, { useEffect } from 'react'; + import { ConfirmModal } from '@grafana/ui'; + import { useDashboardRestore } from './useDashboardRestore'; export interface RevertDashboardModalProps { hideModal: () => void; diff --git a/public/app/features/dashboard/components/VersionHistory/VersionHistoryButtons.tsx b/public/app/features/dashboard/components/VersionHistory/VersionHistoryButtons.tsx index b720d72822b..c8d0d1ad083 100644 --- a/public/app/features/dashboard/components/VersionHistory/VersionHistoryButtons.tsx +++ b/public/app/features/dashboard/components/VersionHistory/VersionHistoryButtons.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { HorizontalGroup, Tooltip, Button } from '@grafana/ui'; type VersionsButtonsType = { diff --git a/public/app/features/dashboard/components/VersionHistory/VersionHistoryComparison.tsx b/public/app/features/dashboard/components/VersionHistory/VersionHistoryComparison.tsx index e132b20a647..8af4e929f90 100644 --- a/public/app/features/dashboard/components/VersionHistory/VersionHistoryComparison.tsx +++ b/public/app/features/dashboard/components/VersionHistory/VersionHistoryComparison.tsx @@ -1,13 +1,15 @@ -import React from 'react'; import { css, cx } from '@emotion/css'; +import React from 'react'; +import { GrafanaTheme } from '@grafana/data'; import { Button, ModalsController, CollapsableSection, HorizontalGroup, useStyles } from '@grafana/ui'; + import { DecoratedRevisionModel } from '../DashboardSettings/VersionsSettings'; -import { RevertDashboardModal } from './RevertDashboardModal'; + import { DiffGroup } from './DiffGroup'; import { DiffViewer } from './DiffViewer'; +import { RevertDashboardModal } from './RevertDashboardModal'; import { jsonDiff } from './utils'; -import { GrafanaTheme } from '@grafana/data'; type DiffViewProps = { isNewLatest: boolean; diff --git a/public/app/features/dashboard/components/VersionHistory/VersionHistoryHeader.tsx b/public/app/features/dashboard/components/VersionHistory/VersionHistoryHeader.tsx index 8ad1cd2ccee..c1109172d62 100644 --- a/public/app/features/dashboard/components/VersionHistory/VersionHistoryHeader.tsx +++ b/public/app/features/dashboard/components/VersionHistory/VersionHistoryHeader.tsx @@ -1,6 +1,7 @@ -import React from 'react'; import { css } from '@emotion/css'; import { noop } from 'lodash'; +import React from 'react'; + import { GrafanaTheme } from '@grafana/data'; import { Icon, useStyles } from '@grafana/ui'; diff --git a/public/app/features/dashboard/components/VersionHistory/VersionHistoryTable.tsx b/public/app/features/dashboard/components/VersionHistory/VersionHistoryTable.tsx index c0b12528f3c..b1809b4502e 100644 --- a/public/app/features/dashboard/components/VersionHistory/VersionHistoryTable.tsx +++ b/public/app/features/dashboard/components/VersionHistory/VersionHistoryTable.tsx @@ -1,7 +1,10 @@ -import React from 'react'; import { css } from '@emotion/css'; +import React from 'react'; + import { Checkbox, Button, Tag, ModalsController } from '@grafana/ui'; + import { DecoratedRevisionModel } from '../DashboardSettings/VersionsSettings'; + import { RevertDashboardModal } from './RevertDashboardModal'; type VersionsTableProps = { diff --git a/public/app/features/dashboard/components/VersionHistory/useDashboardRestore.tsx b/public/app/features/dashboard/components/VersionHistory/useDashboardRestore.tsx index f2422cc850d..b54c2d017fb 100644 --- a/public/app/features/dashboard/components/VersionHistory/useDashboardRestore.tsx +++ b/public/app/features/dashboard/components/VersionHistory/useDashboardRestore.tsx @@ -1,12 +1,15 @@ import { useEffect } from 'react'; import { useSelector } from 'react-redux'; import { useAsyncFn } from 'react-use'; + import { locationUtil } from '@grafana/data'; -import { StoreState } from 'app/types'; -import { useAppNotification } from 'app/core/copy/appNotification'; -import { historySrv } from './HistorySrv'; -import { DashboardModel } from '../../state'; import { locationService } from '@grafana/runtime'; +import { useAppNotification } from 'app/core/copy/appNotification'; +import { StoreState } from 'app/types'; + +import { DashboardModel } from '../../state'; + +import { historySrv } from './HistorySrv'; const restoreDashboard = async (version: number, dashboard: DashboardModel) => { return await historySrv.restoreDashboard(dashboard, version); diff --git a/public/app/features/dashboard/containers/DashboardPage.test.tsx b/public/app/features/dashboard/containers/DashboardPage.test.tsx index c6b90437dc0..c81a9980224 100644 --- a/public/app/features/dashboard/containers/DashboardPage.test.tsx +++ b/public/app/features/dashboard/containers/DashboardPage.test.tsx @@ -1,21 +1,24 @@ +import { render, screen } from '@testing-library/react'; import React from 'react'; import { Provider } from 'react-redux'; -import { useEffectOnce } from 'react-use'; -import { render, screen } from '@testing-library/react'; -import { Props, UnthemedDashboardPage } from './DashboardPage'; -import { Props as LazyLoaderProps } from '../dashgrid/LazyLoader'; import { Router } from 'react-router-dom'; -import { locationService, setDataSourceSrv } from '@grafana/runtime'; -import { DashboardModel } from '../state'; -import { configureStore } from '../../../store/configureStore'; -import { mockToolkitActionCreator } from 'test/core/redux/mocks'; -import { DashboardInitPhase, DashboardRoutes } from 'app/types'; -import { notifyApp } from 'app/core/actions'; -import { selectors } from '@grafana/e2e-selectors'; -import { getRouteComponentProps } from 'app/core/navigation/__mocks__/routeProps'; -import { createTheme } from '@grafana/data'; +import { useEffectOnce } from 'react-use'; import { AutoSizerProps } from 'react-virtualized-auto-sizer'; +import { mockToolkitActionCreator } from 'test/core/redux/mocks'; + +import { createTheme } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; +import { locationService, setDataSourceSrv } from '@grafana/runtime'; +import { notifyApp } from 'app/core/actions'; +import { getRouteComponentProps } from 'app/core/navigation/__mocks__/routeProps'; +import { DashboardInitPhase, DashboardRoutes } from 'app/types'; + +import { configureStore } from '../../../store/configureStore'; +import { Props as LazyLoaderProps } from '../dashgrid/LazyLoader'; import { setDashboardSrv } from '../services/DashboardSrv'; +import { DashboardModel } from '../state'; + +import { Props, UnthemedDashboardPage } from './DashboardPage'; jest.mock('app/features/dashboard/dashgrid/LazyLoader', () => { const LazyLoader = ({ children, onLoad }: Pick) => { diff --git a/public/app/features/dashboard/containers/DashboardPage.tsx b/public/app/features/dashboard/containers/DashboardPage.tsx index c73c0c6fb16..32904dd6042 100644 --- a/public/app/features/dashboard/containers/DashboardPage.tsx +++ b/public/app/features/dashboard/containers/DashboardPage.tsx @@ -1,35 +1,37 @@ -import React, { PureComponent } from 'react'; import { css } from '@emotion/css'; +import classnames from 'classnames'; +import React, { PureComponent } from 'react'; import { connect, ConnectedProps } from 'react-redux'; -import { locationService } from '@grafana/runtime'; + +import { GrafanaTheme2, TimeRange } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; +import { locationService } from '@grafana/runtime'; import { CustomScrollbar, stylesFactory, Themeable2, withTheme2 } from '@grafana/ui'; -import { createErrorNotification } from 'app/core/copy/appNotification'; -import { Branding } from 'app/core/components/Branding/Branding'; -import { DashboardGrid } from '../dashgrid/DashboardGrid'; -import { DashNav } from '../components/DashNav'; -import { DashboardSettings } from '../components/DashboardSettings'; -import { PanelEditor } from '../components/PanelEditor/PanelEditor'; -import { initDashboard } from '../state/initDashboard'; import { notifyApp } from 'app/core/actions'; -import { KioskMode, StoreState } from 'app/types'; +import { Branding } from 'app/core/components/Branding/Branding'; +import { createErrorNotification } from 'app/core/copy/appNotification'; +import { getKioskMode } from 'app/core/navigation/kiosk'; +import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; import { PanelModel } from 'app/features/dashboard/state'; -import { PanelInspector } from '../components/Inspector/PanelInspector'; -import { SubMenu } from '../components/SubMenu/SubMenu'; -import { cleanUpDashboardAndVariables } from '../state/actions'; +import { dashboardWatcher } from 'app/features/live/dashboard/dashboardWatcher'; +import { KioskMode, StoreState } from 'app/types'; +import { PanelEditEnteredEvent, PanelEditExitedEvent } from 'app/types/events'; + import { cancelVariables, templateVarsChangedInUrl } from '../../variables/state/actions'; import { findTemplateVarChanges } from '../../variables/utils'; -import { dashboardWatcher } from 'app/features/live/dashboard/dashboardWatcher'; -import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; -import { getTimeSrv } from '../services/TimeSrv'; -import { getKioskMode } from 'app/core/navigation/kiosk'; -import { GrafanaTheme2, TimeRange } from '@grafana/data'; -import { DashboardLoading } from '../components/DashboardLoading/DashboardLoading'; +import { DashNav } from '../components/DashNav'; import { DashboardFailed } from '../components/DashboardLoading/DashboardFailed'; +import { DashboardLoading } from '../components/DashboardLoading/DashboardLoading'; import { DashboardPrompt } from '../components/DashboardPrompt/DashboardPrompt'; -import classnames from 'classnames'; -import { PanelEditEnteredEvent, PanelEditExitedEvent } from 'app/types/events'; +import { DashboardSettings } from '../components/DashboardSettings'; +import { PanelInspector } from '../components/Inspector/PanelInspector'; +import { PanelEditor } from '../components/PanelEditor/PanelEditor'; +import { SubMenu } from '../components/SubMenu/SubMenu'; +import { DashboardGrid } from '../dashgrid/DashboardGrid'; import { liveTimer } from '../dashgrid/liveTimer'; +import { getTimeSrv } from '../services/TimeSrv'; +import { cleanUpDashboardAndVariables } from '../state/actions'; +import { initDashboard } from '../state/initDashboard'; export interface DashboardPageRouteParams { uid?: string; diff --git a/public/app/features/dashboard/containers/SoloPanelPage.test.tsx b/public/app/features/dashboard/containers/SoloPanelPage.test.tsx index 9ae03c233cb..c292c978f37 100644 --- a/public/app/features/dashboard/containers/SoloPanelPage.test.tsx +++ b/public/app/features/dashboard/containers/SoloPanelPage.test.tsx @@ -1,10 +1,13 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; -import { Props, SoloPanelPage } from './SoloPanelPage'; +import React from 'react'; + +import { DashboardRoutes } from 'app/types'; + +import { getRouteComponentProps } from '../../../core/navigation/__mocks__/routeProps'; import { Props as DashboardPanelProps } from '../dashgrid/DashboardPanel'; import { DashboardModel } from '../state'; -import { DashboardRoutes } from 'app/types'; -import { getRouteComponentProps } from '../../../core/navigation/__mocks__/routeProps'; + +import { Props, SoloPanelPage } from './SoloPanelPage'; jest.mock('app/features/dashboard/components/DashboardSettings/GeneralSettings', () => ({})); jest.mock('app/features/dashboard/dashgrid/DashboardPanel', () => { diff --git a/public/app/features/dashboard/containers/SoloPanelPage.tsx b/public/app/features/dashboard/containers/SoloPanelPage.tsx index b03acf813bd..2d7360f2cdb 100644 --- a/public/app/features/dashboard/containers/SoloPanelPage.tsx +++ b/public/app/features/dashboard/containers/SoloPanelPage.tsx @@ -1,11 +1,13 @@ import React, { Component } from 'react'; import { connect, ConnectedProps } from 'react-redux'; import AutoSizer from 'react-virtualized-auto-sizer'; + +import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; +import { DashboardModel, PanelModel } from 'app/features/dashboard/state'; +import { StoreState } from 'app/types'; + import { DashboardPanel } from '../dashgrid/DashboardPanel'; import { initDashboard } from '../state/initDashboard'; -import { StoreState } from 'app/types'; -import { DashboardModel, PanelModel } from 'app/features/dashboard/state'; -import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; export interface DashboardPageRouteParams { uid?: string; diff --git a/public/app/features/dashboard/dashgrid/DashboardGrid.test.tsx b/public/app/features/dashboard/dashgrid/DashboardGrid.test.tsx index e12caba291c..95963ad97d5 100644 --- a/public/app/features/dashboard/dashgrid/DashboardGrid.test.tsx +++ b/public/app/features/dashboard/dashgrid/DashboardGrid.test.tsx @@ -1,8 +1,10 @@ -import React from 'react'; import { shallow, ShallowWrapper } from 'enzyme'; -import { DashboardGridUnconnected as DashboardGrid, Props } from './DashboardGrid'; +import React from 'react'; + import { DashboardModel } from '../state'; +import { DashboardGridUnconnected as DashboardGrid, Props } from './DashboardGrid'; + jest.mock('app/features/dashboard/dashgrid/LazyLoader', () => { const LazyLoader: React.FC = ({ children }) => { return <>{children}; diff --git a/public/app/features/dashboard/dashgrid/DashboardGrid.tsx b/public/app/features/dashboard/dashgrid/DashboardGrid.tsx index 29d6578dc9a..e5d8e613f20 100644 --- a/public/app/features/dashboard/dashgrid/DashboardGrid.tsx +++ b/public/app/features/dashboard/dashgrid/DashboardGrid.tsx @@ -1,23 +1,21 @@ -// Libraries +import classNames from 'classnames'; import React, { PureComponent, CSSProperties } from 'react'; import ReactGridLayout, { ItemCallback } from 'react-grid-layout'; -import classNames from 'classnames'; +import { connect, ConnectedProps } from 'react-redux'; import AutoSizer from 'react-virtualized-auto-sizer'; +import { Subscription } from 'rxjs'; + +import { config } from '@grafana/runtime'; +import { GRID_CELL_HEIGHT, GRID_CELL_VMARGIN, GRID_COLUMN_COUNT } from 'app/core/constants'; +import { cleanAndRemoveMany } from 'app/features/panel/state/actions'; +import { DashboardPanelsChangedEvent } from 'app/types/events'; -// Components import { AddPanelWidget } from '../components/AddPanelWidget'; import { DashboardRow } from '../components/DashboardRow'; - -// Types -import { GRID_CELL_HEIGHT, GRID_CELL_VMARGIN, GRID_COLUMN_COUNT } from 'app/core/constants'; -import { DashboardPanel } from './DashboardPanel'; import { DashboardModel, PanelModel } from '../state'; -import { Subscription } from 'rxjs'; -import { connect, ConnectedProps } from 'react-redux'; -import { DashboardPanelsChangedEvent } from 'app/types/events'; -import { cleanAndRemoveMany } from 'app/features/panel/state/actions'; import { GridPos } from '../state/PanelModel'; -import { config } from '@grafana/runtime'; + +import { DashboardPanel } from './DashboardPanel'; export interface OwnProps { dashboard: DashboardModel; diff --git a/public/app/features/dashboard/dashgrid/DashboardPanel.tsx b/public/app/features/dashboard/dashgrid/DashboardPanel.tsx index 3783545ae69..773e6de1709 100644 --- a/public/app/features/dashboard/dashgrid/DashboardPanel.tsx +++ b/public/app/features/dashboard/dashgrid/DashboardPanel.tsx @@ -1,12 +1,15 @@ import React, { PureComponent } from 'react'; import { connect, ConnectedProps } from 'react-redux'; + +import { StoreState } from 'app/types'; + +import { initPanelState } from '../../panel/state/actions'; +import { setPanelInstanceState } from '../../panel/state/reducers'; +import { DashboardModel, PanelModel } from '../state'; + +import { LazyLoader } from './LazyLoader'; import { PanelChrome } from './PanelChrome'; import { PanelChromeAngular } from './PanelChromeAngular'; -import { DashboardModel, PanelModel } from '../state'; -import { StoreState } from 'app/types'; -import { setPanelInstanceState } from '../../panel/state/reducers'; -import { initPanelState } from '../../panel/state/actions'; -import { LazyLoader } from './LazyLoader'; export interface OwnProps { panel: PanelModel; diff --git a/public/app/features/dashboard/dashgrid/LazyLoader.tsx b/public/app/features/dashboard/dashgrid/LazyLoader.tsx index 30f9034a125..da9339e5459 100644 --- a/public/app/features/dashboard/dashgrid/LazyLoader.tsx +++ b/public/app/features/dashboard/dashgrid/LazyLoader.tsx @@ -1,7 +1,8 @@ import React, { useRef, useState } from 'react'; -import { useUniqueId } from 'app/plugins/datasource/influxdb/components/useUniqueId'; import { useEffectOnce } from 'react-use'; +import { useUniqueId } from 'app/plugins/datasource/influxdb/components/useUniqueId'; + export interface Props { children: React.ReactNode | (({ isInView }: { isInView: boolean }) => React.ReactNode); width?: number; diff --git a/public/app/features/dashboard/dashgrid/PanelChrome.test.tsx b/public/app/features/dashboard/dashgrid/PanelChrome.test.tsx index 148c3628c8a..a883596bac4 100644 --- a/public/app/features/dashboard/dashgrid/PanelChrome.test.tsx +++ b/public/app/features/dashboard/dashgrid/PanelChrome.test.tsx @@ -1,14 +1,16 @@ +import { act, render, screen } from '@testing-library/react'; import React, { FC } from 'react'; -import { ReplaySubject } from 'rxjs'; import { Provider } from 'react-redux'; import configureMockStore from 'redux-mock-store'; -import { act, render, screen } from '@testing-library/react'; +import { ReplaySubject } from 'rxjs'; + import { EventBusSrv, getDefaultTimeRange, LoadingState, PanelData, PanelPlugin, PanelProps } from '@grafana/data'; -import { PanelChrome, Props } from './PanelChrome'; -import { DashboardModel, PanelModel } from '../state'; import { PanelQueryRunner } from '../../query/state/PanelQueryRunner'; import { setTimeSrv, TimeSrv } from '../services/TimeSrv'; +import { DashboardModel, PanelModel } from '../state'; + +import { PanelChrome, Props } from './PanelChrome'; jest.mock('app/core/profiler', () => ({ profiler: { diff --git a/public/app/features/dashboard/dashgrid/PanelChrome.tsx b/public/app/features/dashboard/dashgrid/PanelChrome.tsx index 890c6c86075..7ace1ab35fa 100644 --- a/public/app/features/dashboard/dashgrid/PanelChrome.tsx +++ b/public/app/features/dashboard/dashgrid/PanelChrome.tsx @@ -1,7 +1,7 @@ -import React, { PureComponent } from 'react'; import classNames from 'classnames'; +import React, { PureComponent } from 'react'; import { Subscription } from 'rxjs'; -import { locationService, RefreshEvent } from '@grafana/runtime'; + import { AbsoluteTimeRange, AnnotationChangeEvent, @@ -19,26 +19,28 @@ import { toDataFrameDTO, toUtc, } from '@grafana/data'; -import { ErrorBoundary, PanelContext, PanelContextProvider, SeriesVisibilityChangeMode } from '@grafana/ui'; -import { VizLegendOptions } from '@grafana/schema'; import { selectors } from '@grafana/e2e-selectors'; - -import { PanelHeader } from './PanelHeader/PanelHeader'; -import { getTimeSrv, TimeSrv } from '../services/TimeSrv'; -import { applyPanelTimeOverrides } from 'app/features/dashboard/utils/panel'; -import { profiler } from 'app/core/profiler'; +import { locationService, RefreshEvent } from '@grafana/runtime'; +import { VizLegendOptions } from '@grafana/schema'; +import { ErrorBoundary, PanelContext, PanelContextProvider, SeriesVisibilityChangeMode } from '@grafana/ui'; import config from 'app/core/config'; -import { DashboardModel, PanelModel } from '../state'; import { PANEL_BORDER } from 'app/core/constants'; -import { loadSnapshotData } from '../utils/loadSnapshotData'; -import { RenderEvent } from 'app/types/events'; +import { profiler } from 'app/core/profiler'; +import { applyPanelTimeOverrides } from 'app/features/dashboard/utils/panel'; import { changeSeriesColorConfigFactory } from 'app/plugins/panel/timeseries/overrides/colorSeriesConfigFactory'; -import { seriesVisibilityConfigFactory } from './SeriesVisibilityConfigFactory'; +import { RenderEvent } from 'app/types/events'; + +import { contextSrv } from '../../../core/services/context_srv'; +import { isSoloRoute } from '../../../routes/utils'; import { deleteAnnotation, saveAnnotation, updateAnnotation } from '../../annotations/api'; import { getDashboardQueryRunner } from '../../query/state/DashboardQueryRunner/DashboardQueryRunner'; +import { getTimeSrv, TimeSrv } from '../services/TimeSrv'; +import { DashboardModel, PanelModel } from '../state'; +import { loadSnapshotData } from '../utils/loadSnapshotData'; + +import { PanelHeader } from './PanelHeader/PanelHeader'; +import { seriesVisibilityConfigFactory } from './SeriesVisibilityConfigFactory'; import { liveTimer } from './liveTimer'; -import { isSoloRoute } from '../../../routes/utils'; -import { contextSrv } from '../../../core/services/context_srv'; const DEFAULT_PLUGIN_ERROR = 'Error in plugin'; diff --git a/public/app/features/dashboard/dashgrid/PanelChromeAngular.tsx b/public/app/features/dashboard/dashgrid/PanelChromeAngular.tsx index 3d82607222b..7f967d603b1 100644 --- a/public/app/features/dashboard/dashgrid/PanelChromeAngular.tsx +++ b/public/app/features/dashboard/dashgrid/PanelChromeAngular.tsx @@ -1,20 +1,22 @@ -import React, { PureComponent } from 'react'; import classNames from 'classnames'; -import { Subscription } from 'rxjs'; +import React, { PureComponent } from 'react'; import { connect, MapDispatchToProps, MapStateToProps } from 'react-redux'; -import { AngularComponent, getAngularLoader, locationService } from '@grafana/runtime'; +import { Subscription } from 'rxjs'; + import { getDefaultTimeRange, LoadingState, PanelData, PanelPlugin } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; +import { AngularComponent, getAngularLoader, locationService } from '@grafana/runtime'; +import config from 'app/core/config'; +import { PANEL_BORDER } from 'app/core/constants'; +import { setPanelAngularComponent } from 'app/features/panel/state/reducers'; +import { getPanelStateForModel } from 'app/features/panel/state/selectors'; +import { StoreState } from 'app/types'; + +import { isSoloRoute } from '../../../routes/utils'; +import { getTimeSrv, TimeSrv } from '../services/TimeSrv'; +import { DashboardModel, PanelModel } from '../state'; import { PanelHeader } from './PanelHeader/PanelHeader'; -import { getTimeSrv, TimeSrv } from '../services/TimeSrv'; -import { setPanelAngularComponent } from 'app/features/panel/state/reducers'; -import config from 'app/core/config'; -import { DashboardModel, PanelModel } from '../state'; -import { StoreState } from 'app/types'; -import { PANEL_BORDER } from 'app/core/constants'; -import { isSoloRoute } from '../../../routes/utils'; -import { getPanelStateForModel } from 'app/features/panel/state/selectors'; interface OwnProps { panel: PanelModel; diff --git a/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeader.tsx b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeader.tsx index a5f020a89a6..36c377f0d37 100644 --- a/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeader.tsx +++ b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeader.tsx @@ -1,17 +1,18 @@ -import React, { FC } from 'react'; import { css, cx } from '@emotion/css'; -import { DataLink, GrafanaTheme2, PanelData } from '@grafana/data'; -import { Icon, useStyles2 } from '@grafana/ui'; -import { selectors } from '@grafana/e2e-selectors'; +import React, { FC } from 'react'; -import PanelHeaderCorner from './PanelHeaderCorner'; +import { DataLink, GrafanaTheme2, PanelData } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; +import { Icon, useStyles2 } from '@grafana/ui'; import { DashboardModel } from 'app/features/dashboard/state/DashboardModel'; import { PanelModel } from 'app/features/dashboard/state/PanelModel'; import { getPanelLinksSupplier } from 'app/features/panel/panellinks/linkSuppliers'; -import { PanelHeaderNotices } from './PanelHeaderNotices'; -import { PanelHeaderMenuTrigger } from './PanelHeaderMenuTrigger'; + +import PanelHeaderCorner from './PanelHeaderCorner'; import { PanelHeaderLoadingIndicator } from './PanelHeaderLoadingIndicator'; +import { PanelHeaderMenuTrigger } from './PanelHeaderMenuTrigger'; import { PanelHeaderMenuWrapper } from './PanelHeaderMenuWrapper'; +import { PanelHeaderNotices } from './PanelHeaderNotices'; export interface Props { panel: PanelModel; diff --git a/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderCorner.test.tsx b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderCorner.test.tsx index 9d2095e2572..20a88cff82d 100644 --- a/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderCorner.test.tsx +++ b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderCorner.test.tsx @@ -1,8 +1,10 @@ -import React from 'react'; import { shallow } from 'enzyme'; -import { PanelHeaderCorner } from './PanelHeaderCorner'; +import React from 'react'; + import { PanelModel } from '../../state'; +import { PanelHeaderCorner } from './PanelHeaderCorner'; + describe('Render', () => { it('should render component', () => { const panel = new PanelModel({}); diff --git a/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderCorner.tsx b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderCorner.tsx index 0448a550a08..09b5b83cfd1 100644 --- a/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderCorner.tsx +++ b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderCorner.tsx @@ -1,13 +1,12 @@ import React, { Component } from 'react'; import { renderMarkdown, LinkModelSupplier, ScopedVars } from '@grafana/data'; -import { Tooltip, PopoverContent } from '@grafana/ui'; -import { locationService, getTemplateSrv } from '@grafana/runtime'; - -import { PanelModel } from 'app/features/dashboard/state/PanelModel'; -import { getTimeSrv, TimeSrv } from 'app/features/dashboard/services/TimeSrv'; -import { InspectTab } from 'app/features/inspector/types'; import { selectors } from '@grafana/e2e-selectors'; +import { locationService, getTemplateSrv } from '@grafana/runtime'; +import { Tooltip, PopoverContent } from '@grafana/ui'; +import { getTimeSrv, TimeSrv } from 'app/features/dashboard/services/TimeSrv'; +import { PanelModel } from 'app/features/dashboard/state/PanelModel'; +import { InspectTab } from 'app/features/inspector/types'; enum InfoMode { Error = 'Error', diff --git a/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderLoadingIndicator.tsx b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderLoadingIndicator.tsx index fb1d42a596a..14151ba1417 100644 --- a/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderLoadingIndicator.tsx +++ b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderLoadingIndicator.tsx @@ -1,5 +1,6 @@ -import React, { FC } from 'react'; import { css } from '@emotion/css'; +import React, { FC } from 'react'; + import { GrafanaTheme, LoadingState } from '@grafana/data'; import { Icon, Tooltip, useStyles } from '@grafana/ui'; diff --git a/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenu.tsx b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenu.tsx index c180359922a..af37c1b6dbc 100644 --- a/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenu.tsx +++ b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenu.tsx @@ -1,7 +1,9 @@ import React, { PureComponent } from 'react'; -import { PanelHeaderMenuItem } from './PanelHeaderMenuItem'; + import { PanelMenuItem } from '@grafana/data'; +import { PanelHeaderMenuItem } from './PanelHeaderMenuItem'; + export interface Props { items: PanelMenuItem[]; } diff --git a/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenuItem.tsx b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenuItem.tsx index ab1a5395583..2e25ccab6e9 100644 --- a/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenuItem.tsx +++ b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenuItem.tsx @@ -1,8 +1,9 @@ -import React, { FC, useState } from 'react'; import { css } from '@emotion/css'; +import React, { FC, useState } from 'react'; + import { PanelMenuItem } from '@grafana/data'; -import { Icon, IconName, useTheme } from '@grafana/ui'; import { selectors } from '@grafana/e2e-selectors'; +import { Icon, IconName, useTheme } from '@grafana/ui'; interface Props { children?: any; diff --git a/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenuProvider.tsx b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenuProvider.tsx index b3b2afe1ab2..54088922bf1 100644 --- a/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenuProvider.tsx +++ b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenuProvider.tsx @@ -1,12 +1,13 @@ import { FC, ReactElement, useEffect, useState } from 'react'; import { useSelector } from 'react-redux'; -import { PanelMenuItem } from '@grafana/data'; -import { DashboardModel, PanelModel } from '../../state'; -import { StoreState } from '../../../../types'; -import { getPanelMenu } from '../../utils/getPanelMenu'; +import { PanelMenuItem } from '@grafana/data'; import { getPanelStateForModel } from 'app/features/panel/state/selectors'; +import { StoreState } from '../../../../types'; +import { DashboardModel, PanelModel } from '../../state'; +import { getPanelMenu } from '../../utils/getPanelMenu'; + interface PanelHeaderMenuProviderApi { items: PanelMenuItem[]; } diff --git a/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenuTrigger.tsx b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenuTrigger.tsx index 509dd0e0c1e..174c07a2d49 100644 --- a/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenuTrigger.tsx +++ b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenuTrigger.tsx @@ -1,4 +1,5 @@ import React, { FC, HTMLAttributes, MouseEvent, ReactElement, useCallback, useState } from 'react'; + import { CartesianCoords2D } from '@grafana/data'; interface PanelHeaderMenuTriggerApi { diff --git a/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenuWrapper.tsx b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenuWrapper.tsx index 596dc96fa65..40d69a5efe7 100644 --- a/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenuWrapper.tsx +++ b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderMenuWrapper.tsx @@ -1,9 +1,12 @@ import React, { FC } from 'react'; + import { ClickOutsideWrapper } from '@grafana/ui'; -import { PanelHeaderMenuProvider } from './PanelHeaderMenuProvider'; -import { PanelHeaderMenu } from './PanelHeaderMenu'; + import { DashboardModel, PanelModel } from '../../state'; +import { PanelHeaderMenu } from './PanelHeaderMenu'; +import { PanelHeaderMenuProvider } from './PanelHeaderMenuProvider'; + interface Props { panel: PanelModel; dashboard: DashboardModel; diff --git a/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderNotice.tsx b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderNotice.tsx index 16e9670523a..18e13ca1ccc 100644 --- a/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderNotice.tsx +++ b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderNotice.tsx @@ -1,4 +1,5 @@ import React, { FC } from 'react'; + import { QueryResultMetaNotice } from '@grafana/data'; import { Icon, Tooltip } from '@grafana/ui'; diff --git a/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderNotices.tsx b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderNotices.tsx index 4e70fdad7e9..76b98043de7 100644 --- a/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderNotices.tsx +++ b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeaderNotices.tsx @@ -1,8 +1,10 @@ import React, { FC, useCallback } from 'react'; + import { DataFrame, QueryResultMetaNotice } from '@grafana/data'; -import { PanelHeaderNotice } from './PanelHeaderNotice'; import { locationService } from '@grafana/runtime'; +import { PanelHeaderNotice } from './PanelHeaderNotice'; + interface Props { panelId: number; frames: DataFrame[]; diff --git a/public/app/features/dashboard/dashgrid/PanelResizer.tsx b/public/app/features/dashboard/dashgrid/PanelResizer.tsx index 3bd191300ff..f7dd6757dac 100644 --- a/public/app/features/dashboard/dashgrid/PanelResizer.tsx +++ b/public/app/features/dashboard/dashgrid/PanelResizer.tsx @@ -1,5 +1,5 @@ -import React, { PureComponent } from 'react'; import { throttle } from 'lodash'; +import React, { PureComponent } from 'react'; import Draggable, { DraggableEventHandler } from 'react-draggable'; import { PanelModel } from '../state/PanelModel'; diff --git a/public/app/features/dashboard/dashgrid/liveTimer.ts b/public/app/features/dashboard/dashgrid/liveTimer.ts index 0631c3ca4db..65b37811ea3 100644 --- a/public/app/features/dashboard/dashgrid/liveTimer.ts +++ b/public/app/features/dashboard/dashgrid/liveTimer.ts @@ -1,5 +1,7 @@ -import { dateMath, dateTime, TimeRange } from '@grafana/data'; import { BehaviorSubject } from 'rxjs'; + +import { dateMath, dateTime, TimeRange } from '@grafana/data'; + import { PanelChrome } from './PanelChrome'; // target is 20hz (50ms), but we poll at 100ms to smooth out jitter diff --git a/public/app/features/dashboard/services/DashboardLoaderSrv.ts b/public/app/features/dashboard/services/DashboardLoaderSrv.ts index dc06ab6e1d2..68a4ec18e6f 100644 --- a/public/app/features/dashboard/services/DashboardLoaderSrv.ts +++ b/public/app/features/dashboard/services/DashboardLoaderSrv.ts @@ -1,16 +1,18 @@ -import moment from 'moment'; // eslint-disable-line no-restricted-imports -// eslint-disable-next-line lodash/import-scope -import _, { isFunction } from 'lodash'; import $ from 'jquery'; -import kbn from 'app/core/utils/kbn'; +import _, { isFunction } from 'lodash'; // eslint-disable-line lodash/import-scope +import moment from 'moment'; // eslint-disable-line no-restricted-imports + import { AppEvents, dateMath, UrlQueryValue } from '@grafana/data'; -import impressionSrv from 'app/core/services/impression_srv'; -import { backendSrv } from 'app/core/services/backend_srv'; -import { getDashboardSrv } from './DashboardSrv'; -import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; import { getBackendSrv, locationService } from '@grafana/runtime'; +import { backendSrv } from 'app/core/services/backend_srv'; +import impressionSrv from 'app/core/services/impression_srv'; +import kbn from 'app/core/utils/kbn'; +import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; + import { appEvents } from '../../../core/core'; +import { getDashboardSrv } from './DashboardSrv'; + export class DashboardLoaderSrv { constructor() {} _dashboardLoadFailed(title: string, snapshot?: boolean) { diff --git a/public/app/features/dashboard/services/DashboardSrv.ts b/public/app/features/dashboard/services/DashboardSrv.ts index 7fa5084d850..0a0ae013172 100644 --- a/public/app/features/dashboard/services/DashboardSrv.ts +++ b/public/app/features/dashboard/services/DashboardSrv.ts @@ -1,12 +1,14 @@ +import { lastValueFrom } from 'rxjs'; + +import { BackendSrvRequest } from '@grafana/runtime'; import { appEvents } from 'app/core/app_events'; -import { DashboardModel } from '../state/DashboardModel'; -import { removePanel } from '../utils/panel'; -import { DashboardMeta } from 'app/types'; import { getBackendSrv } from 'app/core/services/backend_srv'; import { saveDashboard } from 'app/features/manage-dashboards/state/actions'; +import { DashboardMeta } from 'app/types'; + import { RemovePanelEvent } from '../../../types/events'; -import { BackendSrvRequest } from '@grafana/runtime'; -import { lastValueFrom } from 'rxjs'; +import { DashboardModel } from '../state/DashboardModel'; +import { removePanel } from '../utils/panel'; export interface SaveDashboardOptions { /** The complete dashboard model. If `dashboard.id` is not set a new dashboard will be created. */ diff --git a/public/app/features/dashboard/services/TimeSrv.test.ts b/public/app/features/dashboard/services/TimeSrv.test.ts index 90220dd63c1..26124b7b299 100644 --- a/public/app/features/dashboard/services/TimeSrv.test.ts +++ b/public/app/features/dashboard/services/TimeSrv.test.ts @@ -1,10 +1,13 @@ -import { TimeSrv } from './TimeSrv'; -import { ContextSrvStub } from 'test/specs/helpers'; -import { dateTime, isDateTime } from '@grafana/data'; import * as H from 'history'; +import { ContextSrvStub } from 'test/specs/helpers'; + +import { dateTime, isDateTime } from '@grafana/data'; import { HistoryWrapper, locationService, setLocationService } from '@grafana/runtime'; + import { beforeEach } from '../../../../test/lib/common'; +import { TimeSrv } from './TimeSrv'; + jest.mock('app/core/core', () => ({ appEvents: { subscribe: () => {}, diff --git a/public/app/features/dashboard/services/TimeSrv.ts b/public/app/features/dashboard/services/TimeSrv.ts index 490f480ce55..7966a83387b 100644 --- a/public/app/features/dashboard/services/TimeSrv.ts +++ b/public/app/features/dashboard/services/TimeSrv.ts @@ -1,4 +1,5 @@ import { cloneDeep, extend, isString } from 'lodash'; + import { dateMath, dateTime, @@ -9,14 +10,15 @@ import { TimeRange, toUtc, } from '@grafana/data'; -import { getShiftedTimeRange, getZoomedTimeRange } from 'app/core/utils/timePicker'; -import { config } from 'app/core/config'; -import { getRefreshFromUrl } from '../utils/getRefreshFromUrl'; import { locationService } from '@grafana/runtime'; -import { AbsoluteTimeEvent, ShiftTimeEvent, ShiftTimeEventDirection, ZoomOutEvent } from '../../../types/events'; -import { contextSrv, ContextSrv } from 'app/core/services/context_srv'; import appEvents from 'app/core/app_events'; +import { config } from 'app/core/config'; +import { contextSrv, ContextSrv } from 'app/core/services/context_srv'; +import { getShiftedTimeRange, getZoomedTimeRange } from 'app/core/utils/timePicker'; + +import { AbsoluteTimeEvent, ShiftTimeEvent, ShiftTimeEventDirection, ZoomOutEvent } from '../../../types/events'; import { TimeModel } from '../state/TimeModel'; +import { getRefreshFromUrl } from '../utils/getRefreshFromUrl'; export class TimeSrv { time: any; diff --git a/public/app/features/dashboard/state/DashboardMigrator.test.ts b/public/app/features/dashboard/state/DashboardMigrator.test.ts index 201ba1ce202..b53a4088208 100644 --- a/public/app/features/dashboard/state/DashboardMigrator.test.ts +++ b/public/app/features/dashboard/state/DashboardMigrator.test.ts @@ -1,15 +1,17 @@ import { each, map } from 'lodash'; +import { expect } from 'test/lib/common'; + +import { DataLinkBuiltInVars, MappingType } from '@grafana/data'; +import { setDataSourceSrv } from '@grafana/runtime'; +import { config } from 'app/core/config'; +import { GRID_CELL_HEIGHT, GRID_CELL_VMARGIN } from 'app/core/constants'; +import { mockDataSource, MockDataSourceSrv } from 'app/features/alerting/unified/mocks'; +import { getPanelPlugin } from 'app/features/plugins/__mocks__/pluginMocks'; +import { MIXED_DATASOURCE_NAME } from 'app/plugins/datasource/mixed/MixedDataSource'; + +import { VariableHide } from '../../variables/types'; import { DashboardModel } from '../state/DashboardModel'; import { PanelModel } from '../state/PanelModel'; -import { GRID_CELL_HEIGHT, GRID_CELL_VMARGIN } from 'app/core/constants'; -import { expect } from 'test/lib/common'; -import { DataLinkBuiltInVars, MappingType } from '@grafana/data'; -import { VariableHide } from '../../variables/types'; -import { config } from 'app/core/config'; -import { getPanelPlugin } from 'app/features/plugins/__mocks__/pluginMocks'; -import { setDataSourceSrv } from '@grafana/runtime'; -import { mockDataSource, MockDataSourceSrv } from 'app/features/alerting/unified/mocks'; -import { MIXED_DATASOURCE_NAME } from 'app/plugins/datasource/mixed/MixedDataSource'; jest.mock('app/core/services/context_srv', () => ({})); diff --git a/public/app/features/dashboard/state/DashboardMigrator.ts b/public/app/features/dashboard/state/DashboardMigrator.ts index 7ee735ff5d4..f9e5be516c0 100644 --- a/public/app/features/dashboard/state/DashboardMigrator.ts +++ b/public/app/features/dashboard/state/DashboardMigrator.ts @@ -1,11 +1,5 @@ -// Libraries import { each, find, findIndex, flattenDeep, isArray, isBoolean, isNumber, isString, map, max, some } from 'lodash'; -// Utils -import getFactors from 'app/core/utils/factors'; -import kbn from 'app/core/utils/kbn'; -// Types -import { PanelModel } from './PanelModel'; -import { DashboardModel } from './DashboardModel'; + import { AnnotationQuery, DataLink, @@ -29,7 +23,10 @@ import { ValueMap, ValueMapping, } from '@grafana/data'; -// Constants +import { getDataSourceSrv, setDataSourceSrv } from '@grafana/runtime'; +import { AxisPlacement, GraphFieldConfig } from '@grafana/ui'; +import { getAllOptionEditors, getAllStandardFieldConfigs } from 'app/core/components/editors/registry'; +import { config } from 'app/core/config'; import { DEFAULT_PANEL_SPAN, DEFAULT_ROW_HEIGHT, @@ -38,24 +35,26 @@ import { GRID_COLUMN_COUNT, MIN_PANEL_HEIGHT, } from 'app/core/constants'; +import getFactors from 'app/core/utils/factors'; +import kbn from 'app/core/utils/kbn'; +import { DatasourceSrv } from 'app/features/plugins/datasource_srv'; import { isConstant, isMulti } from 'app/features/variables/guard'; import { alignCurrentWithMulti } from 'app/features/variables/shared/multiOptions'; -import { VariableHide } from '../../variables/types'; -import { config } from 'app/core/config'; -import { plugin as statPanelPlugin } from 'app/plugins/panel/stat/module'; -import { plugin as gaugePanelPlugin } from 'app/plugins/panel/gauge/module'; -import { AxisPlacement, GraphFieldConfig } from '@grafana/ui'; -import { getDataSourceSrv, setDataSourceSrv } from '@grafana/runtime'; -import { labelsToFieldsTransformer } from '../../../../../packages/grafana-data/src/transformations/transformers/labelsToFields'; -import { mergeTransformer } from '../../../../../packages/grafana-data/src/transformations/transformers/merge'; import { migrateCloudWatchQuery, migrateMultipleStatsAnnotationQuery, migrateMultipleStatsMetricsQuery, } from 'app/plugins/datasource/cloudwatch/migrations'; import { CloudWatchAnnotationQuery, CloudWatchMetricsQuery } from 'app/plugins/datasource/cloudwatch/types'; -import { getAllOptionEditors, getAllStandardFieldConfigs } from 'app/core/components/editors/registry'; -import { DatasourceSrv } from 'app/features/plugins/datasource_srv'; +import { plugin as gaugePanelPlugin } from 'app/plugins/panel/gauge/module'; +import { plugin as statPanelPlugin } from 'app/plugins/panel/stat/module'; + +import { labelsToFieldsTransformer } from '../../../../../packages/grafana-data/src/transformations/transformers/labelsToFields'; +import { mergeTransformer } from '../../../../../packages/grafana-data/src/transformations/transformers/merge'; +import { VariableHide } from '../../variables/types'; + +import { DashboardModel } from './DashboardModel'; +import { PanelModel } from './PanelModel'; standardEditorsRegistry.setInit(getAllOptionEditors); standardFieldConfigEditorRegistry.setInit(getAllStandardFieldConfigs); diff --git a/public/app/features/dashboard/state/DashboardModel.refresh.test.ts b/public/app/features/dashboard/state/DashboardModel.refresh.test.ts index 338540becdc..8eed7928506 100644 --- a/public/app/features/dashboard/state/DashboardModel.refresh.test.ts +++ b/public/app/features/dashboard/state/DashboardModel.refresh.test.ts @@ -1,9 +1,10 @@ -import { DashboardModel } from './DashboardModel'; +import { afterEach, beforeEach } from '../../../../test/lib/common'; import { appEvents } from '../../../core/core'; import { VariablesChanged } from '../../variables/types'; -import { PanelModel } from './PanelModel'; import { getTimeSrv, setTimeSrv } from '../services/TimeSrv'; -import { afterEach, beforeEach } from '../../../../test/lib/common'; + +import { DashboardModel } from './DashboardModel'; +import { PanelModel } from './PanelModel'; function getTestContext({ usePanelInEdit, diff --git a/public/app/features/dashboard/state/DashboardModel.repeat.test.ts b/public/app/features/dashboard/state/DashboardModel.repeat.test.ts index e393b98d8eb..b333eb878a4 100644 --- a/public/app/features/dashboard/state/DashboardModel.repeat.test.ts +++ b/public/app/features/dashboard/state/DashboardModel.repeat.test.ts @@ -1,10 +1,13 @@ import { compact, flattenDeep, map, uniq } from 'lodash'; -import { DashboardModel } from '../state/DashboardModel'; import { expect } from 'test/lib/common'; -import { getDashboardModel } from '../../../../test/helpers/getDashboardModel'; -import { PanelModel } from './PanelModel'; + import { DashboardPanelsChangedEvent } from 'app/types/events'; +import { getDashboardModel } from '../../../../test/helpers/getDashboardModel'; +import { DashboardModel } from '../state/DashboardModel'; + +import { PanelModel } from './PanelModel'; + jest.mock('app/core/services/context_srv', () => ({})); describe('given dashboard with panel repeat', () => { diff --git a/public/app/features/dashboard/state/DashboardModel.test.ts b/public/app/features/dashboard/state/DashboardModel.test.ts index 764cccd8fcd..f5d494a780c 100644 --- a/public/app/features/dashboard/state/DashboardModel.test.ts +++ b/public/app/features/dashboard/state/DashboardModel.test.ts @@ -1,13 +1,14 @@ import { keys as _keys } from 'lodash'; -import { DashboardModel } from '../state/DashboardModel'; -import { PanelModel } from '../state/PanelModel'; + import { getDashboardModel } from '../../../../test/helpers/getDashboardModel'; +import { expect } from '../../../../test/lib/common'; import { variableAdapters } from '../../variables/adapters'; import { createAdHocVariableAdapter } from '../../variables/adhoc/adapter'; -import { createQueryVariableAdapter } from '../../variables/query/adapter'; import { createCustomVariableAdapter } from '../../variables/custom/adapter'; -import { expect } from '../../../../test/lib/common'; +import { createQueryVariableAdapter } from '../../variables/query/adapter'; import { setTimeSrv, TimeSrv } from '../services/TimeSrv'; +import { DashboardModel } from '../state/DashboardModel'; +import { PanelModel } from '../state/PanelModel'; jest.mock('app/core/services/context_srv', () => ({})); diff --git a/public/app/features/dashboard/state/DashboardModel.ts b/public/app/features/dashboard/state/DashboardModel.ts index 36e95c679f0..1c99bb5a33a 100644 --- a/public/app/features/dashboard/state/DashboardModel.ts +++ b/public/app/features/dashboard/state/DashboardModel.ts @@ -1,4 +1,3 @@ -// Libaries import { cloneDeep, defaults as _defaults, @@ -13,15 +12,8 @@ import { pull, some, } from 'lodash'; -// Constants -import { DEFAULT_ANNOTATION_COLOR } from '@grafana/ui'; -import { GRID_CELL_HEIGHT, GRID_CELL_VMARGIN, GRID_COLUMN_COUNT, REPEAT_DIR_VERTICAL } from 'app/core/constants'; -// Utils & Services -import { contextSrv } from 'app/core/services/context_srv'; -// Types -import { GridPos, PanelModel } from './PanelModel'; -import { TimeModel } from './TimeModel'; -import { DashboardMigrator } from './DashboardMigrator'; +import { Subscription } from 'rxjs'; + import { AnnotationQuery, AppEvent, @@ -37,26 +29,33 @@ import { TimeZone, UrlQueryValue, } from '@grafana/data'; -import { CoreEvents, DashboardMeta, KioskMode } from 'app/types'; -import { GetVariables, getVariablesByKey } from 'app/features/variables/state/selectors'; +import { RefreshEvent, TimeRangeUpdatedEvent } from '@grafana/runtime'; +import { DEFAULT_ANNOTATION_COLOR } from '@grafana/ui'; +import { GRID_CELL_HEIGHT, GRID_CELL_VMARGIN, GRID_COLUMN_COUNT, REPEAT_DIR_VERTICAL } from 'app/core/constants'; +import { contextSrv } from 'app/core/services/context_srv'; +import { sortedDeepCloneWithoutNulls } from 'app/core/utils/object'; import { variableAdapters } from 'app/features/variables/adapters'; import { onTimeRangeUpdated } from 'app/features/variables/state/actions'; -import { dispatch } from '../../../store/store'; -import { isAllVariable } from '../../variables/utils'; +import { GetVariables, getVariablesByKey } from 'app/features/variables/state/selectors'; +import { CoreEvents, DashboardMeta, KioskMode } from 'app/types'; import { DashboardPanelsChangedEvent, RenderEvent } from 'app/types/events'; -import { getTimeSrv } from '../services/TimeSrv'; -import { mergePanels, PanelMergeInfo } from '../utils/panelMerge'; -import { deleteScopeVars, isOnTheSameGridRow } from './utils'; -import { RefreshEvent, TimeRangeUpdatedEvent } from '@grafana/runtime'; -import { sortedDeepCloneWithoutNulls } from 'app/core/utils/object'; -import { Subscription } from 'rxjs'; + import { appEvents } from '../../../core/core'; +import { dispatch } from '../../../store/store'; import { VariablesChanged, VariablesChangedEvent, VariablesChangedInUrl, VariablesTimeRangeProcessDone, } from '../../variables/types'; +import { isAllVariable } from '../../variables/utils'; +import { getTimeSrv } from '../services/TimeSrv'; +import { mergePanels, PanelMergeInfo } from '../utils/panelMerge'; + +import { DashboardMigrator } from './DashboardMigrator'; +import { GridPos, PanelModel } from './PanelModel'; +import { TimeModel } from './TimeModel'; +import { deleteScopeVars, isOnTheSameGridRow } from './utils'; export interface CloneOptions { saveVariables?: boolean; diff --git a/public/app/features/dashboard/state/PanelModel.test.ts b/public/app/features/dashboard/state/PanelModel.test.ts index 1af302c5538..df5459411aa 100644 --- a/public/app/features/dashboard/state/PanelModel.test.ts +++ b/public/app/features/dashboard/state/PanelModel.test.ts @@ -1,5 +1,5 @@ -import { PanelModel } from './PanelModel'; -import { getPanelPlugin } from '../../plugins/__mocks__/pluginMocks'; +import { ComponentClass } from 'react'; + import { DataLinkBuiltInVars, FieldConfigProperty, @@ -10,17 +10,20 @@ import { dateTime, TimeRange, } from '@grafana/data'; -import { ComponentClass } from 'react'; -import { PanelQueryRunner } from '../../query/state/PanelQueryRunner'; -import { setTimeSrv } from '../services/TimeSrv'; -import { TemplateSrv } from '../../templating/template_srv'; import { setTemplateSrv } from '@grafana/runtime'; +import { queryBuilder } from 'app/features/variables/shared/testing/builders'; + +import { mockStandardFieldConfigOptions } from '../../../../test/helpers/fieldConfig'; +import { getPanelPlugin } from '../../plugins/__mocks__/pluginMocks'; +import { PanelQueryRunner } from '../../query/state/PanelQueryRunner'; +import { TemplateSrv } from '../../templating/template_srv'; import { variableAdapters } from '../../variables/adapters'; import { createQueryVariableAdapter } from '../../variables/query/adapter'; -import { mockStandardFieldConfigOptions } from '../../../../test/helpers/fieldConfig'; -import { queryBuilder } from 'app/features/variables/shared/testing/builders'; +import { setTimeSrv } from '../services/TimeSrv'; import { TimeOverrideResult } from '../utils/panel'; +import { PanelModel } from './PanelModel'; + standardFieldConfigEditorRegistry.setInit(() => mockStandardFieldConfigOptions()); standardEditorsRegistry.setInit(() => mockStandardFieldConfigOptions()); diff --git a/public/app/features/dashboard/state/PanelModel.ts b/public/app/features/dashboard/state/PanelModel.ts index 115c7ed8502..81723a24d62 100644 --- a/public/app/features/dashboard/state/PanelModel.ts +++ b/public/app/features/dashboard/state/PanelModel.ts @@ -1,10 +1,6 @@ -// Libraries import { cloneDeep, defaultsDeep, isArray, isEqual, keys } from 'lodash'; import { v4 as uuidv4 } from 'uuid'; -// Utils -import { getTemplateSrv, RefreshEvent } from '@grafana/runtime'; -import { getNextRefIdChar } from 'app/core/utils/query'; -// Types + import { DataConfigSource, DataFrameDTO, @@ -21,24 +17,29 @@ import { PanelModel as IPanelModel, DataSourceRef, } from '@grafana/data'; +import { getTemplateSrv, RefreshEvent } from '@grafana/runtime'; import config from 'app/core/config'; -import { PanelQueryRunner } from '../../query/state/PanelQueryRunner'; +import { getNextRefIdChar } from 'app/core/utils/query'; +import { QueryGroupOptions } from 'app/types'; import { PanelOptionsChangedEvent, PanelQueriesChangedEvent, PanelTransformationsChangedEvent, RenderEvent, } from 'app/types/events'; -import { getTimeSrv } from '../services/TimeSrv'; + +import { PanelModelLibraryPanel } from '../../library-panels/types'; +import { PanelQueryRunner } from '../../query/state/PanelQueryRunner'; import { getVariablesUrlParams } from '../../variables/getAllVariableValuesForUrl'; +import { getTimeSrv } from '../services/TimeSrv'; +import { TimeOverrideResult } from '../utils/panel'; + import { filterFieldConfigOverrides, getPanelOptionsWithDefaults, isStandardFieldProp, restoreCustomOverrideRules, } from './getPanelOptionsWithDefaults'; -import { QueryGroupOptions } from 'app/types'; -import { PanelModelLibraryPanel } from '../../library-panels/types'; export interface GridPos { x: number; @@ -48,8 +49,6 @@ export interface GridPos { static?: boolean; } -import { TimeOverrideResult } from '../utils/panel'; - const notPersistedProperties: { [str: string]: boolean } = { events: true, isViewing: true, diff --git a/public/app/features/dashboard/state/actions.ts b/public/app/features/dashboard/state/actions.ts index e6c070c2c1b..d31b6e168cc 100644 --- a/public/app/features/dashboard/state/actions.ts +++ b/public/app/features/dashboard/state/actions.ts @@ -1,16 +1,15 @@ -// Services & Utils +import { TimeZone } from '@grafana/data'; import { getBackendSrv } from '@grafana/runtime'; -import { createSuccessNotification } from 'app/core/copy/appNotification'; -// Actions -import { loadPluginDashboards } from '../../plugins/admin/state/actions'; -import { cleanUpDashboard, loadDashboardPermissions } from './reducers'; import { notifyApp } from 'app/core/actions'; +import { createSuccessNotification } from 'app/core/copy/appNotification'; import { updateTimeZoneForSession, updateWeekStartForSession } from 'app/features/profile/state/reducers'; -// Types import { DashboardAcl, DashboardAclUpdateDTO, NewDashboardAclItem, PermissionLevel, ThunkResult } from 'app/types'; + +import { loadPluginDashboards } from '../../plugins/admin/state/actions'; import { cancelVariables } from '../../variables/state/actions'; import { getTimeSrv } from '../services/TimeSrv'; -import { TimeZone } from '@grafana/data'; + +import { cleanUpDashboard, loadDashboardPermissions } from './reducers'; export function getDashboardPermissions(id: number): ThunkResult { return async (dispatch) => { diff --git a/public/app/features/dashboard/state/analyticsProcessor.ts b/public/app/features/dashboard/state/analyticsProcessor.ts index 9834d86f149..258cf71ee45 100644 --- a/public/app/features/dashboard/state/analyticsProcessor.ts +++ b/public/app/features/dashboard/state/analyticsProcessor.ts @@ -1,6 +1,7 @@ -import { DashboardModel } from './DashboardModel'; import { reportMetaAnalytics, MetaAnalyticsEventName, DashboardViewEventPayload } from '@grafana/runtime'; +import { DashboardModel } from './DashboardModel'; + export function emitDashboardViewEvent(dashboard: DashboardModel) { const eventData: DashboardViewEventPayload = { dashboardId: dashboard.id, diff --git a/public/app/features/dashboard/state/getPanelOptionsWithDefaults.test.ts b/public/app/features/dashboard/state/getPanelOptionsWithDefaults.test.ts index 6b61bdcaf60..a56c2669238 100644 --- a/public/app/features/dashboard/state/getPanelOptionsWithDefaults.test.ts +++ b/public/app/features/dashboard/state/getPanelOptionsWithDefaults.test.ts @@ -1,3 +1,5 @@ +import { mockStandardFieldConfigOptions } from 'test/helpers/fieldConfig'; + import { ConfigOverrideRule, FieldColorModeId, @@ -11,7 +13,7 @@ import { ThresholdsMode, } from '@grafana/data'; import { getPanelPlugin } from 'app/features/plugins/__mocks__/pluginMocks'; -import { mockStandardFieldConfigOptions } from 'test/helpers/fieldConfig'; + import { getPanelOptionsWithDefaults, restoreCustomOverrideRules } from './getPanelOptionsWithDefaults'; standardFieldConfigEditorRegistry.setInit(() => mockStandardFieldConfigOptions()); diff --git a/public/app/features/dashboard/state/getPanelOptionsWithDefaults.ts b/public/app/features/dashboard/state/getPanelOptionsWithDefaults.ts index 2eb30b6d951..fadb6071164 100644 --- a/public/app/features/dashboard/state/getPanelOptionsWithDefaults.ts +++ b/public/app/features/dashboard/state/getPanelOptionsWithDefaults.ts @@ -1,3 +1,5 @@ +import { mergeWith, isArray, isObject, unset, isEqual } from 'lodash'; + import { ConfigOverrideRule, DynamicConfigValue, @@ -11,7 +13,6 @@ import { ThresholdsConfig, ThresholdsMode, } from '@grafana/data'; -import { mergeWith, isArray, isObject, unset, isEqual } from 'lodash'; export interface Props { plugin: PanelPlugin; diff --git a/public/app/features/dashboard/state/initDashboard.test.ts b/public/app/features/dashboard/state/initDashboard.test.ts index 0bcb74ef8d2..eae72482c81 100644 --- a/public/app/features/dashboard/state/initDashboard.test.ts +++ b/public/app/features/dashboard/state/initDashboard.test.ts @@ -1,28 +1,30 @@ -import { Subject } from 'rxjs'; import configureMockStore from 'redux-mock-store'; import thunk from 'redux-thunk'; -import { locationService, setEchoSrv } from '@grafana/runtime'; +import { Subject } from 'rxjs'; -import { initDashboard, InitDashboardArgs } from './initDashboard'; -import { DashboardInitPhase, DashboardRoutes } from 'app/types'; +import { locationService, setEchoSrv } from '@grafana/runtime'; import { getBackendSrv } from 'app/core/services/backend_srv'; -import { dashboardInitCompleted, dashboardInitFetching, dashboardInitServices } from './reducers'; -import { Echo } from '../../../core/services/echo/Echo'; +import { keybindingSrv } from 'app/core/services/keybindingSrv'; import { variableAdapters } from 'app/features/variables/adapters'; import { createConstantVariableAdapter } from 'app/features/variables/constant/adapter'; import { constantBuilder } from 'app/features/variables/shared/testing/builders'; -import { initialTransactionState, variablesInitTransaction } from '../../variables/state/transactionReducer'; -import { keybindingSrv } from 'app/core/services/keybindingSrv'; -import { getTimeSrv, setTimeSrv } from '../services/TimeSrv'; -import { DashboardLoaderSrv, setDashboardLoaderSrv } from '../services/DashboardLoaderSrv'; -import { getDashboardSrv, setDashboardSrv } from '../services/DashboardSrv'; +import { DashboardInitPhase, DashboardRoutes } from 'app/types'; + +import { Echo } from '../../../core/services/echo/Echo'; import { getDashboardQueryRunner, setDashboardQueryRunnerFactory, } from '../../query/state/DashboardQueryRunner/DashboardQueryRunner'; import { emptyResult } from '../../query/state/DashboardQueryRunner/utils'; -import { TransactionStatus } from '../../variables/types'; import { getPreloadedState } from '../../variables/state/helpers'; +import { initialTransactionState, variablesInitTransaction } from '../../variables/state/transactionReducer'; +import { TransactionStatus } from '../../variables/types'; +import { DashboardLoaderSrv, setDashboardLoaderSrv } from '../services/DashboardLoaderSrv'; +import { getDashboardSrv, setDashboardSrv } from '../services/DashboardSrv'; +import { getTimeSrv, setTimeSrv } from '../services/TimeSrv'; + +import { initDashboard, InitDashboardArgs } from './initDashboard'; +import { dashboardInitCompleted, dashboardInitFetching, dashboardInitServices } from './reducers'; jest.mock('app/core/services/backend_srv'); jest.mock('app/features/dashboard/services/TimeSrv', () => { diff --git a/public/app/features/dashboard/state/initDashboard.ts b/public/app/features/dashboard/state/initDashboard.ts index 654bf8cdab1..c49b5f95628 100644 --- a/public/app/features/dashboard/state/initDashboard.ts +++ b/public/app/features/dashboard/state/initDashboard.ts @@ -1,25 +1,24 @@ -// Services & Utils +import { locationUtil, setWeekStart } from '@grafana/data'; +import { config, locationService } from '@grafana/runtime'; +import { notifyApp } from 'app/core/actions'; import { createErrorNotification } from 'app/core/copy/appNotification'; import { backendSrv } from 'app/core/services/backend_srv'; -import { DashboardSrv, getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv'; -import { dashboardLoaderSrv } from 'app/features/dashboard/services/DashboardLoaderSrv'; -import { getTimeSrv, TimeSrv } from 'app/features/dashboard/services/TimeSrv'; import { keybindingSrv } from 'app/core/services/keybindingSrv'; -// Actions -import { notifyApp } from 'app/core/actions'; -import { dashboardInitCompleted, dashboardInitFailed, dashboardInitFetching, dashboardInitServices } from './reducers'; -// Types -import { DashboardDTO, DashboardInitPhase, DashboardRoutes, StoreState, ThunkDispatch, ThunkResult } from 'app/types'; -import { DashboardModel } from './DashboardModel'; -import { locationUtil, setWeekStart } from '@grafana/data'; -import { initVariablesTransaction } from '../../variables/state/actions'; -import { emitDashboardViewEvent } from './analyticsProcessor'; -import { dashboardWatcher } from 'app/features/live/dashboard/dashboardWatcher'; -import { config, locationService } from '@grafana/runtime'; -import { createDashboardQueryRunner } from '../../query/state/DashboardQueryRunner/DashboardQueryRunner'; -import { getIfExistsLastKey } from '../../variables/state/selectors'; -import { toStateKey } from 'app/features/variables/utils'; import store from 'app/core/store'; +import { dashboardLoaderSrv } from 'app/features/dashboard/services/DashboardLoaderSrv'; +import { DashboardSrv, getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv'; +import { getTimeSrv, TimeSrv } from 'app/features/dashboard/services/TimeSrv'; +import { dashboardWatcher } from 'app/features/live/dashboard/dashboardWatcher'; +import { toStateKey } from 'app/features/variables/utils'; +import { DashboardDTO, DashboardInitPhase, DashboardRoutes, StoreState, ThunkDispatch, ThunkResult } from 'app/types'; + +import { createDashboardQueryRunner } from '../../query/state/DashboardQueryRunner/DashboardQueryRunner'; +import { initVariablesTransaction } from '../../variables/state/actions'; +import { getIfExistsLastKey } from '../../variables/state/selectors'; + +import { DashboardModel } from './DashboardModel'; +import { emitDashboardViewEvent } from './analyticsProcessor'; +import { dashboardInitCompleted, dashboardInitFailed, dashboardInitFetching, dashboardInitServices } from './reducers'; export interface InitDashboardArgs { urlUid?: string; diff --git a/public/app/features/dashboard/state/reducers.test.ts b/public/app/features/dashboard/state/reducers.test.ts index f98a4fa6dec..ab2fa4a8c9e 100644 --- a/public/app/features/dashboard/state/reducers.test.ts +++ b/public/app/features/dashboard/state/reducers.test.ts @@ -1,3 +1,6 @@ +import { DashboardInitPhase, DashboardState, OrgRole, PermissionLevel } from 'app/types'; + +import { DashboardModel } from './DashboardModel'; import { dashboardInitCompleted, dashboardInitFailed, @@ -6,8 +9,6 @@ import { dashboardReducer, initialState, } from './reducers'; -import { DashboardInitPhase, DashboardState, OrgRole, PermissionLevel } from 'app/types'; -import { DashboardModel } from './DashboardModel'; describe('dashboard reducer', () => { describe('loadDashboardPermissions', () => { diff --git a/public/app/features/dashboard/state/reducers.ts b/public/app/features/dashboard/state/reducers.ts index 59cc5eadad2..4e57923e7c4 100644 --- a/public/app/features/dashboard/state/reducers.ts +++ b/public/app/features/dashboard/state/reducers.ts @@ -1,10 +1,12 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit'; -import { DashboardAclDTO, DashboardInitError, DashboardInitPhase, DashboardState } from 'app/types'; + +import { PanelPlugin } from '@grafana/data'; import { AngularComponent } from '@grafana/runtime'; import { processAclItems } from 'app/core/utils/acl'; +import { DashboardAclDTO, DashboardInitError, DashboardInitPhase, DashboardState } from 'app/types'; + import { DashboardModel } from './DashboardModel'; import { PanelModel } from './PanelModel'; -import { PanelPlugin } from '@grafana/data'; export const initialState: DashboardState = { initPhase: DashboardInitPhase.NotStarted, diff --git a/public/app/features/dashboard/state/selectors.ts b/public/app/features/dashboard/state/selectors.ts index b0bf7529bbe..59d486d3a73 100644 --- a/public/app/features/dashboard/state/selectors.ts +++ b/public/app/features/dashboard/state/selectors.ts @@ -1,5 +1,6 @@ -import { StoreState } from 'app/types'; import { PanelPlugin } from '@grafana/data'; +import { StoreState } from 'app/types'; + import { getPanelPluginNotFound } from '../../panel/components/PanelPluginError'; export const getPanelPluginWithFallback = diff --git a/public/app/features/dashboard/state/utils.test.ts b/public/app/features/dashboard/state/utils.test.ts index fcaee378186..5c63afdf2ee 100644 --- a/public/app/features/dashboard/state/utils.test.ts +++ b/public/app/features/dashboard/state/utils.test.ts @@ -1,6 +1,7 @@ +import { REPEAT_DIR_HORIZONTAL } from '../../../core/constants'; + import { PanelModel } from './PanelModel'; import { deleteScopeVars, isOnTheSameGridRow } from './utils'; -import { REPEAT_DIR_HORIZONTAL } from '../../../core/constants'; describe('isOnTheSameGridRow', () => { describe('when source panel is next to a panel', () => { diff --git a/public/app/features/dashboard/state/utils.ts b/public/app/features/dashboard/state/utils.ts index 7a726900aeb..13ca54d302c 100644 --- a/public/app/features/dashboard/state/utils.ts +++ b/public/app/features/dashboard/state/utils.ts @@ -1,6 +1,7 @@ -import { PanelModel } from './PanelModel'; import { REPEAT_DIR_HORIZONTAL } from '../../../core/constants'; +import { PanelModel } from './PanelModel'; + export function isOnTheSameGridRow(sourcePanel: PanelModel, otherPanel: PanelModel): boolean { if (sourcePanel.repeatDirection === REPEAT_DIR_HORIZONTAL) { return false; diff --git a/public/app/features/dashboard/utils/getPanelMenu.test.ts b/public/app/features/dashboard/utils/getPanelMenu.test.ts index 9b2746f5141..6ca07eb7998 100644 --- a/public/app/features/dashboard/utils/getPanelMenu.test.ts +++ b/public/app/features/dashboard/utils/getPanelMenu.test.ts @@ -1,10 +1,12 @@ import { PanelMenuItem } from '@grafana/data'; -import { DashboardModel, PanelModel } from '../state'; -import { getPanelMenu } from './getPanelMenu'; -import { describe } from '../../../../test/lib/common'; -import { setStore } from 'app/store/store'; import config from 'app/core/config'; import * as actions from 'app/features/explore/state/main'; +import { setStore } from 'app/store/store'; + +import { describe } from '../../../../test/lib/common'; +import { DashboardModel, PanelModel } from '../state'; + +import { getPanelMenu } from './getPanelMenu'; jest.mock('app/core/services/context_srv', () => ({ contextSrv: { diff --git a/public/app/features/dashboard/utils/getPanelMenu.ts b/public/app/features/dashboard/utils/getPanelMenu.ts index 16c18b8501e..f5921d734b3 100644 --- a/public/app/features/dashboard/utils/getPanelMenu.ts +++ b/public/app/features/dashboard/utils/getPanelMenu.ts @@ -1,6 +1,9 @@ -import { store } from 'app/store/store'; -import { AngularComponent, getDataSourceSrv, locationService } from '@grafana/runtime'; import { PanelMenuItem } from '@grafana/data'; +import { AngularComponent, getDataSourceSrv, locationService } from '@grafana/runtime'; +import { PanelCtrl } from 'app/angular/panel/panel_ctrl'; +import config from 'app/core/config'; +import { DashboardModel } from 'app/features/dashboard/state/DashboardModel'; +import { PanelModel } from 'app/features/dashboard/state/PanelModel'; import { addLibraryPanel, copyPanel, @@ -10,14 +13,12 @@ import { unlinkLibraryPanel, } from 'app/features/dashboard/utils/panel'; import { isPanelModelLibraryPanel } from 'app/features/library-panels/guard'; -import { PanelModel } from 'app/features/dashboard/state/PanelModel'; -import { DashboardModel } from 'app/features/dashboard/state/DashboardModel'; +import { store } from 'app/store/store'; + import { contextSrv } from '../../../core/services/context_srv'; -import { navigateToExplore } from '../../explore/state/main'; import { getExploreUrl } from '../../../core/utils/explore'; +import { navigateToExplore } from '../../explore/state/main'; import { getTimeSrv } from '../services/TimeSrv'; -import { PanelCtrl } from 'app/angular/panel/panel_ctrl'; -import config from 'app/core/config'; export function getPanelMenu( dashboard: DashboardModel, diff --git a/public/app/features/dashboard/utils/loadSnapshotData.ts b/public/app/features/dashboard/utils/loadSnapshotData.ts index 2a451cef341..40ae85cc49a 100644 --- a/public/app/features/dashboard/utils/loadSnapshotData.ts +++ b/public/app/features/dashboard/utils/loadSnapshotData.ts @@ -1,10 +1,12 @@ import { applyFieldOverrides, ArrayDataFrame, getDefaultTimeRange, LoadingState, PanelData } from '@grafana/data'; import { config } from 'app/core/config'; -import { DashboardModel, PanelModel } from '../state'; -import { getProcessedDataFrames } from '../../query/state/runRequest'; + import { SnapshotWorker } from '../../query/state/DashboardQueryRunner/SnapshotWorker'; -import { applyPanelTimeOverrides } from './panel'; +import { getProcessedDataFrames } from '../../query/state/runRequest'; import { getTimeSrv } from '../services/TimeSrv'; +import { DashboardModel, PanelModel } from '../state'; + +import { applyPanelTimeOverrides } from './panel'; export function loadSnapshotData(panel: PanelModel, dashboard: DashboardModel): PanelData { const data = getProcessedDataFrames(panel.snapshotData); diff --git a/public/app/features/dashboard/utils/panel.test.ts b/public/app/features/dashboard/utils/panel.test.ts index f1431af92a1..a979c7ab1cc 100644 --- a/public/app/features/dashboard/utils/panel.test.ts +++ b/public/app/features/dashboard/utils/panel.test.ts @@ -1,9 +1,11 @@ +import { advanceTo, clear } from 'jest-date-mock'; +import { ComponentClass } from 'react'; + import { dateTime, DateTime, PanelProps, TimeRange } from '@grafana/data'; import { applyPanelTimeOverrides, calculateInnerPanelHeight } from 'app/features/dashboard/utils/panel'; -import { advanceTo, clear } from 'jest-date-mock'; -import { PanelModel } from '../state'; + import { getPanelPlugin } from '../../plugins/__mocks__/pluginMocks'; -import { ComponentClass } from 'react'; +import { PanelModel } from '../state'; const dashboardTimeRange: TimeRange = { from: dateTime([2019, 1, 11, 12, 0]), diff --git a/public/app/features/dashboard/utils/panel.ts b/public/app/features/dashboard/utils/panel.ts index d92497a43f0..202de4be4f4 100644 --- a/public/app/features/dashboard/utils/panel.ts +++ b/public/app/features/dashboard/utils/panel.ts @@ -1,28 +1,20 @@ -// Store -import store from 'app/core/store'; -import { dispatch } from 'app/store/store'; - -// Models -import { DashboardModel } from 'app/features/dashboard/state/DashboardModel'; -import { PanelModel } from 'app/features/dashboard/state/PanelModel'; -import { TimeRange, AppEvents, rangeUtil, dateMath, PanelModel as IPanelModel } from '@grafana/data'; - -// Utils import { isString as _isString } from 'lodash'; + +import { TimeRange, AppEvents, rangeUtil, dateMath, PanelModel as IPanelModel } from '@grafana/data'; +import { getTemplateSrv } from '@grafana/runtime'; import appEvents from 'app/core/app_events'; import config from 'app/core/config'; - -// Services -import { getTemplateSrv } from '@grafana/runtime'; - -// Constants import { LS_PANEL_COPY_KEY, PANEL_BORDER } from 'app/core/constants'; - +import store from 'app/core/store'; import { ShareModal } from 'app/features/dashboard/components/ShareModal'; -import { ShowConfirmModalEvent, ShowModalReactEvent } from '../../../types/events'; +import { DashboardModel } from 'app/features/dashboard/state/DashboardModel'; +import { PanelModel } from 'app/features/dashboard/state/PanelModel'; import { AddLibraryPanelModal } from 'app/features/library-panels/components/AddLibraryPanelModal/AddLibraryPanelModal'; import { UnlinkModal } from 'app/features/library-panels/components/UnlinkModal/UnlinkModal'; import { cleanUpPanelState } from 'app/features/panel/state/actions'; +import { dispatch } from 'app/store/store'; + +import { ShowConfirmModalEvent, ShowModalReactEvent } from '../../../types/events'; export const removePanel = (dashboard: DashboardModel, panel: PanelModel, ask: boolean) => { // confirm deletion diff --git a/public/app/features/dashboard/utils/panelMerge.test.ts b/public/app/features/dashboard/utils/panelMerge.test.ts index d0117f532ad..9882379d3a2 100644 --- a/public/app/features/dashboard/utils/panelMerge.test.ts +++ b/public/app/features/dashboard/utils/panelMerge.test.ts @@ -1,4 +1,5 @@ import { PanelModel } from '@grafana/data'; + import { DashboardModel } from '../state/DashboardModel'; describe('Merge dashbaord panels', () => { diff --git a/public/app/features/dashboard/utils/panelMerge.ts b/public/app/features/dashboard/utils/panelMerge.ts index a0de905acbd..946d3177cf0 100644 --- a/public/app/features/dashboard/utils/panelMerge.ts +++ b/public/app/features/dashboard/utils/panelMerge.ts @@ -1,5 +1,7 @@ -import { PanelModel as IPanelModel } from '@grafana/data'; import { isEqualWith } from 'lodash'; + +import { PanelModel as IPanelModel } from '@grafana/data'; + import { PanelModel } from '../state'; export interface PanelMergeInfo { diff --git a/public/app/features/datasources/DashboardsTable.test.tsx b/public/app/features/datasources/DashboardsTable.test.tsx index 10a14f464e4..4e6fafe722f 100644 --- a/public/app/features/datasources/DashboardsTable.test.tsx +++ b/public/app/features/datasources/DashboardsTable.test.tsx @@ -1,8 +1,10 @@ -import React from 'react'; import { shallow } from 'enzyme'; -import DashboardsTable, { Props } from './DashboardsTable'; +import React from 'react'; + import { PluginDashboard } from '../../types'; +import DashboardsTable, { Props } from './DashboardsTable'; + const setup = (propOverrides?: object) => { const props: Props = { dashboards: [] as PluginDashboard[], diff --git a/public/app/features/datasources/DashboardsTable.tsx b/public/app/features/datasources/DashboardsTable.tsx index da71c9de227..3e45624871c 100644 --- a/public/app/features/datasources/DashboardsTable.tsx +++ b/public/app/features/datasources/DashboardsTable.tsx @@ -1,7 +1,9 @@ import React, { FC } from 'react'; -import { PluginDashboard } from '../../types'; + import { Button, Icon } from '@grafana/ui'; +import { PluginDashboard } from '../../types'; + export interface Props { dashboards: PluginDashboard[]; onImport: (dashboard: PluginDashboard, overwrite: boolean) => void; diff --git a/public/app/features/datasources/DataSourceDashboards.test.tsx b/public/app/features/datasources/DataSourceDashboards.test.tsx index b90133586fa..516b90f6570 100644 --- a/public/app/features/datasources/DataSourceDashboards.test.tsx +++ b/public/app/features/datasources/DataSourceDashboards.test.tsx @@ -1,9 +1,11 @@ -import React from 'react'; import { shallow } from 'enzyme'; -import { DataSourceDashboards, Props } from './DataSourceDashboards'; +import React from 'react'; + import { DataSourceSettings, NavModel } from '@grafana/data'; -import { PluginDashboard } from 'app/types'; import { getRouteComponentProps } from 'app/core/navigation/__mocks__/routeProps'; +import { PluginDashboard } from 'app/types'; + +import { DataSourceDashboards, Props } from './DataSourceDashboards'; const setup = (propOverrides?: object) => { const props: Props = { diff --git a/public/app/features/datasources/DataSourceDashboards.tsx b/public/app/features/datasources/DataSourceDashboards.tsx index f035776ddae..9673716ddc3 100644 --- a/public/app/features/datasources/DataSourceDashboards.tsx +++ b/public/app/features/datasources/DataSourceDashboards.tsx @@ -1,21 +1,17 @@ -// Libraries import React, { PureComponent } from 'react'; import { connect, ConnectedProps } from 'react-redux'; -// Components import Page from 'app/core/components/Page/Page'; -import DashboardTable from './DashboardsTable'; - -// Actions & Selectors -import { getNavModel } from 'app/core/selectors/navModel'; -import { loadDataSource } from './state/actions'; -import { loadPluginDashboards } from '../plugins/admin/state/actions'; -import { importDashboard, removeDashboard } from '../dashboard/state/actions'; -import { getDataSource } from './state/selectors'; - -// Types -import { PluginDashboard, StoreState } from 'app/types'; import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; +import { getNavModel } from 'app/core/selectors/navModel'; +import { PluginDashboard, StoreState } from 'app/types'; + +import { importDashboard, removeDashboard } from '../dashboard/state/actions'; +import { loadPluginDashboards } from '../plugins/admin/state/actions'; + +import DashboardTable from './DashboardsTable'; +import { loadDataSource } from './state/actions'; +import { getDataSource } from './state/selectors'; export interface OwnProps extends GrafanaRouteComponentProps<{ uid: string }> {} diff --git a/public/app/features/datasources/DataSourceList.test.tsx b/public/app/features/datasources/DataSourceList.test.tsx index 55c24291bce..3110b35a6e8 100644 --- a/public/app/features/datasources/DataSourceList.test.tsx +++ b/public/app/features/datasources/DataSourceList.test.tsx @@ -1,8 +1,10 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; +import React from 'react'; + +import { LayoutModes } from '@grafana/data'; + import DataSourcesList from './DataSourcesList'; import { getMockDataSources } from './__mocks__/dataSourcesMocks'; -import { LayoutModes } from '@grafana/data'; const setup = () => { const props = { diff --git a/public/app/features/datasources/DataSourcesList.tsx b/public/app/features/datasources/DataSourcesList.tsx index 3566177d7c0..9bcca5d543c 100644 --- a/public/app/features/datasources/DataSourcesList.tsx +++ b/public/app/features/datasources/DataSourcesList.tsx @@ -1,10 +1,10 @@ // Libraries +import { css } from '@emotion/css'; import React, { FC } from 'react'; // Types import { DataSourceSettings, LayoutMode } from '@grafana/data'; import { Card, Tag, useStyles } from '@grafana/ui'; -import { css } from '@emotion/css'; export interface Props { dataSources: DataSourceSettings[]; diff --git a/public/app/features/datasources/DataSourcesListPage.test.tsx b/public/app/features/datasources/DataSourcesListPage.test.tsx index 975f925c8b3..c26bd1af413 100644 --- a/public/app/features/datasources/DataSourcesListPage.test.tsx +++ b/public/app/features/datasources/DataSourcesListPage.test.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { shallow } from 'enzyme'; +import React from 'react'; + import { DataSourceSettings, NavModel, LayoutModes } from '@grafana/data'; import { DataSourcesListPage, Props } from './DataSourcesListPage'; diff --git a/public/app/features/datasources/DataSourcesListPage.tsx b/public/app/features/datasources/DataSourcesListPage.tsx index 4b1a5101f96..ca8c5d3ec20 100644 --- a/public/app/features/datasources/DataSourcesListPage.tsx +++ b/public/app/features/datasources/DataSourcesListPage.tsx @@ -1,27 +1,23 @@ -// Libraries import React, { PureComponent } from 'react'; import { connect, ConnectedProps } from 'react-redux'; -// Services & Utils -import { contextSrv } from 'app/core/core'; -// Components + +import { IconName } from '@grafana/ui'; +import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA'; import Page from 'app/core/components/Page/Page'; import PageActionBar from 'app/core/components/PageActionBar/PageActionBar'; -import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA'; -import DataSourcesList from './DataSourcesList'; -// Types -import { IconName } from '@grafana/ui'; -import { StoreState, AccessControlAction } from 'app/types'; -// Actions -import { loadDataSources } from './state/actions'; +import { contextSrv } from 'app/core/core'; import { getNavModel } from 'app/core/selectors/navModel'; +import { StoreState, AccessControlAction } from 'app/types'; +import DataSourcesList from './DataSourcesList'; +import { loadDataSources } from './state/actions'; +import { setDataSourcesLayoutMode, setDataSourcesSearchQuery } from './state/reducers'; import { getDataSources, getDataSourcesCount, getDataSourcesLayoutMode, getDataSourcesSearchQuery, } from './state/selectors'; -import { setDataSourcesLayoutMode, setDataSourcesSearchQuery } from './state/reducers'; function mapStateToProps(state: StoreState) { return { diff --git a/public/app/features/datasources/NewDataSourcePage.tsx b/public/app/features/datasources/NewDataSourcePage.tsx index 21b68754131..b7943e8af90 100644 --- a/public/app/features/datasources/NewDataSourcePage.tsx +++ b/public/app/features/datasources/NewDataSourcePage.tsx @@ -1,17 +1,19 @@ +import { css, cx } from '@emotion/css'; import React, { FC, PureComponent } from 'react'; import { connect, ConnectedProps } from 'react-redux'; -import { DataSourcePluginMeta, GrafanaTheme2, NavModel } from '@grafana/data'; -import { Card, LinkButton, List, PluginSignatureBadge, FilterInput, useStyles2 } from '@grafana/ui'; -import { css, cx } from '@emotion/css'; -import { selectors } from '@grafana/e2e-selectors'; +import { DataSourcePluginMeta, GrafanaTheme2, NavModel } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; +import { Card, LinkButton, List, PluginSignatureBadge, FilterInput, useStyles2 } from '@grafana/ui'; import Page from 'app/core/components/Page/Page'; import { StoreState } from 'app/types'; -import { addDataSource, loadDataSourcePlugins } from './state/actions'; -import { getDataSourcePlugins } from './state/selectors'; -import { setDataSourceTypeSearchQuery } from './state/reducers'; + import { PluginsErrorsInfo } from '../plugins/components/PluginsErrorsInfo'; +import { addDataSource, loadDataSourcePlugins } from './state/actions'; +import { setDataSourceTypeSearchQuery } from './state/reducers'; +import { getDataSourcePlugins } from './state/selectors'; + function mapStateToProps(state: StoreState) { return { navModel: getNavModel(), diff --git a/public/app/features/datasources/settings/BasicSettings.test.tsx b/public/app/features/datasources/settings/BasicSettings.test.tsx index 0194adc9007..389c6618fcc 100644 --- a/public/app/features/datasources/settings/BasicSettings.test.tsx +++ b/public/app/features/datasources/settings/BasicSettings.test.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { shallow } from 'enzyme'; +import React from 'react'; + import BasicSettings, { Props } from './BasicSettings'; const setup = () => { diff --git a/public/app/features/datasources/settings/BasicSettings.tsx b/public/app/features/datasources/settings/BasicSettings.tsx index 1271672e6e6..ad9d7d49f72 100644 --- a/public/app/features/datasources/settings/BasicSettings.tsx +++ b/public/app/features/datasources/settings/BasicSettings.tsx @@ -1,6 +1,7 @@ import React, { FC } from 'react'; -import { InlineFormLabel, LegacyForms } from '@grafana/ui'; + import { selectors } from '@grafana/e2e-selectors'; +import { InlineFormLabel, LegacyForms } from '@grafana/ui'; const { Input, Switch } = LegacyForms; diff --git a/public/app/features/datasources/settings/ButtonRow.test.tsx b/public/app/features/datasources/settings/ButtonRow.test.tsx index aa713dd557d..9508cfd8e97 100644 --- a/public/app/features/datasources/settings/ButtonRow.test.tsx +++ b/public/app/features/datasources/settings/ButtonRow.test.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { shallow } from 'enzyme'; +import React from 'react'; + import ButtonRow, { Props } from './ButtonRow'; jest.mock('app/core/core', () => { diff --git a/public/app/features/datasources/settings/ButtonRow.tsx b/public/app/features/datasources/settings/ButtonRow.tsx index e2907d72889..473043ac451 100644 --- a/public/app/features/datasources/settings/ButtonRow.tsx +++ b/public/app/features/datasources/settings/ButtonRow.tsx @@ -1,10 +1,9 @@ import React, { FC } from 'react'; + import { selectors } from '@grafana/e2e-selectors'; - import { Button, LinkButton } from '@grafana/ui'; - -import { AccessControlAction } from 'app/types/'; import { contextSrv } from 'app/core/core'; +import { AccessControlAction } from 'app/types/'; export interface Props { exploreUrl: string; diff --git a/public/app/features/datasources/settings/CloudInfoBox.tsx b/public/app/features/datasources/settings/CloudInfoBox.tsx index 96990bf434f..ce087cd6148 100644 --- a/public/app/features/datasources/settings/CloudInfoBox.tsx +++ b/public/app/features/datasources/settings/CloudInfoBox.tsx @@ -1,9 +1,10 @@ -import { DataSourceSettings } from '@grafana/data'; -import { Alert } from '@grafana/ui'; import React, { FC } from 'react'; -import { config } from 'app/core/config'; + +import { DataSourceSettings } from '@grafana/data'; import { GrafanaEdition } from '@grafana/data/src/types/config'; +import { Alert } from '@grafana/ui'; import { LocalStorageValueProvider } from 'app/core/components/LocalStorageValueProvider'; +import { config } from 'app/core/config'; const LOCAL_STORAGE_KEY = 'datasources.settings.cloudInfoBox.isDismissed'; diff --git a/public/app/features/datasources/settings/DataSourceSettingsPage.test.tsx b/public/app/features/datasources/settings/DataSourceSettingsPage.test.tsx index 12f7226151b..57e0d50c8a6 100644 --- a/public/app/features/datasources/settings/DataSourceSettingsPage.test.tsx +++ b/public/app/features/datasources/settings/DataSourceSettingsPage.test.tsx @@ -1,13 +1,16 @@ -import React from 'react'; -import { DataSourceSettingsPage, Props } from './DataSourceSettingsPage'; -import { getMockDataSource } from '../__mocks__/dataSourcesMocks'; -import { getMockPlugin } from '../../plugins/__mocks__/pluginMocks'; -import { dataSourceLoaded, setDataSourceName, setIsDefault } from '../state/reducers'; -import { getRouteComponentProps } from 'app/core/navigation/__mocks__/routeProps'; -import { cleanUpAction } from 'app/core/actions/cleanUp'; import { screen, render } from '@testing-library/react'; -import { selectors } from '@grafana/e2e-selectors'; +import React from 'react'; + import { PluginState } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; +import { cleanUpAction } from 'app/core/actions/cleanUp'; +import { getRouteComponentProps } from 'app/core/navigation/__mocks__/routeProps'; + +import { getMockPlugin } from '../../plugins/__mocks__/pluginMocks'; +import { getMockDataSource } from '../__mocks__/dataSourcesMocks'; +import { dataSourceLoaded, setDataSourceName, setIsDefault } from '../state/reducers'; + +import { DataSourceSettingsPage, Props } from './DataSourceSettingsPage'; jest.mock('app/core/core', () => { return { diff --git a/public/app/features/datasources/settings/DataSourceSettingsPage.tsx b/public/app/features/datasources/settings/DataSourceSettingsPage.tsx index f4d12900901..68e2a4f2384 100644 --- a/public/app/features/datasources/settings/DataSourceSettingsPage.tsx +++ b/public/app/features/datasources/settings/DataSourceSettingsPage.tsx @@ -1,15 +1,19 @@ import React, { PureComponent } from 'react'; -// Components -import Page from 'app/core/components/Page/Page'; -import { PluginSettings } from './PluginSettings'; -import BasicSettings from './BasicSettings'; -import ButtonRow from './ButtonRow'; -// Services & Utils -import appEvents from 'app/core/app_events'; -import { contextSrv } from 'app/core/core'; +import { connect, ConnectedProps } from 'react-redux'; -// Actions & selectors -import { getDataSource, getDataSourceMeta } from '../state/selectors'; +import { DataSourceSettings, urlUtil } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; +import { Alert, Button } from '@grafana/ui'; +import { cleanUpAction } from 'app/core/actions/cleanUp'; +import appEvents from 'app/core/app_events'; +import Page from 'app/core/components/Page/Page'; +import { contextSrv } from 'app/core/core'; +import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; +import { getNavModel } from 'app/core/selectors/navModel'; +import { PluginStateInfo } from 'app/features/plugins/components/PluginStateInfo'; +import { StoreState, AccessControlAction } from 'app/types/'; + +import { ShowConfirmModalEvent } from '../../../types/events'; import { deleteDataSource, initDataSourceSettings, @@ -17,21 +21,14 @@ import { testDataSource, updateDataSource, } from '../state/actions'; -import { getNavModel } from 'app/core/selectors/navModel'; - -// Types -import { StoreState, AccessControlAction } from 'app/types/'; -import { DataSourceSettings, urlUtil } from '@grafana/data'; -import { Alert, Button } from '@grafana/ui'; import { getDataSourceLoadingNav, buildNavModel, getDataSourceNav } from '../state/navModel'; -import { PluginStateInfo } from 'app/features/plugins/components/PluginStateInfo'; import { dataSourceLoaded, setDataSourceName, setIsDefault } from '../state/reducers'; -import { selectors } from '@grafana/e2e-selectors'; +import { getDataSource, getDataSourceMeta } from '../state/selectors'; + +import BasicSettings from './BasicSettings'; +import ButtonRow from './ButtonRow'; import { CloudInfoBox } from './CloudInfoBox'; -import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; -import { connect, ConnectedProps } from 'react-redux'; -import { cleanUpAction } from 'app/core/actions/cleanUp'; -import { ShowConfirmModalEvent } from '../../../types/events'; +import { PluginSettings } from './PluginSettings'; export interface OwnProps extends GrafanaRouteComponentProps<{ uid: string }> {} diff --git a/public/app/features/datasources/settings/PluginSettings.tsx b/public/app/features/datasources/settings/PluginSettings.tsx index 429f3de6e98..ca322ff2cc5 100644 --- a/public/app/features/datasources/settings/PluginSettings.tsx +++ b/public/app/features/datasources/settings/PluginSettings.tsx @@ -1,5 +1,6 @@ -import React, { PureComponent } from 'react'; import { cloneDeep } from 'lodash'; +import React, { PureComponent } from 'react'; + import { DataQuery, DataSourceApi, diff --git a/public/app/features/datasources/state/actions.test.ts b/public/app/features/datasources/state/actions.test.ts index 8d652cdcd72..84e6ca9c108 100644 --- a/public/app/features/datasources/state/actions.test.ts +++ b/public/app/features/datasources/state/actions.test.ts @@ -1,3 +1,14 @@ +import { of } from 'rxjs'; +import { thunkTester } from 'test/core/thunk/thunkTester'; + +import { BackendSrvRequest, FetchResponse } from '@grafana/runtime'; +import { getBackendSrv } from 'app/core/services/backend_srv'; +import { ThunkResult, ThunkDispatch } from 'app/types'; + +import { getMockPlugin, getMockPlugins } from '../../plugins/__mocks__/pluginMocks'; +import { GenericDataSourcePlugin } from '../settings/PluginSettings'; +import { initDataSourceSettings } from '../state/actions'; + import { findNewName, nameExits, @@ -6,8 +17,6 @@ import { TestDataSourceDependencies, getDataSourceUsingUidOrId, } from './actions'; -import { getMockPlugin, getMockPlugins } from '../../plugins/__mocks__/pluginMocks'; -import { thunkTester } from 'test/core/thunk/thunkTester'; import { initDataSourceSettingsSucceeded, initDataSourceSettingsFailed, @@ -15,12 +24,6 @@ import { testDataSourceSucceeded, testDataSourceFailed, } from './reducers'; -import { initDataSourceSettings } from '../state/actions'; -import { ThunkResult, ThunkDispatch } from 'app/types'; -import { GenericDataSourcePlugin } from '../settings/PluginSettings'; -import { getBackendSrv } from 'app/core/services/backend_srv'; -import { BackendSrvRequest, FetchResponse } from '@grafana/runtime'; -import { of } from 'rxjs'; jest.mock('app/core/services/backend_srv'); jest.mock('@grafana/runtime', () => ({ diff --git a/public/app/features/datasources/state/actions.ts b/public/app/features/datasources/state/actions.ts index 54fa40cc03d..9dd8d5d26e9 100644 --- a/public/app/features/datasources/state/actions.ts +++ b/public/app/features/datasources/state/actions.ts @@ -1,13 +1,17 @@ import { lastValueFrom } from 'rxjs'; + import { DataSourcePluginMeta, DataSourceSettings, locationUtil } from '@grafana/data'; import { DataSourceWithBackend, getDataSourceSrv, locationService } from '@grafana/runtime'; import { updateNavIndex } from 'app/core/actions'; import { getBackendSrv } from 'app/core/services/backend_srv'; +import { accessControlQueryParam } from 'app/core/utils/accessControl'; import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; -import { importDataSourcePlugin } from 'app/features/plugins/plugin_loader'; import { getPluginSettings } from 'app/features/plugins/pluginSettings'; +import { importDataSourcePlugin } from 'app/features/plugins/plugin_loader'; import { DataSourcePluginCategory, ThunkDispatch, ThunkResult } from 'app/types'; +import { contextSrv } from '../../../core/services/context_srv'; + import { buildCategories } from './buildCategories'; import { buildNavModel } from './navModel'; import { @@ -23,8 +27,6 @@ import { testDataSourceSucceeded, } from './reducers'; import { getDataSource, getDataSourceMeta } from './selectors'; -import { accessControlQueryParam } from 'app/core/utils/accessControl'; -import { contextSrv } from '../../../core/services/context_srv'; export interface DataSourceTypesLoadedPayload { plugins: DataSourcePluginMeta[]; diff --git a/public/app/features/datasources/state/buildCategories.test.ts b/public/app/features/datasources/state/buildCategories.test.ts index 04076b74e13..5bea2aa63d1 100644 --- a/public/app/features/datasources/state/buildCategories.test.ts +++ b/public/app/features/datasources/state/buildCategories.test.ts @@ -1,7 +1,9 @@ -import { buildCategories } from './buildCategories'; -import { getMockPlugin } from '../../plugins/__mocks__/pluginMocks'; import { DataSourcePluginMeta } from '@grafana/data'; +import { getMockPlugin } from '../../plugins/__mocks__/pluginMocks'; + +import { buildCategories } from './buildCategories'; + const plugins: DataSourcePluginMeta[] = [ { ...getMockPlugin({ id: 'graphite' }), diff --git a/public/app/features/datasources/state/navModel.ts b/public/app/features/datasources/state/navModel.ts index e9e215293cb..4e0b1ed593d 100644 --- a/public/app/features/datasources/state/navModel.ts +++ b/public/app/features/datasources/state/navModel.ts @@ -1,11 +1,12 @@ import { DataSourceSettings, PluginType, PluginInclude, NavModel, NavModelItem } from '@grafana/data'; import { featureEnabled } from '@grafana/runtime'; +import { ProBadge } from 'app/core/components/Upgrade/ProBadge'; import config from 'app/core/config'; import { contextSrv } from 'app/core/core'; import { AccessControlAction } from 'app/types'; -import { ProBadge } from 'app/core/components/Upgrade/ProBadge'; -import { GenericDataSourcePlugin } from '../settings/PluginSettings'; + import { highlightTrial } from '../../admin/utils'; +import { GenericDataSourcePlugin } from '../settings/PluginSettings'; const loadingDSType = 'Loading'; diff --git a/public/app/features/datasources/state/reducers.test.ts b/public/app/features/datasources/state/reducers.test.ts index cb5e6afed54..f6d409fd5a6 100644 --- a/public/app/features/datasources/state/reducers.test.ts +++ b/public/app/features/datasources/state/reducers.test.ts @@ -1,4 +1,11 @@ import { reducerTester } from 'test/core/redux/reducerTester'; + +import { PluginMeta, PluginMetaInfo, PluginType, LayoutModes } from '@grafana/data'; +import { DataSourceSettingsState, DataSourcesState } from 'app/types'; + +import { getMockDataSource, getMockDataSources } from '../__mocks__/dataSourcesMocks'; +import { GenericDataSourcePlugin } from '../settings/PluginSettings'; + import { dataSourceLoaded, dataSourceMetaLoaded, @@ -17,10 +24,6 @@ import { setDataSourceTypeSearchQuery, setIsDefault, } from './reducers'; -import { getMockDataSource, getMockDataSources } from '../__mocks__/dataSourcesMocks'; -import { DataSourceSettingsState, DataSourcesState } from 'app/types'; -import { PluginMeta, PluginMetaInfo, PluginType, LayoutModes } from '@grafana/data'; -import { GenericDataSourcePlugin } from '../settings/PluginSettings'; const mockPlugin = () => ({ diff --git a/public/app/features/datasources/state/reducers.ts b/public/app/features/datasources/state/reducers.ts index 1af1f762d6b..8410ec5aab6 100644 --- a/public/app/features/datasources/state/reducers.ts +++ b/public/app/features/datasources/state/reducers.ts @@ -1,10 +1,12 @@ import { AnyAction, createAction } from '@reduxjs/toolkit'; -import { DataSourcePluginMeta, DataSourceSettings, LayoutMode, LayoutModes } from '@grafana/data'; +import { DataSourcePluginMeta, DataSourceSettings, LayoutMode, LayoutModes } from '@grafana/data'; import { DataSourcesState, DataSourceSettingsState, TestingStatus } from 'app/types'; -import { DataSourceTypesLoadedPayload } from './actions'; + import { GenericDataSourcePlugin } from '../settings/PluginSettings'; +import { DataSourceTypesLoadedPayload } from './actions'; + export const initialState: DataSourcesState = { dataSources: [], plugins: [], diff --git a/public/app/features/datasources/state/selectors.ts b/public/app/features/datasources/state/selectors.ts index b09e79698f4..558dfa88a4e 100644 --- a/public/app/features/datasources/state/selectors.ts +++ b/public/app/features/datasources/state/selectors.ts @@ -1,4 +1,5 @@ import { DataSourcePluginMeta, DataSourceSettings, UrlQueryValue } from '@grafana/data'; + import { DataSourcesState } from '../../../types/datasources'; export const getDataSources = (state: DataSourcesState) => { diff --git a/public/app/features/dimensions/color.ts b/public/app/features/dimensions/color.ts index d38a3fc34be..5e6646db95c 100644 --- a/public/app/features/dimensions/color.ts +++ b/public/app/features/dimensions/color.ts @@ -1,4 +1,5 @@ import { DataFrame, Field, getDisplayProcessor, getFieldColorModeForField, GrafanaTheme2 } from '@grafana/data'; + import { ColorDimensionConfig, DimensionSupplier } from './types'; import { findField, getLastNotNullFieldValue } from './utils'; diff --git a/public/app/features/dimensions/editors/ColorDimensionEditor.tsx b/public/app/features/dimensions/editors/ColorDimensionEditor.tsx index 823fa1989c5..1b18ddedc60 100644 --- a/public/app/features/dimensions/editors/ColorDimensionEditor.tsx +++ b/public/app/features/dimensions/editors/ColorDimensionEditor.tsx @@ -1,12 +1,14 @@ +import { css } from '@emotion/css'; import React, { FC, useCallback } from 'react'; + import { GrafanaTheme2, SelectableValue, StandardEditorProps } from '@grafana/data'; -import { ColorDimensionConfig } from '../types'; import { Select, ColorPicker, useStyles2 } from '@grafana/ui'; + import { useFieldDisplayNames, useSelectOptions, } from '../../../../../packages/grafana-ui/src/components/MatchersUI/utils'; -import { css } from '@emotion/css'; +import { ColorDimensionConfig } from '../types'; const fixedColorOption: SelectableValue = { label: 'Fixed color', diff --git a/public/app/features/dimensions/editors/FolderPickerTab.tsx b/public/app/features/dimensions/editors/FolderPickerTab.tsx index 13fa478d577..005566852c6 100644 --- a/public/app/features/dimensions/editors/FolderPickerTab.tsx +++ b/public/app/features/dimensions/editors/FolderPickerTab.tsx @@ -1,11 +1,13 @@ -import React, { Dispatch, SetStateAction, useEffect, useState } from 'react'; import { css } from '@emotion/css'; -import { Field, FilterInput, Select, useStyles2 } from '@grafana/ui'; +import React, { Dispatch, SetStateAction, useEffect, useState } from 'react'; + import { GrafanaTheme2, SelectableValue } from '@grafana/data'; +import { Field, FilterInput, Select, useStyles2 } from '@grafana/ui'; +import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; +import { FileElement, GrafanaDatasource } from 'app/plugins/datasource/grafana/datasource'; import { MediaType, ResourceFolderName } from '../types'; -import { FileElement, GrafanaDatasource } from 'app/plugins/datasource/grafana/datasource'; -import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; + import { ResourceCards } from './ResourceCards'; const getFolders = (mediaType: MediaType) => { diff --git a/public/app/features/dimensions/editors/IconSelector.tsx b/public/app/features/dimensions/editors/IconSelector.tsx index 3a2d977c9a7..58188cc383e 100644 --- a/public/app/features/dimensions/editors/IconSelector.tsx +++ b/public/app/features/dimensions/editors/IconSelector.tsx @@ -1,7 +1,8 @@ import React, { useState, useEffect } from 'react'; -import { Select } from '@grafana/ui'; + import { SelectableValue } from '@grafana/data'; import { getBackendSrv } from '@grafana/runtime'; +import { Select } from '@grafana/ui'; interface Props { value: string; diff --git a/public/app/features/dimensions/editors/NumberInput.tsx b/public/app/features/dimensions/editors/NumberInput.tsx index da21132a776..24e8b281c13 100644 --- a/public/app/features/dimensions/editors/NumberInput.tsx +++ b/public/app/features/dimensions/editors/NumberInput.tsx @@ -1,4 +1,5 @@ import React, { PureComponent } from 'react'; + import { Field, Input } from '@grafana/ui'; interface Props { diff --git a/public/app/features/dimensions/editors/ResourceCards.tsx b/public/app/features/dimensions/editors/ResourceCards.tsx index aeaa1fc6758..afd7e0d6bd1 100644 --- a/public/app/features/dimensions/editors/ResourceCards.tsx +++ b/public/app/features/dimensions/editors/ResourceCards.tsx @@ -1,10 +1,12 @@ +import { css, cx } from '@emotion/css'; import React, { memo, CSSProperties } from 'react'; -import { areEqual, FixedSizeGrid as Grid } from 'react-window'; +import SVG from 'react-inlinesvg'; import AutoSizer from 'react-virtualized-auto-sizer'; +import { areEqual, FixedSizeGrid as Grid } from 'react-window'; + import { GrafanaTheme2 } from '@grafana/data'; import { useTheme2, stylesFactory } from '@grafana/ui'; -import SVG from 'react-inlinesvg'; -import { css, cx } from '@emotion/css'; + import { ResourceItem } from './FolderPickerTab'; interface CellProps { diff --git a/public/app/features/dimensions/editors/ResourceDimensionEditor.tsx b/public/app/features/dimensions/editors/ResourceDimensionEditor.tsx index 6818ab6ee37..a9020f991c2 100644 --- a/public/app/features/dimensions/editors/ResourceDimensionEditor.tsx +++ b/public/app/features/dimensions/editors/ResourceDimensionEditor.tsx @@ -1,8 +1,10 @@ import React, { FC, useCallback } from 'react'; + import { FieldNamePickerConfigSettings, StandardEditorProps, StandardEditorsRegistryItem } from '@grafana/data'; import { InlineField, InlineFieldRow, RadioButtonGroup } from '@grafana/ui'; import { FieldNamePicker } from '@grafana/ui/src/components/MatchersUI/FieldNamePicker'; +import { getPublicOrAbsoluteUrl, ResourceFolderName } from '..'; import { MediaType, ResourceDimensionConfig, @@ -10,7 +12,7 @@ import { ResourceDimensionOptions, ResourcePickerSize, } from '../types'; -import { getPublicOrAbsoluteUrl, ResourceFolderName } from '..'; + import { ResourcePicker } from './ResourcePicker'; const resourceOptions = [ diff --git a/public/app/features/dimensions/editors/ResourcePicker.tsx b/public/app/features/dimensions/editors/ResourcePicker.tsx index 938792bc14d..7bc55df26b7 100644 --- a/public/app/features/dimensions/editors/ResourcePicker.tsx +++ b/public/app/features/dimensions/editors/ResourcePicker.tsx @@ -1,5 +1,8 @@ -import React, { createRef } from 'react'; import { css } from '@emotion/css'; +import React, { createRef } from 'react'; +import SVG from 'react-inlinesvg'; + +import { GrafanaTheme2 } from '@grafana/data'; import { Button, InlineField, @@ -11,13 +14,12 @@ import { useStyles2, useTheme2, } from '@grafana/ui'; -import { GrafanaTheme2 } from '@grafana/data'; -import SVG from 'react-inlinesvg'; - -import { MediaType, ResourceFolderName, ResourcePickerSize } from '../types'; import { closePopover } from '@grafana/ui/src/utils/closePopover'; -import { ResourcePickerPopover } from './ResourcePickerPopover'; + import { getPublicOrAbsoluteUrl } from '../resource'; +import { MediaType, ResourceFolderName, ResourcePickerSize } from '../types'; + +import { ResourcePickerPopover } from './ResourcePickerPopover'; interface Props { onChange: (value?: string) => void; diff --git a/public/app/features/dimensions/editors/ResourcePickerPopover.tsx b/public/app/features/dimensions/editors/ResourcePickerPopover.tsx index c38df5788f3..66baddbbcbd 100644 --- a/public/app/features/dimensions/editors/ResourcePickerPopover.tsx +++ b/public/app/features/dimensions/editors/ResourcePickerPopover.tsx @@ -1,12 +1,14 @@ -import React, { createRef, useState } from 'react'; import { css } from '@emotion/css'; -import { Button, ButtonGroup, useStyles2 } from '@grafana/ui'; -import { GrafanaTheme2 } from '@grafana/data'; -import { FocusScope } from '@react-aria/focus'; import { useDialog } from '@react-aria/dialog'; +import { FocusScope } from '@react-aria/focus'; import { useOverlay } from '@react-aria/overlays'; +import React, { createRef, useState } from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; +import { Button, ButtonGroup, useStyles2 } from '@grafana/ui'; import { MediaType, PickerTabType, ResourceFolderName } from '../types'; + import { FolderPickerTab } from './FolderPickerTab'; import { URLPickerTab } from './URLPickerTab'; diff --git a/public/app/features/dimensions/editors/ScalarDimensionEditor.tsx b/public/app/features/dimensions/editors/ScalarDimensionEditor.tsx index 4efef4cb0ec..dc6bc6c4de7 100644 --- a/public/app/features/dimensions/editors/ScalarDimensionEditor.tsx +++ b/public/app/features/dimensions/editors/ScalarDimensionEditor.tsx @@ -1,10 +1,13 @@ +import { css } from '@emotion/css'; import React, { FC, useCallback } from 'react'; + import { FieldType, GrafanaTheme2, SelectableValue, StandardEditorProps } from '@grafana/data'; -import { ScalarDimensionConfig, ScalarDimensionMode, ScalarDimensionOptions } from '../types'; import { InlineField, InlineFieldRow, RadioButtonGroup, Select, useStyles2 } from '@grafana/ui'; import { useFieldDisplayNames, useSelectOptions } from '@grafana/ui/src/components/MatchersUI/utils'; + +import { ScalarDimensionConfig, ScalarDimensionMode, ScalarDimensionOptions } from '../types'; + import { NumberInput } from './NumberInput'; -import { css } from '@emotion/css'; const fixedValueOption: SelectableValue = { label: 'Fixed value', diff --git a/public/app/features/dimensions/editors/ScaleDimensionEditor.tsx b/public/app/features/dimensions/editors/ScaleDimensionEditor.tsx index 7162a82e86e..f57bd2f0fbe 100644 --- a/public/app/features/dimensions/editors/ScaleDimensionEditor.tsx +++ b/public/app/features/dimensions/editors/ScaleDimensionEditor.tsx @@ -1,14 +1,17 @@ +import { css } from '@emotion/css'; import React, { FC, useCallback, useMemo } from 'react'; + import { GrafanaTheme2, SelectableValue, StandardEditorProps } from '@grafana/data'; -import { ScaleDimensionConfig, ScaleDimensionOptions } from '../types'; import { InlineField, InlineFieldRow, Select, useStyles2 } from '@grafana/ui'; + import { useFieldDisplayNames, useSelectOptions, } from '../../../../../packages/grafana-ui/src/components/MatchersUI/utils'; -import { NumberInput } from './NumberInput'; -import { css } from '@emotion/css'; import { validateScaleOptions, validateScaleConfig } from '../scale'; +import { ScaleDimensionConfig, ScaleDimensionOptions } from '../types'; + +import { NumberInput } from './NumberInput'; const fixedValueOption: SelectableValue = { label: 'Fixed value', diff --git a/public/app/features/dimensions/editors/TextDimensionEditor.tsx b/public/app/features/dimensions/editors/TextDimensionEditor.tsx index 0c452fd58b8..6688bbf23ee 100644 --- a/public/app/features/dimensions/editors/TextDimensionEditor.tsx +++ b/public/app/features/dimensions/editors/TextDimensionEditor.tsx @@ -1,4 +1,5 @@ import React, { FC, useCallback } from 'react'; + import { FieldNamePickerConfigSettings, StandardEditorProps, @@ -7,8 +8,8 @@ import { } from '@grafana/data'; import { Button, InlineField, InlineFieldRow, RadioButtonGroup, StringValueEditor } from '@grafana/ui'; -import { TextDimensionConfig, TextDimensionMode, TextDimensionOptions } from '../types'; import { FieldNamePicker } from '../../../../../packages/grafana-ui/src/components/MatchersUI/FieldNamePicker'; +import { TextDimensionConfig, TextDimensionMode, TextDimensionOptions } from '../types'; const textOptions = [ { label: 'Fixed', value: TextDimensionMode.Fixed, description: 'Fixed value' }, diff --git a/public/app/features/dimensions/editors/ThresholdsEditor/ThresholdsEditor.test.tsx b/public/app/features/dimensions/editors/ThresholdsEditor/ThresholdsEditor.test.tsx index f7213e925fa..c680e51c66f 100644 --- a/public/app/features/dimensions/editors/ThresholdsEditor/ThresholdsEditor.test.tsx +++ b/public/app/features/dimensions/editors/ThresholdsEditor/ThresholdsEditor.test.tsx @@ -1,9 +1,11 @@ -import React, { ChangeEvent } from 'react'; import { mount } from 'enzyme'; +import React, { ChangeEvent } from 'react'; + import { createTheme, ThresholdsMode } from '@grafana/data'; -import { ThresholdsEditor, Props, thresholdsWithoutKey } from './ThresholdsEditor'; import { mockThemeContext, colors } from '@grafana/ui'; +import { ThresholdsEditor, Props, thresholdsWithoutKey } from './ThresholdsEditor'; + const setup = (propOverrides?: Partial) => { const props: Props = { onChange: jest.fn(), diff --git a/public/app/features/dimensions/editors/ThresholdsEditor/ThresholdsEditor.tsx b/public/app/features/dimensions/editors/ThresholdsEditor/ThresholdsEditor.tsx index e79c84a0084..2e1c44a78eb 100644 --- a/public/app/features/dimensions/editors/ThresholdsEditor/ThresholdsEditor.tsx +++ b/public/app/features/dimensions/editors/ThresholdsEditor/ThresholdsEditor.tsx @@ -1,5 +1,7 @@ -import React, { PureComponent, ChangeEvent } from 'react'; import { css } from '@emotion/css'; +import { isNumber } from 'lodash'; +import React, { PureComponent, ChangeEvent } from 'react'; + import { Threshold, sortThresholds, @@ -8,7 +10,6 @@ import { SelectableValue, GrafanaTheme, } from '@grafana/data'; -import { isNumber } from 'lodash'; import { Input, colors, diff --git a/public/app/features/dimensions/editors/ThresholdsEditor/thresholds.tsx b/public/app/features/dimensions/editors/ThresholdsEditor/thresholds.tsx index 9900698a6f9..1642c083fe1 100644 --- a/public/app/features/dimensions/editors/ThresholdsEditor/thresholds.tsx +++ b/public/app/features/dimensions/editors/ThresholdsEditor/thresholds.tsx @@ -1,5 +1,7 @@ import React from 'react'; + import { FieldConfigEditorProps, ThresholdsConfig, ThresholdsMode, ThresholdsFieldConfigSettings } from '@grafana/data'; + import { ThresholdsEditor } from './ThresholdsEditor'; export class ThresholdsValueEditor extends React.PureComponent< diff --git a/public/app/features/dimensions/editors/URLPickerTab.tsx b/public/app/features/dimensions/editors/URLPickerTab.tsx index ff2638fbd9e..5402d2e6112 100644 --- a/public/app/features/dimensions/editors/URLPickerTab.tsx +++ b/public/app/features/dimensions/editors/URLPickerTab.tsx @@ -1,11 +1,12 @@ -import React, { Dispatch, SetStateAction } from 'react'; -import { Field, Input, Label, useStyles2 } from '@grafana/ui'; -import { GrafanaTheme2 } from '@grafana/data'; import { css } from '@emotion/css'; +import React, { Dispatch, SetStateAction } from 'react'; import SVG from 'react-inlinesvg'; -import { MediaType } from '../types'; +import { GrafanaTheme2 } from '@grafana/data'; +import { Field, Input, Label, useStyles2 } from '@grafana/ui'; + import { getPublicOrAbsoluteUrl } from '../resource'; +import { MediaType } from '../types'; interface Props { newValue: string; diff --git a/public/app/features/dimensions/editors/ValueMappingsEditor/ValueMappingEditRow.tsx b/public/app/features/dimensions/editors/ValueMappingsEditor/ValueMappingEditRow.tsx index f30c5364cfd..4298ee0d84d 100644 --- a/public/app/features/dimensions/editors/ValueMappingsEditor/ValueMappingEditRow.tsx +++ b/public/app/features/dimensions/editors/ValueMappingsEditor/ValueMappingEditRow.tsx @@ -1,10 +1,12 @@ -import React, { useCallback, useEffect, useRef } from 'react'; -import { GrafanaTheme2, MappingType, SpecialValueMatch, SelectableValue, ValueMappingResult } from '@grafana/data'; -import { Draggable } from 'react-beautiful-dnd'; import { css } from '@emotion/css'; +import React, { useCallback, useEffect, useRef } from 'react'; +import { Draggable } from 'react-beautiful-dnd'; + +import { GrafanaTheme2, MappingType, SpecialValueMatch, SelectableValue, ValueMappingResult } from '@grafana/data'; import { useStyles2, Icon, Select, HorizontalGroup, ColorPicker, IconButton, Input, Button } from '@grafana/ui'; -import { ResourcePicker } from '../ResourcePicker'; + import { ResourcePickerSize, ResourceFolderName, MediaType } from '../../types'; +import { ResourcePicker } from '../ResourcePicker'; export interface ValueMappingEditRowModel { type: MappingType; diff --git a/public/app/features/dimensions/editors/ValueMappingsEditor/ValueMappingsEditor.test.tsx b/public/app/features/dimensions/editors/ValueMappingsEditor/ValueMappingsEditor.test.tsx index 74426b5b5a4..af45eee4069 100644 --- a/public/app/features/dimensions/editors/ValueMappingsEditor/ValueMappingsEditor.test.tsx +++ b/public/app/features/dimensions/editors/ValueMappingsEditor/ValueMappingsEditor.test.tsx @@ -1,8 +1,10 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; -import { ValueMappingsEditor, Props } from './ValueMappingsEditor'; +import React from 'react'; + import { MappingType } from '@grafana/data'; +import { ValueMappingsEditor, Props } from './ValueMappingsEditor'; + const setup = (spy?: any, propOverrides?: object) => { const props: Props = { onChange: (mappings: any) => { diff --git a/public/app/features/dimensions/editors/ValueMappingsEditor/ValueMappingsEditor.tsx b/public/app/features/dimensions/editors/ValueMappingsEditor/ValueMappingsEditor.tsx index 0081440dfc6..46020d3f21d 100644 --- a/public/app/features/dimensions/editors/ValueMappingsEditor/ValueMappingsEditor.tsx +++ b/public/app/features/dimensions/editors/ValueMappingsEditor/ValueMappingsEditor.tsx @@ -1,11 +1,14 @@ -import React, { useCallback, useMemo, useState } from 'react'; -import { GrafanaTheme2, MappingType, StandardEditorProps, ValueMapping } from '@grafana/data'; import { css } from '@emotion/css'; -import { buildEditRowModels, editModelToSaveModel, ValueMappingsEditorModal } from './ValueMappingsEditorModal'; +import React, { useCallback, useMemo, useState } from 'react'; + +import { GrafanaTheme2, MappingType, StandardEditorProps, ValueMapping } from '@grafana/data'; import { useStyles2, VerticalGroup, Icon, ColorPicker, Button, Modal } from '@grafana/ui'; + import { MediaType, ResourceFolderName, ResourcePickerSize } from '../../types'; import { ResourcePicker } from '../ResourcePicker'; +import { buildEditRowModels, editModelToSaveModel, ValueMappingsEditorModal } from './ValueMappingsEditorModal'; + export interface Props extends StandardEditorProps { showIcon?: boolean; } diff --git a/public/app/features/dimensions/editors/ValueMappingsEditor/ValueMappingsEditorModal.test.tsx b/public/app/features/dimensions/editors/ValueMappingsEditor/ValueMappingsEditorModal.test.tsx index e5185c4da07..370e24f7f6b 100644 --- a/public/app/features/dimensions/editors/ValueMappingsEditor/ValueMappingsEditorModal.test.tsx +++ b/public/app/features/dimensions/editors/ValueMappingsEditor/ValueMappingsEditorModal.test.tsx @@ -1,10 +1,12 @@ -import React from 'react'; import { fireEvent, render, screen } from '@testing-library/react'; -import { ValueMappingsEditorModal, Props } from './ValueMappingsEditorModal'; +import React from 'react'; + import { MappingType } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; import { selectOptionInTest } from '@grafana/ui'; +import { ValueMappingsEditorModal, Props } from './ValueMappingsEditorModal'; + const setup = (spy?: any, propOverrides?: object) => { const props: Props = { onClose: jest.fn(), diff --git a/public/app/features/dimensions/editors/ValueMappingsEditor/ValueMappingsEditorModal.tsx b/public/app/features/dimensions/editors/ValueMappingsEditor/ValueMappingsEditorModal.tsx index a8ff61d7c30..aacb26e065a 100644 --- a/public/app/features/dimensions/editors/ValueMappingsEditor/ValueMappingsEditorModal.tsx +++ b/public/app/features/dimensions/editors/ValueMappingsEditor/ValueMappingsEditorModal.tsx @@ -1,10 +1,12 @@ -import React, { useEffect, useState } from 'react'; -import { GrafanaTheme2, MappingType, SelectableValue, SpecialValueMatch, ValueMapping } from '@grafana/data'; -import { ValueMappingEditRow, ValueMappingEditRowModel } from './ValueMappingEditRow'; -import { DragDropContext, Droppable, DropResult } from 'react-beautiful-dnd'; import { css } from '@emotion/css'; +import React, { useEffect, useState } from 'react'; +import { DragDropContext, Droppable, DropResult } from 'react-beautiful-dnd'; + +import { GrafanaTheme2, MappingType, SelectableValue, SpecialValueMatch, ValueMapping } from '@grafana/data'; import { useStyles2, Modal, ValuePicker, Button } from '@grafana/ui'; +import { ValueMappingEditRow, ValueMappingEditRowModel } from './ValueMappingEditRow'; + export interface Props { value: ValueMapping[]; onChange: (valueMappings: ValueMapping[]) => void; diff --git a/public/app/features/dimensions/resource.ts b/public/app/features/dimensions/resource.ts index f7e0d87a1ea..d48873a5740 100644 --- a/public/app/features/dimensions/resource.ts +++ b/public/app/features/dimensions/resource.ts @@ -1,4 +1,5 @@ import { DataFrame } from '@grafana/data'; + import { DimensionSupplier, ResourceDimensionConfig, ResourceDimensionMode } from './types'; import { findField, getLastNotNullFieldValue } from './utils'; diff --git a/public/app/features/dimensions/scalar.test.ts b/public/app/features/dimensions/scalar.test.ts index 3055b2cbc59..7643d090f1f 100644 --- a/public/app/features/dimensions/scalar.test.ts +++ b/public/app/features/dimensions/scalar.test.ts @@ -1,7 +1,9 @@ import { ArrayVector, DataFrame, FieldType } from '@grafana/data'; -import { ScalarDimensionMode } from '.'; + import { getScalarDimension } from './scalar'; +import { ScalarDimensionMode } from '.'; + describe('scalar dimensions', () => { it('handles string field', () => { const values = ['-720', '10', '540', '90', '-210']; diff --git a/public/app/features/dimensions/scalar.ts b/public/app/features/dimensions/scalar.ts index f5388b61c5e..377b412e5a1 100644 --- a/public/app/features/dimensions/scalar.ts +++ b/public/app/features/dimensions/scalar.ts @@ -1,4 +1,5 @@ import { DataFrame, Field } from '@grafana/data'; + import { DimensionSupplier, ScalarDimensionConfig, ScalarDimensionMode } from './types'; import { findField, getLastNotNullFieldValue } from './utils'; diff --git a/public/app/features/dimensions/scale.test.ts b/public/app/features/dimensions/scale.test.ts index 096171babee..d10d65e5875 100644 --- a/public/app/features/dimensions/scale.test.ts +++ b/public/app/features/dimensions/scale.test.ts @@ -1,4 +1,5 @@ import { ArrayVector, DataFrame, FieldType } from '@grafana/data'; + import { getScaledDimension, validateScaleConfig } from './scale'; describe('scale dimensions', () => { diff --git a/public/app/features/dimensions/scale.ts b/public/app/features/dimensions/scale.ts index 45c82c027a1..d3b06fec454 100644 --- a/public/app/features/dimensions/scale.ts +++ b/public/app/features/dimensions/scale.ts @@ -1,9 +1,12 @@ import { DataFrame, Field } from '@grafana/data'; -import { ScaleDimensionMode } from '.'; + import { getMinMaxAndDelta } from '../../../../packages/grafana-data/src/field/scale'; + import { ScaleDimensionConfig, DimensionSupplier, ScaleDimensionOptions } from './types'; import { findField, getLastNotNullFieldValue } from './utils'; +import { ScaleDimensionMode } from '.'; + //--------------------------------------------------------- // Scale dimension //--------------------------------------------------------- diff --git a/public/app/features/dimensions/text.ts b/public/app/features/dimensions/text.ts index c77d0c3e21e..5a7db09529d 100644 --- a/public/app/features/dimensions/text.ts +++ b/public/app/features/dimensions/text.ts @@ -1,4 +1,5 @@ import { DataFrame, Field, FieldType, formattedValueToString } from '@grafana/data'; + import { DimensionSupplier, TextDimensionConfig, TextDimensionMode } from './types'; import { findField, getLastNotNullFieldValue } from './utils'; diff --git a/public/app/features/dimensions/utils.ts b/public/app/features/dimensions/utils.ts index 19bc7342d64..983356ab430 100644 --- a/public/app/features/dimensions/utils.ts +++ b/public/app/features/dimensions/utils.ts @@ -1,4 +1,5 @@ import { DataFrame, PanelData, Field, getFieldDisplayName, ReducerID } from '@grafana/data'; +import { config } from '@grafana/runtime'; import { getColorDimension, getScaledDimension, @@ -11,7 +12,7 @@ import { TextDimensionConfig, ScalarDimensionConfig, } from 'app/features/dimensions'; -import { config } from '@grafana/runtime'; + import { getScalarDimension } from './scalar'; export function getColorDimensionFromData( diff --git a/public/app/features/explore/AddToDashboard/AddToDashboardModal.tsx b/public/app/features/explore/AddToDashboard/AddToDashboardModal.tsx index 3323ef01ff4..4d2366ce2b2 100644 --- a/public/app/features/explore/AddToDashboard/AddToDashboardModal.tsx +++ b/public/app/features/explore/AddToDashboard/AddToDashboardModal.tsx @@ -1,15 +1,18 @@ -import React, { useEffect, useState } from 'react'; -import { Alert, Button, Field, InputControl, Modal, RadioButtonGroup } from '@grafana/ui'; -import { locationUtil, SelectableValue } from '@grafana/data'; -import { setDashboardInLocalStorage, AddToDashboardError } from './addToDashboard'; -import { useSelector } from 'react-redux'; -import { ExploreId } from 'app/types'; -import { DashboardPicker } from 'app/core/components/Select/DashboardPicker'; -import { DeepMap, FieldError, useForm } from 'react-hook-form'; -import { config, locationService, reportInteraction } from '@grafana/runtime'; -import { getExploreItemSelector } from '../state/selectors'; import { partial } from 'lodash'; +import React, { useEffect, useState } from 'react'; +import { DeepMap, FieldError, useForm } from 'react-hook-form'; +import { useSelector } from 'react-redux'; + +import { locationUtil, SelectableValue } from '@grafana/data'; +import { config, locationService, reportInteraction } from '@grafana/runtime'; +import { Alert, Button, Field, InputControl, Modal, RadioButtonGroup } from '@grafana/ui'; +import { DashboardPicker } from 'app/core/components/Select/DashboardPicker'; import { removeDashboardToFetchFromLocalStorage } from 'app/features/dashboard/state/initDashboard'; +import { ExploreId } from 'app/types'; + +import { getExploreItemSelector } from '../state/selectors'; + +import { setDashboardInLocalStorage, AddToDashboardError } from './addToDashboard'; enum SaveTarget { NewDashboard = 'new-dashboard', diff --git a/public/app/features/explore/AddToDashboard/addToDashboard.test.ts b/public/app/features/explore/AddToDashboard/addToDashboard.test.ts index b81c7c9ca48..cc6f3c054b2 100644 --- a/public/app/features/explore/AddToDashboard/addToDashboard.test.ts +++ b/public/app/features/explore/AddToDashboard/addToDashboard.test.ts @@ -1,9 +1,11 @@ import { DataQuery, MutableDataFrame } from '@grafana/data'; -import { ExplorePanelData } from 'app/types'; -import { createEmptyQueryResponse } from '../state/utils'; -import { setDashboardInLocalStorage } from './addToDashboard'; -import * as api from 'app/features/dashboard/state/initDashboard'; import { backendSrv } from 'app/core/services/backend_srv'; +import * as api from 'app/features/dashboard/state/initDashboard'; +import { ExplorePanelData } from 'app/types'; + +import { createEmptyQueryResponse } from '../state/utils'; + +import { setDashboardInLocalStorage } from './addToDashboard'; describe('addPanelToDashboard', () => { let spy: jest.SpyInstance; diff --git a/public/app/features/explore/AddToDashboard/index.test.tsx b/public/app/features/explore/AddToDashboard/index.test.tsx index e3da2cf30e7..a4f4275ceb3 100644 --- a/public/app/features/explore/AddToDashboard/index.test.tsx +++ b/public/app/features/explore/AddToDashboard/index.test.tsx @@ -1,18 +1,22 @@ -import React, { ReactNode } from 'react'; import { act, render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import React, { ReactNode } from 'react'; +import { Provider } from 'react-redux'; + +import { DataQuery } from '@grafana/data'; +import { locationService, setEchoSrv } from '@grafana/runtime'; +import { backendSrv } from 'app/core/services/backend_srv'; +import { Echo } from 'app/core/services/echo/Echo'; +import * as initDashboard from 'app/features/dashboard/state/initDashboard'; +import { DashboardSearchItemType } from 'app/features/search/types'; import { configureStore } from 'app/store/configureStore'; import { ExploreId, ExploreState } from 'app/types'; -import { Provider } from 'react-redux'; -import { AddToDashboard } from '.'; -import * as api from './addToDashboard'; -import { locationService, setEchoSrv } from '@grafana/runtime'; -import * as initDashboard from 'app/features/dashboard/state/initDashboard'; -import { DataQuery } from '@grafana/data'; + import { createEmptyQueryResponse } from '../state/utils'; -import { backendSrv } from 'app/core/services/backend_srv'; -import { DashboardSearchItemType } from 'app/features/search/types'; -import { Echo } from 'app/core/services/echo/Echo'; + +import * as api from './addToDashboard'; + +import { AddToDashboard } from '.'; const setup = (children: ReactNode, queries: DataQuery[] = [{ refId: 'A' }]) => { const store = configureStore({ diff --git a/public/app/features/explore/AddToDashboard/index.tsx b/public/app/features/explore/AddToDashboard/index.tsx index 50d19c3e643..37cbd9a8697 100644 --- a/public/app/features/explore/AddToDashboard/index.tsx +++ b/public/app/features/explore/AddToDashboard/index.tsx @@ -1,10 +1,13 @@ import React, { useState } from 'react'; -import { ExploreId } from 'app/types'; -import { AddToDashboardModal } from './AddToDashboardModal'; -import { ToolbarButton } from '@grafana/ui'; import { useSelector } from 'react-redux'; + +import { ToolbarButton } from '@grafana/ui'; +import { ExploreId } from 'app/types'; + import { getExploreItemSelector } from '../state/selectors'; +import { AddToDashboardModal } from './AddToDashboardModal'; + interface Props { exploreId: ExploreId; } diff --git a/public/app/features/explore/ElapsedTime.tsx b/public/app/features/explore/ElapsedTime.tsx index c358a0048bf..f0eea87e29a 100644 --- a/public/app/features/explore/ElapsedTime.tsx +++ b/public/app/features/explore/ElapsedTime.tsx @@ -1,5 +1,6 @@ import React, { FC, useState, useEffect } from 'react'; import { useInterval } from 'react-use'; + import { Time, TimeProps } from './Time'; const INTERVAL = 150; diff --git a/public/app/features/explore/ErrorContainer.test.tsx b/public/app/features/explore/ErrorContainer.test.tsx index accc19c1877..a3699acc9d4 100644 --- a/public/app/features/explore/ErrorContainer.test.tsx +++ b/public/app/features/explore/ErrorContainer.test.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; +import React from 'react'; + import { ErrorContainer, ErrorContainerProps } from './ErrorContainer'; describe('ErrorContainer', () => { diff --git a/public/app/features/explore/ErrorContainer.tsx b/public/app/features/explore/ErrorContainer.tsx index fffa9c10313..9f6d6a4a320 100644 --- a/public/app/features/explore/ErrorContainer.tsx +++ b/public/app/features/explore/ErrorContainer.tsx @@ -1,4 +1,5 @@ import React, { FunctionComponent } from 'react'; + import { DataQueryError } from '@grafana/data'; import { Alert } from '@grafana/ui'; import { FadeIn } from 'app/core/components/Animations/FadeIn'; diff --git a/public/app/features/explore/Explore.test.tsx b/public/app/features/explore/Explore.test.tsx index b9ce6c9f5f7..d1c30e4d722 100644 --- a/public/app/features/explore/Explore.test.tsx +++ b/public/app/features/explore/Explore.test.tsx @@ -1,12 +1,14 @@ -import React from 'react'; -import { DataSourceApi, LoadingState, CoreApp, createTheme } from '@grafana/data'; import { render, screen } from '@testing-library/react'; +import React from 'react'; +import { Provider } from 'react-redux'; +import { AutoSizerProps } from 'react-virtualized-auto-sizer'; + +import { DataSourceApi, LoadingState, CoreApp, createTheme } from '@grafana/data'; +import { configureStore } from 'app/store/configureStore'; import { ExploreId } from 'app/types/explore'; + import { Explore, Props } from './Explore'; import { scanStopAction } from './state/query'; -import { Provider } from 'react-redux'; -import { configureStore } from 'app/store/configureStore'; -import { AutoSizerProps } from 'react-virtualized-auto-sizer'; import { createEmptyQueryResponse } from './state/utils'; const makeEmptyQueryResponse = (loadingState: LoadingState) => { diff --git a/public/app/features/explore/Explore.tsx b/public/app/features/explore/Explore.tsx index 38ec9457441..319d3801189 100644 --- a/public/app/features/explore/Explore.tsx +++ b/public/app/features/explore/Explore.tsx @@ -1,40 +1,42 @@ -import React, { createRef } from 'react'; import { css, cx } from '@emotion/css'; -import { compose } from 'redux'; +import memoizeOne from 'memoize-one'; +import React, { createRef } from 'react'; import { connect, ConnectedProps } from 'react-redux'; import AutoSizer from 'react-virtualized-auto-sizer'; -import memoizeOne from 'memoize-one'; +import { compose } from 'redux'; +import { Unsubscribable } from 'rxjs'; + +import { AbsoluteTimeRange, DataQuery, GrafanaTheme2, LoadingState, RawTimeRange } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; import { Collapse, CustomScrollbar, ErrorBoundaryAlert, Themeable2, withTheme2 } from '@grafana/ui'; -import { AbsoluteTimeRange, DataQuery, GrafanaTheme2, LoadingState, RawTimeRange } from '@grafana/data'; - -import LogsContainer from './LogsContainer'; -import { QueryRows } from './QueryRows'; -import TableContainer from './TableContainer'; -import RichHistoryContainer from './RichHistory/RichHistoryContainer'; -import ExploreQueryInspector from './ExploreQueryInspector'; -import { splitOpen } from './state/main'; -import { changeSize, changeGraphStyle } from './state/explorePane'; -import { makeAbsoluteTime, updateTimeRange } from './state/time'; -import { addQueryRow, loadLogsVolumeData, modifyQueries, scanStart, scanStopAction, setQueries } from './state/query'; -import { ExploreGraphStyle, ExploreId, ExploreItemState } from 'app/types/explore'; -import { StoreState } from 'app/types'; -import { ExploreToolbar } from './ExploreToolbar'; -import { NoDataSourceCallToAction } from './NoDataSourceCallToAction'; -import { getTimeZone } from '../profile/state/selectors'; -import { SecondaryActions } from './SecondaryActions'; import { FILTER_FOR_OPERATOR, FILTER_OUT_OPERATOR, FilterItem } from '@grafana/ui/src/components/Table/types'; -import { NodeGraphContainer } from './NodeGraphContainer'; -import { ResponseErrorContainer } from './ResponseErrorContainer'; -import { TraceViewContainer } from './TraceView/TraceViewContainer'; -import { ExploreGraph } from './ExploreGraph'; -import { LogsVolumePanel } from './LogsVolumePanel'; -import { ExploreGraphLabel } from './ExploreGraphLabel'; import appEvents from 'app/core/app_events'; -import { AbsoluteTimeEvent } from 'app/types/events'; -import { Unsubscribable } from 'rxjs'; import { getNodeGraphDataFrames } from 'app/plugins/panel/nodeGraph/utils'; +import { StoreState } from 'app/types'; +import { AbsoluteTimeEvent } from 'app/types/events'; +import { ExploreGraphStyle, ExploreId, ExploreItemState } from 'app/types/explore'; + +import { getTimeZone } from '../profile/state/selectors'; + +import { ExploreGraph } from './ExploreGraph'; +import { ExploreGraphLabel } from './ExploreGraphLabel'; +import ExploreQueryInspector from './ExploreQueryInspector'; +import { ExploreToolbar } from './ExploreToolbar'; +import LogsContainer from './LogsContainer'; +import { LogsVolumePanel } from './LogsVolumePanel'; import { NoData } from './NoData'; +import { NoDataSourceCallToAction } from './NoDataSourceCallToAction'; +import { NodeGraphContainer } from './NodeGraphContainer'; +import { QueryRows } from './QueryRows'; +import { ResponseErrorContainer } from './ResponseErrorContainer'; +import RichHistoryContainer from './RichHistory/RichHistoryContainer'; +import { SecondaryActions } from './SecondaryActions'; +import TableContainer from './TableContainer'; +import { TraceViewContainer } from './TraceView/TraceViewContainer'; +import { changeSize, changeGraphStyle } from './state/explorePane'; +import { splitOpen } from './state/main'; +import { addQueryRow, loadLogsVolumeData, modifyQueries, scanStart, scanStopAction, setQueries } from './state/query'; +import { makeAbsoluteTime, updateTimeRange } from './state/time'; const getStyles = (theme: GrafanaTheme2) => { return { diff --git a/public/app/features/explore/ExploreActions.tsx b/public/app/features/explore/ExploreActions.tsx index ac1b95e101e..95b038d4f0e 100644 --- a/public/app/features/explore/ExploreActions.tsx +++ b/public/app/features/explore/ExploreActions.tsx @@ -1,10 +1,12 @@ -import { FC, useEffect, useState } from 'react'; import { useRegisterActions, useKBar, Action, Priority } from 'kbar'; +import { FC, useEffect, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; + import { ExploreId } from 'app/types'; + import { splitOpen, splitClose } from './state/main'; -import { isSplit } from './state/selectors'; import { runQueries } from './state/query'; +import { isSplit } from './state/selectors'; interface Props { exploreIdLeft: ExploreId; diff --git a/public/app/features/explore/ExploreDrawer.tsx b/public/app/features/explore/ExploreDrawer.tsx index 222feef2dac..8220dc748d9 100644 --- a/public/app/features/explore/ExploreDrawer.tsx +++ b/public/app/features/explore/ExploreDrawer.tsx @@ -1,13 +1,13 @@ // Libraries -import React from 'react'; -import { Resizable, ResizeCallback } from 're-resizable'; import { css, cx, keyframes } from '@emotion/css'; +import { Resizable, ResizeCallback } from 're-resizable'; +import React from 'react'; // Services & Utils +import { GrafanaTheme2 } from '@grafana/data'; import { stylesFactory, useTheme2 } from '@grafana/ui'; // Types -import { GrafanaTheme2 } from '@grafana/data'; const drawerSlide = keyframes` 0% { diff --git a/public/app/features/explore/ExploreGraph.tsx b/public/app/features/explore/ExploreGraph.tsx index aaa3f9815bb..42c02f64a98 100644 --- a/public/app/features/explore/ExploreGraph.tsx +++ b/public/app/features/explore/ExploreGraph.tsx @@ -1,4 +1,8 @@ import { css, cx } from '@emotion/css'; +import { identity } from 'lodash'; +import React, { useEffect, useMemo, useRef, useState } from 'react'; +import { usePrevious } from 'react-use'; + import { AbsoluteTimeRange, applyFieldOverrides, @@ -28,12 +32,11 @@ import { import appEvents from 'app/core/app_events'; import { defaultGraphConfig, getGraphFieldConfig } from 'app/plugins/panel/timeseries/config'; import { TimeSeriesOptions } from 'app/plugins/panel/timeseries/types'; -import { identity } from 'lodash'; -import React, { useEffect, useMemo, useRef, useState } from 'react'; -import { usePrevious } from 'react-use'; -import { seriesVisibilityConfigFactory } from '../dashboard/dashgrid/SeriesVisibilityConfigFactory'; -import { applyGraphStyle } from './exploreGraphStyleUtils'; + import { ExploreGraphStyle } from '../../types'; +import { seriesVisibilityConfigFactory } from '../dashboard/dashgrid/SeriesVisibilityConfigFactory'; + +import { applyGraphStyle } from './exploreGraphStyleUtils'; const MAX_NUMBER_OF_TIME_SERIES = 20; diff --git a/public/app/features/explore/ExploreGraphLabel.tsx b/public/app/features/explore/ExploreGraphLabel.tsx index 9084e916966..6075ea08f92 100644 --- a/public/app/features/explore/ExploreGraphLabel.tsx +++ b/public/app/features/explore/ExploreGraphLabel.tsx @@ -1,7 +1,9 @@ -import React from 'react'; import { css } from '@emotion/css'; +import React from 'react'; + import { SelectableValue } from '@grafana/data'; import { RadioButtonGroup } from '@grafana/ui'; + import { EXPLORE_GRAPH_STYLES, ExploreGraphStyle } from '../../types'; const ALL_GRAPH_STYLE_OPTIONS: Array> = EXPLORE_GRAPH_STYLES.map((style) => ({ diff --git a/public/app/features/explore/ExplorePaneContainer.tsx b/public/app/features/explore/ExplorePaneContainer.tsx index e46b3c5ceea..83dd8bb028b 100644 --- a/public/app/features/explore/ExplorePaneContainer.tsx +++ b/public/app/features/explore/ExplorePaneContainer.tsx @@ -1,13 +1,10 @@ +import memoizeOne from 'memoize-one'; import React from 'react'; import { connect, ConnectedProps } from 'react-redux'; -import memoizeOne from 'memoize-one'; + import { DataQuery, ExploreUrlState, EventBusExtended, EventBusSrv } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; import store from 'app/core/store'; -import { lastSavedUrl, cleanupPaneAction } from './state/main'; -import { initializeExplore, refreshExplore } from './state/explorePane'; -import { ExploreId } from 'app/types/explore'; -import { StoreState } from 'app/types'; import { DEFAULT_RANGE, ensureQueries, @@ -16,8 +13,14 @@ import { lastUsedDatasourceKeyForOrgId, parseUrlState, } from 'app/core/utils/explore'; +import { StoreState } from 'app/types'; +import { ExploreId } from 'app/types/explore'; + import { getFiscalYearStartMonth, getTimeZone } from '../profile/state/selectors'; + import Explore from './Explore'; +import { initializeExplore, refreshExplore } from './state/explorePane'; +import { lastSavedUrl, cleanupPaneAction } from './state/main'; interface OwnProps { exploreId: ExploreId; diff --git a/public/app/features/explore/ExploreQueryInspector.test.tsx b/public/app/features/explore/ExploreQueryInspector.test.tsx index f1c39254492..49af7ff1a67 100644 --- a/public/app/features/explore/ExploreQueryInspector.test.tsx +++ b/public/app/features/explore/ExploreQueryInspector.test.tsx @@ -1,8 +1,10 @@ +import { render, screen, fireEvent } from '@testing-library/react'; import React, { ComponentProps } from 'react'; import { Observable } from 'rxjs'; -import { render, screen, fireEvent } from '@testing-library/react'; + import { TimeRange, LoadingState, InternalTimeZones } from '@grafana/data'; import { ExploreId } from 'app/types'; + import { ExploreQueryInspector } from './ExploreQueryInspector'; type ExploreQueryInspectorProps = ComponentProps; diff --git a/public/app/features/explore/ExploreQueryInspector.tsx b/public/app/features/explore/ExploreQueryInspector.tsx index bda8f197cf8..705b31227f0 100644 --- a/public/app/features/explore/ExploreQueryInspector.tsx +++ b/public/app/features/explore/ExploreQueryInspector.tsx @@ -1,15 +1,17 @@ import React from 'react'; -import { TabbedContainer, TabConfig } from '@grafana/ui'; -import { TimeZone } from '@grafana/data'; -import { runQueries } from './state/query'; -import { StoreState, ExploreItemState, ExploreId } from 'app/types'; import { connect, ConnectedProps } from 'react-redux'; + +import { TimeZone } from '@grafana/data'; +import { TabbedContainer, TabConfig } from '@grafana/ui'; import { ExploreDrawer } from 'app/features/explore/ExploreDrawer'; -import { InspectJSONTab } from 'app/features/inspector/InspectJSONTab'; -import { QueryInspector } from 'app/features/inspector/QueryInspector'; -import { InspectStatsTab } from 'app/features/inspector/InspectStatsTab'; import { InspectDataTab } from 'app/features/inspector/InspectDataTab'; import { InspectErrorTab } from 'app/features/inspector/InspectErrorTab'; +import { InspectJSONTab } from 'app/features/inspector/InspectJSONTab'; +import { InspectStatsTab } from 'app/features/inspector/InspectStatsTab'; +import { QueryInspector } from 'app/features/inspector/QueryInspector'; +import { StoreState, ExploreItemState, ExploreId } from 'app/types'; + +import { runQueries } from './state/query'; interface DispatchProps { width: number; diff --git a/public/app/features/explore/ExploreTimeControls.tsx b/public/app/features/explore/ExploreTimeControls.tsx index 2047149cc3d..aa32dbde156 100644 --- a/public/app/features/explore/ExploreTimeControls.tsx +++ b/public/app/features/explore/ExploreTimeControls.tsx @@ -1,18 +1,11 @@ -// Libaries import React, { Component } from 'react'; -// Types -import { ExploreId } from 'app/types'; import { TimeRange, TimeZone, RawTimeRange, dateTimeForTimeZone, dateMath } from '@grafana/data'; - -// State - -// Components -import { TimeSyncButton } from './TimeSyncButton'; import { TimePickerWithHistory } from 'app/core/components/TimePicker/TimePickerWithHistory'; - -// Utils & Services import { getShiftedTimeRange, getZoomedTimeRange } from 'app/core/utils/timePicker'; +import { ExploreId } from 'app/types'; + +import { TimeSyncButton } from './TimeSyncButton'; export interface Props { exploreId: ExploreId; diff --git a/public/app/features/explore/ExploreToolbar.tsx b/public/app/features/explore/ExploreToolbar.tsx index af8030b01e9..aace8efe1aa 100644 --- a/public/app/features/explore/ExploreToolbar.tsx +++ b/public/app/features/explore/ExploreToolbar.tsx @@ -1,23 +1,26 @@ import React, { lazy, PureComponent, RefObject, Suspense } from 'react'; import { connect, ConnectedProps } from 'react-redux'; -import { ExploreId } from 'app/types/explore'; -import { PageToolbar, SetInterval, ToolbarButton, ToolbarButtonRow } from '@grafana/ui'; + import { DataSourceInstanceSettings, RawTimeRange } from '@grafana/data'; import { config, DataSourcePicker } from '@grafana/runtime'; -import { StoreState } from 'app/types/store'; +import { PageToolbar, SetInterval, ToolbarButton, ToolbarButtonRow } from '@grafana/ui'; import { createAndCopyShortLink } from 'app/core/utils/shortLinks'; -import { changeDatasource } from './state/datasource'; -import { splitClose, splitOpen } from './state/main'; -import { syncTimes, changeRefreshInterval } from './state/time'; -import { getFiscalYearStartMonth, getTimeZone } from '../profile/state/selectors'; +import { ExploreId } from 'app/types/explore'; +import { StoreState } from 'app/types/store'; + +import { DashNavButton } from '../dashboard/components/DashNav/DashNavButton'; import { updateFiscalYearStartMonthForSession, updateTimeZoneForSession } from '../profile/state/reducers'; +import { getFiscalYearStartMonth, getTimeZone } from '../profile/state/selectors'; + import { ExploreTimeControls } from './ExploreTimeControls'; import { LiveTailButton } from './LiveTailButton'; import { RunButton } from './RunButton'; -import { LiveTailControls } from './useLiveTailControls'; +import { changeDatasource } from './state/datasource'; +import { splitClose, splitOpen } from './state/main'; import { cancelQueries, runQueries } from './state/query'; import { isSplit } from './state/selectors'; -import { DashNavButton } from '../dashboard/components/DashNav/DashNavButton'; +import { syncTimes, changeRefreshInterval } from './state/time'; +import { LiveTailControls } from './useLiveTailControls'; const AddToDashboard = lazy(() => import('./AddToDashboard').then(({ AddToDashboard }) => ({ default: AddToDashboard })) diff --git a/public/app/features/explore/FeatureTogglePage.tsx b/public/app/features/explore/FeatureTogglePage.tsx index 71ad80801c6..54a00691aaa 100644 --- a/public/app/features/explore/FeatureTogglePage.tsx +++ b/public/app/features/explore/FeatureTogglePage.tsx @@ -1,8 +1,9 @@ -import React from 'react'; -import Page from 'app/core/components/Page/Page'; import { css } from '@emotion/css'; -import { useStyles2 } from '@grafana/ui'; +import React from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; +import { useStyles2 } from '@grafana/ui'; +import Page from 'app/core/components/Page/Page'; export default function FeatureTogglePage() { const styles = useStyles2( diff --git a/public/app/features/explore/LiveLogs.test.tsx b/public/app/features/explore/LiveLogs.test.tsx index 7690d59f54b..901a0f0a9c7 100644 --- a/public/app/features/explore/LiveLogs.test.tsx +++ b/public/app/features/explore/LiveLogs.test.tsx @@ -1,6 +1,8 @@ -import React from 'react'; -import { LogLevel, LogRowModel, MutableDataFrame } from '@grafana/data'; import { mount } from 'enzyme'; +import React from 'react'; + +import { LogLevel, LogRowModel, MutableDataFrame } from '@grafana/data'; + import { LiveLogsWithTheme } from './LiveLogs'; describe('LiveLogs', () => { diff --git a/public/app/features/explore/LiveLogs.tsx b/public/app/features/explore/LiveLogs.tsx index b3e9f832d8f..bf07dd72aeb 100644 --- a/public/app/features/explore/LiveLogs.tsx +++ b/public/app/features/explore/LiveLogs.tsx @@ -1,9 +1,9 @@ -import React, { PureComponent } from 'react'; import { css, cx } from '@emotion/css'; +import React, { PureComponent } from 'react'; import tinycolor from 'tinycolor2'; -import { LogMessageAnsi, getLogRowStyles, Icon, Button, Themeable2, withTheme2 } from '@grafana/ui'; import { LogRowModel, TimeZone, dateTimeFormat, GrafanaTheme2 } from '@grafana/data'; +import { LogMessageAnsi, getLogRowStyles, Icon, Button, Themeable2, withTheme2 } from '@grafana/ui'; import { ElapsedTime } from './ElapsedTime'; diff --git a/public/app/features/explore/LiveTailButton.tsx b/public/app/features/explore/LiveTailButton.tsx index 6bdc8335510..304e7aad342 100644 --- a/public/app/features/explore/LiveTailButton.tsx +++ b/public/app/features/explore/LiveTailButton.tsx @@ -1,6 +1,7 @@ -import React from 'react'; import { css } from '@emotion/css'; +import React from 'react'; import { CSSTransition } from 'react-transition-group'; + import { Tooltip, ButtonGroup, ToolbarButton } from '@grafana/ui'; type LiveTailButtonProps = { diff --git a/public/app/features/explore/Logs.test.tsx b/public/app/features/explore/Logs.test.tsx index 82d32ffbb29..c63c4e909a2 100644 --- a/public/app/features/explore/Logs.test.tsx +++ b/public/app/features/explore/Logs.test.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { render, screen, fireEvent } from '@testing-library/react'; +import React from 'react'; + import { LoadingState, LogLevel, LogRowModel, MutableDataFrame, toUtc } from '@grafana/data'; import { Logs } from './Logs'; diff --git a/public/app/features/explore/Logs.tsx b/public/app/features/explore/Logs.tsx index 1d6d28b051d..6e7f1ef8e39 100644 --- a/public/app/features/explore/Logs.tsx +++ b/public/app/features/explore/Logs.tsx @@ -1,8 +1,8 @@ -import React, { PureComponent, createRef } from 'react'; import { css } from '@emotion/css'; import { capitalize } from 'lodash'; import memoizeOne from 'memoize-one'; -import { TooltipDisplayMode } from '@grafana/schema'; +import React, { PureComponent, createRef } from 'react'; + import { rangeUtil, RawTimeRange, @@ -21,6 +21,7 @@ import { GrafanaTheme2, LoadingState, } from '@grafana/data'; +import { TooltipDisplayMode } from '@grafana/schema'; import { RadioButtonGroup, LogRows, @@ -31,12 +32,13 @@ import { withTheme2, Themeable2, } from '@grafana/ui'; -import store from 'app/core/store'; +import { RowContextOptions } from '@grafana/ui/src/components/Logs/LogRowContextProvider'; import { dedupLogRows, filterLogLevels } from 'app/core/logs_model'; +import store from 'app/core/store'; + +import { ExploreGraph } from './ExploreGraph'; import { LogsMetaRow } from './LogsMetaRow'; import LogsNavigation from './LogsNavigation'; -import { RowContextOptions } from '@grafana/ui/src/components/Logs/LogRowContextProvider'; -import { ExploreGraph } from './ExploreGraph'; const SETTINGS_KEYS = { showLabels: 'grafana.explore.logs.showLabels', diff --git a/public/app/features/explore/LogsContainer.tsx b/public/app/features/explore/LogsContainer.tsx index c96caa86c79..fb27a793e0d 100644 --- a/public/app/features/explore/LogsContainer.tsx +++ b/public/app/features/explore/LogsContainer.tsx @@ -1,7 +1,7 @@ +import { css } from '@emotion/css'; import React, { PureComponent } from 'react'; import { connect, ConnectedProps } from 'react-redux'; -import { css } from '@emotion/css'; -import { Collapse } from '@grafana/ui'; + import { AbsoluteTimeRange, Field, @@ -10,16 +10,19 @@ import { LogRowModel, RawTimeRange, } from '@grafana/data'; -import { ExploreId, ExploreItemState } from 'app/types/explore'; +import { Collapse } from '@grafana/ui'; import { StoreState } from 'app/types'; +import { ExploreId, ExploreItemState } from 'app/types/explore'; + +import { getTimeZone } from '../profile/state/selectors'; + +import { LiveLogsWithTheme } from './LiveLogs'; +import { Logs } from './Logs'; import { splitOpen } from './state/main'; import { addResultsToCache, clearCache } from './state/query'; import { updateTimeRange } from './state/time'; -import { getTimeZone } from '../profile/state/selectors'; -import { LiveLogsWithTheme } from './LiveLogs'; -import { Logs } from './Logs'; -import { LogsCrossFadeTransition } from './utils/LogsCrossFadeTransition'; import { LiveTailControls } from './useLiveTailControls'; +import { LogsCrossFadeTransition } from './utils/LogsCrossFadeTransition'; import { getFieldLinksForExplore } from './utils/links'; interface LogsContainerProps extends PropsFromRedux { diff --git a/public/app/features/explore/LogsMetaRow.tsx b/public/app/features/explore/LogsMetaRow.tsx index 87aa9aba766..3f256ef0db1 100644 --- a/public/app/features/explore/LogsMetaRow.tsx +++ b/public/app/features/explore/LogsMetaRow.tsx @@ -1,7 +1,9 @@ import React from 'react'; + import { LogsDedupStrategy, LogsMetaItem, LogsMetaKind, LogRowModel } from '@grafana/data'; import { Button, Tooltip, Icon, LogLabels } from '@grafana/ui'; import { MAX_CHARACTERS } from '@grafana/ui/src/components/Logs/LogRowMessage'; + import { MetaInfoText, MetaItemProps } from './MetaInfoText'; export type Props = { diff --git a/public/app/features/explore/LogsNavigation.test.tsx b/public/app/features/explore/LogsNavigation.test.tsx index 1c78947acb2..b41f45ab25e 100644 --- a/public/app/features/explore/LogsNavigation.test.tsx +++ b/public/app/features/explore/LogsNavigation.test.tsx @@ -1,6 +1,8 @@ -import React, { ComponentProps } from 'react'; import { render, screen, fireEvent } from '@testing-library/react'; +import React, { ComponentProps } from 'react'; + import { LogsSortOrder } from '@grafana/data'; + import LogsNavigation from './LogsNavigation'; type LogsNavigationProps = ComponentProps; diff --git a/public/app/features/explore/LogsNavigation.tsx b/public/app/features/explore/LogsNavigation.tsx index 73dd0a540d9..5c2cd5a0904 100644 --- a/public/app/features/explore/LogsNavigation.tsx +++ b/public/app/features/explore/LogsNavigation.tsx @@ -1,8 +1,10 @@ -import React, { memo, useState, useEffect, useRef } from 'react'; -import { isEqual } from 'lodash'; import { css } from '@emotion/css'; +import { isEqual } from 'lodash'; +import React, { memo, useState, useEffect, useRef } from 'react'; + import { LogsSortOrder, AbsoluteTimeRange, TimeZone, DataQuery, GrafanaTheme2 } from '@grafana/data'; import { Button, Icon, Spinner, useTheme2 } from '@grafana/ui'; + import { LogsNavigationPages } from './LogsNavigationPages'; type Props = { diff --git a/public/app/features/explore/LogsNavigationPages.test.tsx b/public/app/features/explore/LogsNavigationPages.test.tsx index 9b1b7790326..6320bb1d78b 100644 --- a/public/app/features/explore/LogsNavigationPages.test.tsx +++ b/public/app/features/explore/LogsNavigationPages.test.tsx @@ -1,5 +1,6 @@ -import React, { ComponentProps } from 'react'; import { render, screen } from '@testing-library/react'; +import React, { ComponentProps } from 'react'; + import { LogsNavigationPages } from './LogsNavigationPages'; type LogsNavigationPagesProps = ComponentProps; diff --git a/public/app/features/explore/LogsNavigationPages.tsx b/public/app/features/explore/LogsNavigationPages.tsx index 16f92cb9d47..a5c978b0d8c 100644 --- a/public/app/features/explore/LogsNavigationPages.tsx +++ b/public/app/features/explore/LogsNavigationPages.tsx @@ -1,7 +1,9 @@ -import React from 'react'; import { css, cx } from '@emotion/css'; +import React from 'react'; + import { dateTimeFormat, systemDateFormats, TimeZone, AbsoluteTimeRange, GrafanaTheme2 } from '@grafana/data'; import { CustomScrollbar, Spinner, useTheme2 } from '@grafana/ui'; + import { LogsPage } from './LogsNavigation'; type Props = { diff --git a/public/app/features/explore/LogsVolumePanel.test.tsx b/public/app/features/explore/LogsVolumePanel.test.tsx index 251097f2221..b42b3c37d1b 100644 --- a/public/app/features/explore/LogsVolumePanel.test.tsx +++ b/public/app/features/explore/LogsVolumePanel.test.tsx @@ -1,8 +1,10 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; -import { LogsVolumePanel } from './LogsVolumePanel'; +import React from 'react'; + import { DataQueryResponse, LoadingState } from '@grafana/data'; +import { LogsVolumePanel } from './LogsVolumePanel'; + jest.mock('./ExploreGraph', () => { const ExploreGraph = () => ExploreGraph; return { diff --git a/public/app/features/explore/LogsVolumePanel.tsx b/public/app/features/explore/LogsVolumePanel.tsx index 806e0c7dbca..08e6fb47039 100644 --- a/public/app/features/explore/LogsVolumePanel.tsx +++ b/public/app/features/explore/LogsVolumePanel.tsx @@ -1,8 +1,10 @@ +import { css } from '@emotion/css'; +import React, { useState } from 'react'; + import { AbsoluteTimeRange, DataQueryError, DataQueryResponse, LoadingState, SplitOpen, TimeZone } from '@grafana/data'; import { Alert, Button, Collapse, InlineField, TooltipDisplayMode, useStyles2, useTheme2 } from '@grafana/ui'; + import { ExploreGraph } from './ExploreGraph'; -import React, { useState } from 'react'; -import { css } from '@emotion/css'; type Props = { logsVolumeData?: DataQueryResponse; diff --git a/public/app/features/explore/MetaInfoText.test.tsx b/public/app/features/explore/MetaInfoText.test.tsx index c1d7e316eef..53edd865cd1 100644 --- a/public/app/features/explore/MetaInfoText.test.tsx +++ b/public/app/features/explore/MetaInfoText.test.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; +import React from 'react'; + import { MetaInfoText, MetaItemProps } from './MetaInfoText'; describe('MetaInfoText', () => { it('should render component and items', () => { diff --git a/public/app/features/explore/MetaInfoText.tsx b/public/app/features/explore/MetaInfoText.tsx index dbdd234e1b4..d57baadd88f 100644 --- a/public/app/features/explore/MetaInfoText.tsx +++ b/public/app/features/explore/MetaInfoText.tsx @@ -1,5 +1,6 @@ -import React, { memo } from 'react'; import { css } from '@emotion/css'; +import React, { memo } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { useStyles2 } from '@grafana/ui'; diff --git a/public/app/features/explore/NoData.tsx b/public/app/features/explore/NoData.tsx index d50330747f6..791505c6a57 100644 --- a/public/app/features/explore/NoData.tsx +++ b/public/app/features/explore/NoData.tsx @@ -1,9 +1,8 @@ -import React from 'react'; import { css, cx } from '@emotion/css'; - -import { useStyles2 } from '@grafana/ui'; +import React from 'react'; import { GrafanaTheme2 } from '@grafana/data/src'; +import { useStyles2 } from '@grafana/ui'; export const NoData = () => { const css = useStyles2(getStyles); diff --git a/public/app/features/explore/NoDataSourceCallToAction.tsx b/public/app/features/explore/NoDataSourceCallToAction.tsx index d2d61d3936f..f898ec5808b 100644 --- a/public/app/features/explore/NoDataSourceCallToAction.tsx +++ b/public/app/features/explore/NoDataSourceCallToAction.tsx @@ -1,7 +1,7 @@ -import React from 'react'; import { css } from '@emotion/css'; -import { LinkButton, CallToActionCard, Icon, useTheme2 } from '@grafana/ui'; +import React from 'react'; +import { LinkButton, CallToActionCard, Icon, useTheme2 } from '@grafana/ui'; import { contextSrv } from 'app/core/core'; import { AccessControlAction } from 'app/types'; diff --git a/public/app/features/explore/NodeGraphContainer.test.tsx b/public/app/features/explore/NodeGraphContainer.test.tsx index 2560771fd8d..f05619fe848 100644 --- a/public/app/features/explore/NodeGraphContainer.test.tsx +++ b/public/app/features/explore/NodeGraphContainer.test.tsx @@ -1,9 +1,12 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; -import { UnconnectedNodeGraphContainer } from './NodeGraphContainer'; +import React from 'react'; + import { getDefaultTimeRange, MutableDataFrame } from '@grafana/data'; + import { ExploreId } from '../../types'; +import { UnconnectedNodeGraphContainer } from './NodeGraphContainer'; + describe('NodeGraphContainer', () => { it('is collapsed if shown with traces', () => { const { container } = render( diff --git a/public/app/features/explore/NodeGraphContainer.tsx b/public/app/features/explore/NodeGraphContainer.tsx index e98a2edc346..65d17d11555 100644 --- a/public/app/features/explore/NodeGraphContainer.tsx +++ b/public/app/features/explore/NodeGraphContainer.tsx @@ -1,14 +1,17 @@ -import React from 'react'; -import { useToggle } from 'react-use'; -import { Badge, Collapse, useStyles2, useTheme2 } from '@grafana/ui'; -import { applyFieldOverrides, DataFrame, GrafanaTheme2 } from '@grafana/data'; import { css } from '@emotion/css'; -import { ExploreId, StoreState } from '../../types'; -import { splitOpen } from './state/main'; +import React from 'react'; import { connect, ConnectedProps } from 'react-redux'; -import { useLinks } from './utils/links'; +import { useToggle } from 'react-use'; + +import { applyFieldOverrides, DataFrame, GrafanaTheme2 } from '@grafana/data'; +import { Badge, Collapse, useStyles2, useTheme2 } from '@grafana/ui'; + import { NodeGraph } from '../../plugins/panel/nodeGraph'; import { useCategorizeFrames } from '../../plugins/panel/nodeGraph/useCategorizeFrames'; +import { ExploreId, StoreState } from '../../types'; + +import { splitOpen } from './state/main'; +import { useLinks } from './utils/links'; const getStyles = (theme: GrafanaTheme2) => ({ warningText: css` diff --git a/public/app/features/explore/QueryRows.test.tsx b/public/app/features/explore/QueryRows.test.tsx index 52459dc942a..3c1b791994d 100644 --- a/public/app/features/explore/QueryRows.test.tsx +++ b/public/app/features/explore/QueryRows.test.tsx @@ -1,13 +1,16 @@ -import React from 'react'; import { fireEvent, render, screen } from '@testing-library/react'; -import { configureStore } from 'app/store/configureStore'; +import React from 'react'; import { Provider } from 'react-redux'; -import { QueryRows } from './QueryRows'; -import { ExploreId, ExploreState } from 'app/types'; -import { makeExplorePaneState } from './state/utils'; + import { setDataSourceSrv } from '@grafana/runtime'; -import { UserState } from '../profile/state/reducers'; +import { configureStore } from 'app/store/configureStore'; +import { ExploreId, ExploreState } from 'app/types'; + import { DataQuery } from '../../../../packages/grafana-data/src'; +import { UserState } from '../profile/state/reducers'; + +import { QueryRows } from './QueryRows'; +import { makeExplorePaneState } from './state/utils'; function setup(queries: DataQuery[]) { const defaultDs = { diff --git a/public/app/features/explore/QueryRows.tsx b/public/app/features/explore/QueryRows.tsx index 82cec7ff84e..b8453016478 100644 --- a/public/app/features/explore/QueryRows.tsx +++ b/public/app/features/explore/QueryRows.tsx @@ -1,12 +1,15 @@ +import { createSelector } from '@reduxjs/toolkit'; import React, { useCallback, useMemo } from 'react'; -import { ExploreId } from 'app/types/explore'; import { useDispatch, useSelector } from 'react-redux'; -import { getDatasourceSrv } from '../plugins/datasource_srv'; -import { runQueries, changeQueriesAction } from './state/query'; + import { CoreApp, DataQuery } from '@grafana/data'; import { getNextRefIdChar } from 'app/core/utils/query'; +import { ExploreId } from 'app/types/explore'; + +import { getDatasourceSrv } from '../plugins/datasource_srv'; import { QueryEditorRows } from '../query/components/QueryEditorRows'; -import { createSelector } from '@reduxjs/toolkit'; + +import { runQueries, changeQueriesAction } from './state/query'; import { getExploreItemSelector } from './state/selectors'; interface Props { diff --git a/public/app/features/explore/ResponseErrorContainer.test.tsx b/public/app/features/explore/ResponseErrorContainer.test.tsx index 387dc9ee937..b59782f4bb3 100644 --- a/public/app/features/explore/ResponseErrorContainer.test.tsx +++ b/public/app/features/explore/ResponseErrorContainer.test.tsx @@ -1,13 +1,15 @@ +import { render, screen } from '@testing-library/react'; import React from 'react'; import { Provider } from 'react-redux'; -import { render, screen } from '@testing-library/react'; + import { DataQueryError, LoadingState } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; import { configureStore } from '../../store/configureStore'; -import { ResponseErrorContainer } from './ResponseErrorContainer'; import { ExploreId } from '../../types'; +import { ResponseErrorContainer } from './ResponseErrorContainer'; + describe('ResponseErrorContainer', () => { it('shows error message if it does not contain refId', async () => { const errorMessage = 'test error'; diff --git a/public/app/features/explore/ResponseErrorContainer.tsx b/public/app/features/explore/ResponseErrorContainer.tsx index 5dd5f59f154..667187d2600 100644 --- a/public/app/features/explore/ResponseErrorContainer.tsx +++ b/public/app/features/explore/ResponseErrorContainer.tsx @@ -1,7 +1,10 @@ import React from 'react'; import { useSelector } from 'react-redux'; -import { ExploreId, StoreState } from '../../types'; + import { LoadingState } from '@grafana/data'; + +import { ExploreId, StoreState } from '../../types'; + import { ErrorContainer } from './ErrorContainer'; interface Props { diff --git a/public/app/features/explore/RichHistory/RichHistory.test.tsx b/public/app/features/explore/RichHistory/RichHistory.test.tsx index b588e6f3362..7ca79656a8c 100644 --- a/public/app/features/explore/RichHistory/RichHistory.test.tsx +++ b/public/app/features/explore/RichHistory/RichHistory.test.tsx @@ -1,9 +1,12 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; +import React from 'react'; + import { GrafanaTheme } from '@grafana/data'; -import { ExploreId } from '../../../types/explore'; -import { RichHistory, RichHistoryProps, Tabs } from './RichHistory'; + import { SortOrder } from '../../../core/utils/richHistoryTypes'; +import { ExploreId } from '../../../types/explore'; + +import { RichHistory, RichHistoryProps, Tabs } from './RichHistory'; jest.mock('../state/selectors', () => ({ getExploreDatasources: jest.fn() })); diff --git a/public/app/features/explore/RichHistory/RichHistory.tsx b/public/app/features/explore/RichHistory/RichHistory.tsx index 893a17ca796..3a72d1401bc 100644 --- a/public/app/features/explore/RichHistory/RichHistory.tsx +++ b/public/app/features/explore/RichHistory/RichHistory.tsx @@ -1,19 +1,16 @@ import React, { PureComponent } from 'react'; -//Services & Utils -import { SortOrder } from 'app/core/utils/richHistory'; -import { Themeable, withTheme, TabbedContainer, TabConfig } from '@grafana/ui'; - -//Types -import { RichHistoryQuery, ExploreId } from 'app/types/explore'; import { SelectableValue } from '@grafana/data'; +import { Themeable, withTheme, TabbedContainer, TabConfig } from '@grafana/ui'; +import { SortOrder } from 'app/core/utils/richHistory'; +import { RichHistoryQuery, ExploreId } from 'app/types/explore'; -//Components -import { RichHistorySettingsTab } from './RichHistorySettingsTab'; -import { RichHistoryQueriesTab } from './RichHistoryQueriesTab'; -import { RichHistoryStarredTab } from './RichHistoryStarredTab'; import { RichHistorySearchFilters, RichHistorySettings } from '../../../core/utils/richHistoryTypes'; +import { RichHistoryQueriesTab } from './RichHistoryQueriesTab'; +import { RichHistorySettingsTab } from './RichHistorySettingsTab'; +import { RichHistoryStarredTab } from './RichHistoryStarredTab'; + export enum Tabs { RichHistory = 'Query history', Starred = 'Starred', diff --git a/public/app/features/explore/RichHistory/RichHistoryCard.test.tsx b/public/app/features/explore/RichHistory/RichHistoryCard.test.tsx index 6b2a36efb64..83b73403dc8 100644 --- a/public/app/features/explore/RichHistory/RichHistoryCard.test.tsx +++ b/public/app/features/explore/RichHistory/RichHistoryCard.test.tsx @@ -1,12 +1,14 @@ -import React from 'react'; import { render, screen, fireEvent, getByText } from '@testing-library/react'; -import { RichHistoryCard, Props } from './RichHistoryCard'; -import { ExploreId, RichHistoryQuery } from 'app/types/explore'; +import React from 'react'; + import { DataSourceApi, DataQuery } from '@grafana/data'; +import appEvents from 'app/core/app_events'; import { mockDataSource } from 'app/features/alerting/unified/mocks'; import { DataSourceType } from 'app/features/alerting/unified/utils/datasource'; import { ShowConfirmModalEvent } from 'app/types/events'; -import appEvents from 'app/core/app_events'; +import { ExploreId, RichHistoryQuery } from 'app/types/explore'; + +import { RichHistoryCard, Props } from './RichHistoryCard'; const starRichHistoryMock = jest.fn(); const deleteRichHistoryMock = jest.fn(); diff --git a/public/app/features/explore/RichHistory/RichHistoryCard.tsx b/public/app/features/explore/RichHistory/RichHistoryCard.tsx index 61120641229..850c46f9ee8 100644 --- a/public/app/features/explore/RichHistory/RichHistoryCard.tsx +++ b/public/app/features/explore/RichHistory/RichHistoryCard.tsx @@ -1,23 +1,24 @@ +import { css, cx } from '@emotion/css'; import React, { useState, useEffect } from 'react'; import { connect, ConnectedProps } from 'react-redux'; -import { css, cx } from '@emotion/css'; -import { stylesFactory, useTheme, TextArea, Button, IconButton } from '@grafana/ui'; -import { getDataSourceSrv } from '@grafana/runtime'; + import { GrafanaTheme, DataSourceApi, DataQuery } from '@grafana/data'; -import { RichHistoryQuery, ExploreId } from 'app/types/explore'; +import { getDataSourceSrv } from '@grafana/runtime'; +import { stylesFactory, useTheme, TextArea, Button, IconButton } from '@grafana/ui'; +import { notifyApp } from 'app/core/actions'; +import appEvents from 'app/core/app_events'; +import { createSuccessNotification } from 'app/core/copy/appNotification'; +import { copyStringToClipboard } from 'app/core/utils/explore'; import { createUrlFromRichHistory, createQueryText } from 'app/core/utils/richHistory'; import { createAndCopyShortLink } from 'app/core/utils/shortLinks'; -import { copyStringToClipboard } from 'app/core/utils/explore'; -import appEvents from 'app/core/app_events'; import { dispatch } from 'app/store/store'; -import { notifyApp } from 'app/core/actions'; -import { createSuccessNotification } from 'app/core/copy/appNotification'; import { StoreState } from 'app/types'; +import { RichHistoryQuery, ExploreId } from 'app/types/explore'; -import { starHistoryItem, commentHistoryItem, deleteHistoryItem } from '../state/history'; -import { changeDatasource } from '../state/datasource'; -import { setQueries } from '../state/query'; import { ShowConfirmModalEvent } from '../../../types/events'; +import { changeDatasource } from '../state/datasource'; +import { starHistoryItem, commentHistoryItem, deleteHistoryItem } from '../state/history'; +import { setQueries } from '../state/query'; function mapStateToProps(state: StoreState, { exploreId }: { exploreId: ExploreId }) { const explore = state.explore; diff --git a/public/app/features/explore/RichHistory/RichHistoryContainer.test.tsx b/public/app/features/explore/RichHistory/RichHistoryContainer.test.tsx index 59533a30ac1..bdd07b4d6a5 100644 --- a/public/app/features/explore/RichHistory/RichHistoryContainer.test.tsx +++ b/public/app/features/explore/RichHistory/RichHistoryContainer.test.tsx @@ -1,10 +1,11 @@ -import React from 'react'; import { render } from '@testing-library/react'; +import React from 'react'; -import { ExploreId } from '../../../types/explore'; -import { RichHistoryContainer, Props } from './RichHistoryContainer'; -import { Tabs } from './RichHistory'; import { SortOrder } from '../../../core/utils/richHistoryTypes'; +import { ExploreId } from '../../../types/explore'; + +import { Tabs } from './RichHistory'; +import { RichHistoryContainer, Props } from './RichHistoryContainer'; jest.mock('../state/selectors', () => ({ getExploreDatasources: jest.fn() })); diff --git a/public/app/features/explore/RichHistory/RichHistoryContainer.tsx b/public/app/features/explore/RichHistory/RichHistoryContainer.tsx index 93f03298c10..0824dae0aac 100644 --- a/public/app/features/explore/RichHistory/RichHistoryContainer.tsx +++ b/public/app/features/explore/RichHistory/RichHistoryContainer.tsx @@ -7,16 +7,17 @@ import { ExploreItemState, StoreState } from 'app/types'; import { ExploreId } from 'app/types/explore'; // Components, enums -import { RichHistory, Tabs } from './RichHistory'; - -//Actions +import { ExploreDrawer } from '../ExploreDrawer'; import { deleteRichHistory, initRichHistory, updateHistorySettings, updateHistorySearchFilters, } from '../state/history'; -import { ExploreDrawer } from '../ExploreDrawer'; + +import { RichHistory, Tabs } from './RichHistory'; + +//Actions function mapStateToProps(state: StoreState, { exploreId }: { exploreId: ExploreId }) { const explore = state.explore; diff --git a/public/app/features/explore/RichHistory/RichHistoryQueriesTab.tsx b/public/app/features/explore/RichHistory/RichHistoryQueriesTab.tsx index aa410be7004..bf139dceb12 100644 --- a/public/app/features/explore/RichHistory/RichHistoryQueriesTab.tsx +++ b/public/app/features/explore/RichHistory/RichHistoryQueriesTab.tsx @@ -1,14 +1,10 @@ -import React, { useState, useEffect } from 'react'; import { css } from '@emotion/css'; import { uniqBy } from 'lodash'; +import React, { useState, useEffect } from 'react'; +import { useDebounce } from 'react-use'; -// Types -import { RichHistoryQuery, ExploreId } from 'app/types/explore'; - -// Utils -import { stylesFactory, useTheme, RangeSlider, MultiSelect, Select, FilterInput } from '@grafana/ui'; import { GrafanaTheme, SelectableValue } from '@grafana/data'; - +import { stylesFactory, useTheme, RangeSlider, MultiSelect, Select, FilterInput } from '@grafana/ui'; import { SortOrder, mapNumbertoTimeInSlider, @@ -16,11 +12,10 @@ import { createDatasourcesList, filterAndSortQueries, } from 'app/core/utils/richHistory'; +import { RichHistoryQuery, ExploreId } from 'app/types/explore'; -// Components -import RichHistoryCard from './RichHistoryCard'; import { sortOrderOptions } from './RichHistory'; -import { useDebounce } from 'react-use'; +import RichHistoryCard from './RichHistoryCard'; export interface Props { queries: RichHistoryQuery[]; diff --git a/public/app/features/explore/RichHistory/RichHistorySettingsTab.test.tsx b/public/app/features/explore/RichHistory/RichHistorySettingsTab.test.tsx index fe6780cb286..3d69a6beb8d 100644 --- a/public/app/features/explore/RichHistory/RichHistorySettingsTab.test.tsx +++ b/public/app/features/explore/RichHistory/RichHistorySettingsTab.test.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; +import React from 'react'; + import { RichHistorySettingsTab, RichHistorySettingsProps } from './RichHistorySettingsTab'; const setup = (propOverrides?: Partial) => { diff --git a/public/app/features/explore/RichHistory/RichHistorySettingsTab.tsx b/public/app/features/explore/RichHistory/RichHistorySettingsTab.tsx index e482dfadc74..e5d76d64de1 100644 --- a/public/app/features/explore/RichHistory/RichHistorySettingsTab.tsx +++ b/public/app/features/explore/RichHistory/RichHistorySettingsTab.tsx @@ -1,13 +1,15 @@ -import React from 'react'; import { css } from '@emotion/css'; -import { stylesFactory, useTheme, Select, Button, Field, InlineField, InlineSwitch } from '@grafana/ui'; +import React from 'react'; + import { GrafanaTheme, SelectableValue } from '@grafana/data'; -import appEvents from 'app/core/app_events'; -import { ShowConfirmModalEvent } from '../../../types/events'; -import { dispatch } from 'app/store/store'; +import { stylesFactory, useTheme, Select, Button, Field, InlineField, InlineSwitch } from '@grafana/ui'; import { notifyApp } from 'app/core/actions'; +import appEvents from 'app/core/app_events'; import { createSuccessNotification } from 'app/core/copy/appNotification'; import { MAX_HISTORY_ITEMS } from 'app/core/history/RichHistoryLocalStorage'; +import { dispatch } from 'app/store/store'; + +import { ShowConfirmModalEvent } from '../../../types/events'; export interface RichHistorySettingsProps { retentionPeriod: number; diff --git a/public/app/features/explore/RichHistory/RichHistoryStarredTab.test.tsx b/public/app/features/explore/RichHistory/RichHistoryStarredTab.test.tsx index fa40adb5a43..f5ea74e9239 100644 --- a/public/app/features/explore/RichHistory/RichHistoryStarredTab.test.tsx +++ b/public/app/features/explore/RichHistory/RichHistoryStarredTab.test.tsx @@ -1,7 +1,10 @@ -import React from 'react'; import { mount } from 'enzyme'; -import { ExploreId } from '../../../types/explore'; +import React from 'react'; + import { SortOrder } from 'app/core/utils/richHistory'; + +import { ExploreId } from '../../../types/explore'; + import { RichHistoryStarredTab, Props } from './RichHistoryStarredTab'; jest.mock('../state/selectors', () => ({ getExploreDatasources: jest.fn() })); diff --git a/public/app/features/explore/RichHistory/RichHistoryStarredTab.tsx b/public/app/features/explore/RichHistory/RichHistoryStarredTab.tsx index cbe7915f791..b7ba7ffebbc 100644 --- a/public/app/features/explore/RichHistory/RichHistoryStarredTab.tsx +++ b/public/app/features/explore/RichHistory/RichHistoryStarredTab.tsx @@ -1,19 +1,15 @@ -import React, { useState, useEffect } from 'react'; import { css } from '@emotion/css'; import { uniqBy } from 'lodash'; +import React, { useState, useEffect } from 'react'; +import { useDebounce } from 'react-use'; -// Types +import { GrafanaTheme, SelectableValue } from '@grafana/data'; +import { stylesFactory, useTheme, Select, MultiSelect, FilterInput } from '@grafana/ui'; +import { filterAndSortQueries, createDatasourcesList, SortOrder } from 'app/core/utils/richHistory'; import { RichHistoryQuery, ExploreId } from 'app/types/explore'; -// Utils -import { stylesFactory, useTheme, Select, MultiSelect, FilterInput } from '@grafana/ui'; -import { GrafanaTheme, SelectableValue } from '@grafana/data'; -import { filterAndSortQueries, createDatasourcesList, SortOrder } from 'app/core/utils/richHistory'; - -// Components -import RichHistoryCard from './RichHistoryCard'; import { sortOrderOptions } from './RichHistory'; -import { useDebounce } from 'react-use'; +import RichHistoryCard from './RichHistoryCard'; export interface Props { queries: RichHistoryQuery[]; diff --git a/public/app/features/explore/RunButton.test.tsx b/public/app/features/explore/RunButton.test.tsx index dc0c3190d23..1edfe706ee3 100644 --- a/public/app/features/explore/RunButton.test.tsx +++ b/public/app/features/explore/RunButton.test.tsx @@ -1,9 +1,11 @@ -import React from 'react'; -import { RunButton, Props } from './RunButton'; -import { RefreshPicker } from '@grafana/ui'; import { shallow } from 'enzyme'; +import React from 'react'; + +import { RefreshPicker } from '@grafana/ui'; import { getTimeSrv, TimeSrv } from 'app/features/dashboard/services/TimeSrv'; +import { RunButton, Props } from './RunButton'; + const setup = (propOverrides?: object) => { const props: Props = { isSmall: false, diff --git a/public/app/features/explore/RunButton.tsx b/public/app/features/explore/RunButton.tsx index 15307463d07..96a48506027 100644 --- a/public/app/features/explore/RunButton.tsx +++ b/public/app/features/explore/RunButton.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { RefreshPicker, defaultIntervals } from '@grafana/ui'; import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv'; diff --git a/public/app/features/explore/SecondaryActions.test.tsx b/public/app/features/explore/SecondaryActions.test.tsx index 6b55113f6d8..fb9c32e34c9 100644 --- a/public/app/features/explore/SecondaryActions.test.tsx +++ b/public/app/features/explore/SecondaryActions.test.tsx @@ -1,6 +1,7 @@ -import React from 'react'; -import { noop } from 'lodash'; import { shallow } from 'enzyme'; +import { noop } from 'lodash'; +import React from 'react'; + import { SecondaryActions } from './SecondaryActions'; const addQueryRowButtonSelector = '[aria-label="Add row button"]'; diff --git a/public/app/features/explore/SecondaryActions.tsx b/public/app/features/explore/SecondaryActions.tsx index 4f56f8c8b4e..b18ccd78349 100644 --- a/public/app/features/explore/SecondaryActions.tsx +++ b/public/app/features/explore/SecondaryActions.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { css, cx } from '@emotion/css'; +import React from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { Button, HorizontalGroup, useTheme2 } from '@grafana/ui'; diff --git a/public/app/features/explore/TableContainer.test.tsx b/public/app/features/explore/TableContainer.test.tsx index 471abc061d1..5e4c8097c76 100644 --- a/public/app/features/explore/TableContainer.test.tsx +++ b/public/app/features/explore/TableContainer.test.tsx @@ -1,9 +1,11 @@ -import React from 'react'; import { screen, render, within } from '@testing-library/react'; -import { TableContainer } from './TableContainer'; +import React from 'react'; + import { DataFrame, toDataFrame, FieldType, InternalTimeZones } from '@grafana/data'; import { ExploreId } from 'app/types/explore'; +import { TableContainer } from './TableContainer'; + function getTable(): HTMLElement { return screen.getAllByRole('table')[0]; } diff --git a/public/app/features/explore/TableContainer.tsx b/public/app/features/explore/TableContainer.tsx index ccdf5e3a75f..a31f1bdb2f9 100644 --- a/public/app/features/explore/TableContainer.tsx +++ b/public/app/features/explore/TableContainer.tsx @@ -1,14 +1,16 @@ import React, { PureComponent } from 'react'; import { connect, ConnectedProps } from 'react-redux'; + import { ValueLinkConfig, applyFieldOverrides, TimeZone } from '@grafana/data'; import { Collapse, Table } from '@grafana/ui'; -import { ExploreId, ExploreItemState } from 'app/types/explore'; -import { StoreState } from 'app/types'; -import { splitOpen } from './state/main'; +import { FilterItem } from '@grafana/ui/src/components/Table/types'; import { config } from 'app/core/config'; import { PANEL_BORDER } from 'app/core/constants'; +import { StoreState } from 'app/types'; +import { ExploreId, ExploreItemState } from 'app/types/explore'; + import { MetaInfoText } from './MetaInfoText'; -import { FilterItem } from '@grafana/ui/src/components/Table/types'; +import { splitOpen } from './state/main'; import { getFieldLinksForExplore } from './utils/links'; interface TableContainerProps { diff --git a/public/app/features/explore/Time.tsx b/public/app/features/explore/Time.tsx index 01033176f9a..c5692f1a0dd 100644 --- a/public/app/features/explore/Time.tsx +++ b/public/app/features/explore/Time.tsx @@ -1,4 +1,5 @@ import React, { FC } from 'react'; + import { toDuration } from '@grafana/data'; export interface TimeProps { diff --git a/public/app/features/explore/TimeSyncButton.test.tsx b/public/app/features/explore/TimeSyncButton.test.tsx index afa744155b9..653b675f195 100644 --- a/public/app/features/explore/TimeSyncButton.test.tsx +++ b/public/app/features/explore/TimeSyncButton.test.tsx @@ -1,6 +1,7 @@ -import React from 'react'; -import { TimeSyncButton } from './TimeSyncButton'; import { mount } from 'enzyme'; +import React from 'react'; + +import { TimeSyncButton } from './TimeSyncButton'; const setup = (isSynced: boolean) => { const onClick = () => {}; diff --git a/public/app/features/explore/TimeSyncButton.tsx b/public/app/features/explore/TimeSyncButton.tsx index 87cfe5bc4f4..7745eccf140 100644 --- a/public/app/features/explore/TimeSyncButton.tsx +++ b/public/app/features/explore/TimeSyncButton.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { Tooltip, ToolbarButton } from '@grafana/ui'; interface TimeSyncButtonProps { diff --git a/public/app/features/explore/TraceView/TraceView.test.tsx b/public/app/features/explore/TraceView/TraceView.test.tsx index 82718889de6..97a7cfa1655 100644 --- a/public/app/features/explore/TraceView/TraceView.test.tsx +++ b/public/app/features/explore/TraceView/TraceView.test.tsx @@ -1,14 +1,17 @@ -import React from 'react'; +import { TraceData, TraceSpanData } from '@jaegertracing/jaeger-ui-components/src/types/trace'; import { render, prettyDOM, screen } from '@testing-library/react'; -import { TraceView } from './TraceView'; +import userEvent from '@testing-library/user-event'; +import React from 'react'; +import { Provider } from 'react-redux'; + +import { DataFrame, MutableDataFrame, getDefaultTimeRange, LoadingState } from '@grafana/data'; import { setDataSourceSrv } from '@grafana/runtime'; import { ExploreId } from 'app/types'; -import { TraceData, TraceSpanData } from '@jaegertracing/jaeger-ui-components/src/types/trace'; -import { DataFrame, MutableDataFrame, getDefaultTimeRange, LoadingState } from '@grafana/data'; + import { configureStore } from '../../../store/configureStore'; -import { Provider } from 'react-redux'; + +import { TraceView } from './TraceView'; import { transformDataFrames } from './utils/transform'; -import userEvent from '@testing-library/user-event'; function getTraceView(frames: DataFrame[]) { const store = configureStore(); diff --git a/public/app/features/explore/TraceView/TraceView.tsx b/public/app/features/explore/TraceView/TraceView.tsx index cfb3b61ccfa..ff2e2bb5dee 100644 --- a/public/app/features/explore/TraceView/TraceView.tsx +++ b/public/app/features/explore/TraceView/TraceView.tsx @@ -1,3 +1,6 @@ +import React, { RefObject, useCallback, useEffect, useMemo, useState } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; + import { DataFrame, DataLink, @@ -22,9 +25,9 @@ import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; import { getTimeZone } from 'app/features/profile/state/selectors'; import { StoreState } from 'app/types'; import { ExploreId } from 'app/types/explore'; -import React, { RefObject, useCallback, useEffect, useMemo, useState } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; + import { changePanelState } from '../state/explorePane'; + import { createSpanLinkFactory } from './createSpanLink'; import { useDetailState } from './useDetailState'; import { useHoverIndentGuide } from './useHoverIndentGuide'; diff --git a/public/app/features/explore/TraceView/TraceViewContainer.test.tsx b/public/app/features/explore/TraceView/TraceViewContainer.test.tsx index f9ef0719237..89ee235f4c8 100644 --- a/public/app/features/explore/TraceView/TraceViewContainer.test.tsx +++ b/public/app/features/explore/TraceView/TraceViewContainer.test.tsx @@ -1,12 +1,15 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; -import { TraceViewContainer } from './TraceViewContainer'; -import { frameOld } from './TraceView.test'; -import { ExploreId } from 'app/types'; -import { configureStore } from '../../../store/configureStore'; -import { getDefaultTimeRange, LoadingState } from '@grafana/data'; -import { Provider } from 'react-redux'; import userEvent from '@testing-library/user-event'; +import React from 'react'; +import { Provider } from 'react-redux'; + +import { getDefaultTimeRange, LoadingState } from '@grafana/data'; +import { ExploreId } from 'app/types'; + +import { configureStore } from '../../../store/configureStore'; + +import { frameOld } from './TraceView.test'; +import { TraceViewContainer } from './TraceViewContainer'; function renderTraceViewContainer(frames = [frameOld]) { const store = configureStore(); diff --git a/public/app/features/explore/TraceView/TraceViewContainer.tsx b/public/app/features/explore/TraceView/TraceViewContainer.tsx index 80abebf309c..e5bd747f68b 100644 --- a/public/app/features/explore/TraceView/TraceViewContainer.tsx +++ b/public/app/features/explore/TraceView/TraceViewContainer.tsx @@ -1,12 +1,14 @@ -import React, { RefObject, useMemo, useState } from 'react'; -import { Collapse } from '@grafana/ui'; -import { DataFrame, SplitOpen, PanelData } from '@grafana/data'; -import { TraceView } from './TraceView'; -import { ExploreId } from 'app/types/explore'; import TracePageSearchBar from '@jaegertracing/jaeger-ui-components/src/TracePageHeader/TracePageSearchBar'; +import React, { RefObject, useMemo, useState } from 'react'; + +import { DataFrame, SplitOpen, PanelData } from '@grafana/data'; +import { Collapse } from '@grafana/ui'; +import { ExploreId } from 'app/types/explore'; + +import { TraceView } from './TraceView'; +import { useChildrenState } from './useChildrenState'; import { useSearch } from './useSearch'; import { transformDataFrames } from './utils/transform'; -import { useChildrenState } from './useChildrenState'; interface Props { dataFrames: DataFrame[]; splitOpenFn: SplitOpen; diff --git a/public/app/features/explore/TraceView/createSpanLink.test.ts b/public/app/features/explore/TraceView/createSpanLink.test.ts index 58b4a7d2145..e88ce728b73 100644 --- a/public/app/features/explore/TraceView/createSpanLink.test.ts +++ b/public/app/features/explore/TraceView/createSpanLink.test.ts @@ -1,11 +1,13 @@ import { DataSourceInstanceSettings, MutableDataFrame } from '@grafana/data'; import { setDataSourceSrv, setTemplateSrv } from '@grafana/runtime'; -import { createSpanLinkFactory } from './createSpanLink'; import { TraceSpan } from '@jaegertracing/jaeger-ui-components'; + import { TraceToLogsOptions } from '../../../core/components/TraceToLogs/TraceToLogsSettings'; import { LinkSrv, setLinkSrv } from '../../panel/panellinks/link_srv'; import { TemplateSrv } from '../../templating/template_srv'; +import { createSpanLinkFactory } from './createSpanLink'; + describe('createSpanLinkFactory', () => { it('returns undefined if there is no data source uid', () => { const splitOpenFn = jest.fn(); diff --git a/public/app/features/explore/TraceView/createSpanLink.tsx b/public/app/features/explore/TraceView/createSpanLink.tsx index 5bfcd690816..a036eeb05d8 100644 --- a/public/app/features/explore/TraceView/createSpanLink.tsx +++ b/public/app/features/explore/TraceView/createSpanLink.tsx @@ -1,3 +1,5 @@ +import React from 'react'; + import { DataFrame, DataLink, @@ -17,7 +19,7 @@ import { Icon } from '@grafana/ui'; import { SpanLinkDef, SpanLinkFunc, TraceSpan } from '@jaegertracing/jaeger-ui-components'; import { TraceToLogsOptions } from 'app/core/components/TraceToLogs/TraceToLogsSettings'; import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; -import React from 'react'; + import { LokiQuery } from '../../../plugins/datasource/loki/types'; import { getFieldLinksForExplore } from '../utils/links'; diff --git a/public/app/features/explore/TraceView/useChildrenState.test.ts b/public/app/features/explore/TraceView/useChildrenState.test.ts index 4871401d57a..1d6dca9c200 100644 --- a/public/app/features/explore/TraceView/useChildrenState.test.ts +++ b/public/app/features/explore/TraceView/useChildrenState.test.ts @@ -1,7 +1,9 @@ import { renderHook, act } from '@testing-library/react-hooks'; -import { useChildrenState } from './useChildrenState'; + import { TraceSpan } from '@jaegertracing/jaeger-ui-components'; +import { useChildrenState } from './useChildrenState'; + describe('useChildrenState', () => { describe('childrenToggle', () => { it('toggles children state', async () => { diff --git a/public/app/features/explore/TraceView/useChildrenState.ts b/public/app/features/explore/TraceView/useChildrenState.ts index 431c8946224..ef8607bf9ef 100644 --- a/public/app/features/explore/TraceView/useChildrenState.ts +++ b/public/app/features/explore/TraceView/useChildrenState.ts @@ -1,4 +1,5 @@ import { useCallback, useState } from 'react'; + import { TraceSpan } from '@jaegertracing/jaeger-ui-components'; /** diff --git a/public/app/features/explore/TraceView/useDetailState.test.ts b/public/app/features/explore/TraceView/useDetailState.test.ts index 0a641f461c8..f52bda64446 100644 --- a/public/app/features/explore/TraceView/useDetailState.test.ts +++ b/public/app/features/explore/TraceView/useDetailState.test.ts @@ -1,8 +1,10 @@ -import { act, renderHook } from '@testing-library/react-hooks'; -import { useDetailState } from './useDetailState'; import { TraceLog } from '@jaegertracing/jaeger-ui-components/src/types/trace'; +import { act, renderHook } from '@testing-library/react-hooks'; + import { DataFrame } from '@grafana/data'; +import { useDetailState } from './useDetailState'; + const sampleFrame: DataFrame = { name: 'trace', fields: [], diff --git a/public/app/features/explore/TraceView/useDetailState.ts b/public/app/features/explore/TraceView/useDetailState.ts index c58e91f6d0d..63400a6f2f7 100644 --- a/public/app/features/explore/TraceView/useDetailState.ts +++ b/public/app/features/explore/TraceView/useDetailState.ts @@ -1,7 +1,8 @@ +import { TraceLog, TraceSpanReference } from '@jaegertracing/jaeger-ui-components/src/types/trace'; import { useCallback, useState, useEffect } from 'react'; + import { DataFrame } from '@grafana/data'; import { DetailState } from '@jaegertracing/jaeger-ui-components'; -import { TraceLog, TraceSpanReference } from '@jaegertracing/jaeger-ui-components/src/types/trace'; /** * Keeps state of the span detail. This means whether span details are open but also state of each detail subitem diff --git a/public/app/features/explore/TraceView/useHoverIndentGuide.test.ts b/public/app/features/explore/TraceView/useHoverIndentGuide.test.ts index 94a280e2182..e3a16ce351d 100644 --- a/public/app/features/explore/TraceView/useHoverIndentGuide.test.ts +++ b/public/app/features/explore/TraceView/useHoverIndentGuide.test.ts @@ -1,4 +1,5 @@ import { renderHook, act } from '@testing-library/react-hooks'; + import { useHoverIndentGuide } from './useHoverIndentGuide'; describe('useHoverIndentGuide', () => { diff --git a/public/app/features/explore/TraceView/useSearch.test.ts b/public/app/features/explore/TraceView/useSearch.test.ts index 0279229b0bd..ce5ceddbeb7 100644 --- a/public/app/features/explore/TraceView/useSearch.test.ts +++ b/public/app/features/explore/TraceView/useSearch.test.ts @@ -1,7 +1,9 @@ import { act, renderHook } from '@testing-library/react-hooks'; -import { useSearch } from './useSearch'; + import { TraceSpan } from '@jaegertracing/jaeger-ui-components'; +import { useSearch } from './useSearch'; + describe('useSearch', () => { it('returns matching span IDs', async () => { const { result } = renderHook(() => diff --git a/public/app/features/explore/TraceView/useSearch.ts b/public/app/features/explore/TraceView/useSearch.ts index dba2602a7f3..6574ac5659b 100644 --- a/public/app/features/explore/TraceView/useSearch.ts +++ b/public/app/features/explore/TraceView/useSearch.ts @@ -1,4 +1,5 @@ import { useMemo, useState } from 'react'; + import { filterSpans, TraceSpan } from '@jaegertracing/jaeger-ui-components'; /** diff --git a/public/app/features/explore/TraceView/useViewRange.test.ts b/public/app/features/explore/TraceView/useViewRange.test.ts index 0e4a55abe93..8212c5b05cd 100644 --- a/public/app/features/explore/TraceView/useViewRange.test.ts +++ b/public/app/features/explore/TraceView/useViewRange.test.ts @@ -1,4 +1,5 @@ import { renderHook, act } from '@testing-library/react-hooks'; + import { useViewRange } from './useViewRange'; describe('useViewRange', () => { diff --git a/public/app/features/explore/TraceView/useViewRange.ts b/public/app/features/explore/TraceView/useViewRange.ts index b7706ddc238..e617f488ebe 100644 --- a/public/app/features/explore/TraceView/useViewRange.ts +++ b/public/app/features/explore/TraceView/useViewRange.ts @@ -1,4 +1,5 @@ import { useCallback, useState } from 'react'; + import { ViewRangeTimeUpdate, ViewRange } from '@jaegertracing/jaeger-ui-components'; /** diff --git a/public/app/features/explore/Wrapper.test.tsx b/public/app/features/explore/Wrapper.test.tsx index 75c8f9576d6..21d2c9865ea 100644 --- a/public/app/features/explore/Wrapper.test.tsx +++ b/public/app/features/explore/Wrapper.test.tsx @@ -1,12 +1,14 @@ -import React from 'react'; import { fireEvent, screen, waitFor } from '@testing-library/react'; -import { locationService } from '@grafana/runtime'; -import { serializeStateToUrlParam } from '@grafana/data'; import userEvent from '@testing-library/user-event'; -import { splitOpen } from './state/main'; -import { setupExplore, tearDown, waitForExplore } from './spec/helper/setup'; -import { makeLogsQueryResponse, makeMetricsQueryResponse } from './spec/helper/query'; +import React from 'react'; + +import { serializeStateToUrlParam } from '@grafana/data'; +import { locationService } from '@grafana/runtime'; + import { changeDatasource } from './spec/helper/interactions'; +import { makeLogsQueryResponse, makeMetricsQueryResponse } from './spec/helper/query'; +import { setupExplore, tearDown, waitForExplore } from './spec/helper/setup'; +import { splitOpen } from './state/main'; type Mock = jest.Mock; diff --git a/public/app/features/explore/Wrapper.tsx b/public/app/features/explore/Wrapper.tsx index e1591752591..6afa7dd29d1 100644 --- a/public/app/features/explore/Wrapper.tsx +++ b/public/app/features/explore/Wrapper.tsx @@ -1,16 +1,18 @@ import React, { PureComponent } from 'react'; import { connect, ConnectedProps } from 'react-redux'; -import { ExploreId, ExploreQueryParams } from 'app/types/explore'; -import { ErrorBoundaryAlert } from '@grafana/ui'; -import { lastSavedUrl, resetExploreAction, richHistoryUpdatedAction } from './state/main'; -import { ExplorePaneContainer } from './ExplorePaneContainer'; -import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; -import { Branding } from '../../core/components/Branding/Branding'; -import { ExploreActions } from './ExploreActions'; -import { getNavModel } from '../../core/selectors/navModel'; -import { StoreState } from 'app/types'; import { locationService } from '@grafana/runtime'; +import { ErrorBoundaryAlert } from '@grafana/ui'; +import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; +import { StoreState } from 'app/types'; +import { ExploreId, ExploreQueryParams } from 'app/types/explore'; + +import { Branding } from '../../core/components/Branding/Branding'; +import { getNavModel } from '../../core/selectors/navModel'; + +import { ExploreActions } from './ExploreActions'; +import { ExplorePaneContainer } from './ExplorePaneContainer'; +import { lastSavedUrl, resetExploreAction, richHistoryUpdatedAction } from './state/main'; interface RouteProps extends GrafanaRouteComponentProps<{}, ExploreQueryParams> {} interface OwnProps {} diff --git a/public/app/features/explore/exploreGraphStyleUtils.ts b/public/app/features/explore/exploreGraphStyleUtils.ts index 177fbfcead3..6da223c91b9 100644 --- a/public/app/features/explore/exploreGraphStyleUtils.ts +++ b/public/app/features/explore/exploreGraphStyleUtils.ts @@ -1,6 +1,8 @@ import produce from 'immer'; + import { FieldConfigSource } from '@grafana/data'; import { GraphDrawStyle, GraphFieldConfig, StackingMode } from '@grafana/schema'; + import { ExploreGraphStyle } from '../../types'; export type FieldConfig = FieldConfigSource; diff --git a/public/app/features/explore/spec/helper/assert.ts b/public/app/features/explore/spec/helper/assert.ts index 353455c9b9f..3bbd4c70290 100644 --- a/public/app/features/explore/spec/helper/assert.ts +++ b/public/app/features/explore/spec/helper/assert.ts @@ -1,5 +1,7 @@ import { waitFor } from '@testing-library/react'; + import { ExploreId } from '../../../../types'; + import { withinExplore } from './setup'; export const assertQueryHistoryExists = (query: string, exploreId: ExploreId = ExploreId.left) => { diff --git a/public/app/features/explore/spec/helper/interactions.ts b/public/app/features/explore/spec/helper/interactions.ts index 46e806a00b9..84941bbd361 100644 --- a/public/app/features/explore/spec/helper/interactions.ts +++ b/public/app/features/explore/spec/helper/interactions.ts @@ -1,7 +1,10 @@ -import { selectors } from '@grafana/e2e-selectors'; -import userEvent from '@testing-library/user-event'; import { fireEvent, screen, within } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; + +import { selectors } from '@grafana/e2e-selectors'; + import { ExploreId } from '../../../../types'; + import { withinExplore } from './setup'; export const changeDatasource = async (name: string) => { diff --git a/public/app/features/explore/spec/helper/query.ts b/public/app/features/explore/spec/helper/query.ts index b1156fc6673..a1ec1216b64 100644 --- a/public/app/features/explore/spec/helper/query.ts +++ b/public/app/features/explore/spec/helper/query.ts @@ -1,4 +1,5 @@ import { from, Observable } from 'rxjs'; + import { ArrayDataFrame, DataQueryResponse, FieldType } from '@grafana/data'; export function makeLogsQueryResponse(marker = ''): Observable { diff --git a/public/app/features/explore/spec/helper/setup.tsx b/public/app/features/explore/spec/helper/setup.tsx index ef2930b6717..ad56d246106 100644 --- a/public/app/features/explore/spec/helper/setup.tsx +++ b/public/app/features/explore/spec/helper/setup.tsx @@ -1,9 +1,9 @@ -import React from 'react'; -import { render, screen } from '@testing-library/react'; import { within } from '@testing-library/dom'; +import { render, screen } from '@testing-library/react'; +import { fromPairs } from 'lodash'; +import React from 'react'; import { Provider } from 'react-redux'; import { Route, Router } from 'react-router-dom'; -import { fromPairs } from 'lodash'; import { DataSourceApi, DataSourceInstanceSettings, QueryEditorProps, ScopedVars } from '@grafana/data'; import { locationService, setDataSourceSrv, setEchoSrv } from '@grafana/runtime'; @@ -11,12 +11,11 @@ import { GrafanaRoute } from 'app/core/navigation/GrafanaRoute'; import { Echo } from 'app/core/services/echo/Echo'; import { configureStore } from 'app/store/configureStore'; -import Wrapper from '../../Wrapper'; -import { initialUserState } from '../../../profile/state/reducers'; - import { LokiDatasource } from '../../../../plugins/datasource/loki/datasource'; import { LokiQuery } from '../../../../plugins/datasource/loki/types'; import { ExploreId } from '../../../../types'; +import { initialUserState } from '../../../profile/state/reducers'; +import Wrapper from '../../Wrapper'; type DatasourceSetup = { settings: DataSourceInstanceSettings; api: DataSourceApi }; diff --git a/public/app/features/explore/spec/interpolation.test.tsx b/public/app/features/explore/spec/interpolation.test.tsx index cfe11ccbc0f..8e13045701f 100644 --- a/public/app/features/explore/spec/interpolation.test.tsx +++ b/public/app/features/explore/spec/interpolation.test.tsx @@ -1,10 +1,13 @@ import React from 'react'; -import { setupExplore, waitForExplore } from './helper/setup'; -import { makeLogsQueryResponse } from './helper/query'; + import { DataQueryRequest, serializeStateToUrlParam } from '@grafana/data'; import { getTemplateSrv } from '@grafana/runtime'; + import { LokiQuery } from '../../../plugins/datasource/loki/types'; +import { makeLogsQueryResponse } from './helper/query'; +import { setupExplore, waitForExplore } from './helper/setup'; + jest.mock('react-virtualized-auto-sizer', () => { return { __esModule: true, diff --git a/public/app/features/explore/spec/queryHistory.test.tsx b/public/app/features/explore/spec/queryHistory.test.tsx index 291cc78cfbe..af35b403341 100644 --- a/public/app/features/explore/spec/queryHistory.test.tsx +++ b/public/app/features/explore/spec/queryHistory.test.tsx @@ -1,6 +1,17 @@ import React from 'react'; + import { serializeStateToUrlParam } from '@grafana/data'; -import { setupExplore, tearDown, waitForExplore } from './helper/setup'; + +import { silenceConsoleOutput } from '../../../../test/core/utils/silenceConsoleOutput'; +import { ExploreId } from '../../../types'; + +import { + assertDataSourceFilterVisibility, + assertQueryHistory, + assertQueryHistoryExists, + assertQueryHistoryIsStarred, + assertQueryHistoryTabIsSelected, +} from './helper/assert'; import { closeQueryHistory, deleteQueryHistory, @@ -12,16 +23,8 @@ import { starQueryHistory, switchToQueryHistoryTab, } from './helper/interactions'; -import { - assertDataSourceFilterVisibility, - assertQueryHistory, - assertQueryHistoryExists, - assertQueryHistoryIsStarred, - assertQueryHistoryTabIsSelected, -} from './helper/assert'; import { makeLogsQueryResponse } from './helper/query'; -import { ExploreId } from '../../../types'; -import { silenceConsoleOutput } from '../../../../test/core/utils/silenceConsoleOutput'; +import { setupExplore, tearDown, waitForExplore } from './helper/setup'; jest.mock('react-virtualized-auto-sizer', () => { return { diff --git a/public/app/features/explore/state/datasource.test.ts b/public/app/features/explore/state/datasource.test.ts index 35fe417622c..01a28e8dd95 100644 --- a/public/app/features/explore/state/datasource.test.ts +++ b/public/app/features/explore/state/datasource.test.ts @@ -1,6 +1,7 @@ -import { updateDatasourceInstanceAction, datasourceReducer } from './datasource'; -import { ExploreId, ExploreItemState } from 'app/types'; import { DataQuery, DataSourceApi } from '@grafana/data'; +import { ExploreId, ExploreItemState } from 'app/types'; + +import { updateDatasourceInstanceAction, datasourceReducer } from './datasource'; import { createEmptyQueryResponse } from './utils'; describe('Datasource reducer', () => { diff --git a/public/app/features/explore/state/datasource.ts b/public/app/features/explore/state/datasource.ts index abaab9ad04d..a4564d0fe5b 100644 --- a/public/app/features/explore/state/datasource.ts +++ b/public/app/features/explore/state/datasource.ts @@ -1,11 +1,12 @@ // Libraries import { AnyAction, createAction } from '@reduxjs/toolkit'; -import { RefreshPicker } from '@grafana/ui'; + import { DataSourceApi, HistoryItem } from '@grafana/data'; +import { RefreshPicker } from '@grafana/ui'; import { stopQueryState } from 'app/core/utils/explore'; import { ExploreItemState, ThunkResult } from 'app/types'; - import { ExploreId } from 'app/types/explore'; + import { importQueries, runQueries } from './query'; import { changeRefreshInterval } from './time'; import { createEmptyQueryResponse, loadAndInitDatasource } from './utils'; diff --git a/public/app/features/explore/state/explorePane.test.ts b/public/app/features/explore/state/explorePane.test.ts index e429616a7d6..70b957d17d6 100644 --- a/public/app/features/explore/state/explorePane.test.ts +++ b/public/app/features/explore/state/explorePane.test.ts @@ -1,9 +1,12 @@ -import { serializeStateToUrlParam } from '@grafana/data'; -import { ExploreId, StoreState, ThunkDispatch } from 'app/types'; -import { refreshExplore } from './explorePane'; -import { setDataSourceSrv } from '@grafana/runtime'; -import { configureStore } from '../../../store/configureStore'; import { of } from 'rxjs'; + +import { serializeStateToUrlParam } from '@grafana/data'; +import { setDataSourceSrv } from '@grafana/runtime'; +import { ExploreId, StoreState, ThunkDispatch } from 'app/types'; + +import { configureStore } from '../../../store/configureStore'; + +import { refreshExplore } from './explorePane'; import { createDefaultInitialState } from './helpers'; jest.mock('../../dashboard/services/TimeSrv', () => ({ diff --git a/public/app/features/explore/state/explorePane.ts b/public/app/features/explore/state/explorePane.ts index a9265a441fa..98dac17a6a2 100644 --- a/public/app/features/explore/state/explorePane.ts +++ b/public/app/features/explore/state/explorePane.ts @@ -1,27 +1,7 @@ -import { AnyAction } from 'redux'; -import { isEqual } from 'lodash'; - -import { - DEFAULT_RANGE, - getQueryKeys, - parseUrlState, - ensureQueries, - generateNewKeyAndAddRefIdIfMissing, - getTimeRangeFromUrl, -} from 'app/core/utils/explore'; -import { ExploreGraphStyle, ExploreId, ExploreItemState } from 'app/types/explore'; -import { queryReducer, runQueries, setQueriesAction } from './query'; -import { datasourceReducer } from './datasource'; -import { timeReducer, updateTime } from './time'; -import { historyReducer } from './history'; -import { - makeExplorePaneState, - loadAndInitDatasource, - createEmptyQueryResponse, - getUrlStateFromPaneState, - storeGraphStyle, -} from './utils'; import { createAction, PayloadAction } from '@reduxjs/toolkit'; +import { isEqual } from 'lodash'; +import { AnyAction } from 'redux'; + import { EventBusExtended, DataQuery, @@ -32,12 +12,33 @@ import { ExplorePanelsState, PreferredVisualisationType, } from '@grafana/data'; -// Types -import { ThunkResult } from 'app/types'; -import { getFiscalYearStartMonth, getTimeZone } from 'app/features/profile/state/selectors'; import { getDataSourceSrv } from '@grafana/runtime'; -import { richHistorySearchFiltersUpdatedAction, richHistoryUpdatedAction, stateSave } from './main'; import { keybindingSrv } from 'app/core/services/keybindingSrv'; +import { + DEFAULT_RANGE, + getQueryKeys, + parseUrlState, + ensureQueries, + generateNewKeyAndAddRefIdIfMissing, + getTimeRangeFromUrl, +} from 'app/core/utils/explore'; +import { getFiscalYearStartMonth, getTimeZone } from 'app/features/profile/state/selectors'; +import { ThunkResult } from 'app/types'; +import { ExploreGraphStyle, ExploreId, ExploreItemState } from 'app/types/explore'; + +import { datasourceReducer } from './datasource'; +import { historyReducer } from './history'; +import { richHistorySearchFiltersUpdatedAction, richHistoryUpdatedAction, stateSave } from './main'; +import { queryReducer, runQueries, setQueriesAction } from './query'; +import { timeReducer, updateTime } from './time'; +import { + makeExplorePaneState, + loadAndInitDatasource, + createEmptyQueryResponse, + getUrlStateFromPaneState, + storeGraphStyle, +} from './utils'; +// Types // // Actions and Payloads diff --git a/public/app/features/explore/state/helpers.ts b/public/app/features/explore/state/helpers.ts index 5e744449262..2a9e39f46a6 100644 --- a/public/app/features/explore/state/helpers.ts +++ b/public/app/features/explore/state/helpers.ts @@ -1,4 +1,5 @@ import { DefaultTimeZone, toUtc } from '@grafana/data'; + import { ExploreId } from '../../../types'; export const createDefaultInitialState = () => { diff --git a/public/app/features/explore/state/history.ts b/public/app/features/explore/state/history.ts index 4c5982514db..cd4e6375310 100644 --- a/public/app/features/explore/state/history.ts +++ b/public/app/features/explore/state/history.ts @@ -1,3 +1,6 @@ +import { AnyAction, createAction } from '@reduxjs/toolkit'; + +import { DataQuery, HistoryItem } from '@grafana/data'; import { addToRichHistory, deleteAllFromRichHistory, @@ -10,6 +13,9 @@ import { updateStarredInRichHistory, } from 'app/core/utils/richHistory'; import { ExploreId, ExploreItemState, ExploreState, RichHistoryQuery, ThunkResult } from 'app/types'; + +import { RichHistorySearchFilters, RichHistorySettings } from '../../../core/utils/richHistoryTypes'; + import { richHistoryLimitExceededAction, richHistorySearchFiltersUpdatedAction, @@ -17,9 +23,6 @@ import { richHistoryStorageFullAction, richHistoryUpdatedAction, } from './main'; -import { DataQuery, HistoryItem } from '@grafana/data'; -import { AnyAction, createAction } from '@reduxjs/toolkit'; -import { RichHistorySearchFilters, RichHistorySettings } from '../../../core/utils/richHistoryTypes'; // // Actions and Payloads diff --git a/public/app/features/explore/state/main.test.ts b/public/app/features/explore/state/main.test.ts index a964eafb4b4..3a5d5839784 100644 --- a/public/app/features/explore/state/main.test.ts +++ b/public/app/features/explore/state/main.test.ts @@ -1,12 +1,15 @@ -import { serializeStateToUrlParam } from '@grafana/data/src/utils/url'; -import { exploreReducer, navigateToExplore, splitCloseAction } from './main'; import { thunkTester } from 'test/core/thunk/thunkTester'; + +import { ExploreUrlState } from '@grafana/data'; +import { serializeStateToUrlParam } from '@grafana/data/src/utils/url'; +import { locationService } from '@grafana/runtime'; import { PanelModel } from 'app/features/dashboard/state'; + +import { reducerTester } from '../../../../test/core/redux/reducerTester'; import { MockDataSourceApi } from '../../../../test/mocks/datasource_srv'; import { ExploreId, ExploreItemState, ExploreState } from '../../../types'; -import { reducerTester } from '../../../../test/core/redux/reducerTester'; -import { ExploreUrlState } from '@grafana/data'; -import { locationService } from '@grafana/runtime'; + +import { exploreReducer, navigateToExplore, splitCloseAction } from './main'; const getNavigateToExploreContext = async (openInNewWindow?: (url: string) => void) => { const url = '/explore'; diff --git a/public/app/features/explore/state/main.ts b/public/app/features/explore/state/main.ts index cd439b72d85..32de466c90f 100644 --- a/public/app/features/explore/state/main.ts +++ b/public/app/features/explore/state/main.ts @@ -1,15 +1,18 @@ -import { AnyAction } from 'redux'; -import { DataSourceSrv, getDataSourceSrv, locationService } from '@grafana/runtime'; -import { ExploreUrlState, serializeStateToUrlParam, SplitOpen, UrlQueryMap } from '@grafana/data'; -import { GetExploreUrlArguments, stopQueryState } from 'app/core/utils/explore'; -import { ExploreId, ExploreItemState, ExploreState, RichHistoryQuery } from 'app/types/explore'; -import { paneReducer } from './explorePane'; import { createAction } from '@reduxjs/toolkit'; -import { getUrlStateFromPaneState, makeExplorePaneState } from './utils'; +import { AnyAction } from 'redux'; + +import { ExploreUrlState, serializeStateToUrlParam, SplitOpen, UrlQueryMap } from '@grafana/data'; +import { DataSourceSrv, getDataSourceSrv, locationService } from '@grafana/runtime'; +import { GetExploreUrlArguments, stopQueryState } from 'app/core/utils/explore'; +import { PanelModel } from 'app/features/dashboard/state'; +import { ExploreId, ExploreItemState, ExploreState, RichHistoryQuery } from 'app/types/explore'; + +import { RichHistorySearchFilters, RichHistorySettings } from '../../../core/utils/richHistoryTypes'; import { ThunkResult } from '../../../types'; import { TimeSrv } from '../../dashboard/services/TimeSrv'; -import { PanelModel } from 'app/features/dashboard/state'; -import { RichHistorySearchFilters, RichHistorySettings } from '../../../core/utils/richHistoryTypes'; + +import { paneReducer } from './explorePane'; +import { getUrlStateFromPaneState, makeExplorePaneState } from './utils'; // // Actions and Payloads diff --git a/public/app/features/explore/state/query.test.ts b/public/app/features/explore/state/query.test.ts index c0d235cfd0d..7ca0899a377 100644 --- a/public/app/features/explore/state/query.test.ts +++ b/public/app/features/explore/state/query.test.ts @@ -1,3 +1,26 @@ +import { EMPTY, interval, Observable, of } from 'rxjs'; +import { thunkTester } from 'test/core/thunk/thunkTester'; + +import { + ArrayVector, + DataFrame, + DataQuery, + DataQueryResponse, + DataSourceApi, + DataSourceJsonData, + DataSourceWithLogsVolumeSupport, + LoadingState, + MutableDataFrame, + PanelData, + RawTimeRange, +} from '@grafana/data'; +import { ExploreId, ExploreItemState, StoreState, ThunkDispatch } from 'app/types'; + +import { reducerTester } from '../../../../test/core/redux/reducerTester'; +import { configureStore } from '../../../store/configureStore'; +import { setTimeSrv } from '../../dashboard/services/TimeSrv'; + +import { createDefaultInitialState } from './helpers'; import { addQueryRowAction, addResultsToCache, @@ -12,28 +35,9 @@ import { scanStopAction, storeLogsVolumeDataProviderAction, } from './query'; -import { ExploreId, ExploreItemState, StoreState, ThunkDispatch } from 'app/types'; -import { EMPTY, interval, Observable, of } from 'rxjs'; -import { - ArrayVector, - DataFrame, - DataQuery, - DataQueryResponse, - DataSourceApi, - DataSourceJsonData, - DataSourceWithLogsVolumeSupport, - LoadingState, - MutableDataFrame, - PanelData, - RawTimeRange, -} from '@grafana/data'; -import { thunkTester } from 'test/core/thunk/thunkTester'; import { makeExplorePaneState } from './utils'; -import { reducerTester } from '../../../../test/core/redux/reducerTester'; -import { configureStore } from '../../../store/configureStore'; -import { setTimeSrv } from '../../dashboard/services/TimeSrv'; + import Mock = jest.Mock; -import { createDefaultInitialState } from './helpers'; const { testRange, defaultInitialState } = createDefaultInitialState(); diff --git a/public/app/features/explore/state/query.ts b/public/app/features/explore/state/query.ts index 10216ecdb3c..db4101ca86d 100644 --- a/public/app/features/explore/state/query.ts +++ b/public/app/features/explore/state/query.ts @@ -1,5 +1,8 @@ -import { mergeMap, throttleTime } from 'rxjs/operators'; +import { AnyAction, createAction, PayloadAction } from '@reduxjs/toolkit'; +import deepEqual from 'fast-deep-equal'; import { identity, Observable, of, SubscriptionLike, Unsubscribable } from 'rxjs'; +import { mergeMap, throttleTime } from 'rxjs/operators'; + import { AbsoluteTimeRange, DataQuery, @@ -16,7 +19,6 @@ import { QueryFixAction, toLegacyResponseData, } from '@grafana/data'; - import { buildQueryTransaction, ensureQueries, @@ -27,20 +29,20 @@ import { stopQueryState, updateHistory, } from 'app/core/utils/explore'; +import { getShiftedTimeRange } from 'app/core/utils/timePicker'; +import { getTimeZone } from 'app/features/profile/state/selectors'; import { ExploreItemState, ExplorePanelData, ThunkDispatch, ThunkResult } from 'app/types'; import { ExploreId, ExploreState, QueryOptions } from 'app/types/explore'; -import { getTimeZone } from 'app/features/profile/state/selectors'; -import { getShiftedTimeRange } from 'app/core/utils/timePicker'; + import { notifyApp } from '../../../core/actions'; +import { createErrorNotification } from '../../../core/copy/appNotification'; import { runRequest } from '../../query/state/runRequest'; import { decorateData } from '../utils/decorators'; -import { createErrorNotification } from '../../../core/copy/appNotification'; -import { stateSave } from './main'; -import { AnyAction, createAction, PayloadAction } from '@reduxjs/toolkit'; -import { updateTime } from './time'; + import { addHistoryItem, historyUpdatedAction, loadRichHistory } from './history'; +import { stateSave } from './main'; +import { updateTime } from './time'; import { createCacheKey, getResultsFromCache } from './utils'; -import deepEqual from 'fast-deep-equal'; // // Actions and Payloads diff --git a/public/app/features/explore/state/time.test.ts b/public/app/features/explore/state/time.test.ts index 513887c8e47..ae9e4b0a889 100644 --- a/public/app/features/explore/state/time.test.ts +++ b/public/app/features/explore/state/time.test.ts @@ -1,13 +1,15 @@ -import { dateTime, LoadingState } from '@grafana/data'; - -import { makeExplorePaneState } from './utils'; -import { ExploreId, ExploreItemState } from 'app/types/explore'; import { reducerTester } from 'test/core/redux/reducerTester'; -import { changeRangeAction, changeRefreshIntervalAction, timeReducer, updateTime } from './time'; -import { createDefaultInitialState } from './helpers'; + +import { dateTime, LoadingState } from '@grafana/data'; import { configureStore } from 'app/store/configureStore'; +import { ExploreId, ExploreItemState } from 'app/types/explore'; + import { silenceConsoleOutput } from '../../../../test/core/utils/silenceConsoleOutput'; +import { createDefaultInitialState } from './helpers'; +import { changeRangeAction, changeRefreshIntervalAction, timeReducer, updateTime } from './time'; +import { makeExplorePaneState } from './utils'; + const MOCK_TIME_RANGE = {}; const mockTimeSrv = { diff --git a/public/app/features/explore/state/time.ts b/public/app/features/explore/state/time.ts index 32ccf4c3255..7ea79783a45 100644 --- a/public/app/features/explore/state/time.ts +++ b/public/app/features/explore/state/time.ts @@ -1,4 +1,5 @@ import { AnyAction, createAction, PayloadAction } from '@reduxjs/toolkit'; + import { AbsoluteTimeRange, dateTimeForTimeZone, @@ -7,17 +8,18 @@ import { sortLogsResult, TimeRange, } from '@grafana/data'; -import { RefreshPicker } from '@grafana/ui'; import { getTemplateSrv } from '@grafana/runtime'; - +import { RefreshPicker } from '@grafana/ui'; import { getTimeRange, refreshIntervalToSortOrder, stopQueryState } from 'app/core/utils/explore'; +import { getFiscalYearStartMonth, getTimeZone } from 'app/features/profile/state/selectors'; import { ExploreItemState, ThunkResult } from 'app/types'; import { ExploreId } from 'app/types/explore'; -import { getFiscalYearStartMonth, getTimeZone } from 'app/features/profile/state/selectors'; + import { getTimeSrv } from '../../dashboard/services/TimeSrv'; import { TimeModel } from '../../dashboard/state/TimeModel'; -import { runQueries } from './query'; + import { syncTimesAction, stateSave } from './main'; +import { runQueries } from './query'; // // Actions and Payloads diff --git a/public/app/features/explore/state/utils.test.ts b/public/app/features/explore/state/utils.test.ts index e24ba97000d..c2834f792b3 100644 --- a/public/app/features/explore/state/utils.test.ts +++ b/public/app/features/explore/state/utils.test.ts @@ -1,5 +1,5 @@ -import { lastUsedDatasourceKeyForOrgId } from '../../../core/utils/explore'; import store from '../../../core/store'; +import { lastUsedDatasourceKeyForOrgId } from '../../../core/utils/explore'; const dataSourceMock = { get: jest.fn(), diff --git a/public/app/features/explore/state/utils.ts b/public/app/features/explore/state/utils.ts index 563c86326eb..13ba2788f50 100644 --- a/public/app/features/explore/state/utils.ts +++ b/public/app/features/explore/state/utils.ts @@ -1,3 +1,5 @@ +import { isEmpty, isObject, mapValues, omitBy } from 'lodash'; + import { AbsoluteTimeRange, DataSourceApi, @@ -10,11 +12,11 @@ import { } from '@grafana/data'; import { ExplorePanelData } from 'app/types'; import { ExploreGraphStyle, ExploreItemState } from 'app/types/explore'; -import { getDatasourceSrv } from '../../plugins/datasource_srv'; + import store from '../../../core/store'; import { clearQueryKeys, lastUsedDatasourceKeyForOrgId, toGraphStyle } from '../../../core/utils/explore'; +import { getDatasourceSrv } from '../../plugins/datasource_srv'; import { toRawTimeRange } from '../utils/time'; -import { isEmpty, isObject, mapValues, omitBy } from 'lodash'; export const DEFAULT_RANGE = { from: 'now-6h', diff --git a/public/app/features/explore/useLiveTailControls.ts b/public/app/features/explore/useLiveTailControls.ts index b18bd8b8409..84004381429 100644 --- a/public/app/features/explore/useLiveTailControls.ts +++ b/public/app/features/explore/useLiveTailControls.ts @@ -1,11 +1,13 @@ import React, { useCallback } from 'react'; import { useDispatch } from 'react-redux'; + import { RefreshPicker } from '@grafana/ui'; -import { changeRefreshInterval } from './state/time'; -import { setPausedStateAction, runQueries } from './state/query'; import { ExploreId } from '../../types'; +import { setPausedStateAction, runQueries } from './state/query'; +import { changeRefreshInterval } from './state/time'; + /** * Hook that gives you all the functions needed to control the live tailing. */ diff --git a/public/app/features/explore/utils/LogsCrossFadeTransition.tsx b/public/app/features/explore/utils/LogsCrossFadeTransition.tsx index 259a5930c7a..8ccc6eba5b5 100644 --- a/public/app/features/explore/utils/LogsCrossFadeTransition.tsx +++ b/public/app/features/explore/utils/LogsCrossFadeTransition.tsx @@ -1,6 +1,6 @@ -import React from 'react'; -import memoizeOne from 'memoize-one'; import { css } from '@emotion/css'; +import memoizeOne from 'memoize-one'; +import React from 'react'; import { CSSTransition } from 'react-transition-group'; const transitionDuration = 500; diff --git a/public/app/features/explore/utils/decorators.test.ts b/public/app/features/explore/utils/decorators.test.ts index a2ef493e7ab..893a0894e10 100644 --- a/public/app/features/explore/utils/decorators.test.ts +++ b/public/app/features/explore/utils/decorators.test.ts @@ -1,5 +1,5 @@ -import { GraphDrawStyle, StackingMode } from '@grafana/schema'; import { lastValueFrom } from 'rxjs'; + import { ArrayVector, DataFrame, @@ -11,6 +11,9 @@ import { TimeRange, toDataFrame, } from '@grafana/data'; +import { GraphDrawStyle, StackingMode } from '@grafana/schema'; +import TableModel from 'app/core/table_model'; +import { ExplorePanelData } from 'app/types'; import { decorateWithFrameTypeMetadata, @@ -18,8 +21,6 @@ import { decorateWithLogsResult, decorateWithTableResult, } from './decorators'; -import { ExplorePanelData } from 'app/types'; -import TableModel from 'app/core/table_model'; jest.mock('@grafana/data', () => ({ ...(jest.requireActual('@grafana/data') as any), diff --git a/public/app/features/explore/utils/decorators.ts b/public/app/features/explore/utils/decorators.ts index 249421956db..b2323eeffab 100644 --- a/public/app/features/explore/utils/decorators.ts +++ b/public/app/features/explore/utils/decorators.ts @@ -1,3 +1,7 @@ +import { groupBy } from 'lodash'; +import { Observable, of } from 'rxjs'; +import { map, mergeMap } from 'rxjs/operators'; + import { AbsoluteTimeRange, DataFrame, @@ -9,9 +13,7 @@ import { DataQuery, } from '@grafana/data'; import { config } from '@grafana/runtime'; -import { groupBy } from 'lodash'; -import { Observable, of } from 'rxjs'; -import { map, mergeMap } from 'rxjs/operators'; + import { dataFrameToLogsModel } from '../../../core/logs_model'; import { refreshIntervalToSortOrder } from '../../../core/utils/explore'; import { ExplorePanelData } from '../../../types'; diff --git a/public/app/features/explore/utils/links.test.ts b/public/app/features/explore/utils/links.test.ts index c1e071b5c40..29e35f9a32e 100644 --- a/public/app/features/explore/utils/links.test.ts +++ b/public/app/features/explore/utils/links.test.ts @@ -1,4 +1,3 @@ -import { getFieldLinksForExplore } from './links'; import { ArrayVector, DataLink, @@ -10,8 +9,11 @@ import { TimeRange, } from '@grafana/data'; import { setTemplateSrv } from '@grafana/runtime'; -import { setLinkSrv } from '../../panel/panellinks/link_srv'; + import { setContextSrv } from '../../../core/services/context_srv'; +import { setLinkSrv } from '../../panel/panellinks/link_srv'; + +import { getFieldLinksForExplore } from './links'; describe('getFieldLinksForExplore', () => { beforeEach(() => { diff --git a/public/app/features/explore/utils/links.ts b/public/app/features/explore/utils/links.ts index c3aabab2a51..92198743149 100644 --- a/public/app/features/explore/utils/links.ts +++ b/public/app/features/explore/utils/links.ts @@ -1,4 +1,5 @@ import { useCallback } from 'react'; + import { Field, LinkModel, @@ -11,9 +12,10 @@ import { SplitOpen, } from '@grafana/data'; import { getTemplateSrv } from '@grafana/runtime'; -import { getLinkSrv } from '../../panel/panellinks/link_srv'; import { contextSrv } from 'app/core/services/context_srv'; +import { getLinkSrv } from '../../panel/panellinks/link_srv'; + /** * Get links from the field of a dataframe and in addition check if there is associated * metadata with datasource in which case we will add onClick to open the link in new split window. This assumes diff --git a/public/app/features/expressions/ExpressionDatasource.test.ts b/public/app/features/expressions/ExpressionDatasource.test.ts index 139ec38c23c..c90a2107ca6 100644 --- a/public/app/features/expressions/ExpressionDatasource.test.ts +++ b/public/app/features/expressions/ExpressionDatasource.test.ts @@ -1,5 +1,6 @@ import { DataSourceInstanceSettings } from '@grafana/data'; import { backendSrv } from 'app/core/services/backend_srv'; + import { ExpressionDatasourceApi } from './ExpressionDatasource'; import { ExpressionQueryType } from './types'; diff --git a/public/app/features/expressions/ExpressionDatasource.ts b/public/app/features/expressions/ExpressionDatasource.ts index 15983e97bf5..cb9d4f16be6 100644 --- a/public/app/features/expressions/ExpressionDatasource.ts +++ b/public/app/features/expressions/ExpressionDatasource.ts @@ -1,3 +1,5 @@ +import { Observable, from, mergeMap } from 'rxjs'; + import { DataQueryRequest, DataQueryResponse, @@ -6,11 +8,11 @@ import { PluginType, ScopedVars, } from '@grafana/data'; -import { ExpressionQuery, ExpressionQueryType } from './types'; -import { ExpressionQueryEditor } from './ExpressionQueryEditor'; import { DataSourceWithBackend, getDataSourceSrv, getTemplateSrv } from '@grafana/runtime'; import { ExpressionDatasourceRef } from '@grafana/runtime/src/utils/DataSourceWithBackend'; -import { Observable, from, mergeMap } from 'rxjs'; + +import { ExpressionQueryEditor } from './ExpressionQueryEditor'; +import { ExpressionQuery, ExpressionQueryType } from './types'; /** * This is a singleton instance that just pretends to be a DataSource diff --git a/public/app/features/expressions/ExpressionQueryEditor.tsx b/public/app/features/expressions/ExpressionQueryEditor.tsx index 85783f48959..6e5d8aa5eee 100644 --- a/public/app/features/expressions/ExpressionQueryEditor.tsx +++ b/public/app/features/expressions/ExpressionQueryEditor.tsx @@ -1,12 +1,14 @@ import React, { PureComponent } from 'react'; + import { DataSourceApi, QueryEditorProps, SelectableValue } from '@grafana/data'; import { InlineField, Select } from '@grafana/ui'; -import { Resample } from './components/Resample'; -import { Reduce } from './components/Reduce'; -import { Math } from './components/Math'; + import { ClassicConditions } from './components/ClassicConditions'; -import { getDefaults } from './utils/expressionTypes'; +import { Math } from './components/Math'; +import { Reduce } from './components/Reduce'; +import { Resample } from './components/Resample'; import { ExpressionQuery, ExpressionQueryType, gelTypes } from './types'; +import { getDefaults } from './utils/expressionTypes'; type Props = QueryEditorProps, ExpressionQuery>; diff --git a/public/app/features/expressions/components/ClassicConditions.tsx b/public/app/features/expressions/components/ClassicConditions.tsx index 1903bdd3c8b..6496702d88f 100644 --- a/public/app/features/expressions/components/ClassicConditions.tsx +++ b/public/app/features/expressions/components/ClassicConditions.tsx @@ -1,10 +1,13 @@ import React, { FC } from 'react'; + import { SelectableValue } from '@grafana/data'; import { Button, Icon, InlineField, InlineFieldRow } from '@grafana/ui'; -import { Condition } from './Condition'; + import { ClassicCondition, ExpressionQuery } from '../types'; import { defaultCondition } from '../utils/expressionTypes'; +import { Condition } from './Condition'; + interface Props { query: ExpressionQuery; refIds: Array>; diff --git a/public/app/features/expressions/components/Condition.tsx b/public/app/features/expressions/components/Condition.tsx index a9df2ac796e..973d099ab09 100644 --- a/public/app/features/expressions/components/Condition.tsx +++ b/public/app/features/expressions/components/Condition.tsx @@ -1,7 +1,9 @@ -import React, { FC, FormEvent } from 'react'; import { css, cx } from '@emotion/css'; +import React, { FC, FormEvent } from 'react'; + import { GrafanaTheme, SelectableValue } from '@grafana/data'; import { Button, ButtonSelect, Icon, InlineFieldRow, Input, Select, useStyles } from '@grafana/ui'; + import alertDef, { EvalFunction } from '../../alerting/state/alertDef'; import { ClassicCondition, ReducerType } from '../types'; diff --git a/public/app/features/expressions/components/Math.tsx b/public/app/features/expressions/components/Math.tsx index 2d227321efd..140e569b20b 100644 --- a/public/app/features/expressions/components/Math.tsx +++ b/public/app/features/expressions/components/Math.tsx @@ -1,6 +1,8 @@ -import { InlineField, TextArea } from '@grafana/ui'; import { css } from '@emotion/css'; import React, { ChangeEvent, FC } from 'react'; + +import { InlineField, TextArea } from '@grafana/ui'; + import { ExpressionQuery } from '../types'; interface Props { diff --git a/public/app/features/expressions/components/Reduce.tsx b/public/app/features/expressions/components/Reduce.tsx index 693a66a5371..6e95add1e69 100644 --- a/public/app/features/expressions/components/Reduce.tsx +++ b/public/app/features/expressions/components/Reduce.tsx @@ -1,6 +1,8 @@ import React, { FC } from 'react'; + import { SelectableValue } from '@grafana/data'; import { InlineField, InlineFieldRow, Input, Select } from '@grafana/ui'; + import { ExpressionQuery, ExpressionQuerySettings, ReducerMode, reducerMode, reducerTypes } from '../types'; interface Props { diff --git a/public/app/features/expressions/components/Resample.tsx b/public/app/features/expressions/components/Resample.tsx index 8cc3d606531..ca37957d066 100644 --- a/public/app/features/expressions/components/Resample.tsx +++ b/public/app/features/expressions/components/Resample.tsx @@ -1,6 +1,8 @@ import React, { ChangeEvent, FC } from 'react'; + import { SelectableValue } from '@grafana/data'; import { InlineField, InlineFieldRow, Input, Select } from '@grafana/ui'; + import { downsamplingTypes, ExpressionQuery, upsamplingTypes } from '../types'; interface Props { diff --git a/public/app/features/expressions/guards.ts b/public/app/features/expressions/guards.ts index 67caaa7e7c7..e22053d5b72 100644 --- a/public/app/features/expressions/guards.ts +++ b/public/app/features/expressions/guards.ts @@ -1,5 +1,6 @@ import { DataQuery } from '@grafana/data'; import { isExpressionReference } from '@grafana/runtime/src/utils/DataSourceWithBackend'; + import { ExpressionQuery, ExpressionQueryType } from './types'; export const isExpressionQuery = (dataQuery?: DataQuery): dataQuery is ExpressionQuery => { diff --git a/public/app/features/expressions/types.ts b/public/app/features/expressions/types.ts index aaaa71faec9..d767347efcf 100644 --- a/public/app/features/expressions/types.ts +++ b/public/app/features/expressions/types.ts @@ -1,4 +1,5 @@ import { DataQuery, ReducerID, SelectableValue } from '@grafana/data'; + import { EvalFunction } from '../alerting/state/alertDef'; export enum ExpressionQueryType { diff --git a/public/app/features/expressions/utils/expressionTypes.ts b/public/app/features/expressions/utils/expressionTypes.ts index 6399334a2f1..d3e3665963b 100644 --- a/public/app/features/expressions/utils/expressionTypes.ts +++ b/public/app/features/expressions/utils/expressionTypes.ts @@ -1,6 +1,7 @@ import { ReducerID } from '@grafana/data'; -import { ClassicCondition, ExpressionQuery, ExpressionQueryType } from '../types'; + import { EvalFunction } from '../../alerting/state/alertDef'; +import { ClassicCondition, ExpressionQuery, ExpressionQueryType } from '../types'; export const getDefaults = (query: ExpressionQuery) => { switch (query.type) { diff --git a/public/app/features/folders/AccessControlFolderPermissions.tsx b/public/app/features/folders/AccessControlFolderPermissions.tsx index dac1954caab..376d3ff6f09 100644 --- a/public/app/features/folders/AccessControlFolderPermissions.tsx +++ b/public/app/features/folders/AccessControlFolderPermissions.tsx @@ -1,14 +1,15 @@ import React, { useEffect } from 'react'; -import { Permissions } from 'app/core/components/AccessControl'; import { connect, ConnectedProps } from 'react-redux'; +import { Permissions } from 'app/core/components/AccessControl'; import Page from 'app/core/components/Page/Page'; -import { getNavModel } from 'app/core/selectors/navModel'; import { contextSrv } from 'app/core/core'; -import { getLoadingNav } from './state/navModel'; -import { AccessControlAction, StoreState } from 'app/types'; import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; +import { getNavModel } from 'app/core/selectors/navModel'; +import { AccessControlAction, StoreState } from 'app/types'; + import { getFolderByUid } from './state/actions'; +import { getLoadingNav } from './state/navModel'; interface RouteProps extends GrafanaRouteComponentProps<{ uid: string }> {} diff --git a/public/app/features/folders/FolderAlerting.tsx b/public/app/features/folders/FolderAlerting.tsx index c1ea801a3ec..939676a751c 100644 --- a/public/app/features/folders/FolderAlerting.tsx +++ b/public/app/features/folders/FolderAlerting.tsx @@ -1,11 +1,14 @@ +import React from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import { useAsync } from 'react-use'; + import Page from 'app/core/components/Page/Page'; import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; import { getNavModel } from 'app/core/selectors/navModel'; import { StoreState } from 'app/types'; -import React from 'react'; -import { useDispatch, useSelector } from 'react-redux'; -import { useAsync } from 'react-use'; + import { AlertsFolderView } from '../alerting/unified/AlertsFolderView'; + import { getFolderByUid } from './state/actions'; import { getLoadingNav } from './state/navModel'; diff --git a/public/app/features/folders/FolderLibraryPanelsPage.tsx b/public/app/features/folders/FolderLibraryPanelsPage.tsx index 43443bdee6f..aa27c268d76 100644 --- a/public/app/features/folders/FolderLibraryPanelsPage.tsx +++ b/public/app/features/folders/FolderLibraryPanelsPage.tsx @@ -2,15 +2,16 @@ import React, { useState } from 'react'; import { connect, ConnectedProps } from 'react-redux'; import { useAsync } from 'react-use'; -import { GrafanaRouteComponentProps } from '../../core/navigation/types'; -import { StoreState } from '../../types'; -import { getNavModel } from '../../core/selectors/navModel'; -import { getLoadingNav } from './state/navModel'; -import { LibraryElementDTO } from '../library-panels/types'; import Page from '../../core/components/Page/Page'; +import { GrafanaRouteComponentProps } from '../../core/navigation/types'; +import { getNavModel } from '../../core/selectors/navModel'; +import { StoreState } from '../../types'; import { LibraryPanelsSearch } from '../library-panels/components/LibraryPanelsSearch/LibraryPanelsSearch'; import { OpenLibraryPanelModal } from '../library-panels/components/OpenLibraryPanelModal/OpenLibraryPanelModal'; +import { LibraryElementDTO } from '../library-panels/types'; + import { getFolderByUid } from './state/actions'; +import { getLoadingNav } from './state/navModel'; export interface OwnProps extends GrafanaRouteComponentProps<{ uid: string }> {} diff --git a/public/app/features/folders/FolderPermissions.tsx b/public/app/features/folders/FolderPermissions.tsx index 70f249a994e..ed69935fa4f 100644 --- a/public/app/features/folders/FolderPermissions.tsx +++ b/public/app/features/folders/FolderPermissions.tsx @@ -1,11 +1,17 @@ import React, { PureComponent } from 'react'; import { connect, ConnectedProps } from 'react-redux'; -import Page from 'app/core/components/Page/Page'; + import { Tooltip, Icon, Button } from '@grafana/ui'; import { SlideDown } from 'app/core/components/Animations/SlideDown'; +import Page from 'app/core/components/Page/Page'; +import AddPermission from 'app/core/components/PermissionList/AddPermission'; +import PermissionList from 'app/core/components/PermissionList/PermissionList'; +import PermissionsInfo from 'app/core/components/PermissionList/PermissionsInfo'; +import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; import { getNavModel } from 'app/core/selectors/navModel'; import { StoreState } from 'app/types'; import { DashboardAcl, PermissionLevel, NewDashboardAclItem } from 'app/types/acl'; + import { getFolderByUid, getFolderPermissions, @@ -14,10 +20,6 @@ import { addFolderPermission, } from './state/actions'; import { getLoadingNav } from './state/navModel'; -import PermissionList from 'app/core/components/PermissionList/PermissionList'; -import AddPermission from 'app/core/components/PermissionList/AddPermission'; -import PermissionsInfo from 'app/core/components/PermissionList/PermissionsInfo'; -import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; export interface OwnProps extends GrafanaRouteComponentProps<{ uid: string }> {} diff --git a/public/app/features/folders/FolderSettingsPage.test.tsx b/public/app/features/folders/FolderSettingsPage.test.tsx index 397e8380521..65f024996d3 100644 --- a/public/app/features/folders/FolderSettingsPage.test.tsx +++ b/public/app/features/folders/FolderSettingsPage.test.tsx @@ -1,11 +1,13 @@ -import React from 'react'; -import { FolderSettingsPage, Props } from './FolderSettingsPage'; import { shallow } from 'enzyme'; -import { NavModel } from '@grafana/data'; +import React from 'react'; import { mockToolkitActionCreator } from 'test/core/redux/mocks'; -import { setFolderTitle } from './state/reducers'; + +import { NavModel } from '@grafana/data'; import { getRouteComponentProps } from 'app/core/navigation/__mocks__/routeProps'; +import { FolderSettingsPage, Props } from './FolderSettingsPage'; +import { setFolderTitle } from './state/reducers'; + const setup = (propOverrides?: object) => { const props: Props = { ...getRouteComponentProps(), diff --git a/public/app/features/folders/FolderSettingsPage.tsx b/public/app/features/folders/FolderSettingsPage.tsx index bd3da44ba7e..16cf9a0392a 100644 --- a/public/app/features/folders/FolderSettingsPage.tsx +++ b/public/app/features/folders/FolderSettingsPage.tsx @@ -1,16 +1,19 @@ import React, { PureComponent } from 'react'; import { connect, ConnectedProps } from 'react-redux'; + import { Button, LegacyForms } from '@grafana/ui'; const { Input } = LegacyForms; -import Page from 'app/core/components/Page/Page'; import appEvents from 'app/core/app_events'; +import Page from 'app/core/components/Page/Page'; +import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; import { getNavModel } from 'app/core/selectors/navModel'; import { StoreState } from 'app/types'; + +import { ShowConfirmModalEvent } from '../../types/events'; + import { deleteFolder, getFolderByUid, saveFolder } from './state/actions'; import { getLoadingNav } from './state/navModel'; import { setFolderTitle } from './state/reducers'; -import { ShowConfirmModalEvent } from '../../types/events'; -import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; export interface OwnProps extends GrafanaRouteComponentProps<{ uid: string }> {} diff --git a/public/app/features/folders/components/NewDashboardsFolder.tsx b/public/app/features/folders/components/NewDashboardsFolder.tsx index a3ef23bf5bc..72617c8fbfe 100644 --- a/public/app/features/folders/components/NewDashboardsFolder.tsx +++ b/public/app/features/folders/components/NewDashboardsFolder.tsx @@ -1,11 +1,13 @@ import React, { PureComponent } from 'react'; import { connect, ConnectedProps } from 'react-redux'; + import { Button, Input, Form, Field } from '@grafana/ui'; import Page from 'app/core/components/Page/Page'; -import { createNewFolder } from '../state/actions'; import { getNavModel } from 'app/core/selectors/navModel'; import { StoreState } from 'app/types'; + import { validationSrv } from '../../manage-dashboards/services/ValidationSrv'; +import { createNewFolder } from '../state/actions'; const mapStateToProps = (state: StoreState) => ({ navModel: getNavModel(state.navIndex, 'manage-dashboards'), diff --git a/public/app/features/folders/state/actions.test.ts b/public/app/features/folders/state/actions.test.ts index bf471d2a7ba..dd2d35e822b 100644 --- a/public/app/features/folders/state/actions.test.ts +++ b/public/app/features/folders/state/actions.test.ts @@ -1,11 +1,13 @@ import { Observable, of, throwError } from 'rxjs'; import { thunkTester } from 'test/core/thunk/thunkTester'; -import { checkFolderPermissions } from './actions'; -import { setCanViewFolderPermissions } from './reducers'; -import { backendSrv } from 'app/core/services/backend_srv'; + +import { FetchResponse } from '@grafana/runtime'; import { notifyApp } from 'app/core/actions'; import { createWarningNotification } from 'app/core/copy/appNotification'; -import { FetchResponse } from '@grafana/runtime'; +import { backendSrv } from 'app/core/services/backend_srv'; + +import { checkFolderPermissions } from './actions'; +import { setCanViewFolderPermissions } from './reducers'; describe('folder actions', () => { let fetchSpy: jest.SpyInstance>>; diff --git a/public/app/features/folders/state/actions.ts b/public/app/features/folders/state/actions.ts index 4d6fa6548a5..1a754a5a8c7 100644 --- a/public/app/features/folders/state/actions.ts +++ b/public/app/features/folders/state/actions.ts @@ -1,3 +1,5 @@ +import { lastValueFrom } from 'rxjs'; + import { locationUtil } from '@grafana/data'; import { getBackendSrv, locationService } from '@grafana/runtime'; import { notifyApp, updateNavIndex } from 'app/core/actions'; @@ -6,7 +8,7 @@ import { contextSrv } from 'app/core/core'; import { backendSrv } from 'app/core/services/backend_srv'; import { FolderState, ThunkResult } from 'app/types'; import { DashboardAcl, DashboardAclUpdateDTO, NewDashboardAclItem, PermissionLevel } from 'app/types/acl'; -import { lastValueFrom } from 'rxjs'; + import { buildNavModel } from './navModel'; import { loadFolder, loadFolderPermissions, setCanViewFolderPermissions } from './reducers'; diff --git a/public/app/features/folders/state/navModel.ts b/public/app/features/folders/state/navModel.ts index 7f4a04e9b88..887d6c6a17a 100644 --- a/public/app/features/folders/state/navModel.ts +++ b/public/app/features/folders/state/navModel.ts @@ -1,6 +1,5 @@ import { NavModel, NavModelItem } from '@grafana/data'; import { contextSrv } from 'app/core/services/context_srv'; - import { AccessControlAction, FolderDTO } from 'app/types'; export function buildNavModel(folder: FolderDTO): NavModelItem { diff --git a/public/app/features/folders/state/reducers.test.ts b/public/app/features/folders/state/reducers.test.ts index 041efafe131..f68a707a591 100644 --- a/public/app/features/folders/state/reducers.test.ts +++ b/public/app/features/folders/state/reducers.test.ts @@ -1,4 +1,7 @@ import { FolderDTO, FolderState, OrgRole, PermissionLevel } from 'app/types'; + +import { reducerTester } from '../../../../test/core/redux/reducerTester'; + import { folderReducer, initialState, @@ -7,7 +10,6 @@ import { setCanViewFolderPermissions, setFolderTitle, } from './reducers'; -import { reducerTester } from '../../../../test/core/redux/reducerTester'; function getTestFolder(): FolderDTO { return { diff --git a/public/app/features/folders/state/reducers.ts b/public/app/features/folders/state/reducers.ts index 28fe7e10811..247fb5a84a0 100644 --- a/public/app/features/folders/state/reducers.ts +++ b/public/app/features/folders/state/reducers.ts @@ -1,7 +1,7 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit'; -import { DashboardAclDTO, FolderDTO, FolderState } from 'app/types'; import { processAclItems } from 'app/core/utils/acl'; +import { DashboardAclDTO, FolderDTO, FolderState } from 'app/types'; export const initialState: FolderState = { id: 0, diff --git a/public/app/features/geo/editor/GazetteerPathEditor.tsx b/public/app/features/geo/editor/GazetteerPathEditor.tsx index 2e4cf969e40..6a566193d7f 100644 --- a/public/app/features/geo/editor/GazetteerPathEditor.tsx +++ b/public/app/features/geo/editor/GazetteerPathEditor.tsx @@ -1,8 +1,10 @@ +import { css } from '@emotion/css'; import React, { FC, useMemo, useState, useEffect } from 'react'; + import { StandardEditorProps, SelectableValue, GrafanaTheme2 } from '@grafana/data'; import { Alert, Select, stylesFactory, useTheme2 } from '@grafana/ui'; + import { COUNTRIES_GAZETTEER_PATH, Gazetteer, getGazetteer } from '../gazetteer/gazetteer'; -import { css } from '@emotion/css'; const defaultPaths: Array> = [ { diff --git a/public/app/features/geo/format/geojson.test.ts b/public/app/features/geo/format/geojson.test.ts index 3f15737972c..fe00ba66035 100644 --- a/public/app/features/geo/format/geojson.test.ts +++ b/public/app/features/geo/format/geojson.test.ts @@ -1,4 +1,5 @@ import { dataFrameToJSON, FieldType } from '@grafana/data'; + import { frameFromGeoJSON } from './geojson'; describe('Read GeoJSON', () => { diff --git a/public/app/features/geo/format/geojson.ts b/public/app/features/geo/format/geojson.ts index 6811c6a94a4..447055c5fb0 100644 --- a/public/app/features/geo/format/geojson.ts +++ b/public/app/features/geo/format/geojson.ts @@ -1,7 +1,8 @@ -import { ArrayVector, DataFrame, Field, FieldType, getFieldTypeFromValue } from '@grafana/data'; import GeoJSON from 'ol/format/GeoJSON'; import { Geometry } from 'ol/geom'; +import { ArrayVector, DataFrame, Field, FieldType, getFieldTypeFromValue } from '@grafana/data'; + interface FieldInfo { values: any[]; types: Set; diff --git a/public/app/features/geo/format/utils.ts b/public/app/features/geo/format/utils.ts index e3d9149d70e..babba1cde80 100644 --- a/public/app/features/geo/format/utils.ts +++ b/public/app/features/geo/format/utils.ts @@ -1,8 +1,11 @@ -import { ArrayVector, Field, FieldConfig, FieldType } from '@grafana/data'; -import { getCenterPoint } from 'app/features/transformers/spatial/utils'; import { Geometry, GeometryCollection, LineString, Point } from 'ol/geom'; import { fromLonLat } from 'ol/proj'; + +import { ArrayVector, Field, FieldConfig, FieldType } from '@grafana/data'; +import { getCenterPoint } from 'app/features/transformers/spatial/utils'; + import { Gazetteer } from '../gazetteer/gazetteer'; + import { decodeGeohash } from './geohash'; export function pointFieldFromGeohash(geohash: Field): Field { diff --git a/public/app/features/geo/gazetteer/gazetteer.test.ts b/public/app/features/geo/gazetteer/gazetteer.test.ts index 7bff83cfb1c..f91d7d34fbd 100644 --- a/public/app/features/geo/gazetteer/gazetteer.test.ts +++ b/public/app/features/geo/gazetteer/gazetteer.test.ts @@ -1,4 +1,5 @@ import { getCenterPointWGS84 } from 'app/features/transformers/spatial/utils'; + import { getGazetteer } from './gazetteer'; let backendResults: any = { hello: 'world' }; diff --git a/public/app/features/geo/gazetteer/gazetteer.ts b/public/app/features/geo/gazetteer/gazetteer.ts index 9a6418cc95b..94b2b81a96a 100644 --- a/public/app/features/geo/gazetteer/gazetteer.ts +++ b/public/app/features/geo/gazetteer/gazetteer.ts @@ -1,10 +1,13 @@ +import { getCenter } from 'ol/extent'; +import { Geometry, Point } from 'ol/geom'; + import { DataFrame, Field, FieldType, KeyValue, toDataFrame } from '@grafana/data'; import { getBackendSrv } from '@grafana/runtime'; -import { loadWorldmapPoints } from './worldmap'; -import { Geometry, Point } from 'ol/geom'; + import { frameFromGeoJSON } from '../format/geojson'; import { pointFieldFromLonLat, pointFieldFromGeohash } from '../format/utils'; -import { getCenter } from 'ol/extent'; + +import { loadWorldmapPoints } from './worldmap'; export interface PlacenameInfo { point: () => Point | undefined; // lon, lat (WGS84) diff --git a/public/app/features/geo/gazetteer/worldmap.test.ts b/public/app/features/geo/gazetteer/worldmap.test.ts index 61b14ff94f3..a43471f7363 100644 --- a/public/app/features/geo/gazetteer/worldmap.test.ts +++ b/public/app/features/geo/gazetteer/worldmap.test.ts @@ -1,8 +1,10 @@ +import { toLonLat } from 'ol/proj'; + +import countriesJSON from '../../../../gazetteer/countries.json'; + import { getGazetteer } from './gazetteer'; let backendResults: any = { hello: 'world' }; -import countriesJSON from '../../../../gazetteer/countries.json'; -import { toLonLat } from 'ol/proj'; jest.mock('@grafana/runtime', () => ({ ...(jest.requireActual('@grafana/runtime') as unknown as object), diff --git a/public/app/features/geo/gazetteer/worldmap.ts b/public/app/features/geo/gazetteer/worldmap.ts index 799fe7c64ce..17a63b4823d 100644 --- a/public/app/features/geo/gazetteer/worldmap.ts +++ b/public/app/features/geo/gazetteer/worldmap.ts @@ -1,7 +1,8 @@ -import { PlacenameInfo, Gazetteer } from './gazetteer'; import { Point } from 'ol/geom'; import { fromLonLat } from 'ol/proj'; +import { PlacenameInfo, Gazetteer } from './gazetteer'; + // https://github.com/grafana/worldmap-panel/blob/master/src/data/countries.json export interface WorldmapPoint { key?: string; diff --git a/public/app/features/geo/utils/frameVectorSource.ts b/public/app/features/geo/utils/frameVectorSource.ts index 393b40cc2f8..704af664887 100644 --- a/public/app/features/geo/utils/frameVectorSource.ts +++ b/public/app/features/geo/utils/frameVectorSource.ts @@ -1,7 +1,9 @@ -import { DataFrame } from '@grafana/data'; import { Feature } from 'ol'; import { Geometry } from 'ol/geom'; import VectorSource from 'ol/source/Vector'; + +import { DataFrame } from '@grafana/data'; + import { getGeometryField, LocationFieldMatchers } from './location'; export interface FrameVectorSourceOptions {} diff --git a/public/app/features/geo/utils/location.test.ts b/public/app/features/geo/utils/location.test.ts index 3b3ef12754c..d816361d477 100644 --- a/public/app/features/geo/utils/location.test.ts +++ b/public/app/features/geo/utils/location.test.ts @@ -1,6 +1,8 @@ -import { toDataFrame, FieldType, FrameGeometrySourceMode } from '@grafana/data'; import { Point } from 'ol/geom'; import { toLonLat } from 'ol/proj'; + +import { toDataFrame, FieldType, FrameGeometrySourceMode } from '@grafana/data'; + import { getGeometryField, getLocationFields, getLocationMatchers } from './location'; const longitude = [0, -74.1]; diff --git a/public/app/features/geo/utils/location.ts b/public/app/features/geo/utils/location.ts index 22348e13423..c9f552fa1c2 100644 --- a/public/app/features/geo/utils/location.ts +++ b/public/app/features/geo/utils/location.ts @@ -1,3 +1,5 @@ +import { Geometry } from 'ol/geom'; + import { FrameGeometrySource, FrameGeometrySourceMode, @@ -9,9 +11,9 @@ import { getFieldDisplayName, FieldType, } from '@grafana/data'; -import { Geometry } from 'ol/geom'; -import { getGazetteer, Gazetteer } from '../gazetteer/gazetteer'; + import { getGeoFieldFromGazetteer, pointFieldFromGeohash, pointFieldFromLonLat } from '../format/utils'; +import { getGazetteer, Gazetteer } from '../gazetteer/gazetteer'; export type FieldFinder = (frame: DataFrame) => Field | undefined; diff --git a/public/app/features/inspector/DetailText.tsx b/public/app/features/inspector/DetailText.tsx index 887c041e5b4..73342a1b584 100644 --- a/public/app/features/inspector/DetailText.tsx +++ b/public/app/features/inspector/DetailText.tsx @@ -1,7 +1,8 @@ -import React, { FC } from 'react'; -import { useStyles } from '@grafana/ui'; -import { GrafanaTheme } from '@grafana/data'; import { css } from '@emotion/css'; +import React, { FC } from 'react'; + +import { GrafanaTheme } from '@grafana/data'; +import { useStyles } from '@grafana/ui'; const getStyles = (theme: GrafanaTheme) => css` margin: 0; diff --git a/public/app/features/inspector/InspectDataOptions.tsx b/public/app/features/inspector/InspectDataOptions.tsx index 32339b03b1a..46553d87cbb 100644 --- a/public/app/features/inspector/InspectDataOptions.tsx +++ b/public/app/features/inspector/InspectDataOptions.tsx @@ -1,11 +1,13 @@ import React, { FC } from 'react'; + import { DataFrame, DataTransformerID, getFrameDisplayName, SelectableValue } from '@grafana/data'; import { Field, HorizontalGroup, Select, Switch, VerticalGroup } from '@grafana/ui'; -import { getPanelInspectorStyles } from './styles'; -import { GetDataOptions } from 'app/features/query/state/PanelQueryRunner'; import { QueryOperationRow } from 'app/core/components/QueryOperationRow/QueryOperationRow'; import { PanelModel } from 'app/features/dashboard/state'; import { DetailText } from 'app/features/inspector/DetailText'; +import { GetDataOptions } from 'app/features/query/state/PanelQueryRunner'; + +import { getPanelInspectorStyles } from './styles'; interface Props { options: GetDataOptions; diff --git a/public/app/features/inspector/InspectDataTab.test.tsx b/public/app/features/inspector/InspectDataTab.test.tsx index 15e8d2591db..273fd164696 100644 --- a/public/app/features/inspector/InspectDataTab.test.tsx +++ b/public/app/features/inspector/InspectDataTab.test.tsx @@ -1,7 +1,9 @@ -import React, { ComponentProps } from 'react'; -import { DataFrame, FieldType } from '@grafana/data'; import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import React, { ComponentProps } from 'react'; + +import { DataFrame, FieldType } from '@grafana/data'; + import { InspectDataTab } from './InspectDataTab'; // the mock below gets rid of this warning from recompose: diff --git a/public/app/features/inspector/InspectDataTab.tsx b/public/app/features/inspector/InspectDataTab.tsx index 3f7a43e0c52..6fed6dbfdce 100644 --- a/public/app/features/inspector/InspectDataTab.tsx +++ b/public/app/features/inspector/InspectDataTab.tsx @@ -1,5 +1,8 @@ +import { css } from '@emotion/css'; +import { saveAs } from 'file-saver'; import React, { PureComponent } from 'react'; import AutoSizer from 'react-virtualized-auto-sizer'; + import { applyFieldOverrides, applyRawFieldOverrides, @@ -14,19 +17,18 @@ import { transformDataFrame, TimeZone, } from '@grafana/data'; -import { Button, Spinner, Table } from '@grafana/ui'; import { selectors } from '@grafana/e2e-selectors'; +import { Button, Spinner, Table } from '@grafana/ui'; +import { config } from 'app/core/config'; +import { dataFrameToLogsModel } from 'app/core/logs_model'; +import { PanelModel } from 'app/features/dashboard/state'; +import { GetDataOptions } from 'app/features/query/state/PanelQueryRunner'; +import { transformToJaeger } from 'app/plugins/datasource/jaeger/responseTransform'; +import { transformToOTLP } from 'app/plugins/datasource/tempo/resultTransformer'; +import { transformToZipkin } from 'app/plugins/datasource/zipkin/utils/transforms'; + import { InspectDataOptions } from './InspectDataOptions'; import { getPanelInspectorStyles } from './styles'; -import { config } from 'app/core/config'; -import { saveAs } from 'file-saver'; -import { css } from '@emotion/css'; -import { GetDataOptions } from 'app/features/query/state/PanelQueryRunner'; -import { PanelModel } from 'app/features/dashboard/state'; -import { dataFrameToLogsModel } from 'app/core/logs_model'; -import { transformToJaeger } from 'app/plugins/datasource/jaeger/responseTransform'; -import { transformToZipkin } from 'app/plugins/datasource/zipkin/utils/transforms'; -import { transformToOTLP } from 'app/plugins/datasource/tempo/resultTransformer'; interface Props { isLoading: boolean; diff --git a/public/app/features/inspector/InspectErrorTab.test.tsx b/public/app/features/inspector/InspectErrorTab.test.tsx index 07531dbb3e3..d86db092516 100644 --- a/public/app/features/inspector/InspectErrorTab.test.tsx +++ b/public/app/features/inspector/InspectErrorTab.test.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; +import React from 'react'; + import { InspectErrorTab } from './InspectErrorTab'; describe('InspectErrorTab', () => { diff --git a/public/app/features/inspector/InspectErrorTab.tsx b/public/app/features/inspector/InspectErrorTab.tsx index 55fe2d89cae..f3609b187f4 100644 --- a/public/app/features/inspector/InspectErrorTab.tsx +++ b/public/app/features/inspector/InspectErrorTab.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { DataQueryError } from '@grafana/data'; import { JSONFormatter } from '@grafana/ui'; diff --git a/public/app/features/inspector/InspectJSONTab.tsx b/public/app/features/inspector/InspectJSONTab.tsx index acc6d4b3c95..b0ec6db4f52 100644 --- a/public/app/features/inspector/InspectJSONTab.tsx +++ b/public/app/features/inspector/InspectJSONTab.tsx @@ -1,10 +1,12 @@ import React, { PureComponent } from 'react'; -import { AppEvents, dataFrameToJSON, PanelData, SelectableValue } from '@grafana/data'; -import { Button, CodeEditor, Field, Select } from '@grafana/ui'; import AutoSizer from 'react-virtualized-auto-sizer'; + +import { AppEvents, dataFrameToJSON, PanelData, SelectableValue } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; +import { Button, CodeEditor, Field, Select } from '@grafana/ui'; import { appEvents } from 'app/core/core'; import { DashboardModel, PanelModel } from 'app/features/dashboard/state'; + import { getPanelInspectorStyles } from '../inspector/styles'; enum ShowContent { diff --git a/public/app/features/inspector/InspectMetadataTab.tsx b/public/app/features/inspector/InspectMetadataTab.tsx index a3ab5bda303..cbb7bcfa186 100644 --- a/public/app/features/inspector/InspectMetadataTab.tsx +++ b/public/app/features/inspector/InspectMetadataTab.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { DataSourceApi, PanelData } from '@grafana/data'; interface InspectMetadataTabProps { diff --git a/public/app/features/inspector/InspectStatsTab.tsx b/public/app/features/inspector/InspectStatsTab.tsx index d6508f0e736..22290245b52 100644 --- a/public/app/features/inspector/InspectStatsTab.tsx +++ b/public/app/features/inspector/InspectStatsTab.tsx @@ -1,7 +1,9 @@ +import React from 'react'; + import { PanelData, QueryResultMetaStat, TimeZone } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; + import { InspectStatsTable } from './InspectStatsTable'; -import React from 'react'; interface InspectStatsTabProps { data: PanelData; diff --git a/public/app/features/inspector/InspectStatsTable.tsx b/public/app/features/inspector/InspectStatsTable.tsx index 52dfc62b77c..cc1c5ba6665 100644 --- a/public/app/features/inspector/InspectStatsTable.tsx +++ b/public/app/features/inspector/InspectStatsTable.tsx @@ -1,4 +1,6 @@ +import { css } from '@emotion/css'; import React from 'react'; + import { FieldType, formattedValueToString, @@ -8,7 +10,6 @@ import { TimeZone, } from '@grafana/data'; import { stylesFactory, useTheme2 } from '@grafana/ui'; -import { css } from '@emotion/css'; interface InspectStatsTableProps { timeZone: TimeZone; diff --git a/public/app/features/inspector/QueryInspector.tsx b/public/app/features/inspector/QueryInspector.tsx index 33bffef9592..3fd492e1dfc 100644 --- a/public/app/features/inspector/QueryInspector.tsx +++ b/public/app/features/inspector/QueryInspector.tsx @@ -1,17 +1,18 @@ -import React, { PureComponent } from 'react'; -import { Button, ClipboardButton, JSONFormatter, LoadingPlaceholder } from '@grafana/ui'; -import { selectors } from '@grafana/e2e-selectors'; -import { AppEvents, DataFrame } from '@grafana/data'; - -import appEvents from 'app/core/app_events'; -import { PanelModel } from 'app/features/dashboard/state'; -import { getPanelInspectorStyles } from './styles'; -import { supportsDataQuery } from 'app/features/dashboard/components/PanelEditor/utils'; -import { config, RefreshEvent } from '@grafana/runtime'; import { css } from '@emotion/css'; +import React, { PureComponent } from 'react'; import { Subscription } from 'rxjs'; -import { backendSrv } from 'app/core/services/backend_srv'; + +import { AppEvents, DataFrame } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; import { Stack } from '@grafana/experimental'; +import { config, RefreshEvent } from '@grafana/runtime'; +import { Button, ClipboardButton, JSONFormatter, LoadingPlaceholder } from '@grafana/ui'; +import appEvents from 'app/core/app_events'; +import { backendSrv } from 'app/core/services/backend_srv'; +import { supportsDataQuery } from 'app/features/dashboard/components/PanelEditor/utils'; +import { PanelModel } from 'app/features/dashboard/state'; + +import { getPanelInspectorStyles } from './styles'; interface DsQuery { isLoading: boolean; diff --git a/public/app/features/inspector/styles.ts b/public/app/features/inspector/styles.ts index 5e9873ceffd..66aef0e653d 100644 --- a/public/app/features/inspector/styles.ts +++ b/public/app/features/inspector/styles.ts @@ -1,6 +1,7 @@ import { css } from '@emotion/css'; -import { config } from 'app/core/config'; + import { stylesFactory } from '@grafana/ui'; +import { config } from 'app/core/config'; export const getPanelInspectorStyles = stylesFactory(() => { return { diff --git a/public/app/features/invites/InviteeRow.tsx b/public/app/features/invites/InviteeRow.tsx index 1f5007df263..51425cee932 100644 --- a/public/app/features/invites/InviteeRow.tsx +++ b/public/app/features/invites/InviteeRow.tsx @@ -1,8 +1,10 @@ import React, { PureComponent } from 'react'; import { connect, ConnectedProps } from 'react-redux'; -import { Invitee } from 'app/types'; -import { revokeInvite } from './state/actions'; + import { Button, ClipboardButton } from '@grafana/ui'; +import { Invitee } from 'app/types'; + +import { revokeInvite } from './state/actions'; const mapDispatchToProps = { revokeInvite, diff --git a/public/app/features/invites/InviteesTable.test.tsx b/public/app/features/invites/InviteesTable.test.tsx index e776b52e714..3cdc53b069b 100644 --- a/public/app/features/invites/InviteesTable.test.tsx +++ b/public/app/features/invites/InviteesTable.test.tsx @@ -1,9 +1,12 @@ -import React from 'react'; import { shallow } from 'enzyme'; -import InviteesTable, { Props } from './InviteesTable'; +import React from 'react'; + import { Invitee } from 'app/types'; + import { getMockInvitees } from '../users/__mocks__/userMocks'; +import InviteesTable, { Props } from './InviteesTable'; + const setup = (propOverrides?: object) => { const props: Props = { invitees: [] as Invitee[], diff --git a/public/app/features/invites/InviteesTable.tsx b/public/app/features/invites/InviteesTable.tsx index fa5fd087a2f..3720c239fac 100644 --- a/public/app/features/invites/InviteesTable.tsx +++ b/public/app/features/invites/InviteesTable.tsx @@ -1,5 +1,7 @@ import React, { PureComponent } from 'react'; + import { Invitee } from 'app/types'; + import InviteeRow from './InviteeRow'; export interface Props { diff --git a/public/app/features/invites/SignupInvited.test.tsx b/public/app/features/invites/SignupInvited.test.tsx index c5202a15eac..d16170371e9 100644 --- a/public/app/features/invites/SignupInvited.test.tsx +++ b/public/app/features/invites/SignupInvited.test.tsx @@ -1,10 +1,12 @@ -import React from 'react'; import { render, screen, waitFor, within } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import React from 'react'; + +import { getRouteComponentProps } from 'app/core/navigation/__mocks__/routeProps'; + +import { backendSrv } from '../../core/services/backend_srv'; import { SignupInvitedPage, Props } from './SignupInvited'; -import { backendSrv } from '../../core/services/backend_srv'; -import { getRouteComponentProps } from 'app/core/navigation/__mocks__/routeProps'; jest.mock('app/core/core', () => ({ contextSrv: { diff --git a/public/app/features/invites/SignupInvited.tsx b/public/app/features/invites/SignupInvited.tsx index 57cfe41a5df..4d862d6377d 100644 --- a/public/app/features/invites/SignupInvited.tsx +++ b/public/app/features/invites/SignupInvited.tsx @@ -1,10 +1,11 @@ import React, { FC, useState } from 'react'; +import { useAsync } from 'react-use'; + import { getBackendSrv } from '@grafana/runtime'; import { Button, Field, Form, Input } from '@grafana/ui'; -import { useAsync } from 'react-use'; import Page from 'app/core/components/Page/Page'; -import { contextSrv } from 'app/core/core'; import { getConfig } from 'app/core/config'; +import { contextSrv } from 'app/core/core'; import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; interface FormModel { diff --git a/public/app/features/invites/state/reducers.test.ts b/public/app/features/invites/state/reducers.test.ts index e4563709220..9ac92e88f68 100644 --- a/public/app/features/invites/state/reducers.test.ts +++ b/public/app/features/invites/state/reducers.test.ts @@ -1,9 +1,12 @@ import { keyBy } from 'lodash'; -import { reducerTester } from '../../../../test/core/redux/reducerTester'; -import { initialState, invitesReducer } from './reducers'; -import { fetchInvitees, revokeInvite } from './actions'; + import { getMockInvitees } from 'app/features/users/__mocks__/userMocks'; +import { reducerTester } from '../../../../test/core/redux/reducerTester'; + +import { fetchInvitees, revokeInvite } from './actions'; +import { initialState, invitesReducer } from './reducers'; + describe('inviteesReducer', () => { describe('when fetchInvitees is dispatched', () => { it('then state should be correct', () => { diff --git a/public/app/features/invites/state/reducers.ts b/public/app/features/invites/state/reducers.ts index bad26fdc938..35ac54eeca0 100644 --- a/public/app/features/invites/state/reducers.ts +++ b/public/app/features/invites/state/reducers.ts @@ -1,5 +1,7 @@ import { createEntityAdapter, createSlice } from '@reduxjs/toolkit'; + import { Invitee } from 'app/types'; + import { fetchInvitees, revokeInvite } from './actions'; export type Status = 'idle' | 'loading' | 'succeeded' | 'failed'; diff --git a/public/app/features/invites/state/selectors.ts b/public/app/features/invites/state/selectors.ts index 7a9468dbde9..daf42e464bc 100644 --- a/public/app/features/invites/state/selectors.ts +++ b/public/app/features/invites/state/selectors.ts @@ -1,4 +1,5 @@ import { createSelector } from '@reduxjs/toolkit'; + import { selectors } from './reducers'; export const { selectAll, selectById, selectTotal } = selectors; diff --git a/public/app/features/library-panels/LibraryPanelsPage.tsx b/public/app/features/library-panels/LibraryPanelsPage.tsx index e13d5937643..09342b0e5cf 100644 --- a/public/app/features/library-panels/LibraryPanelsPage.tsx +++ b/public/app/features/library-panels/LibraryPanelsPage.tsx @@ -1,13 +1,14 @@ import React, { FC, useState } from 'react'; import { connect, ConnectedProps } from 'react-redux'; -import { GrafanaRouteComponentProps } from '../../core/navigation/types'; -import { StoreState } from '../../types'; -import { getNavModel } from '../../core/selectors/navModel'; import Page from '../../core/components/Page/Page'; +import { GrafanaRouteComponentProps } from '../../core/navigation/types'; +import { getNavModel } from '../../core/selectors/navModel'; +import { StoreState } from '../../types'; + import { LibraryPanelsSearch } from './components/LibraryPanelsSearch/LibraryPanelsSearch'; -import { LibraryElementDTO } from './types'; import { OpenLibraryPanelModal } from './components/OpenLibraryPanelModal/OpenLibraryPanelModal'; +import { LibraryElementDTO } from './types'; const mapStateToProps = (state: StoreState) => ({ navModel: getNavModel(state.navIndex, 'library-panels'), diff --git a/public/app/features/library-panels/components/AddLibraryPanelModal/AddLibraryPanelModal.tsx b/public/app/features/library-panels/components/AddLibraryPanelModal/AddLibraryPanelModal.tsx index e8c12b97c3d..7173d22125f 100644 --- a/public/app/features/library-panels/components/AddLibraryPanelModal/AddLibraryPanelModal.tsx +++ b/public/app/features/library-panels/components/AddLibraryPanelModal/AddLibraryPanelModal.tsx @@ -1,10 +1,12 @@ import React, { useCallback, useEffect, useState } from 'react'; +import { useAsync, useDebounce } from 'react-use'; + import { Button, Field, Input, Modal } from '@grafana/ui'; import { FolderPicker } from 'app/core/components/Select/FolderPicker'; + import { PanelModel } from '../../../dashboard/state'; -import { usePanelSave } from '../../utils/usePanelSave'; -import { useAsync, useDebounce } from 'react-use'; import { getLibraryPanelByName } from '../../state/api'; +import { usePanelSave } from '../../utils/usePanelSave'; interface AddLibraryPanelContentsProps { onDismiss: () => void; diff --git a/public/app/features/library-panels/components/ChangeLibraryPanelModal/ChangeLibraryPanelModal.tsx b/public/app/features/library-panels/components/ChangeLibraryPanelModal/ChangeLibraryPanelModal.tsx index c6b7697c2f4..f42ab49b6bb 100644 --- a/public/app/features/library-panels/components/ChangeLibraryPanelModal/ChangeLibraryPanelModal.tsx +++ b/public/app/features/library-panels/components/ChangeLibraryPanelModal/ChangeLibraryPanelModal.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { ConfirmModal } from '@grafana/ui'; import { PanelModel } from '../../../dashboard/state'; diff --git a/public/app/features/library-panels/components/DeleteLibraryPanelModal/DeleteLibraryPanelModal.tsx b/public/app/features/library-panels/components/DeleteLibraryPanelModal/DeleteLibraryPanelModal.tsx index 0f2da652370..5ef9b35e88d 100644 --- a/public/app/features/library-panels/components/DeleteLibraryPanelModal/DeleteLibraryPanelModal.tsx +++ b/public/app/features/library-panels/components/DeleteLibraryPanelModal/DeleteLibraryPanelModal.tsx @@ -1,12 +1,14 @@ import React, { FC, useEffect, useMemo, useReducer } from 'react'; -import { Button, Modal, useStyles } from '@grafana/ui'; -import { LoadingState } from '@grafana/data'; +import { LoadingState } from '@grafana/data'; +import { Button, Modal, useStyles } from '@grafana/ui'; + +import { getModalStyles } from '../../styles'; import { LibraryElementDTO } from '../../types'; import { asyncDispatcher } from '../LibraryPanelsView/actions'; -import { deleteLibraryPanelModalReducer, initialDeleteLibraryPanelModalState } from './reducer'; + import { getConnectedDashboards } from './actions'; -import { getModalStyles } from '../../styles'; +import { deleteLibraryPanelModalReducer, initialDeleteLibraryPanelModalState } from './reducer'; interface Props { libraryPanel: LibraryElementDTO; diff --git a/public/app/features/library-panels/components/DeleteLibraryPanelModal/actions.ts b/public/app/features/library-panels/components/DeleteLibraryPanelModal/actions.ts index 0d7784495c8..5b8e2e18911 100644 --- a/public/app/features/library-panels/components/DeleteLibraryPanelModal/actions.ts +++ b/public/app/features/library-panels/components/DeleteLibraryPanelModal/actions.ts @@ -1,5 +1,6 @@ -import { DispatchResult, LibraryElementDTO } from '../../types'; import { getConnectedDashboards as apiGetConnectedDashboards } from '../../state/api'; +import { DispatchResult, LibraryElementDTO } from '../../types'; + import { searchCompleted } from './reducer'; export function getConnectedDashboards(libraryPanel: LibraryElementDTO): DispatchResult { diff --git a/public/app/features/library-panels/components/DeleteLibraryPanelModal/reducer.test.ts b/public/app/features/library-panels/components/DeleteLibraryPanelModal/reducer.test.ts index 78d9265edce..f2604303d3f 100644 --- a/public/app/features/library-panels/components/DeleteLibraryPanelModal/reducer.test.ts +++ b/public/app/features/library-panels/components/DeleteLibraryPanelModal/reducer.test.ts @@ -1,11 +1,13 @@ +import { LoadingState } from '@grafana/data'; + import { reducerTester } from '../../../../../test/core/redux/reducerTester'; + import { deleteLibraryPanelModalReducer, DeleteLibraryPanelModalState, initialDeleteLibraryPanelModalState, searchCompleted, } from './reducer'; -import { LoadingState } from '@grafana/data'; describe('deleteLibraryPanelModalReducer', () => { describe('when created', () => { diff --git a/public/app/features/library-panels/components/DeleteLibraryPanelModal/reducer.ts b/public/app/features/library-panels/components/DeleteLibraryPanelModal/reducer.ts index 091b4f499de..0f019572df4 100644 --- a/public/app/features/library-panels/components/DeleteLibraryPanelModal/reducer.ts +++ b/public/app/features/library-panels/components/DeleteLibraryPanelModal/reducer.ts @@ -1,7 +1,8 @@ -import { DashboardSearchHit } from 'app/features/search/types'; -import { LoadingState } from '@grafana/data'; -import { AnyAction } from 'redux'; import { createAction } from '@reduxjs/toolkit'; +import { AnyAction } from 'redux'; + +import { LoadingState } from '@grafana/data'; +import { DashboardSearchHit } from 'app/features/search/types'; export interface DeleteLibraryPanelModalState { loadingState: LoadingState; diff --git a/public/app/features/library-panels/components/LibraryPanelCard/LibraryPanelCard.tsx b/public/app/features/library-panels/components/LibraryPanelCard/LibraryPanelCard.tsx index a1578e21014..1717ab7c313 100644 --- a/public/app/features/library-panels/components/LibraryPanelCard/LibraryPanelCard.tsx +++ b/public/app/features/library-panels/components/LibraryPanelCard/LibraryPanelCard.tsx @@ -1,12 +1,14 @@ -import React, { ReactElement, useState } from 'react'; import { css } from '@emotion/css'; +import React, { ReactElement, useState } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; -import { Icon, Link, useStyles2 } from '@grafana/ui'; -import { LibraryElementDTO } from '../../types'; -import { PanelTypeCard } from 'app/features/panel/components/VizTypePicker/PanelTypeCard'; -import { DeleteLibraryPanelModal } from '../DeleteLibraryPanelModal/DeleteLibraryPanelModal'; import { config } from '@grafana/runtime'; +import { Icon, Link, useStyles2 } from '@grafana/ui'; import { getPanelPluginNotFound } from 'app/features/panel/components/PanelPluginError'; +import { PanelTypeCard } from 'app/features/panel/components/VizTypePicker/PanelTypeCard'; + +import { LibraryElementDTO } from '../../types'; +import { DeleteLibraryPanelModal } from '../DeleteLibraryPanelModal/DeleteLibraryPanelModal'; export interface LibraryPanelCardProps { libraryPanel: LibraryElementDTO; diff --git a/public/app/features/library-panels/components/LibraryPanelInfo/LibraryPanelInfo.tsx b/public/app/features/library-panels/components/LibraryPanelInfo/LibraryPanelInfo.tsx index 462f92fa0d0..57f472a9d33 100644 --- a/public/app/features/library-panels/components/LibraryPanelInfo/LibraryPanelInfo.tsx +++ b/public/app/features/library-panels/components/LibraryPanelInfo/LibraryPanelInfo.tsx @@ -1,9 +1,11 @@ -import { DateTimeInput, GrafanaTheme } from '@grafana/data'; -import { useStyles } from '@grafana/ui'; import { css } from '@emotion/css'; import React from 'react'; -import { PanelModelWithLibraryPanel } from '../../types'; + +import { DateTimeInput, GrafanaTheme } from '@grafana/data'; +import { useStyles } from '@grafana/ui'; + import { isPanelModelLibraryPanel } from '../../guard'; +import { PanelModelWithLibraryPanel } from '../../types'; interface Props { panel: PanelModelWithLibraryPanel; diff --git a/public/app/features/library-panels/components/LibraryPanelsSearch/LibraryPanelsSearch.test.tsx b/public/app/features/library-panels/components/LibraryPanelsSearch/LibraryPanelsSearch.test.tsx index e6ced466761..80244f7e6e5 100644 --- a/public/app/features/library-panels/components/LibraryPanelsSearch/LibraryPanelsSearch.test.tsx +++ b/public/app/features/library-panels/components/LibraryPanelsSearch/LibraryPanelsSearch.test.tsx @@ -1,14 +1,16 @@ -import React from 'react'; -import { render, screen, waitFor } from '@testing-library/react'; import { within } from '@testing-library/dom'; +import { render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import React from 'react'; + import { PanelPluginMeta, PluginType } from '@grafana/data'; -import { LibraryPanelsSearch, LibraryPanelsSearchProps } from './LibraryPanelsSearch'; -import * as api from '../../state/api'; -import { LibraryElementKind, LibraryElementsSearchResult } from '../../types'; import { backendSrv } from '../../../../core/services/backend_srv'; import * as panelUtils from '../../../panel/state/util'; +import * as api from '../../state/api'; +import { LibraryElementKind, LibraryElementsSearchResult } from '../../types'; + +import { LibraryPanelsSearch, LibraryPanelsSearchProps } from './LibraryPanelsSearch'; jest.mock('@grafana/runtime', () => ({ ...(jest.requireActual('@grafana/runtime') as unknown as object), diff --git a/public/app/features/library-panels/components/LibraryPanelsSearch/LibraryPanelsSearch.tsx b/public/app/features/library-panels/components/LibraryPanelsSearch/LibraryPanelsSearch.tsx index 728db2ca9e3..fcd6a5a8086 100644 --- a/public/app/features/library-panels/components/LibraryPanelsSearch/LibraryPanelsSearch.tsx +++ b/public/app/features/library-panels/components/LibraryPanelsSearch/LibraryPanelsSearch.tsx @@ -1,14 +1,17 @@ -import React, { useReducer } from 'react'; -import { HorizontalGroup, useStyles2, VerticalGroup, FilterInput } from '@grafana/ui'; -import { GrafanaTheme2, PanelPluginMeta, SelectableValue } from '@grafana/data'; import { css } from '@emotion/css'; -import { SortPicker } from '../../../../core/components/Select/SortPicker'; -import { PanelTypeFilter } from '../../../../core/components/PanelTypeFilter/PanelTypeFilter'; -import { LibraryPanelsView } from '../LibraryPanelsView/LibraryPanelsView'; -import { DEFAULT_PER_PAGE_PAGINATION } from '../../../../core/constants'; -import { LibraryElementDTO } from '../../types'; +import React, { useReducer } from 'react'; + +import { GrafanaTheme2, PanelPluginMeta, SelectableValue } from '@grafana/data'; +import { HorizontalGroup, useStyles2, VerticalGroup, FilterInput } from '@grafana/ui'; + import { FolderFilter } from '../../../../core/components/FolderFilter/FolderFilter'; +import { PanelTypeFilter } from '../../../../core/components/PanelTypeFilter/PanelTypeFilter'; +import { SortPicker } from '../../../../core/components/Select/SortPicker'; +import { DEFAULT_PER_PAGE_PAGINATION } from '../../../../core/constants'; import { FolderInfo } from '../../../../types'; +import { LibraryElementDTO } from '../../types'; +import { LibraryPanelsView } from '../LibraryPanelsView/LibraryPanelsView'; + import { folderFilterChanged, initialLibraryPanelsSearchState, diff --git a/public/app/features/library-panels/components/LibraryPanelsSearch/reducer.test.ts b/public/app/features/library-panels/components/LibraryPanelsSearch/reducer.test.ts index e887a5588b6..b6d9f5cb989 100644 --- a/public/app/features/library-panels/components/LibraryPanelsSearch/reducer.test.ts +++ b/public/app/features/library-panels/components/LibraryPanelsSearch/reducer.test.ts @@ -1,4 +1,5 @@ import { reducerTester } from '../../../../../test/core/redux/reducerTester'; + import { folderFilterChanged, initialLibraryPanelsSearchState, diff --git a/public/app/features/library-panels/components/LibraryPanelsSearch/reducer.ts b/public/app/features/library-panels/components/LibraryPanelsSearch/reducer.ts index 1a81e65d427..0e009bb76d8 100644 --- a/public/app/features/library-panels/components/LibraryPanelsSearch/reducer.ts +++ b/public/app/features/library-panels/components/LibraryPanelsSearch/reducer.ts @@ -1,5 +1,6 @@ -import { AnyAction } from 'redux'; import { createAction } from '@reduxjs/toolkit'; +import { AnyAction } from 'redux'; + import { PanelPluginMeta, SelectableValue } from '@grafana/data'; import { FolderInfo } from '../../../../types'; diff --git a/public/app/features/library-panels/components/LibraryPanelsView/LibraryPanelsView.tsx b/public/app/features/library-panels/components/LibraryPanelsView/LibraryPanelsView.tsx index cecfec6d7be..c3b7c9dd866 100644 --- a/public/app/features/library-panels/components/LibraryPanelsView/LibraryPanelsView.tsx +++ b/public/app/features/library-panels/components/LibraryPanelsView/LibraryPanelsView.tsx @@ -1,13 +1,15 @@ +import { css, cx } from '@emotion/css'; import React, { useMemo, useReducer } from 'react'; import { useDebounce } from 'react-use'; -import { css, cx } from '@emotion/css'; -import { Pagination, useStyles } from '@grafana/ui'; -import { GrafanaTheme, LoadingState } from '@grafana/data'; -import { LibraryPanelCard } from '../LibraryPanelCard/LibraryPanelCard'; +import { GrafanaTheme, LoadingState } from '@grafana/data'; +import { Pagination, useStyles } from '@grafana/ui'; + import { LibraryElementDTO } from '../../types'; -import { changePage, initialLibraryPanelsViewState, libraryPanelsViewReducer } from './reducer'; +import { LibraryPanelCard } from '../LibraryPanelCard/LibraryPanelCard'; + import { asyncDispatcher, deleteLibraryPanel, searchForLibraryPanels } from './actions'; +import { changePage, initialLibraryPanelsViewState, libraryPanelsViewReducer } from './reducer'; interface LibraryPanelViewProps { className?: string; diff --git a/public/app/features/library-panels/components/LibraryPanelsView/actions.ts b/public/app/features/library-panels/components/LibraryPanelsView/actions.ts index 8dbd962787c..f304c318f22 100644 --- a/public/app/features/library-panels/components/LibraryPanelsView/actions.ts +++ b/public/app/features/library-panels/components/LibraryPanelsView/actions.ts @@ -1,9 +1,10 @@ -import { Dispatch } from 'react'; import { AnyAction } from '@reduxjs/toolkit'; +import { Dispatch } from 'react'; import { from, merge, of, Subscription, timer } from 'rxjs'; import { catchError, finalize, mapTo, mergeMap, share, takeUntil } from 'rxjs/operators'; import { deleteLibraryPanel as apiDeleteLibraryPanel, getLibraryPanels } from '../../state/api'; + import { initialLibraryPanelsViewState, initSearch, searchCompleted } from './reducer'; type DispatchResult = (dispatch: Dispatch) => void; diff --git a/public/app/features/library-panels/components/LibraryPanelsView/reducer.test.ts b/public/app/features/library-panels/components/LibraryPanelsView/reducer.test.ts index 9b9864d5bc3..be4cbad2922 100644 --- a/public/app/features/library-panels/components/LibraryPanelsView/reducer.test.ts +++ b/public/app/features/library-panels/components/LibraryPanelsView/reducer.test.ts @@ -1,6 +1,8 @@ import { LoadingState } from '@grafana/data'; import { reducerTester } from '../../../../../test/core/redux/reducerTester'; +import { LibraryElementDTO, LibraryElementKind } from '../../types'; + import { changePage, initialLibraryPanelsViewState, @@ -9,7 +11,6 @@ import { LibraryPanelsViewState, searchCompleted, } from './reducer'; -import { LibraryElementDTO, LibraryElementKind } from '../../types'; describe('libraryPanelsViewReducer', () => { describe('when initSearch is dispatched', () => { diff --git a/public/app/features/library-panels/components/LibraryPanelsView/reducer.ts b/public/app/features/library-panels/components/LibraryPanelsView/reducer.ts index 4d4726f0183..b72a261853c 100644 --- a/public/app/features/library-panels/components/LibraryPanelsView/reducer.ts +++ b/public/app/features/library-panels/components/LibraryPanelsView/reducer.ts @@ -1,8 +1,9 @@ import { createAction } from '@reduxjs/toolkit'; +import { AnyAction } from 'redux'; + import { LoadingState } from '@grafana/data'; import { LibraryElementDTO } from '../../types'; -import { AnyAction } from 'redux'; export interface LibraryPanelsViewState { loadingState: LoadingState; diff --git a/public/app/features/library-panels/components/OpenLibraryPanelModal/OpenLibraryPanelModal.tsx b/public/app/features/library-panels/components/OpenLibraryPanelModal/OpenLibraryPanelModal.tsx index 6d560282d29..6bb986fcfb0 100644 --- a/public/app/features/library-panels/components/OpenLibraryPanelModal/OpenLibraryPanelModal.tsx +++ b/public/app/features/library-panels/components/OpenLibraryPanelModal/OpenLibraryPanelModal.tsx @@ -1,13 +1,14 @@ -import React, { MouseEvent, useCallback, useEffect, useMemo, useState } from 'react'; import { css } from '@emotion/css'; -import { AsyncSelect, Button, Modal, useStyles2 } from '@grafana/ui'; +import { debounce } from 'lodash'; +import React, { MouseEvent, useCallback, useEffect, useMemo, useState } from 'react'; + import { GrafanaTheme2, SelectableValue, urlUtil } from '@grafana/data'; import { locationService } from '@grafana/runtime'; +import { AsyncSelect, Button, Modal, useStyles2 } from '@grafana/ui'; -import { LibraryElementDTO } from '../../types'; import { DashboardSearchHit } from '../../../search/types'; import { getConnectedDashboards, getLibraryPanelConnectedDashboards } from '../../state/api'; -import { debounce } from 'lodash'; +import { LibraryElementDTO } from '../../types'; export interface OpenLibraryPanelModalProps { onDismiss: () => void; diff --git a/public/app/features/library-panels/components/PanelLibraryOptionsGroup/PanelLibraryOptionsGroup.tsx b/public/app/features/library-panels/components/PanelLibraryOptionsGroup/PanelLibraryOptionsGroup.tsx index c39c5b7beaf..f61cdb81276 100644 --- a/public/app/features/library-panels/components/PanelLibraryOptionsGroup/PanelLibraryOptionsGroup.tsx +++ b/public/app/features/library-panels/components/PanelLibraryOptionsGroup/PanelLibraryOptionsGroup.tsx @@ -1,17 +1,18 @@ +import { css } from '@emotion/css'; import React, { FC, useCallback, useState } from 'react'; import { useDispatch } from 'react-redux'; -import { css } from '@emotion/css'; + import { GrafanaTheme2, PanelPluginMeta } from '@grafana/data'; import { Button, useStyles2, VerticalGroup } from '@grafana/ui'; - -import { PanelModel } from 'app/features/dashboard/state'; -import { AddLibraryPanelModal } from '../AddLibraryPanelModal/AddLibraryPanelModal'; -import { LibraryPanelsView } from '../LibraryPanelsView/LibraryPanelsView'; -import { LibraryElementDTO } from '../../types'; -import { changeToLibraryPanel } from 'app/features/panel/state/actions'; import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv'; -import { ChangeLibraryPanelModal } from '../ChangeLibraryPanelModal/ChangeLibraryPanelModal'; +import { PanelModel } from 'app/features/dashboard/state'; +import { changeToLibraryPanel } from 'app/features/panel/state/actions'; + import { PanelTypeFilter } from '../../../../core/components/PanelTypeFilter/PanelTypeFilter'; +import { LibraryElementDTO } from '../../types'; +import { AddLibraryPanelModal } from '../AddLibraryPanelModal/AddLibraryPanelModal'; +import { ChangeLibraryPanelModal } from '../ChangeLibraryPanelModal/ChangeLibraryPanelModal'; +import { LibraryPanelsView } from '../LibraryPanelsView/LibraryPanelsView'; interface Props { panel: PanelModel; diff --git a/public/app/features/library-panels/components/SaveLibraryPanelModal/SaveLibraryPanelModal.tsx b/public/app/features/library-panels/components/SaveLibraryPanelModal/SaveLibraryPanelModal.tsx index 6829868aea2..8806b2ab5ad 100644 --- a/public/app/features/library-panels/components/SaveLibraryPanelModal/SaveLibraryPanelModal.tsx +++ b/public/app/features/library-panels/components/SaveLibraryPanelModal/SaveLibraryPanelModal.tsx @@ -1,10 +1,12 @@ import React, { useCallback, useState } from 'react'; -import { Button, Icon, Input, Modal, useStyles } from '@grafana/ui'; import { useAsync, useDebounce } from 'react-use'; -import { usePanelSave } from '../../utils/usePanelSave'; + +import { Button, Icon, Input, Modal, useStyles } from '@grafana/ui'; + import { getConnectedDashboards } from '../../state/api'; -import { PanelModelWithLibraryPanel } from '../../types'; import { getModalStyles } from '../../styles'; +import { PanelModelWithLibraryPanel } from '../../types'; +import { usePanelSave } from '../../utils/usePanelSave'; interface Props { panel: PanelModelWithLibraryPanel; diff --git a/public/app/features/library-panels/components/UnlinkModal/UnlinkModal.tsx b/public/app/features/library-panels/components/UnlinkModal/UnlinkModal.tsx index ad342d8f83b..961c06f0dea 100644 --- a/public/app/features/library-panels/components/UnlinkModal/UnlinkModal.tsx +++ b/public/app/features/library-panels/components/UnlinkModal/UnlinkModal.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { ConfirmModal } from '@grafana/ui'; interface Props { diff --git a/public/app/features/library-panels/guard.ts b/public/app/features/library-panels/guard.ts index 713aefbf411..739fe7bd2e3 100644 --- a/public/app/features/library-panels/guard.ts +++ b/public/app/features/library-panels/guard.ts @@ -1,4 +1,5 @@ import { PanelModel } from '../dashboard/state'; + import { PanelModelWithLibraryPanel } from './types'; export function isPanelModelLibraryPanel(panel: PanelModel): panel is PanelModelWithLibraryPanel { diff --git a/public/app/features/library-panels/state/api.ts b/public/app/features/library-panels/state/api.ts index 6f70625da1e..8ea659de250 100644 --- a/public/app/features/library-panels/state/api.ts +++ b/public/app/features/library-panels/state/api.ts @@ -1,3 +1,7 @@ +import { lastValueFrom } from 'rxjs'; + +import { getBackendSrv } from '../../../core/services/backend_srv'; +import { DashboardSearchHit } from '../../search/types'; import { LibraryElementConnectionDTO, LibraryElementDTO, @@ -5,9 +9,6 @@ import { LibraryElementsSearchResult, PanelModelWithLibraryPanel, } from '../types'; -import { DashboardSearchHit } from '../../search/types'; -import { getBackendSrv } from '../../../core/services/backend_srv'; -import { lastValueFrom } from 'rxjs'; export interface GetLibraryPanelsOptions { searchString?: string; diff --git a/public/app/features/library-panels/styles.ts b/public/app/features/library-panels/styles.ts index 3c26f7a1876..b76b2e7b43e 100644 --- a/public/app/features/library-panels/styles.ts +++ b/public/app/features/library-panels/styles.ts @@ -1,4 +1,5 @@ import { css } from '@emotion/css'; + import { GrafanaTheme } from '@grafana/data'; export function getModalStyles(theme: GrafanaTheme) { diff --git a/public/app/features/library-panels/types.ts b/public/app/features/library-panels/types.ts index b523cdca8d7..8991ce02872 100644 --- a/public/app/features/library-panels/types.ts +++ b/public/app/features/library-panels/types.ts @@ -1,6 +1,7 @@ -import { PanelModel } from '../dashboard/state'; -import { Dispatch } from 'react'; import { AnyAction } from '@reduxjs/toolkit'; +import { Dispatch } from 'react'; + +import { PanelModel } from '../dashboard/state'; export enum LibraryElementKind { Panel = 1, diff --git a/public/app/features/library-panels/utils.ts b/public/app/features/library-panels/utils.ts index 07ae681628e..c9e2b8a9bc6 100644 --- a/public/app/features/library-panels/utils.ts +++ b/public/app/features/library-panels/utils.ts @@ -1,8 +1,9 @@ -import { LibraryElementDTO, PanelModelLibraryPanel } from './types'; -import { PanelModel } from '../dashboard/state'; -import { addLibraryPanel, updateLibraryPanel } from './state/api'; import { createErrorNotification, createSuccessNotification } from '../../core/copy/appNotification'; import { AppNotification } from '../../types'; +import { PanelModel } from '../dashboard/state'; + +import { addLibraryPanel, updateLibraryPanel } from './state/api'; +import { LibraryElementDTO, PanelModelLibraryPanel } from './types'; export function createPanelLibraryErrorNotification(message: string): AppNotification { return createErrorNotification(message); diff --git a/public/app/features/library-panels/utils/usePanelSave.ts b/public/app/features/library-panels/utils/usePanelSave.ts index 436d2b255b7..90bb0e468a6 100644 --- a/public/app/features/library-panels/utils/usePanelSave.ts +++ b/public/app/features/library-panels/utils/usePanelSave.ts @@ -2,13 +2,14 @@ import { useEffect } from 'react'; import { useDispatch } from 'react-redux'; import useAsyncFn from 'react-use/lib/useAsyncFn'; +import { notifyApp } from 'app/core/actions'; import { PanelModel } from 'app/features/dashboard/state'; + import { createPanelLibraryErrorNotification, createPanelLibrarySuccessNotification, saveAndRefreshLibraryPanel, } from '../utils'; -import { notifyApp } from 'app/core/actions'; export const usePanelSave = () => { const dispatch = useDispatch(); diff --git a/public/app/features/live/LiveConnectionWarning.tsx b/public/app/features/live/LiveConnectionWarning.tsx index 54f23413c93..646705d8a34 100644 --- a/public/app/features/live/LiveConnectionWarning.tsx +++ b/public/app/features/live/LiveConnectionWarning.tsx @@ -1,9 +1,10 @@ import { css } from '@emotion/css'; +import React, { PureComponent } from 'react'; +import { Unsubscribable } from 'rxjs'; + import { GrafanaTheme2 } from '@grafana/data'; import { config, getGrafanaLiveSrv } from '@grafana/runtime'; import { Alert, stylesFactory } from '@grafana/ui'; -import React, { PureComponent } from 'react'; -import { Unsubscribable } from 'rxjs'; import { contextSrv } from 'app/core/services/context_srv'; export interface Props {} diff --git a/public/app/features/live/centrifuge/LiveDataStream.test.ts b/public/app/features/live/centrifuge/LiveDataStream.test.ts index 200f7475da4..c3311f355f3 100644 --- a/public/app/features/live/centrifuge/LiveDataStream.test.ts +++ b/public/app/features/live/centrifuge/LiveDataStream.test.ts @@ -1,3 +1,7 @@ +import mockConsole, { RestoreConsole } from 'jest-mock-console'; +import { mapValues } from 'lodash'; +import { Observable, Subject, Subscription, Unsubscribable } from 'rxjs'; + import { DataFrameJSON, dataFrameToJSON, @@ -11,13 +15,12 @@ import { LiveChannelScope, LoadingState, } from '@grafana/data'; -import { Observable, Subject, Subscription, Unsubscribable } from 'rxjs'; -import { DataStreamHandlerDeps, LiveDataStream } from './LiveDataStream'; -import { mapValues } from 'lodash'; import { StreamingFrameAction } from '@grafana/runtime'; -import { isStreamingResponseData, StreamingResponseData, StreamingResponseDataType } from '../data/utils'; + import { StreamingDataFrame } from '../data/StreamingDataFrame'; -import mockConsole, { RestoreConsole } from 'jest-mock-console'; +import { isStreamingResponseData, StreamingResponseData, StreamingResponseDataType } from '../data/utils'; + +import { DataStreamHandlerDeps, LiveDataStream } from './LiveDataStream'; type SubjectsInsteadOfObservables = { [key in keyof T]: T[key] extends Observable ? Subject : T[key]; diff --git a/public/app/features/live/centrifuge/LiveDataStream.ts b/public/app/features/live/centrifuge/LiveDataStream.ts index 3f735a52f2c..d992fdeb09b 100644 --- a/public/app/features/live/centrifuge/LiveDataStream.ts +++ b/public/app/features/live/centrifuge/LiveDataStream.ts @@ -1,5 +1,5 @@ -import { LiveDataStreamOptions, StreamingFrameAction, StreamingFrameOptions } from '@grafana/runtime/src/services/live'; -import { toDataQueryError } from '@grafana/runtime/src/utils/toDataQueryError'; +import { map, Observable, ReplaySubject, Subject, Subscriber, Subscription } from 'rxjs'; + import { DataFrameJSON, DataQueryError, @@ -11,11 +11,14 @@ import { LiveChannelId, LoadingState, } from '@grafana/data'; -import { map, Observable, ReplaySubject, Subject, Subscriber, Subscription } from 'rxjs'; -import { DataStreamSubscriptionKey, StreamingDataQueryResponse } from './service'; +import { LiveDataStreamOptions, StreamingFrameAction, StreamingFrameOptions } from '@grafana/runtime/src/services/live'; +import { toDataQueryError } from '@grafana/runtime/src/utils/toDataQueryError'; + import { getStreamingFrameOptions, StreamingDataFrame } from '../data/StreamingDataFrame'; import { StreamingResponseDataType } from '../data/utils'; +import { DataStreamSubscriptionKey, StreamingDataQueryResponse } from './service'; + const bufferIfNot = (canEmitObservable: Observable) => (source: Observable): Observable => { diff --git a/public/app/features/live/centrifuge/channel.ts b/public/app/features/live/centrifuge/channel.ts index 0ad529a6598..c15c73572b2 100644 --- a/public/app/features/live/centrifuge/channel.ts +++ b/public/app/features/live/centrifuge/channel.ts @@ -1,3 +1,13 @@ +import Centrifuge, { + JoinLeaveContext, + PublicationContext, + SubscribeErrorContext, + SubscribeSuccessContext, + SubscriptionEvents, + UnsubscribeContext, +} from 'centrifuge/dist/centrifuge'; +import { Subject, of, Observable } from 'rxjs'; + import { LiveChannelStatusEvent, LiveChannelEvent, @@ -8,16 +18,6 @@ import { DataFrameJSON, isValidLiveChannelAddress, } from '@grafana/data'; -import Centrifuge, { - JoinLeaveContext, - PublicationContext, - SubscribeErrorContext, - SubscribeSuccessContext, - SubscriptionEvents, - UnsubscribeContext, -} from 'centrifuge/dist/centrifuge'; - -import { Subject, of, Observable } from 'rxjs'; /** * Internal class that maps Centrifuge support to GrafanaLive diff --git a/public/app/features/live/centrifuge/service.ts b/public/app/features/live/centrifuge/service.ts index d65154762e7..3cb95ff6ca6 100644 --- a/public/app/features/live/centrifuge/service.ts +++ b/public/app/features/live/centrifuge/service.ts @@ -1,12 +1,6 @@ import Centrifuge from 'centrifuge/dist/centrifuge'; -import { - GrafanaLiveSrv, - LiveDataStreamOptions, - LiveQueryDataOptions, - StreamingFrameAction, - StreamingFrameOptions, -} from '@grafana/runtime/src/services/live'; import { BehaviorSubject, Observable, share, startWith } from 'rxjs'; + import { DataQueryError, DataQueryResponse, @@ -15,11 +9,20 @@ import { LiveChannelId, toLiveChannelId, } from '@grafana/data'; -import { CentrifugeLiveChannel } from './channel'; -import { LiveDataStream } from './LiveDataStream'; -import { StreamingResponseData } from '../data/utils'; -import { BackendDataSourceResponse } from '@grafana/runtime/src/utils/queryResponse'; import { FetchResponse } from '@grafana/runtime/src/services/backendSrv'; +import { + GrafanaLiveSrv, + LiveDataStreamOptions, + LiveQueryDataOptions, + StreamingFrameAction, + StreamingFrameOptions, +} from '@grafana/runtime/src/services/live'; +import { BackendDataSourceResponse } from '@grafana/runtime/src/utils/queryResponse'; + +import { StreamingResponseData } from '../data/utils'; + +import { LiveDataStream } from './LiveDataStream'; +import { CentrifugeLiveChannel } from './channel'; export type CentrifugeSrvDeps = { appUrl: string; diff --git a/public/app/features/live/centrifuge/service.worker.ts b/public/app/features/live/centrifuge/service.worker.ts index e47681175f3..a168bc34824 100644 --- a/public/app/features/live/centrifuge/service.worker.ts +++ b/public/app/features/live/centrifuge/service.worker.ts @@ -1,10 +1,13 @@ -import { CentrifugeService, CentrifugeSrvDeps } from './service'; -import * as comlink from 'comlink'; import './transferHandlers'; -import { remoteObservableAsObservable } from './remoteObservable'; + +import * as comlink from 'comlink'; + import { LiveChannelAddress } from '@grafana/data'; import { LiveDataStreamOptions, LiveQueryDataOptions } from '@grafana/runtime'; +import { remoteObservableAsObservable } from './remoteObservable'; +import { CentrifugeService, CentrifugeSrvDeps } from './service'; + let centrifuge: CentrifugeService; const initialize = ( diff --git a/public/app/features/live/centrifuge/serviceWorkerProxy.ts b/public/app/features/live/centrifuge/serviceWorkerProxy.ts index c53d2e49507..9cbea1b8312 100644 --- a/public/app/features/live/centrifuge/serviceWorkerProxy.ts +++ b/public/app/features/live/centrifuge/serviceWorkerProxy.ts @@ -1,12 +1,14 @@ -import { CentrifugeSrv, CentrifugeSrvDeps } from './service'; -import { RemoteCentrifugeService } from './service.worker'; import './transferHandlers'; import * as comlink from 'comlink'; import { asyncScheduler, Observable, observeOn } from 'rxjs'; + import { LiveChannelAddress, LiveChannelEvent } from '@grafana/data'; -import { promiseWithRemoteObservableAsObservable } from './remoteObservable'; + import { createWorker } from './createCentrifugeServiceWorker'; +import { promiseWithRemoteObservableAsObservable } from './remoteObservable'; +import { CentrifugeSrv, CentrifugeSrvDeps } from './service'; +import { RemoteCentrifugeService } from './service.worker'; export class CentrifugeServiceWorkerProxy implements CentrifugeSrv { private centrifugeWorker; diff --git a/public/app/features/live/dashboard/DashboardChangedModal.tsx b/public/app/features/live/dashboard/DashboardChangedModal.tsx index 26e00e17930..b8db7b2f8c9 100644 --- a/public/app/features/live/dashboard/DashboardChangedModal.tsx +++ b/public/app/features/live/dashboard/DashboardChangedModal.tsx @@ -1,10 +1,12 @@ -import React, { PureComponent } from 'react'; -import { Modal, stylesFactory } from '@grafana/ui'; import { css } from '@emotion/css'; -import { dashboardWatcher } from './dashboardWatcher'; -import { config } from '@grafana/runtime'; -import { DashboardEvent, DashboardEventAction } from './types'; +import React, { PureComponent } from 'react'; + import { GrafanaTheme } from '@grafana/data'; +import { config } from '@grafana/runtime'; +import { Modal, stylesFactory } from '@grafana/ui'; + +import { dashboardWatcher } from './dashboardWatcher'; +import { DashboardEvent, DashboardEventAction } from './types'; interface Props { event?: DashboardEvent; diff --git a/public/app/features/live/dashboard/dashboardWatcher.ts b/public/app/features/live/dashboard/dashboardWatcher.ts index f4f89713845..e7cccd2b721 100644 --- a/public/app/features/live/dashboard/dashboardWatcher.ts +++ b/public/app/features/live/dashboard/dashboardWatcher.ts @@ -1,6 +1,5 @@ -import { getGrafanaLiveSrv, locationService } from '@grafana/runtime'; -import { getDashboardSrv } from '../../dashboard/services/DashboardSrv'; -import { appEvents, contextSrv } from 'app/core/core'; +import { Unsubscribable } from 'rxjs'; + import { AppEvents, isLiveChannelMessageEvent, @@ -10,11 +9,15 @@ import { LiveChannelEvent, LiveChannelScope, } from '@grafana/data'; +import { getGrafanaLiveSrv, locationService } from '@grafana/runtime'; +import { appEvents, contextSrv } from 'app/core/core'; +import { sessionId } from 'app/features/live'; + +import { ShowModalReactEvent } from '../../../types/events'; +import { getDashboardSrv } from '../../dashboard/services/DashboardSrv'; + import { DashboardChangedModal } from './DashboardChangedModal'; import { DashboardEvent, DashboardEventAction } from './types'; -import { sessionId } from 'app/features/live'; -import { ShowModalReactEvent } from '../../../types/events'; -import { Unsubscribable } from 'rxjs'; class DashboardWatcher { channel?: LiveChannelAddress; // path to the channel diff --git a/public/app/features/live/index.ts b/public/app/features/live/index.ts index 31a2001c828..b1ae4baca8f 100644 --- a/public/app/features/live/index.ts +++ b/public/app/features/live/index.ts @@ -1,10 +1,12 @@ import { config, getBackendSrv, getGrafanaLiveSrv, setGrafanaLiveSrv } from '@grafana/runtime'; -import { GrafanaLiveService } from './live'; -import { contextSrv } from '../../core/services/context_srv'; -import { CentrifugeServiceWorkerProxy } from './centrifuge/serviceWorkerProxy'; -import { CentrifugeService } from './centrifuge/service'; import { liveTimer } from 'app/features/dashboard/dashgrid/liveTimer'; +import { contextSrv } from '../../core/services/context_srv'; + +import { CentrifugeService } from './centrifuge/service'; +import { CentrifugeServiceWorkerProxy } from './centrifuge/serviceWorkerProxy'; +import { GrafanaLiveService } from './live'; + export const sessionId = (window as any)?.grafanaBootData?.user?.id + '/' + diff --git a/public/app/features/live/live.test.ts b/public/app/features/live/live.test.ts index 58355588a39..e31feeb9715 100644 --- a/public/app/features/live/live.test.ts +++ b/public/app/features/live/live.test.ts @@ -1,10 +1,12 @@ -import { GrafanaLiveService } from './live'; -import { StreamingDataQueryResponse } from './centrifuge/service'; +import mockConsole, { RestoreConsole } from 'jest-mock-console'; import { Subject } from 'rxjs'; + import { DataQueryResponse, FieldType, LiveChannelScope } from '@grafana/data'; + +import { StreamingDataQueryResponse } from './centrifuge/service'; import { StreamingDataFrame } from './data/StreamingDataFrame'; import { StreamingResponseDataType } from './data/utils'; -import mockConsole, { RestoreConsole } from 'jest-mock-console'; +import { GrafanaLiveService } from './live'; describe('GrafanaLiveService', () => { let restoreConsole: RestoreConsole | undefined; diff --git a/public/app/features/live/live.ts b/public/app/features/live/live.ts index d541a282500..689e5fcf4a4 100644 --- a/public/app/features/live/live.ts +++ b/public/app/features/live/live.ts @@ -1,15 +1,16 @@ -import { BackendSrv, GrafanaLiveSrv, toDataQueryResponse } from '@grafana/runtime'; -import { CentrifugeSrv, StreamingDataQueryResponse } from './centrifuge/service'; +import { from, map, of, switchMap } from 'rxjs'; import { DataFrame, toLiveChannelId } from '@grafana/data'; -import { StreamingDataFrame } from './data/StreamingDataFrame'; -import { isStreamingResponseData, StreamingResponseDataType } from './data/utils'; -import { from, map, of, switchMap } from 'rxjs'; +import { BackendSrv, GrafanaLiveSrv, toDataQueryResponse } from '@grafana/runtime'; import { standardStreamOptionsProvider, toStreamingDataResponse, } from '@grafana/runtime/src/utils/DataSourceWithBackend'; +import { CentrifugeSrv, StreamingDataQueryResponse } from './centrifuge/service'; +import { StreamingDataFrame } from './data/StreamingDataFrame'; +import { isStreamingResponseData, StreamingResponseDataType } from './data/utils'; + type GrafanaLiveServiceDeps = { centrifugeSrv: CentrifugeSrv; backendSrv: BackendSrv; diff --git a/public/app/features/live/pages/AddNewRule.tsx b/public/app/features/live/pages/AddNewRule.tsx index 5fa392361d0..fea6a9fa681 100644 --- a/public/app/features/live/pages/AddNewRule.tsx +++ b/public/app/features/live/pages/AddNewRule.tsx @@ -1,8 +1,10 @@ import React, { useState } from 'react'; -import { Input, Field, Button, ValuePicker, HorizontalGroup } from '@grafana/ui'; -import { DataSourcePicker, getBackendSrv } from '@grafana/runtime'; + import { DataSourceRef, LiveChannelScope, SelectableValue } from '@grafana/data'; +import { DataSourcePicker, getBackendSrv } from '@grafana/runtime'; +import { Input, Field, Button, ValuePicker, HorizontalGroup } from '@grafana/ui'; import { useAppNotification } from 'app/core/copy/appNotification'; + import { Rule } from './types'; interface Props { diff --git a/public/app/features/live/pages/CloudAdminPage.tsx b/public/app/features/live/pages/CloudAdminPage.tsx index b24dba5e6c4..fe3face9db2 100644 --- a/public/app/features/live/pages/CloudAdminPage.tsx +++ b/public/app/features/live/pages/CloudAdminPage.tsx @@ -1,10 +1,12 @@ +import { css } from '@emotion/css'; import React, { useEffect, useState } from 'react'; + +import { GrafanaTheme } from '@grafana/data'; import { getBackendSrv } from '@grafana/runtime'; import { useStyles } from '@grafana/ui'; import Page from 'app/core/components/Page/Page'; import { useNavModel } from 'app/core/hooks/useNavModel'; -import { css } from '@emotion/css'; -import { GrafanaTheme } from '@grafana/data'; + import { GrafanaCloudBackend } from './types'; export default function CloudAdminPage() { diff --git a/public/app/features/live/pages/FeatureTogglePage.tsx b/public/app/features/live/pages/FeatureTogglePage.tsx index 4ccdaef6f2e..a1d3e635c5a 100644 --- a/public/app/features/live/pages/FeatureTogglePage.tsx +++ b/public/app/features/live/pages/FeatureTogglePage.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import Page from 'app/core/components/Page/Page'; import { useNavModel } from 'app/core/hooks/useNavModel'; diff --git a/public/app/features/live/pages/LiveStatusPage.tsx b/public/app/features/live/pages/LiveStatusPage.tsx index b5f2231db53..569853591af 100644 --- a/public/app/features/live/pages/LiveStatusPage.tsx +++ b/public/app/features/live/pages/LiveStatusPage.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import Page from 'app/core/components/Page/Page'; import { useNavModel } from 'app/core/hooks/useNavModel'; diff --git a/public/app/features/live/pages/PipelineAdminPage.tsx b/public/app/features/live/pages/PipelineAdminPage.tsx index 2edda347c00..2face908dc6 100644 --- a/public/app/features/live/pages/PipelineAdminPage.tsx +++ b/public/app/features/live/pages/PipelineAdminPage.tsx @@ -1,11 +1,13 @@ import React, { useEffect, useState, ChangeEvent } from 'react'; + import { getBackendSrv } from '@grafana/runtime'; import { Input } from '@grafana/ui'; import Page from 'app/core/components/Page/Page'; import { useNavModel } from 'app/core/hooks/useNavModel'; -import { Rule } from './types'; -import { PipelineTable } from './PipelineTable'; + import { AddNewRule } from './AddNewRule'; +import { PipelineTable } from './PipelineTable'; +import { Rule } from './types'; export default function PipelineAdminPage() { const [rules, setRules] = useState([]); diff --git a/public/app/features/live/pages/PipelineTable.tsx b/public/app/features/live/pages/PipelineTable.tsx index 32873a40c16..073417618af 100644 --- a/public/app/features/live/pages/PipelineTable.tsx +++ b/public/app/features/live/pages/PipelineTable.tsx @@ -1,12 +1,14 @@ +import { css } from '@emotion/css'; import React, { useEffect, useState } from 'react'; + +import { GrafanaTheme } from '@grafana/data'; import { getBackendSrv } from '@grafana/runtime'; import { Tag, useStyles, IconButton } from '@grafana/ui'; -import { css } from '@emotion/css'; -import { GrafanaTheme } from '@grafana/data'; -import { Rule, Output, RuleType } from './types'; -import { RuleModal } from './RuleModal'; import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; +import { RuleModal } from './RuleModal'; +import { Rule, Output, RuleType } from './types'; + function renderOutputTags(key: string, output?: Output): React.ReactNode { if (!output?.type) { return null; diff --git a/public/app/features/live/pages/RuleModal.tsx b/public/app/features/live/pages/RuleModal.tsx index 0f2686024cb..95b4a8d4f2c 100644 --- a/public/app/features/live/pages/RuleModal.tsx +++ b/public/app/features/live/pages/RuleModal.tsx @@ -1,13 +1,15 @@ -import React, { useState, useMemo } from 'react'; -import { Modal, TabContent, TabsBar, Tab, Button, useStyles } from '@grafana/ui'; -import { Rule, RuleType, PipeLineEntitiesInfo, RuleSetting } from './types'; -import { getBackendSrv } from '@grafana/runtime'; import { css } from '@emotion/css'; +import React, { useState, useMemo } from 'react'; + import { GrafanaTheme } from '@grafana/data'; -import { RuleSettingsEditor } from './RuleSettingsEditor'; -import { getPipeLineEntities } from './utils'; +import { getBackendSrv } from '@grafana/runtime'; +import { Modal, TabContent, TabsBar, Tab, Button, useStyles } from '@grafana/ui'; + import { RuleSettingsArray } from './RuleSettingsArray'; +import { RuleSettingsEditor } from './RuleSettingsEditor'; import { RuleTest } from './RuleTest'; +import { Rule, RuleType, PipeLineEntitiesInfo, RuleSetting } from './types'; +import { getPipeLineEntities } from './utils'; interface Props { rule: Rule; diff --git a/public/app/features/live/pages/RuleSettingsArray.tsx b/public/app/features/live/pages/RuleSettingsArray.tsx index c209e9d578d..fe9ed83163c 100644 --- a/public/app/features/live/pages/RuleSettingsArray.tsx +++ b/public/app/features/live/pages/RuleSettingsArray.tsx @@ -1,8 +1,11 @@ import React, { useState } from 'react'; + +import { Select } from '@grafana/ui'; + +import { SelectableValue } from '../../../../../packages/grafana-data/src'; + import { RuleSettingsEditor } from './RuleSettingsEditor'; import { RuleType, RuleSetting, PipeLineEntitiesInfo } from './types'; -import { Select } from '@grafana/ui'; -import { SelectableValue } from '../../../../../packages/grafana-data/src'; interface Props { ruleType: RuleType; diff --git a/public/app/features/live/pages/RuleSettingsEditor.tsx b/public/app/features/live/pages/RuleSettingsEditor.tsx index e7c7411127b..9a34068e8fc 100644 --- a/public/app/features/live/pages/RuleSettingsEditor.tsx +++ b/public/app/features/live/pages/RuleSettingsEditor.tsx @@ -1,5 +1,7 @@ import React from 'react'; + import { CodeEditor, Select } from '@grafana/ui'; + import { RuleType, RuleSetting, PipeLineEntitiesInfo } from './types'; interface Props { diff --git a/public/app/features/live/pages/RuleTest.tsx b/public/app/features/live/pages/RuleTest.tsx index d6494ccf82e..70e8622efa5 100644 --- a/public/app/features/live/pages/RuleTest.tsx +++ b/public/app/features/live/pages/RuleTest.tsx @@ -1,9 +1,11 @@ -import React, { useState } from 'react'; -import { Button, CodeEditor, Table, useStyles, Field } from '@grafana/ui'; -import { ChannelFrame, Rule } from './types'; -import { getBackendSrv, config } from '@grafana/runtime'; import { css } from '@emotion/css'; +import React, { useState } from 'react'; + import { dataFrameFromJSON, getDisplayProcessor, GrafanaTheme } from '@grafana/data'; +import { getBackendSrv, config } from '@grafana/runtime'; +import { Button, CodeEditor, Table, useStyles, Field } from '@grafana/ui'; + +import { ChannelFrame, Rule } from './types'; interface Props { rule: Rule; diff --git a/public/app/features/live/pages/utils.ts b/public/app/features/live/pages/utils.ts index a2c3dc2757c..db986d17c27 100644 --- a/public/app/features/live/pages/utils.ts +++ b/public/app/features/live/pages/utils.ts @@ -1,4 +1,5 @@ import { getBackendSrv } from '@grafana/runtime'; + import { PipelineListOption, PipeLineEntitiesInfo } from './types'; export async function getPipeLineEntities(): Promise { diff --git a/public/app/features/manage-dashboards/DashboardImportPage.tsx b/public/app/features/manage-dashboards/DashboardImportPage.tsx index 378b9fe4cc5..9ea96938469 100644 --- a/public/app/features/manage-dashboards/DashboardImportPage.tsx +++ b/public/app/features/manage-dashboards/DashboardImportPage.tsx @@ -1,6 +1,7 @@ +import { css } from '@emotion/css'; import React, { FormEvent, PureComponent } from 'react'; import { connect, ConnectedProps } from 'react-redux'; -import { css } from '@emotion/css'; + import { AppEvents, GrafanaTheme2, LoadingState } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; import { reportInteraction } from '@grafana/runtime'; @@ -18,16 +19,18 @@ import { VerticalGroup, withTheme2, } from '@grafana/ui'; -import Page from 'app/core/components/Page/Page'; -import { ImportDashboardOverview } from './components/ImportDashboardOverview'; -import { validateDashboardJson, validateGcomDashboard } from './utils/validation'; -import { fetchGcomDashboard, importDashboardJson } from './state/actions'; import appEvents from 'app/core/app_events'; +import Page from 'app/core/components/Page/Page'; +import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; import { getNavModel } from 'app/core/selectors/navModel'; import { StoreState } from 'app/types'; -import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; + import { cleanUpAction } from '../../core/actions/cleanUp'; +import { ImportDashboardOverview } from './components/ImportDashboardOverview'; +import { fetchGcomDashboard, importDashboardJson } from './state/actions'; +import { validateDashboardJson, validateGcomDashboard } from './utils/validation'; + type DashboardImportPageRouteSearchParams = { gcomDashboardId?: string; }; diff --git a/public/app/features/manage-dashboards/SnapshotListPage.tsx b/public/app/features/manage-dashboards/SnapshotListPage.tsx index 7755b38989f..5aa91777a34 100644 --- a/public/app/features/manage-dashboards/SnapshotListPage.tsx +++ b/public/app/features/manage-dashboards/SnapshotListPage.tsx @@ -1,11 +1,14 @@ import React, { FC } from 'react'; import { MapStateToProps, connect } from 'react-redux'; + import { NavModel } from '@grafana/data'; import Page from 'app/core/components/Page/Page'; -import { StoreState } from 'app/types'; -import { SnapshotListTable } from './components/SnapshotListTable'; -import { GrafanaRouteComponentProps } from '../../core/navigation/types'; import { getNavModel } from 'app/core/selectors/navModel'; +import { StoreState } from 'app/types'; + +import { GrafanaRouteComponentProps } from '../../core/navigation/types'; + +import { SnapshotListTable } from './components/SnapshotListTable'; interface ConnectedProps { navModel: NavModel; diff --git a/public/app/features/manage-dashboards/components/ImportDashboardForm.tsx b/public/app/features/manage-dashboards/components/ImportDashboardForm.tsx index 332b8ff1c13..ea0f1cc26b6 100644 --- a/public/app/features/manage-dashboards/components/ImportDashboardForm.tsx +++ b/public/app/features/manage-dashboards/components/ImportDashboardForm.tsx @@ -1,4 +1,8 @@ import React, { FC, useEffect, useState } from 'react'; + +import { selectors } from '@grafana/e2e-selectors'; +import { DataSourcePicker } from '@grafana/runtime'; +import { ExpressionDatasourceRef } from '@grafana/runtime/src/utils/DataSourceWithBackend'; import { Button, Field, @@ -10,11 +14,8 @@ import { InputControl, Legend, } from '@grafana/ui'; -import { DataSourcePicker } from '@grafana/runtime'; -import { ExpressionDatasourceRef } from '@grafana/runtime/src/utils/DataSourceWithBackend'; -import { selectors } from '@grafana/e2e-selectors'; - import { FolderPicker } from 'app/core/components/Select/FolderPicker'; + import { DashboardInput, DashboardInputs, @@ -23,6 +24,7 @@ import { LibraryPanelInputState, } from '../state/reducers'; import { validateTitle, validateUid } from '../utils/validation'; + import { ImportDashboardLibraryPanelsList } from './ImportDashboardLibraryPanelsList'; interface Props extends Pick, 'register' | 'errors' | 'control' | 'getValues' | 'watch'> { diff --git a/public/app/features/manage-dashboards/components/ImportDashboardLibraryPanelsList.tsx b/public/app/features/manage-dashboards/components/ImportDashboardLibraryPanelsList.tsx index e6a3b677030..cb3b47b7b71 100644 --- a/public/app/features/manage-dashboards/components/ImportDashboardLibraryPanelsList.tsx +++ b/public/app/features/manage-dashboards/components/ImportDashboardLibraryPanelsList.tsx @@ -1,10 +1,11 @@ +import { css } from '@emotion/css'; import React, { ReactElement } from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; import { Field, useStyles2 } from '@grafana/ui'; -import { LibraryPanelInput, LibraryPanelInputState } from '../state/reducers'; -import { GrafanaTheme2 } from '@grafana/data'; -import { css } from '@emotion/css'; import { LibraryPanelCard } from '../../library-panels/components/LibraryPanelCard/LibraryPanelCard'; +import { LibraryPanelInput, LibraryPanelInputState } from '../state/reducers'; interface ImportDashboardLibraryPanelsListProps { inputs: LibraryPanelInput[]; diff --git a/public/app/features/manage-dashboards/components/ImportDashboardOverview.tsx b/public/app/features/manage-dashboards/components/ImportDashboardOverview.tsx index 275a12d18ac..9fdbbedb5fe 100644 --- a/public/app/features/manage-dashboards/components/ImportDashboardOverview.tsx +++ b/public/app/features/manage-dashboards/components/ImportDashboardOverview.tsx @@ -1,12 +1,15 @@ import React, { PureComponent } from 'react'; -import { dateTimeFormat } from '@grafana/data'; -import { Form, Legend } from '@grafana/ui'; import { connect, ConnectedProps } from 'react-redux'; -import { ImportDashboardForm } from './ImportDashboardForm'; + +import { dateTimeFormat } from '@grafana/data'; +import { locationService, reportInteraction } from '@grafana/runtime'; +import { Form, Legend } from '@grafana/ui'; +import { StoreState } from 'app/types'; + import { clearLoadedDashboard, importDashboard } from '../state/actions'; import { DashboardSource, ImportDashboardDTO } from '../state/reducers'; -import { StoreState } from 'app/types'; -import { locationService, reportInteraction } from '@grafana/runtime'; + +import { ImportDashboardForm } from './ImportDashboardForm'; const IMPORT_FINISHED_EVENT_NAME = 'dashboard_import_imported'; diff --git a/public/app/features/manage-dashboards/components/SnapshotListTable.test.tsx b/public/app/features/manage-dashboards/components/SnapshotListTable.test.tsx index 3ecdb01fb89..ac89f7f9684 100644 --- a/public/app/features/manage-dashboards/components/SnapshotListTable.test.tsx +++ b/public/app/features/manage-dashboards/components/SnapshotListTable.test.tsx @@ -1,4 +1,5 @@ import { locationService } from '@grafana/runtime'; + import { getSnapshots } from './SnapshotListTable'; jest.mock('@grafana/runtime', () => ({ diff --git a/public/app/features/manage-dashboards/components/SnapshotListTable.tsx b/public/app/features/manage-dashboards/components/SnapshotListTable.tsx index 29c7c38325e..8eccb0b1513 100644 --- a/public/app/features/manage-dashboards/components/SnapshotListTable.tsx +++ b/public/app/features/manage-dashboards/components/SnapshotListTable.tsx @@ -1,9 +1,11 @@ import React, { FC, useState, useCallback } from 'react'; -import { ConfirmModal, Button, LinkButton } from '@grafana/ui'; -import { getBackendSrv, locationService } from '@grafana/runtime'; -import { Snapshot } from '../types'; import useAsync from 'react-use/lib/useAsync'; +import { getBackendSrv, locationService } from '@grafana/runtime'; +import { ConfirmModal, Button, LinkButton } from '@grafana/ui'; + +import { Snapshot } from '../types'; + export function getSnapshots() { return getBackendSrv() .get('/api/dashboard/snapshots') diff --git a/public/app/features/manage-dashboards/state/actions.test.ts b/public/app/features/manage-dashboards/state/actions.test.ts index 7c55fb72f20..d6c366ed545 100644 --- a/public/app/features/manage-dashboards/state/actions.test.ts +++ b/public/app/features/manage-dashboards/state/actions.test.ts @@ -1,5 +1,7 @@ -import { setBackendSrv } from '@grafana/runtime'; import { thunkTester } from 'test/core/thunk/thunkTester'; + +import { setBackendSrv } from '@grafana/runtime'; + import { importDashboard } from './actions'; import { DataSourceInput, ImportDashboardDTO, initialImportDashboardState, InputType } from './reducers'; diff --git a/public/app/features/manage-dashboards/state/actions.ts b/public/app/features/manage-dashboards/state/actions.ts index 99499d4960c..711e8f60e5a 100644 --- a/public/app/features/manage-dashboards/state/actions.ts +++ b/public/app/features/manage-dashboards/state/actions.ts @@ -1,4 +1,15 @@ import { DataSourceInstanceSettings, locationUtil } from '@grafana/data'; +import { getDataSourceSrv, locationService, getBackendSrv } from '@grafana/runtime'; +import { notifyApp } from 'app/core/actions'; +import { createErrorNotification } from 'app/core/copy/appNotification'; +import { dashboardWatcher } from 'app/features/live/dashboard/dashboardWatcher'; +import { DashboardDataDTO, DashboardDTO, FolderInfo, PermissionLevelString, ThunkResult } from 'app/types'; + +import { LibraryElementExport } from '../../dashboard/components/DashExportModal/DashboardExporter'; +import { getLibraryPanel } from '../../library-panels/state/api'; +import { LibraryElementDTO, LibraryElementKind } from '../../library-panels/types'; +import { DashboardSearchHit } from '../../search/types'; + import { clearDashboard, fetchDashboard, @@ -12,15 +23,6 @@ import { setJsonDashboard, setLibraryPanelInputs, } from './reducers'; -import { DashboardDataDTO, DashboardDTO, FolderInfo, PermissionLevelString, ThunkResult } from 'app/types'; -import { createErrorNotification } from 'app/core/copy/appNotification'; -import { notifyApp } from 'app/core/actions'; -import { dashboardWatcher } from 'app/features/live/dashboard/dashboardWatcher'; -import { getDataSourceSrv, locationService, getBackendSrv } from '@grafana/runtime'; -import { DashboardSearchHit } from '../../search/types'; -import { getLibraryPanel } from '../../library-panels/state/api'; -import { LibraryElementDTO, LibraryElementKind } from '../../library-panels/types'; -import { LibraryElementExport } from '../../dashboard/components/DashExportModal/DashboardExporter'; export function fetchGcomDashboard(id: string): ThunkResult { return async (dispatch) => { diff --git a/public/app/features/manage-dashboards/state/reducers.test.ts b/public/app/features/manage-dashboards/state/reducers.test.ts index 8d845d271f6..5b25d1a394e 100644 --- a/public/app/features/manage-dashboards/state/reducers.test.ts +++ b/public/app/features/manage-dashboards/state/reducers.test.ts @@ -1,4 +1,8 @@ +import { LoadingState } from '@grafana/data'; + import { reducerTester } from '../../../../test/core/redux/reducerTester'; +import { LibraryElementDTO } from '../../library-panels/types'; + import { clearDashboard, DashboardSource, @@ -14,8 +18,6 @@ import { setJsonDashboard, setLibraryPanelInputs, } from './reducers'; -import { LibraryElementDTO } from '../../library-panels/types'; -import { LoadingState } from '@grafana/data'; describe('importDashboardReducer', () => { describe('when setGcomDashboard action is dispatched', () => { diff --git a/public/app/features/manage-dashboards/state/reducers.ts b/public/app/features/manage-dashboards/state/reducers.ts index 89940277dd1..b2127692d74 100644 --- a/public/app/features/manage-dashboards/state/reducers.ts +++ b/public/app/features/manage-dashboards/state/reducers.ts @@ -1,5 +1,7 @@ import { createSlice, Draft, PayloadAction } from '@reduxjs/toolkit'; + import { DataSourceInstanceSettings, LoadingState } from '@grafana/data'; + import { LibraryElementDTO } from '../../library-panels/types'; export enum DashboardSource { diff --git a/public/app/features/manage-dashboards/utils/validation.ts b/public/app/features/manage-dashboards/utils/validation.ts index f68d3c30e37..bee8a2200c8 100644 --- a/public/app/features/manage-dashboards/utils/validation.ts +++ b/public/app/features/manage-dashboards/utils/validation.ts @@ -1,6 +1,7 @@ -import { validationSrv } from '../services/ValidationSrv'; import { getBackendSrv } from '@grafana/runtime'; +import { validationSrv } from '../services/ValidationSrv'; + export const validateDashboardJson = (json: string) => { try { JSON.parse(json); diff --git a/public/app/features/notifications/NotificationsPage.tsx b/public/app/features/notifications/NotificationsPage.tsx index e2e5c49338d..e809b8e49fa 100644 --- a/public/app/features/notifications/NotificationsPage.tsx +++ b/public/app/features/notifications/NotificationsPage.tsx @@ -3,10 +3,11 @@ import { connect, ConnectedProps } from 'react-redux'; import { config } from '@grafana/runtime'; -import { GrafanaRouteComponentProps } from '../../core/navigation/types'; -import { StoreState } from '../../types'; -import { getNavModel } from '../../core/selectors/navModel'; import Page from '../../core/components/Page/Page'; +import { GrafanaRouteComponentProps } from '../../core/navigation/types'; +import { getNavModel } from '../../core/selectors/navModel'; +import { StoreState } from '../../types'; + import { StoredNotifications } from './StoredNotifications'; const mapStateToProps = (state: StoreState) => ({ diff --git a/public/app/features/notifications/StoredNotifications.tsx b/public/app/features/notifications/StoredNotifications.tsx index 1fa99b3b903..cd126c4d030 100644 --- a/public/app/features/notifications/StoredNotifications.tsx +++ b/public/app/features/notifications/StoredNotifications.tsx @@ -1,9 +1,10 @@ +import { css, cx } from '@emotion/css'; import React, { useRef } from 'react'; import { useEffectOnce } from 'react-use'; -import { css, cx } from '@emotion/css'; + import { GrafanaTheme2 } from '@grafana/data'; import { Button, Icon, useStyles2 } from '@grafana/ui'; -import { useDispatch, useSelector } from 'app/types'; +import { StoredNotificationItem } from 'app/core/components/AppNotifications/StoredNotificationItem'; import { clearAllNotifications, clearNotification, @@ -11,7 +12,7 @@ import { selectWarningsAndErrors, selectLastReadTimestamp, } from 'app/core/reducers/appNotification'; -import { StoredNotificationItem } from 'app/core/components/AppNotifications/StoredNotificationItem'; +import { useDispatch, useSelector } from 'app/types'; export function StoredNotifications() { const dispatch = useDispatch(); diff --git a/public/app/features/org/NewOrgPage.tsx b/public/app/features/org/NewOrgPage.tsx index c9e940e2b25..34d2619110b 100644 --- a/public/app/features/org/NewOrgPage.tsx +++ b/public/app/features/org/NewOrgPage.tsx @@ -1,11 +1,14 @@ import React, { FC } from 'react'; -import Page from 'app/core/components/Page/Page'; -import { Button, Input, Field, Form } from '@grafana/ui'; -import { StoreState } from 'app/types'; import { connect, ConnectedProps } from 'react-redux'; -import { getNavModel } from '../../core/selectors/navModel'; -import { createOrganization } from './state/actions'; + +import { Button, Input, Field, Form } from '@grafana/ui'; +import Page from 'app/core/components/Page/Page'; import { getConfig } from 'app/core/config'; +import { StoreState } from 'app/types'; + +import { getNavModel } from '../../core/selectors/navModel'; + +import { createOrganization } from './state/actions'; const mapStateToProps = (state: StoreState) => { return { navModel: getNavModel(state.navIndex, 'global-orgs') }; diff --git a/public/app/features/org/OrgDetailsPage.test.tsx b/public/app/features/org/OrgDetailsPage.test.tsx index 93cca7cc902..7d927f2f00b 100644 --- a/public/app/features/org/OrgDetailsPage.test.tsx +++ b/public/app/features/org/OrgDetailsPage.test.tsx @@ -1,10 +1,12 @@ -import React from 'react'; import { shallow } from 'enzyme'; +import React from 'react'; +import { mockToolkitActionCreator } from 'test/core/redux/mocks'; + import { NavModel } from '@grafana/data'; -import { OrgDetailsPage, Props } from './OrgDetailsPage'; import { Organization } from '../../types'; -import { mockToolkitActionCreator } from 'test/core/redux/mocks'; + +import { OrgDetailsPage, Props } from './OrgDetailsPage'; import { setOrganizationName } from './state/reducers'; jest.mock('app/core/core', () => { diff --git a/public/app/features/org/OrgDetailsPage.tsx b/public/app/features/org/OrgDetailsPage.tsx index 75776303601..5059ad5dd25 100644 --- a/public/app/features/org/OrgDetailsPage.tsx +++ b/public/app/features/org/OrgDetailsPage.tsx @@ -1,16 +1,17 @@ import React, { PureComponent } from 'react'; import { connect } from 'react-redux'; -import { NavModel } from '@grafana/data'; -import Page from 'app/core/components/Page/Page'; -import OrgProfile from './OrgProfile'; -import SharedPreferences from 'app/core/components/SharedPreferences/SharedPreferences'; -import { loadOrganization, updateOrganization } from './state/actions'; -import { AccessControlAction, Organization, StoreState } from 'app/types'; -import { getNavModel } from 'app/core/selectors/navModel'; -import { setOrganizationName } from './state/reducers'; +import { NavModel } from '@grafana/data'; import { VerticalGroup } from '@grafana/ui'; +import Page from 'app/core/components/Page/Page'; +import SharedPreferences from 'app/core/components/SharedPreferences/SharedPreferences'; import { contextSrv } from 'app/core/core'; +import { getNavModel } from 'app/core/selectors/navModel'; +import { AccessControlAction, Organization, StoreState } from 'app/types'; + +import OrgProfile from './OrgProfile'; +import { loadOrganization, updateOrganization } from './state/actions'; +import { setOrganizationName } from './state/reducers'; export interface Props { navModel: NavModel; diff --git a/public/app/features/org/OrgProfile.test.tsx b/public/app/features/org/OrgProfile.test.tsx index 9eceebcee95..459ad6cbe6a 100644 --- a/public/app/features/org/OrgProfile.test.tsx +++ b/public/app/features/org/OrgProfile.test.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { shallow } from 'enzyme'; +import React from 'react'; + import OrgProfile, { Props } from './OrgProfile'; jest.mock('app/core/core', () => { diff --git a/public/app/features/org/OrgProfile.tsx b/public/app/features/org/OrgProfile.tsx index f4b9a0bd293..42e2abffe9b 100644 --- a/public/app/features/org/OrgProfile.tsx +++ b/public/app/features/org/OrgProfile.tsx @@ -1,4 +1,5 @@ import React, { FC } from 'react'; + import { Input, Field, FieldSet, Button, Form } from '@grafana/ui'; import { contextSrv } from 'app/core/core'; import { AccessControlAction } from 'app/types'; diff --git a/public/app/features/org/SelectOrgPage.tsx b/public/app/features/org/SelectOrgPage.tsx index 1367e5d6573..273f699cc65 100644 --- a/public/app/features/org/SelectOrgPage.tsx +++ b/public/app/features/org/SelectOrgPage.tsx @@ -1,11 +1,13 @@ import React, { FC } from 'react'; -import Page from 'app/core/components/Page/Page'; -import { config } from '@grafana/runtime'; -import { StoreState, UserOrg } from 'app/types'; -import { useEffectOnce } from 'react-use'; -import { Button, HorizontalGroup } from '@grafana/ui'; -import { getUserOrganizations, setUserOrganization } from './state/actions'; import { connect, ConnectedProps } from 'react-redux'; +import { useEffectOnce } from 'react-use'; + +import { config } from '@grafana/runtime'; +import { Button, HorizontalGroup } from '@grafana/ui'; +import Page from 'app/core/components/Page/Page'; +import { StoreState, UserOrg } from 'app/types'; + +import { getUserOrganizations, setUserOrganization } from './state/actions'; const navModel = { main: { diff --git a/public/app/features/org/UserInviteForm.tsx b/public/app/features/org/UserInviteForm.tsx index 3ab5073d6c9..e94c6c9e9cf 100644 --- a/public/app/features/org/UserInviteForm.tsx +++ b/public/app/features/org/UserInviteForm.tsx @@ -1,4 +1,7 @@ import React from 'react'; + +import { locationUtil } from '@grafana/data'; +import { locationService } from '@grafana/runtime'; import { HorizontalGroup, Button, @@ -10,10 +13,9 @@ import { Field, InputControl, } from '@grafana/ui'; -import { locationService } from '@grafana/runtime'; -import { locationUtil } from '@grafana/data'; import { getConfig } from 'app/core/config'; import { OrgRole, useDispatch } from 'app/types'; + import { addInvitee } from '../invites/state/actions'; const roles = [ diff --git a/public/app/features/org/UserInvitePage.tsx b/public/app/features/org/UserInvitePage.tsx index affe62a13e9..8afa065a0b7 100644 --- a/public/app/features/org/UserInvitePage.tsx +++ b/public/app/features/org/UserInvitePage.tsx @@ -1,11 +1,13 @@ import React, { FC } from 'react'; import { connect } from 'react-redux'; -import UserInviteForm from './UserInviteForm'; + +import { NavModel } from '@grafana/data'; +import Page from 'app/core/components/Page/Page'; import { contextSrv } from 'app/core/core'; import { getNavModel } from 'app/core/selectors/navModel'; import { StoreState } from 'app/types/store'; -import Page from 'app/core/components/Page/Page'; -import { NavModel } from '@grafana/data'; + +import UserInviteForm from './UserInviteForm'; interface Props { navModel: NavModel; diff --git a/public/app/features/org/state/actions.test.ts b/public/app/features/org/state/actions.test.ts index 9dd97426e5f..924d2aef871 100644 --- a/public/app/features/org/state/actions.test.ts +++ b/public/app/features/org/state/actions.test.ts @@ -1,8 +1,10 @@ -import { updateOrganization, setUserOrganization, getUserOrganizations } from './actions'; -import { updateConfigurationSubtitle } from 'app/core/actions'; import { thunkTester } from 'test/core/thunk/thunkTester'; + +import { updateConfigurationSubtitle } from 'app/core/actions'; import { OrgRole } from 'app/types'; +import { updateOrganization, setUserOrganization, getUserOrganizations } from './actions'; + const setup = () => { const initialState = { organization: { diff --git a/public/app/features/org/state/actions.ts b/public/app/features/org/state/actions.ts index 6b01d1b2f91..7b382a71751 100644 --- a/public/app/features/org/state/actions.ts +++ b/public/app/features/org/state/actions.ts @@ -1,7 +1,8 @@ -import { ThunkResult } from 'app/types'; import { getBackendSrv } from '@grafana/runtime'; -import { organizationLoaded, userOrganizationsLoaded } from './reducers'; import { updateConfigurationSubtitle } from 'app/core/actions'; +import { ThunkResult } from 'app/types'; + +import { organizationLoaded, userOrganizationsLoaded } from './reducers'; type OrganizationDependencies = { getBackendSrv: typeof getBackendSrv }; diff --git a/public/app/features/org/state/reducers.test.ts b/public/app/features/org/state/reducers.test.ts index 00d47a26c6c..b99e2ce762f 100644 --- a/public/app/features/org/state/reducers.test.ts +++ b/public/app/features/org/state/reducers.test.ts @@ -1,5 +1,6 @@ import { reducerTester } from '../../../../test/core/redux/reducerTester'; import { OrganizationState, OrgRole } from '../../../types'; + import { initialState, organizationLoaded, diff --git a/public/app/features/panel/components/PanelDataErrorView.test.tsx b/public/app/features/panel/components/PanelDataErrorView.test.tsx index 10525bf0751..3d8ed667d61 100644 --- a/public/app/features/panel/components/PanelDataErrorView.test.tsx +++ b/public/app/features/panel/components/PanelDataErrorView.test.tsx @@ -1,12 +1,14 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; import { defaultsDeep } from 'lodash'; -import { PanelDataErrorView } from './PanelDataErrorView'; -import { PanelDataErrorViewProps } from '@grafana/runtime'; -import { getDefaultTimeRange, LoadingState } from '@grafana/data'; +import React from 'react'; import { Provider } from 'react-redux'; + +import { getDefaultTimeRange, LoadingState } from '@grafana/data'; +import { PanelDataErrorViewProps } from '@grafana/runtime'; import { configureStore } from 'app/store/configureStore'; +import { PanelDataErrorView } from './PanelDataErrorView'; + describe('PanelDataErrorView', () => { it('show No data when there is no data', () => { renderWithProps(); diff --git a/public/app/features/panel/components/PanelDataErrorView.tsx b/public/app/features/panel/components/PanelDataErrorView.tsx index 55bb7aa50ca..a58848c432c 100644 --- a/public/app/features/panel/components/PanelDataErrorView.tsx +++ b/public/app/features/panel/components/PanelDataErrorView.tsx @@ -1,16 +1,18 @@ -import React from 'react'; -import { CoreApp, GrafanaTheme2, PanelDataSummary, VisualizationSuggestionsBuilder } from '@grafana/data'; -import { usePanelContext, useStyles2 } from '@grafana/ui'; import { css } from '@emotion/css'; -import { PanelDataErrorViewProps } from '@grafana/runtime'; -import { CardButton } from 'app/core/components/CardButton'; +import React from 'react'; import { useDispatch } from 'react-redux'; -import { toggleVizPicker } from 'app/features/dashboard/components/PanelEditor/state/reducers'; -import { changePanelPlugin } from '../state/actions'; -import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv'; -import store from 'app/core/store'; + +import { CoreApp, GrafanaTheme2, PanelDataSummary, VisualizationSuggestionsBuilder } from '@grafana/data'; +import { PanelDataErrorViewProps } from '@grafana/runtime'; +import { usePanelContext, useStyles2 } from '@grafana/ui'; +import { CardButton } from 'app/core/components/CardButton'; import { LS_VISUALIZATION_SELECT_TAB_KEY } from 'app/core/constants'; +import store from 'app/core/store'; +import { toggleVizPicker } from 'app/features/dashboard/components/PanelEditor/state/reducers'; import { VisualizationSelectPaneTab } from 'app/features/dashboard/components/PanelEditor/types'; +import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv'; + +import { changePanelPlugin } from '../state/actions'; export function PanelDataErrorView(props: PanelDataErrorViewProps) { const styles = useStyles2(getStyles); diff --git a/public/app/features/panel/components/PanelPluginError.tsx b/public/app/features/panel/components/PanelPluginError.tsx index 1e001613ffc..0ce26af720f 100644 --- a/public/app/features/panel/components/PanelPluginError.tsx +++ b/public/app/features/panel/components/PanelPluginError.tsx @@ -2,9 +2,9 @@ import React, { PureComponent, ReactNode } from 'react'; // Types -import { AppNotificationSeverity } from 'app/types'; -import { Alert } from '@grafana/ui'; import { PanelProps, PanelPlugin, PluginType, PanelPluginMeta } from '@grafana/data'; +import { Alert } from '@grafana/ui'; +import { AppNotificationSeverity } from 'app/types'; interface Props { title: string; diff --git a/public/app/features/panel/components/PanelRenderer.tsx b/public/app/features/panel/components/PanelRenderer.tsx index 72ceb49bafd..98a86b3a209 100644 --- a/public/app/features/panel/components/PanelRenderer.tsx +++ b/public/app/features/panel/components/PanelRenderer.tsx @@ -1,11 +1,13 @@ import React, { useState, useMemo, useEffect, useRef } from 'react'; +import { useAsync } from 'react-use'; + import { applyFieldOverrides, FieldConfigSource, getTimeZone, PanelData, PanelPlugin } from '@grafana/data'; import { PanelRendererProps } from '@grafana/runtime'; +import { ErrorBoundaryAlert, useTheme2 } from '@grafana/ui'; import { appEvents } from 'app/core/core'; -import { useAsync } from 'react-use'; + import { getPanelOptionsWithDefaults, OptionDefaults } from '../../dashboard/state/getPanelOptionsWithDefaults'; import { importPanelPlugin } from '../../plugins/importPanelPlugin'; -import { ErrorBoundaryAlert, useTheme2 } from '@grafana/ui'; const defaultFieldConfig = { defaults: {}, overrides: [] }; diff --git a/public/app/features/panel/components/VizTypePicker/PanelTypeCard.tsx b/public/app/features/panel/components/VizTypePicker/PanelTypeCard.tsx index 9c2c93f6f9a..7b3c9c57b5f 100644 --- a/public/app/features/panel/components/VizTypePicker/PanelTypeCard.tsx +++ b/public/app/features/panel/components/VizTypePicker/PanelTypeCard.tsx @@ -1,8 +1,9 @@ -import React, { MouseEventHandler } from 'react'; -import { GrafanaTheme2, isUnsignedPluginSignature, PanelPluginMeta, PluginState } from '@grafana/data'; -import { IconButton, PluginSignatureBadge, useStyles2 } from '@grafana/ui'; import { css, cx } from '@emotion/css'; +import React, { MouseEventHandler } from 'react'; + +import { GrafanaTheme2, isUnsignedPluginSignature, PanelPluginMeta, PluginState } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; +import { IconButton, PluginSignatureBadge, useStyles2 } from '@grafana/ui'; import { PluginStateInfo } from 'app/features/plugins/components/PluginStateInfo'; interface Props { diff --git a/public/app/features/panel/components/VizTypePicker/VisualizationSuggestionCard.tsx b/public/app/features/panel/components/VizTypePicker/VisualizationSuggestionCard.tsx index 3305e1f64a2..99725d694fd 100644 --- a/public/app/features/panel/components/VizTypePicker/VisualizationSuggestionCard.tsx +++ b/public/app/features/panel/components/VizTypePicker/VisualizationSuggestionCard.tsx @@ -1,11 +1,14 @@ -import React, { CSSProperties } from 'react'; -import { GrafanaTheme2, PanelData, VisualizationSuggestion } from '@grafana/data'; -import { PanelRenderer } from '../PanelRenderer'; import { css, cx } from '@emotion/css'; -import { Tooltip, useStyles2 } from '@grafana/ui'; -import { VizTypeChangeDetails } from './types'; -import { selectors } from '@grafana/e2e-selectors'; import { cloneDeep } from 'lodash'; +import React, { CSSProperties } from 'react'; + +import { GrafanaTheme2, PanelData, VisualizationSuggestion } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; +import { Tooltip, useStyles2 } from '@grafana/ui'; + +import { PanelRenderer } from '../PanelRenderer'; + +import { VizTypeChangeDetails } from './types'; export interface Props { data: PanelData; diff --git a/public/app/features/panel/components/VizTypePicker/VisualizationSuggestions.tsx b/public/app/features/panel/components/VizTypePicker/VisualizationSuggestions.tsx index f8ecb38c7c3..14cd6bbed8b 100644 --- a/public/app/features/panel/components/VizTypePicker/VisualizationSuggestions.tsx +++ b/public/app/features/panel/components/VizTypePicker/VisualizationSuggestions.tsx @@ -1,13 +1,16 @@ -import React from 'react'; -import { useStyles2 } from '@grafana/ui'; -import { GrafanaTheme2, PanelData, PanelPluginMeta, PanelModel, VisualizationSuggestion } from '@grafana/data'; import { css } from '@emotion/css'; -import { VizTypeChangeDetails } from './types'; -import { VisualizationSuggestionCard } from './VisualizationSuggestionCard'; -import { getAllSuggestions } from '../../state/getAllSuggestions'; +import React from 'react'; import { useAsync, useLocalStorage } from 'react-use'; import AutoSizer from 'react-virtualized-auto-sizer'; +import { GrafanaTheme2, PanelData, PanelPluginMeta, PanelModel, VisualizationSuggestion } from '@grafana/data'; +import { useStyles2 } from '@grafana/ui'; + +import { getAllSuggestions } from '../../state/getAllSuggestions'; + +import { VisualizationSuggestionCard } from './VisualizationSuggestionCard'; +import { VizTypeChangeDetails } from './types'; + export interface Props { current: PanelPluginMeta; data?: PanelData; diff --git a/public/app/features/panel/components/VizTypePicker/VizTypePicker.tsx b/public/app/features/panel/components/VizTypePicker/VizTypePicker.tsx index 01cb66ffd57..76f6687e0e6 100644 --- a/public/app/features/panel/components/VizTypePicker/VizTypePicker.tsx +++ b/public/app/features/panel/components/VizTypePicker/VizTypePicker.tsx @@ -1,9 +1,12 @@ -import React, { useMemo } from 'react'; -import { VizTypePickerPlugin } from './VizTypePickerPlugin'; -import { EmptySearchResult, useStyles2 } from '@grafana/ui'; -import { GrafanaTheme2, PanelData, PanelPluginMeta } from '@grafana/data'; import { css } from '@emotion/css'; +import React, { useMemo } from 'react'; + +import { GrafanaTheme2, PanelData, PanelPluginMeta } from '@grafana/data'; +import { EmptySearchResult, useStyles2 } from '@grafana/ui'; + import { filterPluginList, getAllPanelPluginMeta } from '../../state/util'; + +import { VizTypePickerPlugin } from './VizTypePickerPlugin'; import { VizTypeChangeDetails } from './types'; export interface Props { diff --git a/public/app/features/panel/components/VizTypePicker/VizTypePickerPlugin.tsx b/public/app/features/panel/components/VizTypePicker/VizTypePickerPlugin.tsx index c39c9582a97..c792da0f90e 100644 --- a/public/app/features/panel/components/VizTypePicker/VizTypePickerPlugin.tsx +++ b/public/app/features/panel/components/VizTypePicker/VizTypePickerPlugin.tsx @@ -1,5 +1,7 @@ import React, { MouseEventHandler } from 'react'; + import { PanelPluginMeta } from '@grafana/data'; + import { PanelTypeCard } from './PanelTypeCard'; interface Props { diff --git a/public/app/features/panel/panellinks/linkSuppliers.test.ts b/public/app/features/panel/panellinks/linkSuppliers.test.ts index 69f44e4af14..2bdf1977972 100644 --- a/public/app/features/panel/panellinks/linkSuppliers.test.ts +++ b/public/app/features/panel/panellinks/linkSuppliers.test.ts @@ -1,8 +1,10 @@ -import { getFieldLinksSupplier } from './linkSuppliers'; import { applyFieldOverrides, createTheme, DataFrameView, dateTime, FieldDisplay, toDataFrame } from '@grafana/data'; -import { getLinkSrv, LinkService, LinkSrv, setLinkSrv } from './link_srv'; + import { TemplateSrv } from '../../templating/template_srv'; +import { getFieldLinksSupplier } from './linkSuppliers'; +import { getLinkSrv, LinkService, LinkSrv, setLinkSrv } from './link_srv'; + // We do not need more here and TimeSrv is hard to setup fully. jest.mock('app/features/dashboard/services/TimeSrv', () => ({ getTimeSrv: () => ({ diff --git a/public/app/features/panel/panellinks/linkSuppliers.ts b/public/app/features/panel/panellinks/linkSuppliers.ts index 65f2d075b3d..f34da404f94 100644 --- a/public/app/features/panel/panellinks/linkSuppliers.ts +++ b/public/app/features/panel/panellinks/linkSuppliers.ts @@ -1,4 +1,3 @@ -import { PanelModel } from 'app/features/dashboard/state/PanelModel'; import { DataLink, DisplayValue, @@ -12,6 +11,8 @@ import { ScopedVar, ScopedVars, } from '@grafana/data'; +import { PanelModel } from 'app/features/dashboard/state/PanelModel'; + import { getLinkSrv } from './link_srv'; interface SeriesVars { diff --git a/public/app/features/panel/panellinks/link_srv.ts b/public/app/features/panel/panellinks/link_srv.ts index a803bd8ec0f..88477e5d60b 100644 --- a/public/app/features/panel/panellinks/link_srv.ts +++ b/public/app/features/panel/panellinks/link_srv.ts @@ -1,7 +1,5 @@ import { chain } from 'lodash'; -import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv'; -import { getTemplateSrv } from '@grafana/runtime'; -import { getConfig } from 'app/core/config'; + import { DataFrame, DataLink, @@ -21,6 +19,10 @@ import { VariableSuggestion, VariableSuggestionsScope, } from '@grafana/data'; +import { getTemplateSrv } from '@grafana/runtime'; +import { getConfig } from 'app/core/config'; +import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv'; + import { getVariablesUrlParams } from '../../variables/getAllVariableValuesForUrl'; const timeRangeVars = [ diff --git a/public/app/features/panel/panellinks/specs/link_srv.test.ts b/public/app/features/panel/panellinks/specs/link_srv.test.ts index b2b30096045..791a95d7441 100644 --- a/public/app/features/panel/panellinks/specs/link_srv.test.ts +++ b/public/app/features/panel/panellinks/specs/link_srv.test.ts @@ -1,12 +1,13 @@ import { FieldType, locationUtil, toDataFrame, VariableOrigin } from '@grafana/data'; import { setTemplateSrv } from '@grafana/runtime'; -import { getDataFrameVars, LinkSrv } from '../link_srv'; import { getTimeSrv, setTimeSrv, TimeSrv } from 'app/features/dashboard/services/TimeSrv'; import { TemplateSrv } from 'app/features/templating/template_srv'; import { variableAdapters } from 'app/features/variables/adapters'; import { createQueryVariableAdapter } from 'app/features/variables/query/adapter'; -import { updateConfig } from '../../../../core/config'; + import { initTemplateSrv } from '../../../../../test/helpers/initTemplateSrv'; +import { updateConfig } from '../../../../core/config'; +import { getDataFrameVars, LinkSrv } from '../link_srv'; jest.mock('app/core/core', () => ({ appEvents: { diff --git a/public/app/features/panel/state/actions.test.ts b/public/app/features/panel/state/actions.test.ts index 65cd5bcfbc0..beb0687757b 100644 --- a/public/app/features/panel/state/actions.test.ts +++ b/public/app/features/panel/state/actions.test.ts @@ -1,11 +1,14 @@ +import { mockStandardFieldConfigOptions } from 'test/helpers/fieldConfig'; + +import { standardEditorsRegistry, standardFieldConfigEditorRegistry } from '@grafana/data'; import { PanelModel } from 'app/features/dashboard/state'; -import { thunkTester } from '../../../../test/core/thunk/thunkTester'; -import { changePanelPlugin } from './actions'; -import { panelModelAndPluginReady } from './reducers'; import { getPanelPlugin } from 'app/features/plugins/__mocks__/pluginMocks'; import { panelPluginLoaded } from 'app/features/plugins/admin/state/actions'; -import { standardEditorsRegistry, standardFieldConfigEditorRegistry } from '@grafana/data'; -import { mockStandardFieldConfigOptions } from 'test/helpers/fieldConfig'; + +import { thunkTester } from '../../../../test/core/thunk/thunkTester'; + +import { changePanelPlugin } from './actions'; +import { panelModelAndPluginReady } from './reducers'; jest.mock('app/features/plugins/importPanelPlugin', () => { return { diff --git a/public/app/features/panel/state/actions.ts b/public/app/features/panel/state/actions.ts index 0864c763632..1bfb01dac2b 100644 --- a/public/app/features/panel/state/actions.ts +++ b/public/app/features/panel/state/actions.ts @@ -1,7 +1,13 @@ -import { getPanelPluginNotFound } from 'app/features/panel/components/PanelPluginError'; +import { DataTransformerConfig, FieldConfigSource } from '@grafana/data'; import { PanelModel } from 'app/features/dashboard/state/PanelModel'; +import { getPanelOptionsWithDefaults } from 'app/features/dashboard/state/getPanelOptionsWithDefaults'; +import { LibraryElementDTO } from 'app/features/library-panels/types'; +import { toPanelModelLibraryPanel } from 'app/features/library-panels/utils'; +import { getPanelPluginNotFound } from 'app/features/panel/components/PanelPluginError'; import { loadPanelPlugin } from 'app/features/plugins/admin/state/actions'; import { ThunkResult } from 'app/types'; +import { PanelOptionsChangedEvent, PanelQueriesChangedEvent } from 'app/types/events'; + import { changePanelKey, cleanUpAngularComponent, @@ -9,11 +15,6 @@ import { removePanel, removePanels, } from './reducers'; -import { LibraryElementDTO } from 'app/features/library-panels/types'; -import { toPanelModelLibraryPanel } from 'app/features/library-panels/utils'; -import { PanelOptionsChangedEvent, PanelQueriesChangedEvent } from 'app/types/events'; -import { DataTransformerConfig, FieldConfigSource } from '@grafana/data'; -import { getPanelOptionsWithDefaults } from 'app/features/dashboard/state/getPanelOptionsWithDefaults'; export function initPanelState(panel: PanelModel): ThunkResult { return async (dispatch, getStore) => { diff --git a/public/app/features/panel/state/getAllSuggestions.test.ts b/public/app/features/panel/state/getAllSuggestions.test.ts index 13200f1b454..dcb489ff84a 100644 --- a/public/app/features/panel/state/getAllSuggestions.test.ts +++ b/public/app/features/panel/state/getAllSuggestions.test.ts @@ -10,6 +10,7 @@ import { } from '@grafana/data'; import { config } from 'app/core/config'; import { SuggestionName } from 'app/types/suggestions'; + import { getAllSuggestions, panelsToCheckFirst } from './getAllSuggestions'; jest.unmock('app/core/core'); diff --git a/public/app/features/panel/state/reducers.ts b/public/app/features/panel/state/reducers.ts index b809a223ba4..7c61f4f46cc 100644 --- a/public/app/features/panel/state/reducers.ts +++ b/public/app/features/panel/state/reducers.ts @@ -1,6 +1,7 @@ import { createSlice, Draft, PayloadAction } from '@reduxjs/toolkit'; -import { AngularComponent } from '@grafana/runtime'; + import { PanelPlugin } from '@grafana/data'; +import { AngularComponent } from '@grafana/runtime'; export type RootPanelsState = Record; diff --git a/public/app/features/panel/state/selectors.ts b/public/app/features/panel/state/selectors.ts index af4aac6faee..5bfaccfe5f7 100644 --- a/public/app/features/panel/state/selectors.ts +++ b/public/app/features/panel/state/selectors.ts @@ -1,5 +1,6 @@ import { PanelModel } from 'app/features/dashboard/state'; import { StoreState } from 'app/types'; + import { PanelState } from './reducers'; export function getPanelStateForModel(state: StoreState, model: PanelModel): PanelState | undefined { diff --git a/public/app/features/panel/state/utils.test.ts b/public/app/features/panel/state/utils.test.ts index 6735aeb9a98..f37af140f32 100644 --- a/public/app/features/panel/state/utils.test.ts +++ b/public/app/features/panel/state/utils.test.ts @@ -1,4 +1,5 @@ import { PanelPluginMeta, escapeStringForRegex } from '@grafana/data'; + import { filterPluginList } from './util'; describe('panel state utils', () => { diff --git a/public/app/features/playlist/EmptyQueryListBanner.tsx b/public/app/features/playlist/EmptyQueryListBanner.tsx index 6a098c21d30..2a2e7967cb1 100644 --- a/public/app/features/playlist/EmptyQueryListBanner.tsx +++ b/public/app/features/playlist/EmptyQueryListBanner.tsx @@ -1,7 +1,8 @@ -import React from 'react'; -import { useStyles2 } from '@grafana/ui'; -import { GrafanaTheme2 } from '@grafana/data'; import { css } from '@emotion/css'; +import React from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; +import { useStyles2 } from '@grafana/ui'; export const EmptyQueryListBanner = () => { const styles = useStyles2(getStyles); diff --git a/public/app/features/playlist/PlaylistEditPage.test.tsx b/public/app/features/playlist/PlaylistEditPage.test.tsx index b72ab02eb0a..4815eb4e183 100644 --- a/public/app/features/playlist/PlaylistEditPage.test.tsx +++ b/public/app/features/playlist/PlaylistEditPage.test.tsx @@ -1,11 +1,12 @@ -import React from 'react'; import { fireEvent, render, screen, waitFor } from '@testing-library/react'; - -import { Playlist } from './types'; -import { PlaylistEditPage } from './PlaylistEditPage'; -import { backendSrv } from 'app/core/services/backend_srv'; import userEvent from '@testing-library/user-event'; +import React from 'react'; + import { locationService } from '@grafana/runtime'; +import { backendSrv } from 'app/core/services/backend_srv'; + +import { PlaylistEditPage } from './PlaylistEditPage'; +import { Playlist } from './types'; jest.mock('@grafana/runtime', () => ({ ...(jest.requireActual('@grafana/runtime') as any), diff --git a/public/app/features/playlist/PlaylistEditPage.tsx b/public/app/features/playlist/PlaylistEditPage.tsx index 2643a95cee7..15855980dd3 100644 --- a/public/app/features/playlist/PlaylistEditPage.tsx +++ b/public/app/features/playlist/PlaylistEditPage.tsx @@ -1,18 +1,20 @@ import React, { FC } from 'react'; import { connect, MapStateToProps } from 'react-redux'; + import { NavModel } from '@grafana/data'; import { locationService } from '@grafana/runtime'; import { useStyles2 } from '@grafana/ui'; - import Page from 'app/core/components/Page/Page'; -import { StoreState } from 'app/types'; -import { GrafanaRouteComponentProps } from '../../core/navigation/types'; import { getNavModel } from 'app/core/selectors/navModel'; +import { StoreState } from 'app/types'; + +import { GrafanaRouteComponentProps } from '../../core/navigation/types'; + import { PlaylistForm } from './PlaylistForm'; import { updatePlaylist } from './api'; +import { getPlaylistStyles } from './styles'; import { Playlist } from './types'; import { usePlaylist } from './usePlaylist'; -import { getPlaylistStyles } from './styles'; interface ConnectedProps { navModel: NavModel; diff --git a/public/app/features/playlist/PlaylistForm.test.tsx b/public/app/features/playlist/PlaylistForm.test.tsx index 2786ae0006a..d257436645d 100644 --- a/public/app/features/playlist/PlaylistForm.test.tsx +++ b/public/app/features/playlist/PlaylistForm.test.tsx @@ -1,10 +1,10 @@ -import React from 'react'; -import { fireEvent, render, screen, waitFor } from '@testing-library/react'; import { within } from '@testing-library/dom'; +import { fireEvent, render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import React from 'react'; -import { Playlist } from './types'; import { PlaylistForm } from './PlaylistForm'; +import { Playlist } from './types'; jest.mock('../../core/components/TagFilter/TagFilter', () => ({ TagFilter: () => { diff --git a/public/app/features/playlist/PlaylistForm.tsx b/public/app/features/playlist/PlaylistForm.tsx index 6e5b6662c99..b648b151330 100644 --- a/public/app/features/playlist/PlaylistForm.tsx +++ b/public/app/features/playlist/PlaylistForm.tsx @@ -1,14 +1,16 @@ import React, { FC } from 'react'; + +import { selectors } from '@grafana/e2e-selectors'; import { config } from '@grafana/runtime'; import { Button, Field, Form, HorizontalGroup, Input, LinkButton } from '@grafana/ui'; -import { selectors } from '@grafana/e2e-selectors'; +import { DashboardPickerByID } from 'app/core/components/editors/DashboardPickerByID'; -import { Playlist } from './types'; import { TagFilter } from '../../core/components/TagFilter/TagFilter'; import { SearchSrv } from '../../core/services/search_srv'; -import { usePlaylistItems } from './usePlaylistItems'; + import { PlaylistTable } from './PlaylistTable'; -import { DashboardPickerByID } from 'app/core/components/editors/DashboardPickerByID'; +import { Playlist } from './types'; +import { usePlaylistItems } from './usePlaylistItems'; interface PlaylistFormProps { onSubmit: (playlist: Playlist) => void; diff --git a/public/app/features/playlist/PlaylistNewPage.test.tsx b/public/app/features/playlist/PlaylistNewPage.test.tsx index c7011b41414..9dbb9cadab0 100644 --- a/public/app/features/playlist/PlaylistNewPage.test.tsx +++ b/public/app/features/playlist/PlaylistNewPage.test.tsx @@ -1,12 +1,14 @@ -import React from 'react'; import { fireEvent, render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import React from 'react'; -import { Playlist } from './types'; -import { PlaylistNewPage } from './PlaylistNewPage'; -import { backendSrv } from '../../core/services/backend_srv'; import { locationService } from '@grafana/runtime'; +import { backendSrv } from '../../core/services/backend_srv'; + +import { PlaylistNewPage } from './PlaylistNewPage'; +import { Playlist } from './types'; + jest.mock('./usePlaylist', () => ({ // so we don't need to add dashboard items in test usePlaylist: jest.fn().mockReturnValue({ diff --git a/public/app/features/playlist/PlaylistNewPage.tsx b/public/app/features/playlist/PlaylistNewPage.tsx index 29449d91044..c08d288ec99 100644 --- a/public/app/features/playlist/PlaylistNewPage.tsx +++ b/public/app/features/playlist/PlaylistNewPage.tsx @@ -1,18 +1,20 @@ import React, { FC } from 'react'; import { connect, MapStateToProps } from 'react-redux'; + import { NavModel } from '@grafana/data'; import { locationService } from '@grafana/runtime'; import { useStyles2 } from '@grafana/ui'; - import Page from 'app/core/components/Page/Page'; -import { StoreState } from 'app/types'; -import { GrafanaRouteComponentProps } from '../../core/navigation/types'; import { getNavModel } from 'app/core/selectors/navModel'; +import { StoreState } from 'app/types'; + +import { GrafanaRouteComponentProps } from '../../core/navigation/types'; + import { PlaylistForm } from './PlaylistForm'; import { createPlaylist } from './api'; +import { getPlaylistStyles } from './styles'; import { Playlist } from './types'; import { usePlaylist } from './usePlaylist'; -import { getPlaylistStyles } from './styles'; interface ConnectedProps { navModel: NavModel; diff --git a/public/app/features/playlist/PlaylistPage.test.tsx b/public/app/features/playlist/PlaylistPage.test.tsx index f60149d3df9..861bd8759e0 100644 --- a/public/app/features/playlist/PlaylistPage.test.tsx +++ b/public/app/features/playlist/PlaylistPage.test.tsx @@ -1,8 +1,10 @@ -import React from 'react'; import { render, waitFor } from '@testing-library/react'; -import { PlaylistPage, PlaylistPageProps } from './PlaylistPage'; +import React from 'react'; + import { locationService } from '../../../../packages/grafana-runtime/src'; +import { PlaylistPage, PlaylistPageProps } from './PlaylistPage'; + const fnMock = jest.fn(); jest.mock('@grafana/runtime', () => ({ diff --git a/public/app/features/playlist/PlaylistPage.tsx b/public/app/features/playlist/PlaylistPage.tsx index 3477bc489d8..715de58040d 100644 --- a/public/app/features/playlist/PlaylistPage.tsx +++ b/public/app/features/playlist/PlaylistPage.tsx @@ -1,19 +1,22 @@ import React, { FC, useState } from 'react'; import { connect, MapStateToProps } from 'react-redux'; -import { NavModel } from '@grafana/data'; -import Page from 'app/core/components/Page/Page'; -import { StoreState } from 'app/types'; -import { GrafanaRouteComponentProps } from '../../core/navigation/types'; -import { getNavModel } from 'app/core/selectors/navModel'; import { useDebounce } from 'react-use'; -import { PlaylistDTO } from './types'; + +import { NavModel } from '@grafana/data'; import { ConfirmModal } from '@grafana/ui'; +import Page from 'app/core/components/Page/Page'; import PageActionBar from 'app/core/components/PageActionBar/PageActionBar'; +import { getNavModel } from 'app/core/selectors/navModel'; +import { StoreState } from 'app/types'; + import EmptyListCTA from '../../core/components/EmptyListCTA/EmptyListCTA'; -import { deletePlaylist, getAllPlaylist } from './api'; -import { StartModal } from './StartModal'; -import { PlaylistPageList } from './PlaylistPageList'; +import { GrafanaRouteComponentProps } from '../../core/navigation/types'; + import { EmptyQueryListBanner } from './EmptyQueryListBanner'; +import { PlaylistPageList } from './PlaylistPageList'; +import { StartModal } from './StartModal'; +import { deletePlaylist, getAllPlaylist } from './api'; +import { PlaylistDTO } from './types'; interface ConnectedProps { navModel: NavModel; diff --git a/public/app/features/playlist/PlaylistPageList.tsx b/public/app/features/playlist/PlaylistPageList.tsx index 79adbe7e964..d8b77397b05 100644 --- a/public/app/features/playlist/PlaylistPageList.tsx +++ b/public/app/features/playlist/PlaylistPageList.tsx @@ -1,11 +1,14 @@ +import { css } from '@emotion/css'; import React from 'react'; -import { PlaylistDTO } from './types'; + +import { GrafanaTheme2 } from '@grafana/data'; import { Button, Card, LinkButton, ModalsController, useStyles2 } from '@grafana/ui'; import { contextSrv } from 'app/core/services/context_srv'; -import { GrafanaTheme2 } from '@grafana/data'; -import { css } from '@emotion/css'; + import { DashNavButton } from '../dashboard/components/DashNav/DashNavButton'; + import { ShareModal } from './ShareModal'; +import { PlaylistDTO } from './types'; interface Props { setStartPlaylist: (playlistItem: PlaylistDTO) => void; diff --git a/public/app/features/playlist/PlaylistSrv.test.ts b/public/app/features/playlist/PlaylistSrv.test.ts index d886883e9c4..b5238fe9c4d 100644 --- a/public/app/features/playlist/PlaylistSrv.test.ts +++ b/public/app/features/playlist/PlaylistSrv.test.ts @@ -1,8 +1,10 @@ // @ts-ignore import configureMockStore from 'redux-mock-store'; -import { PlaylistSrv } from './PlaylistSrv'; -import { setStore } from 'app/store/store'; + import { locationService } from '@grafana/runtime'; +import { setStore } from 'app/store/store'; + +import { PlaylistSrv } from './PlaylistSrv'; const getMock = jest.fn(); diff --git a/public/app/features/playlist/PlaylistSrv.ts b/public/app/features/playlist/PlaylistSrv.ts index b959d5eed17..a2d1704c565 100644 --- a/public/app/features/playlist/PlaylistSrv.ts +++ b/public/app/features/playlist/PlaylistSrv.ts @@ -1,10 +1,10 @@ // Libraries +import { Location } from 'history'; import { pickBy } from 'lodash'; // Utils -import { getBackendSrv, locationService } from '@grafana/runtime'; import { locationUtil, urlUtil, rangeUtil } from '@grafana/data'; -import { Location } from 'history'; +import { getBackendSrv, locationService } from '@grafana/runtime'; export const queryParamsToPreserve: { [key: string]: boolean } = { kiosk: true, diff --git a/public/app/features/playlist/PlaylistStartPage.tsx b/public/app/features/playlist/PlaylistStartPage.tsx index 5ca538b096a..07741b62d62 100644 --- a/public/app/features/playlist/PlaylistStartPage.tsx +++ b/public/app/features/playlist/PlaylistStartPage.tsx @@ -1,5 +1,7 @@ import { FC } from 'react'; + import { GrafanaRouteComponentProps } from '../../core/navigation/types'; + import { playlistSrv } from './PlaylistSrv'; interface Props extends GrafanaRouteComponentProps<{ id: string }> {} diff --git a/public/app/features/playlist/PlaylistTableRow.tsx b/public/app/features/playlist/PlaylistTableRow.tsx index 79ec985c757..ca34695e4ac 100644 --- a/public/app/features/playlist/PlaylistTableRow.tsx +++ b/public/app/features/playlist/PlaylistTableRow.tsx @@ -1,11 +1,13 @@ -import React, { FC, MouseEvent } from 'react'; import { css, cx } from '@emotion/css'; -import { Icon, IconButton, useStyles } from '@grafana/ui'; +import React, { FC, MouseEvent } from 'react'; + import { GrafanaTheme } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; +import { Icon, IconButton, useStyles } from '@grafana/ui'; import { TagBadge } from '../../core/components/TagFilter/TagBadge'; + import { PlaylistItem } from './types'; -import { selectors } from '@grafana/e2e-selectors'; interface PlaylistTableRowProps { first: boolean; diff --git a/public/app/features/playlist/ShareModal.tsx b/public/app/features/playlist/ShareModal.tsx index e43450525d6..ce312acfe6d 100644 --- a/public/app/features/playlist/ShareModal.tsx +++ b/public/app/features/playlist/ShareModal.tsx @@ -1,8 +1,11 @@ import React, { useState } from 'react'; + import { AppEvents, SelectableValue, UrlQueryMap, urlUtil } from '@grafana/data'; import { Checkbox, ClipboardButton, Field, FieldSet, Icon, Input, Modal, RadioButtonGroup } from '@grafana/ui'; import appEvents from 'app/core/app_events'; + import { buildBaseUrl } from '../dashboard/components/ShareModal/utils'; + import { PlaylistMode } from './types'; interface ShareModalProps { diff --git a/public/app/features/playlist/StartModal.tsx b/public/app/features/playlist/StartModal.tsx index ffe772e91df..8d9e85443ab 100644 --- a/public/app/features/playlist/StartModal.tsx +++ b/public/app/features/playlist/StartModal.tsx @@ -1,9 +1,11 @@ import React, { FC, useState } from 'react'; + import { SelectableValue, urlUtil } from '@grafana/data'; import { locationService } from '@grafana/runtime'; -import { PlaylistDTO, PlaylistMode } from './types'; import { Button, Checkbox, Field, FieldSet, Modal, RadioButtonGroup } from '@grafana/ui'; +import { PlaylistDTO, PlaylistMode } from './types'; + export interface StartModalProps { playlist: PlaylistDTO; onDismiss: () => void; diff --git a/public/app/features/playlist/api.ts b/public/app/features/playlist/api.ts index d7b6f2739a0..cab3e54859a 100644 --- a/public/app/features/playlist/api.ts +++ b/public/app/features/playlist/api.ts @@ -1,9 +1,10 @@ import { getBackendSrv } from '@grafana/runtime'; -import { Playlist, PlaylistDTO } from './types'; -import { dispatch } from '../../store/store'; import { notifyApp } from '../../core/actions'; import { createErrorNotification, createSuccessNotification } from '../../core/copy/appNotification'; +import { dispatch } from '../../store/store'; + +import { Playlist, PlaylistDTO } from './types'; export async function createPlaylist(playlist: Playlist) { await withErrorHandling(() => getBackendSrv().post('/api/playlists', playlist)); diff --git a/public/app/features/playlist/styles.ts b/public/app/features/playlist/styles.ts index 4a301594464..0d04725bae5 100644 --- a/public/app/features/playlist/styles.ts +++ b/public/app/features/playlist/styles.ts @@ -1,6 +1,7 @@ -import { GrafanaTheme2 } from '@grafana/data'; import { css } from '@emotion/css'; +import { GrafanaTheme2 } from '@grafana/data'; + export function getPlaylistStyles(theme: GrafanaTheme2) { return { description: css` diff --git a/public/app/features/playlist/usePlaylist.tsx b/public/app/features/playlist/usePlaylist.tsx index b3e7e872889..6cb9d0f006f 100644 --- a/public/app/features/playlist/usePlaylist.tsx +++ b/public/app/features/playlist/usePlaylist.tsx @@ -1,6 +1,7 @@ import { useEffect, useState } from 'react'; -import { Playlist } from './types'; + import { getPlaylist } from './api'; +import { Playlist } from './types'; export function usePlaylist(playlistId?: number) { const [playlist, setPlaylist] = useState({ items: [], interval: '5m', name: '' }); diff --git a/public/app/features/playlist/usePlaylistItems.tsx b/public/app/features/playlist/usePlaylistItems.tsx index 576879190d4..83e58132705 100644 --- a/public/app/features/playlist/usePlaylistItems.tsx +++ b/public/app/features/playlist/usePlaylistItems.tsx @@ -1,6 +1,7 @@ -import { DashboardPickerItem } from 'app/core/components/editors/DashboardPickerByID'; import { useCallback, useState } from 'react'; +import { DashboardPickerItem } from 'app/core/components/editors/DashboardPickerByID'; + import { PlaylistItem } from './types'; export function usePlaylistItems(playlistItems?: PlaylistItem[]) { diff --git a/public/app/features/plugins/__mocks__/pluginMocks.ts b/public/app/features/plugins/__mocks__/pluginMocks.ts index dbbd1fb89ad..372e2f49c2e 100644 --- a/public/app/features/plugins/__mocks__/pluginMocks.ts +++ b/public/app/features/plugins/__mocks__/pluginMocks.ts @@ -1,6 +1,7 @@ -import { defaultsDeep } from 'lodash'; -import { PanelPluginMeta, PluginMeta, PluginType, PanelPlugin, PanelProps } from '@grafana/data'; import { ComponentType } from 'enzyme'; +import { defaultsDeep } from 'lodash'; + +import { PanelPluginMeta, PluginMeta, PluginType, PanelPlugin, PanelProps } from '@grafana/data'; export const getMockPlugins = (amount: number): PluginMeta[] => { const plugins = []; diff --git a/public/app/features/plugins/admin/__mocks__/mockHelpers.ts b/public/app/features/plugins/admin/__mocks__/mockHelpers.ts index ac18a598857..096f7384dc2 100644 --- a/public/app/features/plugins/admin/__mocks__/mockHelpers.ts +++ b/public/app/features/plugins/admin/__mocks__/mockHelpers.ts @@ -1,5 +1,7 @@ import { setBackendSrv } from '@grafana/runtime'; + import { API_ROOT, GCOM_API_ROOT } from '../constants'; +import * as permissions from '../permissions'; import { CatalogPlugin, LocalPlugin, @@ -9,10 +11,10 @@ import { RequestStatus, PluginListDisplayMode, } from '../types'; -import * as permissions from '../permissions'; -import remotePluginMock from './remotePlugin.mock'; -import localPluginMock from './localPlugin.mock'; + import catalogPluginMock from './catalogPlugin.mock'; +import localPluginMock from './localPlugin.mock'; +import remotePluginMock from './remotePlugin.mock'; // Returns a sample mock for a CatalogPlugin plugin with the possibility to extend it export const getCatalogPluginMock = (overrides?: Partial) => ({ ...catalogPluginMock, ...overrides }); diff --git a/public/app/features/plugins/admin/__mocks__/remotePlugin.mock.ts b/public/app/features/plugins/admin/__mocks__/remotePlugin.mock.ts index 903d6b7435b..1ea0ed50654 100644 --- a/public/app/features/plugins/admin/__mocks__/remotePlugin.mock.ts +++ b/public/app/features/plugins/admin/__mocks__/remotePlugin.mock.ts @@ -1,4 +1,5 @@ import { PluginSignatureType, PluginType } from '@grafana/data'; + import { RemotePlugin } from '../types'; // Copied from /api/gnet/plugins/alexanderzobnin-zabbix-app diff --git a/public/app/features/plugins/admin/api.ts b/public/app/features/plugins/admin/api.ts index fbca7d8a193..949209b42bc 100644 --- a/public/app/features/plugins/admin/api.ts +++ b/public/app/features/plugins/admin/api.ts @@ -1,8 +1,9 @@ -import { getBackendSrv } from '@grafana/runtime'; import { PluginError, PluginMeta, renderMarkdown } from '@grafana/data'; +import { getBackendSrv } from '@grafana/runtime'; + import { API_ROOT, GCOM_API_ROOT } from './constants'; -import { LocalPlugin, RemotePlugin, CatalogPluginDetails, Version, PluginVersion } from './types'; import { isLocalPluginVisible, isRemotePluginVisible } from './helpers'; +import { LocalPlugin, RemotePlugin, CatalogPluginDetails, Version, PluginVersion } from './types'; export async function getPluginDetails(id: string): Promise { const remote = await getRemotePlugin(id); diff --git a/public/app/features/plugins/admin/components/AppConfigWrapper.tsx b/public/app/features/plugins/admin/components/AppConfigWrapper.tsx index 267455ed1d4..f2f71509e88 100644 --- a/public/app/features/plugins/admin/components/AppConfigWrapper.tsx +++ b/public/app/features/plugins/admin/components/AppConfigWrapper.tsx @@ -1,12 +1,11 @@ // Libraries -import React, { PureComponent } from 'react'; +import { css } from '@emotion/css'; import { cloneDeep, extend } from 'lodash'; +import React, { PureComponent } from 'react'; -import { Button } from '@grafana/ui'; import { PluginMeta, AppPlugin, deprecationWarning } from '@grafana/data'; import { AngularComponent, getAngularLoader, getBackendSrv } from '@grafana/runtime'; - -import { css } from '@emotion/css'; +import { Button } from '@grafana/ui'; interface Props { app: AppPlugin; diff --git a/public/app/features/plugins/admin/components/Badges/PluginDisabledBadge.tsx b/public/app/features/plugins/admin/components/Badges/PluginDisabledBadge.tsx index 22178e64fe4..dbac4871b07 100644 --- a/public/app/features/plugins/admin/components/Badges/PluginDisabledBadge.tsx +++ b/public/app/features/plugins/admin/components/Badges/PluginDisabledBadge.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { PluginErrorCode } from '@grafana/data'; import { Badge } from '@grafana/ui'; diff --git a/public/app/features/plugins/admin/components/Badges/PluginEnterpriseBadge.tsx b/public/app/features/plugins/admin/components/Badges/PluginEnterpriseBadge.tsx index 345e077ba5f..7032ce2d22c 100644 --- a/public/app/features/plugins/admin/components/Badges/PluginEnterpriseBadge.tsx +++ b/public/app/features/plugins/admin/components/Badges/PluginEnterpriseBadge.tsx @@ -1,8 +1,11 @@ import React from 'react'; -import { Badge, Button, HorizontalGroup, PluginSignatureBadge, useStyles2 } from '@grafana/ui'; -import { CatalogPlugin } from '../../types'; -import { getBadgeColor } from './sharedStyles'; + import { featureEnabled } from '@grafana/runtime'; +import { Badge, Button, HorizontalGroup, PluginSignatureBadge, useStyles2 } from '@grafana/ui'; + +import { CatalogPlugin } from '../../types'; + +import { getBadgeColor } from './sharedStyles'; type Props = { plugin: CatalogPlugin }; diff --git a/public/app/features/plugins/admin/components/Badges/PluginInstallBadge.tsx b/public/app/features/plugins/admin/components/Badges/PluginInstallBadge.tsx index dc035ec77ff..bc5c182af68 100644 --- a/public/app/features/plugins/admin/components/Badges/PluginInstallBadge.tsx +++ b/public/app/features/plugins/admin/components/Badges/PluginInstallBadge.tsx @@ -1,5 +1,7 @@ import React from 'react'; + import { Badge, useStyles2 } from '@grafana/ui'; + import { getBadgeColor } from './sharedStyles'; export function PluginInstalledBadge(): React.ReactElement { diff --git a/public/app/features/plugins/admin/components/Badges/PluginUpdateAvailableBadge.tsx b/public/app/features/plugins/admin/components/Badges/PluginUpdateAvailableBadge.tsx index 2c518c5179b..f726ac2fc26 100644 --- a/public/app/features/plugins/admin/components/Badges/PluginUpdateAvailableBadge.tsx +++ b/public/app/features/plugins/admin/components/Badges/PluginUpdateAvailableBadge.tsx @@ -1,7 +1,9 @@ -import React from 'react'; import { css } from '@emotion/css'; +import React from 'react'; + import { GrafanaTheme2, PluginType } from '@grafana/data'; import { useStyles2 } from '@grafana/ui'; + import { CatalogPlugin } from '../../types'; type Props = { diff --git a/public/app/features/plugins/admin/components/Badges/sharedStyles.ts b/public/app/features/plugins/admin/components/Badges/sharedStyles.ts index 26486c6ad57..9ad5e6521f4 100644 --- a/public/app/features/plugins/admin/components/Badges/sharedStyles.ts +++ b/public/app/features/plugins/admin/components/Badges/sharedStyles.ts @@ -1,4 +1,5 @@ import { css } from '@emotion/css'; + import { GrafanaTheme2 } from '@grafana/data'; export const getBadgeColor = (theme: GrafanaTheme2) => css` diff --git a/public/app/features/plugins/admin/components/GetStartedWithPlugin/GetStartedWithApp.tsx b/public/app/features/plugins/admin/components/GetStartedWithPlugin/GetStartedWithApp.tsx index 08ebd079970..90e93f83ac4 100644 --- a/public/app/features/plugins/admin/components/GetStartedWithPlugin/GetStartedWithApp.tsx +++ b/public/app/features/plugins/admin/components/GetStartedWithPlugin/GetStartedWithApp.tsx @@ -1,8 +1,10 @@ +import React from 'react'; + import { PluginMeta } from '@grafana/data'; import { Button } from '@grafana/ui'; -import { usePluginConfig } from '../../hooks/usePluginConfig'; + import { updatePluginSettings } from '../../api'; -import React from 'react'; +import { usePluginConfig } from '../../hooks/usePluginConfig'; import { CatalogPlugin } from '../../types'; type Props = { diff --git a/public/app/features/plugins/admin/components/GetStartedWithPlugin/GetStartedWithDataSource.tsx b/public/app/features/plugins/admin/components/GetStartedWithPlugin/GetStartedWithDataSource.tsx index 55e7c3f29ae..7f4e9cdf903 100644 --- a/public/app/features/plugins/admin/components/GetStartedWithPlugin/GetStartedWithDataSource.tsx +++ b/public/app/features/plugins/admin/components/GetStartedWithPlugin/GetStartedWithDataSource.tsx @@ -1,8 +1,10 @@ +import React, { useCallback } from 'react'; +import { useDispatch } from 'react-redux'; + import { DataSourcePluginMeta } from '@grafana/data'; import { Button } from '@grafana/ui'; import { addDataSource } from 'app/features/datasources/state/actions'; -import React, { useCallback } from 'react'; -import { useDispatch } from 'react-redux'; + import { isDataSourceEditor } from '../../permissions'; import { CatalogPlugin } from '../../types'; diff --git a/public/app/features/plugins/admin/components/GetStartedWithPlugin/GetStartedWithPlugin.tsx b/public/app/features/plugins/admin/components/GetStartedWithPlugin/GetStartedWithPlugin.tsx index aa251e1d07e..260633c79b1 100644 --- a/public/app/features/plugins/admin/components/GetStartedWithPlugin/GetStartedWithPlugin.tsx +++ b/public/app/features/plugins/admin/components/GetStartedWithPlugin/GetStartedWithPlugin.tsx @@ -1,8 +1,11 @@ import React, { ReactElement } from 'react'; + import { PluginType } from '@grafana/data'; + import { CatalogPlugin } from '../../types'; -import { GetStartedWithDataSource } from './GetStartedWithDataSource'; + import { GetStartedWithApp } from './GetStartedWithApp'; +import { GetStartedWithDataSource } from './GetStartedWithDataSource'; type Props = { plugin: CatalogPlugin; diff --git a/public/app/features/plugins/admin/components/HorizontalGroup.tsx b/public/app/features/plugins/admin/components/HorizontalGroup.tsx index 5e0fbaa06b1..0d948f963c9 100644 --- a/public/app/features/plugins/admin/components/HorizontalGroup.tsx +++ b/public/app/features/plugins/admin/components/HorizontalGroup.tsx @@ -1,8 +1,8 @@ -import React from 'react'; import { css, cx } from '@emotion/css'; +import React from 'react'; -import { useTheme2 } from '@grafana/ui'; import { GrafanaTheme2 } from '@grafana/data'; +import { useTheme2 } from '@grafana/ui'; interface HorizontalGroupProps { children: React.ReactNode; diff --git a/public/app/features/plugins/admin/components/InstallControls/ExternallyManagedButton.tsx b/public/app/features/plugins/admin/components/InstallControls/ExternallyManagedButton.tsx index 5aa72575014..651d46b132b 100644 --- a/public/app/features/plugins/admin/components/InstallControls/ExternallyManagedButton.tsx +++ b/public/app/features/plugins/admin/components/InstallControls/ExternallyManagedButton.tsx @@ -1,5 +1,7 @@ import React from 'react'; + import { HorizontalGroup, LinkButton } from '@grafana/ui'; + import { getExternalManageLink } from '../../helpers'; import { PluginStatus } from '../../types'; diff --git a/public/app/features/plugins/admin/components/InstallControls/InstallControls.tsx b/public/app/features/plugins/admin/components/InstallControls/InstallControls.tsx index 17cafd20c43..73235702496 100644 --- a/public/app/features/plugins/admin/components/InstallControls/InstallControls.tsx +++ b/public/app/features/plugins/admin/components/InstallControls/InstallControls.tsx @@ -1,16 +1,17 @@ -import React from 'react'; import { css } from '@emotion/css'; +import React from 'react'; +import { GrafanaTheme2, PluginType } from '@grafana/data'; import { config, featureEnabled } from '@grafana/runtime'; import { HorizontalGroup, Icon, LinkButton, useStyles2 } from '@grafana/ui'; -import { GrafanaTheme2, PluginType } from '@grafana/data'; + +import { getExternalManageLink, isInstallControlsEnabled } from '../../helpers'; +import { isGrafanaAdmin } from '../../permissions'; +import { useIsRemotePluginsAvailable } from '../../state/hooks'; +import { CatalogPlugin, PluginStatus, Version } from '../../types'; import { ExternallyManagedButton } from './ExternallyManagedButton'; import { InstallControlsButton } from './InstallControlsButton'; -import { CatalogPlugin, PluginStatus, Version } from '../../types'; -import { getExternalManageLink, isInstallControlsEnabled } from '../../helpers'; -import { useIsRemotePluginsAvailable } from '../../state/hooks'; -import { isGrafanaAdmin } from '../../permissions'; interface Props { plugin: CatalogPlugin; diff --git a/public/app/features/plugins/admin/components/InstallControls/InstallControlsButton.tsx b/public/app/features/plugins/admin/components/InstallControls/InstallControlsButton.tsx index ab18c18c9fc..6b47cb70014 100644 --- a/public/app/features/plugins/admin/components/InstallControls/InstallControlsButton.tsx +++ b/public/app/features/plugins/admin/components/InstallControls/InstallControlsButton.tsx @@ -1,10 +1,11 @@ import React, { useState } from 'react'; + import { AppEvents } from '@grafana/data'; import { Button, HorizontalGroup, ConfirmModal } from '@grafana/ui'; import appEvents from 'app/core/app_events'; -import { CatalogPlugin, PluginStatus, Version } from '../../types'; import { useInstallStatus, useUninstallStatus, useInstall, useUninstall } from '../../state/hooks'; +import { CatalogPlugin, PluginStatus, Version } from '../../types'; type InstallControlsButtonProps = { plugin: CatalogPlugin; diff --git a/public/app/features/plugins/admin/components/Loader.tsx b/public/app/features/plugins/admin/components/Loader.tsx index 1113f8e7215..2ce20da786d 100644 --- a/public/app/features/plugins/admin/components/Loader.tsx +++ b/public/app/features/plugins/admin/components/Loader.tsx @@ -1,5 +1,7 @@ import React from 'react'; + import { LoadingPlaceholder } from '@grafana/ui'; + import { Page } from './Page'; export interface Props { diff --git a/public/app/features/plugins/admin/components/Page.tsx b/public/app/features/plugins/admin/components/Page.tsx index fd3ac726632..199cb9939c3 100644 --- a/public/app/features/plugins/admin/components/Page.tsx +++ b/public/app/features/plugins/admin/components/Page.tsx @@ -1,7 +1,8 @@ -import React from 'react'; import { css } from '@emotion/css'; -import { useStyles2 } from '@grafana/ui'; +import React from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; +import { useStyles2 } from '@grafana/ui'; export const Page: React.FC = ({ children }) => { const styles = useStyles2(getStyles); diff --git a/public/app/features/plugins/admin/components/PluginDashboards.tsx b/public/app/features/plugins/admin/components/PluginDashboards.tsx index 734368722aa..464a84f4e18 100644 --- a/public/app/features/plugins/admin/components/PluginDashboards.tsx +++ b/public/app/features/plugins/admin/components/PluginDashboards.tsx @@ -1,12 +1,11 @@ +import { extend } from 'lodash'; import React, { PureComponent } from 'react'; -import { extend } from 'lodash'; - -import { PluginDashboard } from 'app/types'; +import { AppEvents, PluginMeta, DataSourceApi } from '@grafana/data'; import { getBackendSrv } from '@grafana/runtime'; import { appEvents } from 'app/core/core'; import DashboardsTable from 'app/features/datasources/DashboardsTable'; -import { AppEvents, PluginMeta, DataSourceApi } from '@grafana/data'; +import { PluginDashboard } from 'app/types'; interface Props { plugin: PluginMeta; diff --git a/public/app/features/plugins/admin/components/PluginDetailsBody.tsx b/public/app/features/plugins/admin/components/PluginDetailsBody.tsx index 5608e976b42..790afe2a7f5 100644 --- a/public/app/features/plugins/admin/components/PluginDetailsBody.tsx +++ b/public/app/features/plugins/admin/components/PluginDetailsBody.tsx @@ -1,12 +1,13 @@ -import React from 'react'; import { css, cx } from '@emotion/css'; +import React from 'react'; import { AppPlugin, GrafanaTheme2, UrlQueryMap } from '@grafana/data'; import { useStyles2 } from '@grafana/ui'; -import { CatalogPlugin, PluginTabIds } from '../types'; import { VersionList } from '../components/VersionList'; import { usePluginConfig } from '../hooks/usePluginConfig'; +import { CatalogPlugin, PluginTabIds } from '../types'; + import { AppConfigCtrlWrapper } from './AppConfigWrapper'; import { PluginDashboards } from './PluginDashboards'; diff --git a/public/app/features/plugins/admin/components/PluginDetailsDisabledError.tsx b/public/app/features/plugins/admin/components/PluginDetailsDisabledError.tsx index 12b6b6cf043..9f34a4b0ced 100644 --- a/public/app/features/plugins/admin/components/PluginDetailsDisabledError.tsx +++ b/public/app/features/plugins/admin/components/PluginDetailsDisabledError.tsx @@ -1,8 +1,10 @@ import React, { ReactElement } from 'react'; + import { PluginErrorCode } from '@grafana/data'; -import { Alert } from '@grafana/ui'; -import { CatalogPlugin } from '../types'; import { selectors } from '@grafana/e2e-selectors'; +import { Alert } from '@grafana/ui'; + +import { CatalogPlugin } from '../types'; type Props = { className?: string; diff --git a/public/app/features/plugins/admin/components/PluginDetailsHeader.tsx b/public/app/features/plugins/admin/components/PluginDetailsHeader.tsx index 51f161901e4..4e8b77e58c8 100644 --- a/public/app/features/plugins/admin/components/PluginDetailsHeader.tsx +++ b/public/app/features/plugins/admin/components/PluginDetailsHeader.tsx @@ -1,16 +1,18 @@ -import React from 'react'; import { css, cx } from '@emotion/css'; +import React from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { useStyles2, Icon, HorizontalGroup } from '@grafana/ui'; -import { InstallControls } from './InstallControls'; -import { PluginDetailsHeaderSignature } from './PluginDetailsHeaderSignature'; -import { PluginDetailsHeaderDependencies } from './PluginDetailsHeaderDependencies'; -import { PluginLogo } from './PluginLogo'; +import { getLatestCompatibleVersion } from '../helpers'; import { CatalogPlugin } from '../types'; + import { PluginDisabledBadge } from './Badges'; import { GetStartedWithPlugin } from './GetStartedWithPlugin'; -import { getLatestCompatibleVersion } from '../helpers'; +import { InstallControls } from './InstallControls'; +import { PluginDetailsHeaderDependencies } from './PluginDetailsHeaderDependencies'; +import { PluginDetailsHeaderSignature } from './PluginDetailsHeaderSignature'; +import { PluginLogo } from './PluginLogo'; type Props = { currentUrl: string; diff --git a/public/app/features/plugins/admin/components/PluginDetailsHeaderDependencies.tsx b/public/app/features/plugins/admin/components/PluginDetailsHeaderDependencies.tsx index a0c6ae173d4..ba73cf57716 100644 --- a/public/app/features/plugins/admin/components/PluginDetailsHeaderDependencies.tsx +++ b/public/app/features/plugins/admin/components/PluginDetailsHeaderDependencies.tsx @@ -1,7 +1,9 @@ -import React from 'react'; import { css } from '@emotion/css'; +import React from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { useStyles2, Icon } from '@grafana/ui'; + import { Version, CatalogPlugin, PluginIconName } from '../types'; type Props = { diff --git a/public/app/features/plugins/admin/components/PluginDetailsHeaderSignature.tsx b/public/app/features/plugins/admin/components/PluginDetailsHeaderSignature.tsx index 5c73d09d048..f44452ed7d9 100644 --- a/public/app/features/plugins/admin/components/PluginDetailsHeaderSignature.tsx +++ b/public/app/features/plugins/admin/components/PluginDetailsHeaderSignature.tsx @@ -1,10 +1,13 @@ -import React from 'react'; import { css } from '@emotion/css'; +import React from 'react'; + import { GrafanaTheme2, PluginSignatureStatus } from '@grafana/data'; import { PluginSignatureBadge, useStyles2 } from '@grafana/ui'; -import { PluginSignatureDetailsBadge } from './PluginSignatureDetailsBadge'; + import { CatalogPlugin } from '../types'; +import { PluginSignatureDetailsBadge } from './PluginSignatureDetailsBadge'; + type Props = { plugin: CatalogPlugin; }; diff --git a/public/app/features/plugins/admin/components/PluginDetailsSignature.tsx b/public/app/features/plugins/admin/components/PluginDetailsSignature.tsx index 210d71b73b3..bdb0a250e62 100644 --- a/public/app/features/plugins/admin/components/PluginDetailsSignature.tsx +++ b/public/app/features/plugins/admin/components/PluginDetailsSignature.tsx @@ -1,7 +1,9 @@ import React from 'react'; -import { selectors } from '@grafana/e2e-selectors'; + import { PluginErrorCode, PluginSignatureStatus } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; import { Alert } from '@grafana/ui'; + import { CatalogPlugin } from '../types'; type Props = { diff --git a/public/app/features/plugins/admin/components/PluginList.tsx b/public/app/features/plugins/admin/components/PluginList.tsx index 62e862aa7f2..97e40cbbd96 100644 --- a/public/app/features/plugins/admin/components/PluginList.tsx +++ b/public/app/features/plugins/admin/components/PluginList.tsx @@ -1,9 +1,12 @@ -import React from 'react'; import { css, cx } from '@emotion/css'; -import { useStyles2 } from '@grafana/ui'; -import { GrafanaTheme2 } from '@grafana/data'; +import React from 'react'; import { useLocation } from 'react-router-dom'; + +import { GrafanaTheme2 } from '@grafana/data'; +import { useStyles2 } from '@grafana/ui'; + import { CatalogPlugin, PluginListDisplayMode } from '../types'; + import { PluginListItem } from './PluginListItem'; interface Props { diff --git a/public/app/features/plugins/admin/components/PluginListItem.test.tsx b/public/app/features/plugins/admin/components/PluginListItem.test.tsx index fb2ed8558b0..856709f4589 100644 --- a/public/app/features/plugins/admin/components/PluginListItem.test.tsx +++ b/public/app/features/plugins/admin/components/PluginListItem.test.tsx @@ -1,9 +1,12 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; +import React from 'react'; + import { PluginErrorCode, PluginSignatureStatus, PluginType } from '@grafana/data'; -import { PluginListItem } from './PluginListItem'; + import { CatalogPlugin, PluginListDisplayMode } from '../types'; +import { PluginListItem } from './PluginListItem'; + /** * The whole Icon component needs to be mock * currently is using react-inlinesvg that does not render the icon svg in the test. diff --git a/public/app/features/plugins/admin/components/PluginListItem.tsx b/public/app/features/plugins/admin/components/PluginListItem.tsx index 772f5f9a0b8..012f9b0803a 100644 --- a/public/app/features/plugins/admin/components/PluginListItem.tsx +++ b/public/app/features/plugins/admin/components/PluginListItem.tsx @@ -1,10 +1,13 @@ -import React from 'react'; import { css, cx } from '@emotion/css'; +import React from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; +import { Icon, useStyles2 } from '@grafana/ui'; + import { CatalogPlugin, PluginIconName, PluginListDisplayMode } from '../types'; + import { PluginListItemBadges } from './PluginListItemBadges'; import { PluginLogo } from './PluginLogo'; -import { Icon, useStyles2 } from '@grafana/ui'; export const LOGO_SIZE = '48px'; diff --git a/public/app/features/plugins/admin/components/PluginListItemBadges.test.tsx b/public/app/features/plugins/admin/components/PluginListItemBadges.test.tsx index b455f9bd42a..e649279fd47 100644 --- a/public/app/features/plugins/admin/components/PluginListItemBadges.test.tsx +++ b/public/app/features/plugins/admin/components/PluginListItemBadges.test.tsx @@ -1,10 +1,13 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; +import React from 'react'; + import { PluginErrorCode, PluginSignatureStatus } from '@grafana/data'; -import { PluginListItemBadges } from './PluginListItemBadges'; -import { CatalogPlugin } from '../types'; import { config } from '@grafana/runtime'; +import { CatalogPlugin } from '../types'; + +import { PluginListItemBadges } from './PluginListItemBadges'; + describe('PluginListItemBadges', () => { const plugin: CatalogPlugin = { description: 'The test plugin', diff --git a/public/app/features/plugins/admin/components/PluginListItemBadges.tsx b/public/app/features/plugins/admin/components/PluginListItemBadges.tsx index e96c9b8431b..bfc21d07130 100644 --- a/public/app/features/plugins/admin/components/PluginListItemBadges.tsx +++ b/public/app/features/plugins/admin/components/PluginListItemBadges.tsx @@ -1,6 +1,9 @@ import React from 'react'; + import { HorizontalGroup, PluginSignatureBadge } from '@grafana/ui'; + import { CatalogPlugin } from '../types'; + import { PluginEnterpriseBadge, PluginDisabledBadge, PluginInstalledBadge, PluginUpdateAvailableBadge } from './Badges'; type PluginBadgeType = { diff --git a/public/app/features/plugins/admin/components/PluginSignatureDetailsBadge.tsx b/public/app/features/plugins/admin/components/PluginSignatureDetailsBadge.tsx index fc87f60b461..158e0ed27b9 100644 --- a/public/app/features/plugins/admin/components/PluginSignatureDetailsBadge.tsx +++ b/public/app/features/plugins/admin/components/PluginSignatureDetailsBadge.tsx @@ -1,6 +1,7 @@ -import React from 'react'; import { css } from '@emotion/css'; import { capitalize } from 'lodash'; +import React from 'react'; + import { GrafanaTheme2, PluginSignatureType } from '@grafana/data'; import { useStyles2, Icon, Badge, IconName } from '@grafana/ui'; diff --git a/public/app/features/plugins/admin/components/PluginTypeIcon.tsx b/public/app/features/plugins/admin/components/PluginTypeIcon.tsx index bf4d39e1bee..0d0d9d716f4 100644 --- a/public/app/features/plugins/admin/components/PluginTypeIcon.tsx +++ b/public/app/features/plugins/admin/components/PluginTypeIcon.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { css } from '@emotion/css'; +import React from 'react'; + import { PluginTypeCode } from '../types'; interface PluginTypeIconProps { diff --git a/public/app/features/plugins/admin/components/SearchField.tsx b/public/app/features/plugins/admin/components/SearchField.tsx index e09996e76c0..c251f34b1cc 100644 --- a/public/app/features/plugins/admin/components/SearchField.tsx +++ b/public/app/features/plugins/admin/components/SearchField.tsx @@ -1,7 +1,8 @@ -import { FilterInput } from '@grafana/ui'; import React, { useState, useRef } from 'react'; import { useDebounce } from 'react-use'; +import { FilterInput } from '@grafana/ui'; + interface Props { value?: string; onSearch: (value: string) => void; diff --git a/public/app/features/plugins/admin/components/VersionList.tsx b/public/app/features/plugins/admin/components/VersionList.tsx index 9942a873303..7224bd35065 100644 --- a/public/app/features/plugins/admin/components/VersionList.tsx +++ b/public/app/features/plugins/admin/components/VersionList.tsx @@ -1,10 +1,11 @@ -import React from 'react'; import { css } from '@emotion/css'; +import React from 'react'; import { dateTimeFormatTimeAgo, GrafanaTheme2 } from '@grafana/data'; import { useStyles2 } from '@grafana/ui'; -import { Version } from '../types'; + import { getLatestCompatibleVersion } from '../helpers'; +import { Version } from '../types'; interface Props { versions?: Version[]; diff --git a/public/app/features/plugins/admin/helpers.test.ts b/public/app/features/plugins/admin/helpers.test.ts index 0c50d50dee5..b88a5d65887 100644 --- a/public/app/features/plugins/admin/helpers.test.ts +++ b/public/app/features/plugins/admin/helpers.test.ts @@ -1,7 +1,7 @@ -import { RemotePlugin, LocalPlugin } from './types'; -import { getLocalPluginMock, getRemotePluginMock, getCatalogPluginMock } from './__mocks__'; import { PluginSignatureStatus, PluginSignatureType, PluginType } from '@grafana/data'; import { config } from '@grafana/runtime'; + +import { getLocalPluginMock, getRemotePluginMock, getCatalogPluginMock } from './__mocks__'; import { mapToCatalogPlugin, mapRemoteToCatalog, @@ -13,6 +13,7 @@ import { isLocalPluginVisible, isRemotePluginVisible, } from './helpers'; +import { RemotePlugin, LocalPlugin } from './types'; describe('Plugins/Helpers', () => { let remotePlugin: RemotePlugin; diff --git a/public/app/features/plugins/admin/helpers.ts b/public/app/features/plugins/admin/helpers.ts index 7c044a2e3b9..2a52055b3a4 100644 --- a/public/app/features/plugins/admin/helpers.ts +++ b/public/app/features/plugins/admin/helpers.ts @@ -1,7 +1,8 @@ -import { config } from '@grafana/runtime'; import { PluginSignatureStatus, dateTimeParse, PluginError, PluginErrorCode } from '@grafana/data'; -import { getBackendSrv } from 'app/core/services/backend_srv'; +import { config } from '@grafana/runtime'; import { Settings } from 'app/core/config'; +import { getBackendSrv } from 'app/core/services/backend_srv'; + import { CatalogPlugin, LocalPlugin, RemotePlugin, Version } from './types'; export function mergeLocalsAndRemotes( diff --git a/public/app/features/plugins/admin/hooks/usePluginConfig.tsx b/public/app/features/plugins/admin/hooks/usePluginConfig.tsx index 43a2fe47809..d515ba81594 100644 --- a/public/app/features/plugins/admin/hooks/usePluginConfig.tsx +++ b/public/app/features/plugins/admin/hooks/usePluginConfig.tsx @@ -1,6 +1,7 @@ import { useAsync } from 'react-use'; -import { CatalogPlugin } from '../types'; + import { loadPlugin } from '../../utils'; +import { CatalogPlugin } from '../types'; export const usePluginConfig = (plugin?: CatalogPlugin) => { return useAsync(async () => { diff --git a/public/app/features/plugins/admin/hooks/usePluginDetailsTabs.tsx b/public/app/features/plugins/admin/hooks/usePluginDetailsTabs.tsx index 6a045fca1a4..40c17a061f7 100644 --- a/public/app/features/plugins/admin/hooks/usePluginDetailsTabs.tsx +++ b/public/app/features/plugins/admin/hooks/usePluginDetailsTabs.tsx @@ -1,9 +1,11 @@ import { useMemo } from 'react'; import { useLocation } from 'react-router-dom'; + import { PluginIncludeType, PluginType } from '@grafana/data'; -import { CatalogPlugin, PluginDetailsTab, PluginTabIds, PluginTabLabels } from '../types'; + import { usePluginConfig } from '../hooks/usePluginConfig'; import { isOrgAdmin } from '../permissions'; +import { CatalogPlugin, PluginDetailsTab, PluginTabIds, PluginTabLabels } from '../types'; type ReturnType = { error: Error | undefined; diff --git a/public/app/features/plugins/admin/pages/Browse.test.tsx b/public/app/features/plugins/admin/pages/Browse.test.tsx index b1c4e5cab7e..56096458df0 100644 --- a/public/app/features/plugins/admin/pages/Browse.test.tsx +++ b/public/app/features/plugins/admin/pages/Browse.test.tsx @@ -1,15 +1,18 @@ -import React from 'react'; -import { Router } from 'react-router-dom'; import { render, RenderResult, waitFor, within } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import React from 'react'; import { Provider } from 'react-redux'; -import { locationService } from '@grafana/runtime'; +import { Router } from 'react-router-dom'; + import { PluginType } from '@grafana/data'; +import { locationService } from '@grafana/runtime'; import { getRouteComponentProps } from 'app/core/navigation/__mocks__/routeProps'; import { configureStore } from 'app/store/configureStore'; + +import { getCatalogPluginMock, getPluginsStateMock } from '../__mocks__'; import { fetchRemotePlugins } from '../state/actions'; import { PluginAdminRoutes, CatalogPlugin, ReducerState, RequestStatus } from '../types'; -import { getCatalogPluginMock, getPluginsStateMock } from '../__mocks__'; + import BrowsePage from './Browse'; jest.mock('@grafana/runtime', () => { diff --git a/public/app/features/plugins/admin/pages/Browse.tsx b/public/app/features/plugins/admin/pages/Browse.tsx index 2d8a08eafee..91d5ae6d2e9 100644 --- a/public/app/features/plugins/admin/pages/Browse.tsx +++ b/public/app/features/plugins/admin/pages/Browse.tsx @@ -1,22 +1,24 @@ -import React, { ReactElement } from 'react'; import { css } from '@emotion/css'; -import { SelectableValue, GrafanaTheme2 } from '@grafana/data'; -import { LoadingPlaceholder, Select, RadioButtonGroup, useStyles2, Tooltip } from '@grafana/ui'; +import React, { ReactElement } from 'react'; +import { useSelector } from 'react-redux'; import { useLocation } from 'react-router-dom'; + +import { SelectableValue, GrafanaTheme2 } from '@grafana/data'; import { locationSearchToObject } from '@grafana/runtime'; +import { LoadingPlaceholder, Select, RadioButtonGroup, useStyles2, Tooltip } from '@grafana/ui'; +import { Page } from 'app/core/components/Page/Page'; import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; +import { getNavModel } from 'app/core/selectors/navModel'; +import { StoreState } from 'app/types/store'; + +import { HorizontalGroup } from '../components/HorizontalGroup'; +import { Page as PluginPage } from '../components/Page'; import { PluginList } from '../components/PluginList'; import { SearchField } from '../components/SearchField'; -import { useHistory } from '../hooks/useHistory'; -import { PluginAdminRoutes, PluginListDisplayMode } from '../types'; -import { Page as PluginPage } from '../components/Page'; -import { HorizontalGroup } from '../components/HorizontalGroup'; -import { Page } from 'app/core/components/Page/Page'; -import { useSelector } from 'react-redux'; -import { StoreState } from 'app/types/store'; -import { getNavModel } from 'app/core/selectors/navModel'; -import { useGetAllWithFilters, useIsRemotePluginsAvailable, useDisplayMode } from '../state/hooks'; import { Sorters } from '../helpers'; +import { useHistory } from '../hooks/useHistory'; +import { useGetAllWithFilters, useIsRemotePluginsAvailable, useDisplayMode } from '../state/hooks'; +import { PluginAdminRoutes, PluginListDisplayMode } from '../types'; export default function Browse({ route }: GrafanaRouteComponentProps): ReactElement | null { const location = useLocation(); diff --git a/public/app/features/plugins/admin/pages/NotEnabed.tsx b/public/app/features/plugins/admin/pages/NotEnabed.tsx index e0442d31c39..9d56dab9319 100644 --- a/public/app/features/plugins/admin/pages/NotEnabed.tsx +++ b/public/app/features/plugins/admin/pages/NotEnabed.tsx @@ -1,9 +1,11 @@ -import React from 'react'; import { css } from '@emotion/css'; +import React from 'react'; + import { NavModel, NavModelItem } from '@grafana/data'; -import { Page as PluginPage } from '../components/Page'; import { Page } from 'app/core/components/Page/Page'; +import { Page as PluginPage } from '../components/Page'; + const node: NavModelItem = { id: 'not-found', text: 'The plugin catalog is not enabled', diff --git a/public/app/features/plugins/admin/pages/PluginDetails.test.tsx b/public/app/features/plugins/admin/pages/PluginDetails.test.tsx index 6f24844251f..1a89c61e3e7 100644 --- a/public/app/features/plugins/admin/pages/PluginDetails.test.tsx +++ b/public/app/features/plugins/admin/pages/PluginDetails.test.tsx @@ -1,13 +1,19 @@ +import { getDefaultNormalizer, render, RenderResult, SelectorMatcherOptions, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; import React from 'react'; import { Provider } from 'react-redux'; import { MemoryRouter } from 'react-router-dom'; -import { getDefaultNormalizer, render, RenderResult, SelectorMatcherOptions, waitFor } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; + +import { PluginErrorCode, PluginSignatureStatus, PluginType, dateTimeFormatTimeAgo } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; import { config } from '@grafana/runtime'; -import { mockPluginApis, getCatalogPluginMock, getPluginsStateMock, mockUserPermissions } from '../__mocks__'; -import { configureStore } from 'app/store/configureStore'; -import PluginDetailsPage from './PluginDetails'; import { getRouteComponentProps } from 'app/core/navigation/__mocks__/routeProps'; +import { configureStore } from 'app/store/configureStore'; + +import { mockPluginApis, getCatalogPluginMock, getPluginsStateMock, mockUserPermissions } from '../__mocks__'; +import * as api from '../api'; +import { usePluginConfig } from '../hooks/usePluginConfig'; +import { fetchRemotePlugins } from '../state/actions'; import { CatalogPlugin, CatalogPluginDetails, @@ -16,11 +22,8 @@ import { ReducerState, RequestStatus, } from '../types'; -import * as api from '../api'; -import { fetchRemotePlugins } from '../state/actions'; -import { usePluginConfig } from '../hooks/usePluginConfig'; -import { PluginErrorCode, PluginSignatureStatus, PluginType, dateTimeFormatTimeAgo } from '@grafana/data'; -import { selectors } from '@grafana/e2e-selectors'; + +import PluginDetailsPage from './PluginDetails'; jest.mock('@grafana/runtime', () => { const original = jest.requireActual('@grafana/runtime'); diff --git a/public/app/features/plugins/admin/pages/PluginDetails.tsx b/public/app/features/plugins/admin/pages/PluginDetails.tsx index 8674ca21f0d..394bdfbe8b1 100644 --- a/public/app/features/plugins/admin/pages/PluginDetails.tsx +++ b/public/app/features/plugins/admin/pages/PluginDetails.tsx @@ -1,22 +1,24 @@ -import React, { useEffect } from 'react'; import { css } from '@emotion/css'; +import React, { useEffect } from 'react'; import { usePrevious } from 'react-use'; + import { GrafanaTheme2 } from '@grafana/data'; -import { useStyles2, TabsBar, TabContent, Tab, Alert, IconName } from '@grafana/ui'; import { locationService } from '@grafana/runtime'; +import { useStyles2, TabsBar, TabContent, Tab, Alert, IconName } from '@grafana/ui'; import { Layout } from '@grafana/ui/src/components/Layout/Layout'; import { Page } from 'app/core/components/Page/Page'; import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; -import { PluginDetailsSignature } from '../components/PluginDetailsSignature'; -import { PluginDetailsHeader } from '../components/PluginDetailsHeader'; -import { PluginDetailsBody } from '../components/PluginDetailsBody'; -import { Page as PluginPage } from '../components/Page'; -import { Loader } from '../components/Loader'; -import { PluginTabLabels, PluginTabIds, PluginDetailsTab } from '../types'; -import { useGetSingle, useFetchStatus, useFetchDetailsStatus } from '../state/hooks'; -import { usePluginDetailsTabs } from '../hooks/usePluginDetailsTabs'; import { AppNotificationSeverity } from 'app/types'; + +import { Loader } from '../components/Loader'; +import { Page as PluginPage } from '../components/Page'; +import { PluginDetailsBody } from '../components/PluginDetailsBody'; import { PluginDetailsDisabledError } from '../components/PluginDetailsDisabledError'; +import { PluginDetailsHeader } from '../components/PluginDetailsHeader'; +import { PluginDetailsSignature } from '../components/PluginDetailsSignature'; +import { usePluginDetailsTabs } from '../hooks/usePluginDetailsTabs'; +import { useGetSingle, useFetchStatus, useFetchDetailsStatus } from '../state/hooks'; +import { PluginTabLabels, PluginTabIds, PluginDetailsTab } from '../types'; type Props = GrafanaRouteComponentProps<{ pluginId?: string }>; diff --git a/public/app/features/plugins/admin/routes.ts b/public/app/features/plugins/admin/routes.ts index f2f9f6317ca..02a54c1c6c8 100644 --- a/public/app/features/plugins/admin/routes.ts +++ b/public/app/features/plugins/admin/routes.ts @@ -1,5 +1,6 @@ import { SafeDynamicImport } from 'app/core/components/DynamicImports/SafeDynamicImport'; import { RouteDescriptor } from 'app/core/navigation/types'; + import { isGrafanaAdmin } from './permissions'; import { PluginAdminRoutes } from './types'; diff --git a/public/app/features/plugins/admin/state/actions.ts b/public/app/features/plugins/admin/state/actions.ts index e23bf4b0b0e..408f1d38833 100644 --- a/public/app/features/plugins/admin/state/actions.ts +++ b/public/app/features/plugins/admin/state/actions.ts @@ -1,8 +1,11 @@ import { createAction, createAsyncThunk, Update } from '@reduxjs/toolkit'; -import { getBackendSrv } from '@grafana/runtime'; + import { PanelPlugin } from '@grafana/data'; -import { StoreState, ThunkResult } from 'app/types'; +import { getBackendSrv } from '@grafana/runtime'; import { importPanelPlugin } from 'app/features/plugins/importPanelPlugin'; +import { StoreState, ThunkResult } from 'app/types'; + +import { invalidatePluginInCache } from '../../pluginCacheBuster'; import { getRemotePlugins, getPluginErrors, @@ -14,7 +17,6 @@ import { import { STATE_PREFIX } from '../constants'; import { mergeLocalsAndRemotes, updatePanels } from '../helpers'; import { CatalogPlugin, RemotePlugin } from '../types'; -import { invalidatePluginInCache } from '../../pluginCacheBuster'; export const fetchAll = createAsyncThunk(`${STATE_PREFIX}/fetchAll`, async (_, thunkApi) => { try { diff --git a/public/app/features/plugins/admin/state/hooks.ts b/public/app/features/plugins/admin/state/hooks.ts index e6eaae31789..9a4862f3d19 100644 --- a/public/app/features/plugins/admin/state/hooks.ts +++ b/public/app/features/plugins/admin/state/hooks.ts @@ -1,9 +1,13 @@ import { useEffect } from 'react'; import { useDispatch, useSelector } from 'react-redux'; + import { PluginError } from '@grafana/data'; -import { setDisplayMode } from './reducer'; -import { fetchAll, fetchDetails, fetchRemotePlugins, install, uninstall } from './actions'; + +import { sortPlugins, Sorters } from '../helpers'; import { CatalogPlugin, PluginCatalogStoreState, PluginListDisplayMode } from '../types'; + +import { fetchAll, fetchDetails, fetchRemotePlugins, install, uninstall } from './actions'; +import { setDisplayMode } from './reducer'; import { find, selectAll, @@ -14,7 +18,6 @@ import { selectDisplayMode, selectPluginErrors, } from './selectors'; -import { sortPlugins, Sorters } from '../helpers'; type Filters = { query?: string; diff --git a/public/app/features/plugins/admin/state/reducer.ts b/public/app/features/plugins/admin/state/reducer.ts index 565b84973f8..515e9536fdb 100644 --- a/public/app/features/plugins/admin/state/reducer.ts +++ b/public/app/features/plugins/admin/state/reducer.ts @@ -1,9 +1,12 @@ import { createSlice, createEntityAdapter, Reducer, AnyAction, PayloadAction } from '@reduxjs/toolkit'; -import { fetchAll, fetchDetails, install, uninstall, loadPluginDashboards, panelPluginLoaded } from './actions'; -import { CatalogPlugin, PluginListDisplayMode, ReducerState, RequestStatus } from '../types'; -import { STATE_PREFIX } from '../constants'; + import { PanelPlugin } from '@grafana/data'; +import { STATE_PREFIX } from '../constants'; +import { CatalogPlugin, PluginListDisplayMode, ReducerState, RequestStatus } from '../types'; + +import { fetchAll, fetchDetails, install, uninstall, loadPluginDashboards, panelPluginLoaded } from './actions'; + export const pluginsAdapter = createEntityAdapter(); const isPendingRequest = (action: AnyAction) => new RegExp(`${STATE_PREFIX}\/(.*)\/pending`).test(action.type); diff --git a/public/app/features/plugins/admin/state/selectors.ts b/public/app/features/plugins/admin/state/selectors.ts index a0dae21aba9..b8bced29eae 100644 --- a/public/app/features/plugins/admin/state/selectors.ts +++ b/public/app/features/plugins/admin/state/selectors.ts @@ -1,6 +1,9 @@ import { createSelector } from '@reduxjs/toolkit'; + import { PluginError, PluginErrorCode } from '@grafana/data'; + import { RequestStatus, PluginCatalogStoreState } from '../types'; + import { pluginsAdapter } from './reducer'; export const selectRoot = (state: PluginCatalogStoreState) => state.plugins; diff --git a/public/app/features/plugins/admin/types.ts b/public/app/features/plugins/admin/types.ts index a20e212b427..53907d3bdb6 100644 --- a/public/app/features/plugins/admin/types.ts +++ b/public/app/features/plugins/admin/types.ts @@ -1,4 +1,5 @@ import { EntityState } from '@reduxjs/toolkit'; + import { PluginType, PluginSignatureStatus, diff --git a/public/app/features/plugins/built_in_plugins.ts b/public/app/features/plugins/built_in_plugins.ts index 3128e26f815..9bd37e1a13f 100644 --- a/public/app/features/plugins/built_in_plugins.ts +++ b/public/app/features/plugins/built_in_plugins.ts @@ -40,31 +40,31 @@ const tempoPlugin = async () => const alertmanagerPlugin = async () => await import(/* webpackChunkName: "alertmanagerPlugin" */ 'app/plugins/datasource/alertmanager/module'); -import * as textPanel from 'app/plugins/panel/text/module'; -import * as timeseriesPanel from 'app/plugins/panel/timeseries/module'; -import * as stateTimelinePanel from 'app/plugins/panel/state-timeline/module'; -import * as statusHistoryPanel from 'app/plugins/panel/status-history/module'; -import * as candlestickPanel from 'app/plugins/panel/candlestick/module'; -import * as xyChartPanel from 'app/plugins/panel/xychart/module'; -import * as dashListPanel from 'app/plugins/panel/dashlist/module'; +import * as alertGroupsPanel from 'app/plugins/panel/alertGroups/module'; import * as alertListPanel from 'app/plugins/panel/alertlist/module'; import * as annoListPanel from 'app/plugins/panel/annolist/module'; -import * as heatmapPanelNG from 'app/plugins/panel/heatmap-new/module'; -import * as tablePanel from 'app/plugins/panel/table/module'; -import * as statPanel from 'app/plugins/panel/stat/module'; -import * as gettingStartedPanel from 'app/plugins/panel/gettingstarted/module'; -import * as gaugePanel from 'app/plugins/panel/gauge/module'; -import * as pieChartPanel from 'app/plugins/panel/piechart/module'; -import * as barGaugePanel from 'app/plugins/panel/bargauge/module'; import * as barChartPanel from 'app/plugins/panel/barchart/module'; +import * as barGaugePanel from 'app/plugins/panel/bargauge/module'; +import * as candlestickPanel from 'app/plugins/panel/candlestick/module'; +import * as dashListPanel from 'app/plugins/panel/dashlist/module'; +import * as debugPanel from 'app/plugins/panel/debug/module'; +import * as gaugePanel from 'app/plugins/panel/gauge/module'; +import * as gettingStartedPanel from 'app/plugins/panel/gettingstarted/module'; +import * as heatmapPanelNG from 'app/plugins/panel/heatmap-new/module'; +import * as histogramPanel from 'app/plugins/panel/histogram/module'; +import * as livePanel from 'app/plugins/panel/live/module'; import * as logsPanel from 'app/plugins/panel/logs/module'; import * as newsPanel from 'app/plugins/panel/news/module'; -import * as livePanel from 'app/plugins/panel/live/module'; -import * as debugPanel from 'app/plugins/panel/debug/module'; -import * as welcomeBanner from 'app/plugins/panel/welcome/module'; import * as nodeGraph from 'app/plugins/panel/nodeGraph/module'; -import * as histogramPanel from 'app/plugins/panel/histogram/module'; -import * as alertGroupsPanel from 'app/plugins/panel/alertGroups/module'; +import * as pieChartPanel from 'app/plugins/panel/piechart/module'; +import * as statPanel from 'app/plugins/panel/stat/module'; +import * as stateTimelinePanel from 'app/plugins/panel/state-timeline/module'; +import * as statusHistoryPanel from 'app/plugins/panel/status-history/module'; +import * as tablePanel from 'app/plugins/panel/table/module'; +import * as textPanel from 'app/plugins/panel/text/module'; +import * as timeseriesPanel from 'app/plugins/panel/timeseries/module'; +import * as welcomeBanner from 'app/plugins/panel/welcome/module'; +import * as xyChartPanel from 'app/plugins/panel/xychart/module'; // Async loaded panels const geomapPanel = async () => await import(/* webpackChunkName: "geomapPanel" */ 'app/plugins/panel/geomap/module'); diff --git a/public/app/features/plugins/components/AppRootPage.test.tsx b/public/app/features/plugins/components/AppRootPage.test.tsx index cf6609f3c3d..cf9ba1f02ed 100644 --- a/public/app/features/plugins/components/AppRootPage.test.tsx +++ b/public/app/features/plugins/components/AppRootPage.test.tsx @@ -1,15 +1,18 @@ import { act, render, screen } from '@testing-library/react'; import React, { Component } from 'react'; -import AppRootPage from './AppRootPage'; -import { getPluginSettings } from '../pluginSettings'; -import { importAppPlugin } from '../plugin_loader'; -import { getMockPlugin } from '../__mocks__/pluginMocks'; -import { AppPlugin, PluginType, AppRootProps, NavModelItem } from '@grafana/data'; import { Route, Router } from 'react-router-dom'; + +import { AppPlugin, PluginType, AppRootProps, NavModelItem } from '@grafana/data'; import { locationService, setEchoSrv } from '@grafana/runtime'; import { GrafanaRoute } from 'app/core/navigation/GrafanaRoute'; import { Echo } from 'app/core/services/echo/Echo'; +import { getMockPlugin } from '../__mocks__/pluginMocks'; +import { getPluginSettings } from '../pluginSettings'; +import { importAppPlugin } from '../plugin_loader'; + +import AppRootPage from './AppRootPage'; + jest.mock('../pluginSettings', () => ({ getPluginSettings: jest.fn(), })); diff --git a/public/app/features/plugins/components/AppRootPage.tsx b/public/app/features/plugins/components/AppRootPage.tsx index faa63014b8f..c5b7b6c20a1 100644 --- a/public/app/features/plugins/components/AppRootPage.tsx +++ b/public/app/features/plugins/components/AppRootPage.tsx @@ -1,15 +1,16 @@ // Libraries import React, { Component } from 'react'; -import { AppEvents, AppPlugin, AppPluginMeta, KeyValue, NavModel, PluginType } from '@grafana/data'; import { createHtmlPortalNode, InPortal, OutPortal, HtmlPortalNode } from 'react-reverse-portal'; +import { AppEvents, AppPlugin, AppPluginMeta, KeyValue, NavModel, PluginType } from '@grafana/data'; +import { getNotFoundNav, getWarningNav, getExceptionNav } from 'app/angular/services/nav_model_srv'; import Page from 'app/core/components/Page/Page'; +import PageLoader from 'app/core/components/PageLoader/PageLoader'; +import { appEvents } from 'app/core/core'; +import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; + import { getPluginSettings } from '../pluginSettings'; import { importAppPlugin } from '../plugin_loader'; -import { getNotFoundNav, getWarningNav, getExceptionNav } from 'app/angular/services/nav_model_srv'; -import { appEvents } from 'app/core/core'; -import PageLoader from 'app/core/components/PageLoader/PageLoader'; -import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; interface RouteParams { pluginId: string; } diff --git a/public/app/features/plugins/components/PluginStateInfo.tsx b/public/app/features/plugins/components/PluginStateInfo.tsx index 2552cf9f997..066034de2f8 100644 --- a/public/app/features/plugins/components/PluginStateInfo.tsx +++ b/public/app/features/plugins/components/PluginStateInfo.tsx @@ -1,6 +1,7 @@ import React, { FC } from 'react'; -import { Badge, BadgeProps } from '@grafana/ui'; + import { PluginState } from '@grafana/data'; +import { Badge, BadgeProps } from '@grafana/ui'; interface Props { state?: PluginState; diff --git a/public/app/features/plugins/components/PluginsErrorsInfo.tsx b/public/app/features/plugins/components/PluginsErrorsInfo.tsx index 6be74a424e1..9d085ee0fcf 100644 --- a/public/app/features/plugins/components/PluginsErrorsInfo.tsx +++ b/public/app/features/plugins/components/PluginsErrorsInfo.tsx @@ -1,9 +1,11 @@ +import { css } from '@emotion/css'; import React from 'react'; + +import { PluginErrorCode, PluginSignatureStatus } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; import { HorizontalGroup, InfoBox, List, PluginSignatureBadge, useTheme } from '@grafana/ui'; + import { useGetErrors, useFetchStatus } from '../admin/state/hooks'; -import { PluginErrorCode, PluginSignatureStatus } from '@grafana/data'; -import { css } from '@emotion/css'; export function PluginsErrorsInfo(): React.ReactElement | null { const errors = useGetErrors(); diff --git a/public/app/features/plugins/datasource_srv.ts b/public/app/features/plugins/datasource_srv.ts index a78301cc87d..6eb54233043 100644 --- a/public/app/features/plugins/datasource_srv.ts +++ b/public/app/features/plugins/datasource_srv.ts @@ -1,5 +1,11 @@ -// Services & Utils -import { importDataSourcePlugin } from './plugin_loader'; +import { + AppEvents, + DataSourceApi, + DataSourceInstanceSettings, + DataSourceRef, + DataSourceSelectItem, + ScopedVars, +} from '@grafana/data'; import { GetDataSourceListFilters, DataSourceSrv as DataSourceService, @@ -9,25 +15,18 @@ import { getLegacyAngularInjector, getBackendSrv, } from '@grafana/runtime'; -// Types -import { - AppEvents, - DataSourceApi, - DataSourceInstanceSettings, - DataSourceRef, - DataSourceSelectItem, - ScopedVars, -} from '@grafana/data'; -// Pretend Datasource +import { ExpressionDatasourceRef } from '@grafana/runtime/src/utils/DataSourceWithBackend'; +import appEvents from 'app/core/app_events'; +import config from 'app/core/config'; import { dataSource as expressionDatasource, ExpressionDatasourceUID, instanceSettings as expressionInstanceSettings, } from 'app/features/expressions/ExpressionDatasource'; + import { DataSourceVariableModel } from '../variables/types'; -import { ExpressionDatasourceRef } from '@grafana/runtime/src/utils/DataSourceWithBackend'; -import appEvents from 'app/core/app_events'; -import config from 'app/core/config'; + +import { importDataSourcePlugin } from './plugin_loader'; export class DatasourceSrv implements DataSourceService { private datasources: Record = {}; // UID diff --git a/public/app/features/plugins/importPanelPlugin.ts b/public/app/features/plugins/importPanelPlugin.ts index ccb3bdf9251..042db64bae1 100644 --- a/public/app/features/plugins/importPanelPlugin.ts +++ b/public/app/features/plugins/importPanelPlugin.ts @@ -1,6 +1,8 @@ -import config from 'app/core/config'; import * as grafanaData from '@grafana/data'; +import config from 'app/core/config'; + import { getPanelPluginLoadError } from '../panel/components/PanelPluginError'; + import { importPluginModule } from './plugin_loader'; interface PanelCache { [key: string]: Promise; diff --git a/public/app/features/plugins/pluginPreloader.ts b/public/app/features/plugins/pluginPreloader.ts index 34c10c44097..a8703471d89 100644 --- a/public/app/features/plugins/pluginPreloader.ts +++ b/public/app/features/plugins/pluginPreloader.ts @@ -1,4 +1,5 @@ import { PreloadPlugin } from '@grafana/data'; + import { importPluginModule } from './plugin_loader'; export async function preloadPlugins(pluginsToPreload: PreloadPlugin[] = []): Promise { diff --git a/public/app/features/plugins/pluginSettings.test.ts b/public/app/features/plugins/pluginSettings.test.ts index 08d6b67a5fc..c987f430180 100644 --- a/public/app/features/plugins/pluginSettings.test.ts +++ b/public/app/features/plugins/pluginSettings.test.ts @@ -1,6 +1,7 @@ -import { getPluginSettings, clearPluginSettingsCache } from './pluginSettings'; import { getBackendSrv } from '@grafana/runtime'; +import { getPluginSettings, clearPluginSettingsCache } from './pluginSettings'; + jest.mock('@grafana/runtime', () => ({ getBackendSrv: jest.fn().mockReturnValue({ get: jest.fn(), diff --git a/public/app/features/plugins/pluginSettings.ts b/public/app/features/plugins/pluginSettings.ts index 29a9f041cef..d3f21b83a8c 100644 --- a/public/app/features/plugins/pluginSettings.ts +++ b/public/app/features/plugins/pluginSettings.ts @@ -1,5 +1,5 @@ -import { getBackendSrv } from '@grafana/runtime'; import { PluginMeta } from '@grafana/data'; +import { getBackendSrv } from '@grafana/runtime'; type PluginCache = { [key: string]: PluginMeta; diff --git a/public/app/features/plugins/plugin_loader.ts b/public/app/features/plugins/plugin_loader.ts index 831a5947762..d3685cab5d2 100644 --- a/public/app/features/plugins/plugin_loader.ts +++ b/public/app/features/plugins/plugin_loader.ts @@ -1,36 +1,36 @@ -// eslint-disable-next-line lodash/import-scope -import _ from 'lodash'; -import kbn from 'app/core/utils/kbn'; -import moment from 'moment'; // eslint-disable-line no-restricted-imports +import * as emotion from '@emotion/css'; +import * as d3 from 'd3'; import jquery from 'jquery'; - -// Experimental module exports +import _ from 'lodash'; // eslint-disable-line lodash/import-scope +import moment from 'moment'; // eslint-disable-line no-restricted-imports import prismjs from 'prismjs'; -import slate from 'slate'; -// @ts-ignore -import slateReact from '@grafana/slate-react'; -// @ts-ignore -import slatePlain from 'slate-plain-serializer'; import react from 'react'; import reactDom from 'react-dom'; import * as reactRedux from 'react-redux'; +import * as reactRouter from 'react-router-dom'; import * as redux from 'redux'; +import * as rxjs from 'rxjs'; +import * as rxjsOperators from 'rxjs/operators'; +import slate from 'slate'; +import slatePlain from 'slate-plain-serializer'; +import * as grafanaData from '@grafana/data'; +import * as grafanaRuntime from '@grafana/runtime'; +import slateReact from '@grafana/slate-react'; +import * as grafanaUIraw from '@grafana/ui'; import config from 'app/core/config'; -import TimeSeries from 'app/core/time_series2'; -import TableModel from 'app/core/table_model'; import { appEvents, contextSrv } from 'app/core/core'; -import * as flatten from 'app/core/utils/flatten'; -import * as ticks from 'app/core/utils/ticks'; import { BackendSrv, getBackendSrv } from 'app/core/services/backend_srv'; import impressionSrv from 'app/core/services/impression_srv'; -import builtInPlugins from './built_in_plugins'; -import * as d3 from 'd3'; -import * as emotion from '@emotion/css'; -import * as grafanaData from '@grafana/data'; -import * as grafanaUIraw from '@grafana/ui'; -import * as grafanaRuntime from '@grafana/runtime'; +import TableModel from 'app/core/table_model'; +import TimeSeries from 'app/core/time_series2'; +import * as flatten from 'app/core/utils/flatten'; +import kbn from 'app/core/utils/kbn'; +import * as ticks from 'app/core/utils/ticks'; + import { GenericDataSourcePlugin } from '../datasources/settings/PluginSettings'; + +import builtInPlugins from './built_in_plugins'; import { locateWithCache, registerPluginInCache } from './pluginCacheBuster'; // Help the 6.4 to 6.5 migration @@ -42,12 +42,6 @@ grafanaUI.DataSourcePlugin = grafanaData.DataSourcePlugin; grafanaUI.AppPlugin = grafanaData.AppPlugin; grafanaUI.DataSourceApi = grafanaData.DataSourceApi; -// rxjs -import * as rxjs from 'rxjs'; -import * as rxjsOperators from 'rxjs/operators'; -// routing -import * as reactRouter from 'react-router-dom'; - grafanaRuntime.SystemJS.registry.set('plugin-loader', grafanaRuntime.SystemJS.newModule({ locate: locateWithCache })); grafanaRuntime.SystemJS.config({ diff --git a/public/app/features/plugins/tests/datasource_srv.test.ts b/public/app/features/plugins/tests/datasource_srv.test.ts index eba0d0dc8ce..14517b7d3e8 100644 --- a/public/app/features/plugins/tests/datasource_srv.test.ts +++ b/public/app/features/plugins/tests/datasource_srv.test.ts @@ -1,4 +1,3 @@ -import { DatasourceSrv } from 'app/features/plugins/datasource_srv'; import { DataSourceApi, DataSourceInstanceSettings, @@ -6,6 +5,7 @@ import { DataSourcePluginMeta, ScopedVar, } from '@grafana/data'; +import { DatasourceSrv } from 'app/features/plugins/datasource_srv'; // Datasource variable $datasource with current value 'BBB' const templateSrv: any = { diff --git a/public/app/features/plugins/tests/plugin_loader.test.ts b/public/app/features/plugins/tests/plugin_loader.test.ts index 2ddc26bd51f..e7af4f5d919 100644 --- a/public/app/features/plugins/tests/plugin_loader.test.ts +++ b/public/app/features/plugins/tests/plugin_loader.test.ts @@ -13,8 +13,8 @@ jest.mock('app/core/core', () => { }; }); -import { SystemJS } from '@grafana/runtime'; import { AppPluginMeta, PluginMetaInfo, PluginType, AppPlugin } from '@grafana/data'; +import { SystemJS } from '@grafana/runtime'; // Loaded after the `unmock` abve import { importAppPlugin } from '../plugin_loader'; diff --git a/public/app/features/plugins/utils.ts b/public/app/features/plugins/utils.ts index d11ef5150d7..f1662fa7b7a 100644 --- a/public/app/features/plugins/utils.ts +++ b/public/app/features/plugins/utils.ts @@ -1,7 +1,8 @@ import { GrafanaPlugin, PanelPluginMeta, PluginType } from '@grafana/data'; + +import { importPanelPluginFromMeta } from './importPanelPlugin'; import { getPluginSettings } from './pluginSettings'; import { importAppPlugin, importDataSourcePlugin } from './plugin_loader'; -import { importPanelPluginFromMeta } from './importPanelPlugin'; export async function loadPlugin(pluginId: string): Promise { const info = await getPluginSettings(pluginId); diff --git a/public/app/features/profile/ChangePasswordForm.tsx b/public/app/features/profile/ChangePasswordForm.tsx index 05b6be12a2b..d86dcd1e8e9 100644 --- a/public/app/features/profile/ChangePasswordForm.tsx +++ b/public/app/features/profile/ChangePasswordForm.tsx @@ -1,12 +1,14 @@ -import React, { FC } from 'react'; import { css } from '@emotion/css'; -import { Button, Field, Form, HorizontalGroup, LinkButton } from '@grafana/ui'; +import React, { FC } from 'react'; +import { Button, Field, Form, HorizontalGroup, LinkButton } from '@grafana/ui'; import config from 'app/core/config'; import { UserDTO } from 'app/types'; -import { ChangePasswordFields } from './types'; + import { PasswordField } from '../../core/components/PasswordField/PasswordField'; +import { ChangePasswordFields } from './types'; + export interface Props { user: UserDTO; isSaving: boolean; diff --git a/public/app/features/profile/ChangePasswordPage.test.tsx b/public/app/features/profile/ChangePasswordPage.test.tsx index 3fc936793b6..2c6e15e39d9 100644 --- a/public/app/features/profile/ChangePasswordPage.test.tsx +++ b/public/app/features/profile/ChangePasswordPage.test.tsx @@ -1,12 +1,15 @@ -import React from 'react'; import { fireEvent, render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import React from 'react'; + import config from 'app/core/config'; -import { Props, ChangePasswordPage } from './ChangePasswordPage'; -import { initialUserState } from './state/reducers'; + import { getNavModel } from '../../core/selectors/navModel'; import { backendSrv } from '../../core/services/backend_srv'; +import { Props, ChangePasswordPage } from './ChangePasswordPage'; +import { initialUserState } from './state/reducers'; + const defaultProps: Props = { ...initialUserState, user: { diff --git a/public/app/features/profile/ChangePasswordPage.tsx b/public/app/features/profile/ChangePasswordPage.tsx index db8ce8f8531..a5324bc1dbc 100644 --- a/public/app/features/profile/ChangePasswordPage.tsx +++ b/public/app/features/profile/ChangePasswordPage.tsx @@ -1,11 +1,12 @@ import React from 'react'; -import { useMount } from 'react-use'; import { connect, ConnectedProps } from 'react-redux'; -import { NavModel } from '@grafana/data'; +import { useMount } from 'react-use'; -import { StoreState } from 'app/types'; -import { getNavModel } from 'app/core/selectors/navModel'; +import { NavModel } from '@grafana/data'; import Page from 'app/core/components/Page/Page'; +import { getNavModel } from 'app/core/selectors/navModel'; +import { StoreState } from 'app/types'; + import { ChangePasswordForm } from './ChangePasswordForm'; import { changePassword, loadUser } from './state/actions'; diff --git a/public/app/features/profile/FeatureTogglePage.tsx b/public/app/features/profile/FeatureTogglePage.tsx index 1b7b3be5a2e..6fd197166dd 100644 --- a/public/app/features/profile/FeatureTogglePage.tsx +++ b/public/app/features/profile/FeatureTogglePage.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import Page from 'app/core/components/Page/Page'; import { useNavModel } from 'app/core/hooks/useNavModel'; diff --git a/public/app/features/profile/UserOrganizations.tsx b/public/app/features/profile/UserOrganizations.tsx index 288ec250492..f050c2b51b5 100644 --- a/public/app/features/profile/UserOrganizations.tsx +++ b/public/app/features/profile/UserOrganizations.tsx @@ -1,8 +1,9 @@ -import React, { PureComponent } from 'react'; -import { UserDTO, UserOrg } from 'app/types'; -import { Button, LoadingPlaceholder } from '@grafana/ui'; import { Trans } from '@lingui/macro'; +import React, { PureComponent } from 'react'; + import { selectors } from '@grafana/e2e-selectors'; +import { Button, LoadingPlaceholder } from '@grafana/ui'; +import { UserDTO, UserOrg } from 'app/types'; export interface Props { user: UserDTO | null; diff --git a/public/app/features/profile/UserProfileEditForm.tsx b/public/app/features/profile/UserProfileEditForm.tsx index b1be3a0cf87..f3c8927fbe9 100644 --- a/public/app/features/profile/UserProfileEditForm.tsx +++ b/public/app/features/profile/UserProfileEditForm.tsx @@ -1,9 +1,11 @@ -import React, { FC } from 'react'; import { Trans, t } from '@lingui/macro'; -import { Button, Field, FieldSet, Form, Icon, Input, Tooltip } from '@grafana/ui'; +import React, { FC } from 'react'; + import { selectors } from '@grafana/e2e-selectors'; -import { UserDTO } from 'app/types'; +import { Button, Field, FieldSet, Form, Icon, Input, Tooltip } from '@grafana/ui'; import config from 'app/core/config'; +import { UserDTO } from 'app/types'; + import { ProfileUpdateFields } from './types'; export interface Props { diff --git a/public/app/features/profile/UserProfileEditPage.test.tsx b/public/app/features/profile/UserProfileEditPage.test.tsx index bc31d02c8c6..83ada3e7937 100644 --- a/public/app/features/profile/UserProfileEditPage.test.tsx +++ b/public/app/features/profile/UserProfileEditPage.test.tsx @@ -1,17 +1,19 @@ -import React from 'react'; +import { within } from '@testing-library/dom'; import { render, screen, waitFor } from '@testing-library/react'; import userEvent, { PointerEventsCheckLevel } from '@testing-library/user-event'; -import { within } from '@testing-library/dom'; +import React from 'react'; + import { OrgRole } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; -import TestProvider from '../../../test/helpers/TestProvider'; -import { Props, UserProfileEditPage } from './UserProfileEditPage'; -import { initialUserState } from './state/reducers'; +import TestProvider from '../../../test/helpers/TestProvider'; import { getNavModel } from '../../core/selectors/navModel'; import { backendSrv } from '../../core/services/backend_srv'; import { TeamPermissionLevel } from '../../types'; +import { Props, UserProfileEditPage } from './UserProfileEditPage'; +import { initialUserState } from './state/reducers'; + const defaultProps: Props = { ...initialUserState, user: { diff --git a/public/app/features/profile/UserProfileEditPage.tsx b/public/app/features/profile/UserProfileEditPage.tsx index eee60196dd8..008893323b0 100644 --- a/public/app/features/profile/UserProfileEditPage.tsx +++ b/public/app/features/profile/UserProfileEditPage.tsx @@ -1,18 +1,19 @@ import React from 'react'; import { connect, ConnectedProps } from 'react-redux'; import { useMount } from 'react-use'; + import { NavModel } from '@grafana/data'; import { VerticalGroup } from '@grafana/ui'; - +import Page from 'app/core/components/Page/Page'; +import SharedPreferences from 'app/core/components/SharedPreferences/SharedPreferences'; import { getNavModel } from 'app/core/selectors/navModel'; import { StoreState } from 'app/types'; -import Page from 'app/core/components/Page/Page'; -import { changeUserOrg, initUserProfilePage, revokeUserSession, updateUserProfile } from './state/actions'; -import UserProfileEditForm from './UserProfileEditForm'; -import SharedPreferences from 'app/core/components/SharedPreferences/SharedPreferences'; -import { UserTeams } from './UserTeams'; + import UserOrganizations from './UserOrganizations'; +import UserProfileEditForm from './UserProfileEditForm'; import UserSessions from './UserSessions'; +import { UserTeams } from './UserTeams'; +import { changeUserOrg, initUserProfilePage, revokeUserSession, updateUserProfile } from './state/actions'; export interface OwnProps { navModel: NavModel; diff --git a/public/app/features/profile/UserSessions.tsx b/public/app/features/profile/UserSessions.tsx index 5036b501450..5a10f7e769e 100644 --- a/public/app/features/profile/UserSessions.tsx +++ b/public/app/features/profile/UserSessions.tsx @@ -1,9 +1,10 @@ -import React, { PureComponent } from 'react'; -import { UserSession } from 'app/types'; -import { Button, Icon, LoadingPlaceholder } from '@grafana/ui'; -import { withI18n, withI18nProps } from '@lingui/react'; import { t, Trans } from '@lingui/macro'; +import { withI18n, withI18nProps } from '@lingui/react'; +import React, { PureComponent } from 'react'; + import { selectors } from '@grafana/e2e-selectors'; +import { Button, Icon, LoadingPlaceholder } from '@grafana/ui'; +import { UserSession } from 'app/types'; interface Props extends withI18nProps { sessions: UserSession[]; diff --git a/public/app/features/profile/UserTeams.tsx b/public/app/features/profile/UserTeams.tsx index fc5c4bf3a94..a8af0342f8d 100644 --- a/public/app/features/profile/UserTeams.tsx +++ b/public/app/features/profile/UserTeams.tsx @@ -1,6 +1,7 @@ import React, { PureComponent } from 'react'; -import { Team } from 'app/types'; + import { LoadingPlaceholder } from '@grafana/ui'; +import { Team } from 'app/types'; export interface Props { teams: Team[]; diff --git a/public/app/features/profile/api.ts b/public/app/features/profile/api.ts index 7adc848a5ec..bb7e30d6b34 100644 --- a/public/app/features/profile/api.ts +++ b/public/app/features/profile/api.ts @@ -1,8 +1,9 @@ import { getBackendSrv } from '@grafana/runtime'; -import { ChangePasswordFields, ProfileUpdateFields } from './types'; import { Team, UserDTO, UserOrg, UserSession } from '../../types'; +import { ChangePasswordFields, ProfileUpdateFields } from './types'; + async function changePassword(payload: ChangePasswordFields): Promise { try { await getBackendSrv().put('/api/user/password', payload); diff --git a/public/app/features/profile/routes.tsx b/public/app/features/profile/routes.tsx index 48029f75dc8..cd101b79164 100644 --- a/public/app/features/profile/routes.tsx +++ b/public/app/features/profile/routes.tsx @@ -1,7 +1,8 @@ +import { uniq } from 'lodash'; + import { SafeDynamicImport } from 'app/core/components/DynamicImports/SafeDynamicImport'; import { config } from 'app/core/config'; import { RouteDescriptor } from 'app/core/navigation/types'; -import { uniq } from 'lodash'; const profileRoutes: RouteDescriptor[] = [ { diff --git a/public/app/features/profile/state/actions.ts b/public/app/features/profile/state/actions.ts index 2155b1088b2..e1e5f25600c 100644 --- a/public/app/features/profile/state/actions.ts +++ b/public/app/features/profile/state/actions.ts @@ -1,7 +1,9 @@ import { config } from '@grafana/runtime'; -import { ChangePasswordFields, ProfileUpdateFields } from '../types'; import { ThunkResult, UserOrg } from '../../../types'; +import { api } from '../api'; +import { ChangePasswordFields, ProfileUpdateFields } from '../types'; + import { initLoadOrgs, initLoadSessions, @@ -13,7 +15,6 @@ import { userLoaded, userSessionRevoked, } from './reducers'; -import { api } from '../api'; export function changePassword(payload: ChangePasswordFields): ThunkResult { return async function (dispatch) { diff --git a/public/app/features/profile/state/reducers.test.ts b/public/app/features/profile/state/reducers.test.ts index b9bcd399ab3..6993b46283d 100644 --- a/public/app/features/profile/state/reducers.test.ts +++ b/public/app/features/profile/state/reducers.test.ts @@ -1,5 +1,6 @@ import { reducerTester } from '../../../../test/core/redux/reducerTester'; import { OrgRole, TeamPermissionLevel } from '../../../types'; + import { initialUserState, orgsLoaded, diff --git a/public/app/features/profile/state/reducers.ts b/public/app/features/profile/state/reducers.ts index 90bde6f695b..a78ed3d5316 100644 --- a/public/app/features/profile/state/reducers.ts +++ b/public/app/features/profile/state/reducers.ts @@ -1,10 +1,10 @@ -import { isEmpty, isString, set } from 'lodash'; import { createSlice, PayloadAction } from '@reduxjs/toolkit'; -import { dateTimeFormatTimeAgo, setWeekStart, TimeZone } from '@grafana/data'; +import { isEmpty, isString, set } from 'lodash'; -import { Team, ThunkResult, UserDTO, UserOrg, UserSession } from 'app/types'; +import { dateTimeFormatTimeAgo, setWeekStart, TimeZone } from '@grafana/data'; import config from 'app/core/config'; import { contextSrv } from 'app/core/core'; +import { Team, ThunkResult, UserDTO, UserOrg, UserSession } from 'app/types'; export interface UserState { orgId: number; diff --git a/public/app/features/query/components/HelpToggle.tsx b/public/app/features/query/components/HelpToggle.tsx index 158cb5b8bd5..e06fbbb38a8 100644 --- a/public/app/features/query/components/HelpToggle.tsx +++ b/public/app/features/query/components/HelpToggle.tsx @@ -1,8 +1,9 @@ -import { GrafanaTheme } from '@grafana/data'; -import { Icon, InfoBox, stylesFactory, useTheme } from '@grafana/ui'; import { css, cx } from '@emotion/css'; import React, { useState } from 'react'; +import { GrafanaTheme } from '@grafana/data'; +import { Icon, InfoBox, stylesFactory, useTheme } from '@grafana/ui'; + const getStyles = stylesFactory((theme: GrafanaTheme) => ({ infoBox: css` margin-top: ${theme.spacing.xs}; diff --git a/public/app/features/query/components/QueryEditorRow.test.ts b/public/app/features/query/components/QueryEditorRow.test.ts index 34953929ce2..e5199482b05 100644 --- a/public/app/features/query/components/QueryEditorRow.test.ts +++ b/public/app/features/query/components/QueryEditorRow.test.ts @@ -1,4 +1,5 @@ import { DataQueryRequest, dateTime, LoadingState, PanelData, toDataFrame } from '@grafana/data'; + import { filterPanelDataToQuery } from './QueryEditorRow'; function makePretendRequest(requestId: string, subRequests?: DataQueryRequest[]): DataQueryRequest { diff --git a/public/app/features/query/components/QueryEditorRow.tsx b/public/app/features/query/components/QueryEditorRow.tsx index d7a6f156d2e..4ed1185e9a2 100644 --- a/public/app/features/query/components/QueryEditorRow.tsx +++ b/public/app/features/query/components/QueryEditorRow.tsx @@ -1,12 +1,9 @@ // Libraries -import React, { PureComponent, ReactNode } from 'react'; import classNames from 'classnames'; import { cloneDeep, has } from 'lodash'; +import React, { PureComponent, ReactNode } from 'react'; + // Utils & Services -import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; -import { AngularComponent, getAngularLoader } from '@grafana/runtime'; -import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv'; -import { ErrorBoundaryAlert, HorizontalGroup } from '@grafana/ui'; import { CoreApp, DataQuery, @@ -21,17 +18,22 @@ import { TimeRange, toLegacyResponseData, } from '@grafana/data'; -import { QueryEditorRowHeader } from './QueryEditorRowHeader'; +import { selectors } from '@grafana/e2e-selectors'; +import { AngularComponent, getAngularLoader } from '@grafana/runtime'; +import { ErrorBoundaryAlert, HorizontalGroup } from '@grafana/ui'; +import { OperationRowHelp } from 'app/core/components/QueryOperationRow/OperationRowHelp'; +import { QueryOperationAction } from 'app/core/components/QueryOperationRow/QueryOperationAction'; import { QueryOperationRow, QueryOperationRowRenderProps, } from 'app/core/components/QueryOperationRow/QueryOperationRow'; -import { QueryOperationAction } from 'app/core/components/QueryOperationRow/QueryOperationAction'; -import { selectors } from '@grafana/e2e-selectors'; -import { PanelModel } from 'app/features/dashboard/state/PanelModel'; +import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv'; import { DashboardModel } from 'app/features/dashboard/state/DashboardModel'; -import { OperationRowHelp } from 'app/core/components/QueryOperationRow/OperationRowHelp'; +import { PanelModel } from 'app/features/dashboard/state/PanelModel'; +import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; + import { RowActionComponents } from './QueryActionComponent'; +import { QueryEditorRowHeader } from './QueryEditorRowHeader'; import { QueryErrorAlert } from './QueryErrorAlert'; interface Props { diff --git a/public/app/features/query/components/QueryEditorRowHeader.test.tsx b/public/app/features/query/components/QueryEditorRowHeader.test.tsx index 8e6d616be84..736c8bc2a95 100644 --- a/public/app/features/query/components/QueryEditorRowHeader.test.tsx +++ b/public/app/features/query/components/QueryEditorRowHeader.test.tsx @@ -1,11 +1,13 @@ -import React from 'react'; import { fireEvent, render, screen } from '@testing-library/react'; -import { Props, QueryEditorRowHeader } from './QueryEditorRowHeader'; +import React from 'react'; + import { DataSourceInstanceSettings } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; import { mockDataSource } from 'app/features/alerting/unified/mocks'; import { DataSourceType } from 'app/features/alerting/unified/utils/datasource'; +import { Props, QueryEditorRowHeader } from './QueryEditorRowHeader'; + const mockDS = mockDataSource({ name: 'CloudManager', type: DataSourceType.Alertmanager, diff --git a/public/app/features/query/components/QueryEditorRowHeader.tsx b/public/app/features/query/components/QueryEditorRowHeader.tsx index 13714dba70a..20c8d86e900 100644 --- a/public/app/features/query/components/QueryEditorRowHeader.tsx +++ b/public/app/features/query/components/QueryEditorRowHeader.tsx @@ -1,9 +1,10 @@ -import React, { ReactNode, useState } from 'react'; import { css, cx } from '@emotion/css'; +import React, { ReactNode, useState } from 'react'; + import { DataQuery, DataSourceInstanceSettings, GrafanaTheme } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; import { DataSourcePicker } from '@grafana/runtime'; import { Icon, Input, FieldValidationMessage, useStyles } from '@grafana/ui'; -import { selectors } from '@grafana/e2e-selectors'; export interface Props { query: TQuery; diff --git a/public/app/features/query/components/QueryEditorRows.tsx b/public/app/features/query/components/QueryEditorRows.tsx index 575569fc59c..b81512e7eaf 100644 --- a/public/app/features/query/components/QueryEditorRows.tsx +++ b/public/app/features/query/components/QueryEditorRows.tsx @@ -1,7 +1,6 @@ -// Libraries import React, { PureComponent } from 'react'; +import { DragDropContext, DragStart, Droppable, DropResult } from 'react-beautiful-dnd'; -// Types import { CoreApp, DataQuery, @@ -10,10 +9,10 @@ import { HistoryItem, PanelData, } from '@grafana/data'; -import { QueryEditorRow } from './QueryEditorRow'; -import { DragDropContext, DragStart, Droppable, DropResult } from 'react-beautiful-dnd'; import { getDataSourceSrv, reportInteraction } from '@grafana/runtime'; +import { QueryEditorRow } from './QueryEditorRow'; + interface Props { // The query configuration queries: DataQuery[]; diff --git a/public/app/features/query/components/QueryErrorAlert.tsx b/public/app/features/query/components/QueryErrorAlert.tsx index c7cfd73909b..3a31cdadadf 100644 --- a/public/app/features/query/components/QueryErrorAlert.tsx +++ b/public/app/features/query/components/QueryErrorAlert.tsx @@ -1,7 +1,8 @@ +import { css } from '@emotion/css'; import React from 'react'; + import { DataQueryError, GrafanaTheme2 } from '@grafana/data'; import { Icon, useStyles2 } from '@grafana/ui'; -import { css } from '@emotion/css'; export interface Props { error: DataQueryError; diff --git a/public/app/features/query/components/QueryGroup.tsx b/public/app/features/query/components/QueryGroup.tsx index a28f71cc65d..9d784f45682 100644 --- a/public/app/features/query/components/QueryGroup.tsx +++ b/public/app/features/query/components/QueryGroup.tsx @@ -1,6 +1,17 @@ -// Libraries +import { css } from '@emotion/css'; import React, { PureComponent } from 'react'; -// Components +import { Unsubscribable } from 'rxjs'; + +import { + DataQuery, + DataSourceApi, + DataSourceInstanceSettings, + getDefaultTimeRange, + LoadingState, + PanelData, +} from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; +import { DataSourcePicker, getDataSourceSrv } from '@grafana/runtime'; import { Button, CustomScrollbar, @@ -10,33 +21,21 @@ import { ScrollbarPosition, stylesFactory, } from '@grafana/ui'; -import { DataSourcePicker, getDataSourceSrv } from '@grafana/runtime'; -import { QueryEditorRows } from './QueryEditorRows'; -// Services -import { backendSrv } from 'app/core/services/backend_srv'; -import config from 'app/core/config'; -// Types -import { - DataQuery, - DataSourceApi, - DataSourceInstanceSettings, - getDefaultTimeRange, - LoadingState, - PanelData, -} from '@grafana/data'; import { PluginHelp } from 'app/core/components/PluginHelp/PluginHelp'; +import config from 'app/core/config'; +import { backendSrv } from 'app/core/services/backend_srv'; import { addQuery } from 'app/core/utils/query'; -import { Unsubscribable } from 'rxjs'; import { dataSource as expressionDatasource } from 'app/features/expressions/ExpressionDatasource'; -import { selectors } from '@grafana/e2e-selectors'; -import { PanelQueryRunner } from '../state/PanelQueryRunner'; -import { QueryGroupOptionsEditor } from './QueryGroupOptions'; import { DashboardQueryEditor, isSharedDashboardQuery } from 'app/plugins/datasource/dashboard'; -import { css } from '@emotion/css'; import { QueryGroupOptions } from 'app/types'; -import { GroupActionComponents } from './QueryActionComponent'; + +import { PanelQueryRunner } from '../state/PanelQueryRunner'; import { updateQueries } from '../state/updateQueries'; +import { GroupActionComponents } from './QueryActionComponent'; +import { QueryEditorRows } from './QueryEditorRows'; +import { QueryGroupOptionsEditor } from './QueryGroupOptions'; + interface Props { queryRunner: PanelQueryRunner; options: QueryGroupOptions; diff --git a/public/app/features/query/components/QueryGroupOptions.tsx b/public/app/features/query/components/QueryGroupOptions.tsx index 202bcf29bbd..371851a7011 100644 --- a/public/app/features/query/components/QueryGroupOptions.tsx +++ b/public/app/features/query/components/QueryGroupOptions.tsx @@ -1,16 +1,10 @@ -// Libraries +import { css } from '@emotion/css'; import React, { PureComponent, ChangeEvent, FocusEvent } from 'react'; -// Utils import { rangeUtil, PanelData, DataSourceApi } from '@grafana/data'; - -// Components import { Switch, Input, InlineField, InlineFormLabel, stylesFactory } from '@grafana/ui'; - -// Types import { QueryOperationRow } from 'app/core/components/QueryOperationRow/QueryOperationRow'; import { config } from 'app/core/config'; -import { css } from '@emotion/css'; import { QueryGroupOptions } from 'app/types'; interface Props { diff --git a/public/app/features/query/state/DashboardQueryRunner/AlertStatesWorker.test.ts b/public/app/features/query/state/DashboardQueryRunner/AlertStatesWorker.test.ts index 93426591994..6c75831bb31 100644 --- a/public/app/features/query/state/DashboardQueryRunner/AlertStatesWorker.test.ts +++ b/public/app/features/query/state/DashboardQueryRunner/AlertStatesWorker.test.ts @@ -1,11 +1,12 @@ import { AlertState, AlertStateInfo, getDefaultTimeRange, TimeRange } from '@grafana/data'; import { backendSrv } from 'app/core/services/backend_srv'; -import { DashboardQueryRunnerOptions } from './types'; -import { AlertStatesWorker } from './AlertStatesWorker'; import { silenceConsoleOutput } from '../../../../../test/core/utils/silenceConsoleOutput'; import * as store from '../../../../store/store'; +import { AlertStatesWorker } from './AlertStatesWorker'; +import { DashboardQueryRunnerOptions } from './types'; + jest.mock('@grafana/runtime', () => ({ ...(jest.requireActual('@grafana/runtime') as unknown as object), getBackendSrv: () => backendSrv, diff --git a/public/app/features/query/state/DashboardQueryRunner/AlertStatesWorker.ts b/public/app/features/query/state/DashboardQueryRunner/AlertStatesWorker.ts index 698f05d7165..edefd0710e0 100644 --- a/public/app/features/query/state/DashboardQueryRunner/AlertStatesWorker.ts +++ b/public/app/features/query/state/DashboardQueryRunner/AlertStatesWorker.ts @@ -1,7 +1,9 @@ -import { DashboardQueryRunnerOptions, DashboardQueryRunnerWorker, DashboardQueryRunnerWorkerResult } from './types'; import { from, Observable } from 'rxjs'; -import { getBackendSrv } from '@grafana/runtime'; import { catchError, map } from 'rxjs/operators'; + +import { getBackendSrv } from '@grafana/runtime'; + +import { DashboardQueryRunnerOptions, DashboardQueryRunnerWorker, DashboardQueryRunnerWorkerResult } from './types'; import { emptyResult, handleDashboardQueryRunnerWorkerError } from './utils'; export class AlertStatesWorker implements DashboardQueryRunnerWorker { diff --git a/public/app/features/query/state/DashboardQueryRunner/AnnotationsQueryRunner.test.ts b/public/app/features/query/state/DashboardQueryRunner/AnnotationsQueryRunner.test.ts index 220363dde2f..9e04b783c8d 100644 --- a/public/app/features/query/state/DashboardQueryRunner/AnnotationsQueryRunner.test.ts +++ b/public/app/features/query/state/DashboardQueryRunner/AnnotationsQueryRunner.test.ts @@ -1,12 +1,14 @@ +import { Observable, of, throwError } from 'rxjs'; + import { getDefaultTimeRange } from '@grafana/data'; -import { AnnotationsQueryRunner } from './AnnotationsQueryRunner'; -import { AnnotationQueryRunnerOptions } from './types'; import { silenceConsoleOutput } from '../../../../../test/core/utils/silenceConsoleOutput'; import * as store from '../../../../store/store'; import * as annotationsSrv from '../../../annotations/executeAnnotationQuery'; -import { Observable, of, throwError } from 'rxjs'; + +import { AnnotationsQueryRunner } from './AnnotationsQueryRunner'; import { toAsyncOfResult } from './testHelpers'; +import { AnnotationQueryRunnerOptions } from './types'; function getDefaultOptions(): AnnotationQueryRunnerOptions { const annotation: any = {}; diff --git a/public/app/features/query/state/DashboardQueryRunner/AnnotationsQueryRunner.ts b/public/app/features/query/state/DashboardQueryRunner/AnnotationsQueryRunner.ts index 458656615b2..4eadff44e59 100644 --- a/public/app/features/query/state/DashboardQueryRunner/AnnotationsQueryRunner.ts +++ b/public/app/features/query/state/DashboardQueryRunner/AnnotationsQueryRunner.ts @@ -1,10 +1,12 @@ import { Observable, of } from 'rxjs'; import { catchError, map } from 'rxjs/operators'; + import { AnnotationEvent, DataSourceApi } from '@grafana/data'; -import { AnnotationQueryRunner, AnnotationQueryRunnerOptions } from './types'; -import { PanelModel } from '../../../dashboard/state'; import { executeAnnotationQuery } from '../../../annotations/executeAnnotationQuery'; +import { PanelModel } from '../../../dashboard/state'; + +import { AnnotationQueryRunner, AnnotationQueryRunnerOptions } from './types'; import { handleAnnotationQueryRunnerError } from './utils'; export class AnnotationsQueryRunner implements AnnotationQueryRunner { diff --git a/public/app/features/query/state/DashboardQueryRunner/AnnotationsWorker.test.ts b/public/app/features/query/state/DashboardQueryRunner/AnnotationsWorker.test.ts index 8f6917004c9..c82ff012f6e 100644 --- a/public/app/features/query/state/DashboardQueryRunner/AnnotationsWorker.test.ts +++ b/public/app/features/query/state/DashboardQueryRunner/AnnotationsWorker.test.ts @@ -1,15 +1,17 @@ import { Subject, throwError } from 'rxjs'; +import { delay } from 'rxjs/operators'; + +import { AnnotationQuery } from '@grafana/data'; import { setDataSourceSrv } from '@grafana/runtime'; -import { AnnotationsWorker } from './AnnotationsWorker'; -import * as annotationsSrv from '../../../annotations/executeAnnotationQuery'; -import { getDefaultOptions, LEGACY_DS_NAME, NEXT_GEN_DS_NAME, toAsyncOfResult } from './testHelpers'; import { silenceConsoleOutput } from '../../../../../test/core/utils/silenceConsoleOutput'; +import * as annotationsSrv from '../../../annotations/executeAnnotationQuery'; + +import { AnnotationsWorker } from './AnnotationsWorker'; import { createDashboardQueryRunner, setDashboardQueryRunnerFactory } from './DashboardQueryRunner'; -import { emptyResult } from './utils'; +import { getDefaultOptions, LEGACY_DS_NAME, NEXT_GEN_DS_NAME, toAsyncOfResult } from './testHelpers'; import { DashboardQueryRunnerOptions, DashboardQueryRunnerWorkerResult } from './types'; -import { AnnotationQuery } from '@grafana/data'; -import { delay } from 'rxjs/operators'; +import { emptyResult } from './utils'; function getTestContext(dataSourceSrvRejects = false) { jest.clearAllMocks(); diff --git a/public/app/features/query/state/DashboardQueryRunner/AnnotationsWorker.ts b/public/app/features/query/state/DashboardQueryRunner/AnnotationsWorker.ts index 7233303b84c..4744483d2a1 100644 --- a/public/app/features/query/state/DashboardQueryRunner/AnnotationsWorker.ts +++ b/public/app/features/query/state/DashboardQueryRunner/AnnotationsWorker.ts @@ -1,9 +1,15 @@ import { cloneDeep } from 'lodash'; import { from, merge, Observable, of } from 'rxjs'; import { catchError, filter, finalize, map, mergeAll, mergeMap, reduce, takeUntil } from 'rxjs/operators'; -import { getDataSourceSrv } from '@grafana/runtime'; -import { AnnotationQuery, DataSourceApi } from '@grafana/data'; +import { AnnotationQuery, DataSourceApi } from '@grafana/data'; +import { getDataSourceSrv } from '@grafana/runtime'; + +import { AnnotationQueryFinished, AnnotationQueryStarted } from '../../../../types/events'; + +import { AnnotationsQueryRunner } from './AnnotationsQueryRunner'; +import { getDashboardQueryRunner } from './DashboardQueryRunner'; +import { LegacyAnnotationQueryRunner } from './LegacyAnnotationQueryRunner'; import { AnnotationQueryRunner, DashboardQueryRunnerOptions, @@ -11,10 +17,6 @@ import { DashboardQueryRunnerWorkerResult, } from './types'; import { emptyResult, handleDatasourceSrvError, translateQueryResult } from './utils'; -import { LegacyAnnotationQueryRunner } from './LegacyAnnotationQueryRunner'; -import { AnnotationsQueryRunner } from './AnnotationsQueryRunner'; -import { AnnotationQueryFinished, AnnotationQueryStarted } from '../../../../types/events'; -import { getDashboardQueryRunner } from './DashboardQueryRunner'; export class AnnotationsWorker implements DashboardQueryRunnerWorker { constructor( diff --git a/public/app/features/query/state/DashboardQueryRunner/DashboardQueryRunner.test.ts b/public/app/features/query/state/DashboardQueryRunner/DashboardQueryRunner.test.ts index ba65d463d4f..43c0509e6eb 100644 --- a/public/app/features/query/state/DashboardQueryRunner/DashboardQueryRunner.test.ts +++ b/public/app/features/query/state/DashboardQueryRunner/DashboardQueryRunner.test.ts @@ -1,14 +1,16 @@ import { throwError } from 'rxjs'; import { delay, first } from 'rxjs/operators'; -import { setDataSourceSrv } from '@grafana/runtime'; -import { AlertState, AlertStateInfo } from '@grafana/data'; -import * as annotationsSrv from '../../../annotations/executeAnnotationQuery'; -import { getDefaultOptions, LEGACY_DS_NAME, NEXT_GEN_DS_NAME, toAsyncOfResult } from './testHelpers'; -import { backendSrv } from '../../../../core/services/backend_srv'; -import { DashboardQueryRunner, DashboardQueryRunnerResult } from './types'; +import { AlertState, AlertStateInfo } from '@grafana/data'; +import { setDataSourceSrv } from '@grafana/runtime'; + import { silenceConsoleOutput } from '../../../../../test/core/utils/silenceConsoleOutput'; +import { backendSrv } from '../../../../core/services/backend_srv'; +import * as annotationsSrv from '../../../annotations/executeAnnotationQuery'; + import { createDashboardQueryRunner } from './DashboardQueryRunner'; +import { getDefaultOptions, LEGACY_DS_NAME, NEXT_GEN_DS_NAME, toAsyncOfResult } from './testHelpers'; +import { DashboardQueryRunner, DashboardQueryRunnerResult } from './types'; jest.mock('@grafana/runtime', () => ({ ...(jest.requireActual('@grafana/runtime') as unknown as object), diff --git a/public/app/features/query/state/DashboardQueryRunner/DashboardQueryRunner.ts b/public/app/features/query/state/DashboardQueryRunner/DashboardQueryRunner.ts index b7756e6295c..42538db0392 100644 --- a/public/app/features/query/state/DashboardQueryRunner/DashboardQueryRunner.ts +++ b/public/app/features/query/state/DashboardQueryRunner/DashboardQueryRunner.ts @@ -1,8 +1,18 @@ import { merge, Observable, ReplaySubject, Subject, Subscription, timer, Unsubscribable } from 'rxjs'; import { finalize, map, mapTo, mergeAll, reduce, share, takeUntil } from 'rxjs/operators'; -import { AnnotationQuery } from '@grafana/data'; +import { AnnotationQuery } from '@grafana/data'; +import { RefreshEvent } from '@grafana/runtime'; +import { config } from 'app/core/config'; import { dedupAnnotations } from 'app/features/annotations/events_processing'; + +import { getTimeSrv, TimeSrv } from '../../../dashboard/services/TimeSrv'; +import { DashboardModel } from '../../../dashboard/state'; + +import { AlertStatesWorker } from './AlertStatesWorker'; +import { AnnotationsWorker } from './AnnotationsWorker'; +import { SnapshotWorker } from './SnapshotWorker'; +import { UnifiedAlertStatesWorker } from './UnifiedAlertStatesWorker'; import { DashboardQueryRunner, DashboardQueryRunnerOptions, @@ -10,15 +20,7 @@ import { DashboardQueryRunnerWorker, DashboardQueryRunnerWorkerResult, } from './types'; -import { AlertStatesWorker } from './AlertStatesWorker'; -import { SnapshotWorker } from './SnapshotWorker'; -import { AnnotationsWorker } from './AnnotationsWorker'; import { getAnnotationsByPanelId } from './utils'; -import { DashboardModel } from '../../../dashboard/state'; -import { getTimeSrv, TimeSrv } from '../../../dashboard/services/TimeSrv'; -import { RefreshEvent } from '@grafana/runtime'; -import { config } from 'app/core/config'; -import { UnifiedAlertStatesWorker } from './UnifiedAlertStatesWorker'; class DashboardQueryRunnerImpl implements DashboardQueryRunner { private readonly results: ReplaySubject; diff --git a/public/app/features/query/state/DashboardQueryRunner/LegacyAnnotationQueryRunner.test.ts b/public/app/features/query/state/DashboardQueryRunner/LegacyAnnotationQueryRunner.test.ts index 082bf648edd..9111583e8df 100644 --- a/public/app/features/query/state/DashboardQueryRunner/LegacyAnnotationQueryRunner.test.ts +++ b/public/app/features/query/state/DashboardQueryRunner/LegacyAnnotationQueryRunner.test.ts @@ -1,9 +1,10 @@ import { getDefaultTimeRange } from '@grafana/data'; +import { silenceConsoleOutput } from '../../../../../test/core/utils/silenceConsoleOutput'; +import * as store from '../../../../store/store'; + import { LegacyAnnotationQueryRunner } from './LegacyAnnotationQueryRunner'; import { AnnotationQueryRunnerOptions } from './types'; -import { silenceConsoleOutput } from '../../../../../test/core/utils/silenceConsoleOutput'; -import * as store from '../../../../store/store'; function getDefaultOptions(annotationQuery?: jest.Mock): AnnotationQueryRunnerOptions { const annotation: any = {}; diff --git a/public/app/features/query/state/DashboardQueryRunner/LegacyAnnotationQueryRunner.ts b/public/app/features/query/state/DashboardQueryRunner/LegacyAnnotationQueryRunner.ts index 47d5ee5a533..5d94911b9ab 100644 --- a/public/app/features/query/state/DashboardQueryRunner/LegacyAnnotationQueryRunner.ts +++ b/public/app/features/query/state/DashboardQueryRunner/LegacyAnnotationQueryRunner.ts @@ -1,5 +1,6 @@ import { from, Observable, of } from 'rxjs'; import { catchError } from 'rxjs/operators'; + import { AnnotationEvent, DataSourceApi } from '@grafana/data'; import { AnnotationQueryRunner, AnnotationQueryRunnerOptions } from './types'; diff --git a/public/app/features/query/state/DashboardQueryRunner/SnapshotWorker.test.ts b/public/app/features/query/state/DashboardQueryRunner/SnapshotWorker.test.ts index e9f669a5ef1..f8f1f499869 100644 --- a/public/app/features/query/state/DashboardQueryRunner/SnapshotWorker.test.ts +++ b/public/app/features/query/state/DashboardQueryRunner/SnapshotWorker.test.ts @@ -1,7 +1,7 @@ import { AnnotationEvent, getDefaultTimeRange } from '@grafana/data'; -import { DashboardQueryRunnerOptions } from './types'; import { SnapshotWorker } from './SnapshotWorker'; +import { DashboardQueryRunnerOptions } from './types'; function getDefaultOptions(): DashboardQueryRunnerOptions { const dashboard: any = {}; diff --git a/public/app/features/query/state/DashboardQueryRunner/SnapshotWorker.ts b/public/app/features/query/state/DashboardQueryRunner/SnapshotWorker.ts index 2ed6b42cf33..861b1cbd819 100644 --- a/public/app/features/query/state/DashboardQueryRunner/SnapshotWorker.ts +++ b/public/app/features/query/state/DashboardQueryRunner/SnapshotWorker.ts @@ -1,9 +1,11 @@ import { Observable, of } from 'rxjs'; + import { AnnotationEvent } from '@grafana/data'; +import { DashboardModel } from '../../../dashboard/state'; + import { DashboardQueryRunnerOptions, DashboardQueryRunnerWorker, DashboardQueryRunnerWorkerResult } from './types'; import { emptyResult, getAnnotationsByPanelId, translateQueryResult } from './utils'; -import { DashboardModel } from '../../../dashboard/state'; export class SnapshotWorker implements DashboardQueryRunnerWorker { canWork({ dashboard }: DashboardQueryRunnerOptions): boolean { diff --git a/public/app/features/query/state/DashboardQueryRunner/UnifiedAlertStatesWorker.test.ts b/public/app/features/query/state/DashboardQueryRunner/UnifiedAlertStatesWorker.test.ts index ebb2ee19c7c..f2d1c4eaf8c 100644 --- a/public/app/features/query/state/DashboardQueryRunner/UnifiedAlertStatesWorker.test.ts +++ b/public/app/features/query/state/DashboardQueryRunner/UnifiedAlertStatesWorker.test.ts @@ -1,13 +1,15 @@ +import { lastValueFrom } from 'rxjs'; + import { AlertState, getDefaultTimeRange, TimeRange } from '@grafana/data'; import { backendSrv } from 'app/core/services/backend_srv'; +import { Annotation } from 'app/features/alerting/unified/utils/constants'; +import { PromAlertingRuleState, PromRuleDTO, PromRulesResponse, PromRuleType } from 'app/types/unified-alerting-dto'; -import { DashboardQueryRunnerOptions } from './types'; -import { UnifiedAlertStatesWorker } from './UnifiedAlertStatesWorker'; import { silenceConsoleOutput } from '../../../../../test/core/utils/silenceConsoleOutput'; import * as store from '../../../../store/store'; -import { PromAlertingRuleState, PromRuleDTO, PromRulesResponse, PromRuleType } from 'app/types/unified-alerting-dto'; -import { Annotation } from 'app/features/alerting/unified/utils/constants'; -import { lastValueFrom } from 'rxjs'; + +import { UnifiedAlertStatesWorker } from './UnifiedAlertStatesWorker'; +import { DashboardQueryRunnerOptions } from './types'; jest.mock('@grafana/runtime', () => ({ ...(jest.requireActual('@grafana/runtime') as unknown as object), diff --git a/public/app/features/query/state/DashboardQueryRunner/UnifiedAlertStatesWorker.ts b/public/app/features/query/state/DashboardQueryRunner/UnifiedAlertStatesWorker.ts index fc43b6b93a7..a9100ce3e60 100644 --- a/public/app/features/query/state/DashboardQueryRunner/UnifiedAlertStatesWorker.ts +++ b/public/app/features/query/state/DashboardQueryRunner/UnifiedAlertStatesWorker.ts @@ -1,12 +1,14 @@ -import { DashboardQueryRunnerOptions, DashboardQueryRunnerWorker, DashboardQueryRunnerWorkerResult } from './types'; import { from, Observable } from 'rxjs'; -import { getBackendSrv } from '@grafana/runtime'; import { catchError, map } from 'rxjs/operators'; -import { emptyResult, handleDashboardQueryRunnerWorkerError } from './utils'; -import { PromAlertingRuleState, PromRulesResponse } from 'app/types/unified-alerting-dto'; + import { AlertState, AlertStateInfo } from '@grafana/data'; -import { isAlertingRule } from 'app/features/alerting/unified/utils/rules'; +import { getBackendSrv } from '@grafana/runtime'; import { Annotation } from 'app/features/alerting/unified/utils/constants'; +import { isAlertingRule } from 'app/features/alerting/unified/utils/rules'; +import { PromAlertingRuleState, PromRulesResponse } from 'app/types/unified-alerting-dto'; + +import { DashboardQueryRunnerOptions, DashboardQueryRunnerWorker, DashboardQueryRunnerWorkerResult } from './types'; +import { emptyResult, handleDashboardQueryRunnerWorkerError } from './utils'; export class UnifiedAlertStatesWorker implements DashboardQueryRunnerWorker { // maps dashboard uid to wether it has alert rules. diff --git a/public/app/features/query/state/DashboardQueryRunner/testHelpers.ts b/public/app/features/query/state/DashboardQueryRunner/testHelpers.ts index 7891c23e604..0015adfc081 100644 --- a/public/app/features/query/state/DashboardQueryRunner/testHelpers.ts +++ b/public/app/features/query/state/DashboardQueryRunner/testHelpers.ts @@ -1,7 +1,9 @@ import { asyncScheduler, Observable, of, scheduled } from 'rxjs'; -import { DashboardQueryRunnerOptions } from './types'; + import { AnnotationEvent, getDefaultTimeRange } from '@grafana/data'; +import { DashboardQueryRunnerOptions } from './types'; + // function that creates an async of result Observable export function toAsyncOfResult(result: any): Observable { return scheduled(of(result), asyncScheduler); diff --git a/public/app/features/query/state/DashboardQueryRunner/types.ts b/public/app/features/query/state/DashboardQueryRunner/types.ts index 12f78b23077..ff19d443506 100644 --- a/public/app/features/query/state/DashboardQueryRunner/types.ts +++ b/public/app/features/query/state/DashboardQueryRunner/types.ts @@ -1,4 +1,5 @@ import { Observable } from 'rxjs'; + import { AlertStateInfo, AnnotationEvent, AnnotationQuery, DataSourceApi, TimeRange } from '@grafana/data'; import { DashboardModel } from '../../../dashboard/state'; diff --git a/public/app/features/query/state/DashboardQueryRunner/utils.ts b/public/app/features/query/state/DashboardQueryRunner/utils.ts index f3f88682059..2e17bf360b2 100644 --- a/public/app/features/query/state/DashboardQueryRunner/utils.ts +++ b/public/app/features/query/state/DashboardQueryRunner/utils.ts @@ -1,11 +1,13 @@ import { cloneDeep } from 'lodash'; import { Observable, of } from 'rxjs'; + import { AnnotationEvent, AnnotationQuery, DataFrame, DataFrameView, DataSourceApi } from '@grafana/data'; import { config, toDataQueryError } from '@grafana/runtime'; - import { dispatch } from 'app/store/store'; + import { createErrorNotification } from '../../../../core/copy/appNotification'; import { notifyApp } from '../../../../core/reducers/appNotification'; + import { DashboardQueryRunnerWorkerResult } from './types'; export function handleAnnotationQueryRunnerError(err: any): Observable { diff --git a/public/app/features/query/state/PanelQueryRunner.test.ts b/public/app/features/query/state/PanelQueryRunner.test.ts index 40ad3b52c19..d86db370a6d 100644 --- a/public/app/features/query/state/PanelQueryRunner.test.ts +++ b/public/app/features/query/state/PanelQueryRunner.test.ts @@ -1,16 +1,19 @@ const applyFieldOverridesMock = jest.fn(); // needs to be first in this file import { Subject } from 'rxjs'; + // Importing this way to be able to spy on grafana/data import * as grafanaData from '@grafana/data'; -import { DashboardModel } from '../../dashboard/state/index'; import { setDataSourceSrv, setEchoSrv } from '@grafana/runtime'; + import { Echo } from '../../../core/services/echo/Echo'; -import { emptyResult } from './DashboardQueryRunner/utils'; +import { DashboardModel } from '../../dashboard/state/index'; + import { createDashboardQueryRunner, setDashboardQueryRunnerFactory, } from './DashboardQueryRunner/DashboardQueryRunner'; +import { emptyResult } from './DashboardQueryRunner/utils'; import { PanelQueryRunner } from './PanelQueryRunner'; jest.mock('@grafana/data', () => ({ diff --git a/public/app/features/query/state/PanelQueryRunner.ts b/public/app/features/query/state/PanelQueryRunner.ts index 90336b3f23b..f7ceea18895 100644 --- a/public/app/features/query/state/PanelQueryRunner.ts +++ b/public/app/features/query/state/PanelQueryRunner.ts @@ -1,15 +1,7 @@ -// Libraries import { cloneDeep } from 'lodash'; import { MonoTypeOperatorFunction, Observable, of, ReplaySubject, Unsubscribable } from 'rxjs'; import { map, mergeMap } from 'rxjs/operators'; -// Services & Utils -import { getTemplateSrv } from '@grafana/runtime'; -import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; -import { preProcessPanelData, runRequest } from './runRequest'; -import { isSharedDashboardQuery, runSharedRequest } from '../../../plugins/datasource/dashboard'; - -// Types import { applyFieldOverrides, compareArrayValues, @@ -33,11 +25,17 @@ import { toDataFrame, transformDataFrame, } from '@grafana/data'; +import { getTemplateSrv } from '@grafana/runtime'; +import { StreamingDataFrame } from 'app/features/live/data/StreamingDataFrame'; +import { isStreamingDataFrame } from 'app/features/live/data/utils'; +import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; + +import { isSharedDashboardQuery, runSharedRequest } from '../../../plugins/datasource/dashboard'; +import { PanelModel } from '../../dashboard/state'; + import { getDashboardQueryRunner } from './DashboardQueryRunner/DashboardQueryRunner'; import { mergePanelAndDashData } from './mergePanelAndDashData'; -import { PanelModel } from '../../dashboard/state'; -import { isStreamingDataFrame } from 'app/features/live/data/utils'; -import { StreamingDataFrame } from 'app/features/live/data/StreamingDataFrame'; +import { preProcessPanelData, runRequest } from './runRequest'; export interface QueryRunnerOptions< TQuery extends DataQuery = DataQuery, diff --git a/public/app/features/query/state/QueryRunner.ts b/public/app/features/query/state/QueryRunner.ts index a437e7ec554..8002bd7b860 100644 --- a/public/app/features/query/state/QueryRunner.ts +++ b/public/app/features/query/state/QueryRunner.ts @@ -1,3 +1,7 @@ +import { cloneDeep } from 'lodash'; +import { from, Observable, ReplaySubject, Unsubscribable } from 'rxjs'; +import { first } from 'rxjs/operators'; + import { CoreApp, DataQueryRequest, @@ -12,9 +16,7 @@ import { } from '@grafana/data'; import { getTemplateSrv } from '@grafana/runtime'; import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; -import { cloneDeep } from 'lodash'; -import { from, Observable, ReplaySubject, Unsubscribable } from 'rxjs'; -import { first } from 'rxjs/operators'; + import { getNextRequestId } from './PanelQueryRunner'; import { setStructureRevision } from './processing/revision'; import { preProcessPanelData, runRequest } from './runRequest'; diff --git a/public/app/features/query/state/mergePanelAndDashData.test.ts b/public/app/features/query/state/mergePanelAndDashData.test.ts index b559ba47878..06c3fff4ea1 100644 --- a/public/app/features/query/state/mergePanelAndDashData.test.ts +++ b/public/app/features/query/state/mergePanelAndDashData.test.ts @@ -1,7 +1,9 @@ -import { AlertState, getDefaultTimeRange, LoadingState, PanelData, toDataFrame } from '@grafana/data'; -import { mergePanelAndDashData } from './mergePanelAndDashData'; import { TestScheduler } from 'rxjs/testing'; +import { AlertState, getDefaultTimeRange, LoadingState, PanelData, toDataFrame } from '@grafana/data'; + +import { mergePanelAndDashData } from './mergePanelAndDashData'; + function getTestContext() { const timeRange = getDefaultTimeRange(); const panelData: PanelData = { diff --git a/public/app/features/query/state/mergePanelAndDashData.ts b/public/app/features/query/state/mergePanelAndDashData.ts index 1ee11a541b4..f661b7dd649 100644 --- a/public/app/features/query/state/mergePanelAndDashData.ts +++ b/public/app/features/query/state/mergePanelAndDashData.ts @@ -1,8 +1,10 @@ import { combineLatest, Observable, of } from 'rxjs'; -import { ArrayDataFrame, PanelData } from '@grafana/data'; -import { DashboardQueryRunnerResult } from './DashboardQueryRunner/types'; import { mergeMap } from 'rxjs/operators'; +import { ArrayDataFrame, PanelData } from '@grafana/data'; + +import { DashboardQueryRunnerResult } from './DashboardQueryRunner/types'; + export function mergePanelAndDashData( panelObservable: Observable, dashObservable: Observable diff --git a/public/app/features/query/state/processing/canceler.ts b/public/app/features/query/state/processing/canceler.ts index 3e0498b108e..254395adabc 100644 --- a/public/app/features/query/state/processing/canceler.ts +++ b/public/app/features/query/state/processing/canceler.ts @@ -1,7 +1,8 @@ -import { BackendSrv } from 'app/core/services/backend_srv'; import { MonoTypeOperatorFunction } from 'rxjs'; import { finalize } from 'rxjs/operators'; +import { BackendSrv } from 'app/core/services/backend_srv'; + export function cancelNetworkRequestsOnUnsubscribe( backendSrv: BackendSrv, requestId: string | undefined diff --git a/public/app/features/query/state/queryAnalytics.test.ts b/public/app/features/query/state/queryAnalytics.test.ts index 18e7ceaeab0..e9fa2e159bd 100644 --- a/public/app/features/query/state/queryAnalytics.test.ts +++ b/public/app/features/query/state/queryAnalytics.test.ts @@ -1,8 +1,10 @@ -import { MetaAnalyticsEventName, reportMetaAnalytics } from '@grafana/runtime'; import { CoreApp, DataFrame, DataQueryRequest, DataSourceApi, dateTime, LoadingState, PanelData } from '@grafana/data'; -import { emitDataRequestEvent } from './queryAnalytics'; +import { MetaAnalyticsEventName, reportMetaAnalytics } from '@grafana/runtime'; + import { DashboardModel } from '../../dashboard/state'; +import { emitDataRequestEvent } from './queryAnalytics'; + beforeEach(() => { jest.clearAllMocks(); }); diff --git a/public/app/features/query/state/queryAnalytics.ts b/public/app/features/query/state/queryAnalytics.ts index 7fefcd8e9e0..b3e3dccd160 100644 --- a/public/app/features/query/state/queryAnalytics.ts +++ b/public/app/features/query/state/queryAnalytics.ts @@ -1,7 +1,8 @@ -import { getDashboardSrv } from '../../dashboard/services/DashboardSrv'; import { PanelData, LoadingState, DataSourceApi, CoreApp, urlUtil } from '@grafana/data'; import { reportMetaAnalytics, MetaAnalyticsEventName, DataRequestEventPayload } from '@grafana/runtime'; +import { getDashboardSrv } from '../../dashboard/services/DashboardSrv'; + export function emitDataRequestEvent(datasource: DataSourceApi) { let done = false; diff --git a/public/app/features/query/state/runRequest.test.ts b/public/app/features/query/state/runRequest.test.ts index 8a40ef7fd08..366e0282be9 100644 --- a/public/app/features/query/state/runRequest.test.ts +++ b/public/app/features/query/state/runRequest.test.ts @@ -1,3 +1,5 @@ +import { Observable, Subscriber, Subscription } from 'rxjs'; + import { DataFrame, DataQueryRequest, @@ -8,12 +10,13 @@ import { LoadingState, PanelData, } from '@grafana/data'; -import { Observable, Subscriber, Subscription } from 'rxjs'; -import { runRequest } from './runRequest'; -import { deepFreeze } from '../../../../test/core/redux/reducerTester'; -import { DashboardModel } from '../../dashboard/state/DashboardModel'; import { setEchoSrv } from '@grafana/runtime'; + +import { deepFreeze } from '../../../../test/core/redux/reducerTester'; import { Echo } from '../../../core/services/echo/Echo'; +import { DashboardModel } from '../../dashboard/state/DashboardModel'; + +import { runRequest } from './runRequest'; jest.mock('app/core/services/backend_srv'); diff --git a/public/app/features/query/state/runRequest.ts b/public/app/features/query/state/runRequest.ts index 76a7442ab3f..768262916f7 100644 --- a/public/app/features/query/state/runRequest.ts +++ b/public/app/features/query/state/runRequest.ts @@ -1,9 +1,9 @@ // Libraries -import { from, merge, Observable, of, timer } from 'rxjs'; import { isString, map as isArray } from 'lodash'; +import { from, merge, Observable, of, timer } from 'rxjs'; import { catchError, map, mapTo, share, takeUntil, tap } from 'rxjs/operators'; + // Utils & Services -import { backendSrv } from 'app/core/services/backend_srv'; // Types import { DataFrame, @@ -21,11 +21,13 @@ import { toDataFrame, } from '@grafana/data'; import { toDataQueryError } from '@grafana/runtime'; -import { emitDataRequestEvent } from './queryAnalytics'; +import { isExpressionReference } from '@grafana/runtime/src/utils/DataSourceWithBackend'; +import { backendSrv } from 'app/core/services/backend_srv'; import { dataSource as expressionDatasource } from 'app/features/expressions/ExpressionDatasource'; import { ExpressionQuery } from 'app/features/expressions/types'; + import { cancelNetworkRequestsOnUnsubscribe } from './processing/canceler'; -import { isExpressionReference } from '@grafana/runtime/src/utils/DataSourceWithBackend'; +import { emitDataRequestEvent } from './queryAnalytics'; type MapOfResponsePackets = { [str: string]: DataQueryResponse }; diff --git a/public/app/features/query/state/updateQueries.test.ts b/public/app/features/query/state/updateQueries.test.ts index f4f8a2de817..ad87cb3be9d 100644 --- a/public/app/features/query/state/updateQueries.test.ts +++ b/public/app/features/query/state/updateQueries.test.ts @@ -5,6 +5,7 @@ import { DataSourceWithQueryImportSupport, } from '@grafana/data'; import { ExpressionDatasourceRef } from '@grafana/runtime/src/utils/DataSourceWithBackend'; + import { updateQueries } from './updateQueries'; const oldUidDS = { diff --git a/public/app/features/sandbox/BenchmarksPage.tsx b/public/app/features/sandbox/BenchmarksPage.tsx index ace7740745d..d8813fdbf78 100644 --- a/public/app/features/sandbox/BenchmarksPage.tsx +++ b/public/app/features/sandbox/BenchmarksPage.tsx @@ -1,6 +1,7 @@ -import { EmotionPerfTest, VerticalGroup } from '@grafana/ui'; import React, { FC } from 'react'; +import { EmotionPerfTest, VerticalGroup } from '@grafana/ui'; + export const BenchmarksPage: FC = () => { return ( diff --git a/public/app/features/sandbox/TestStuffPage.tsx b/public/app/features/sandbox/TestStuffPage.tsx index 7da9e64ac90..7d34b5a9e4e 100644 --- a/public/app/features/sandbox/TestStuffPage.tsx +++ b/public/app/features/sandbox/TestStuffPage.tsx @@ -1,3 +1,7 @@ +import React, { FC, useMemo, useState } from 'react'; +import { useObservable } from 'react-use'; +import AutoSizer from 'react-virtualized-auto-sizer'; + import { ApplyFieldOverrideOptions, DataTransformerConfig, @@ -8,15 +12,13 @@ import { } from '@grafana/data'; import { Button, Table } from '@grafana/ui'; import { config } from 'app/core/config'; -import React, { FC, useMemo, useState } from 'react'; -import { useObservable } from 'react-use'; +import { useAppNotification } from 'app/core/copy/appNotification'; +import { QueryGroupOptions } from 'app/types'; + +import Page from '../../core/components/Page/Page'; +import { PanelRenderer } from '../panel/components/PanelRenderer'; import { QueryGroup } from '../query/components/QueryGroup'; import { PanelQueryRunner } from '../query/state/PanelQueryRunner'; -import { QueryGroupOptions } from 'app/types'; -import Page from '../../core/components/Page/Page'; -import AutoSizer from 'react-virtualized-auto-sizer'; -import { PanelRenderer } from '../panel/components/PanelRenderer'; -import { useAppNotification } from 'app/core/copy/appNotification'; interface State { queryRunner: PanelQueryRunner; diff --git a/public/app/features/search/components/ActionRow.tsx b/public/app/features/search/components/ActionRow.tsx index dc6d0af3294..ef9c5d13c65 100644 --- a/public/app/features/search/components/ActionRow.tsx +++ b/public/app/features/search/components/ActionRow.tsx @@ -1,12 +1,14 @@ -import React, { FC, ChangeEvent, FormEvent } from 'react'; import { css } from '@emotion/css'; -import { HorizontalGroup, RadioButtonGroup, stylesFactory, useTheme, Checkbox, InlineSwitch } from '@grafana/ui'; +import React, { FC, ChangeEvent, FormEvent } from 'react'; + import { GrafanaTheme, SelectableValue } from '@grafana/data'; +import { config } from '@grafana/runtime'; +import { HorizontalGroup, RadioButtonGroup, stylesFactory, useTheme, Checkbox, InlineSwitch } from '@grafana/ui'; import { SortPicker } from 'app/core/components/Select/SortPicker'; import { TagFilter } from 'app/core/components/TagFilter/TagFilter'; import { SearchSrv } from 'app/core/services/search_srv'; + import { DashboardQuery, SearchLayout } from '../types'; -import { config } from '@grafana/runtime'; export const layoutOptions = [ { value: SearchLayout.Folders, icon: 'folder', ariaLabel: 'View by folders' }, diff --git a/public/app/features/search/components/ConfirmDeleteModal.tsx b/public/app/features/search/components/ConfirmDeleteModal.tsx index d4882e1a2eb..2a5e7fcc61a 100644 --- a/public/app/features/search/components/ConfirmDeleteModal.tsx +++ b/public/app/features/search/components/ConfirmDeleteModal.tsx @@ -1,10 +1,12 @@ -import React, { FC } from 'react'; import { css } from '@emotion/css'; +import React, { FC } from 'react'; + import { GrafanaTheme } from '@grafana/data'; import { ConfirmModal, stylesFactory, useTheme } from '@grafana/ui'; +import { deleteFoldersAndDashboards } from 'app/features/manage-dashboards/state/actions'; + import { DashboardSection, OnDeleteItems } from '../types'; import { getCheckedUids } from '../utils'; -import { deleteFoldersAndDashboards } from 'app/features/manage-dashboards/state/actions'; interface Props { onDeleteItems: OnDeleteItems; diff --git a/public/app/features/search/components/DashboardActions.tsx b/public/app/features/search/components/DashboardActions.tsx index f7b2acc2c25..95b8f6e04b9 100644 --- a/public/app/features/search/components/DashboardActions.tsx +++ b/public/app/features/search/components/DashboardActions.tsx @@ -1,4 +1,5 @@ import React, { FC } from 'react'; + import { HorizontalGroup, LinkButton } from '@grafana/ui'; export interface Props { diff --git a/public/app/features/search/components/DashboardListPage.tsx b/public/app/features/search/components/DashboardListPage.tsx index 3bf90987135..5e28073914d 100644 --- a/public/app/features/search/components/DashboardListPage.tsx +++ b/public/app/features/search/components/DashboardListPage.tsx @@ -1,14 +1,17 @@ import React, { FC, memo } from 'react'; -import { useAsync } from 'react-use'; import { connect, MapStateToProps } from 'react-redux'; +import { useAsync } from 'react-use'; + import { NavModel, locationUtil } from '@grafana/data'; import { locationService } from '@grafana/runtime'; -import { FolderDTO, StoreState } from 'app/types'; -import { getNavModel } from 'app/core/selectors/navModel'; import Page from 'app/core/components/Page/Page'; -import { loadFolderPage } from '../loaders'; -import ManageDashboards from './ManageDashboards'; +import { getNavModel } from 'app/core/selectors/navModel'; +import { FolderDTO, StoreState } from 'app/types'; + import { GrafanaRouteComponentProps } from '../../../core/navigation/types'; +import { loadFolderPage } from '../loaders'; + +import ManageDashboards from './ManageDashboards'; export interface DashboardListPageRouteParams { uid?: string; diff --git a/public/app/features/search/components/DashboardSearch.test.tsx b/public/app/features/search/components/DashboardSearch.test.tsx index 8004154fc21..0ead5d5cc4c 100644 --- a/public/app/features/search/components/DashboardSearch.test.tsx +++ b/public/app/features/search/components/DashboardSearch.test.tsx @@ -1,15 +1,17 @@ -import React from 'react'; import { act, fireEvent, render, screen, waitFor } from '@testing-library/react'; +import React from 'react'; + +import { selectors } from '@grafana/e2e-selectors'; import { locationService, setEchoSrv } from '@grafana/runtime'; import { selectOptionInTest } from '@grafana/ui'; -import { selectors } from '@grafana/e2e-selectors'; - -import * as SearchSrv from 'app/core/services/search_srv'; import * as MockSearchSrv from 'app/core/services/__mocks__/search_srv'; -import { DashboardSearch, Props } from './DashboardSearch'; +import { Echo } from 'app/core/services/echo/Echo'; +import * as SearchSrv from 'app/core/services/search_srv'; + import { searchResults } from '../testData'; import { SearchLayout } from '../types'; -import { Echo } from 'app/core/services/echo/Echo'; + +import { DashboardSearch, Props } from './DashboardSearch'; jest.mock('app/core/services/search_srv'); // Typecast the mock search so the mock import is correctly recognised by TS diff --git a/public/app/features/search/components/DashboardSearch.tsx b/public/app/features/search/components/DashboardSearch.tsx index 1864459e715..da60871d749 100644 --- a/public/app/features/search/components/DashboardSearch.tsx +++ b/public/app/features/search/components/DashboardSearch.tsx @@ -1,13 +1,16 @@ -import React, { FC, memo } from 'react'; import { css } from '@emotion/css'; -import { CustomScrollbar, IconButton, stylesFactory, useTheme2 } from '@grafana/ui'; +import React, { FC, memo } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; -import { useSearchQuery } from '../hooks/useSearchQuery'; +import { CustomScrollbar, IconButton, stylesFactory, useTheme2 } from '@grafana/ui'; + import { useDashboardSearch } from '../hooks/useDashboardSearch'; -import { SearchField } from './SearchField'; -import { SearchResults } from './SearchResults'; +import { useSearchQuery } from '../hooks/useSearchQuery'; + import { ActionRow } from './ActionRow'; import { PreviewsSystemRequirements } from './PreviewsSystemRequirements'; +import { SearchField } from './SearchField'; +import { SearchResults } from './SearchResults'; export interface Props { onCloseSearch: () => void; diff --git a/public/app/features/search/components/ManageDashboards.tsx b/public/app/features/search/components/ManageDashboards.tsx index 6f3b46b7c3b..0a5737ae657 100644 --- a/public/app/features/search/components/ManageDashboards.tsx +++ b/public/app/features/search/components/ManageDashboards.tsx @@ -1,18 +1,21 @@ -import React, { FC, memo, useState } from 'react'; import { css } from '@emotion/css'; -import { FilterInput, Spinner, stylesFactory, useTheme } from '@grafana/ui'; +import React, { FC, memo, useState } from 'react'; + import { GrafanaTheme } from '@grafana/data'; -import { contextSrv } from 'app/core/services/context_srv'; +import { FilterInput, Spinner, stylesFactory, useTheme } from '@grafana/ui'; import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA'; +import { contextSrv } from 'app/core/services/context_srv'; import { FolderDTO } from 'app/types'; + import { useManageDashboards } from '../hooks/useManageDashboards'; -import { SearchLayout } from '../types'; -import { ConfirmDeleteModal } from './ConfirmDeleteModal'; -import { MoveToFolderModal } from './MoveToFolderModal'; import { useSearchQuery } from '../hooks/useSearchQuery'; -import { SearchResultsFilter } from './SearchResultsFilter'; -import { SearchResults } from './SearchResults'; +import { SearchLayout } from '../types'; + +import { ConfirmDeleteModal } from './ConfirmDeleteModal'; import { DashboardActions } from './DashboardActions'; +import { MoveToFolderModal } from './MoveToFolderModal'; +import { SearchResults } from './SearchResults'; +import { SearchResultsFilter } from './SearchResultsFilter'; export interface Props { folder?: FolderDTO; diff --git a/public/app/features/search/components/MoveToFolderModal.tsx b/public/app/features/search/components/MoveToFolderModal.tsx index dac46e5ae31..b850f9462ba 100644 --- a/public/app/features/search/components/MoveToFolderModal.tsx +++ b/public/app/features/search/components/MoveToFolderModal.tsx @@ -1,13 +1,15 @@ -import React, { FC, useState } from 'react'; import { css } from '@emotion/css'; -import { Button, HorizontalGroup, Modal, stylesFactory, useTheme } from '@grafana/ui'; +import React, { FC, useState } from 'react'; + import { GrafanaTheme } from '@grafana/data'; -import { FolderInfo } from 'app/types'; +import { Button, HorizontalGroup, Modal, stylesFactory, useTheme } from '@grafana/ui'; import { FolderPicker } from 'app/core/components/Select/FolderPicker'; import { useAppNotification } from 'app/core/copy/appNotification'; +import { moveDashboards } from 'app/features/manage-dashboards/state/actions'; +import { FolderInfo } from 'app/types'; + import { DashboardSection, OnMoveItems } from '../types'; import { getCheckedDashboards } from '../utils'; -import { moveDashboards } from 'app/features/manage-dashboards/state/actions'; interface Props { onMoveItems: OnMoveItems; diff --git a/public/app/features/search/components/PreviewsSystemRequirements.tsx b/public/app/features/search/components/PreviewsSystemRequirements.tsx index 0e023c4e138..c3ba284c01b 100644 --- a/public/app/features/search/components/PreviewsSystemRequirements.tsx +++ b/public/app/features/search/components/PreviewsSystemRequirements.tsx @@ -1,7 +1,8 @@ -import { Alert, useStyles2 } from '@grafana/ui'; -import React from 'react'; -import { config } from '@grafana/runtime/src'; import { css } from '@emotion/css'; +import React from 'react'; + +import { config } from '@grafana/runtime/src'; +import { Alert, useStyles2 } from '@grafana/ui'; export interface Props { showPreviews?: boolean; diff --git a/public/app/features/search/components/SearchCard.tsx b/public/app/features/search/components/SearchCard.tsx index 12a2d3e55a8..862c3deefc8 100644 --- a/public/app/features/search/components/SearchCard.tsx +++ b/public/app/features/search/components/SearchCard.tsx @@ -1,13 +1,16 @@ -import React, { useCallback, useRef, useState } from 'react'; import { css } from '@emotion/css'; +import React, { useCallback, useRef, useState } from 'react'; import { usePopper } from 'react-popper'; + import { GrafanaTheme2 } from '@grafana/data'; -import { Icon, Portal, TagList, useTheme2 } from '@grafana/ui'; import { selectors } from '@grafana/e2e-selectors'; +import { Icon, Portal, TagList, useTheme2 } from '@grafana/ui'; import { backendSrv } from 'app/core/services/backend_srv'; + import { DashboardSectionItem, OnToggleChecked } from '../types'; -import { SearchCheckbox } from './SearchCheckbox'; + import { SearchCardExpanded } from './SearchCardExpanded'; +import { SearchCheckbox } from './SearchCheckbox'; const DELAY_BEFORE_EXPANDING = 500; diff --git a/public/app/features/search/components/SearchCardExpanded.tsx b/public/app/features/search/components/SearchCardExpanded.tsx index 350e2b54347..548cce70706 100644 --- a/public/app/features/search/components/SearchCardExpanded.tsx +++ b/public/app/features/search/components/SearchCardExpanded.tsx @@ -1,9 +1,12 @@ -import React, { useState } from 'react'; import { css } from '@emotion/css'; import classNames from 'classnames'; +import React, { useState } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { Icon, Spinner, TagList, useTheme2 } from '@grafana/ui'; + import { DashboardSectionItem } from '../types'; + import { getThumbnailURL } from './SearchCard'; export interface Props { diff --git a/public/app/features/search/components/SearchCheckbox.tsx b/public/app/features/search/components/SearchCheckbox.tsx index a06703bfa28..d4c669aed49 100644 --- a/public/app/features/search/components/SearchCheckbox.tsx +++ b/public/app/features/search/components/SearchCheckbox.tsx @@ -1,4 +1,5 @@ import React, { FC, memo } from 'react'; + import { Checkbox } from '@grafana/ui'; interface Props { diff --git a/public/app/features/search/components/SearchField.tsx b/public/app/features/search/components/SearchField.tsx index 17272480c08..274fa528a31 100644 --- a/public/app/features/search/components/SearchField.tsx +++ b/public/app/features/search/components/SearchField.tsx @@ -1,9 +1,11 @@ -import React, { FC } from 'react'; import { css, cx } from '@emotion/css'; +import React, { FC } from 'react'; + import { GrafanaTheme } from '@grafana/data'; -import { DashboardQuery } from '../types'; import { useStyles } from '@grafana/ui'; +import { DashboardQuery } from '../types'; + type Omit = Pick>; interface SearchFieldProps extends Omit, 'onChange'> { diff --git a/public/app/features/search/components/SearchItem.test.tsx b/public/app/features/search/components/SearchItem.test.tsx index 7e9744e1400..822b3c14c13 100644 --- a/public/app/features/search/components/SearchItem.test.tsx +++ b/public/app/features/search/components/SearchItem.test.tsx @@ -1,10 +1,12 @@ -import React from 'react'; import { fireEvent, render, screen } from '@testing-library/react'; +import React from 'react'; + import { selectors } from '@grafana/e2e-selectors'; -import { Props, SearchItem } from './SearchItem'; import { DashboardSearchItemType } from '../types'; +import { Props, SearchItem } from './SearchItem'; + beforeEach(() => { jest.clearAllMocks(); }); diff --git a/public/app/features/search/components/SearchItem.tsx b/public/app/features/search/components/SearchItem.tsx index 920bd52e1f8..d2eefa9654d 100644 --- a/public/app/features/search/components/SearchItem.tsx +++ b/public/app/features/search/components/SearchItem.tsx @@ -1,11 +1,14 @@ -import React, { FC, useCallback } from 'react'; import { css } from '@emotion/css'; +import React, { FC, useCallback } from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; import { selectors as e2eSelectors } from '@grafana/e2e-selectors'; import { Card, Icon, IconName, TagList, useStyles2 } from '@grafana/ui'; -import { GrafanaTheme2 } from '@grafana/data'; -import { DashboardSectionItem, OnToggleChecked } from '../types'; -import { SearchCheckbox } from './SearchCheckbox'; + import { SEARCH_ITEM_HEIGHT } from '../constants'; +import { DashboardSectionItem, OnToggleChecked } from '../types'; + +import { SearchCheckbox } from './SearchCheckbox'; export interface Props { item: DashboardSectionItem; diff --git a/public/app/features/search/components/SearchResults.test.tsx b/public/app/features/search/components/SearchResults.test.tsx index ba249df1811..2b307496b25 100644 --- a/public/app/features/search/components/SearchResults.test.tsx +++ b/public/app/features/search/components/SearchResults.test.tsx @@ -1,11 +1,13 @@ -import React from 'react'; import { fireEvent, render, screen } from '@testing-library/react'; +import React from 'react'; + import { selectors } from '@grafana/e2e-selectors'; -import { Props, SearchResults } from './SearchResults'; import { generalFolder, searchResults } from '../testData'; import { SearchLayout } from '../types'; +import { Props, SearchResults } from './SearchResults'; + beforeEach(() => { jest.clearAllMocks(); }); diff --git a/public/app/features/search/components/SearchResults.tsx b/public/app/features/search/components/SearchResults.tsx index bc5da39620f..cafddc351c3 100644 --- a/public/app/features/search/components/SearchResults.tsx +++ b/public/app/features/search/components/SearchResults.tsx @@ -1,14 +1,17 @@ -import React, { FC, memo } from 'react'; import { css, cx } from '@emotion/css'; -import { FixedSizeList, FixedSizeGrid } from 'react-window'; +import React, { FC, memo } from 'react'; import AutoSizer from 'react-virtualized-auto-sizer'; +import { FixedSizeList, FixedSizeGrid } from 'react-window'; + import { GrafanaTheme } from '@grafana/data'; -import { Spinner, stylesFactory, useTheme } from '@grafana/ui'; import { selectors } from '@grafana/e2e-selectors'; -import { DashboardSection, OnToggleChecked, SearchLayout } from '../types'; +import { Spinner, stylesFactory, useTheme } from '@grafana/ui'; + import { SEARCH_ITEM_HEIGHT, SEARCH_ITEM_MARGIN } from '../constants'; -import { SearchItem } from './SearchItem'; +import { DashboardSection, OnToggleChecked, SearchLayout } from '../types'; + import { SearchCard } from './SearchCard'; +import { SearchItem } from './SearchItem'; import { SectionHeader } from './SectionHeader'; export interface Props { diff --git a/public/app/features/search/components/SearchResultsFilter.test.tsx b/public/app/features/search/components/SearchResultsFilter.test.tsx index e88ce063da2..991e0d8bf53 100644 --- a/public/app/features/search/components/SearchResultsFilter.test.tsx +++ b/public/app/features/search/components/SearchResultsFilter.test.tsx @@ -1,9 +1,12 @@ -import React from 'react'; import { fireEvent, render, screen } from '@testing-library/react'; +import React from 'react'; + import { selectOptionInTest } from '@grafana/ui'; -import { Props, SearchResultsFilter } from './SearchResultsFilter'; + import { SearchLayout } from '../types'; +import { Props, SearchResultsFilter } from './SearchResultsFilter'; + jest.mock('app/core/services/search_srv'); const noop = jest.fn(); diff --git a/public/app/features/search/components/SearchResultsFilter.tsx b/public/app/features/search/components/SearchResultsFilter.tsx index 7a8b43b9ba7..51ec8d7ffcf 100644 --- a/public/app/features/search/components/SearchResultsFilter.tsx +++ b/public/app/features/search/components/SearchResultsFilter.tsx @@ -1,8 +1,11 @@ -import React, { FC, FormEvent } from 'react'; import { css } from '@emotion/css'; -import { Button, Checkbox, stylesFactory, useTheme, HorizontalGroup } from '@grafana/ui'; +import React, { FC, FormEvent } from 'react'; + import { GrafanaTheme, SelectableValue } from '@grafana/data'; +import { Button, Checkbox, stylesFactory, useTheme, HorizontalGroup } from '@grafana/ui'; + import { DashboardQuery, SearchLayout } from '../types'; + import { ActionRow } from './ActionRow'; import { PreviewsSystemRequirements } from './PreviewsSystemRequirements'; diff --git a/public/app/features/search/components/SearchWrapper.tsx b/public/app/features/search/components/SearchWrapper.tsx index b98771fdc21..506f8944ef9 100644 --- a/public/app/features/search/components/SearchWrapper.tsx +++ b/public/app/features/search/components/SearchWrapper.tsx @@ -1,8 +1,11 @@ import React, { FC, memo } from 'react'; -import DashboardSearch from './DashboardSearch'; + import { useUrlParams } from 'app/core/navigation/hooks'; + import { defaultQueryParams } from '../reducers/searchQueryReducer'; +import DashboardSearch from './DashboardSearch'; + export const SearchWrapper: FC = memo(() => { const [params, updateUrlParams] = useUrlParams(); const isOpen = params.get('search') === 'open'; diff --git a/public/app/features/search/components/SectionHeader.tsx b/public/app/features/search/components/SectionHeader.tsx index 685babe2379..43b418985a3 100644 --- a/public/app/features/search/components/SectionHeader.tsx +++ b/public/app/features/search/components/SectionHeader.tsx @@ -1,13 +1,15 @@ -import React, { FC, useCallback } from 'react'; import { css, cx } from '@emotion/css'; +import React, { FC, useCallback } from 'react'; import { useLocalStorage } from 'react-use'; + import { GrafanaTheme } from '@grafana/data'; import { CollapsableSection, Icon, stylesFactory, useTheme } from '@grafana/ui'; +import { useUniqueId } from 'app/plugins/datasource/influxdb/components/useUniqueId'; import { DashboardSection, OnToggleChecked } from '../types'; -import { SearchCheckbox } from './SearchCheckbox'; import { getSectionIcon, getSectionStorageKey } from '../utils'; -import { useUniqueId } from 'app/plugins/datasource/influxdb/components/useUniqueId'; + +import { SearchCheckbox } from './SearchCheckbox'; interface SectionHeaderProps { editable?: boolean; diff --git a/public/app/features/search/hooks/useDashboardSearch.ts b/public/app/features/search/hooks/useDashboardSearch.ts index c3b7434f002..96267739453 100644 --- a/public/app/features/search/hooks/useDashboardSearch.ts +++ b/public/app/features/search/hooks/useDashboardSearch.ts @@ -1,14 +1,17 @@ import { KeyboardEvent, useReducer } from 'react'; +import { useDebounce } from 'react-use'; + +import { locationUtil } from '@grafana/data'; import { locationService } from '@grafana/runtime'; -import { DashboardQuery, DashboardSearchItemType, DashboardSection } from '../types'; + import { MOVE_SELECTION_DOWN, MOVE_SELECTION_UP } from '../reducers/actionTypes'; import { dashboardsSearchState, DashboardsSearchState, searchReducer } from '../reducers/dashboardSearch'; +import { DashboardQuery, DashboardSearchItemType, DashboardSection } from '../types'; import { findSelected } from '../utils'; -import { useSearch } from './useSearch'; -import { locationUtil } from '@grafana/data'; -import { useShowDashboardPreviews } from './useShowDashboardPreviews'; + import { reportDashboardListViewed } from './useManageDashboards'; -import { useDebounce } from 'react-use'; +import { useSearch } from './useSearch'; +import { useShowDashboardPreviews } from './useShowDashboardPreviews'; export const useDashboardSearch = (query: DashboardQuery, onCloseSearch: () => void) => { const reducer = useReducer(searchReducer, dashboardsSearchState); diff --git a/public/app/features/search/hooks/useManageDashboards.test.ts b/public/app/features/search/hooks/useManageDashboards.test.ts index a75c9957e1a..6c2dd608b0b 100644 --- a/public/app/features/search/hooks/useManageDashboards.test.ts +++ b/public/app/features/search/hooks/useManageDashboards.test.ts @@ -1,14 +1,16 @@ -import { Dispatch } from 'react'; import { renderHook } from '@testing-library/react-hooks'; +import { Dispatch } from 'react'; -import * as useSearch from './useSearch'; -import { DashboardQuery, DashboardSearchItemType, DashboardSection, SearchAction } from '../types'; -import { ManageDashboardsState } from '../reducers/manageDashboards'; -import { useManageDashboards } from './useManageDashboards'; -import { GENERAL_FOLDER_ID } from '../constants'; import { setEchoSrv } from '@grafana/runtime/src'; import { Echo } from 'app/core/services/echo/Echo'; +import { GENERAL_FOLDER_ID } from '../constants'; +import { ManageDashboardsState } from '../reducers/manageDashboards'; +import { DashboardQuery, DashboardSearchItemType, DashboardSection, SearchAction } from '../types'; + +import { useManageDashboards } from './useManageDashboards'; +import * as useSearch from './useSearch'; + describe('useManageDashboards', () => { const useSearchMock = jest.spyOn(useSearch, 'useSearch'); const toggle = async (section: DashboardSection) => section; diff --git a/public/app/features/search/hooks/useManageDashboards.ts b/public/app/features/search/hooks/useManageDashboards.ts index caa971f5b8f..bf55d4ff11f 100644 --- a/public/app/features/search/hooks/useManageDashboards.ts +++ b/public/app/features/search/hooks/useManageDashboards.ts @@ -1,14 +1,17 @@ import { useCallback, useMemo, useReducer } from 'react'; -import { FolderDTO } from 'app/types'; +import { useDebounce } from 'react-use'; + +import { reportInteraction } from '@grafana/runtime/src'; import { contextSrv } from 'app/core/services/context_srv'; -import { DashboardQuery, DashboardSection, OnDeleteItems, OnMoveItems, OnToggleChecked, SearchLayout } from '../types'; +import { FolderDTO } from 'app/types'; + +import { GENERAL_FOLDER_ID } from '../constants'; import { DELETE_ITEMS, MOVE_ITEMS, TOGGLE_ALL_CHECKED, TOGGLE_CHECKED } from '../reducers/actionTypes'; import { manageDashboardsReducer, manageDashboardsState, ManageDashboardsState } from '../reducers/manageDashboards'; +import { DashboardQuery, DashboardSection, OnDeleteItems, OnMoveItems, OnToggleChecked, SearchLayout } from '../types'; + import { useSearch } from './useSearch'; -import { GENERAL_FOLDER_ID } from '../constants'; import { useShowDashboardPreviews } from './useShowDashboardPreviews'; -import { reportInteraction } from '@grafana/runtime/src'; -import { useDebounce } from 'react-use'; const hasChecked = (section: DashboardSection) => { return section.checked || section.items.some((item) => item.checked); diff --git a/public/app/features/search/hooks/useSearch.ts b/public/app/features/search/hooks/useSearch.ts index cc138226294..fda96885d65 100644 --- a/public/app/features/search/hooks/useSearch.ts +++ b/public/app/features/search/hooks/useSearch.ts @@ -1,7 +1,9 @@ import { useCallback, useEffect } from 'react'; import { useDebounce } from 'react-use'; -import { SearchSrv } from 'app/core/services/search_srv'; + import { backendSrv } from 'app/core/services/backend_srv'; +import { SearchSrv } from 'app/core/services/search_srv'; + import { FETCH_RESULTS, FETCH_ITEMS, TOGGLE_SECTION, SEARCH_START, FETCH_ITEMS_START } from '../reducers/actionTypes'; import { DashboardSection, UseSearch } from '../types'; import { hasId, getParsedQuery } from '../utils'; diff --git a/public/app/features/search/hooks/useSearchQuery.ts b/public/app/features/search/hooks/useSearchQuery.ts index 64ec9e8b075..9b425e1066d 100644 --- a/public/app/features/search/hooks/useSearchQuery.ts +++ b/public/app/features/search/hooks/useSearchQuery.ts @@ -1,8 +1,9 @@ -import { FormEvent, useCallback, useReducer } from 'react'; import { debounce } from 'lodash'; +import { FormEvent, useCallback, useReducer } from 'react'; + import { SelectableValue } from '@grafana/data'; import { locationService } from '@grafana/runtime'; -import { defaultQuery, defaultQueryParams, queryReducer } from '../reducers/searchQueryReducer'; + import { ADD_TAG, CLEAR_FILTERS, @@ -13,6 +14,7 @@ import { TOGGLE_STARRED, DATASOURCE_CHANGE, } from '../reducers/actionTypes'; +import { defaultQuery, defaultQueryParams, queryReducer } from '../reducers/searchQueryReducer'; import { DashboardQuery, SearchLayout } from '../types'; import { hasFilters, parseRouteParams } from '../utils'; diff --git a/public/app/features/search/hooks/useShowDashboardPreviews.ts b/public/app/features/search/hooks/useShowDashboardPreviews.ts index e15780fff6d..ebddd8b607b 100644 --- a/public/app/features/search/hooks/useShowDashboardPreviews.ts +++ b/public/app/features/search/hooks/useShowDashboardPreviews.ts @@ -1,7 +1,9 @@ -import { PREVIEWS_LOCAL_STORAGE_KEY } from '../constants'; -import { config } from '@grafana/runtime/src'; import { useLocalStorage } from 'react-use'; +import { config } from '@grafana/runtime/src'; + +import { PREVIEWS_LOCAL_STORAGE_KEY } from '../constants'; + export const useShowDashboardPreviews = () => { const previewFeatureEnabled = Boolean(config.featureToggles.dashboardPreviews); const [showPreviews, setShowPreviews] = useLocalStorage(PREVIEWS_LOCAL_STORAGE_KEY, previewFeatureEnabled); diff --git a/public/app/features/search/loaders.ts b/public/app/features/search/loaders.ts index 98df76a95b6..0edaf223072 100644 --- a/public/app/features/search/loaders.ts +++ b/public/app/features/search/loaders.ts @@ -1,4 +1,5 @@ import { backendSrv } from 'app/core/services/backend_srv'; + import { buildNavModel } from '../folders/state/navModel'; export const loadFolderPage = (uid: string) => { diff --git a/public/app/features/search/page/SearchPage.tsx b/public/app/features/search/page/SearchPage.tsx index 923f677bc43..58712813895 100644 --- a/public/app/features/search/page/SearchPage.tsx +++ b/public/app/features/search/page/SearchPage.tsx @@ -1,17 +1,19 @@ -import React from 'react'; -import { GrafanaTheme2, NavModelItem } from '@grafana/data'; -import { Input, useStyles2, Spinner, Button } from '@grafana/ui'; -import { config } from '@grafana/runtime'; -import AutoSizer from 'react-virtualized-auto-sizer'; import { css } from '@emotion/css'; - -import Page from 'app/core/components/Page/Page'; +import React from 'react'; import { useAsync } from 'react-use'; -import { getGrafanaSearcher, QueryFilters } from '../service'; -import { Table } from './table/Table'; +import AutoSizer from 'react-virtualized-auto-sizer'; + +import { GrafanaTheme2, NavModelItem } from '@grafana/data'; +import { config } from '@grafana/runtime'; +import { Input, useStyles2, Spinner, Button } from '@grafana/ui'; +import Page from 'app/core/components/Page/Page'; import { TagFilter, TermCount } from 'app/core/components/TagFilter/TagFilter'; -import { getTermCounts } from '../service/backend'; + import { useSearchQuery } from '../hooks/useSearchQuery'; +import { getGrafanaSearcher, QueryFilters } from '../service'; +import { getTermCounts } from '../service/backend'; + +import { Table } from './table/Table'; const node: NavModelItem = { id: 'search', diff --git a/public/app/features/search/page/table/Table.tsx b/public/app/features/search/page/table/Table.tsx index e28e17fa222..ab3afd8918e 100644 --- a/public/app/features/search/page/table/Table.tsx +++ b/public/app/features/search/page/table/Table.tsx @@ -1,13 +1,15 @@ +import { css } from '@emotion/css'; import React, { useMemo } from 'react'; import { useTable, Column, TableOptions, Cell, useAbsoluteLayout } from 'react-table'; -import { DataFrame, DataFrameType, DataFrameView, DataSourceRef, Field, GrafanaTheme2 } from '@grafana/data'; -import { css } from '@emotion/css'; import { FixedSizeList } from 'react-window'; + +import { DataFrame, DataFrameType, DataFrameView, DataSourceRef, Field, GrafanaTheme2 } from '@grafana/data'; +import { useStyles2 } from '@grafana/ui'; import { TableCell } from '@grafana/ui/src/components/Table/TableCell'; import { getTableStyles } from '@grafana/ui/src/components/Table/styles'; -import { useStyles2 } from '@grafana/ui'; import { LocationInfo } from '../../service'; + import { generateColumns } from './columns'; type Props = { diff --git a/public/app/features/search/page/table/columns.tsx b/public/app/features/search/page/table/columns.tsx index 5edab606248..7c65b721ee3 100644 --- a/public/app/features/search/page/table/columns.tsx +++ b/public/app/features/search/page/table/columns.tsx @@ -1,13 +1,15 @@ import React from 'react'; +import SVG from 'react-inlinesvg'; + import { DataFrameView, DataSourceRef, Field } from '@grafana/data'; import { config, getDataSourceSrv } from '@grafana/runtime'; -import SVG from 'react-inlinesvg'; import { Checkbox, Icon, IconName, TagList } from '@grafana/ui'; import { DefaultCell } from '@grafana/ui/src/components/Table/DefaultCell'; -import { FieldAccess, TableColumn } from './Table'; import { LocationInfo } from '../../service'; +import { FieldAccess, TableColumn } from './Table'; + export const generateColumns = ( data: DataFrameView, isDashboardList: boolean, diff --git a/public/app/features/search/reducers/dashboardSearch.test.ts b/public/app/features/search/reducers/dashboardSearch.test.ts index fc47dfd5435..5f5ebf182ec 100644 --- a/public/app/features/search/reducers/dashboardSearch.test.ts +++ b/public/app/features/search/reducers/dashboardSearch.test.ts @@ -1,6 +1,7 @@ +import { searchResults, sections } from '../testData'; + import { FETCH_ITEMS, FETCH_RESULTS, TOGGLE_SECTION, MOVE_SELECTION_DOWN, MOVE_SELECTION_UP } from './actionTypes'; import { searchReducer as reducer, dashboardsSearchState } from './dashboardSearch'; -import { searchResults, sections } from '../testData'; const defaultState = { selectedIndex: 0, loading: false, results: sections as any[], initialLoading: false }; describe('Dashboard Search reducer', () => { diff --git a/public/app/features/search/reducers/dashboardSearch.ts b/public/app/features/search/reducers/dashboardSearch.ts index 6c887960110..182b1ba4e5d 100644 --- a/public/app/features/search/reducers/dashboardSearch.ts +++ b/public/app/features/search/reducers/dashboardSearch.ts @@ -1,5 +1,6 @@ import { DashboardSection, SearchAction } from '../types'; import { getFlattenedSections, getLookupField, markSelected } from '../utils'; + import { FETCH_ITEMS, FETCH_RESULTS, diff --git a/public/app/features/search/reducers/manageDashboards.test.ts b/public/app/features/search/reducers/manageDashboards.test.ts index e4dfc41a0cb..a005996cf04 100644 --- a/public/app/features/search/reducers/manageDashboards.test.ts +++ b/public/app/features/search/reducers/manageDashboards.test.ts @@ -1,8 +1,9 @@ -import { TOGGLE_ALL_CHECKED, TOGGLE_CHECKED, DELETE_ITEMS, MOVE_ITEMS } from './actionTypes'; -import { manageDashboardsReducer as reducer, manageDashboardsState as state } from './manageDashboards'; import { sections } from '../testData'; import { DashboardSection, UidsToDelete } from '../types'; +import { TOGGLE_ALL_CHECKED, TOGGLE_CHECKED, DELETE_ITEMS, MOVE_ITEMS } from './actionTypes'; +import { manageDashboardsReducer as reducer, manageDashboardsState as state } from './manageDashboards'; + // Remove Recent and Starred sections as they're not used in manage dashboards const results = sections.slice(2); diff --git a/public/app/features/search/reducers/manageDashboards.ts b/public/app/features/search/reducers/manageDashboards.ts index f1467320124..ee58d2f422b 100644 --- a/public/app/features/search/reducers/manageDashboards.ts +++ b/public/app/features/search/reducers/manageDashboards.ts @@ -1,7 +1,8 @@ import { DashboardSection, DashboardSectionItem, SearchAction } from '../types'; +import { mergeReducers } from '../utils'; + import { TOGGLE_ALL_CHECKED, TOGGLE_CHECKED, MOVE_ITEMS, DELETE_ITEMS } from './actionTypes'; import { dashboardsSearchState, DashboardsSearchState, searchReducer } from './dashboardSearch'; -import { mergeReducers } from '../utils'; export interface ManageDashboardsState extends DashboardsSearchState { allChecked: boolean; diff --git a/public/app/features/search/reducers/searchQueryReducer.ts b/public/app/features/search/reducers/searchQueryReducer.ts index 6ba096ae266..9def0ce0de1 100644 --- a/public/app/features/search/reducers/searchQueryReducer.ts +++ b/public/app/features/search/reducers/searchQueryReducer.ts @@ -1,4 +1,5 @@ import { DashboardQuery, SearchQueryParams, SearchAction, SearchLayout } from '../types'; + import { ADD_TAG, CLEAR_FILTERS, diff --git a/public/app/features/search/service/backend.ts b/public/app/features/search/service/backend.ts index 34e4222f350..bd391ef95f7 100644 --- a/public/app/features/search/service/backend.ts +++ b/public/app/features/search/service/backend.ts @@ -1,3 +1,5 @@ +import { lastValueFrom } from 'rxjs'; + import { ArrayVector, DataFrame, @@ -9,11 +11,12 @@ import { Vector, } from '@grafana/data'; import { config, getDataSourceSrv } from '@grafana/runtime'; -import { GrafanaDatasource } from 'app/plugins/datasource/grafana/datasource'; -import { lastValueFrom } from 'rxjs'; -import { GrafanaQueryType } from 'app/plugins/datasource/grafana/types'; import { TermCount } from 'app/core/components/TagFilter/TagFilter'; +import { GrafanaDatasource } from 'app/plugins/datasource/grafana/datasource'; +import { GrafanaQueryType } from 'app/plugins/datasource/grafana/types'; + import { QueryFilters } from './types'; + import { QueryResult } from '.'; // The raw restuls from query server diff --git a/public/app/features/search/service/minisearcher.ts b/public/app/features/search/service/minisearcher.ts index 68db6a10b72..9a7bf738009 100644 --- a/public/app/features/search/service/minisearcher.ts +++ b/public/app/features/search/service/minisearcher.ts @@ -1,11 +1,13 @@ +import { isArray, isString } from 'lodash'; import MiniSearch from 'minisearch'; + import { ArrayVector, DataFrame, DataSourceRef, Field, FieldType, getDisplayProcessor, Vector } from '@grafana/data'; import { config } from '@grafana/runtime'; -import { GrafanaSearcher, QueryFilters, QueryResponse } from './types'; import { filterFrame, getRawIndexData, RawIndexData, rawIndexSupplier } from './backend'; +import { GrafanaSearcher, QueryFilters, QueryResponse } from './types'; + import { LocationInfo } from '.'; -import { isArray, isString } from 'lodash'; export type SearchResultKind = keyof RawIndexData; diff --git a/public/app/features/search/types.ts b/public/app/features/search/types.ts index d7bcebd32da..cb657854ab0 100644 --- a/public/app/features/search/types.ts +++ b/public/app/features/search/types.ts @@ -1,6 +1,8 @@ import { Dispatch } from 'react'; import { Action } from 'redux'; + import { SelectableValue } from '@grafana/data'; + import { FolderInfo } from '../../types'; export enum DashboardSearchItemType { diff --git a/public/app/features/search/utils.test.ts b/public/app/features/search/utils.test.ts index 8f7f3a8af03..cbae358ab69 100644 --- a/public/app/features/search/utils.test.ts +++ b/public/app/features/search/utils.test.ts @@ -1,3 +1,5 @@ +import { sections, searchResults, checkedGeneralFolder, checkedOtherFolder, folderViewAllChecked } from './testData'; +import { SearchQueryParams } from './types'; import { findSelected, getCheckedDashboardsUids, @@ -7,8 +9,6 @@ import { mergeReducers, parseRouteParams, } from './utils'; -import { sections, searchResults, checkedGeneralFolder, checkedOtherFolder, folderViewAllChecked } from './testData'; -import { SearchQueryParams } from './types'; describe('Search utils', () => { describe('getFlattenedSections', () => { diff --git a/public/app/features/search/utils.ts b/public/app/features/search/utils.ts index 3d09fa56265..9d49cca2747 100644 --- a/public/app/features/search/utils.ts +++ b/public/app/features/search/utils.ts @@ -1,10 +1,13 @@ import { parse, SearchParserResult } from 'search-query-parser'; -import { IconName } from '@grafana/ui'; + import { UrlQueryMap } from '@grafana/data'; -import { DashboardQuery, DashboardSection, DashboardSectionItem, SearchAction, UidsToDelete } from './types'; -import { NO_ID_SECTIONS, SECTION_STORAGE_KEY } from './constants'; +import { IconName } from '@grafana/ui'; + import { getDashboardSrv } from '../dashboard/services/DashboardSrv'; +import { NO_ID_SECTIONS, SECTION_STORAGE_KEY } from './constants'; +import { DashboardQuery, DashboardSection, DashboardSectionItem, SearchAction, UidsToDelete } from './types'; + /** * Check if folder has id. Only Recent and Starred folders are the ones without * ids so far, as they are created manually after results are fetched from API. diff --git a/public/app/features/serviceaccounts/CreateServiceAccountTokenModal.tsx b/public/app/features/serviceaccounts/CreateServiceAccountTokenModal.tsx index 5cc322dc664..8823c862d8a 100644 --- a/public/app/features/serviceaccounts/CreateServiceAccountTokenModal.tsx +++ b/public/app/features/serviceaccounts/CreateServiceAccountTokenModal.tsx @@ -1,5 +1,6 @@ -import React, { useState } from 'react'; import { css } from '@emotion/css'; +import React, { useState } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { Button, diff --git a/public/app/features/serviceaccounts/ServiceAccountCreatePage.tsx b/public/app/features/serviceaccounts/ServiceAccountCreatePage.tsx index 2e58ee1faf4..ace8e467279 100644 --- a/public/app/features/serviceaccounts/ServiceAccountCreatePage.tsx +++ b/public/app/features/serviceaccounts/ServiceAccountCreatePage.tsx @@ -1,12 +1,14 @@ import React, { useCallback } from 'react'; import { connect } from 'react-redux'; -import { Form, Button, Input, Field } from '@grafana/ui'; +import { useHistory } from 'react-router-dom'; + import { NavModel } from '@grafana/data'; import { getBackendSrv } from '@grafana/runtime'; -import { StoreState } from '../../types'; -import { getNavModel } from '../../core/selectors/navModel'; +import { Form, Button, Input, Field } from '@grafana/ui'; import Page from 'app/core/components/Page/Page'; -import { useHistory } from 'react-router-dom'; + +import { getNavModel } from '../../core/selectors/navModel'; +import { StoreState } from '../../types'; interface ServiceAccountCreatePageProps { navModel: NavModel; diff --git a/public/app/features/serviceaccounts/ServiceAccountPage.tsx b/public/app/features/serviceaccounts/ServiceAccountPage.tsx index 061e7a0d309..4a5fb5f3963 100644 --- a/public/app/features/serviceaccounts/ServiceAccountPage.tsx +++ b/public/app/features/serviceaccounts/ServiceAccountPage.tsx @@ -1,10 +1,17 @@ import React, { useEffect, useState } from 'react'; import { connect, ConnectedProps } from 'react-redux'; -import { getNavModel } from 'app/core/selectors/navModel'; + +import { getTimeZone, NavModel } from '@grafana/data'; +import { Button } from '@grafana/ui'; import Page from 'app/core/components/Page/Page'; -import { ServiceAccountProfile } from './ServiceAccountProfile'; -import { StoreState, ServiceAccountDTO, ApiKey, Role, AccessControlAction } from 'app/types'; +import { contextSrv } from 'app/core/core'; import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; +import { getNavModel } from 'app/core/selectors/navModel'; +import { StoreState, ServiceAccountDTO, ApiKey, Role, AccessControlAction } from 'app/types'; + +import { CreateTokenModal, ServiceAccountToken } from './CreateServiceAccountTokenModal'; +import { ServiceAccountProfile } from './ServiceAccountProfile'; +import { ServiceAccountTokensTable } from './ServiceAccountTokensTable'; import { deleteServiceAccountToken, loadServiceAccount, @@ -14,11 +21,6 @@ import { updateServiceAccount, deleteServiceAccount, } from './state/actions'; -import { ServiceAccountTokensTable } from './ServiceAccountTokensTable'; -import { getTimeZone, NavModel } from '@grafana/data'; -import { Button } from '@grafana/ui'; -import { CreateTokenModal, ServiceAccountToken } from './CreateServiceAccountTokenModal'; -import { contextSrv } from 'app/core/core'; interface OwnProps extends GrafanaRouteComponentProps<{ id: string }> { navModel: NavModel; diff --git a/public/app/features/serviceaccounts/ServiceAccountProfile.tsx b/public/app/features/serviceaccounts/ServiceAccountProfile.tsx index 368134f9077..e1ab18f7739 100644 --- a/public/app/features/serviceaccounts/ServiceAccountProfile.tsx +++ b/public/app/features/serviceaccounts/ServiceAccountProfile.tsx @@ -1,10 +1,12 @@ -import React, { PureComponent, useRef, useState } from 'react'; -import { Role, ServiceAccountDTO, AccessControlAction } from 'app/types'; import { css, cx } from '@emotion/css'; +import React, { PureComponent, useRef, useState } from 'react'; + import { dateTimeFormat, GrafanaTheme2, OrgRole, TimeZone } from '@grafana/data'; import { Button, ConfirmButton, ConfirmModal, Input, LegacyInputStatus, useStyles2 } from '@grafana/ui'; -import { ServiceAccountRoleRow } from './ServiceAccountRoleRow'; import { contextSrv } from 'app/core/core'; +import { Role, ServiceAccountDTO, AccessControlAction } from 'app/types'; + +import { ServiceAccountRoleRow } from './ServiceAccountRoleRow'; interface Props { serviceAccount: ServiceAccountDTO; diff --git a/public/app/features/serviceaccounts/ServiceAccountRoleRow.tsx b/public/app/features/serviceaccounts/ServiceAccountRoleRow.tsx index 851d4b1298d..ea1d0eb6f57 100644 --- a/public/app/features/serviceaccounts/ServiceAccountRoleRow.tsx +++ b/public/app/features/serviceaccounts/ServiceAccountRoleRow.tsx @@ -1,9 +1,11 @@ -import React, { PureComponent } from 'react'; import { css, cx } from '@emotion/css'; -import { AccessControlAction, OrgRole, Role, ServiceAccountDTO } from 'app/types'; -import { OrgRolePicker } from '../admin/OrgRolePicker'; -import { contextSrv } from 'app/core/core'; +import React, { PureComponent } from 'react'; + import { UserRolePicker } from 'app/core/components/RolePicker/UserRolePicker'; +import { contextSrv } from 'app/core/core'; +import { AccessControlAction, OrgRole, Role, ServiceAccountDTO } from 'app/types'; + +import { OrgRolePicker } from '../admin/OrgRolePicker'; interface Props { label: string; diff --git a/public/app/features/serviceaccounts/ServiceAccountTokensTable.tsx b/public/app/features/serviceaccounts/ServiceAccountTokensTable.tsx index e3c517bdef3..6d076ed8086 100644 --- a/public/app/features/serviceaccounts/ServiceAccountTokensTable.tsx +++ b/public/app/features/serviceaccounts/ServiceAccountTokensTable.tsx @@ -1,11 +1,12 @@ -import React, { FC } from 'react'; -import { DeleteButton, Icon, Tooltip, useStyles2, useTheme2 } from '@grafana/ui'; -import { dateTimeFormat, GrafanaTheme2, TimeZone } from '@grafana/data'; - -import { AccessControlAction } from 'app/types'; -import { ApiKey } from '../../types'; import { css } from '@emotion/css'; +import React, { FC } from 'react'; + +import { dateTimeFormat, GrafanaTheme2, TimeZone } from '@grafana/data'; +import { DeleteButton, Icon, Tooltip, useStyles2, useTheme2 } from '@grafana/ui'; import { contextSrv } from 'app/core/core'; +import { AccessControlAction } from 'app/types'; + +import { ApiKey } from '../../types'; interface Props { tokens: ApiKey[]; diff --git a/public/app/features/serviceaccounts/ServiceAccountsListItem.tsx b/public/app/features/serviceaccounts/ServiceAccountsListItem.tsx index b2d2d3aabb8..b1d7c8af80f 100644 --- a/public/app/features/serviceaccounts/ServiceAccountsListItem.tsx +++ b/public/app/features/serviceaccounts/ServiceAccountsListItem.tsx @@ -1,11 +1,14 @@ import { cx } from '@emotion/css'; +import React, { memo } from 'react'; + import { OrgRole } from '@grafana/data'; import { Button, Icon, useStyles2 } from '@grafana/ui'; import { UserRolePicker } from 'app/core/components/RolePicker/UserRolePicker'; import { contextSrv } from 'app/core/core'; import { AccessControlAction, Role, ServiceAccountDTO } from 'app/types'; -import React, { memo } from 'react'; + import { OrgRolePicker } from '../admin/OrgRolePicker'; + import { getStyles } from './ServiceAccountsListPage'; type ServiceAccountListItemProps = { diff --git a/public/app/features/serviceaccounts/ServiceAccountsListPage.tsx b/public/app/features/serviceaccounts/ServiceAccountsListPage.tsx index 2970193f335..f06120a2dbf 100644 --- a/public/app/features/serviceaccounts/ServiceAccountsListPage.tsx +++ b/public/app/features/serviceaccounts/ServiceAccountsListPage.tsx @@ -1,10 +1,18 @@ +import { css, cx } from '@emotion/css'; +import pluralize from 'pluralize'; import React, { useEffect } from 'react'; import { connect, ConnectedProps } from 'react-redux'; -import { ConfirmModal, FilterInput, LinkButton, RadioButtonGroup, useStyles2 } from '@grafana/ui'; -import { css, cx } from '@emotion/css'; +import { GrafanaTheme2, OrgRole } from '@grafana/data'; +import { ConfirmModal, FilterInput, LinkButton, RadioButtonGroup, useStyles2 } from '@grafana/ui'; +import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA'; import Page from 'app/core/components/Page/Page'; +import PageLoader from 'app/core/components/PageLoader/PageLoader'; +import { contextSrv } from 'app/core/core'; +import { getNavModel } from 'app/core/selectors/navModel'; import { StoreState, ServiceAccountDTO, AccessControlAction } from 'app/types'; + +import ServiceAccountListItem from './ServiceAccountsListItem'; import { changeFilter, changeQuery, @@ -14,13 +22,6 @@ import { updateServiceAccount, setServiceAccountToRemove, } from './state/actions'; -import { getNavModel } from 'app/core/selectors/navModel'; -import PageLoader from 'app/core/components/PageLoader/PageLoader'; -import { GrafanaTheme2, OrgRole } from '@grafana/data'; -import { contextSrv } from 'app/core/core'; -import pluralize from 'pluralize'; -import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA'; -import ServiceAccountListItem from './ServiceAccountsListItem'; interface OwnProps {} diff --git a/public/app/features/serviceaccounts/state/actions.ts b/public/app/features/serviceaccounts/state/actions.ts index 80380e5e492..9eb5ccb3d9b 100644 --- a/public/app/features/serviceaccounts/state/actions.ts +++ b/public/app/features/serviceaccounts/state/actions.ts @@ -1,5 +1,13 @@ -import { ServiceAccountDTO, ThunkResult, ServiceAccountFilter, AccessControlAction } from '../../../types'; +import { debounce } from 'lodash'; + import { getBackendSrv, locationService } from '@grafana/runtime'; +import { fetchBuiltinRoles, fetchRoleOptions } from 'app/core/components/RolePicker/api'; +import { accessControlQueryParam } from 'app/core/utils/accessControl'; + +import { contextSrv } from '../../../core/services/context_srv'; +import { ServiceAccountDTO, ThunkResult, ServiceAccountFilter, AccessControlAction } from '../../../types'; +import { ServiceAccountToken } from '../CreateServiceAccountTokenModal'; + import { acOptionsLoaded, builtInRolesLoaded, @@ -13,11 +21,6 @@ import { serviceAccountTokensLoaded, serviceAccountToRemoveLoaded, } from './reducers'; -import { accessControlQueryParam } from 'app/core/utils/accessControl'; -import { fetchBuiltinRoles, fetchRoleOptions } from 'app/core/components/RolePicker/api'; -import { debounce } from 'lodash'; -import { contextSrv } from '../../../core/services/context_srv'; -import { ServiceAccountToken } from '../CreateServiceAccountTokenModal'; const BASE_URL = `/api/serviceaccounts`; diff --git a/public/app/features/teams/CreateTeam.test.tsx b/public/app/features/teams/CreateTeam.test.tsx index c16c9d24c51..77af350c6aa 100644 --- a/public/app/features/teams/CreateTeam.test.tsx +++ b/public/app/features/teams/CreateTeam.test.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { shallow } from 'enzyme'; +import React from 'react'; + import { CreateTeam, Props } from './CreateTeam'; describe('Render', () => { diff --git a/public/app/features/teams/CreateTeam.tsx b/public/app/features/teams/CreateTeam.tsx index 47373c38d76..7685e43c190 100644 --- a/public/app/features/teams/CreateTeam.tsx +++ b/public/app/features/teams/CreateTeam.tsx @@ -1,12 +1,13 @@ import React, { PureComponent } from 'react'; -import Page from 'app/core/components/Page/Page'; -import { Button, Form, Field, Input, FieldSet, Label, Tooltip, Icon } from '@grafana/ui'; +import { connect } from 'react-redux'; + import { NavModel } from '@grafana/data'; import { getBackendSrv, locationService } from '@grafana/runtime'; -import { connect } from 'react-redux'; +import { Button, Form, Field, Input, FieldSet, Label, Tooltip, Icon } from '@grafana/ui'; +import Page from 'app/core/components/Page/Page'; +import { contextSrv } from 'app/core/core'; import { getNavModel } from 'app/core/selectors/navModel'; import { StoreState } from 'app/types'; -import { contextSrv } from 'app/core/core'; export interface Props { navModel: NavModel; diff --git a/public/app/features/teams/TeamGroupSync.test.tsx b/public/app/features/teams/TeamGroupSync.test.tsx index 6ba6f050278..3d909176fa3 100644 --- a/public/app/features/teams/TeamGroupSync.test.tsx +++ b/public/app/features/teams/TeamGroupSync.test.tsx @@ -1,7 +1,9 @@ -import React from 'react'; import { shallow } from 'enzyme'; -import { Props, TeamGroupSync } from './TeamGroupSync'; +import React from 'react'; + import { TeamGroup } from '../../types'; + +import { Props, TeamGroupSync } from './TeamGroupSync'; import { getMockTeamGroups } from './__mocks__/teamMocks'; const setup = (propOverrides?: object) => { diff --git a/public/app/features/teams/TeamGroupSync.tsx b/public/app/features/teams/TeamGroupSync.tsx index dc3d78e1048..16531c2eea9 100644 --- a/public/app/features/teams/TeamGroupSync.tsx +++ b/public/app/features/teams/TeamGroupSync.tsx @@ -1,18 +1,20 @@ import React, { PureComponent } from 'react'; import { connect, ConnectedProps } from 'react-redux'; -import { SlideDown } from 'app/core/components/Animations/SlideDown'; import { LegacyForms, Tooltip, Icon, Button, useTheme2 } from '@grafana/ui'; -const { Input } = LegacyForms; - -import { StoreState, TeamGroup } from '../../types'; -import { addTeamGroup, loadTeamGroups, removeTeamGroup } from './state/actions'; -import { getTeamGroups } from './state/selectors'; -import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA'; +import { SlideDown } from 'app/core/components/Animations/SlideDown'; import { CloseButton } from 'app/core/components/CloseButton/CloseButton'; +import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA'; import { UpgradeBox, UpgradeContent, UpgradeContentProps } from 'app/core/components/Upgrade/UpgradeBox'; import { highlightTrial } from 'app/features/admin/utils'; +import { StoreState, TeamGroup } from '../../types'; + +import { addTeamGroup, loadTeamGroups, removeTeamGroup } from './state/actions'; +import { getTeamGroups } from './state/selectors'; + +const { Input } = LegacyForms; + function mapStateToProps(state: StoreState) { return { groups: getTeamGroups(state.team), diff --git a/public/app/features/teams/TeamList.test.tsx b/public/app/features/teams/TeamList.test.tsx index aa53bf1d995..598ecdd3a5c 100644 --- a/public/app/features/teams/TeamList.test.tsx +++ b/public/app/features/teams/TeamList.test.tsx @@ -1,11 +1,14 @@ -import React from 'react'; import { shallow } from 'enzyme'; -import { Props, TeamList } from './TeamList'; -import { OrgRole, Team } from '../../types'; -import { getMockTeam, getMultipleMockTeams } from './__mocks__/teamMocks'; -import { contextSrv, User } from 'app/core/services/context_srv'; -import { NavModel } from '@grafana/data'; +import React from 'react'; import { mockToolkitActionCreator } from 'test/core/redux/mocks'; + +import { NavModel } from '@grafana/data'; +import { contextSrv, User } from 'app/core/services/context_srv'; + +import { OrgRole, Team } from '../../types'; + +import { Props, TeamList } from './TeamList'; +import { getMockTeam, getMultipleMockTeams } from './__mocks__/teamMocks'; import { setSearchQuery, setTeamsSearchPage } from './state/reducers'; jest.mock('app/core/config', () => { diff --git a/public/app/features/teams/TeamList.tsx b/public/app/features/teams/TeamList.tsx index f044e4681d7..99913f21f52 100644 --- a/public/app/features/teams/TeamList.tsx +++ b/public/app/features/teams/TeamList.tsx @@ -1,18 +1,21 @@ import React, { PureComponent } from 'react'; -import Page from 'app/core/components/Page/Page'; -import { DeleteButton, LinkButton, FilterInput, VerticalGroup, HorizontalGroup, Pagination } from '@grafana/ui'; + import { NavModel } from '@grafana/data'; +import { DeleteButton, LinkButton, FilterInput, VerticalGroup, HorizontalGroup, Pagination } from '@grafana/ui'; import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA'; -import { AccessControlAction, Role, StoreState, Team } from 'app/types'; -import { deleteTeam, loadTeams } from './state/actions'; -import { getSearchQuery, getTeams, getTeamsCount, getTeamsSearchPage, isPermissionTeamAdmin } from './state/selectors'; -import { getNavModel } from 'app/core/selectors/navModel'; -import { config } from 'app/core/config'; -import { contextSrv, User } from 'app/core/services/context_srv'; -import { connectWithCleanUp } from '../../core/components/connectWithCleanUp'; -import { setSearchQuery, setTeamsSearchPage } from './state/reducers'; +import Page from 'app/core/components/Page/Page'; import { TeamRolePicker } from 'app/core/components/RolePicker/TeamRolePicker'; import { fetchRoleOptions } from 'app/core/components/RolePicker/api'; +import { config } from 'app/core/config'; +import { getNavModel } from 'app/core/selectors/navModel'; +import { contextSrv, User } from 'app/core/services/context_srv'; +import { AccessControlAction, Role, StoreState, Team } from 'app/types'; + +import { connectWithCleanUp } from '../../core/components/connectWithCleanUp'; + +import { deleteTeam, loadTeams } from './state/actions'; +import { setSearchQuery, setTeamsSearchPage } from './state/reducers'; +import { getSearchQuery, getTeams, getTeamsCount, getTeamsSearchPage, isPermissionTeamAdmin } from './state/selectors'; const pageLimit = 30; diff --git a/public/app/features/teams/TeamMemberRow.test.tsx b/public/app/features/teams/TeamMemberRow.test.tsx index f09d4d7742a..c2318e946fd 100644 --- a/public/app/features/teams/TeamMemberRow.test.tsx +++ b/public/app/features/teams/TeamMemberRow.test.tsx @@ -1,10 +1,13 @@ -import React from 'react'; import { shallow } from 'enzyme'; -import { TeamMember, TeamPermissionLevel } from '../../types'; -import { getMockTeamMember } from './__mocks__/teamMocks'; -import { TeamMemberRow, Props } from './TeamMemberRow'; +import React from 'react'; + import { SelectableValue } from '@grafana/data'; +import { TeamMember, TeamPermissionLevel } from '../../types'; + +import { TeamMemberRow, Props } from './TeamMemberRow'; +import { getMockTeamMember } from './__mocks__/teamMocks'; + const setup = (propOverrides?: object) => { const props: Props = { member: getMockTeamMember(), diff --git a/public/app/features/teams/TeamMemberRow.tsx b/public/app/features/teams/TeamMemberRow.tsx index 52c5229e25a..9d16ec471a3 100644 --- a/public/app/features/teams/TeamMemberRow.tsx +++ b/public/app/features/teams/TeamMemberRow.tsx @@ -1,13 +1,15 @@ import React, { PureComponent } from 'react'; import { connect, ConnectedProps } from 'react-redux'; -import { LegacyForms, DeleteButton } from '@grafana/ui'; -const { Select } = LegacyForms; -import { SelectableValue } from '@grafana/data'; -import { TeamMember, teamsPermissionLevels, TeamPermissionLevel } from 'app/types'; -import { WithFeatureToggle } from 'app/core/components/WithFeatureToggle'; -import { updateTeamMember, removeTeamMember } from './state/actions'; +import { SelectableValue } from '@grafana/data'; +import { LegacyForms, DeleteButton } from '@grafana/ui'; import { TagBadge } from 'app/core/components/TagFilter/TagBadge'; +import { WithFeatureToggle } from 'app/core/components/WithFeatureToggle'; +import { TeamMember, teamsPermissionLevels, TeamPermissionLevel } from 'app/types'; + +import { updateTeamMember, removeTeamMember } from './state/actions'; + +const { Select } = LegacyForms; const mapDispatchToProps = { removeTeamMember, diff --git a/public/app/features/teams/TeamMembers.test.tsx b/public/app/features/teams/TeamMembers.test.tsx index fdd418ebd02..2253a4671cf 100644 --- a/public/app/features/teams/TeamMembers.test.tsx +++ b/public/app/features/teams/TeamMembers.test.tsx @@ -1,10 +1,13 @@ -import React from 'react'; import { shallow } from 'enzyme'; -import { Props, State, TeamMembers } from './TeamMembers'; -import { OrgRole, TeamMember } from '../../types'; -import { getMockTeamMembers } from './__mocks__/teamMocks'; -import { User } from 'app/core/services/context_srv'; +import React from 'react'; import { mockToolkitActionCreator } from 'test/core/redux/mocks'; + +import { User } from 'app/core/services/context_srv'; + +import { OrgRole, TeamMember } from '../../types'; + +import { Props, State, TeamMembers } from './TeamMembers'; +import { getMockTeamMembers } from './__mocks__/teamMocks'; import { setSearchMemberQuery } from './state/reducers'; const signedInUserId = 1; diff --git a/public/app/features/teams/TeamMembers.tsx b/public/app/features/teams/TeamMembers.tsx index b505d9f296e..afa843d8b94 100644 --- a/public/app/features/teams/TeamMembers.tsx +++ b/public/app/features/teams/TeamMembers.tsx @@ -1,19 +1,21 @@ import React, { PureComponent } from 'react'; import { connect, ConnectedProps } from 'react-redux'; + +import { SelectableValue } from '@grafana/data'; +import { Button, FilterInput, Label } from '@grafana/ui'; import { SlideDown } from 'app/core/components/Animations/SlideDown'; +import { CloseButton } from 'app/core/components/CloseButton/CloseButton'; import { UserPicker } from 'app/core/components/Select/UserPicker'; import { TagBadge } from 'app/core/components/TagFilter/TagBadge'; -import { TeamMember, OrgUser } from 'app/types'; -import { addTeamMember } from './state/actions'; -import { getSearchMemberQuery, isSignedInUserTeamAdmin } from './state/selectors'; import { WithFeatureToggle } from 'app/core/components/WithFeatureToggle'; import { config } from 'app/core/config'; import { contextSrv } from 'app/core/services/context_srv'; +import { TeamMember, OrgUser } from 'app/types'; + import TeamMemberRow from './TeamMemberRow'; +import { addTeamMember } from './state/actions'; import { setSearchMemberQuery } from './state/reducers'; -import { CloseButton } from 'app/core/components/CloseButton/CloseButton'; -import { Button, FilterInput, Label } from '@grafana/ui'; -import { SelectableValue } from '@grafana/data'; +import { getSearchMemberQuery, isSignedInUserTeamAdmin } from './state/selectors'; function mapStateToProps(state: any) { return { diff --git a/public/app/features/teams/TeamPages.test.tsx b/public/app/features/teams/TeamPages.test.tsx index 54eb487585c..91efcd8d58a 100644 --- a/public/app/features/teams/TeamPages.test.tsx +++ b/public/app/features/teams/TeamPages.test.tsx @@ -1,11 +1,14 @@ -import React from 'react'; import { shallow } from 'enzyme'; -import { Props, TeamPages } from './TeamPages'; -import { OrgRole, Team, TeamMember } from '../../types'; -import { getMockTeam } from './__mocks__/teamMocks'; -import { User } from 'app/core/services/context_srv'; +import React from 'react'; + import { NavModel, createTheme } from '@grafana/data'; import { getRouteComponentProps } from 'app/core/navigation/__mocks__/routeProps'; +import { User } from 'app/core/services/context_srv'; + +import { OrgRole, Team, TeamMember } from '../../types'; + +import { Props, TeamPages } from './TeamPages'; +import { getMockTeam } from './__mocks__/teamMocks'; jest.mock('@grafana/runtime/src/config', () => ({ ...(jest.requireActual('@grafana/runtime/src/config') as unknown as object), diff --git a/public/app/features/teams/TeamPages.tsx b/public/app/features/teams/TeamPages.tsx index dc2873334bb..f72b7f0b532 100644 --- a/public/app/features/teams/TeamPages.tsx +++ b/public/app/features/teams/TeamPages.tsx @@ -1,23 +1,25 @@ +import { includes } from 'lodash'; import React, { PureComponent } from 'react'; import { connect, ConnectedProps } from 'react-redux'; -import { includes } from 'lodash'; + +import { NavModel } from '@grafana/data'; +import { featureEnabled } from '@grafana/runtime'; import { Themeable2, withTheme2 } from '@grafana/ui'; -import config from 'app/core/config'; import Page from 'app/core/components/Page/Page'; +import { UpgradeBox } from 'app/core/components/Upgrade/UpgradeBox'; +import config from 'app/core/config'; +import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; +import { getNavModel } from 'app/core/selectors/navModel'; +import { contextSrv } from 'app/core/services/context_srv'; +import { AccessControlAction, StoreState } from 'app/types'; + +import TeamGroupSync, { TeamSyncUpgradeContent } from './TeamGroupSync'; import TeamMembers from './TeamMembers'; import TeamPermissions from './TeamPermissions'; import TeamSettings from './TeamSettings'; -import TeamGroupSync, { TeamSyncUpgradeContent } from './TeamGroupSync'; -import { AccessControlAction, StoreState } from 'app/types'; import { loadTeam, loadTeamMembers } from './state/actions'; -import { getTeam, getTeamMembers, isSignedInUserTeamAdmin } from './state/selectors'; import { getTeamLoadingNav } from './state/navModel'; -import { getNavModel } from 'app/core/selectors/navModel'; -import { contextSrv } from 'app/core/services/context_srv'; -import { NavModel } from '@grafana/data'; -import { featureEnabled } from '@grafana/runtime'; -import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; -import { UpgradeBox } from 'app/core/components/Upgrade/UpgradeBox'; +import { getTeam, getTeamMembers, isSignedInUserTeamAdmin } from './state/selectors'; interface TeamPageRouteParams { id: string; diff --git a/public/app/features/teams/TeamPermissions.tsx b/public/app/features/teams/TeamPermissions.tsx index 6416bdd62ec..7dce1fef56f 100644 --- a/public/app/features/teams/TeamPermissions.tsx +++ b/public/app/features/teams/TeamPermissions.tsx @@ -1,8 +1,10 @@ import React from 'react'; + import { Permissions } from 'app/core/components/AccessControl'; -import { AccessControlAction, Team } from '../../types'; import { contextSrv } from 'app/core/services/context_srv'; +import { AccessControlAction, Team } from '../../types'; + type TeamPermissionsProps = { team: Team; }; diff --git a/public/app/features/teams/TeamSettings.test.tsx b/public/app/features/teams/TeamSettings.test.tsx index 4d4cfc0e83c..2b6bb754ca3 100644 --- a/public/app/features/teams/TeamSettings.test.tsx +++ b/public/app/features/teams/TeamSettings.test.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { shallow } from 'enzyme'; +import React from 'react'; + import { Props, TeamSettings } from './TeamSettings'; import { getMockTeam } from './__mocks__/teamMocks'; diff --git a/public/app/features/teams/TeamSettings.tsx b/public/app/features/teams/TeamSettings.tsx index ede17d8da8f..1c0048fe910 100644 --- a/public/app/features/teams/TeamSettings.tsx +++ b/public/app/features/teams/TeamSettings.tsx @@ -1,11 +1,12 @@ import React, { FC } from 'react'; import { connect, ConnectedProps } from 'react-redux'; -import { Input, Field, Form, Button, FieldSet, VerticalGroup } from '@grafana/ui'; +import { Input, Field, Form, Button, FieldSet, VerticalGroup } from '@grafana/ui'; import { SharedPreferences } from 'app/core/components/SharedPreferences/SharedPreferences'; -import { updateTeam } from './state/actions'; -import { AccessControlAction, Team } from 'app/types'; import { contextSrv } from 'app/core/core'; +import { AccessControlAction, Team } from 'app/types'; + +import { updateTeam } from './state/actions'; const mapDispatchToProps = { updateTeam, diff --git a/public/app/features/teams/state/actions.ts b/public/app/features/teams/state/actions.ts index df695929dc1..d02e2300f4d 100644 --- a/public/app/features/teams/state/actions.ts +++ b/public/app/features/teams/state/actions.ts @@ -1,11 +1,11 @@ import { getBackendSrv } from '@grafana/runtime'; - -import { AccessControlAction, TeamMember, ThunkResult } from 'app/types'; import { updateNavIndex } from 'app/core/actions'; +import { contextSrv } from 'app/core/core'; +import { accessControlQueryParam } from 'app/core/utils/accessControl'; +import { AccessControlAction, TeamMember, ThunkResult } from 'app/types'; + import { buildNavModel } from './navModel'; import { teamGroupsLoaded, teamLoaded, teamMembersLoaded, teamsLoaded } from './reducers'; -import { accessControlQueryParam } from 'app/core/utils/accessControl'; -import { contextSrv } from 'app/core/core'; export function loadTeams(): ThunkResult { return async (dispatch) => { diff --git a/public/app/features/teams/state/navModel.ts b/public/app/features/teams/state/navModel.ts index 3671b1095d7..bdfb6a01231 100644 --- a/public/app/features/teams/state/navModel.ts +++ b/public/app/features/teams/state/navModel.ts @@ -1,10 +1,10 @@ -import { AccessControlAction, Team, TeamPermissionLevel } from 'app/types'; -import { featureEnabled } from '@grafana/runtime'; import { NavModelItem, NavModel } from '@grafana/data'; +import { featureEnabled } from '@grafana/runtime'; +import { ProBadge } from 'app/core/components/Upgrade/ProBadge'; import config from 'app/core/config'; import { contextSrv } from 'app/core/services/context_srv'; -import { ProBadge } from 'app/core/components/Upgrade/ProBadge'; import { highlightTrial } from 'app/features/admin/utils'; +import { AccessControlAction, Team, TeamPermissionLevel } from 'app/types'; const loadingTeam = { avatarUrl: 'public/img/user_profile.png', diff --git a/public/app/features/teams/state/reducers.test.ts b/public/app/features/teams/state/reducers.test.ts index 0dd9d83eaa6..5482f349650 100644 --- a/public/app/features/teams/state/reducers.test.ts +++ b/public/app/features/teams/state/reducers.test.ts @@ -1,3 +1,7 @@ +import { reducerTester } from '../../../../test/core/redux/reducerTester'; +import { TeamsState, TeamState } from '../../../types'; +import { getMockTeam, getMockTeamGroups, getMockTeamMember } from '../__mocks__/teamMocks'; + import { initialTeamsState, initialTeamState, @@ -10,9 +14,6 @@ import { teamsLoaded, teamsReducer, } from './reducers'; -import { getMockTeam, getMockTeamGroups, getMockTeamMember } from '../__mocks__/teamMocks'; -import { reducerTester } from '../../../../test/core/redux/reducerTester'; -import { TeamsState, TeamState } from '../../../types'; describe('teams reducer', () => { describe('when teamsLoaded is dispatched', () => { diff --git a/public/app/features/teams/state/selectors.test.ts b/public/app/features/teams/state/selectors.test.ts index 6a5dd24117d..850943fb64b 100644 --- a/public/app/features/teams/state/selectors.test.ts +++ b/public/app/features/teams/state/selectors.test.ts @@ -1,8 +1,10 @@ -import { getTeam, getTeamMembers, getTeams, isSignedInUserTeamAdmin, Config } from './selectors'; -import { getMockTeam, getMockTeamMembers, getMultipleMockTeams } from '../__mocks__/teamMocks'; -import { Team, TeamGroup, TeamsState, TeamState, OrgRole } from '../../../types'; import { User } from 'app/core/services/context_srv'; +import { Team, TeamGroup, TeamsState, TeamState, OrgRole } from '../../../types'; +import { getMockTeam, getMockTeamMembers, getMultipleMockTeams } from '../__mocks__/teamMocks'; + +import { getTeam, getTeamMembers, getTeams, isSignedInUserTeamAdmin, Config } from './selectors'; + describe('Teams selectors', () => { describe('Get teams', () => { const mockTeams = getMultipleMockTeams(5); diff --git a/public/app/features/teams/state/selectors.ts b/public/app/features/teams/state/selectors.ts index f8461c7eb3a..a374645fd53 100644 --- a/public/app/features/teams/state/selectors.ts +++ b/public/app/features/teams/state/selectors.ts @@ -1,5 +1,5 @@ -import { Team, TeamsState, TeamState, TeamMember, OrgRole, TeamPermissionLevel } from 'app/types'; import { User } from 'app/core/services/context_srv'; +import { Team, TeamsState, TeamState, TeamMember, OrgRole, TeamPermissionLevel } from 'app/types'; export const getSearchQuery = (state: TeamsState) => state.searchQuery; export const getSearchMemberQuery = (state: TeamState) => state.searchMemberQuery; diff --git a/public/app/features/templating/formatRegistry.ts b/public/app/features/templating/formatRegistry.ts index 03e5f1bcd15..6256c4259ff 100644 --- a/public/app/features/templating/formatRegistry.ts +++ b/public/app/features/templating/formatRegistry.ts @@ -1,8 +1,10 @@ -import kbn from 'app/core/utils/kbn'; -import { dateTime, Registry, RegistryItem, textUtil, VariableModel } from '@grafana/data'; import { isArray, map, replace } from 'lodash'; -import { formatVariableLabel } from '../variables/shared/formatVariable'; + +import { dateTime, Registry, RegistryItem, textUtil, VariableModel } from '@grafana/data'; +import kbn from 'app/core/utils/kbn'; + import { ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE } from '../variables/constants'; +import { formatVariableLabel } from '../variables/shared/formatVariable'; export interface FormatOptions { value: any; diff --git a/public/app/features/templating/template_srv.mock.ts b/public/app/features/templating/template_srv.mock.ts index 4d4b4961de0..0d7e41f8ad4 100644 --- a/public/app/features/templating/template_srv.mock.ts +++ b/public/app/features/templating/template_srv.mock.ts @@ -1,7 +1,8 @@ import { ScopedVars, TimeRange, VariableModel } from '@grafana/data'; -import { variableRegex } from '../variables/utils'; import { TemplateSrv } from '@grafana/runtime'; +import { variableRegex } from '../variables/utils'; + /** * Mock for TemplateSrv where you can just supply map of key and values and it will do the interpolation based on that. * For simple tests whether you your data source for example calls correct replacing code. diff --git a/public/app/features/templating/template_srv.test.ts b/public/app/features/templating/template_srv.test.ts index c99d43b1a9f..25e9528ab35 100644 --- a/public/app/features/templating/template_srv.test.ts +++ b/public/app/features/templating/template_srv.test.ts @@ -1,13 +1,15 @@ import { dateTime, TimeRange } from '@grafana/data'; -import { initTemplateSrv } from '../../../test/helpers/initTemplateSrv'; -import { silenceConsoleOutput } from '../../../test/core/utils/silenceConsoleOutput'; -import { VariableAdapter, variableAdapters } from '../variables/adapters'; -import { createQueryVariableAdapter } from '../variables/query/adapter'; -import { createAdHocVariableAdapter } from '../variables/adhoc/adapter'; -import { VariableModel } from '../variables/types'; -import { FormatRegistryID } from './formatRegistry'; import { setDataSourceSrv } from '@grafana/runtime'; + +import { silenceConsoleOutput } from '../../../test/core/utils/silenceConsoleOutput'; +import { initTemplateSrv } from '../../../test/helpers/initTemplateSrv'; import { mockDataSource, MockDataSourceSrv } from '../alerting/unified/mocks'; +import { VariableAdapter, variableAdapters } from '../variables/adapters'; +import { createAdHocVariableAdapter } from '../variables/adhoc/adapter'; +import { createQueryVariableAdapter } from '../variables/query/adapter'; +import { VariableModel } from '../variables/types'; + +import { FormatRegistryID } from './formatRegistry'; const key = 'key'; diff --git a/public/app/features/templating/template_srv.ts b/public/app/features/templating/template_srv.ts index a1f024e4daa..7a06912ddfc 100644 --- a/public/app/features/templating/template_srv.ts +++ b/public/app/features/templating/template_srv.ts @@ -1,13 +1,16 @@ import { escape, isString, property } from 'lodash'; + import { deprecationWarning, ScopedVars, TimeRange } from '@grafana/data'; -import { getFilteredVariables, getVariables, getVariableWithName } from '../variables/state/selectors'; -import { variableRegex } from '../variables/utils'; -import { isAdHoc } from '../variables/guard'; -import { AdHocVariableFilter, AdHocVariableModel, VariableModel } from '../variables/types'; import { getDataSourceSrv, setTemplateSrv, TemplateSrv as BaseTemplateSrv } from '@grafana/runtime'; -import { FormatOptions, formatRegistry, FormatRegistryID } from './formatRegistry'; + import { variableAdapters } from '../variables/adapters'; import { ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE } from '../variables/constants'; +import { isAdHoc } from '../variables/guard'; +import { getFilteredVariables, getVariables, getVariableWithName } from '../variables/state/selectors'; +import { AdHocVariableFilter, AdHocVariableModel, VariableModel } from '../variables/types'; +import { variableRegex } from '../variables/utils'; + +import { FormatOptions, formatRegistry, FormatRegistryID } from './formatRegistry'; interface FieldAccessorCache { [key: string]: (obj: any) => any; diff --git a/public/app/features/transformers/FilterByValueTransformer/FilterByValueFilterEditor.tsx b/public/app/features/transformers/FilterByValueTransformer/FilterByValueFilterEditor.tsx index 44fce104fbf..2afb51bd98a 100644 --- a/public/app/features/transformers/FilterByValueTransformer/FilterByValueFilterEditor.tsx +++ b/public/app/features/transformers/FilterByValueTransformer/FilterByValueFilterEditor.tsx @@ -1,7 +1,9 @@ import React, { useCallback } from 'react'; -import { Button, Select } from '@grafana/ui'; + import { Field, SelectableValue, valueMatchers } from '@grafana/data'; import { FilterByValueFilter } from '@grafana/data/src/transformations/transformers/filterByValue'; +import { Button, Select } from '@grafana/ui'; + import { valueMatchersUI } from './ValueMatchers/valueMatchersUI'; interface Props { diff --git a/public/app/features/transformers/FilterByValueTransformer/FilterByValueTransformerEditor.tsx b/public/app/features/transformers/FilterByValueTransformer/FilterByValueTransformerEditor.tsx index 169d17dcd62..53f434ff5a1 100644 --- a/public/app/features/transformers/FilterByValueTransformer/FilterByValueTransformerEditor.tsx +++ b/public/app/features/transformers/FilterByValueTransformer/FilterByValueTransformerEditor.tsx @@ -1,5 +1,7 @@ -import React, { useMemo, useCallback } from 'react'; import { css } from '@emotion/css'; +import { cloneDeep } from 'lodash'; +import React, { useMemo, useCallback } from 'react'; + import { DataTransformerID, standardTransformers, @@ -12,14 +14,13 @@ import { ValueMatcherID, valueMatchers, } from '@grafana/data'; -import { Button, RadioButtonGroup, stylesFactory } from '@grafana/ui'; -import { cloneDeep } from 'lodash'; import { FilterByValueFilter, FilterByValueMatch, FilterByValueTransformerOptions, FilterByValueType, } from '@grafana/data/src/transformations/transformers/filterByValue'; +import { Button, RadioButtonGroup, stylesFactory } from '@grafana/ui'; import { DataFrameFieldsInfo, FilterByValueFilterEditor } from './FilterByValueFilterEditor'; diff --git a/public/app/features/transformers/FilterByValueTransformer/ValueMatchers/BasicMatcherEditor.tsx b/public/app/features/transformers/FilterByValueTransformer/ValueMatchers/BasicMatcherEditor.tsx index 00499b90cc3..726c2fb8bbd 100644 --- a/public/app/features/transformers/FilterByValueTransformer/ValueMatchers/BasicMatcherEditor.tsx +++ b/public/app/features/transformers/FilterByValueTransformer/ValueMatchers/BasicMatcherEditor.tsx @@ -1,6 +1,8 @@ import React, { useCallback, useState } from 'react'; -import { Input } from '@grafana/ui'; + import { ValueMatcherID, BasicValueMatcherOptions } from '@grafana/data'; +import { Input } from '@grafana/ui'; + import { ValueMatcherEditorConfig, ValueMatcherUIProps, ValueMatcherUIRegistryItem } from './types'; import { convertToType } from './utils'; diff --git a/public/app/features/transformers/FilterByValueTransformer/ValueMatchers/NoopMatcherEditor.tsx b/public/app/features/transformers/FilterByValueTransformer/ValueMatchers/NoopMatcherEditor.tsx index 84119754b0b..ea764d8dc3e 100644 --- a/public/app/features/transformers/FilterByValueTransformer/ValueMatchers/NoopMatcherEditor.tsx +++ b/public/app/features/transformers/FilterByValueTransformer/ValueMatchers/NoopMatcherEditor.tsx @@ -1,5 +1,7 @@ -import { ValueMatcherID } from '@grafana/data'; import React from 'react'; + +import { ValueMatcherID } from '@grafana/data'; + import { ValueMatcherUIProps, ValueMatcherUIRegistryItem } from './types'; export const NoopMatcherEditor: React.FC> = () => { diff --git a/public/app/features/transformers/FilterByValueTransformer/ValueMatchers/RangeMatcherEditor.tsx b/public/app/features/transformers/FilterByValueTransformer/ValueMatchers/RangeMatcherEditor.tsx index 5738f38b09e..fc64c0b64a1 100644 --- a/public/app/features/transformers/FilterByValueTransformer/ValueMatchers/RangeMatcherEditor.tsx +++ b/public/app/features/transformers/FilterByValueTransformer/ValueMatchers/RangeMatcherEditor.tsx @@ -1,6 +1,8 @@ import React, { useCallback, useState } from 'react'; -import { Input } from '@grafana/ui'; + import { ValueMatcherID, RangeValueMatcherOptions } from '@grafana/data'; +import { Input } from '@grafana/ui'; + import { ValueMatcherEditorConfig, ValueMatcherUIProps, ValueMatcherUIRegistryItem } from './types'; import { convertToType } from './utils'; diff --git a/public/app/features/transformers/FilterByValueTransformer/ValueMatchers/utils.ts b/public/app/features/transformers/FilterByValueTransformer/ValueMatchers/utils.ts index f30f590a476..5c95ffe729b 100644 --- a/public/app/features/transformers/FilterByValueTransformer/ValueMatchers/utils.ts +++ b/public/app/features/transformers/FilterByValueTransformer/ValueMatchers/utils.ts @@ -1,6 +1,7 @@ -import { Field, FieldType } from '@grafana/data'; import { isString, isUndefined } from 'lodash'; +import { Field, FieldType } from '@grafana/data'; + export function convertToType(value: any, field: Field): any { switch (field.type) { case FieldType.boolean: diff --git a/public/app/features/transformers/FilterByValueTransformer/ValueMatchers/valueMatchersUI.ts b/public/app/features/transformers/FilterByValueTransformer/ValueMatchers/valueMatchersUI.ts index 0517333aca6..d1c7e994c9e 100644 --- a/public/app/features/transformers/FilterByValueTransformer/ValueMatchers/valueMatchersUI.ts +++ b/public/app/features/transformers/FilterByValueTransformer/ValueMatchers/valueMatchersUI.ts @@ -1,4 +1,5 @@ import { Registry } from '@grafana/data'; + import { getBasicValueMatchersUI } from './BasicMatcherEditor'; import { getNoopValueMatchersUI } from './NoopMatcherEditor'; import { getRangeValueMatchersUI } from './RangeMatcherEditor'; diff --git a/public/app/features/transformers/calculateHeatmap/HeatmapTransformerEditor.tsx b/public/app/features/transformers/calculateHeatmap/HeatmapTransformerEditor.tsx index dc0e6eb1fed..aca854f71d3 100644 --- a/public/app/features/transformers/calculateHeatmap/HeatmapTransformerEditor.tsx +++ b/public/app/features/transformers/calculateHeatmap/HeatmapTransformerEditor.tsx @@ -1,4 +1,5 @@ import React, { useEffect } from 'react'; + import { PanelOptionsEditorBuilder, PluginState, @@ -7,10 +8,11 @@ import { TransformerUIProps, } from '@grafana/data'; -import { HeatmapTransformerOptions, heatmapTransformer } from './heatmap'; -import { addHeatmapCalculationOptions } from './editor/helper'; import { getDefaultOptions, getTransformerOptionPane } from '../spatial/optionsHelper'; +import { addHeatmapCalculationOptions } from './editor/helper'; +import { HeatmapTransformerOptions, heatmapTransformer } from './heatmap'; + // Nothing defined in state const supplier = ( builder: PanelOptionsEditorBuilder, diff --git a/public/app/features/transformers/calculateHeatmap/editor/AxisEditor.tsx b/public/app/features/transformers/calculateHeatmap/editor/AxisEditor.tsx index a35e9ba126c..c459dba078a 100644 --- a/public/app/features/transformers/calculateHeatmap/editor/AxisEditor.tsx +++ b/public/app/features/transformers/calculateHeatmap/editor/AxisEditor.tsx @@ -1,6 +1,8 @@ import React from 'react'; + import { SelectableValue, StandardEditorProps } from '@grafana/data'; import { HorizontalGroup, Input, RadioButtonGroup } from '@grafana/ui'; + import { HeatmapCalculationAxisConfig, HeatmapCalculationMode } from '../models.gen'; const modeOptions: Array> = [ diff --git a/public/app/features/transformers/calculateHeatmap/editor/helper.ts b/public/app/features/transformers/calculateHeatmap/editor/helper.ts index 5ba5721f43d..af78c5113c6 100644 --- a/public/app/features/transformers/calculateHeatmap/editor/helper.ts +++ b/public/app/features/transformers/calculateHeatmap/editor/helper.ts @@ -1,6 +1,7 @@ import { PanelOptionsEditorBuilder } from '@grafana/data'; import { HeatmapCalculationMode, HeatmapCalculationOptions } from '../models.gen'; + import { AxisEditor } from './AxisEditor'; export function addHeatmapCalculationOptions( diff --git a/public/app/features/transformers/calculateHeatmap/heatmap.test.ts b/public/app/features/transformers/calculateHeatmap/heatmap.test.ts index 58303f46cf5..d2302dcf2d3 100644 --- a/public/app/features/transformers/calculateHeatmap/heatmap.test.ts +++ b/public/app/features/transformers/calculateHeatmap/heatmap.test.ts @@ -1,5 +1,6 @@ import { FieldType } from '@grafana/data'; import { toDataFrame } from '@grafana/data/src/dataframe/processDataFrame'; + import { calculateHeatmapFromData } from './heatmap'; import { HeatmapCalculationOptions } from './models.gen'; diff --git a/public/app/features/transformers/calculateHeatmap/heatmap.ts b/public/app/features/transformers/calculateHeatmap/heatmap.ts index a714be39029..5b7e3d8b8a6 100644 --- a/public/app/features/transformers/calculateHeatmap/heatmap.ts +++ b/public/app/features/transformers/calculateHeatmap/heatmap.ts @@ -1,3 +1,5 @@ +import { map } from 'rxjs'; + import { ArrayVector, DataFrame, @@ -10,7 +12,7 @@ import { getFieldDisplayName, Field, } from '@grafana/data'; -import { map } from 'rxjs'; + import { HeatmapCalculationMode, HeatmapCalculationOptions } from './models.gen'; import { niceLinearIncrs, niceTimeIncrs } from './utils'; diff --git a/public/app/features/transformers/configFromQuery/ConfigFromQueryTransformerEditor.test.tsx b/public/app/features/transformers/configFromQuery/ConfigFromQueryTransformerEditor.test.tsx index 863d0f0c0cc..d6c866c30d6 100644 --- a/public/app/features/transformers/configFromQuery/ConfigFromQueryTransformerEditor.test.tsx +++ b/public/app/features/transformers/configFromQuery/ConfigFromQueryTransformerEditor.test.tsx @@ -1,7 +1,9 @@ -import React from 'react'; -import { toDataFrame, FieldType } from '@grafana/data'; import { fireEvent, render, screen } from '@testing-library/react'; +import React from 'react'; + +import { toDataFrame, FieldType } from '@grafana/data'; import { selectOptionInTest } from '@grafana/ui'; + import { Props, ConfigFromQueryTransformerEditor } from './ConfigFromQueryTransformerEditor'; beforeEach(() => { diff --git a/public/app/features/transformers/configFromQuery/ConfigFromQueryTransformerEditor.tsx b/public/app/features/transformers/configFromQuery/ConfigFromQueryTransformerEditor.tsx index 1a0a8303a44..081c87d8e00 100644 --- a/public/app/features/transformers/configFromQuery/ConfigFromQueryTransformerEditor.tsx +++ b/public/app/features/transformers/configFromQuery/ConfigFromQueryTransformerEditor.tsx @@ -1,4 +1,6 @@ +import { css } from '@emotion/css'; import React from 'react'; + import { FieldMatcherID, GrafanaTheme2, @@ -7,10 +9,11 @@ import { TransformerRegistryItem, TransformerUIProps, } from '@grafana/data'; -import { configFromDataTransformer, ConfigFromQueryTransformOptions } from './configFromQuery'; import { fieldMatchersUI, InlineField, InlineFieldRow, Select, useStyles2 } from '@grafana/ui'; + import { FieldToConfigMappingEditor } from '../fieldToConfigMapping/FieldToConfigMappingEditor'; -import { css } from '@emotion/css'; + +import { configFromDataTransformer, ConfigFromQueryTransformOptions } from './configFromQuery'; export interface Props extends TransformerUIProps {} diff --git a/public/app/features/transformers/configFromQuery/configFromQuery.test.ts b/public/app/features/transformers/configFromQuery/configFromQuery.test.ts index 99ecd9e9086..2e5266590c1 100644 --- a/public/app/features/transformers/configFromQuery/configFromQuery.test.ts +++ b/public/app/features/transformers/configFromQuery/configFromQuery.test.ts @@ -1,5 +1,7 @@ import { toDataFrame, FieldType, ReducerID } from '@grafana/data'; + import { FieldConfigHandlerKey } from '../fieldToConfigMapping/fieldToConfigMapping'; + import { extractConfigFromQuery, ConfigFromQueryTransformOptions } from './configFromQuery'; describe('config from data', () => { diff --git a/public/app/features/transformers/configFromQuery/configFromQuery.ts b/public/app/features/transformers/configFromQuery/configFromQuery.ts index 3f140f721d5..c114a2ce0d6 100644 --- a/public/app/features/transformers/configFromQuery/configFromQuery.ts +++ b/public/app/features/transformers/configFromQuery/configFromQuery.ts @@ -1,4 +1,5 @@ import { map } from 'rxjs/operators'; + import { ArrayVector, DataFrame, @@ -10,6 +11,7 @@ import { MatcherConfig, reduceField, } from '@grafana/data'; + import { getFieldConfigFromFrame, FieldToConfigMapping, diff --git a/public/app/features/transformers/editors/CalculateFieldTransformerEditor.tsx b/public/app/features/transformers/editors/CalculateFieldTransformerEditor.tsx index 6f7c1d97e4c..7cb6abcf1a0 100644 --- a/public/app/features/transformers/editors/CalculateFieldTransformerEditor.tsx +++ b/public/app/features/transformers/editors/CalculateFieldTransformerEditor.tsx @@ -1,6 +1,8 @@ +import { defaults } from 'lodash'; import React, { ChangeEvent } from 'react'; import { of, OperatorFunction } from 'rxjs'; import { map } from 'rxjs/operators'; + import { BinaryOperationID, binaryOperators, @@ -15,7 +17,6 @@ import { TransformerRegistryItem, TransformerUIProps, } from '@grafana/data'; -import { FilterPill, HorizontalGroup, Input, LegacyForms, Select, StatsPicker } from '@grafana/ui'; import { BinaryOptions, CalculateFieldMode, @@ -23,8 +24,7 @@ import { getNameFromOptions, ReduceOptions, } from '@grafana/data/src/transformations/transformers/calculateField'; - -import { defaults } from 'lodash'; +import { FilterPill, HorizontalGroup, Input, LegacyForms, Select, StatsPicker } from '@grafana/ui'; interface CalculateFieldTransformerEditorProps extends TransformerUIProps {} diff --git a/public/app/features/transformers/editors/ConcatenateTransformerEditor.tsx b/public/app/features/transformers/editors/ConcatenateTransformerEditor.tsx index 0e7749234f0..fe60117bd59 100644 --- a/public/app/features/transformers/editors/ConcatenateTransformerEditor.tsx +++ b/public/app/features/transformers/editors/ConcatenateTransformerEditor.tsx @@ -1,4 +1,5 @@ import React, { ChangeEvent } from 'react'; + import { DataTransformerID, SelectableValue, @@ -6,11 +7,11 @@ import { TransformerRegistryItem, TransformerUIProps, } from '@grafana/data'; -import { Input, Select } from '@grafana/ui'; import { ConcatenateFrameNameMode, ConcatenateTransformerOptions, } from '@grafana/data/src/transformations/transformers/concat'; +import { Input, Select } from '@grafana/ui'; interface ConcatenateTransformerEditorProps extends TransformerUIProps {} diff --git a/public/app/features/transformers/editors/ConvertFieldTypeTransformerEditor.tsx b/public/app/features/transformers/editors/ConvertFieldTypeTransformerEditor.tsx index 456761e5c5c..7d32106224c 100644 --- a/public/app/features/transformers/editors/ConvertFieldTypeTransformerEditor.tsx +++ b/public/app/features/transformers/editors/ConvertFieldTypeTransformerEditor.tsx @@ -1,4 +1,5 @@ import React, { ChangeEvent, useCallback } from 'react'; + import { DataTransformerID, FieldNamePickerConfigSettings, @@ -9,11 +10,11 @@ import { TransformerRegistryItem, TransformerUIProps, } from '@grafana/data'; - import { ConvertFieldTypeTransformerOptions } from '@grafana/data/src/transformations/transformers/convertFieldType'; import { Button, InlineField, InlineFieldRow, Input, Select } from '@grafana/ui'; -import { FieldNamePicker } from '../../../../../packages/grafana-ui/src/components/MatchersUI/FieldNamePicker'; + import { ConvertFieldTypeOptions } from '../../../../../packages/grafana-data/src/transformations/transformers/convertFieldType'; +import { FieldNamePicker } from '../../../../../packages/grafana-ui/src/components/MatchersUI/FieldNamePicker'; const fieldNamePickerSettings: StandardEditorsRegistryItem = { settings: { width: 24 }, diff --git a/public/app/features/transformers/editors/FilterByNameTransformerEditor.tsx b/public/app/features/transformers/editors/FilterByNameTransformerEditor.tsx index dcf3ec3d12c..edb19aef24a 100644 --- a/public/app/features/transformers/editors/FilterByNameTransformerEditor.tsx +++ b/public/app/features/transformers/editors/FilterByNameTransformerEditor.tsx @@ -1,4 +1,6 @@ +import { css } from '@emotion/css'; import React from 'react'; + import { DataTransformerID, KeyValue, @@ -8,9 +10,8 @@ import { getFieldDisplayName, stringToJsRegex, } from '@grafana/data'; -import { Field, Input, FilterPill, HorizontalGroup } from '@grafana/ui'; -import { css } from '@emotion/css'; import { FilterFieldsByNameTransformerOptions } from '@grafana/data/src/transformations/transformers/filterByName'; +import { Field, Input, FilterPill, HorizontalGroup } from '@grafana/ui'; interface FilterByNameTransformerEditorProps extends TransformerUIProps {} diff --git a/public/app/features/transformers/editors/FilterByRefIdTransformerEditor.tsx b/public/app/features/transformers/editors/FilterByRefIdTransformerEditor.tsx index f17536c3b58..036e8eb4bc8 100644 --- a/public/app/features/transformers/editors/FilterByRefIdTransformerEditor.tsx +++ b/public/app/features/transformers/editors/FilterByRefIdTransformerEditor.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { DataTransformerID, KeyValue, @@ -6,9 +7,8 @@ import { TransformerRegistryItem, TransformerUIProps, } from '@grafana/data'; -import { HorizontalGroup, FilterPill } from '@grafana/ui'; - import { FilterFramesByRefIdTransformerOptions } from '@grafana/data/src/transformations/transformers/filterByRefId'; +import { HorizontalGroup, FilterPill } from '@grafana/ui'; interface FilterByRefIdTransformerEditorProps extends TransformerUIProps {} diff --git a/public/app/features/transformers/editors/GroupByTransformerEditor.tsx b/public/app/features/transformers/editors/GroupByTransformerEditor.tsx index d6e6c372817..2812bf86848 100644 --- a/public/app/features/transformers/editors/GroupByTransformerEditor.tsx +++ b/public/app/features/transformers/editors/GroupByTransformerEditor.tsx @@ -1,5 +1,6 @@ -import React, { useCallback } from 'react'; import { css, cx } from '@emotion/css'; +import React, { useCallback } from 'react'; + import { DataTransformerID, ReducerID, @@ -8,13 +9,13 @@ import { TransformerRegistryItem, TransformerUIProps, } from '@grafana/data'; -import { Select, StatsPicker, stylesFactory } from '@grafana/ui'; - import { GroupByFieldOptions, GroupByOperationID, GroupByTransformerOptions, } from '@grafana/data/src/transformations/transformers/groupBy'; +import { Select, StatsPicker, stylesFactory } from '@grafana/ui'; + import { useAllFieldNamesFromDataFrames } from '../utils'; interface FieldProps { diff --git a/public/app/features/transformers/editors/GroupingToMatrixTransformerEditor.tsx b/public/app/features/transformers/editors/GroupingToMatrixTransformerEditor.tsx index 32cc311f61b..585493ce0ac 100644 --- a/public/app/features/transformers/editors/GroupingToMatrixTransformerEditor.tsx +++ b/public/app/features/transformers/editors/GroupingToMatrixTransformerEditor.tsx @@ -1,4 +1,5 @@ import React, { useCallback } from 'react'; + import { DataTransformerID, SelectableValue, @@ -8,6 +9,7 @@ import { GroupingToMatrixTransformerOptions, } from '@grafana/data'; import { InlineField, InlineFieldRow, Select } from '@grafana/ui'; + import { useAllFieldNamesFromDataFrames } from '../utils'; export const GroupingToMatrixTransformerEditor: React.FC> = ({ diff --git a/public/app/features/transformers/editors/HistogramTransformerEditor.tsx b/public/app/features/transformers/editors/HistogramTransformerEditor.tsx index 0b65a9fc8ae..82982aa8dee 100644 --- a/public/app/features/transformers/editors/HistogramTransformerEditor.tsx +++ b/public/app/features/transformers/editors/HistogramTransformerEditor.tsx @@ -1,6 +1,6 @@ import React, { FormEvent, useCallback } from 'react'; -import { DataTransformerID, standardTransformers, TransformerRegistryItem, TransformerUIProps } from '@grafana/data'; +import { DataTransformerID, standardTransformers, TransformerRegistryItem, TransformerUIProps } from '@grafana/data'; import { HistogramTransformerOptions, histogramFieldInfo, diff --git a/public/app/features/transformers/editors/LabelsToFieldsTransformerEditor.tsx b/public/app/features/transformers/editors/LabelsToFieldsTransformerEditor.tsx index 0101173bba1..a7f164cfe3d 100644 --- a/public/app/features/transformers/editors/LabelsToFieldsTransformerEditor.tsx +++ b/public/app/features/transformers/editors/LabelsToFieldsTransformerEditor.tsx @@ -1,4 +1,5 @@ import React, { useMemo } from 'react'; + import { DataTransformerID, SelectableValue, @@ -6,12 +7,11 @@ import { TransformerRegistryItem, TransformerUIProps, } from '@grafana/data'; -import { InlineField, InlineFieldRow, RadioButtonGroup, Select, FilterPill } from '@grafana/ui'; - import { LabelsToFieldsMode, LabelsToFieldsOptions, } from '@grafana/data/src/transformations/transformers/labelsToFields'; +import { InlineField, InlineFieldRow, RadioButtonGroup, Select, FilterPill } from '@grafana/ui'; const modes: Array> = [ { value: LabelsToFieldsMode.Columns, label: 'Columns' }, diff --git a/public/app/features/transformers/editors/MergeTransformerEditor.tsx b/public/app/features/transformers/editors/MergeTransformerEditor.tsx index c2905712d3e..69e86d4af89 100644 --- a/public/app/features/transformers/editors/MergeTransformerEditor.tsx +++ b/public/app/features/transformers/editors/MergeTransformerEditor.tsx @@ -1,8 +1,10 @@ import React from 'react'; + import { DataTransformerID, standardTransformers, TransformerRegistryItem, TransformerUIProps } from '@grafana/data'; -import { MergeTransformerOptions } from '../../../../../packages/grafana-data/src/transformations/transformers/merge'; import { FieldValidationMessage } from '@grafana/ui'; +import { MergeTransformerOptions } from '../../../../../packages/grafana-data/src/transformations/transformers/merge'; + export const MergeTransformerEditor: React.FC> = ({ input, options, diff --git a/public/app/features/transformers/editors/OrganizeFieldsTransformerEditor.tsx b/public/app/features/transformers/editors/OrganizeFieldsTransformerEditor.tsx index 2f7c9a2e023..95eec6a6230 100644 --- a/public/app/features/transformers/editors/OrganizeFieldsTransformerEditor.tsx +++ b/public/app/features/transformers/editors/OrganizeFieldsTransformerEditor.tsx @@ -1,6 +1,7 @@ -import React, { useCallback, useMemo } from 'react'; import { css } from '@emotion/css'; +import React, { useCallback, useMemo } from 'react'; import { DragDropContext, Draggable, Droppable, DropResult } from 'react-beautiful-dnd'; + import { DataTransformerID, GrafanaTheme, @@ -8,10 +9,10 @@ import { TransformerRegistryItem, TransformerUIProps, } from '@grafana/data'; +import { createOrderFieldsComparer } from '@grafana/data/src/transformations/transformers/order'; +import { OrganizeFieldsTransformerOptions } from '@grafana/data/src/transformations/transformers/organize'; import { stylesFactory, useTheme, Input, IconButton, Icon, FieldValidationMessage } from '@grafana/ui'; -import { OrganizeFieldsTransformerOptions } from '@grafana/data/src/transformations/transformers/organize'; -import { createOrderFieldsComparer } from '@grafana/data/src/transformations/transformers/order'; import { useAllFieldNamesFromDataFrames } from '../utils'; interface OrganizeFieldsTransformerEditorProps extends TransformerUIProps {} diff --git a/public/app/features/transformers/editors/ReduceTransformerEditor.tsx b/public/app/features/transformers/editors/ReduceTransformerEditor.tsx index 24be86576e0..188703a4d80 100644 --- a/public/app/features/transformers/editors/ReduceTransformerEditor.tsx +++ b/public/app/features/transformers/editors/ReduceTransformerEditor.tsx @@ -1,5 +1,5 @@ import React, { useCallback } from 'react'; -import { LegacyForms, Select, StatsPicker } from '@grafana/ui'; + import { DataTransformerID, ReducerID, @@ -8,9 +8,9 @@ import { TransformerRegistryItem, TransformerUIProps, } from '@grafana/data'; - import { ReduceTransformerMode, ReduceTransformerOptions } from '@grafana/data/src/transformations/transformers/reduce'; import { selectors } from '@grafana/e2e-selectors'; +import { LegacyForms, Select, StatsPicker } from '@grafana/ui'; // TODO: Minimal implementation, needs some <3 export const ReduceTransformerEditor: React.FC> = ({ diff --git a/public/app/features/transformers/editors/RenameByRegexTransformer.tsx b/public/app/features/transformers/editors/RenameByRegexTransformer.tsx index 23d16034d95..1fd61587cf0 100644 --- a/public/app/features/transformers/editors/RenameByRegexTransformer.tsx +++ b/public/app/features/transformers/editors/RenameByRegexTransformer.tsx @@ -1,4 +1,6 @@ +import { css } from '@emotion/css'; import React from 'react'; + import { DataTransformerID, standardTransformers, @@ -6,9 +8,8 @@ import { TransformerUIProps, stringToJsRegex, } from '@grafana/data'; -import { Field, Input } from '@grafana/ui'; -import { css } from '@emotion/css'; import { RenameByRegexTransformerOptions } from '@grafana/data/src/transformations/transformers/renameByRegex'; +import { Field, Input } from '@grafana/ui'; interface RenameByRegexTransformerEditorProps extends TransformerUIProps {} diff --git a/public/app/features/transformers/editors/SeriesToFieldsTransformerEditor.tsx b/public/app/features/transformers/editors/SeriesToFieldsTransformerEditor.tsx index 028c9c55d1a..82915e7fbd3 100644 --- a/public/app/features/transformers/editors/SeriesToFieldsTransformerEditor.tsx +++ b/public/app/features/transformers/editors/SeriesToFieldsTransformerEditor.tsx @@ -1,4 +1,5 @@ import React, { useCallback } from 'react'; + import { DataTransformerID, SelectableValue, @@ -6,9 +7,9 @@ import { TransformerRegistryItem, TransformerUIProps, } from '@grafana/data'; +import { SeriesToColumnsOptions } from '@grafana/data/src/transformations/transformers/seriesToColumns'; import { Select } from '@grafana/ui'; -import { SeriesToColumnsOptions } from '@grafana/data/src/transformations/transformers/seriesToColumns'; import { useAllFieldNamesFromDataFrames } from '../utils'; export const SeriesToFieldsTransformerEditor: React.FC> = ({ diff --git a/public/app/features/transformers/editors/SeriesToRowsTransformerEditor.tsx b/public/app/features/transformers/editors/SeriesToRowsTransformerEditor.tsx index 0355877f97c..01673a5bcda 100644 --- a/public/app/features/transformers/editors/SeriesToRowsTransformerEditor.tsx +++ b/public/app/features/transformers/editors/SeriesToRowsTransformerEditor.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { DataTransformerID, standardTransformers, TransformerRegistryItem, TransformerUIProps } from '@grafana/data'; import { SeriesToRowsTransformerOptions } from '@grafana/data/src/transformations/transformers/seriesToRows'; diff --git a/public/app/features/transformers/editors/SortByTransformerEditor.tsx b/public/app/features/transformers/editors/SortByTransformerEditor.tsx index 51c931fc1b0..f7b27f71f68 100644 --- a/public/app/features/transformers/editors/SortByTransformerEditor.tsx +++ b/public/app/features/transformers/editors/SortByTransformerEditor.tsx @@ -1,7 +1,9 @@ import React, { useCallback } from 'react'; + import { DataTransformerID, standardTransformers, TransformerRegistryItem, TransformerUIProps } from '@grafana/data'; -import { InlineField, InlineSwitch, InlineFieldRow, Select } from '@grafana/ui'; import { SortByField, SortByTransformerOptions } from '@grafana/data/src/transformations/transformers/sortBy'; +import { InlineField, InlineSwitch, InlineFieldRow, Select } from '@grafana/ui'; + import { useAllFieldNamesFromDataFrames } from '../utils'; export const SortByTransformerEditor: React.FC> = ({ diff --git a/public/app/features/transformers/extractFields/ExtractFieldsTransformerEditor.tsx b/public/app/features/transformers/extractFields/ExtractFieldsTransformerEditor.tsx index d7a868b7c2a..deff6aade82 100644 --- a/public/app/features/transformers/extractFields/ExtractFieldsTransformerEditor.tsx +++ b/public/app/features/transformers/extractFields/ExtractFieldsTransformerEditor.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { DataTransformerID, FieldNamePickerConfigSettings, @@ -8,9 +9,9 @@ import { TransformerRegistryItem, TransformerUIProps, } from '@grafana/data'; - import { InlineField, InlineFieldRow, InlineSwitch, Select } from '@grafana/ui'; import { FieldNamePicker } from '@grafana/ui/src/components/MatchersUI/FieldNamePicker'; + import { ExtractFieldsOptions, extractFieldsTransformer } from './extractFields'; import { FieldExtractorID, fieldExtractors } from './fieldExtractors'; diff --git a/public/app/features/transformers/extractFields/extractFields.test.ts b/public/app/features/transformers/extractFields/extractFields.test.ts index 753cd065950..a25d7b299d0 100644 --- a/public/app/features/transformers/extractFields/extractFields.test.ts +++ b/public/app/features/transformers/extractFields/extractFields.test.ts @@ -1,4 +1,5 @@ import { toDataFrame } from '@grafana/data/src/dataframe/processDataFrame'; + import { ExtractFieldsOptions, extractFieldsTransformer } from './extractFields'; describe('Fields from JSON', () => { diff --git a/public/app/features/transformers/extractFields/extractFields.ts b/public/app/features/transformers/extractFields/extractFields.ts index 2d2707ee959..81628b595ed 100644 --- a/public/app/features/transformers/extractFields/extractFields.ts +++ b/public/app/features/transformers/extractFields/extractFields.ts @@ -1,3 +1,6 @@ +import { isString } from 'lodash'; +import { map } from 'rxjs/operators'; + import { ArrayVector, DataFrame, @@ -8,8 +11,7 @@ import { SynchronousDataTransformerInfo, } from '@grafana/data'; import { findField } from 'app/features/dimensions'; -import { isString } from 'lodash'; -import { map } from 'rxjs/operators'; + import { FieldExtractorID, fieldExtractors } from './fieldExtractors'; export interface ExtractFieldsOptions { diff --git a/public/app/features/transformers/fieldToConfigMapping/FieldToConfigMappingEditor.test.tsx b/public/app/features/transformers/fieldToConfigMapping/FieldToConfigMappingEditor.test.tsx index cd709e4a2c4..c2ac51effb9 100644 --- a/public/app/features/transformers/fieldToConfigMapping/FieldToConfigMappingEditor.test.tsx +++ b/public/app/features/transformers/fieldToConfigMapping/FieldToConfigMappingEditor.test.tsx @@ -1,8 +1,10 @@ -import React from 'react'; -import { toDataFrame, FieldType } from '@grafana/data'; import { fireEvent, render, screen, getByText, getByLabelText } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import React from 'react'; + +import { toDataFrame, FieldType } from '@grafana/data'; import { selectOptionInTest } from '@grafana/ui'; + import { Props, FieldToConfigMappingEditor } from './FieldToConfigMappingEditor'; beforeEach(() => { diff --git a/public/app/features/transformers/fieldToConfigMapping/FieldToConfigMappingEditor.tsx b/public/app/features/transformers/fieldToConfigMapping/FieldToConfigMappingEditor.tsx index d65317ac1f9..67df4834c06 100644 --- a/public/app/features/transformers/fieldToConfigMapping/FieldToConfigMappingEditor.tsx +++ b/public/app/features/transformers/fieldToConfigMapping/FieldToConfigMappingEditor.tsx @@ -1,7 +1,10 @@ +import { css } from '@emotion/css'; +import { capitalize } from 'lodash'; import React from 'react'; + import { DataFrame, getFieldDisplayName, GrafanaTheme2, ReducerID, SelectableValue } from '@grafana/data'; import { Select, StatsPicker, useStyles2 } from '@grafana/ui'; -import { css } from '@emotion/css'; + import { configMapHandlers, evaluteFieldMappings, @@ -9,7 +12,6 @@ import { FieldToConfigMapping, lookUpConfigHandler as findConfigHandlerFor, } from '../fieldToConfigMapping/fieldToConfigMapping'; -import { capitalize } from 'lodash'; export interface Props { frame: DataFrame; diff --git a/public/app/features/transformers/fieldToConfigMapping/fieldToConfigMapping.ts b/public/app/features/transformers/fieldToConfigMapping/fieldToConfigMapping.ts index 8795d73c5e2..36995d4085d 100644 --- a/public/app/features/transformers/fieldToConfigMapping/fieldToConfigMapping.ts +++ b/public/app/features/transformers/fieldToConfigMapping/fieldToConfigMapping.ts @@ -1,3 +1,5 @@ +import { isArray } from 'lodash'; + import { anyToNumber, DataFrame, @@ -12,7 +14,6 @@ import { Field, FieldType, } from '@grafana/data'; -import { isArray } from 'lodash'; export interface FieldToConfigMapping { fieldName: string; diff --git a/public/app/features/transformers/lookupGazetteer/FieldLookupTransformerEditor.tsx b/public/app/features/transformers/lookupGazetteer/FieldLookupTransformerEditor.tsx index 2739bcc1af9..fcc9af08c37 100644 --- a/public/app/features/transformers/lookupGazetteer/FieldLookupTransformerEditor.tsx +++ b/public/app/features/transformers/lookupGazetteer/FieldLookupTransformerEditor.tsx @@ -1,4 +1,5 @@ import React, { useCallback } from 'react'; + import { DataTransformerID, FieldNamePickerConfigSettings, @@ -8,12 +9,12 @@ import { TransformerUIProps, FieldType, } from '@grafana/data'; - import { InlineField, InlineFieldRow } from '@grafana/ui'; import { FieldNamePicker } from '@grafana/ui/src/components/MatchersUI/FieldNamePicker'; -import { FieldLookupOptions, fieldLookupTransformer } from './fieldLookup'; import { GazetteerPathEditor, GazetteerPathEditorConfigSettings } from 'app/features/geo/editor/GazetteerPathEditor'; +import { FieldLookupOptions, fieldLookupTransformer } from './fieldLookup'; + const fieldNamePickerSettings: StandardEditorsRegistryItem = { settings: { width: 30, diff --git a/public/app/features/transformers/lookupGazetteer/fieldLookup.test.ts b/public/app/features/transformers/lookupGazetteer/fieldLookup.test.ts index 85a68668253..be0f273246f 100644 --- a/public/app/features/transformers/lookupGazetteer/fieldLookup.test.ts +++ b/public/app/features/transformers/lookupGazetteer/fieldLookup.test.ts @@ -2,6 +2,7 @@ import { FieldMatcherID, fieldMatchers, FieldType } from '@grafana/data'; import { toDataFrame } from '@grafana/data/src/dataframe/processDataFrame'; import { DataTransformerID } from '@grafana/data/src/transformations/transformers/ids'; import { frameAsGazetter } from 'app/features/geo/gazetteer/gazetteer'; + import { addFieldsFromGazetteer } from './fieldLookup'; describe('Lookup gazetteer', () => { diff --git a/public/app/features/transformers/lookupGazetteer/fieldLookup.ts b/public/app/features/transformers/lookupGazetteer/fieldLookup.ts index 8bf78259cd4..ccaf1da4926 100644 --- a/public/app/features/transformers/lookupGazetteer/fieldLookup.ts +++ b/public/app/features/transformers/lookupGazetteer/fieldLookup.ts @@ -1,3 +1,5 @@ +import { mergeMap, from } from 'rxjs'; + import { ArrayVector, DataFrame, @@ -9,7 +11,6 @@ import { DataTransformerInfo, } from '@grafana/data'; import { COUNTRIES_GAZETTEER_PATH, Gazetteer, getGazetteer } from 'app/features/geo/gazetteer/gazetteer'; -import { mergeMap, from } from 'rxjs'; export interface FieldLookupOptions { lookupField?: string; diff --git a/public/app/features/transformers/prepareTimeSeries/PrepareTimeSeriesEditor.tsx b/public/app/features/transformers/prepareTimeSeries/PrepareTimeSeriesEditor.tsx index fc31ff4351a..dadb684e2cd 100644 --- a/public/app/features/transformers/prepareTimeSeries/PrepareTimeSeriesEditor.tsx +++ b/public/app/features/transformers/prepareTimeSeries/PrepareTimeSeriesEditor.tsx @@ -1,8 +1,10 @@ -import React, { useCallback } from 'react'; -import { GrafanaTheme2, SelectableValue, TransformerRegistryItem, TransformerUIProps } from '@grafana/data'; -import { prepareTimeSeriesTransformer, PrepareTimeSeriesOptions, timeSeriesFormat } from './prepareTimeSeries'; -import { InlineField, InlineFieldRow, Select, useStyles2 } from '@grafana/ui'; import { css } from '@emotion/css'; +import React, { useCallback } from 'react'; + +import { GrafanaTheme2, SelectableValue, TransformerRegistryItem, TransformerUIProps } from '@grafana/data'; +import { InlineField, InlineFieldRow, Select, useStyles2 } from '@grafana/ui'; + +import { prepareTimeSeriesTransformer, PrepareTimeSeriesOptions, timeSeriesFormat } from './prepareTimeSeries'; const wideInfo = { label: 'Wide time series', diff --git a/public/app/features/transformers/prepareTimeSeries/prepareTimeSeries.test.ts b/public/app/features/transformers/prepareTimeSeries/prepareTimeSeries.test.ts index 059a0aed15c..4dd2dc7b030 100644 --- a/public/app/features/transformers/prepareTimeSeries/prepareTimeSeries.test.ts +++ b/public/app/features/transformers/prepareTimeSeries/prepareTimeSeries.test.ts @@ -8,6 +8,7 @@ import { DataFrameType, getFrameDisplayName, } from '@grafana/data'; + import { prepareTimeSeriesTransformer, PrepareTimeSeriesOptions, timeSeriesFormat } from './prepareTimeSeries'; describe('Prepare time series transformer', () => { diff --git a/public/app/features/transformers/prepareTimeSeries/prepareTimeSeries.ts b/public/app/features/transformers/prepareTimeSeries/prepareTimeSeries.ts index e2248bc4502..14b68b3fd3c 100644 --- a/public/app/features/transformers/prepareTimeSeries/prepareTimeSeries.ts +++ b/public/app/features/transformers/prepareTimeSeries/prepareTimeSeries.ts @@ -1,3 +1,5 @@ +import { map } from 'rxjs/operators'; + import { SynchronousDataTransformerInfo, DataFrame, @@ -12,7 +14,6 @@ import { ArrayVector, } from '@grafana/data'; import { Labels } from 'app/types/unified-alerting-dto'; -import { map } from 'rxjs/operators'; /** * There is currently an effort to figure out consistent names diff --git a/public/app/features/transformers/rowsToFields/RowsToFieldsTransformerEditor.test.tsx b/public/app/features/transformers/rowsToFields/RowsToFieldsTransformerEditor.test.tsx index 3f9958dbb0f..f66f5748ae3 100644 --- a/public/app/features/transformers/rowsToFields/RowsToFieldsTransformerEditor.test.tsx +++ b/public/app/features/transformers/rowsToFields/RowsToFieldsTransformerEditor.test.tsx @@ -1,7 +1,9 @@ -import React from 'react'; -import { toDataFrame, FieldType } from '@grafana/data'; import { fireEvent, render, screen } from '@testing-library/react'; +import React from 'react'; + +import { toDataFrame, FieldType } from '@grafana/data'; import { selectOptionInTest } from '@grafana/ui'; + import { Props, RowsToFieldsTransformerEditor } from './RowsToFieldsTransformerEditor'; beforeEach(() => { diff --git a/public/app/features/transformers/rowsToFields/RowsToFieldsTransformerEditor.tsx b/public/app/features/transformers/rowsToFields/RowsToFieldsTransformerEditor.tsx index 727df3b1691..2bac83c6add 100644 --- a/public/app/features/transformers/rowsToFields/RowsToFieldsTransformerEditor.tsx +++ b/public/app/features/transformers/rowsToFields/RowsToFieldsTransformerEditor.tsx @@ -1,8 +1,11 @@ import React from 'react'; + import { PluginState, TransformerRegistryItem, TransformerUIProps } from '@grafana/data'; -import { rowsToFieldsTransformer, RowToFieldsTransformOptions } from './rowsToFields'; + import { FieldToConfigMappingEditor } from '../fieldToConfigMapping/FieldToConfigMappingEditor'; +import { rowsToFieldsTransformer, RowToFieldsTransformOptions } from './rowsToFields'; + export interface Props extends TransformerUIProps {} export function RowsToFieldsTransformerEditor({ input, options, onChange }: Props) { diff --git a/public/app/features/transformers/rowsToFields/rowsToFields.test.ts b/public/app/features/transformers/rowsToFields/rowsToFields.test.ts index 29bdff2e750..9b6c6f3b583 100644 --- a/public/app/features/transformers/rowsToFields/rowsToFields.test.ts +++ b/public/app/features/transformers/rowsToFields/rowsToFields.test.ts @@ -1,4 +1,5 @@ import { toDataFrame, FieldType } from '@grafana/data'; + import { rowsToFields } from './rowsToFields'; describe('Rows to fields', () => { diff --git a/public/app/features/transformers/rowsToFields/rowsToFields.ts b/public/app/features/transformers/rowsToFields/rowsToFields.ts index b72b9516752..6874073a6af 100644 --- a/public/app/features/transformers/rowsToFields/rowsToFields.ts +++ b/public/app/features/transformers/rowsToFields/rowsToFields.ts @@ -1,4 +1,5 @@ import { map } from 'rxjs/operators'; + import { ArrayVector, DataFrame, @@ -8,6 +9,7 @@ import { getFieldDisplayName, Labels, } from '@grafana/data'; + import { getFieldConfigFromFrame, FieldToConfigMapping, diff --git a/public/app/features/transformers/spatial/SpatialTransformerEditor.tsx b/public/app/features/transformers/spatial/SpatialTransformerEditor.tsx index a3e1fbe8baf..f61bfb2ffd5 100644 --- a/public/app/features/transformers/spatial/SpatialTransformerEditor.tsx +++ b/public/app/features/transformers/spatial/SpatialTransformerEditor.tsx @@ -1,5 +1,6 @@ -import React, { useEffect } from 'react'; import { css } from '@emotion/css'; +import React, { useEffect } from 'react'; + import { DataTransformerID, FrameGeometrySource, @@ -11,12 +12,12 @@ import { TransformerRegistryItem, TransformerUIProps, } from '@grafana/data'; - -import { isLineBuilderOption, spatialTransformer } from './spatialTransformer'; -import { addLocationFields } from 'app/features/geo/editor/locationEditor'; -import { getDefaultOptions, getTransformerOptionPane } from './optionsHelper'; -import { SpatialCalculation, SpatialOperation, SpatialAction, SpatialTransformOptions } from './models.gen'; import { useTheme2 } from '@grafana/ui'; +import { addLocationFields } from 'app/features/geo/editor/locationEditor'; + +import { SpatialCalculation, SpatialOperation, SpatialAction, SpatialTransformOptions } from './models.gen'; +import { getDefaultOptions, getTransformerOptionPane } from './optionsHelper'; +import { isLineBuilderOption, spatialTransformer } from './spatialTransformer'; // Nothing defined in state const supplier = ( diff --git a/public/app/features/transformers/spatial/optionsHelper.tsx b/public/app/features/transformers/spatial/optionsHelper.tsx index 07ade5b3824..8c60d6527bf 100644 --- a/public/app/features/transformers/spatial/optionsHelper.tsx +++ b/public/app/features/transformers/spatial/optionsHelper.tsx @@ -1,10 +1,11 @@ +import { set, get as lodashGet } from 'lodash'; + import { StandardEditorContext, TransformerUIProps, PanelOptionsEditorBuilder } from '@grafana/data'; -import { OptionsPaneCategoryDescriptor } from 'app/features/dashboard/components/PanelEditor/OptionsPaneCategoryDescriptor'; import { PanelOptionsSupplier } from '@grafana/data/src/panel/PanelPlugin'; import { NestedValueAccess } from '@grafana/data/src/utils/OptionsUIBuilders'; -import { set, get as lodashGet } from 'lodash'; -import { setOptionImmutably } from 'app/features/dashboard/components/PanelEditor/utils'; +import { OptionsPaneCategoryDescriptor } from 'app/features/dashboard/components/PanelEditor/OptionsPaneCategoryDescriptor'; import { fillOptionsPaneItems } from 'app/features/dashboard/components/PanelEditor/getVisualizationOptions'; +import { setOptionImmutably } from 'app/features/dashboard/components/PanelEditor/utils'; export function getTransformerOptionPane( props: TransformerUIProps, diff --git a/public/app/features/transformers/spatial/spatialTransformer.ts b/public/app/features/transformers/spatial/spatialTransformer.ts index 03b2a4d2dc3..2c73a5603c6 100644 --- a/public/app/features/transformers/spatial/spatialTransformer.ts +++ b/public/app/features/transformers/spatial/spatialTransformer.ts @@ -1,7 +1,9 @@ +import { mergeMap, from } from 'rxjs'; + import { ArrayVector, DataFrame, DataTransformerID, DataTransformerInfo, FieldType } from '@grafana/data'; import { createGeometryCollection, createLineBetween } from 'app/features/geo/format/utils'; import { getGeometryField, getLocationMatchers } from 'app/features/geo/utils/location'; -import { mergeMap, from } from 'rxjs'; + import { SpatialOperation, SpatialAction, SpatialTransformOptions } from './models.gen'; import { doGeomeryCalculation, toLineString } from './utils'; diff --git a/public/app/features/transformers/spatial/utils.ts b/public/app/features/transformers/spatial/utils.ts index 5a4ab6de23b..c1d1f9dd0dd 100644 --- a/public/app/features/transformers/spatial/utils.ts +++ b/public/app/features/transformers/spatial/utils.ts @@ -1,8 +1,10 @@ -import { ArrayVector, Field, FieldType } from '@grafana/data'; import { getCenter } from 'ol/extent'; import { Geometry, LineString, Point } from 'ol/geom'; import { toLonLat } from 'ol/proj'; import { getArea, getLength } from 'ol/sphere'; + +import { ArrayVector, Field, FieldType } from '@grafana/data'; + import { SpatialCalculation, SpatialCalculationOption } from './models.gen'; /** Will return a field with a single row */ diff --git a/public/app/features/transformers/standardTransformers.ts b/public/app/features/transformers/standardTransformers.ts index 3618d03c246..83ed7104dca 100644 --- a/public/app/features/transformers/standardTransformers.ts +++ b/public/app/features/transformers/standardTransformers.ts @@ -1,28 +1,29 @@ import { TransformerRegistryItem } from '@grafana/data'; -import { reduceTransformRegistryItem } from './editors/ReduceTransformerEditor'; + +import { filterByValueTransformRegistryItem } from './FilterByValueTransformer/FilterByValueTransformerEditor'; +import { heatmapTransformRegistryItem } from './calculateHeatmap/HeatmapTransformerEditor'; +import { configFromQueryTransformRegistryItem } from './configFromQuery/ConfigFromQueryTransformerEditor'; +import { calculateFieldTransformRegistryItem } from './editors/CalculateFieldTransformerEditor'; +import { concatenateTransformRegistryItem } from './editors/ConcatenateTransformerEditor'; +import { convertFieldTypeTransformRegistryItem } from './editors/ConvertFieldTypeTransformerEditor'; import { filterFieldsByNameTransformRegistryItem } from './editors/FilterByNameTransformerEditor'; import { filterFramesByRefIdTransformRegistryItem } from './editors/FilterByRefIdTransformerEditor'; -import { filterByValueTransformRegistryItem } from './FilterByValueTransformer/FilterByValueTransformerEditor'; -import { organizeFieldsTransformRegistryItem } from './editors/OrganizeFieldsTransformerEditor'; -import { seriesToFieldsTransformerRegistryItem } from './editors/SeriesToFieldsTransformerEditor'; -import { calculateFieldTransformRegistryItem } from './editors/CalculateFieldTransformerEditor'; -import { labelsToFieldsTransformerRegistryItem } from './editors/LabelsToFieldsTransformerEditor'; import { groupByTransformRegistryItem } from './editors/GroupByTransformerEditor'; -import { sortByTransformRegistryItem } from './editors/SortByTransformerEditor'; -import { mergeTransformerRegistryItem } from './editors/MergeTransformerEditor'; -import { seriesToRowsTransformerRegistryItem } from './editors/SeriesToRowsTransformerEditor'; -import { concatenateTransformRegistryItem } from './editors/ConcatenateTransformerEditor'; -import { renameByRegexTransformRegistryItem } from './editors/RenameByRegexTransformer'; -import { histogramTransformRegistryItem } from './editors/HistogramTransformerEditor'; -import { rowsToFieldsTransformRegistryItem } from './rowsToFields/RowsToFieldsTransformerEditor'; -import { configFromQueryTransformRegistryItem } from './configFromQuery/ConfigFromQueryTransformerEditor'; -import { prepareTimeseriesTransformerRegistryItem } from './prepareTimeSeries/PrepareTimeSeriesEditor'; -import { convertFieldTypeTransformRegistryItem } from './editors/ConvertFieldTypeTransformerEditor'; -import { fieldLookupTransformRegistryItem } from './lookupGazetteer/FieldLookupTransformerEditor'; -import { extractFieldsTransformRegistryItem } from './extractFields/ExtractFieldsTransformerEditor'; -import { heatmapTransformRegistryItem } from './calculateHeatmap/HeatmapTransformerEditor'; -import { spatialTransformRegistryItem } from './spatial/SpatialTransformerEditor'; import { groupingToMatrixTransformRegistryItem } from './editors/GroupingToMatrixTransformerEditor'; +import { histogramTransformRegistryItem } from './editors/HistogramTransformerEditor'; +import { labelsToFieldsTransformerRegistryItem } from './editors/LabelsToFieldsTransformerEditor'; +import { mergeTransformerRegistryItem } from './editors/MergeTransformerEditor'; +import { organizeFieldsTransformRegistryItem } from './editors/OrganizeFieldsTransformerEditor'; +import { reduceTransformRegistryItem } from './editors/ReduceTransformerEditor'; +import { renameByRegexTransformRegistryItem } from './editors/RenameByRegexTransformer'; +import { seriesToFieldsTransformerRegistryItem } from './editors/SeriesToFieldsTransformerEditor'; +import { seriesToRowsTransformerRegistryItem } from './editors/SeriesToRowsTransformerEditor'; +import { sortByTransformRegistryItem } from './editors/SortByTransformerEditor'; +import { extractFieldsTransformRegistryItem } from './extractFields/ExtractFieldsTransformerEditor'; +import { fieldLookupTransformRegistryItem } from './lookupGazetteer/FieldLookupTransformerEditor'; +import { prepareTimeseriesTransformerRegistryItem } from './prepareTimeSeries/PrepareTimeSeriesEditor'; +import { rowsToFieldsTransformRegistryItem } from './rowsToFields/RowsToFieldsTransformerEditor'; +import { spatialTransformRegistryItem } from './spatial/SpatialTransformerEditor'; export const getStandardTransformers = (): Array> => { return [ diff --git a/public/app/features/transformers/utils.ts b/public/app/features/transformers/utils.ts index 4bb949169a0..6a942d6c55b 100644 --- a/public/app/features/transformers/utils.ts +++ b/public/app/features/transformers/utils.ts @@ -1,6 +1,7 @@ -import { DataFrame, getFieldDisplayName } from '@grafana/data'; import { useMemo } from 'react'; +import { DataFrame, getFieldDisplayName } from '@grafana/data'; + export function useAllFieldNamesFromDataFrames(input: DataFrame[]): string[] { return useMemo(() => { if (!Array.isArray(input)) { diff --git a/public/app/features/users/TokenRevokedModal.tsx b/public/app/features/users/TokenRevokedModal.tsx index 9ba3ed36df1..912a1819ff2 100644 --- a/public/app/features/users/TokenRevokedModal.tsx +++ b/public/app/features/users/TokenRevokedModal.tsx @@ -1,8 +1,9 @@ +import { css, cx } from '@emotion/css'; import React from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; import { Button, InfoBox, Portal, stylesFactory, useTheme2 } from '@grafana/ui'; import { getModalStyles } from '@grafana/ui/src/components/Modal/getModalStyles'; -import { css, cx } from '@emotion/css'; -import { GrafanaTheme2 } from '@grafana/data'; interface Props { maxConcurrentSessions?: number; diff --git a/public/app/features/users/UsersActionBar.test.tsx b/public/app/features/users/UsersActionBar.test.tsx index ea04bb7cbdb..a9e9c4b4490 100644 --- a/public/app/features/users/UsersActionBar.test.tsx +++ b/public/app/features/users/UsersActionBar.test.tsx @@ -1,7 +1,8 @@ -import React from 'react'; import { shallow } from 'enzyme'; -import { Props, UsersActionBar } from './UsersActionBar'; +import React from 'react'; import { mockToolkitActionCreator } from 'test/core/redux/mocks'; + +import { Props, UsersActionBar } from './UsersActionBar'; import { setUsersSearchQuery } from './state/reducers'; jest.mock('app/core/core', () => ({ diff --git a/public/app/features/users/UsersActionBar.tsx b/public/app/features/users/UsersActionBar.tsx index 9e4765490fd..05b1166b2c1 100644 --- a/public/app/features/users/UsersActionBar.tsx +++ b/public/app/features/users/UsersActionBar.tsx @@ -1,12 +1,15 @@ import React, { PureComponent } from 'react'; import { connect } from 'react-redux'; -import { setUsersSearchQuery } from './state/reducers'; -import { selectTotal } from '../invites/state/selectors'; -import { getUsersSearchQuery } from './state/selectors'; + import { RadioButtonGroup, LinkButton, FilterInput } from '@grafana/ui'; import { contextSrv } from 'app/core/core'; import { AccessControlAction } from 'app/types'; +import { selectTotal } from '../invites/state/selectors'; + +import { setUsersSearchQuery } from './state/reducers'; +import { getUsersSearchQuery } from './state/selectors'; + export interface Props { searchQuery: string; setUsersSearchQuery: typeof setUsersSearchQuery; diff --git a/public/app/features/users/UsersListPage.test.tsx b/public/app/features/users/UsersListPage.test.tsx index 4907b7403a6..bc334b6287a 100644 --- a/public/app/features/users/UsersListPage.test.tsx +++ b/public/app/features/users/UsersListPage.test.tsx @@ -1,10 +1,11 @@ -import React from 'react'; import { shallow } from 'enzyme'; -import { Props, UsersListPage } from './UsersListPage'; -import { Invitee, OrgUser } from 'app/types'; -// import { getMockUser } from './__mocks__/userMocks'; -import { NavModel } from '@grafana/data'; +import React from 'react'; import { mockToolkitActionCreator } from 'test/core/redux/mocks'; + +import { NavModel } from '@grafana/data'; +import { Invitee, OrgUser } from 'app/types'; + +import { Props, UsersListPage } from './UsersListPage'; import { setUsersSearchPage, setUsersSearchQuery } from './state/reducers'; jest.mock('../../core/app_events', () => ({ diff --git a/public/app/features/users/UsersListPage.tsx b/public/app/features/users/UsersListPage.tsx index 1083b4f9ac1..f53b3f47b9f 100644 --- a/public/app/features/users/UsersListPage.tsx +++ b/public/app/features/users/UsersListPage.tsx @@ -1,19 +1,21 @@ import React, { PureComponent } from 'react'; import { connect, ConnectedProps } from 'react-redux'; + import { renderMarkdown } from '@grafana/data'; import { HorizontalGroup, Pagination, VerticalGroup } from '@grafana/ui'; - import Page from 'app/core/components/Page/Page'; +import { getNavModel } from 'app/core/selectors/navModel'; +import { OrgUser, OrgRole, StoreState } from 'app/types'; + +import InviteesTable from '../invites/InviteesTable'; +import { fetchInvitees } from '../invites/state/actions'; +import { selectInvitesMatchingQuery } from '../invites/state/selectors'; + import UsersActionBar from './UsersActionBar'; import UsersTable from './UsersTable'; -import InviteesTable from '../invites/InviteesTable'; -import { OrgUser, OrgRole, StoreState } from 'app/types'; import { loadUsers, removeUser, updateUser } from './state/actions'; -import { fetchInvitees } from '../invites/state/actions'; -import { getNavModel } from 'app/core/selectors/navModel'; -import { getUsers, getUsersSearchQuery, getUsersSearchPage } from './state/selectors'; import { setUsersSearchQuery, setUsersSearchPage } from './state/reducers'; -import { selectInvitesMatchingQuery } from '../invites/state/selectors'; +import { getUsers, getUsersSearchQuery, getUsersSearchPage } from './state/selectors'; function mapStateToProps(state: StoreState) { const searchQuery = getUsersSearchQuery(state.users); diff --git a/public/app/features/users/UsersTable.test.tsx b/public/app/features/users/UsersTable.test.tsx index f71e0517eb7..8782c0bdb64 100644 --- a/public/app/features/users/UsersTable.test.tsx +++ b/public/app/features/users/UsersTable.test.tsx @@ -1,9 +1,11 @@ -import React from 'react'; import { shallow } from 'enzyme'; -import UsersTable, { Props } from './UsersTable'; -import { OrgUser } from 'app/types'; -import { getMockUsers } from './__mocks__/userMocks'; +import React from 'react'; + import { ConfirmModal } from '@grafana/ui'; +import { OrgUser } from 'app/types'; + +import UsersTable, { Props } from './UsersTable'; +import { getMockUsers } from './__mocks__/userMocks'; jest.mock('app/core/core', () => ({ contextSrv: { diff --git a/public/app/features/users/UsersTable.tsx b/public/app/features/users/UsersTable.tsx index c5c05f1faf2..aee80c96897 100644 --- a/public/app/features/users/UsersTable.tsx +++ b/public/app/features/users/UsersTable.tsx @@ -1,11 +1,13 @@ import React, { FC, useEffect, useState } from 'react'; -import { AccessControlAction, OrgUser, Role } from 'app/types'; -import { OrgRolePicker } from '../admin/OrgRolePicker'; -import { Button, ConfirmModal } from '@grafana/ui'; + import { OrgRole } from '@grafana/data'; -import { contextSrv } from 'app/core/core'; -import { fetchBuiltinRoles, fetchRoleOptions } from 'app/core/components/RolePicker/api'; +import { Button, ConfirmModal } from '@grafana/ui'; import { UserRolePicker } from 'app/core/components/RolePicker/UserRolePicker'; +import { fetchBuiltinRoles, fetchRoleOptions } from 'app/core/components/RolePicker/api'; +import { contextSrv } from 'app/core/core'; +import { AccessControlAction, OrgUser, Role } from 'app/types'; + +import { OrgRolePicker } from '../admin/OrgRolePicker'; export interface Props { users: OrgUser[]; diff --git a/public/app/features/users/state/actions.ts b/public/app/features/users/state/actions.ts index 8d36742c584..259d0d1829d 100644 --- a/public/app/features/users/state/actions.ts +++ b/public/app/features/users/state/actions.ts @@ -1,8 +1,10 @@ -import { ThunkResult } from '../../../types'; import { getBackendSrv } from '@grafana/runtime'; -import { OrgUser } from 'app/types'; -import { usersLoaded } from './reducers'; import { accessControlQueryParam } from 'app/core/utils/accessControl'; +import { OrgUser } from 'app/types'; + +import { ThunkResult } from '../../../types'; + +import { usersLoaded } from './reducers'; export function loadUsers(): ThunkResult { return async (dispatch) => { diff --git a/public/app/features/users/state/reducers.test.ts b/public/app/features/users/state/reducers.test.ts index 6499959c449..c5634126f0b 100644 --- a/public/app/features/users/state/reducers.test.ts +++ b/public/app/features/users/state/reducers.test.ts @@ -1,8 +1,9 @@ import { reducerTester } from '../../../../test/core/redux/reducerTester'; import { UsersState } from '../../../types'; -import { initialState, setUsersSearchQuery, usersLoaded, usersReducer } from './reducers'; import { getMockUsers } from '../__mocks__/userMocks'; +import { initialState, setUsersSearchQuery, usersLoaded, usersReducer } from './reducers'; + describe('usersReducer', () => { describe('when usersLoaded is dispatched', () => { it('then state should be correct', () => { diff --git a/public/app/features/users/state/reducers.ts b/public/app/features/users/state/reducers.ts index 436feccdd78..8b77465357b 100644 --- a/public/app/features/users/state/reducers.ts +++ b/public/app/features/users/state/reducers.ts @@ -1,7 +1,7 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit'; -import { OrgUser, UsersState } from 'app/types'; import config from 'app/core/config'; +import { OrgUser, UsersState } from 'app/types'; export const initialState: UsersState = { users: [] as OrgUser[], diff --git a/public/app/features/variables/adapters.ts b/public/app/features/variables/adapters.ts index ad76e41229d..0f52ab42f4a 100644 --- a/public/app/features/variables/adapters.ts +++ b/public/app/features/variables/adapters.ts @@ -1,11 +1,12 @@ import { ComponentType } from 'react'; import { Reducer } from 'redux'; + import { Registry, UrlQueryValue, VariableType } from '@grafana/data'; -import { VariableModel, VariableOption } from './types'; import { VariableEditorProps } from './editor/types'; import { VariablePickerProps } from './pickers/types'; import { VariablesState } from './state/types'; +import { VariableModel, VariableOption } from './types'; export interface VariableAdapter { id: VariableType; diff --git a/public/app/features/variables/adhoc/AdHocVariableEditor.test.tsx b/public/app/features/variables/adhoc/AdHocVariableEditor.test.tsx index 2bb3a2d7289..d27f1546daa 100644 --- a/public/app/features/variables/adhoc/AdHocVariableEditor.test.tsx +++ b/public/app/features/variables/adhoc/AdHocVariableEditor.test.tsx @@ -1,11 +1,13 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; +import React from 'react'; + import { selectOptionInTest } from '@grafana/ui'; import { getSelectParent } from '@grafana/ui/src/components/Select/test-utils'; -import { AdHocVariableEditorUnConnected as AdHocVariableEditor } from './AdHocVariableEditor'; import { adHocBuilder } from '../shared/testing/builders'; +import { AdHocVariableEditorUnConnected as AdHocVariableEditor } from './AdHocVariableEditor'; + const props = { extended: { dataSources: [ diff --git a/public/app/features/variables/adhoc/AdHocVariableEditor.tsx b/public/app/features/variables/adhoc/AdHocVariableEditor.tsx index 3e4ca258479..0aa81cd7d9b 100644 --- a/public/app/features/variables/adhoc/AdHocVariableEditor.tsx +++ b/public/app/features/variables/adhoc/AdHocVariableEditor.tsx @@ -1,19 +1,21 @@ import React, { PureComponent } from 'react'; import { connect, ConnectedProps } from 'react-redux'; -import { Alert, InlineFieldRow, VerticalGroup } from '@grafana/ui'; -import { DataSourceRef, SelectableValue } from '@grafana/data'; -import { AdHocVariableModel } from '../types'; -import { VariableEditorProps } from '../editor/types'; -import { initialVariableEditorState } from '../editor/reducer'; -import { changeVariableDatasource, initAdHocVariableEditor } from './actions'; +import { DataSourceRef, SelectableValue } from '@grafana/data'; +import { Alert, InlineFieldRow, VerticalGroup } from '@grafana/ui'; import { StoreState } from 'app/types'; + import { VariableSectionHeader } from '../editor/VariableSectionHeader'; import { VariableSelectField } from '../editor/VariableSelectField'; +import { initialVariableEditorState } from '../editor/reducer'; import { getAdhocVariableEditorState } from '../editor/selectors'; +import { VariableEditorProps } from '../editor/types'; import { getVariablesState } from '../state/selectors'; +import { AdHocVariableModel } from '../types'; import { toKeyedVariableIdentifier } from '../utils'; +import { changeVariableDatasource, initAdHocVariableEditor } from './actions'; + const mapStateToProps = (state: StoreState, ownProps: OwnProps) => { const { rootStateKey } = ownProps.variable; diff --git a/public/app/features/variables/adhoc/actions.test.ts b/public/app/features/variables/adhoc/actions.test.ts index becf0bb4a76..22c3d49b1e0 100644 --- a/public/app/features/variables/adhoc/actions.test.ts +++ b/public/app/features/variables/adhoc/actions.test.ts @@ -1,9 +1,16 @@ import { DataSourceInstanceSettings, DataSourcePluginMeta } from '@grafana/data'; +import { locationService } from '@grafana/runtime'; +import { VariableModel } from 'app/features/variables/types'; -import { variableAdapters } from '../adapters'; -import { createAdHocVariableAdapter } from './adapter'; import { reduxTester } from '../../../../test/core/redux/reduxTester'; +import { variableAdapters } from '../adapters'; +import { changeVariableEditorExtended, setIdInEditor } from '../editor/reducer'; +import { adHocBuilder } from '../shared/testing/builders'; import { getPreloadedState, getRootReducer, RootReducerType } from '../state/helpers'; +import { toKeyedAction } from '../state/keyedVariablesReducer'; +import { addVariable, changeVariableProp } from '../state/sharedReducer'; +import { toKeyedVariableIdentifier, toVariablePayload } from '../utils'; + import { addFilter, AdHocTableOptions, @@ -14,14 +21,8 @@ import { removeFilter, setFiltersFromUrl, } from './actions'; +import { createAdHocVariableAdapter } from './adapter'; import { filterAdded, filterRemoved, filtersRestored, filterUpdated } from './reducer'; -import { addVariable, changeVariableProp } from '../state/sharedReducer'; -import { VariableModel } from 'app/features/variables/types'; -import { changeVariableEditorExtended, setIdInEditor } from '../editor/reducer'; -import { adHocBuilder } from '../shared/testing/builders'; -import { locationService } from '@grafana/runtime'; -import { toKeyedAction } from '../state/keyedVariablesReducer'; -import { toKeyedVariableIdentifier, toVariablePayload } from '../utils'; const getList = jest.fn().mockReturnValue([]); const getDatasource = jest.fn().mockResolvedValue({}); diff --git a/public/app/features/variables/adhoc/actions.ts b/public/app/features/variables/adhoc/actions.ts index b49e398e524..596c60cdc49 100644 --- a/public/app/features/variables/adhoc/actions.ts +++ b/public/app/features/variables/adhoc/actions.ts @@ -1,10 +1,20 @@ import { cloneDeep } from 'lodash'; -import { StoreState, ThunkResult } from 'app/types'; + +import { DataSourceRef, getDataSourceRef } from '@grafana/data'; import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; +import { AdHocVariableFilter, AdHocVariableModel } from 'app/features/variables/types'; +import { StoreState, ThunkResult } from 'app/types'; + import { changeVariableEditorExtended } from '../editor/reducer'; -import { addVariable, changeVariableProp } from '../state/sharedReducer'; +import { getAdhocVariableEditorState } from '../editor/selectors'; +import { isAdHoc } from '../guard'; +import { variableUpdated } from '../state/actions'; +import { toKeyedAction } from '../state/keyedVariablesReducer'; import { getLastKey, getNewVariableIndex, getVariable, getVariablesState } from '../state/selectors'; +import { addVariable, changeVariableProp } from '../state/sharedReducer'; import { AddVariable, KeyedVariableIdentifier } from '../state/types'; +import { toKeyedVariableIdentifier, toVariablePayload } from '../utils'; + import { AdHocVariabelFilterUpdate, filterAdded, @@ -13,13 +23,6 @@ import { filterUpdated, initialAdHocVariableModelState, } from './reducer'; -import { AdHocVariableFilter, AdHocVariableModel } from 'app/features/variables/types'; -import { variableUpdated } from '../state/actions'; -import { isAdHoc } from '../guard'; -import { DataSourceRef, getDataSourceRef } from '@grafana/data'; -import { getAdhocVariableEditorState } from '../editor/selectors'; -import { toKeyedAction } from '../state/keyedVariablesReducer'; -import { toKeyedVariableIdentifier, toVariablePayload } from '../utils'; export interface AdHocTableOptions { datasource: DataSourceRef; diff --git a/public/app/features/variables/adhoc/adapter.ts b/public/app/features/variables/adhoc/adapter.ts index 6f2ed40e074..f5e9587de50 100644 --- a/public/app/features/variables/adhoc/adapter.ts +++ b/public/app/features/variables/adhoc/adapter.ts @@ -1,14 +1,15 @@ import { cloneDeep } from 'lodash'; -import { AdHocVariableModel } from '../types'; import { dispatch } from '../../../store/store'; import { VariableAdapter } from '../adapters'; -import { AdHocPicker } from './picker/AdHocPicker'; -import { adHocVariableReducer, initialAdHocVariableModelState } from './reducer'; +import { AdHocVariableModel } from '../types'; +import { toKeyedVariableIdentifier } from '../utils'; + import { AdHocVariableEditor } from './AdHocVariableEditor'; import { setFiltersFromUrl } from './actions'; +import { AdHocPicker } from './picker/AdHocPicker'; +import { adHocVariableReducer, initialAdHocVariableModelState } from './reducer'; import * as urlParser from './urlParser'; -import { toKeyedVariableIdentifier } from '../utils'; const noop = async () => {}; diff --git a/public/app/features/variables/adhoc/picker/AdHocFilter.test.tsx b/public/app/features/variables/adhoc/picker/AdHocFilter.test.tsx index 526c76f353d..932f1731c24 100644 --- a/public/app/features/variables/adhoc/picker/AdHocFilter.test.tsx +++ b/public/app/features/variables/adhoc/picker/AdHocFilter.test.tsx @@ -1,10 +1,12 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import React from 'react'; import selectEvent from 'react-select-event'; -import { AdHocFilter } from './AdHocFilter'; -import { AdHocVariableFilter } from '../../types'; + import { setDataSourceSrv } from '../../../../../../packages/grafana-runtime'; +import { AdHocVariableFilter } from '../../types'; + +import { AdHocFilter } from './AdHocFilter'; describe('AdHocFilter', () => { it('renders filters', async () => { diff --git a/public/app/features/variables/adhoc/picker/AdHocFilter.tsx b/public/app/features/variables/adhoc/picker/AdHocFilter.tsx index ca072d118ea..a7300a4177f 100644 --- a/public/app/features/variables/adhoc/picker/AdHocFilter.tsx +++ b/public/app/features/variables/adhoc/picker/AdHocFilter.tsx @@ -1,10 +1,12 @@ import React, { PureComponent, ReactNode } from 'react'; -import { AdHocVariableFilter } from 'app/features/variables/types'; + import { DataSourceRef, SelectableValue } from '@grafana/data'; +import { AdHocVariableFilter } from 'app/features/variables/types'; + import { AdHocFilterBuilder } from './AdHocFilterBuilder'; -import { ConditionSegment } from './ConditionSegment'; import { REMOVE_FILTER_KEY } from './AdHocFilterKey'; import { AdHocFilterRenderer } from './AdHocFilterRenderer'; +import { ConditionSegment } from './ConditionSegment'; interface Props { datasource: DataSourceRef | null; diff --git a/public/app/features/variables/adhoc/picker/AdHocFilterBuilder.tsx b/public/app/features/variables/adhoc/picker/AdHocFilterBuilder.tsx index 06424e95cfa..d8b3e822bd5 100644 --- a/public/app/features/variables/adhoc/picker/AdHocFilterBuilder.tsx +++ b/public/app/features/variables/adhoc/picker/AdHocFilterBuilder.tsx @@ -1,6 +1,8 @@ import React, { FC, useCallback, useState } from 'react'; -import { AdHocVariableFilter } from 'app/features/variables/types'; + import { DataSourceRef, SelectableValue } from '@grafana/data'; +import { AdHocVariableFilter } from 'app/features/variables/types'; + import { AdHocFilterKey, REMOVE_FILTER_KEY } from './AdHocFilterKey'; import { AdHocFilterRenderer } from './AdHocFilterRenderer'; diff --git a/public/app/features/variables/adhoc/picker/AdHocFilterKey.tsx b/public/app/features/variables/adhoc/picker/AdHocFilterKey.tsx index a99afca4cde..48b2e0ee6c0 100644 --- a/public/app/features/variables/adhoc/picker/AdHocFilterKey.tsx +++ b/public/app/features/variables/adhoc/picker/AdHocFilterKey.tsx @@ -1,7 +1,9 @@ import React, { FC, ReactElement } from 'react'; -import { Icon, SegmentAsync } from '@grafana/ui'; -import { getDatasourceSrv } from '../../../plugins/datasource_srv'; + import { DataSourceRef, SelectableValue } from '@grafana/data'; +import { Icon, SegmentAsync } from '@grafana/ui'; + +import { getDatasourceSrv } from '../../../plugins/datasource_srv'; interface Props { datasource: DataSourceRef; diff --git a/public/app/features/variables/adhoc/picker/AdHocFilterRenderer.tsx b/public/app/features/variables/adhoc/picker/AdHocFilterRenderer.tsx index a3664125f57..9ed209f9031 100644 --- a/public/app/features/variables/adhoc/picker/AdHocFilterRenderer.tsx +++ b/public/app/features/variables/adhoc/picker/AdHocFilterRenderer.tsx @@ -1,9 +1,11 @@ import React, { FC } from 'react'; -import { OperatorSegment } from './OperatorSegment'; -import { AdHocVariableFilter } from 'app/features/variables/types'; + import { DataSourceRef, SelectableValue } from '@grafana/data'; +import { AdHocVariableFilter } from 'app/features/variables/types'; + import { AdHocFilterKey } from './AdHocFilterKey'; import { AdHocFilterValue } from './AdHocFilterValue'; +import { OperatorSegment } from './OperatorSegment'; interface Props { datasource: DataSourceRef; diff --git a/public/app/features/variables/adhoc/picker/AdHocFilterValue.tsx b/public/app/features/variables/adhoc/picker/AdHocFilterValue.tsx index 0eaf2d54620..1d2fd45bb81 100644 --- a/public/app/features/variables/adhoc/picker/AdHocFilterValue.tsx +++ b/public/app/features/variables/adhoc/picker/AdHocFilterValue.tsx @@ -1,7 +1,9 @@ import React, { FC } from 'react'; -import { SegmentAsync } from '@grafana/ui'; -import { getDatasourceSrv } from '../../../plugins/datasource_srv'; + import { DataSourceRef, MetricFindValue, SelectableValue } from '@grafana/data'; +import { SegmentAsync } from '@grafana/ui'; + +import { getDatasourceSrv } from '../../../plugins/datasource_srv'; interface Props { datasource: DataSourceRef; diff --git a/public/app/features/variables/adhoc/picker/AdHocPicker.tsx b/public/app/features/variables/adhoc/picker/AdHocPicker.tsx index 1fa6e55e1ce..9343f4aa0a8 100644 --- a/public/app/features/variables/adhoc/picker/AdHocPicker.tsx +++ b/public/app/features/variables/adhoc/picker/AdHocPicker.tsx @@ -1,10 +1,13 @@ import React, { PureComponent } from 'react'; import { connect, ConnectedProps } from 'react-redux'; + import { AdHocVariableFilter, AdHocVariableModel } from 'app/features/variables/types'; + import { VariablePickerProps } from '../../pickers/types'; -import { addFilter, changeFilter, removeFilter } from '../actions'; -import { AdHocFilter } from './AdHocFilter'; import { toKeyedVariableIdentifier } from '../../utils'; +import { addFilter, changeFilter, removeFilter } from '../actions'; + +import { AdHocFilter } from './AdHocFilter'; const mapDispatchToProps = { addFilter, diff --git a/public/app/features/variables/adhoc/picker/OperatorSegment.tsx b/public/app/features/variables/adhoc/picker/OperatorSegment.tsx index f42702b8204..dcd4eb9575d 100644 --- a/public/app/features/variables/adhoc/picker/OperatorSegment.tsx +++ b/public/app/features/variables/adhoc/picker/OperatorSegment.tsx @@ -1,6 +1,7 @@ import React, { FC } from 'react'; -import { Segment } from '@grafana/ui'; + import { SelectableValue } from '@grafana/data'; +import { Segment } from '@grafana/ui'; interface Props { value: string; diff --git a/public/app/features/variables/adhoc/reducer.test.ts b/public/app/features/variables/adhoc/reducer.test.ts index ce4b7948cd4..0f34801e2c1 100644 --- a/public/app/features/variables/adhoc/reducer.test.ts +++ b/public/app/features/variables/adhoc/reducer.test.ts @@ -1,12 +1,14 @@ -import { reducerTester } from '../../../../test/core/redux/reducerTester'; import { cloneDeep } from 'lodash'; + +import { reducerTester } from '../../../../test/core/redux/reducerTester'; import { getVariableTestContext } from '../state/helpers'; import { VariablesState } from '../state/types'; -import { adHocVariableReducer, filterAdded, filterRemoved, filtersRestored, filterUpdated } from './reducer'; import { AdHocVariableFilter, AdHocVariableModel } from '../types'; -import { createAdHocVariableAdapter } from './adapter'; import { toVariablePayload } from '../utils'; +import { createAdHocVariableAdapter } from './adapter'; +import { adHocVariableReducer, filterAdded, filterRemoved, filtersRestored, filterUpdated } from './reducer'; + describe('adHocVariableReducer', () => { const adapter = createAdHocVariableAdapter(); diff --git a/public/app/features/variables/adhoc/reducer.ts b/public/app/features/variables/adhoc/reducer.ts index f5ff0945961..267257ad2b0 100644 --- a/public/app/features/variables/adhoc/reducer.ts +++ b/public/app/features/variables/adhoc/reducer.ts @@ -1,8 +1,9 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit'; import { AdHocVariableFilter, AdHocVariableModel, initialVariableModelState } from 'app/features/variables/types'; -import { initialVariablesState, VariablePayload, VariablesState } from '../state/types'; + import { getInstanceState } from '../state/selectors'; +import { initialVariablesState, VariablePayload, VariablesState } from '../state/types'; export interface AdHocVariabelFilterUpdate { index: number; diff --git a/public/app/features/variables/adhoc/urlParser.test.ts b/public/app/features/variables/adhoc/urlParser.test.ts index a163809b0c7..bb4d6326a34 100644 --- a/public/app/features/variables/adhoc/urlParser.test.ts +++ b/public/app/features/variables/adhoc/urlParser.test.ts @@ -1,6 +1,7 @@ -import { toFilters, toUrl } from './urlParser'; -import { AdHocVariableFilter } from 'app/features/variables/types'; import { UrlQueryValue } from '@grafana/data'; +import { AdHocVariableFilter } from 'app/features/variables/types'; + +import { toFilters, toUrl } from './urlParser'; describe('urlParser', () => { describe('parsing toUrl with no filters', () => { diff --git a/public/app/features/variables/adhoc/urlParser.ts b/public/app/features/variables/adhoc/urlParser.ts index 8003fd159ab..4d6db307fa6 100644 --- a/public/app/features/variables/adhoc/urlParser.ts +++ b/public/app/features/variables/adhoc/urlParser.ts @@ -1,7 +1,8 @@ -import { AdHocVariableFilter } from 'app/features/variables/types'; -import { UrlQueryValue } from '@grafana/data'; import { isArray, isString } from 'lodash'; +import { UrlQueryValue } from '@grafana/data'; +import { AdHocVariableFilter } from 'app/features/variables/types'; + export const toUrl = (filters: AdHocVariableFilter[]): string[] => { return filters.map((filter) => toArray(filter).map(escapeDelimiter).join('|')); }; diff --git a/public/app/features/variables/constant/ConstantVariableEditor.tsx b/public/app/features/variables/constant/ConstantVariableEditor.tsx index a054aebf240..d5cb25d0e5f 100644 --- a/public/app/features/variables/constant/ConstantVariableEditor.tsx +++ b/public/app/features/variables/constant/ConstantVariableEditor.tsx @@ -1,11 +1,12 @@ import React, { FormEvent, PureComponent } from 'react'; + import { selectors } from '@grafana/e2e-selectors'; import { VerticalGroup } from '@grafana/ui'; -import { ConstantVariableModel } from '../types'; -import { VariableEditorProps } from '../editor/types'; import { VariableSectionHeader } from '../editor/VariableSectionHeader'; import { VariableTextField } from '../editor/VariableTextField'; +import { VariableEditorProps } from '../editor/types'; +import { ConstantVariableModel } from '../types'; export interface Props extends VariableEditorProps {} diff --git a/public/app/features/variables/constant/actions.test.ts b/public/app/features/variables/constant/actions.test.ts index a609cdc69ce..a593715b404 100644 --- a/public/app/features/variables/constant/actions.test.ts +++ b/public/app/features/variables/constant/actions.test.ts @@ -1,14 +1,15 @@ -import { variableAdapters } from '../adapters'; -import { createConstantVariableAdapter } from './adapter'; import { reduxTester } from '../../../../test/core/redux/reduxTester'; -import { updateConstantVariableOptions } from './actions'; +import { variableAdapters } from '../adapters'; import { getRootReducer, RootReducerType } from '../state/helpers'; -import { ConstantVariableModel, initialVariableModelState, VariableOption } from '../types'; -import { createConstantOptionsFromQuery } from './reducer'; -import { addVariable, setCurrentVariableValue } from '../state/sharedReducer'; import { toKeyedAction } from '../state/keyedVariablesReducer'; +import { addVariable, setCurrentVariableValue } from '../state/sharedReducer'; +import { ConstantVariableModel, initialVariableModelState, VariableOption } from '../types'; import { toKeyedVariableIdentifier, toVariablePayload } from '../utils'; +import { updateConstantVariableOptions } from './actions'; +import { createConstantVariableAdapter } from './adapter'; +import { createConstantOptionsFromQuery } from './reducer'; + describe('constant actions', () => { variableAdapters.setInit(() => [createConstantVariableAdapter()]); diff --git a/public/app/features/variables/constant/actions.ts b/public/app/features/variables/constant/actions.ts index 6f865bcaa19..87f78229983 100644 --- a/public/app/features/variables/constant/actions.ts +++ b/public/app/features/variables/constant/actions.ts @@ -1,10 +1,12 @@ -import { validateVariableSelectionState } from '../state/actions'; import { ThunkResult } from 'app/types'; -import { createConstantOptionsFromQuery } from './reducer'; -import { KeyedVariableIdentifier } from '../state/types'; + +import { validateVariableSelectionState } from '../state/actions'; import { toKeyedAction } from '../state/keyedVariablesReducer'; +import { KeyedVariableIdentifier } from '../state/types'; import { toVariablePayload } from '../utils'; +import { createConstantOptionsFromQuery } from './reducer'; + export const updateConstantVariableOptions = (identifier: KeyedVariableIdentifier): ThunkResult => { return async (dispatch) => { const { rootStateKey } = identifier; diff --git a/public/app/features/variables/constant/adapter.ts b/public/app/features/variables/constant/adapter.ts index 4555a63c788..cd304d46ced 100644 --- a/public/app/features/variables/constant/adapter.ts +++ b/public/app/features/variables/constant/adapter.ts @@ -1,13 +1,15 @@ import { cloneDeep } from 'lodash'; -import { ConstantVariableModel } from '../types'; + import { dispatch } from '../../../store/store'; -import { setOptionAsCurrent, setOptionFromUrl } from '../state/actions'; import { VariableAdapter } from '../adapters'; -import { constantVariableReducer, initialConstantVariableModelState } from './reducer'; +import { optionPickerFactory } from '../pickers'; +import { setOptionAsCurrent, setOptionFromUrl } from '../state/actions'; +import { ConstantVariableModel } from '../types'; +import { toKeyedVariableIdentifier } from '../utils'; + import { ConstantVariableEditor } from './ConstantVariableEditor'; import { updateConstantVariableOptions } from './actions'; -import { optionPickerFactory } from '../pickers'; -import { toKeyedVariableIdentifier } from '../utils'; +import { constantVariableReducer, initialConstantVariableModelState } from './reducer'; export const createConstantVariableAdapter = (): VariableAdapter => { return { diff --git a/public/app/features/variables/constant/reducer.test.ts b/public/app/features/variables/constant/reducer.test.ts index 932593582b2..4b64b64e87b 100644 --- a/public/app/features/variables/constant/reducer.test.ts +++ b/public/app/features/variables/constant/reducer.test.ts @@ -3,11 +3,12 @@ import { cloneDeep } from 'lodash'; import { reducerTester } from '../../../../test/core/redux/reducerTester'; import { getVariableTestContext } from '../state/helpers'; import { VariablesState } from '../state/types'; -import { constantVariableReducer, createConstantOptionsFromQuery } from './reducer'; import { ConstantVariableModel } from '../types'; -import { createConstantVariableAdapter } from './adapter'; import { toVariablePayload } from '../utils'; +import { createConstantVariableAdapter } from './adapter'; +import { constantVariableReducer, createConstantOptionsFromQuery } from './reducer'; + describe('constantVariableReducer', () => { const adapter = createConstantVariableAdapter(); diff --git a/public/app/features/variables/constant/reducer.ts b/public/app/features/variables/constant/reducer.ts index 8a830d779d1..c6b4eac74f8 100644 --- a/public/app/features/variables/constant/reducer.ts +++ b/public/app/features/variables/constant/reducer.ts @@ -1,8 +1,8 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit'; -import { ConstantVariableModel, initialVariableModelState, VariableHide, VariableOption } from '../types'; -import { initialVariablesState, VariablePayload, VariablesState } from '../state/types'; import { getInstanceState } from '../state/selectors'; +import { initialVariablesState, VariablePayload, VariablesState } from '../state/types'; +import { ConstantVariableModel, initialVariableModelState, VariableHide, VariableOption } from '../types'; export const initialConstantVariableModelState: ConstantVariableModel = { ...initialVariableModelState, diff --git a/public/app/features/variables/custom/CustomVariableEditor.tsx b/public/app/features/variables/custom/CustomVariableEditor.tsx index 64a76e1b3b6..bdc179bf10a 100644 --- a/public/app/features/variables/custom/CustomVariableEditor.tsx +++ b/public/app/features/variables/custom/CustomVariableEditor.tsx @@ -1,15 +1,17 @@ import React, { FormEvent, PureComponent } from 'react'; -import { CustomVariableModel, VariableWithMultiSupport } from '../types'; -import { SelectionOptionsEditor } from '../editor/SelectionOptionsEditor'; -import { OnPropChangeArguments, VariableEditorProps } from '../editor/types'; -import { connectWithStore } from 'app/core/utils/connectWithReduxStore'; import { MapDispatchToProps, MapStateToProps } from 'react-redux'; -import { VerticalGroup } from '@grafana/ui'; + import { selectors } from '@grafana/e2e-selectors'; +import { VerticalGroup } from '@grafana/ui'; +import { connectWithStore } from 'app/core/utils/connectWithReduxStore'; import { StoreState } from 'app/types'; -import { changeVariableMultiValue } from '../state/actions'; + +import { SelectionOptionsEditor } from '../editor/SelectionOptionsEditor'; import { VariableSectionHeader } from '../editor/VariableSectionHeader'; import { VariableTextAreaField } from '../editor/VariableTextAreaField'; +import { OnPropChangeArguments, VariableEditorProps } from '../editor/types'; +import { changeVariableMultiValue } from '../state/actions'; +import { CustomVariableModel, VariableWithMultiSupport } from '../types'; interface OwnProps extends VariableEditorProps {} diff --git a/public/app/features/variables/custom/actions.test.ts b/public/app/features/variables/custom/actions.test.ts index 9df0916264d..d537fb1b414 100644 --- a/public/app/features/variables/custom/actions.test.ts +++ b/public/app/features/variables/custom/actions.test.ts @@ -1,13 +1,14 @@ +import { reduxTester } from '../../../../test/core/redux/reduxTester'; import { variableAdapters } from '../adapters'; +import { getRootReducer, RootReducerType } from '../state/helpers'; +import { toKeyedAction } from '../state/keyedVariablesReducer'; +import { addVariable, setCurrentVariableValue } from '../state/sharedReducer'; +import { CustomVariableModel, initialVariableModelState, VariableOption } from '../types'; +import { toKeyedVariableIdentifier, toVariablePayload } from '../utils'; + import { updateCustomVariableOptions } from './actions'; import { createCustomVariableAdapter } from './adapter'; -import { reduxTester } from '../../../../test/core/redux/reduxTester'; -import { getRootReducer, RootReducerType } from '../state/helpers'; -import { CustomVariableModel, initialVariableModelState, VariableOption } from '../types'; -import { addVariable, setCurrentVariableValue } from '../state/sharedReducer'; import { createCustomOptionsFromQuery } from './reducer'; -import { toKeyedAction } from '../state/keyedVariablesReducer'; -import { toKeyedVariableIdentifier, toVariablePayload } from '../utils'; describe('custom actions', () => { variableAdapters.setInit(() => [createCustomVariableAdapter()]); diff --git a/public/app/features/variables/custom/actions.ts b/public/app/features/variables/custom/actions.ts index 557d2044dca..898412fe49b 100644 --- a/public/app/features/variables/custom/actions.ts +++ b/public/app/features/variables/custom/actions.ts @@ -1,10 +1,12 @@ -import { validateVariableSelectionState } from '../state/actions'; import { ThunkResult } from 'app/types'; -import { createCustomOptionsFromQuery } from './reducer'; -import { KeyedVariableIdentifier } from '../state/types'; + +import { validateVariableSelectionState } from '../state/actions'; import { toKeyedAction } from '../state/keyedVariablesReducer'; +import { KeyedVariableIdentifier } from '../state/types'; import { toVariablePayload } from '../utils'; +import { createCustomOptionsFromQuery } from './reducer'; + export const updateCustomVariableOptions = (identifier: KeyedVariableIdentifier): ThunkResult => { return async (dispatch) => { const { rootStateKey } = identifier; diff --git a/public/app/features/variables/custom/adapter.ts b/public/app/features/variables/custom/adapter.ts index 47af02927bc..c98374f195d 100644 --- a/public/app/features/variables/custom/adapter.ts +++ b/public/app/features/variables/custom/adapter.ts @@ -1,14 +1,16 @@ import { cloneDeep } from 'lodash'; -import { CustomVariableModel } from '../types'; + import { dispatch } from '../../../store/store'; -import { setOptionAsCurrent, setOptionFromUrl } from '../state/actions'; import { VariableAdapter } from '../adapters'; -import { customVariableReducer, initialCustomVariableModelState } from './reducer'; +import { ALL_VARIABLE_TEXT } from '../constants'; +import { optionPickerFactory } from '../pickers'; +import { setOptionAsCurrent, setOptionFromUrl } from '../state/actions'; +import { CustomVariableModel } from '../types'; +import { isAllVariable, toKeyedVariableIdentifier } from '../utils'; + import { CustomVariableEditor } from './CustomVariableEditor'; import { updateCustomVariableOptions } from './actions'; -import { isAllVariable, toKeyedVariableIdentifier } from '../utils'; -import { optionPickerFactory } from '../pickers'; -import { ALL_VARIABLE_TEXT } from '../constants'; +import { customVariableReducer, initialCustomVariableModelState } from './reducer'; export const createCustomVariableAdapter = (): VariableAdapter => { return { diff --git a/public/app/features/variables/custom/reducer.test.ts b/public/app/features/variables/custom/reducer.test.ts index 39f0ef09815..23ad676a298 100644 --- a/public/app/features/variables/custom/reducer.test.ts +++ b/public/app/features/variables/custom/reducer.test.ts @@ -1,14 +1,15 @@ import { cloneDeep } from 'lodash'; import { reducerTester } from '../../../../test/core/redux/reducerTester'; +import { ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE } from '../constants'; import { getVariableTestContext } from '../state/helpers'; import { VariablesState } from '../state/types'; -import { createCustomOptionsFromQuery, customVariableReducer } from './reducer'; -import { createCustomVariableAdapter } from './adapter'; import { CustomVariableModel } from '../types'; -import { ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE } from '../constants'; import { toVariablePayload } from '../utils'; +import { createCustomVariableAdapter } from './adapter'; +import { createCustomOptionsFromQuery, customVariableReducer } from './reducer'; + describe('customVariableReducer', () => { const adapter = createCustomVariableAdapter(); diff --git a/public/app/features/variables/custom/reducer.ts b/public/app/features/variables/custom/reducer.ts index 9a897030c30..4c5c744d657 100644 --- a/public/app/features/variables/custom/reducer.ts +++ b/public/app/features/variables/custom/reducer.ts @@ -1,9 +1,9 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit'; -import { CustomVariableModel, initialVariableModelState, VariableOption } from '../types'; -import { initialVariablesState, VariablePayload, VariablesState } from '../state/types'; import { ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE } from '../constants'; import { getInstanceState } from '../state/selectors'; +import { initialVariablesState, VariablePayload, VariablesState } from '../state/types'; +import { CustomVariableModel, initialVariableModelState, VariableOption } from '../types'; export const initialCustomVariableModelState: CustomVariableModel = { ...initialVariableModelState, diff --git a/public/app/features/variables/datasource/DataSourceVariableEditor.test.tsx b/public/app/features/variables/datasource/DataSourceVariableEditor.test.tsx index 42190e73bb4..68a58da3835 100644 --- a/public/app/features/variables/datasource/DataSourceVariableEditor.test.tsx +++ b/public/app/features/variables/datasource/DataSourceVariableEditor.test.tsx @@ -1,10 +1,11 @@ -import React from 'react'; import { render, screen, fireEvent } from '@testing-library/react'; +import React from 'react'; + +import { selectOptionInTest } from '@grafana/ui'; +import { getSelectParent } from '@grafana/ui/src/components/Select/test-utils'; import { DataSourceVariableEditorUnConnected as DataSourceVariableEditor } from './DataSourceVariableEditor'; import { initialDataSourceVariableModelState } from './reducer'; -import { selectOptionInTest } from '@grafana/ui'; -import { getSelectParent } from '@grafana/ui/src/components/Select/test-utils'; const props = { extended: { diff --git a/public/app/features/variables/datasource/DataSourceVariableEditor.tsx b/public/app/features/variables/datasource/DataSourceVariableEditor.tsx index 51f9a827f71..eacd5f98139 100644 --- a/public/app/features/variables/datasource/DataSourceVariableEditor.tsx +++ b/public/app/features/variables/datasource/DataSourceVariableEditor.tsx @@ -1,21 +1,23 @@ import React, { FormEvent, PureComponent } from 'react'; import { connect, ConnectedProps } from 'react-redux'; + import { SelectableValue } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; import { InlineFieldRow, VerticalGroup } from '@grafana/ui'; -import { DataSourceVariableModel, VariableWithMultiSupport } from '../types'; -import { OnPropChangeArguments, VariableEditorProps } from '../editor/types'; -import { SelectionOptionsEditor } from '../editor/SelectionOptionsEditor'; -import { initialVariableEditorState } from '../editor/reducer'; -import { initDataSourceVariableEditor } from './actions'; import { StoreState } from '../../../types'; -import { changeVariableMultiValue } from '../state/actions'; +import { SelectionOptionsEditor } from '../editor/SelectionOptionsEditor'; import { VariableSectionHeader } from '../editor/VariableSectionHeader'; import { VariableSelectField } from '../editor/VariableSelectField'; import { VariableTextField } from '../editor/VariableTextField'; -import { getVariablesState } from '../state/selectors'; -import { selectors } from '@grafana/e2e-selectors'; +import { initialVariableEditorState } from '../editor/reducer'; import { getDatasourceVariableEditorState } from '../editor/selectors'; +import { OnPropChangeArguments, VariableEditorProps } from '../editor/types'; +import { changeVariableMultiValue } from '../state/actions'; +import { getVariablesState } from '../state/selectors'; +import { DataSourceVariableModel, VariableWithMultiSupport } from '../types'; + +import { initDataSourceVariableEditor } from './actions'; const mapStateToProps = (state: StoreState, ownProps: OwnProps) => { const { diff --git a/public/app/features/variables/datasource/actions.test.ts b/public/app/features/variables/datasource/actions.test.ts index 67f62788eae..3d4f669fce6 100644 --- a/public/app/features/variables/datasource/actions.test.ts +++ b/public/app/features/variables/datasource/actions.test.ts @@ -1,22 +1,23 @@ import { DataSourceInstanceSettings } from '@grafana/data'; import { reduxTester } from '../../../../test/core/redux/reduxTester'; -import { getRootReducer, RootReducerType } from '../state/helpers'; +import { getMockPlugin } from '../../plugins/__mocks__/pluginMocks'; import { variableAdapters } from '../adapters'; -import { createDataSourceVariableAdapter } from './adapter'; +import { changeVariableEditorExtended } from '../editor/reducer'; +import { datasourceBuilder } from '../shared/testing/builders'; +import { getDataSourceInstanceSetting } from '../shared/testing/helpers'; +import { getRootReducer, RootReducerType } from '../state/helpers'; +import { toKeyedAction } from '../state/keyedVariablesReducer'; +import { addVariable, setCurrentVariableValue } from '../state/sharedReducer'; +import { toKeyedVariableIdentifier, toVariablePayload } from '../utils'; + import { DataSourceVariableActionDependencies, initDataSourceVariableEditor, updateDataSourceVariableOptions, } from './actions'; -import { getMockPlugin } from '../../plugins/__mocks__/pluginMocks'; +import { createDataSourceVariableAdapter } from './adapter'; import { createDataSourceOptions } from './reducer'; -import { addVariable, setCurrentVariableValue } from '../state/sharedReducer'; -import { changeVariableEditorExtended } from '../editor/reducer'; -import { datasourceBuilder } from '../shared/testing/builders'; -import { getDataSourceInstanceSetting } from '../shared/testing/helpers'; -import { toKeyedAction } from '../state/keyedVariablesReducer'; -import { toKeyedVariableIdentifier, toVariablePayload } from '../utils'; interface Args { sources?: DataSourceInstanceSettings[]; diff --git a/public/app/features/variables/datasource/actions.ts b/public/app/features/variables/datasource/actions.ts index dc7b34cdd75..33708cd493a 100644 --- a/public/app/features/variables/datasource/actions.ts +++ b/public/app/features/variables/datasource/actions.ts @@ -1,18 +1,20 @@ import { chain } from 'lodash'; -import { getTemplateSrv } from '@grafana/runtime'; -import { stringToJsRegex } from '@grafana/data'; -import { KeyedVariableIdentifier } from '../state/types'; +import { stringToJsRegex } from '@grafana/data'; +import { getTemplateSrv } from '@grafana/runtime'; + import { ThunkResult } from '../../../types'; -import { createDataSourceOptions } from './reducer'; -import { validateVariableSelectionState } from '../state/actions'; import { getDatasourceSrv } from '../../plugins/datasource_srv'; -import { getVariable } from '../state/selectors'; -import { DataSourceVariableModel } from '../types'; import { changeVariableEditorExtended } from '../editor/reducer'; +import { validateVariableSelectionState } from '../state/actions'; import { toKeyedAction } from '../state/keyedVariablesReducer'; +import { getVariable } from '../state/selectors'; +import { KeyedVariableIdentifier } from '../state/types'; +import { DataSourceVariableModel } from '../types'; import { toVariablePayload } from '../utils'; +import { createDataSourceOptions } from './reducer'; + export interface DataSourceVariableActionDependencies { getDatasourceSrv: typeof getDatasourceSrv; } diff --git a/public/app/features/variables/datasource/adapter.ts b/public/app/features/variables/datasource/adapter.ts index 9b4da36805a..d43b82f403c 100644 --- a/public/app/features/variables/datasource/adapter.ts +++ b/public/app/features/variables/datasource/adapter.ts @@ -1,14 +1,16 @@ import { cloneDeep } from 'lodash'; -import { DataSourceVariableModel } from '../types'; + import { dispatch } from '../../../store/store'; -import { setOptionAsCurrent, setOptionFromUrl } from '../state/actions'; import { VariableAdapter } from '../adapters'; -import { dataSourceVariableReducer, initialDataSourceVariableModelState } from './reducer'; +import { ALL_VARIABLE_TEXT } from '../constants'; +import { optionPickerFactory } from '../pickers'; +import { setOptionAsCurrent, setOptionFromUrl } from '../state/actions'; +import { DataSourceVariableModel } from '../types'; +import { containsVariable, isAllVariable, toKeyedVariableIdentifier } from '../utils'; + import { DataSourceVariableEditor } from './DataSourceVariableEditor'; import { updateDataSourceVariableOptions } from './actions'; -import { containsVariable, isAllVariable, toKeyedVariableIdentifier } from '../utils'; -import { optionPickerFactory } from '../pickers'; -import { ALL_VARIABLE_TEXT } from '../constants'; +import { dataSourceVariableReducer, initialDataSourceVariableModelState } from './reducer'; export const createDataSourceVariableAdapter = (): VariableAdapter => { return { diff --git a/public/app/features/variables/datasource/reducer.test.ts b/public/app/features/variables/datasource/reducer.test.ts index dce1a1ed93f..31a096eb3cc 100644 --- a/public/app/features/variables/datasource/reducer.test.ts +++ b/public/app/features/variables/datasource/reducer.test.ts @@ -1,16 +1,18 @@ import { cloneDeep } from 'lodash'; + import { DataSourceInstanceSettings } from '@grafana/data'; import { reducerTester } from '../../../../test/core/redux/reducerTester'; -import { createDataSourceOptions, dataSourceVariableReducer } from './reducer'; -import { DataSourceVariableModel } from '../types'; -import { getVariableTestContext } from '../state/helpers'; -import { createDataSourceVariableAdapter } from './adapter'; -import { VariablesState } from '../state/types'; import { getMockPlugins } from '../../plugins/__mocks__/pluginMocks'; import { getDataSourceInstanceSetting } from '../shared/testing/helpers'; +import { getVariableTestContext } from '../state/helpers'; +import { VariablesState } from '../state/types'; +import { DataSourceVariableModel } from '../types'; import { toVariablePayload } from '../utils'; +import { createDataSourceVariableAdapter } from './adapter'; +import { createDataSourceOptions, dataSourceVariableReducer } from './reducer'; + describe('dataSourceVariableReducer', () => { const adapter = createDataSourceVariableAdapter(); describe('when createDataSourceOptions is dispatched', () => { diff --git a/public/app/features/variables/datasource/reducer.ts b/public/app/features/variables/datasource/reducer.ts index 3e2370dd495..eda07cac254 100644 --- a/public/app/features/variables/datasource/reducer.ts +++ b/public/app/features/variables/datasource/reducer.ts @@ -1,10 +1,11 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit'; + import { DataSourceInstanceSettings } from '@grafana/data'; -import { DataSourceVariableModel, initialVariableModelState, VariableOption, VariableRefresh } from '../types'; -import { initialVariablesState, VariablePayload, VariablesState } from '../state/types'; import { ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE } from '../constants'; import { getInstanceState } from '../state/selectors'; +import { initialVariablesState, VariablePayload, VariablesState } from '../state/types'; +import { DataSourceVariableModel, initialVariableModelState, VariableOption, VariableRefresh } from '../types'; export const initialDataSourceVariableModelState: DataSourceVariableModel = { ...initialVariableModelState, diff --git a/public/app/features/variables/editor/LegacyVariableQueryEditor.tsx b/public/app/features/variables/editor/LegacyVariableQueryEditor.tsx index 19ef28e01d3..cee7cae4083 100644 --- a/public/app/features/variables/editor/LegacyVariableQueryEditor.tsx +++ b/public/app/features/variables/editor/LegacyVariableQueryEditor.tsx @@ -1,11 +1,13 @@ +import { css } from '@emotion/css'; import React, { FC, useCallback, useState } from 'react'; + +import { GrafanaTheme } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; import { useStyles } from '@grafana/ui'; -import { GrafanaTheme } from '@grafana/data'; -import { css } from '@emotion/css'; + +import { VariableQueryEditorProps } from '../types'; import { VariableTextAreaField } from './VariableTextAreaField'; -import { VariableQueryEditorProps } from '../types'; export const LEGACY_VARIABLE_QUERY_EDITOR_NAME = 'Grafana-LegacyVariableQueryEditor'; diff --git a/public/app/features/variables/editor/SelectionOptionsEditor.tsx b/public/app/features/variables/editor/SelectionOptionsEditor.tsx index d1e2688cc40..00288f9d8d4 100644 --- a/public/app/features/variables/editor/SelectionOptionsEditor.tsx +++ b/public/app/features/variables/editor/SelectionOptionsEditor.tsx @@ -1,14 +1,16 @@ import React, { ChangeEvent, FormEvent, FunctionComponent, useCallback } from 'react'; -import { InlineFieldRow, VerticalGroup } from '@grafana/ui'; -import { selectors } from '@grafana/e2e-selectors'; -import { VariableWithMultiSupport } from '../types'; -import { VariableEditorProps } from './types'; +import { selectors } from '@grafana/e2e-selectors'; +import { InlineFieldRow, VerticalGroup } from '@grafana/ui'; + import { KeyedVariableIdentifier } from '../state/types'; +import { VariableWithMultiSupport } from '../types'; +import { toKeyedVariableIdentifier } from '../utils'; + import { VariableSectionHeader } from './VariableSectionHeader'; import { VariableSwitchField } from './VariableSwitchField'; import { VariableTextField } from './VariableTextField'; -import { toKeyedVariableIdentifier } from '../utils'; +import { VariableEditorProps } from './types'; export interface SelectionOptionsEditorProps extends VariableEditorProps { diff --git a/public/app/features/variables/editor/VariableEditorContainer.tsx b/public/app/features/variables/editor/VariableEditorContainer.tsx index 3170eb9f35d..9245d4d93ce 100644 --- a/public/app/features/variables/editor/VariableEditorContainer.tsx +++ b/public/app/features/variables/editor/VariableEditorContainer.tsx @@ -1,10 +1,11 @@ -import { selectors } from '@grafana/e2e-selectors'; -import { Button, Icon } from '@grafana/ui'; -import { DashboardModel } from 'app/features/dashboard/state/DashboardModel'; import React, { MouseEvent, PureComponent } from 'react'; import { connect, ConnectedProps } from 'react-redux'; import { bindActionCreators } from 'redux'; +import { selectors } from '@grafana/e2e-selectors'; +import { Button, Icon } from '@grafana/ui'; +import { DashboardModel } from 'app/features/dashboard/state/DashboardModel'; + import { StoreState, ThunkDispatch } from '../../../types'; import { VariablesDependenciesButton } from '../inspect/VariablesDependenciesButton'; import { VariablesUnknownTable } from '../inspect/VariablesUnknownTable'; @@ -13,9 +14,10 @@ import { getEditorVariables, getVariablesState } from '../state/selectors'; import { changeVariableOrder, duplicateVariable, removeVariable } from '../state/sharedReducer'; import { KeyedVariableIdentifier } from '../state/types'; import { toKeyedVariableIdentifier, toVariablePayload } from '../utils'; -import { switchToEditMode, switchToListMode, switchToNewMode } from './actions'; + import { VariableEditorEditor } from './VariableEditorEditor'; import { VariableEditorList } from './VariableEditorList'; +import { switchToEditMode, switchToListMode, switchToNewMode } from './actions'; const mapStateToProps = (state: StoreState, ownProps: OwnProps) => { const { uid } = ownProps.dashboard; diff --git a/public/app/features/variables/editor/VariableEditorEditor.tsx b/public/app/features/variables/editor/VariableEditorEditor.tsx index 58441e2eff1..43f5d70483f 100644 --- a/public/app/features/variables/editor/VariableEditorEditor.tsx +++ b/public/app/features/variables/editor/VariableEditorEditor.tsx @@ -1,29 +1,31 @@ -import React, { FormEvent, PureComponent } from 'react'; -import { bindActionCreators } from 'redux'; -import { connect, ConnectedProps } from 'react-redux'; import { isEqual } from 'lodash'; -import { AppEvents, LoadingState, SelectableValue, VariableType } from '@grafana/data'; -import { Button, Icon, InlineFieldRow, VerticalGroup } from '@grafana/ui'; -import { selectors } from '@grafana/e2e-selectors'; +import React, { FormEvent, PureComponent } from 'react'; +import { connect, ConnectedProps } from 'react-redux'; +import { bindActionCreators } from 'redux'; +import { AppEvents, LoadingState, SelectableValue, VariableType } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; +import { Button, Icon, InlineFieldRow, VerticalGroup } from '@grafana/ui'; + +import { appEvents } from '../../../core/core'; +import { StoreState, ThunkDispatch } from '../../../types'; import { variableAdapters } from '../adapters'; +import { hasOptions } from '../guard'; +import { updateOptions } from '../state/actions'; +import { toKeyedAction } from '../state/keyedVariablesReducer'; +import { getVariable, getVariablesState } from '../state/selectors'; +import { changeVariableProp, changeVariableType } from '../state/sharedReducer'; import { KeyedVariableIdentifier } from '../state/types'; import { VariableHide } from '../types'; -import { appEvents } from '../../../core/core'; +import { toKeyedVariableIdentifier, toVariablePayload } from '../utils'; + +import { VariableHideSelect } from './VariableHideSelect'; +import { VariableSectionHeader } from './VariableSectionHeader'; +import { VariableTextField } from './VariableTextField'; +import { VariableTypeSelect } from './VariableTypeSelect'; import { VariableValuesPreview } from './VariableValuesPreview'; import { changeVariableName, onEditorUpdate, variableEditorMount, variableEditorUnMount } from './actions'; import { OnPropChangeArguments } from './types'; -import { changeVariableProp, changeVariableType } from '../state/sharedReducer'; -import { updateOptions } from '../state/actions'; -import { VariableTextField } from './VariableTextField'; -import { VariableSectionHeader } from './VariableSectionHeader'; -import { hasOptions } from '../guard'; -import { VariableTypeSelect } from './VariableTypeSelect'; -import { VariableHideSelect } from './VariableHideSelect'; -import { getVariable, getVariablesState } from '../state/selectors'; -import { toKeyedAction } from '../state/keyedVariablesReducer'; -import { StoreState, ThunkDispatch } from '../../../types'; -import { toKeyedVariableIdentifier, toVariablePayload } from '../utils'; const mapStateToProps = (state: StoreState, ownProps: OwnProps) => ({ editor: getVariablesState(ownProps.identifier.rootStateKey, state).editor, diff --git a/public/app/features/variables/editor/VariableEditorList.tsx b/public/app/features/variables/editor/VariableEditorList.tsx index c3ac0e585cd..e6c052e358a 100644 --- a/public/app/features/variables/editor/VariableEditorList.tsx +++ b/public/app/features/variables/editor/VariableEditorList.tsx @@ -1,14 +1,16 @@ import React, { ReactElement } from 'react'; import { DragDropContext, Droppable, DropResult } from 'react-beautiful-dnd'; + import { selectors } from '@grafana/e2e-selectors'; import { reportInteraction } from '@grafana/runtime'; - -import { VariableModel } from '../types'; -import { KeyedVariableIdentifier } from '../state/types'; -import { UsagesToNetwork, VariableUsageTree } from '../inspect/utils'; -import { VariableEditorListRow } from './VariableEditorListRow'; import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA'; +import { UsagesToNetwork, VariableUsageTree } from '../inspect/utils'; +import { KeyedVariableIdentifier } from '../state/types'; +import { VariableModel } from '../types'; + +import { VariableEditorListRow } from './VariableEditorListRow'; + export interface Props { variables: VariableModel[]; usages: VariableUsageTree[]; diff --git a/public/app/features/variables/editor/VariableEditorListRow.tsx b/public/app/features/variables/editor/VariableEditorListRow.tsx index 272f29314ea..4873a926286 100644 --- a/public/app/features/variables/editor/VariableEditorListRow.tsx +++ b/public/app/features/variables/editor/VariableEditorListRow.tsx @@ -1,14 +1,15 @@ import { css } from '@emotion/css'; +import React, { ReactElement } from 'react'; +import { Draggable } from 'react-beautiful-dnd'; + import { GrafanaTheme2 } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; import { reportInteraction } from '@grafana/runtime'; import { Button, Icon, IconButton, useStyles2, useTheme2 } from '@grafana/ui'; -import React, { ReactElement } from 'react'; -import { Draggable } from 'react-beautiful-dnd'; import { hasOptions, isAdHoc, isQuery } from '../guard'; -import { getVariableUsages, UsagesToNetwork, VariableUsageTree } from '../inspect/utils'; import { VariableUsagesButton } from '../inspect/VariableUsagesButton'; +import { getVariableUsages, UsagesToNetwork, VariableUsageTree } from '../inspect/utils'; import { KeyedVariableIdentifier } from '../state/types'; import { VariableModel } from '../types'; import { toKeyedVariableIdentifier } from '../utils'; diff --git a/public/app/features/variables/editor/VariableHideSelect.tsx b/public/app/features/variables/editor/VariableHideSelect.tsx index bccf9e740f7..8018ff23a42 100644 --- a/public/app/features/variables/editor/VariableHideSelect.tsx +++ b/public/app/features/variables/editor/VariableHideSelect.tsx @@ -1,4 +1,5 @@ import React, { PropsWithChildren, useMemo } from 'react'; + import { SelectableValue, VariableType } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; diff --git a/public/app/features/variables/editor/VariableSectionHeader.tsx b/public/app/features/variables/editor/VariableSectionHeader.tsx index 72ccf3109ff..407d2c6eb75 100644 --- a/public/app/features/variables/editor/VariableSectionHeader.tsx +++ b/public/app/features/variables/editor/VariableSectionHeader.tsx @@ -1,7 +1,8 @@ -import React, { PropsWithChildren, ReactElement } from 'react'; -import { useStyles } from '@grafana/ui'; -import { GrafanaTheme } from '@grafana/data'; import { css } from '@emotion/css'; +import React, { PropsWithChildren, ReactElement } from 'react'; + +import { GrafanaTheme } from '@grafana/data'; +import { useStyles } from '@grafana/ui'; interface VariableSectionHeaderProps { name: string; diff --git a/public/app/features/variables/editor/VariableSelectField.tsx b/public/app/features/variables/editor/VariableSelectField.tsx index 4ef00603c35..b08aca6ab5c 100644 --- a/public/app/features/variables/editor/VariableSelectField.tsx +++ b/public/app/features/variables/editor/VariableSelectField.tsx @@ -1,7 +1,8 @@ -import React, { PropsWithChildren, ReactElement } from 'react'; -import { InlineFormLabel, Select, useStyles } from '@grafana/ui'; -import { GrafanaTheme, SelectableValue } from '@grafana/data'; import { css } from '@emotion/css'; +import React, { PropsWithChildren, ReactElement } from 'react'; + +import { GrafanaTheme, SelectableValue } from '@grafana/data'; +import { InlineFormLabel, Select, useStyles } from '@grafana/ui'; import { useUniqueId } from 'app/plugins/datasource/influxdb/components/useUniqueId'; interface VariableSelectFieldProps { diff --git a/public/app/features/variables/editor/VariableSwitchField.tsx b/public/app/features/variables/editor/VariableSwitchField.tsx index da796823354..aa3cb42de03 100644 --- a/public/app/features/variables/editor/VariableSwitchField.tsx +++ b/public/app/features/variables/editor/VariableSwitchField.tsx @@ -1,4 +1,5 @@ import React, { ChangeEvent, PropsWithChildren, ReactElement } from 'react'; + import { InlineField, InlineSwitch } from '@grafana/ui'; import { useUniqueId } from 'app/plugins/datasource/influxdb/components/useUniqueId'; interface VariableSwitchFieldProps { diff --git a/public/app/features/variables/editor/VariableTextAreaField.tsx b/public/app/features/variables/editor/VariableTextAreaField.tsx index 5298b0c53a2..60263be1386 100644 --- a/public/app/features/variables/editor/VariableTextAreaField.tsx +++ b/public/app/features/variables/editor/VariableTextAreaField.tsx @@ -1,7 +1,8 @@ -import React, { FormEvent, PropsWithChildren, ReactElement, useCallback } from 'react'; -import { InlineField, TextArea, useStyles } from '@grafana/ui'; -import { GrafanaTheme } from '@grafana/data'; import { css } from '@emotion/css'; +import React, { FormEvent, PropsWithChildren, ReactElement, useCallback } from 'react'; + +import { GrafanaTheme } from '@grafana/data'; +import { InlineField, TextArea, useStyles } from '@grafana/ui'; interface VariableTextAreaFieldProps { name: string; diff --git a/public/app/features/variables/editor/VariableTextField.tsx b/public/app/features/variables/editor/VariableTextField.tsx index 1e77844199a..5d8b5c4ed61 100644 --- a/public/app/features/variables/editor/VariableTextField.tsx +++ b/public/app/features/variables/editor/VariableTextField.tsx @@ -1,4 +1,5 @@ import React, { FormEvent, PropsWithChildren, ReactElement } from 'react'; + import { InlineField, Input, PopoverContent } from '@grafana/ui'; interface VariableTextFieldProps { diff --git a/public/app/features/variables/editor/VariableTypeSelect.tsx b/public/app/features/variables/editor/VariableTypeSelect.tsx index 907f4ebc9c7..7f5a0b26cbd 100644 --- a/public/app/features/variables/editor/VariableTypeSelect.tsx +++ b/public/app/features/variables/editor/VariableTypeSelect.tsx @@ -1,10 +1,11 @@ import React, { PropsWithChildren, useMemo } from 'react'; + import { SelectableValue, VariableType } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; +import { variableAdapters } from '../adapters'; import { VariableSelectField } from '../editor/VariableSelectField'; import { getVariableTypes } from '../utils'; -import { variableAdapters } from '../adapters'; interface Props { onChange: (option: SelectableValue) => void; diff --git a/public/app/features/variables/editor/VariableValuesPreview.tsx b/public/app/features/variables/editor/VariableValuesPreview.tsx index 248e470f040..9623c72c50b 100644 --- a/public/app/features/variables/editor/VariableValuesPreview.tsx +++ b/public/app/features/variables/editor/VariableValuesPreview.tsx @@ -1,9 +1,11 @@ +import { css } from '@emotion/css'; import React, { MouseEvent, useCallback, useEffect, useState } from 'react'; -import { VariableOption, VariableWithOptions } from '../types'; + +import { GrafanaTheme } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; import { Button, InlineFieldRow, InlineLabel, useStyles, VerticalGroup } from '@grafana/ui'; -import { GrafanaTheme } from '@grafana/data'; -import { css } from '@emotion/css'; + +import { VariableOption, VariableWithOptions } from '../types'; export interface VariableValuesPreviewProps { variable: VariableWithOptions; diff --git a/public/app/features/variables/editor/actions.test.ts b/public/app/features/variables/editor/actions.test.ts index d421d852f66..57ee80e95a7 100644 --- a/public/app/features/variables/editor/actions.test.ts +++ b/public/app/features/variables/editor/actions.test.ts @@ -1,14 +1,15 @@ +import { initialState } from '../../dashboard/state/reducers'; import { variableAdapters } from '../adapters'; +import { createConstantVariableAdapter } from '../constant/adapter'; import { initialConstantVariableModelState } from '../constant/reducer'; +import * as inspectUtils from '../inspect/utils'; import { constantBuilder, customBuilder } from '../shared/testing/builders'; import { initialKeyedVariablesState, toKeyedAction } from '../state/keyedVariablesReducer'; import * as selectors from '../state/selectors'; -import * as inspectUtils from '../inspect/utils'; import { addVariable } from '../state/sharedReducer'; -import { createConstantVariableAdapter } from '../constant/adapter'; + import { getNextAvailableId, switchToListMode, switchToNewMode } from './actions'; import { setIdInEditor } from './reducer'; -import { initialState } from '../../dashboard/state/reducers'; describe('getNextAvailableId', () => { describe('when called with a custom type and there is already 2 variables', () => { diff --git a/public/app/features/variables/editor/actions.ts b/public/app/features/variables/editor/actions.ts index 00d92fe1ffc..263ccac3b0c 100644 --- a/public/app/features/variables/editor/actions.ts +++ b/public/app/features/variables/editor/actions.ts @@ -1,5 +1,7 @@ -import { VariableType } from '@grafana/data'; import { cloneDeep } from 'lodash'; + +import { VariableType } from '@grafana/data'; + import { ThunkResult } from '../../../types'; import { variableAdapters } from '../adapters'; import { initInspect } from '../inspect/reducer'; @@ -11,6 +13,7 @@ import { addVariable, removeVariable } from '../state/sharedReducer'; import { AddVariable, KeyedVariableIdentifier, VariableIdentifier } from '../state/types'; import { VariableModel } from '../types'; import { toKeyedVariableIdentifier, toStateKey, toVariablePayload } from '../utils'; + import { changeVariableNameFailed, changeVariableNameSucceeded, diff --git a/public/app/features/variables/editor/getVariableQueryEditor.test.tsx b/public/app/features/variables/editor/getVariableQueryEditor.test.tsx index 3eab35ea809..a69e66195f7 100644 --- a/public/app/features/variables/editor/getVariableQueryEditor.test.tsx +++ b/public/app/features/variables/editor/getVariableQueryEditor.test.tsx @@ -1,6 +1,7 @@ import { VariableSupportType } from '@grafana/data'; -import { getVariableQueryEditor, StandardVariableQueryEditor } from './getVariableQueryEditor'; + import { LegacyVariableQueryEditor } from './LegacyVariableQueryEditor'; +import { getVariableQueryEditor, StandardVariableQueryEditor } from './getVariableQueryEditor'; describe('getVariableQueryEditor', () => { describe('happy cases', () => { diff --git a/public/app/features/variables/editor/getVariableQueryEditor.tsx b/public/app/features/variables/editor/getVariableQueryEditor.tsx index 5824530e5d9..d3557d7f07a 100644 --- a/public/app/features/variables/editor/getVariableQueryEditor.tsx +++ b/public/app/features/variables/editor/getVariableQueryEditor.tsx @@ -1,17 +1,19 @@ import React, { useCallback } from 'react'; + import { DataQuery, DataSourceApi, DataSourceJsonData, QueryEditorProps, StandardVariableQuery } from '@grafana/data'; import { getTemplateSrv } from '@grafana/runtime'; -import { LegacyVariableQueryEditor } from './LegacyVariableQueryEditor'; +import { importDataSourcePlugin } from '../../plugins/plugin_loader'; import { hasCustomVariableSupport, hasDatasourceVariableSupport, hasLegacyVariableSupport, hasStandardVariableSupport, } from '../guard'; -import { importDataSourcePlugin } from '../../plugins/plugin_loader'; import { VariableQueryEditorType } from '../types'; +import { LegacyVariableQueryEditor } from './LegacyVariableQueryEditor'; + export async function getVariableQueryEditor< TQuery extends DataQuery = DataQuery, TOptions extends DataSourceJsonData = DataSourceJsonData, diff --git a/public/app/features/variables/editor/reducer.test.ts b/public/app/features/variables/editor/reducer.test.ts index e1ed467bb3f..dde10201c0a 100644 --- a/public/app/features/variables/editor/reducer.test.ts +++ b/public/app/features/variables/editor/reducer.test.ts @@ -1,4 +1,6 @@ import { reducerTester } from '../../../../test/core/redux/reducerTester'; +import { toVariablePayload } from '../utils'; + import { addVariableEditorError, changeVariableEditorExtended, @@ -14,7 +16,6 @@ import { VariableEditorState, variableEditorUnMounted, } from './reducer'; -import { toVariablePayload } from '../utils'; describe('variableEditorReducer', () => { describe('when setIdInEditor is dispatched', () => { diff --git a/public/app/features/variables/editor/reducer.ts b/public/app/features/variables/editor/reducer.ts index 5e0fcbcce33..530a486bd6c 100644 --- a/public/app/features/variables/editor/reducer.ts +++ b/public/app/features/variables/editor/reducer.ts @@ -1,5 +1,7 @@ -import { DataSourceApi, DataSourceRef } from '@grafana/data'; import { createSlice, PayloadAction } from '@reduxjs/toolkit'; + +import { DataSourceApi, DataSourceRef } from '@grafana/data'; + import { VariablePayload } from '../state/types'; import { VariableQueryEditorType } from '../types'; diff --git a/public/app/features/variables/editor/selectors.test.ts b/public/app/features/variables/editor/selectors.test.ts index 6380d9153df..7281ec468b3 100644 --- a/public/app/features/variables/editor/selectors.test.ts +++ b/public/app/features/variables/editor/selectors.test.ts @@ -1,16 +1,17 @@ -import { - getAdhocVariableEditorState, - getDatasourceVariableEditorState, - getQueryVariableEditorState, -} from './selectors'; +import { DataSourceApi } from '@grafana/data'; + +import { LegacyVariableQueryEditor } from './LegacyVariableQueryEditor'; import { AdHocVariableEditorState, DataSourceVariableEditorState, initialVariableEditorState, QueryVariableEditorState, } from './reducer'; -import { LegacyVariableQueryEditor } from './LegacyVariableQueryEditor'; -import { DataSourceApi } from '@grafana/data'; +import { + getAdhocVariableEditorState, + getDatasourceVariableEditorState, + getQueryVariableEditorState, +} from './selectors'; const adhocExtended: AdHocVariableEditorState = { dataSources: [ diff --git a/public/app/features/variables/getAllVariableValuesForUrl.test.ts b/public/app/features/variables/getAllVariableValuesForUrl.test.ts index dbd04260212..8d8ef1172c6 100644 --- a/public/app/features/variables/getAllVariableValuesForUrl.test.ts +++ b/public/app/features/variables/getAllVariableValuesForUrl.test.ts @@ -1,9 +1,11 @@ import { setTemplateSrv } from '@grafana/runtime'; -import { variableAdapters } from './adapters'; -import { createQueryVariableAdapter } from './query/adapter'; -import { getVariablesUrlParams } from './getAllVariableValuesForUrl'; + import { initTemplateSrv } from '../../../test/helpers/initTemplateSrv'; +import { variableAdapters } from './adapters'; +import { getVariablesUrlParams } from './getAllVariableValuesForUrl'; +import { createQueryVariableAdapter } from './query/adapter'; + const key = 'key'; describe('getAllVariableValuesForUrl', () => { diff --git a/public/app/features/variables/getAllVariableValuesForUrl.ts b/public/app/features/variables/getAllVariableValuesForUrl.ts index e775394f287..629904673ad 100644 --- a/public/app/features/variables/getAllVariableValuesForUrl.ts +++ b/public/app/features/variables/getAllVariableValuesForUrl.ts @@ -1,5 +1,6 @@ import { ScopedVars, UrlQueryMap } from '@grafana/data'; import { getTemplateSrv } from '@grafana/runtime'; + import { variableAdapters } from './adapters'; export function getVariablesUrlParams(scopedVars?: ScopedVars): UrlQueryMap { diff --git a/public/app/features/variables/guard.test.ts b/public/app/features/variables/guard.test.ts index 081ee056be5..476fbf4289b 100644 --- a/public/app/features/variables/guard.test.ts +++ b/public/app/features/variables/guard.test.ts @@ -1,3 +1,7 @@ +import { VariableSupportType } from '@grafana/data'; + +import { LegacyVariableQueryEditor } from './editor/LegacyVariableQueryEditor'; +import { StandardVariableQueryEditor } from './editor/getVariableQueryEditor'; import { hasCustomVariableSupport, hasDatasourceVariableSupport, @@ -6,9 +10,6 @@ import { isLegacyQueryEditor, isQueryEditor, } from './guard'; -import { LegacyVariableQueryEditor } from './editor/LegacyVariableQueryEditor'; -import { StandardVariableQueryEditor } from './editor/getVariableQueryEditor'; -import { VariableSupportType } from '@grafana/data'; describe('type guards', () => { describe('hasLegacyVariableSupport', () => { diff --git a/public/app/features/variables/guard.ts b/public/app/features/variables/guard.ts index f5006df682c..0efb21229b5 100644 --- a/public/app/features/variables/guard.ts +++ b/public/app/features/variables/guard.ts @@ -1,5 +1,6 @@ import { ComponentType } from 'react'; import { Observable } from 'rxjs'; + import { CustomVariableSupport, DataQuery, @@ -15,6 +16,7 @@ import { VariableSupportType, } from '@grafana/data'; +import { LEGACY_VARIABLE_QUERY_EDITOR_NAME } from './editor/LegacyVariableQueryEditor'; import { AdHocVariableModel, ConstantVariableModel, @@ -24,7 +26,6 @@ import { VariableWithMultiSupport, VariableWithOptions, } from './types'; -import { LEGACY_VARIABLE_QUERY_EDITOR_NAME } from './editor/LegacyVariableQueryEditor'; export const isQuery = (model: VariableModel): model is QueryVariableModel => { return model.type === 'query'; diff --git a/public/app/features/variables/inspect/NetworkGraph.tsx b/public/app/features/variables/inspect/NetworkGraph.tsx index c72c00b8c6f..38d7707bfef 100644 --- a/public/app/features/variables/inspect/NetworkGraph.tsx +++ b/public/app/features/variables/inspect/NetworkGraph.tsx @@ -1,4 +1,5 @@ import React, { FC, useCallback, useEffect, useRef } from 'react'; + import { GraphEdge, GraphNode } from './utils'; interface OwnProps { diff --git a/public/app/features/variables/inspect/NetworkGraphModal.tsx b/public/app/features/variables/inspect/NetworkGraphModal.tsx index bcabe37d643..2effdbb2b4e 100644 --- a/public/app/features/variables/inspect/NetworkGraphModal.tsx +++ b/public/app/features/variables/inspect/NetworkGraphModal.tsx @@ -1,8 +1,9 @@ import React, { useCallback, useState } from 'react'; + import { Modal } from '@grafana/ui'; -import { GraphEdge, GraphNode } from './utils'; import { NetworkGraph, Props as NetWorkGraphProps } from './NetworkGraph'; +import { GraphEdge, GraphNode } from './utils'; interface NetworkGraphModalApi { showModal: () => void; diff --git a/public/app/features/variables/inspect/VariableUsagesButton.tsx b/public/app/features/variables/inspect/VariableUsagesButton.tsx index 1cc89513179..58a7d2625ca 100644 --- a/public/app/features/variables/inspect/VariableUsagesButton.tsx +++ b/public/app/features/variables/inspect/VariableUsagesButton.tsx @@ -1,9 +1,10 @@ import React, { FC, useMemo } from 'react'; -import { IconButton } from '@grafana/ui'; -import { reportInteraction } from '@grafana/runtime'; -import { UsagesToNetwork } from './utils'; +import { reportInteraction } from '@grafana/runtime'; +import { IconButton } from '@grafana/ui'; + import { NetworkGraphModal } from './NetworkGraphModal'; +import { UsagesToNetwork } from './utils'; interface Props { id: string; diff --git a/public/app/features/variables/inspect/VariablesDependenciesButton.tsx b/public/app/features/variables/inspect/VariablesDependenciesButton.tsx index 142e6fcaca3..e2a76a6e6f6 100644 --- a/public/app/features/variables/inspect/VariablesDependenciesButton.tsx +++ b/public/app/features/variables/inspect/VariablesDependenciesButton.tsx @@ -1,12 +1,14 @@ import React, { FC, useMemo } from 'react'; import { Provider } from 'react-redux'; -import { Button } from '@grafana/ui'; -import { reportInteraction } from '@grafana/runtime'; -import { createDependencyEdges, createDependencyNodes, filterNodesWithDependencies } from './utils'; +import { reportInteraction } from '@grafana/runtime'; +import { Button } from '@grafana/ui'; + import { store } from '../../../store/store'; import { VariableModel } from '../types'; + import { NetworkGraphModal } from './NetworkGraphModal'; +import { createDependencyEdges, createDependencyNodes, filterNodesWithDependencies } from './utils'; interface OwnProps { variables: VariableModel[]; diff --git a/public/app/features/variables/inspect/VariablesUnknownButton.tsx b/public/app/features/variables/inspect/VariablesUnknownButton.tsx index a8ec1998118..1e37f0986dc 100644 --- a/public/app/features/variables/inspect/VariablesUnknownButton.tsx +++ b/public/app/features/variables/inspect/VariablesUnknownButton.tsx @@ -1,7 +1,9 @@ import React, { FC, useMemo } from 'react'; + import { IconButton } from '@grafana/ui'; -import { UsagesToNetwork } from './utils'; + import { NetworkGraphModal } from './NetworkGraphModal'; +import { UsagesToNetwork } from './utils'; interface Props { id: string; diff --git a/public/app/features/variables/inspect/VariablesUnknownTable.test.tsx b/public/app/features/variables/inspect/VariablesUnknownTable.test.tsx index 231bc03134c..161f12f03bd 100644 --- a/public/app/features/variables/inspect/VariablesUnknownTable.test.tsx +++ b/public/app/features/variables/inspect/VariablesUnknownTable.test.tsx @@ -1,10 +1,12 @@ -import React from 'react'; -import * as runtime from '@grafana/runtime'; import { render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import React from 'react'; + +import * as runtime from '@grafana/runtime'; + +import { customBuilder } from '../shared/testing/builders'; import { VariablesUnknownTable, VariablesUnknownTableProps } from './VariablesUnknownTable'; -import { customBuilder } from '../shared/testing/builders'; import * as utils from './utils'; import { UsagesToNetwork } from './utils'; diff --git a/public/app/features/variables/inspect/VariablesUnknownTable.tsx b/public/app/features/variables/inspect/VariablesUnknownTable.tsx index 5c45b6a5b88..d9ef1157f24 100644 --- a/public/app/features/variables/inspect/VariablesUnknownTable.tsx +++ b/public/app/features/variables/inspect/VariablesUnknownTable.tsx @@ -1,12 +1,14 @@ -import React, { ReactElement, useEffect, useState } from 'react'; import { css } from '@emotion/css'; +import React, { ReactElement, useEffect, useState } from 'react'; import { useAsync } from 'react-use'; -import { CollapsableSection, HorizontalGroup, Icon, Spinner, Tooltip, useStyles, VerticalGroup } from '@grafana/ui'; + import { GrafanaTheme } from '@grafana/data'; import { reportInteraction } from '@grafana/runtime'; +import { CollapsableSection, HorizontalGroup, Icon, Spinner, Tooltip, useStyles, VerticalGroup } from '@grafana/ui'; -import { VariableModel } from '../types'; import { DashboardModel } from '../../dashboard/state'; +import { VariableModel } from '../types'; + import { VariablesUnknownButton } from './VariablesUnknownButton'; import { getUnknownsNetwork, UsagesToNetwork } from './utils'; diff --git a/public/app/features/variables/inspect/reducer.test.ts b/public/app/features/variables/inspect/reducer.test.ts index 75218bcb366..7d2a7c6c2d6 100644 --- a/public/app/features/variables/inspect/reducer.test.ts +++ b/public/app/features/variables/inspect/reducer.test.ts @@ -1,7 +1,8 @@ import { reducerTester } from '../../../../test/core/redux/reducerTester'; -import { initialVariableInspectState, initInspect, variableInspectReducer, VariableInspectState } from './reducer'; import { textboxBuilder } from '../shared/testing/builders'; +import { initialVariableInspectState, initInspect, variableInspectReducer, VariableInspectState } from './reducer'; + describe('variableInspectReducer', () => { describe('when initInspect is dispatched', () => { it('then state should be correct', () => { diff --git a/public/app/features/variables/inspect/reducer.ts b/public/app/features/variables/inspect/reducer.ts index 8ec775d4d1a..be8282edb22 100644 --- a/public/app/features/variables/inspect/reducer.ts +++ b/public/app/features/variables/inspect/reducer.ts @@ -1,6 +1,7 @@ -import { UsagesToNetwork, VariableUsageTree } from './utils'; import { createSlice, PayloadAction } from '@reduxjs/toolkit'; +import { UsagesToNetwork, VariableUsageTree } from './utils'; + export interface VariableInspectState { usages: VariableUsageTree[]; usagesNetwork: UsagesToNetwork[]; diff --git a/public/app/features/variables/inspect/utils.test.ts b/public/app/features/variables/inspect/utils.test.ts index 4b2f6167de4..c313f6ef6a0 100644 --- a/public/app/features/variables/inspect/utils.test.ts +++ b/public/app/features/variables/inspect/utils.test.ts @@ -1,3 +1,10 @@ +import { PanelModel } from 'app/features/dashboard/state'; + +import { variableAdapters } from '../adapters'; +import { createCustomVariableAdapter } from '../custom/adapter'; +import { createDataSourceVariableAdapter } from '../datasource/adapter'; +import { createQueryVariableAdapter } from '../query/adapter'; + import { flattenPanels, getAffectedPanelIdsForVariable, @@ -5,11 +12,6 @@ import { getDependenciesForVariable, getPropsWithVariable, } from './utils'; -import { variableAdapters } from '../adapters'; -import { createDataSourceVariableAdapter } from '../datasource/adapter'; -import { createCustomVariableAdapter } from '../custom/adapter'; -import { createQueryVariableAdapter } from '../query/adapter'; -import { PanelModel } from 'app/features/dashboard/state'; describe('getPropsWithVariable', () => { it('when called it should return the correct graph', () => { diff --git a/public/app/features/variables/inspect/utils.ts b/public/app/features/variables/inspect/utils.ts index 3eb5e2affd6..36afa0e2cf4 100644 --- a/public/app/features/variables/inspect/utils.ts +++ b/public/app/features/variables/inspect/utils.ts @@ -1,10 +1,11 @@ -import { variableAdapters } from '../adapters'; -import { DashboardModel, PanelModel } from '../../dashboard/state'; -import { isAdHoc } from '../guard'; +import { DataLinkBuiltInVars } from '@grafana/data'; + import { safeStringifyValue } from '../../../core/utils/explore'; +import { DashboardModel, PanelModel } from '../../dashboard/state'; +import { variableAdapters } from '../adapters'; +import { isAdHoc } from '../guard'; import { VariableModel } from '../types'; import { containsVariable, variableRegex, variableRegexExec } from '../utils'; -import { DataLinkBuiltInVars } from '@grafana/data'; export interface GraphNode { id: string; diff --git a/public/app/features/variables/interval/IntervalVariableEditor.tsx b/public/app/features/variables/interval/IntervalVariableEditor.tsx index 4c12a7960fd..717ec2a7997 100644 --- a/public/app/features/variables/interval/IntervalVariableEditor.tsx +++ b/public/app/features/variables/interval/IntervalVariableEditor.tsx @@ -1,14 +1,15 @@ import React, { ChangeEvent, FormEvent, PureComponent } from 'react'; -import { InlineFieldRow, VerticalGroup } from '@grafana/ui'; -import { IntervalVariableModel } from '../types'; -import { VariableEditorProps } from '../editor/types'; -import { VariableSectionHeader } from '../editor/VariableSectionHeader'; -import { VariableTextField } from '../editor/VariableTextField'; -import { VariableSwitchField } from '../editor/VariableSwitchField'; -import { VariableSelectField } from '../editor/VariableSelectField'; import { SelectableValue } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; +import { InlineFieldRow, VerticalGroup } from '@grafana/ui'; + +import { VariableSectionHeader } from '../editor/VariableSectionHeader'; +import { VariableSelectField } from '../editor/VariableSelectField'; +import { VariableSwitchField } from '../editor/VariableSwitchField'; +import { VariableTextField } from '../editor/VariableTextField'; +import { VariableEditorProps } from '../editor/types'; +import { IntervalVariableModel } from '../types'; export interface Props extends VariableEditorProps {} diff --git a/public/app/features/variables/interval/actions.test.ts b/public/app/features/variables/interval/actions.test.ts index 007caacc7a7..6a8b4020b79 100644 --- a/public/app/features/variables/interval/actions.test.ts +++ b/public/app/features/variables/interval/actions.test.ts @@ -1,27 +1,29 @@ -import { getRootReducer, RootReducerType } from '../state/helpers'; +import { dateTime } from '@grafana/data'; + import { reduxTester } from '../../../../test/core/redux/reduxTester'; -import { updateAutoValue, UpdateAutoValueDependencies, updateIntervalVariableOptions } from './actions'; -import { createIntervalOptions } from './reducer'; +import { silenceConsoleOutput } from '../../../../test/core/utils/silenceConsoleOutput'; +import { afterEach, beforeEach } from '../../../../test/lib/common'; +import { notifyApp } from '../../../core/actions'; +import { getTimeSrv, setTimeSrv, TimeSrv } from '../../dashboard/services/TimeSrv'; +import { TemplateSrv } from '../../templating/template_srv'; +import { variableAdapters } from '../adapters'; +import { intervalBuilder } from '../shared/testing/builders'; +import { updateOptions } from '../state/actions'; +import { getRootReducer, RootReducerType } from '../state/helpers'; +import { toKeyedAction } from '../state/keyedVariablesReducer'; import { addVariable, setCurrentVariableValue, variableStateFailed, variableStateFetching, } from '../state/sharedReducer'; -import { variableAdapters } from '../adapters'; -import { createIntervalVariableAdapter } from './adapter'; -import { dateTime } from '@grafana/data'; -import { getTimeSrv, setTimeSrv, TimeSrv } from '../../dashboard/services/TimeSrv'; -import { TemplateSrv } from '../../templating/template_srv'; -import { intervalBuilder } from '../shared/testing/builders'; -import { updateOptions } from '../state/actions'; -import { notifyApp } from '../../../core/actions'; -import { silenceConsoleOutput } from '../../../../test/core/utils/silenceConsoleOutput'; import { variablesInitTransaction } from '../state/transactionReducer'; -import { afterEach, beforeEach } from '../../../../test/lib/common'; -import { toKeyedAction } from '../state/keyedVariablesReducer'; import { toKeyedVariableIdentifier, toVariablePayload } from '../utils'; +import { updateAutoValue, UpdateAutoValueDependencies, updateIntervalVariableOptions } from './actions'; +import { createIntervalVariableAdapter } from './adapter'; +import { createIntervalOptions } from './reducer'; + describe('interval actions', () => { variableAdapters.setInit(() => [createIntervalVariableAdapter()]); describe('when updateIntervalVariableOptions is dispatched', () => { diff --git a/public/app/features/variables/interval/actions.ts b/public/app/features/variables/interval/actions.ts index bc3f4d8d521..24565a1fea2 100644 --- a/public/app/features/variables/interval/actions.ts +++ b/public/app/features/variables/interval/actions.ts @@ -1,16 +1,17 @@ import { rangeUtil } from '@grafana/data'; -import { KeyedVariableIdentifier } from '../state/types'; import { ThunkResult } from '../../../types'; -import { createIntervalOptions } from './reducer'; -import { validateVariableSelectionState } from '../state/actions'; -import { getVariable } from '../state/selectors'; -import { IntervalVariableModel } from '../types'; import { getTimeSrv } from '../../dashboard/services/TimeSrv'; import { getTemplateSrv, TemplateSrv } from '../../templating/template_srv'; +import { validateVariableSelectionState } from '../state/actions'; import { toKeyedAction } from '../state/keyedVariablesReducer'; +import { getVariable } from '../state/selectors'; +import { KeyedVariableIdentifier } from '../state/types'; +import { IntervalVariableModel } from '../types'; import { toVariablePayload } from '../utils'; +import { createIntervalOptions } from './reducer'; + export const updateIntervalVariableOptions = (identifier: KeyedVariableIdentifier): ThunkResult => async (dispatch) => { diff --git a/public/app/features/variables/interval/adapter.ts b/public/app/features/variables/interval/adapter.ts index 69e523836a6..a88a83b455c 100644 --- a/public/app/features/variables/interval/adapter.ts +++ b/public/app/features/variables/interval/adapter.ts @@ -1,13 +1,15 @@ import { cloneDeep } from 'lodash'; -import { IntervalVariableModel } from '../types'; + import { dispatch } from '../../../store/store'; -import { setOptionAsCurrent, setOptionFromUrl } from '../state/actions'; import { VariableAdapter } from '../adapters'; -import { initialIntervalVariableModelState, intervalVariableReducer } from './reducer'; +import { optionPickerFactory } from '../pickers'; +import { setOptionAsCurrent, setOptionFromUrl } from '../state/actions'; +import { IntervalVariableModel } from '../types'; +import { toKeyedVariableIdentifier } from '../utils'; + import { IntervalVariableEditor } from './IntervalVariableEditor'; import { updateAutoValue, updateIntervalVariableOptions } from './actions'; -import { optionPickerFactory } from '../pickers'; -import { toKeyedVariableIdentifier } from '../utils'; +import { initialIntervalVariableModelState, intervalVariableReducer } from './reducer'; export const createIntervalVariableAdapter = (): VariableAdapter => { return { diff --git a/public/app/features/variables/interval/reducer.test.ts b/public/app/features/variables/interval/reducer.test.ts index e5b04df6ae8..c3542c2322b 100644 --- a/public/app/features/variables/interval/reducer.test.ts +++ b/public/app/features/variables/interval/reducer.test.ts @@ -1,13 +1,14 @@ import { cloneDeep } from 'lodash'; +import { reducerTester } from '../../../../test/core/redux/reducerTester'; import { getVariableTestContext } from '../state/helpers'; import { VariablesState } from '../state/types'; -import { createIntervalVariableAdapter } from './adapter'; import { IntervalVariableModel } from '../types'; -import { reducerTester } from '../../../../test/core/redux/reducerTester'; -import { createIntervalOptions, intervalVariableReducer } from './reducer'; import { toVariablePayload } from '../utils'; +import { createIntervalVariableAdapter } from './adapter'; +import { createIntervalOptions, intervalVariableReducer } from './reducer'; + describe('intervalVariableReducer', () => { const adapter = createIntervalVariableAdapter(); describe('when createIntervalOptions is dispatched', () => { diff --git a/public/app/features/variables/interval/reducer.ts b/public/app/features/variables/interval/reducer.ts index faadce99a6a..d1e910bd7f2 100644 --- a/public/app/features/variables/interval/reducer.ts +++ b/public/app/features/variables/interval/reducer.ts @@ -1,8 +1,9 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit'; -import { initialVariableModelState, IntervalVariableModel, VariableOption, VariableRefresh } from '../types'; -import { initialVariablesState, VariablePayload, VariablesState } from '../state/types'; import { map } from 'lodash'; + import { getInstanceState } from '../state/selectors'; +import { initialVariablesState, VariablePayload, VariablesState } from '../state/types'; +import { initialVariableModelState, IntervalVariableModel, VariableOption, VariableRefresh } from '../types'; export const initialIntervalVariableModelState: IntervalVariableModel = { ...initialVariableModelState, diff --git a/public/app/features/variables/pickers/OptionsPicker/OptionPicker.test.tsx b/public/app/features/variables/pickers/OptionsPicker/OptionPicker.test.tsx index 8806a3a6231..60b42c963dd 100644 --- a/public/app/features/variables/pickers/OptionsPicker/OptionPicker.test.tsx +++ b/public/app/features/variables/pickers/OptionsPicker/OptionPicker.test.tsx @@ -1,16 +1,18 @@ -import React from 'react'; -import { Provider } from 'react-redux'; import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import React from 'react'; +import { Provider } from 'react-redux'; + +import { LoadingState } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; -import { LoadingState } from '@grafana/data'; -import { VariablePickerProps } from '../types'; -import { QueryVariableModel, VariableWithMultiSupport, VariableWithOptions } from '../../types'; import { queryBuilder } from '../../shared/testing/builders'; +import { getPreloadedState } from '../../state/helpers'; +import { QueryVariableModel, VariableWithMultiSupport, VariableWithOptions } from '../../types'; +import { VariablePickerProps } from '../types'; + import { optionPickerFactory } from './OptionsPicker'; import { initialOptionPickerState, OptionsPickerState } from './reducer'; -import { getPreloadedState } from '../../state/helpers'; interface Args { pickerState?: Partial; diff --git a/public/app/features/variables/pickers/OptionsPicker/OptionsPicker.tsx b/public/app/features/variables/pickers/OptionsPicker/OptionsPicker.tsx index c33a9afc05b..aad1ab98e0f 100644 --- a/public/app/features/variables/pickers/OptionsPicker/OptionsPicker.tsx +++ b/public/app/features/variables/pickers/OptionsPicker/OptionsPicker.tsx @@ -1,24 +1,26 @@ import React, { ComponentType, PureComponent } from 'react'; -import { bindActionCreators } from 'redux'; import { connect, ConnectedProps } from 'react-redux'; -import { ClickOutsideWrapper } from '@grafana/ui'; -import { LoadingState } from '@grafana/data'; +import { bindActionCreators } from 'redux'; +import { LoadingState } from '@grafana/data'; +import { ClickOutsideWrapper } from '@grafana/ui'; import { StoreState, ThunkDispatch } from 'app/types'; + +import { isMulti } from '../../guard'; +import { getVariableQueryRunner } from '../../query/VariableQueryRunner'; +import { formatVariableLabel } from '../../shared/formatVariable'; +import { toKeyedAction } from '../../state/keyedVariablesReducer'; +import { getVariablesState } from '../../state/selectors'; +import { KeyedVariableIdentifier } from '../../state/types'; +import { VariableOption, VariableWithMultiSupport, VariableWithOptions } from '../../types'; +import { toKeyedVariableIdentifier } from '../../utils'; import { VariableInput } from '../shared/VariableInput'; +import { VariableLink } from '../shared/VariableLink'; +import { VariableOptions } from '../shared/VariableOptions'; +import { NavigationKey, VariablePickerProps } from '../types'; + import { commitChangesToVariable, filterOrSearchOptions, navigateOptions, openOptions } from './actions'; import { initialOptionPickerState, OptionsPickerState, toggleAllOptions, toggleOption } from './reducer'; -import { VariableOption, VariableWithMultiSupport, VariableWithOptions } from '../../types'; -import { VariableOptions } from '../shared/VariableOptions'; -import { isMulti } from '../../guard'; -import { NavigationKey, VariablePickerProps } from '../types'; -import { formatVariableLabel } from '../../shared/formatVariable'; -import { KeyedVariableIdentifier } from '../../state/types'; -import { getVariableQueryRunner } from '../../query/VariableQueryRunner'; -import { VariableLink } from '../shared/VariableLink'; -import { getVariablesState } from '../../state/selectors'; -import { toKeyedAction } from '../../state/keyedVariablesReducer'; -import { toKeyedVariableIdentifier } from '../../utils'; export const optionPickerFactory = (): ComponentType< VariablePickerProps diff --git a/public/app/features/variables/pickers/OptionsPicker/actions.test.ts b/public/app/features/variables/pickers/OptionsPicker/actions.test.ts index 0c5e4ecffc3..c578748bfc4 100644 --- a/public/app/features/variables/pickers/OptionsPicker/actions.test.ts +++ b/public/app/features/variables/pickers/OptionsPicker/actions.test.ts @@ -1,6 +1,23 @@ +import { locationService } from '@grafana/runtime'; + import { reduxTester } from '../../../../../test/core/redux/reduxTester'; +import { variableAdapters } from '../../adapters'; +import { createQueryVariableAdapter } from '../../query/adapter'; +import { queryBuilder } from '../../shared/testing/builders'; import { getPreloadedState, getRootReducer, RootReducerType } from '../../state/helpers'; +import { toKeyedAction } from '../../state/keyedVariablesReducer'; +import { addVariable, changeVariableProp, setCurrentVariableValue } from '../../state/sharedReducer'; import { initialVariableModelState, QueryVariableModel, VariableRefresh, VariableSort } from '../../types'; +import { toKeyedVariableIdentifier, toVariablePayload } from '../../utils'; +import { NavigationKey } from '../types'; + +import { + commitChangesToVariable, + filterOrSearchOptions, + navigateOptions, + openOptions, + toggleOptionByHighlight, +} from './actions'; import { hideOptions, initialOptionPickerState, @@ -10,21 +27,6 @@ import { updateOptionsAndFilter, updateSearchQuery, } from './reducer'; -import { - commitChangesToVariable, - filterOrSearchOptions, - navigateOptions, - openOptions, - toggleOptionByHighlight, -} from './actions'; -import { NavigationKey } from '../types'; -import { addVariable, changeVariableProp, setCurrentVariableValue } from '../../state/sharedReducer'; -import { variableAdapters } from '../../adapters'; -import { createQueryVariableAdapter } from '../../query/adapter'; -import { locationService } from '@grafana/runtime'; -import { queryBuilder } from '../../shared/testing/builders'; -import { toKeyedAction } from '../../state/keyedVariablesReducer'; -import { toKeyedVariableIdentifier, toVariablePayload } from '../../utils'; const datasource = { metricFindQuery: jest.fn(() => Promise.resolve([])), diff --git a/public/app/features/variables/pickers/OptionsPicker/actions.ts b/public/app/features/variables/pickers/OptionsPicker/actions.ts index 7d25290fb22..04f604f9fd5 100644 --- a/public/app/features/variables/pickers/OptionsPicker/actions.ts +++ b/public/app/features/variables/pickers/OptionsPicker/actions.ts @@ -1,9 +1,16 @@ import { debounce, trim } from 'lodash'; + import { StoreState, ThunkDispatch, ThunkResult } from 'app/types'; -import { VariableOption, VariableWithMultiSupport, VariableWithOptions } from '../../types'; + import { variableAdapters } from '../../adapters'; +import { toKeyedAction } from '../../state/keyedVariablesReducer'; import { getVariable, getVariablesState } from '../../state/selectors'; +import { changeVariableProp, setCurrentVariableValue } from '../../state/sharedReducer'; +import { KeyedVariableIdentifier } from '../../state/types'; +import { VariableOption, VariableWithMultiSupport, VariableWithOptions } from '../../types'; +import { containsSearchFilter, getCurrentText, toVariablePayload } from '../../utils'; import { NavigationKey } from '../types'; + import { hideOptions, moveOptionsHighlight, @@ -14,10 +21,6 @@ import { updateOptionsFromSearch, updateSearchQuery, } from './reducer'; -import { changeVariableProp, setCurrentVariableValue } from '../../state/sharedReducer'; -import { KeyedVariableIdentifier } from '../../state/types'; -import { containsSearchFilter, getCurrentText, toVariablePayload } from '../../utils'; -import { toKeyedAction } from '../../state/keyedVariablesReducer'; export const navigateOptions = (rootStateKey: string, key: NavigationKey, clearOthers: boolean): ThunkResult => { return async (dispatch, getState) => { diff --git a/public/app/features/variables/pickers/OptionsPicker/reducer.test.ts b/public/app/features/variables/pickers/OptionsPicker/reducer.test.ts index b706a6c3a83..473d70a78c6 100644 --- a/public/app/features/variables/pickers/OptionsPicker/reducer.test.ts +++ b/public/app/features/variables/pickers/OptionsPicker/reducer.test.ts @@ -1,4 +1,9 @@ import { cloneDeep } from 'lodash'; + +import { reducerTester } from '../../../../../test/core/redux/reducerTester'; +import { ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE } from '../../constants'; +import { QueryVariableModel, VariableOption } from '../../types'; + import { cleanPickerState, hideOptions, @@ -14,9 +19,6 @@ import { updateOptionsFromSearch, updateSearchQuery, } from './reducer'; -import { reducerTester } from '../../../../../test/core/redux/reducerTester'; -import { QueryVariableModel, VariableOption } from '../../types'; -import { ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE } from '../../constants'; const getVariableTestContext = (extend: Partial) => { return { diff --git a/public/app/features/variables/pickers/OptionsPicker/reducer.ts b/public/app/features/variables/pickers/OptionsPicker/reducer.ts index ce9f009f384..64461273399 100644 --- a/public/app/features/variables/pickers/OptionsPicker/reducer.ts +++ b/public/app/features/variables/pickers/OptionsPicker/reducer.ts @@ -1,10 +1,11 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit'; import { cloneDeep, isString, trim } from 'lodash'; -import { VariableOption, VariableWithOptions } from '../../types'; -import { isMulti, isQuery } from '../../guard'; + import { applyStateChanges } from '../../../../core/utils/applyStateChanges'; -import { containsSearchFilter } from '../../utils'; import { ALL_VARIABLE_VALUE } from '../../constants'; +import { isMulti, isQuery } from '../../guard'; +import { VariableOption, VariableWithOptions } from '../../types'; +import { containsSearchFilter } from '../../utils'; export interface ToggleOption { option?: VariableOption; diff --git a/public/app/features/variables/pickers/PickerRenderer.tsx b/public/app/features/variables/pickers/PickerRenderer.tsx index 7defe8ceb0b..80c2a73a5df 100644 --- a/public/app/features/variables/pickers/PickerRenderer.tsx +++ b/public/app/features/variables/pickers/PickerRenderer.tsx @@ -1,9 +1,11 @@ import React, { FunctionComponent, PropsWithChildren, ReactElement, useMemo } from 'react'; -import { VariableHide, VariableModel } from '../types'; + import { selectors } from '@grafana/e2e-selectors'; -import { variableAdapters } from '../adapters'; import { Tooltip } from '@grafana/ui'; +import { variableAdapters } from '../adapters'; +import { VariableHide, VariableModel } from '../types'; + interface Props { variable: VariableModel; } diff --git a/public/app/features/variables/pickers/shared/VariableInput.tsx b/public/app/features/variables/pickers/shared/VariableInput.tsx index ad9c57a5a94..967015709db 100644 --- a/public/app/features/variables/pickers/shared/VariableInput.tsx +++ b/public/app/features/variables/pickers/shared/VariableInput.tsx @@ -1,4 +1,5 @@ import React, { PureComponent } from 'react'; + import { NavigationKey } from '../types'; export interface Props extends Omit, 'onChange' | 'value'> { diff --git a/public/app/features/variables/pickers/shared/VariableLink.tsx b/public/app/features/variables/pickers/shared/VariableLink.tsx index e50fda6d2a5..dcdf06f73b9 100644 --- a/public/app/features/variables/pickers/shared/VariableLink.tsx +++ b/public/app/features/variables/pickers/shared/VariableLink.tsx @@ -1,8 +1,9 @@ -import React, { FC, MouseEvent, useCallback } from 'react'; import { css } from '@emotion/css'; -import { Icon, Tooltip, useStyles } from '@grafana/ui'; -import { selectors } from '@grafana/e2e-selectors'; +import React, { FC, MouseEvent, useCallback } from 'react'; + import { GrafanaTheme } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; +import { Icon, Tooltip, useStyles } from '@grafana/ui'; interface Props { onClick: () => void; diff --git a/public/app/features/variables/pickers/shared/VariableOptions.tsx b/public/app/features/variables/pickers/shared/VariableOptions.tsx index e3f77b863de..3a4e96e05fc 100644 --- a/public/app/features/variables/pickers/shared/VariableOptions.tsx +++ b/public/app/features/variables/pickers/shared/VariableOptions.tsx @@ -1,9 +1,10 @@ +import { css, cx } from '@emotion/css'; import React, { PureComponent } from 'react'; -import { Tooltip } from '@grafana/ui'; + import { selectors } from '@grafana/e2e-selectors'; +import { Tooltip } from '@grafana/ui'; import { VariableOption } from '../../types'; -import { css, cx } from '@emotion/css'; export interface Props extends React.HTMLProps { multi: boolean; diff --git a/public/app/features/variables/query/QueryVariableEditor.test.tsx b/public/app/features/variables/query/QueryVariableEditor.test.tsx index b8a79ce6f52..23754e21007 100644 --- a/public/app/features/variables/query/QueryVariableEditor.test.tsx +++ b/public/app/features/variables/query/QueryVariableEditor.test.tsx @@ -1,17 +1,19 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import React from 'react'; + import { DataSourceApi } from '@grafana/data'; +import { mockDataSource } from 'app/features/alerting/unified/mocks'; +import { DataSourceType } from 'app/features/alerting/unified/utils/datasource'; + +import { describe, expect } from '../../../../test/lib/common'; +import { NEW_VARIABLE_ID } from '../constants'; +import { LegacyVariableQueryEditor } from '../editor/LegacyVariableQueryEditor'; +import { KeyedVariableIdentifier } from '../state/types'; +import { VariableModel } from '../types'; import { Props, QueryVariableEditorUnConnected } from './QueryVariableEditor'; import { initialQueryVariableModelState } from './reducer'; -import { describe, expect } from '../../../../test/lib/common'; -import { LegacyVariableQueryEditor } from '../editor/LegacyVariableQueryEditor'; -import { mockDataSource } from 'app/features/alerting/unified/mocks'; -import { DataSourceType } from 'app/features/alerting/unified/utils/datasource'; -import { NEW_VARIABLE_ID } from '../constants'; -import { VariableModel } from '../types'; -import { KeyedVariableIdentifier } from '../state/types'; const setupTestContext = (options: Partial) => { const variableDefaults: Partial = { rootStateKey: 'key' }; diff --git a/public/app/features/variables/query/QueryVariableEditor.tsx b/public/app/features/variables/query/QueryVariableEditor.tsx index 94ff3cb539b..d407e965d9c 100644 --- a/public/app/features/variables/query/QueryVariableEditor.tsx +++ b/public/app/features/variables/query/QueryVariableEditor.tsx @@ -1,27 +1,29 @@ +import { css } from '@emotion/css'; import React, { FormEvent, PureComponent } from 'react'; import { connect, ConnectedProps } from 'react-redux'; -import { css } from '@emotion/css'; -import { InlineField, InlineFieldRow, VerticalGroup } from '@grafana/ui'; + +import { DataSourceInstanceSettings, getDataSourceRef, LoadingState, SelectableValue } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; import { DataSourcePicker, getTemplateSrv } from '@grafana/runtime'; -import { DataSourceInstanceSettings, getDataSourceRef, LoadingState, SelectableValue } from '@grafana/data'; +import { InlineField, InlineFieldRow, VerticalGroup } from '@grafana/ui'; -import { SelectionOptionsEditor } from '../editor/SelectionOptionsEditor'; -import { QueryVariableModel, VariableRefresh, VariableSort, VariableWithMultiSupport } from '../types'; -import { changeQueryVariableDataSource, changeQueryVariableQuery, initQueryVariableEditor } from './actions'; -import { initialVariableEditorState } from '../editor/reducer'; -import { OnPropChangeArguments, VariableEditorProps } from '../editor/types'; import { StoreState } from '../../../types'; -import { changeVariableMultiValue } from '../state/actions'; import { getTimeSrv } from '../../dashboard/services/TimeSrv'; -import { isLegacyQueryEditor, isQueryEditor } from '../guard'; +import { SelectionOptionsEditor } from '../editor/SelectionOptionsEditor'; import { VariableSectionHeader } from '../editor/VariableSectionHeader'; import { VariableTextField } from '../editor/VariableTextField'; +import { initialVariableEditorState } from '../editor/reducer'; +import { getQueryVariableEditorState } from '../editor/selectors'; +import { OnPropChangeArguments, VariableEditorProps } from '../editor/types'; +import { isLegacyQueryEditor, isQueryEditor } from '../guard'; +import { changeVariableMultiValue } from '../state/actions'; +import { getVariablesState } from '../state/selectors'; +import { QueryVariableModel, VariableRefresh, VariableSort, VariableWithMultiSupport } from '../types'; +import { toKeyedVariableIdentifier } from '../utils'; + import { QueryVariableRefreshSelect } from './QueryVariableRefreshSelect'; import { QueryVariableSortSelect } from './QueryVariableSortSelect'; -import { getQueryVariableEditorState } from '../editor/selectors'; -import { getVariablesState } from '../state/selectors'; -import { toKeyedVariableIdentifier } from '../utils'; +import { changeQueryVariableDataSource, changeQueryVariableQuery, initQueryVariableEditor } from './actions'; const mapStateToProps = (state: StoreState, ownProps: OwnProps) => { const { rootStateKey } = ownProps.variable; diff --git a/public/app/features/variables/query/QueryVariableRefreshSelect.tsx b/public/app/features/variables/query/QueryVariableRefreshSelect.tsx index 4bb6d7953e4..ed77552852b 100644 --- a/public/app/features/variables/query/QueryVariableRefreshSelect.tsx +++ b/public/app/features/variables/query/QueryVariableRefreshSelect.tsx @@ -1,6 +1,8 @@ import React, { PropsWithChildren, useMemo } from 'react'; + import { SelectableValue } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; + import { VariableSelectField } from '../editor/VariableSelectField'; import { VariableRefresh } from '../types'; diff --git a/public/app/features/variables/query/QueryVariableSortSelect.tsx b/public/app/features/variables/query/QueryVariableSortSelect.tsx index 6ab3052ceb5..d097f460c62 100644 --- a/public/app/features/variables/query/QueryVariableSortSelect.tsx +++ b/public/app/features/variables/query/QueryVariableSortSelect.tsx @@ -1,6 +1,8 @@ import React, { PropsWithChildren, useMemo } from 'react'; + import { SelectableValue } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; + import { VariableSelectField } from '../editor/VariableSelectField'; import { VariableSort } from '../types'; diff --git a/public/app/features/variables/query/VariableQueryRunner.test.ts b/public/app/features/variables/query/VariableQueryRunner.test.ts index e1670479de2..223da0473c1 100644 --- a/public/app/features/variables/query/VariableQueryRunner.test.ts +++ b/public/app/features/variables/query/VariableQueryRunner.test.ts @@ -1,18 +1,20 @@ import { of, throwError } from 'rxjs'; -import { getDefaultTimeRange, LoadingState, VariableSupportType } from '@grafana/data'; import { delay } from 'rxjs/operators'; -import { UpdateOptionsResults, VariableQueryRunner } from './VariableQueryRunner'; +import { getDefaultTimeRange, LoadingState, VariableSupportType } from '@grafana/data'; + import { queryBuilder } from '../shared/testing/builders'; -import { QueryRunner, QueryRunners } from './queryRunners'; -import { KeyedVariableIdentifier } from '../state/types'; -import { QueryVariableModel } from '../types'; -import { updateVariableOptions } from './reducer'; +import { getPreloadedState } from '../state/helpers'; import { toKeyedAction } from '../state/keyedVariablesReducer'; import { initialTransactionState } from '../state/transactionReducer'; -import { getPreloadedState } from '../state/helpers'; +import { KeyedVariableIdentifier } from '../state/types'; +import { QueryVariableModel } from '../types'; import { toKeyedVariableIdentifier } from '../utils'; +import { UpdateOptionsResults, VariableQueryRunner } from './VariableQueryRunner'; +import { QueryRunner, QueryRunners } from './queryRunners'; +import { updateVariableOptions } from './reducer'; + type DoneCallback = { (...args: any[]): any; fail(error?: string | { message: string }): any; diff --git a/public/app/features/variables/query/VariableQueryRunner.ts b/public/app/features/variables/query/VariableQueryRunner.ts index 866cc92ca85..7b33e615cd2 100644 --- a/public/app/features/variables/query/VariableQueryRunner.ts +++ b/public/app/features/variables/query/VariableQueryRunner.ts @@ -1,5 +1,7 @@ import { merge, Observable, of, Subject, throwError, Unsubscribable } from 'rxjs'; import { catchError, filter, finalize, mergeMap, take, takeUntil } from 'rxjs/operators'; +import { v4 as uuidv4 } from 'uuid'; + import { CoreApp, DataQuery, @@ -11,17 +13,17 @@ import { ScopedVars, } from '@grafana/data'; -import { KeyedVariableIdentifier } from '../state/types'; -import { getLastKey, getVariable } from '../state/selectors'; -import { QueryVariableModel, VariableRefresh } from '../types'; -import { StoreState, ThunkDispatch } from '../../../types'; import { dispatch, getState } from '../../../store/store'; -import { getTemplatedRegex } from '../utils'; -import { v4 as uuidv4 } from 'uuid'; +import { StoreState, ThunkDispatch } from '../../../types'; import { getTimeSrv } from '../../dashboard/services/TimeSrv'; -import { QueryRunners } from './queryRunners'; import { runRequest } from '../../query/state/runRequest'; +import { getLastKey, getVariable } from '../state/selectors'; +import { KeyedVariableIdentifier } from '../state/types'; +import { QueryVariableModel, VariableRefresh } from '../types'; +import { getTemplatedRegex } from '../utils'; + import { toMetricFindValues, updateOptionsState, validateVariableSelection } from './operators'; +import { QueryRunners } from './queryRunners'; interface UpdateOptionsArgs { identifier: KeyedVariableIdentifier; diff --git a/public/app/features/variables/query/actions.test.tsx b/public/app/features/variables/query/actions.test.tsx index 7f8afffcd8b..50ed066034c 100644 --- a/public/app/features/variables/query/actions.test.tsx +++ b/public/app/features/variables/query/actions.test.tsx @@ -1,11 +1,26 @@ import React from 'react'; +import { expect } from 'test/lib/common'; + import { DataSourceRef, getDefaultTimeRange, LoadingState } from '@grafana/data'; +import { setDataSourceSrv } from '@grafana/runtime'; -import { variableAdapters } from '../adapters'; -import { createQueryVariableAdapter } from './adapter'; import { reduxTester } from '../../../../test/core/redux/reduxTester'; +import { silenceConsoleOutput } from '../../../../test/core/utils/silenceConsoleOutput'; +import { notifyApp } from '../../../core/reducers/appNotification'; +import { getTimeSrv, setTimeSrv, TimeSrv } from '../../dashboard/services/TimeSrv'; +import { variableAdapters } from '../adapters'; +import { ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE } from '../constants'; +import { LegacyVariableQueryEditor } from '../editor/LegacyVariableQueryEditor'; +import { + addVariableEditorError, + changeVariableEditorExtended, + initialVariableEditorState, + removeVariableEditorError, + setIdInEditor, +} from '../editor/reducer'; +import { updateOptions } from '../state/actions'; import { getPreloadedState, getRootReducer, RootReducerType } from '../state/helpers'; -import { QueryVariableModel, VariableHide, VariableQueryEditorProps, VariableRefresh, VariableSort } from '../types'; +import { toKeyedAction } from '../state/keyedVariablesReducer'; import { addVariable, changeVariableProp, @@ -14,6 +29,11 @@ import { variableStateFailed, variableStateFetching, } from '../state/sharedReducer'; +import { variablesInitTransaction } from '../state/transactionReducer'; +import { QueryVariableModel, VariableHide, VariableQueryEditorProps, VariableRefresh, VariableSort } from '../types'; +import { toKeyedVariableIdentifier, toVariablePayload } from '../utils'; + +import { setVariableQueryRunner, VariableQueryRunner } from './VariableQueryRunner'; import { changeQueryVariableDataSource, changeQueryVariableQuery, @@ -22,26 +42,8 @@ import { initQueryVariableEditor, updateQueryVariableOptions, } from './actions'; +import { createQueryVariableAdapter } from './adapter'; import { updateVariableOptions } from './reducer'; -import { - addVariableEditorError, - changeVariableEditorExtended, - initialVariableEditorState, - removeVariableEditorError, - setIdInEditor, -} from '../editor/reducer'; -import { LegacyVariableQueryEditor } from '../editor/LegacyVariableQueryEditor'; -import { expect } from 'test/lib/common'; -import { updateOptions } from '../state/actions'; -import { notifyApp } from '../../../core/reducers/appNotification'; -import { silenceConsoleOutput } from '../../../../test/core/utils/silenceConsoleOutput'; -import { getTimeSrv, setTimeSrv, TimeSrv } from '../../dashboard/services/TimeSrv'; -import { setVariableQueryRunner, VariableQueryRunner } from './VariableQueryRunner'; -import { setDataSourceSrv } from '@grafana/runtime'; -import { variablesInitTransaction } from '../state/transactionReducer'; -import { ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE } from '../constants'; -import { toKeyedAction } from '../state/keyedVariablesReducer'; -import { toKeyedVariableIdentifier, toVariablePayload } from '../utils'; const mocks: Record = { datasource: { diff --git a/public/app/features/variables/query/actions.ts b/public/app/features/variables/query/actions.ts index 45d42c5fec8..f2aca6b6e59 100644 --- a/public/app/features/variables/query/actions.ts +++ b/public/app/features/variables/query/actions.ts @@ -1,20 +1,22 @@ import { Subscription } from 'rxjs'; -import { getDataSourceSrv, toDataQueryError } from '@grafana/runtime'; -import { DataSourceRef } from '@grafana/data'; -import { updateOptions } from '../state/actions'; -import { QueryVariableModel } from '../types'; +import { DataSourceRef } from '@grafana/data'; +import { getDataSourceSrv, toDataQueryError } from '@grafana/runtime'; + import { ThunkResult } from '../../../types'; -import { getVariable, getVariablesState } from '../state/selectors'; +import { getVariableQueryEditor } from '../editor/getVariableQueryEditor'; import { addVariableEditorError, changeVariableEditorExtended, removeVariableEditorError } from '../editor/reducer'; +import { getQueryVariableEditorState } from '../editor/selectors'; +import { updateOptions } from '../state/actions'; +import { toKeyedAction } from '../state/keyedVariablesReducer'; +import { getVariable, getVariablesState } from '../state/selectors'; import { changeVariableProp } from '../state/sharedReducer'; import { KeyedVariableIdentifier } from '../state/types'; -import { getVariableQueryEditor } from '../editor/getVariableQueryEditor'; +import { QueryVariableModel } from '../types'; +import { hasOngoingTransaction, toKeyedVariableIdentifier, toVariablePayload } from '../utils'; + import { getVariableQueryRunner } from './VariableQueryRunner'; import { variableQueryObserver } from './variableQueryObserver'; -import { hasOngoingTransaction, toKeyedVariableIdentifier, toVariablePayload } from '../utils'; -import { toKeyedAction } from '../state/keyedVariablesReducer'; -import { getQueryVariableEditorState } from '../editor/selectors'; export const updateQueryVariableOptions = ( identifier: KeyedVariableIdentifier, diff --git a/public/app/features/variables/query/adapter.ts b/public/app/features/variables/query/adapter.ts index 06a2442ab69..6c4eb1f7563 100644 --- a/public/app/features/variables/query/adapter.ts +++ b/public/app/features/variables/query/adapter.ts @@ -1,15 +1,16 @@ import { cloneDeep } from 'lodash'; -import { QueryVariableModel, VariableRefresh } from '../types'; -import { initialQueryVariableModelState, queryVariableReducer } from './reducer'; import { dispatch } from '../../../store/store'; -import { setOptionAsCurrent, setOptionFromUrl } from '../state/actions'; import { VariableAdapter } from '../adapters'; +import { ALL_VARIABLE_TEXT } from '../constants'; +import { optionPickerFactory } from '../pickers'; +import { setOptionAsCurrent, setOptionFromUrl } from '../state/actions'; +import { QueryVariableModel, VariableRefresh } from '../types'; +import { containsVariable, isAllVariable, toKeyedVariableIdentifier } from '../utils'; + import { QueryVariableEditor } from './QueryVariableEditor'; import { updateQueryVariableOptions } from './actions'; -import { containsVariable, isAllVariable, toKeyedVariableIdentifier } from '../utils'; -import { optionPickerFactory } from '../pickers'; -import { ALL_VARIABLE_TEXT } from '../constants'; +import { initialQueryVariableModelState, queryVariableReducer } from './reducer'; export const createQueryVariableAdapter = (): VariableAdapter => { return { diff --git a/public/app/features/variables/query/operators.test.ts b/public/app/features/variables/query/operators.test.ts index ad3cdcce819..9f4fd29d987 100644 --- a/public/app/features/variables/query/operators.test.ts +++ b/public/app/features/variables/query/operators.test.ts @@ -1,10 +1,13 @@ import { of } from 'rxjs'; -import { queryBuilder } from '../shared/testing/builders'; + import { FieldType, toDataFrame } from '@grafana/data'; -import { updateVariableOptions } from './reducer'; -import { areMetricFindValues, toMetricFindValues, updateOptionsState, validateVariableSelection } from './operators'; + +import { queryBuilder } from '../shared/testing/builders'; import { toKeyedAction } from '../state/keyedVariablesReducer'; +import { areMetricFindValues, toMetricFindValues, updateOptionsState, validateVariableSelection } from './operators'; +import { updateVariableOptions } from './reducer'; + describe('operators', () => { beforeEach(() => { jest.clearAllMocks(); diff --git a/public/app/features/variables/query/operators.ts b/public/app/features/variables/query/operators.ts index 2085df4bd23..43df3bed00e 100644 --- a/public/app/features/variables/query/operators.ts +++ b/public/app/features/variables/query/operators.ts @@ -1,14 +1,16 @@ import { from, of, OperatorFunction } from 'rxjs'; import { map, mergeMap } from 'rxjs/operators'; -import { QueryVariableModel } from '../types'; +import { FieldType, getFieldDisplayName, isDataFrame, MetricFindValue, PanelData } from '@grafana/data'; +import { getProcessedDataFrames } from 'app/features/query/state/runRequest'; + import { ThunkDispatch } from '../../../types'; import { validateVariableSelectionState } from '../state/actions'; -import { FieldType, getFieldDisplayName, isDataFrame, MetricFindValue, PanelData } from '@grafana/data'; -import { updateVariableOptions } from './reducer'; -import { getTemplatedRegex, toKeyedVariableIdentifier, toVariablePayload } from '../utils'; -import { getProcessedDataFrames } from 'app/features/query/state/runRequest'; import { toKeyedAction } from '../state/keyedVariablesReducer'; +import { QueryVariableModel } from '../types'; +import { getTemplatedRegex, toKeyedVariableIdentifier, toVariablePayload } from '../utils'; + +import { updateVariableOptions } from './reducer'; export function toMetricFindValues(): OperatorFunction { return (source) => diff --git a/public/app/features/variables/query/queryRunners.test.ts b/public/app/features/variables/query/queryRunners.test.ts index 066defdd32a..8757209939e 100644 --- a/public/app/features/variables/query/queryRunners.test.ts +++ b/public/app/features/variables/query/queryRunners.test.ts @@ -1,8 +1,11 @@ -import { QueryRunners, variableDummyRefId } from './queryRunners'; -import { getDefaultTimeRange, VariableSupportType } from '@grafana/data'; -import { VariableRefresh } from '../types'; import { of } from 'rxjs'; +import { getDefaultTimeRange, VariableSupportType } from '@grafana/data'; + +import { VariableRefresh } from '../types'; + +import { QueryRunners, variableDummyRefId } from './queryRunners'; + describe('QueryRunners', () => { describe('when using a legacy data source', () => { const getLegacyTestContext = (variable?: any) => { diff --git a/public/app/features/variables/query/queryRunners.ts b/public/app/features/variables/query/queryRunners.ts index 38d7fa60c12..3229bff1eee 100644 --- a/public/app/features/variables/query/queryRunners.ts +++ b/public/app/features/variables/query/queryRunners.ts @@ -1,5 +1,6 @@ import { from, Observable, of } from 'rxjs'; import { mergeMap } from 'rxjs/operators'; + import { DataQuery, DataQueryRequest, @@ -10,15 +11,15 @@ import { VariableSupportType, } from '@grafana/data'; -import { QueryVariableModel } from '../types'; +import { TimeSrv } from '../../dashboard/services/TimeSrv'; import { hasCustomVariableSupport, hasDatasourceVariableSupport, hasLegacyVariableSupport, hasStandardVariableSupport, } from '../guard'; +import { QueryVariableModel } from '../types'; import { getLegacyQueryOptions } from '../utils'; -import { TimeSrv } from '../../dashboard/services/TimeSrv'; export interface RunnerArgs { variable: QueryVariableModel; diff --git a/public/app/features/variables/query/reducer.test.ts b/public/app/features/variables/query/reducer.test.ts index 106f8c50903..89643ff82da 100644 --- a/public/app/features/variables/query/reducer.test.ts +++ b/public/app/features/variables/query/reducer.test.ts @@ -1,18 +1,20 @@ import { cloneDeep } from 'lodash'; + import { MetricFindValue } from '@grafana/data'; import { reducerTester } from '../../../../test/core/redux/reducerTester'; +import { getVariableTestContext } from '../state/helpers'; +import { VariablesState } from '../state/types'; +import { QueryVariableModel, VariableSort } from '../types'; +import { toVariablePayload } from '../utils'; + +import { createQueryVariableAdapter } from './adapter'; import { metricNamesToVariableValues, queryVariableReducer, sortVariableValues, updateVariableOptions, } from './reducer'; -import { QueryVariableModel, VariableSort } from '../types'; -import { getVariableTestContext } from '../state/helpers'; -import { VariablesState } from '../state/types'; -import { createQueryVariableAdapter } from './adapter'; -import { toVariablePayload } from '../utils'; describe('queryVariableReducer', () => { const adapter = createQueryVariableAdapter(); diff --git a/public/app/features/variables/query/reducer.ts b/public/app/features/variables/query/reducer.ts index e4afc5c609d..91b895bf8c4 100644 --- a/public/app/features/variables/query/reducer.ts +++ b/public/app/features/variables/query/reducer.ts @@ -1,12 +1,12 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit'; import { isNumber, sortBy, toLower, uniqBy } from 'lodash'; + import { MetricFindValue, stringToJsRegex } from '@grafana/data'; -import { initialVariableModelState, QueryVariableModel, VariableOption, VariableRefresh, VariableSort } from '../types'; - -import { initialVariablesState, VariablePayload, VariablesState } from '../state/types'; import { ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE, NONE_VARIABLE_TEXT, NONE_VARIABLE_VALUE } from '../constants'; import { getInstanceState } from '../state/selectors'; +import { initialVariablesState, VariablePayload, VariablesState } from '../state/types'; +import { initialVariableModelState, QueryVariableModel, VariableOption, VariableRefresh, VariableSort } from '../types'; interface VariableOptionsUpdate { templatedRegex: string; diff --git a/public/app/features/variables/query/variableQueryObserver.test.ts b/public/app/features/variables/query/variableQueryObserver.test.ts index 8232e74df55..3730b39c725 100644 --- a/public/app/features/variables/query/variableQueryObserver.test.ts +++ b/public/app/features/variables/query/variableQueryObserver.test.ts @@ -1,7 +1,9 @@ -import { variableQueryObserver } from './variableQueryObserver'; import { LoadingState } from '@grafana/data'; + import { KeyedVariableIdentifier } from '../state/types'; + import { UpdateOptionsResults } from './VariableQueryRunner'; +import { variableQueryObserver } from './variableQueryObserver'; function getTestContext(args: { next?: UpdateOptionsResults; error?: any; complete?: boolean }) { const { next, error, complete } = args; diff --git a/public/app/features/variables/query/variableQueryObserver.ts b/public/app/features/variables/query/variableQueryObserver.ts index 9ad39a14f26..f6cddbb3059 100644 --- a/public/app/features/variables/query/variableQueryObserver.ts +++ b/public/app/features/variables/query/variableQueryObserver.ts @@ -1,4 +1,5 @@ import { Observer, Subscription } from 'rxjs'; + import { LoadingState } from '@grafana/data'; import { UpdateOptionsResults } from './VariableQueryRunner'; diff --git a/public/app/features/variables/shared/formatVariable.ts b/public/app/features/variables/shared/formatVariable.ts index 3cb47e741b2..34d798c68fa 100644 --- a/public/app/features/variables/shared/formatVariable.ts +++ b/public/app/features/variables/shared/formatVariable.ts @@ -1,4 +1,5 @@ import { VariableModel } from '@grafana/data'; + import { VariableWithOptions } from '../types'; export const formatVariableLabel = (variable: VariableModel) => { diff --git a/public/app/features/variables/shared/multiOptions.test.ts b/public/app/features/variables/shared/multiOptions.test.ts index 51d423067fe..f660088de10 100644 --- a/public/app/features/variables/shared/multiOptions.test.ts +++ b/public/app/features/variables/shared/multiOptions.test.ts @@ -1,4 +1,5 @@ import { VariableOption } from 'app/features/variables/types'; + import { alignCurrentWithMulti } from './multiOptions'; describe('alignCurrentWithMulti', () => { diff --git a/public/app/features/variables/shared/testing/adHocVariableBuilder.ts b/public/app/features/variables/shared/testing/adHocVariableBuilder.ts index 973e0fd62f8..724e3c19a60 100644 --- a/public/app/features/variables/shared/testing/adHocVariableBuilder.ts +++ b/public/app/features/variables/shared/testing/adHocVariableBuilder.ts @@ -1,5 +1,6 @@ import { DataSourceRef } from '@grafana/data'; import { AdHocVariableFilter, AdHocVariableModel } from 'app/features/variables/types'; + import { VariableBuilder } from './variableBuilder'; export class AdHocVariableBuilder extends VariableBuilder { diff --git a/public/app/features/variables/shared/testing/builders.ts b/public/app/features/variables/shared/testing/builders.ts index c2351663973..ed072e8ea53 100644 --- a/public/app/features/variables/shared/testing/builders.ts +++ b/public/app/features/variables/shared/testing/builders.ts @@ -1,15 +1,16 @@ -import { AdHocVariableBuilder } from './adHocVariableBuilder'; -import { IntervalVariableBuilder } from './intervalVariableBuilder'; -import { DatasourceVariableBuilder } from './datasourceVariableBuilder'; -import { OptionsVariableBuilder } from './optionsVariableBuilder'; -import { initialQueryVariableModelState } from '../../query/reducer'; import { initialAdHocVariableModelState } from '../../adhoc/reducer'; +import { initialConstantVariableModelState } from '../../constant/reducer'; +import { initialCustomVariableModelState } from '../../custom/reducer'; import { initialDataSourceVariableModelState } from '../../datasource/reducer'; import { initialIntervalVariableModelState } from '../../interval/reducer'; +import { initialQueryVariableModelState } from '../../query/reducer'; import { initialTextBoxVariableModelState } from '../../textbox/reducer'; -import { initialCustomVariableModelState } from '../../custom/reducer'; + +import { AdHocVariableBuilder } from './adHocVariableBuilder'; +import { DatasourceVariableBuilder } from './datasourceVariableBuilder'; +import { IntervalVariableBuilder } from './intervalVariableBuilder'; import { MultiVariableBuilder } from './multiVariableBuilder'; -import { initialConstantVariableModelState } from '../../constant/reducer'; +import { OptionsVariableBuilder } from './optionsVariableBuilder'; import { QueryVariableBuilder } from './queryVariableBuilder'; import { TextBoxVariableBuilder } from './textboxVariableBuilder'; diff --git a/public/app/features/variables/shared/testing/datasourceVariableBuilder.ts b/public/app/features/variables/shared/testing/datasourceVariableBuilder.ts index 39e58ea7e63..db4c9be4ed6 100644 --- a/public/app/features/variables/shared/testing/datasourceVariableBuilder.ts +++ b/public/app/features/variables/shared/testing/datasourceVariableBuilder.ts @@ -1,6 +1,7 @@ -import { MultiVariableBuilder } from './multiVariableBuilder'; import { DataSourceVariableModel, VariableRefresh } from 'app/features/variables/types'; +import { MultiVariableBuilder } from './multiVariableBuilder'; + export class DatasourceVariableBuilder extends MultiVariableBuilder { withRefresh(refresh: VariableRefresh) { this.variable.refresh = refresh; diff --git a/public/app/features/variables/shared/testing/intervalVariableBuilder.ts b/public/app/features/variables/shared/testing/intervalVariableBuilder.ts index fa6358acaa4..3979d194932 100644 --- a/public/app/features/variables/shared/testing/intervalVariableBuilder.ts +++ b/public/app/features/variables/shared/testing/intervalVariableBuilder.ts @@ -1,6 +1,7 @@ -import { OptionsVariableBuilder } from './optionsVariableBuilder'; import { IntervalVariableModel, VariableRefresh } from 'app/features/variables/types'; +import { OptionsVariableBuilder } from './optionsVariableBuilder'; + export class IntervalVariableBuilder extends OptionsVariableBuilder { withRefresh(refresh: VariableRefresh) { this.variable.refresh = refresh; diff --git a/public/app/features/variables/shared/testing/multiVariableBuilder.ts b/public/app/features/variables/shared/testing/multiVariableBuilder.ts index f4da7108051..3fb6309f381 100644 --- a/public/app/features/variables/shared/testing/multiVariableBuilder.ts +++ b/public/app/features/variables/shared/testing/multiVariableBuilder.ts @@ -1,4 +1,5 @@ import { VariableWithMultiSupport } from 'app/features/variables/types'; + import { OptionsVariableBuilder } from './optionsVariableBuilder'; export class MultiVariableBuilder extends OptionsVariableBuilder { diff --git a/public/app/features/variables/shared/testing/optionsVariableBuilder.ts b/public/app/features/variables/shared/testing/optionsVariableBuilder.ts index 271defad78e..18f2100e0b1 100644 --- a/public/app/features/variables/shared/testing/optionsVariableBuilder.ts +++ b/public/app/features/variables/shared/testing/optionsVariableBuilder.ts @@ -1,4 +1,5 @@ import { VariableOption, VariableWithOptions } from 'app/features/variables/types'; + import { VariableBuilder } from './variableBuilder'; export class OptionsVariableBuilder extends VariableBuilder { diff --git a/public/app/features/variables/shared/testing/queryVariableBuilder.ts b/public/app/features/variables/shared/testing/queryVariableBuilder.ts index fbfd4843f10..d7455324c97 100644 --- a/public/app/features/variables/shared/testing/queryVariableBuilder.ts +++ b/public/app/features/variables/shared/testing/queryVariableBuilder.ts @@ -1,6 +1,6 @@ import { DataSourceRef } from '@grafana/data'; - import { QueryVariableModel } from 'app/features/variables/types'; + import { DatasourceVariableBuilder } from './datasourceVariableBuilder'; export class QueryVariableBuilder extends DatasourceVariableBuilder { diff --git a/public/app/features/variables/shared/testing/textboxVariableBuilder.ts b/public/app/features/variables/shared/testing/textboxVariableBuilder.ts index 6170c7ee8f7..497e8741917 100644 --- a/public/app/features/variables/shared/testing/textboxVariableBuilder.ts +++ b/public/app/features/variables/shared/testing/textboxVariableBuilder.ts @@ -1,4 +1,5 @@ import { TextBoxVariableModel } from 'app/features/variables/types'; + import { OptionsVariableBuilder } from './optionsVariableBuilder'; export class TextBoxVariableBuilder extends OptionsVariableBuilder { diff --git a/public/app/features/variables/shared/testing/variableBuilder.ts b/public/app/features/variables/shared/testing/variableBuilder.ts index f966605787b..1b8cdaccfce 100644 --- a/public/app/features/variables/shared/testing/variableBuilder.ts +++ b/public/app/features/variables/shared/testing/variableBuilder.ts @@ -1,4 +1,5 @@ import { cloneDeep } from 'lodash'; + import { VariableModel } from 'app/features/variables/types'; export class VariableBuilder { diff --git a/public/app/features/variables/state/actions.test.ts b/public/app/features/variables/state/actions.test.ts index e73555705bf..89f5579348f 100644 --- a/public/app/features/variables/state/actions.test.ts +++ b/public/app/features/variables/state/actions.test.ts @@ -1,12 +1,36 @@ import { AnyAction } from 'redux'; -import { getPreloadedState, getTemplatingRootReducer, TemplatingReducerType } from './helpers'; -import { variableAdapters } from '../adapters'; -import { createQueryVariableAdapter } from '../query/adapter'; -import { createCustomVariableAdapter } from '../custom/adapter'; -import { createTextBoxVariableAdapter } from '../textbox/adapter'; -import { createConstantVariableAdapter } from '../constant/adapter'; +import { LoadingState } from '@grafana/data'; +import * as runtime from '@grafana/runtime'; + import { reduxTester } from '../../../../test/core/redux/reduxTester'; +import { toAsyncOfResult } from '../../query/state/DashboardQueryRunner/testHelpers'; +import { variableAdapters } from '../adapters'; +import { createConstantVariableAdapter } from '../constant/adapter'; +import { ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE, NEW_VARIABLE_ID } from '../constants'; +import { createCustomVariableAdapter } from '../custom/adapter'; +import { changeVariableName } from '../editor/actions'; +import { + changeVariableNameFailed, + changeVariableNameSucceeded, + cleanEditorState, + setIdInEditor, +} from '../editor/reducer'; +import { cleanPickerState } from '../pickers/OptionsPicker/reducer'; +import { setVariableQueryRunner, VariableQueryRunner } from '../query/VariableQueryRunner'; +import { createQueryVariableAdapter } from '../query/adapter'; +import { updateVariableOptions } from '../query/reducer'; +import { + constantBuilder, + customBuilder, + datasourceBuilder, + queryBuilder, + textboxBuilder, +} from '../shared/testing/builders'; +import { createTextBoxVariableAdapter } from '../textbox/adapter'; +import { ConstantVariableModel, VariableRefresh } from '../types'; +import { toKeyedVariableIdentifier, toVariablePayload } from '../utils'; + import { cancelVariables, changeVariableMultiValue, @@ -17,6 +41,8 @@ import { processVariables, validateVariableSelectionState, } from './actions'; +import { getPreloadedState, getTemplatingRootReducer, TemplatingReducerType } from './helpers'; +import { toKeyedAction } from './keyedVariablesReducer'; import { addVariable, changeVariableProp, @@ -26,32 +52,8 @@ import { variableStateFetching, variableStateNotStarted, } from './sharedReducer'; -import { - constantBuilder, - customBuilder, - datasourceBuilder, - queryBuilder, - textboxBuilder, -} from '../shared/testing/builders'; -import { changeVariableName } from '../editor/actions'; -import { - changeVariableNameFailed, - changeVariableNameSucceeded, - cleanEditorState, - setIdInEditor, -} from '../editor/reducer'; import { variablesClearTransaction, variablesInitTransaction } from './transactionReducer'; -import { cleanPickerState } from '../pickers/OptionsPicker/reducer'; import { cleanVariables } from './variablesReducer'; -import { ConstantVariableModel, VariableRefresh } from '../types'; -import { updateVariableOptions } from '../query/reducer'; -import { setVariableQueryRunner, VariableQueryRunner } from '../query/VariableQueryRunner'; -import * as runtime from '@grafana/runtime'; -import { LoadingState } from '@grafana/data'; -import { toAsyncOfResult } from '../../query/state/DashboardQueryRunner/testHelpers'; -import { ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE, NEW_VARIABLE_ID } from '../constants'; -import { toKeyedAction } from './keyedVariablesReducer'; -import { toKeyedVariableIdentifier, toVariablePayload } from '../utils'; variableAdapters.setInit(() => [ createQueryVariableAdapter(), diff --git a/public/app/features/variables/state/actions.ts b/public/app/features/variables/state/actions.ts index 6c064431173..5a31fc12e89 100644 --- a/public/app/features/variables/state/actions.ts +++ b/public/app/features/variables/state/actions.ts @@ -1,4 +1,5 @@ import { castArray, isEqual } from 'lodash'; + import { DataQuery, getDataSourceRef, @@ -8,7 +9,36 @@ import { UrlQueryMap, UrlQueryValue, } from '@grafana/data'; +import { locationService } from '@grafana/runtime'; +import { notifyApp } from 'app/core/actions'; +import { contextSrv } from 'app/core/services/context_srv'; +import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv'; +import { DashboardModel } from 'app/features/dashboard/state'; +import { store } from 'app/store/store'; +import { createErrorNotification } from '../../../core/copy/appNotification'; +import { appEvents } from '../../../core/core'; +import { getBackendSrv } from '../../../core/services/backend_srv'; +import { Graph } from '../../../core/utils/dag'; +import { AppNotification, StoreState, ThunkResult } from '../../../types'; +import { getDatasourceSrv } from '../../plugins/datasource_srv'; +import { getTemplateSrv, TemplateSrv } from '../../templating/template_srv'; +import { variableAdapters } from '../adapters'; +import { ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE } from '../constants'; +import { cleanEditorState } from '../editor/reducer'; +import { + hasCurrent, + hasLegacyVariableSupport, + hasOptions, + hasStandardVariableSupport, + isAdHoc, + isConstant, + isMulti, + isQuery, +} from '../guard'; +import { getAllAffectedPanelIdsForVariableChange } from '../inspect/utils'; +import { cleanPickerState } from '../pickers/OptionsPicker/reducer'; +import { alignCurrentWithMulti } from '../shared/multiOptions'; import { DashboardVariableModel, initialVariableModelState, @@ -27,44 +57,6 @@ import { VariableWithMultiSupport, VariableWithOptions, } from '../types'; -import { AppNotification, StoreState, ThunkResult } from '../../../types'; -import { getIfExistsLastKey, getVariable, getVariablesByKey, getVariablesState } from './selectors'; -import { variableAdapters } from '../adapters'; -import { Graph } from '../../../core/utils/dag'; -import { notifyApp } from 'app/core/actions'; -import { - addVariable, - changeVariableProp, - setCurrentVariableValue, - variableStateCompleted, - variableStateFailed, - variableStateFetching, - variableStateNotStarted, -} from './sharedReducer'; -import { KeyedVariableIdentifier } from './types'; -import { contextSrv } from 'app/core/services/context_srv'; -import { getTemplateSrv, TemplateSrv } from '../../templating/template_srv'; -import { alignCurrentWithMulti } from '../shared/multiOptions'; -import { - hasCurrent, - hasLegacyVariableSupport, - hasOptions, - hasStandardVariableSupport, - isAdHoc, - isConstant, - isMulti, - isQuery, -} from '../guard'; -import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv'; -import { DashboardModel } from 'app/features/dashboard/state'; -import { createErrorNotification } from '../../../core/copy/appNotification'; -import { - variablesClearTransaction, - variablesCompleteTransaction, - variablesInitTransaction, -} from './transactionReducer'; -import { getBackendSrv } from '../../../core/services/backend_srv'; -import { cleanVariables } from './variablesReducer'; import { ensureStringValues, ExtendedUrlQueryMap, @@ -75,15 +67,25 @@ import { toStateKey, toVariablePayload, } from '../utils'; -import { store } from 'app/store/store'; -import { getDatasourceSrv } from '../../plugins/datasource_srv'; -import { cleanEditorState } from '../editor/reducer'; -import { cleanPickerState } from '../pickers/OptionsPicker/reducer'; -import { locationService } from '@grafana/runtime'; -import { appEvents } from '../../../core/core'; -import { getAllAffectedPanelIdsForVariableChange } from '../inspect/utils'; -import { ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE } from '../constants'; + import { toKeyedAction } from './keyedVariablesReducer'; +import { getIfExistsLastKey, getVariable, getVariablesByKey, getVariablesState } from './selectors'; +import { + addVariable, + changeVariableProp, + setCurrentVariableValue, + variableStateCompleted, + variableStateFailed, + variableStateFetching, + variableStateNotStarted, +} from './sharedReducer'; +import { + variablesClearTransaction, + variablesCompleteTransaction, + variablesInitTransaction, +} from './transactionReducer'; +import { KeyedVariableIdentifier } from './types'; +import { cleanVariables } from './variablesReducer'; // process flow queryVariable // thunk => processVariables diff --git a/public/app/features/variables/state/helpers.ts b/public/app/features/variables/state/helpers.ts index 5ea13a64fd9..70db7abdeb3 100644 --- a/public/app/features/variables/state/helpers.ts +++ b/public/app/features/variables/state/helpers.ts @@ -1,7 +1,11 @@ import { combineReducers } from '@reduxjs/toolkit'; -import { LoadingState } from '@grafana/data'; -import { VariablesState } from './types'; +import { LoadingState } from '@grafana/data'; +import { dashboardReducer } from 'app/features/dashboard/state/reducers'; + +import { DashboardState, StoreState } from '../../../types'; +import { VariableAdapter } from '../adapters'; +import { NEW_VARIABLE_ID } from '../constants'; import { DashboardVariableModel, initialVariableModelState, @@ -11,12 +15,9 @@ import { VariableModel, } from '../types'; -import { VariableAdapter } from '../adapters'; -import { dashboardReducer } from 'app/features/dashboard/state/reducers'; -import { DashboardState, StoreState } from '../../../types'; -import { NEW_VARIABLE_ID } from '../constants'; import { keyedVariablesReducer, KeyedVariablesState } from './keyedVariablesReducer'; import { getInitialTemplatingState, TemplatingState } from './reducers'; +import { VariablesState } from './types'; export const getVariableState = ( noOfVariables: number, diff --git a/public/app/features/variables/state/initVariableTransaction.test.ts b/public/app/features/variables/state/initVariableTransaction.test.ts index 592d46cc68a..c8830f3674e 100644 --- a/public/app/features/variables/state/initVariableTransaction.test.ts +++ b/public/app/features/variables/state/initVariableTransaction.test.ts @@ -1,8 +1,24 @@ -import { getPreloadedState, getRootReducer, RootReducerType } from './helpers'; -import { variableAdapters } from '../adapters'; -import { createQueryVariableAdapter } from '../query/adapter'; -import { createConstantVariableAdapter } from '../constant/adapter'; +import { DataSourceRef, LoadingState } from '@grafana/data/src'; +import { setDataSourceSrv } from '@grafana/runtime/src'; + import { reduxTester } from '../../../../test/core/redux/reduxTester'; +import { toAsyncOfResult } from '../../query/state/DashboardQueryRunner/testHelpers'; +import { variableAdapters } from '../adapters'; +import { createAdHocVariableAdapter } from '../adhoc/adapter'; +import { createConstantVariableAdapter } from '../constant/adapter'; +import { createDataSourceVariableAdapter } from '../datasource/adapter'; +import { createDataSourceOptions } from '../datasource/reducer'; +import { cleanEditorState } from '../editor/reducer'; +import { cleanPickerState } from '../pickers/OptionsPicker/reducer'; +import { setVariableQueryRunner } from '../query/VariableQueryRunner'; +import { createQueryVariableAdapter } from '../query/adapter'; +import { adHocBuilder, constantBuilder, datasourceBuilder, queryBuilder } from '../shared/testing/builders'; +import { TransactionStatus, VariableModel } from '../types'; +import { toVariablePayload } from '../utils'; + +import { initVariablesTransaction } from './actions'; +import { getPreloadedState, getRootReducer, RootReducerType } from './helpers'; +import { toKeyedAction } from './keyedVariablesReducer'; import { addVariable, changeVariableProp, @@ -11,27 +27,13 @@ import { variableStateFetching, variableStateNotStarted, } from './sharedReducer'; -import { adHocBuilder, constantBuilder, datasourceBuilder, queryBuilder } from '../shared/testing/builders'; -import { cleanEditorState } from '../editor/reducer'; import { initialTransactionState, variablesClearTransaction, variablesCompleteTransaction, variablesInitTransaction, } from './transactionReducer'; -import { cleanPickerState } from '../pickers/OptionsPicker/reducer'; import { cleanVariables } from './variablesReducer'; -import { createAdHocVariableAdapter } from '../adhoc/adapter'; -import { createDataSourceVariableAdapter } from '../datasource/adapter'; -import { DataSourceRef, LoadingState } from '@grafana/data/src'; -import { setDataSourceSrv } from '@grafana/runtime/src'; -import { TransactionStatus, VariableModel } from '../types'; -import { toAsyncOfResult } from '../../query/state/DashboardQueryRunner/testHelpers'; -import { setVariableQueryRunner } from '../query/VariableQueryRunner'; -import { createDataSourceOptions } from '../datasource/reducer'; -import { initVariablesTransaction } from './actions'; -import { toKeyedAction } from './keyedVariablesReducer'; -import { toVariablePayload } from '../utils'; variableAdapters.setInit(() => [ createQueryVariableAdapter(), diff --git a/public/app/features/variables/state/keyedVariablesReducer.test.ts b/public/app/features/variables/state/keyedVariablesReducer.test.ts index 4a4dfa346f5..9d6e99a2168 100644 --- a/public/app/features/variables/state/keyedVariablesReducer.test.ts +++ b/public/app/features/variables/state/keyedVariablesReducer.test.ts @@ -1,13 +1,14 @@ +import { reducerTester } from '../../../../test/core/redux/reducerTester'; +import { TransactionStatus } from '../types'; + import { initialKeyedVariablesState, keyedVariablesReducer, KeyedVariablesState, toKeyedAction, } from './keyedVariablesReducer'; -import { reducerTester } from '../../../../test/core/redux/reducerTester'; -import { initialTransactionState, variablesCompleteTransaction, variablesInitTransaction } from './transactionReducer'; -import { TransactionStatus } from '../types'; import { getInitialTemplatingState } from './reducers'; +import { initialTransactionState, variablesCompleteTransaction, variablesInitTransaction } from './transactionReducer'; describe('dashboardVariablesReducer', () => { describe('when an toUidAction is dispatched', () => { diff --git a/public/app/features/variables/state/keyedVariablesReducer.ts b/public/app/features/variables/state/keyedVariablesReducer.ts index 56f4aee6b82..54f09d50d8d 100644 --- a/public/app/features/variables/state/keyedVariablesReducer.ts +++ b/public/app/features/variables/state/keyedVariablesReducer.ts @@ -1,8 +1,10 @@ -import { AnyAction } from 'redux'; import { PayloadAction } from '@reduxjs/toolkit'; +import { AnyAction } from 'redux'; + +import { toStateKey } from '../utils'; + import { getTemplatingReducers, TemplatingState } from './reducers'; import { variablesInitTransaction } from './transactionReducer'; -import { toStateKey } from '../utils'; export interface KeyedVariablesState { lastKey?: string; diff --git a/public/app/features/variables/state/migrateVariablesDatasourceNameToRef.test.ts b/public/app/features/variables/state/migrateVariablesDatasourceNameToRef.test.ts index 65cf7a33559..aea1a31a10b 100644 --- a/public/app/features/variables/state/migrateVariablesDatasourceNameToRef.test.ts +++ b/public/app/features/variables/state/migrateVariablesDatasourceNameToRef.test.ts @@ -1,11 +1,13 @@ -import { migrateVariablesDatasourceNameToRef } from './actions'; -import { adHocBuilder, queryBuilder } from '../shared/testing/builders'; import { DataSourceRef } from '@grafana/data/src'; -import { changeVariableProp } from './sharedReducer'; -import { toKeyedAction } from './keyedVariablesReducer'; -import { getPreloadedState } from './helpers'; + +import { adHocBuilder, queryBuilder } from '../shared/testing/builders'; import { toVariablePayload } from '../utils'; +import { migrateVariablesDatasourceNameToRef } from './actions'; +import { getPreloadedState } from './helpers'; +import { toKeyedAction } from './keyedVariablesReducer'; +import { changeVariableProp } from './sharedReducer'; + function getTestContext(ds: DataSourceRef, dsInstance?: { uid: string; type: string }) { jest.clearAllMocks(); const key = 'key'; diff --git a/public/app/features/variables/state/onTimeRangeUpdated.test.ts b/public/app/features/variables/state/onTimeRangeUpdated.test.ts index 388916def33..774467c69b0 100644 --- a/public/app/features/variables/state/onTimeRangeUpdated.test.ts +++ b/public/app/features/variables/state/onTimeRangeUpdated.test.ts @@ -1,30 +1,31 @@ import { dateTime, TimeRange } from '@grafana/data'; -import { TemplateSrv } from '../../templating/template_srv'; -import { onTimeRangeUpdated, OnTimeRangeUpdatedDependencies, setOptionAsCurrent } from './actions'; -import { DashboardModel } from '../../dashboard/state'; +import { reduxTester } from '../../../../test/core/redux/reduxTester'; +import { silenceConsoleOutput } from '../../../../test/core/utils/silenceConsoleOutput'; +import { expect } from '../../../../test/lib/common'; +import { appEvents } from '../../../core/core'; +import { notifyApp } from '../../../core/reducers/appNotification'; import { DashboardState } from '../../../types'; -import { createIntervalVariableAdapter } from '../interval/adapter'; +import { DashboardModel } from '../../dashboard/state'; +import { TemplateSrv } from '../../templating/template_srv'; import { variableAdapters } from '../adapters'; import { createConstantVariableAdapter } from '../constant/adapter'; -import { VariableRefresh } from '../types'; +import { createIntervalVariableAdapter } from '../interval/adapter'; +import { createIntervalOptions } from '../interval/reducer'; import { constantBuilder, intervalBuilder } from '../shared/testing/builders'; -import { reduxTester } from '../../../../test/core/redux/reduxTester'; +import { VariableRefresh } from '../types'; +import { toKeyedVariableIdentifier, toVariablePayload } from '../utils'; + +import { onTimeRangeUpdated, OnTimeRangeUpdatedDependencies, setOptionAsCurrent } from './actions'; import { getPreloadedState, getRootReducer, RootReducerType } from './helpers'; +import { toKeyedAction } from './keyedVariablesReducer'; import { setCurrentVariableValue, variableStateCompleted, variableStateFailed, variableStateFetching, } from './sharedReducer'; -import { createIntervalOptions } from '../interval/reducer'; -import { silenceConsoleOutput } from '../../../../test/core/utils/silenceConsoleOutput'; -import { notifyApp } from '../../../core/reducers/appNotification'; -import { expect } from '../../../../test/lib/common'; -import { appEvents } from '../../../core/core'; import { variablesInitTransaction } from './transactionReducer'; -import { toKeyedAction } from './keyedVariablesReducer'; -import { toKeyedVariableIdentifier, toVariablePayload } from '../utils'; variableAdapters.setInit(() => [createIntervalVariableAdapter(), createConstantVariableAdapter()]); diff --git a/public/app/features/variables/state/processVariable.test.ts b/public/app/features/variables/state/processVariable.test.ts index d05cfe193fe..391461adab2 100644 --- a/public/app/features/variables/state/processVariable.test.ts +++ b/public/app/features/variables/state/processVariable.test.ts @@ -1,21 +1,22 @@ import { UrlQueryMap } from '@grafana/data'; +import { setDataSourceSrv } from '@grafana/runtime'; -import { getTemplatingRootReducer, TemplatingReducerType } from './helpers'; -import { variableAdapters } from '../adapters'; -import { createQueryVariableAdapter } from '../query/adapter'; -import { createCustomVariableAdapter } from '../custom/adapter'; import { reduxTester } from '../../../../test/core/redux/reduxTester'; -import { initDashboardTemplating, processVariable } from './actions'; -import { setCurrentVariableValue, variableStateCompleted, variableStateFetching } from './sharedReducer'; -import { VariableRefresh } from '../types'; +import { variableAdapters } from '../adapters'; +import { createCustomVariableAdapter } from '../custom/adapter'; +import { setVariableQueryRunner, VariableQueryRunner } from '../query/VariableQueryRunner'; +import { createQueryVariableAdapter } from '../query/adapter'; import { updateVariableOptions } from '../query/reducer'; import { customBuilder, queryBuilder } from '../shared/testing/builders'; -import { variablesInitTransaction } from './transactionReducer'; -import { setVariableQueryRunner, VariableQueryRunner } from '../query/VariableQueryRunner'; -import { setDataSourceSrv } from '@grafana/runtime'; -import { toKeyedAction } from './keyedVariablesReducer'; +import { VariableRefresh } from '../types'; import { toKeyedVariableIdentifier, toVariablePayload } from '../utils'; +import { initDashboardTemplating, processVariable } from './actions'; +import { getTemplatingRootReducer, TemplatingReducerType } from './helpers'; +import { toKeyedAction } from './keyedVariablesReducer'; +import { setCurrentVariableValue, variableStateCompleted, variableStateFetching } from './sharedReducer'; +import { variablesInitTransaction } from './transactionReducer'; + jest.mock('app/features/dashboard/services/TimeSrv', () => ({ getTimeSrv: jest.fn().mockReturnValue({ timeRange: jest.fn().mockReturnValue({ diff --git a/public/app/features/variables/state/reducers.test.ts b/public/app/features/variables/state/reducers.test.ts index 3e156e2236a..fdf61d8cbab 100644 --- a/public/app/features/variables/state/reducers.test.ts +++ b/public/app/features/variables/state/reducers.test.ts @@ -1,13 +1,15 @@ import { createAction } from '@reduxjs/toolkit'; + import { VariableType } from '@grafana/data'; import { reducerTester } from '../../../../test/core/redux/reducerTester'; -import { initialVariableModelState, QueryVariableModel } from '../types'; import { VariableAdapter, variableAdapters } from '../adapters'; -import { cleanVariables, variablesReducer } from './variablesReducer'; -import { VariablePayload, VariablesState } from './types'; +import { initialVariableModelState, QueryVariableModel } from '../types'; import { toVariablePayload } from '../utils'; +import { VariablePayload, VariablesState } from './types'; +import { cleanVariables, variablesReducer } from './variablesReducer'; + const variableAdapter: VariableAdapter = { id: 'mock' as unknown as VariableType, name: 'Mock label', diff --git a/public/app/features/variables/state/reducers.ts b/public/app/features/variables/state/reducers.ts index 7cc63679118..64eb75f45a2 100644 --- a/public/app/features/variables/state/reducers.ts +++ b/public/app/features/variables/state/reducers.ts @@ -1,10 +1,12 @@ import { CombinedState, combineReducers, Reducer } from 'redux'; -import { initialOptionPickerState, optionsPickerReducer, OptionsPickerState } from '../pickers/OptionsPicker/reducer'; + import { initialVariableEditorState, variableEditorReducer, VariableEditorState } from '../editor/reducer'; -import { variablesReducer } from './variablesReducer'; -import { initialTransactionState, transactionReducer, TransactionState } from './transactionReducer'; import { initialVariableInspectState, variableInspectReducer, VariableInspectState } from '../inspect/reducer'; +import { initialOptionPickerState, optionsPickerReducer, OptionsPickerState } from '../pickers/OptionsPicker/reducer'; + +import { initialTransactionState, transactionReducer, TransactionState } from './transactionReducer'; import { initialVariablesState, VariablesState } from './types'; +import { variablesReducer } from './variablesReducer'; export interface TemplatingState { editor: VariableEditorState; diff --git a/public/app/features/variables/state/selectors.ts b/public/app/features/variables/state/selectors.ts index 685b0b9b51d..301b2341ea4 100644 --- a/public/app/features/variables/state/selectors.ts +++ b/public/app/features/variables/state/selectors.ts @@ -1,9 +1,11 @@ +import memoizeOne from 'memoize-one'; + +import { getState } from '../../../store/store'; import { StoreState } from '../../../types'; import { VariableModel } from '../types'; -import { getState } from '../../../store/store'; -import memoizeOne from 'memoize-one'; -import { getInitialTemplatingState, TemplatingState } from './reducers'; import { toStateKey } from '../utils'; + +import { getInitialTemplatingState, TemplatingState } from './reducers'; import { KeyedVariableIdentifier, VariablesState } from './types'; export const getVariable = ( diff --git a/public/app/features/variables/state/setOptionFromUrl.test.ts b/public/app/features/variables/state/setOptionFromUrl.test.ts index 5128deefe8a..8e5b5476e1f 100644 --- a/public/app/features/variables/state/setOptionFromUrl.test.ts +++ b/public/app/features/variables/state/setOptionFromUrl.test.ts @@ -1,14 +1,15 @@ +import { reduxTester } from '../../../../test/core/redux/reduxTester'; import { variableAdapters } from '../adapters'; +import { ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE } from '../constants'; import { createCustomVariableAdapter } from '../custom/adapter'; import { customBuilder } from '../shared/testing/builders'; -import { reduxTester } from '../../../../test/core/redux/reduxTester'; -import { getTemplatingRootReducer, TemplatingReducerType } from './helpers'; -import { addVariable, setCurrentVariableValue } from './sharedReducer'; -import { setOptionFromUrl } from './actions'; -import { ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE } from '../constants'; -import { toKeyedAction } from './keyedVariablesReducer'; import { toKeyedVariableIdentifier, toVariablePayload } from '../utils'; +import { setOptionFromUrl } from './actions'; +import { getTemplatingRootReducer, TemplatingReducerType } from './helpers'; +import { toKeyedAction } from './keyedVariablesReducer'; +import { addVariable, setCurrentVariableValue } from './sharedReducer'; + variableAdapters.setInit(() => [createCustomVariableAdapter()]); describe('when setOptionFromUrl is dispatched with a custom variable (no refresh property)', () => { diff --git a/public/app/features/variables/state/sharedReducer.test.ts b/public/app/features/variables/state/sharedReducer.test.ts index ec1b2deb01b..5e6e10d2811 100644 --- a/public/app/features/variables/state/sharedReducer.test.ts +++ b/public/app/features/variables/state/sharedReducer.test.ts @@ -1,7 +1,19 @@ import { cloneDeep } from 'lodash'; + import { LoadingState, VariableType } from '@grafana/data'; import { reducerTester } from '../../../../test/core/redux/reducerTester'; +import { variableAdapters } from '../adapters'; +import { createConstantVariableAdapter } from '../constant/adapter'; +import { initialConstantVariableModelState } from '../constant/reducer'; +import { ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE } from '../constants'; +import { changeVariableNameSucceeded } from '../editor/reducer'; +import { createQueryVariableAdapter } from '../query/adapter'; +import { initialQueryVariableModelState } from '../query/reducer'; +import { ConstantVariableModel, QueryVariableModel, VariableHide, VariableOption } from '../types'; +import { toVariablePayload } from '../utils'; + +import { getVariableState, getVariableTestContext } from './helpers'; import { addVariable, changeVariableOrder, @@ -16,17 +28,7 @@ import { variableStateFetching, variableStateNotStarted, } from './sharedReducer'; -import { ConstantVariableModel, QueryVariableModel, VariableHide, VariableOption } from '../types'; import { initialVariablesState, KeyedVariableIdentifier, VariablesState } from './types'; -import { variableAdapters } from '../adapters'; -import { createQueryVariableAdapter } from '../query/adapter'; -import { initialQueryVariableModelState } from '../query/reducer'; -import { getVariableState, getVariableTestContext } from './helpers'; -import { changeVariableNameSucceeded } from '../editor/reducer'; -import { createConstantVariableAdapter } from '../constant/adapter'; -import { initialConstantVariableModelState } from '../constant/reducer'; -import { ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE } from '../constants'; -import { toVariablePayload } from '../utils'; variableAdapters.setInit(() => [createQueryVariableAdapter(), createConstantVariableAdapter()]); diff --git a/public/app/features/variables/state/sharedReducer.ts b/public/app/features/variables/state/sharedReducer.ts index 7b5e4ecb6ce..53c29487412 100644 --- a/public/app/features/variables/state/sharedReducer.ts +++ b/public/app/features/variables/state/sharedReducer.ts @@ -1,12 +1,15 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit'; import { cloneDeep, defaults as lodashDefaults } from 'lodash'; + import { LoadingState, VariableType } from '@grafana/data'; -import { VariableModel, VariableOption, VariableWithOptions } from '../types'; -import { AddVariable, initialVariablesState, VariablePayload, VariablesState } from './types'; + import { variableAdapters } from '../adapters'; import { changeVariableNameSucceeded } from '../editor/reducer'; +import { VariableModel, VariableOption, VariableWithOptions } from '../types'; import { ensureStringValues } from '../utils'; + import { getInstanceState, getNextVariableIndex } from './selectors'; +import { AddVariable, initialVariablesState, VariablePayload, VariablesState } from './types'; const sharedReducerSlice = createSlice({ name: 'templating/shared', diff --git a/public/app/features/variables/state/templateVarsChangedInUrl.test.ts b/public/app/features/variables/state/templateVarsChangedInUrl.test.ts index 7163f2c9bf0..d50ad5d8dcd 100644 --- a/public/app/features/variables/state/templateVarsChangedInUrl.test.ts +++ b/public/app/features/variables/state/templateVarsChangedInUrl.test.ts @@ -1,15 +1,16 @@ -import { variableAdapters } from '../adapters'; -import { constantBuilder, customBuilder } from '../shared/testing/builders'; import { DashboardState, StoreState } from '../../../types'; -import { initialState } from '../../dashboard/state/reducers'; -import { ExtendedUrlQueryMap } from '../utils'; -import { templateVarsChangedInUrl } from './actions'; -import { createCustomVariableAdapter } from '../custom/adapter'; -import { VariablesState } from './types'; import { DashboardModel } from '../../dashboard/state'; -import { getPreloadedState } from './helpers'; +import { initialState } from '../../dashboard/state/reducers'; +import { variableAdapters } from '../adapters'; import { createConstantVariableAdapter } from '../constant/adapter'; +import { createCustomVariableAdapter } from '../custom/adapter'; +import { constantBuilder, customBuilder } from '../shared/testing/builders'; import { VariableModel } from '../types'; +import { ExtendedUrlQueryMap } from '../utils'; + +import { templateVarsChangedInUrl } from './actions'; +import { getPreloadedState } from './helpers'; +import { VariablesState } from './types'; const dashboardModel = new DashboardModel({}); diff --git a/public/app/features/variables/state/transactionReducer.test.ts b/public/app/features/variables/state/transactionReducer.test.ts index 4772f55e48f..c769c10636a 100644 --- a/public/app/features/variables/state/transactionReducer.test.ts +++ b/public/app/features/variables/state/transactionReducer.test.ts @@ -1,4 +1,6 @@ import { reducerTester } from '../../../../test/core/redux/reducerTester'; +import { TransactionStatus } from '../types'; + import { removeVariable, variableStateNotStarted } from './sharedReducer'; import { initialTransactionState, @@ -8,7 +10,6 @@ import { variablesCompleteTransaction, variablesInitTransaction, } from './transactionReducer'; -import { TransactionStatus } from '../types'; describe('transactionReducer', () => { describe('when variablesInitTransaction is dispatched', () => { diff --git a/public/app/features/variables/state/transactionReducer.ts b/public/app/features/variables/state/transactionReducer.ts index 05d4a1c6cdf..0bce8898aba 100644 --- a/public/app/features/variables/state/transactionReducer.ts +++ b/public/app/features/variables/state/transactionReducer.ts @@ -1,4 +1,7 @@ import { AnyAction, createSlice, PayloadAction } from '@reduxjs/toolkit'; + +import { TransactionStatus } from '../types'; + import { addVariable, changeVariableOrder, @@ -7,7 +10,6 @@ import { duplicateVariable, removeVariable, } from './sharedReducer'; -import { TransactionStatus } from '../types'; export interface TransactionState { uid: string | undefined | null; diff --git a/public/app/features/variables/state/upgradeLegacyQueries.test.ts b/public/app/features/variables/state/upgradeLegacyQueries.test.ts index d3f68d6e90d..bc4281ca926 100644 --- a/public/app/features/variables/state/upgradeLegacyQueries.test.ts +++ b/public/app/features/variables/state/upgradeLegacyQueries.test.ts @@ -1,13 +1,15 @@ -import { customBuilder, queryBuilder } from '../shared/testing/builders'; import { VariableSupportType } from '@grafana/data'; -import { upgradeLegacyQueries } from './actions'; -import { changeVariableProp } from './sharedReducer'; + import { thunkTester } from '../../../../test/core/thunk/thunkTester'; +import { customBuilder, queryBuilder } from '../shared/testing/builders'; import { TransactionStatus, VariableModel } from '../types'; -import { toKeyedAction } from './keyedVariablesReducer'; -import { getPreloadedState } from './helpers'; import { toKeyedVariableIdentifier } from '../utils'; +import { upgradeLegacyQueries } from './actions'; +import { getPreloadedState } from './helpers'; +import { toKeyedAction } from './keyedVariablesReducer'; +import { changeVariableProp } from './sharedReducer'; + interface Args { query?: any; variable?: VariableModel; diff --git a/public/app/features/variables/state/variablesReducer.ts b/public/app/features/variables/state/variablesReducer.ts index 3319196dd64..222fa558da1 100644 --- a/public/app/features/variables/state/variablesReducer.ts +++ b/public/app/features/variables/state/variablesReducer.ts @@ -1,8 +1,10 @@ import { createAction } from '@reduxjs/toolkit'; -import { variableAdapters } from '../adapters'; -import { sharedReducer } from './sharedReducer'; -import { VariableModel } from '../types'; import { AnyAction } from 'redux'; + +import { variableAdapters } from '../adapters'; +import { VariableModel } from '../types'; + +import { sharedReducer } from './sharedReducer'; import { initialVariablesState, VariablesState } from './types'; export const cleanVariables = createAction('templating/cleanVariables'); diff --git a/public/app/features/variables/system/adapter.ts b/public/app/features/variables/system/adapter.ts index 40f1e91d8e0..82b8c277da5 100644 --- a/public/app/features/variables/system/adapter.ts +++ b/public/app/features/variables/system/adapter.ts @@ -1,10 +1,11 @@ import { ComponentType } from 'react'; + import { LoadingState } from '@grafana/data'; -import { initialVariableModelState, SystemVariable, VariableHide } from '../types'; import { VariableAdapter } from '../adapters'; -import { VariablePickerProps } from '../pickers/types'; import { VariableEditorProps } from '../editor/types'; +import { VariablePickerProps } from '../pickers/types'; +import { initialVariableModelState, SystemVariable, VariableHide } from '../types'; export const createSystemVariableAdapter = (): VariableAdapter> => { return { diff --git a/public/app/features/variables/textbox/TextBoxVariableEditor.tsx b/public/app/features/variables/textbox/TextBoxVariableEditor.tsx index cb13f732018..119291d63a9 100644 --- a/public/app/features/variables/textbox/TextBoxVariableEditor.tsx +++ b/public/app/features/variables/textbox/TextBoxVariableEditor.tsx @@ -1,11 +1,12 @@ import React, { FormEvent, ReactElement, useCallback } from 'react'; + +import { selectors } from '@grafana/e2e-selectors'; import { VerticalGroup } from '@grafana/ui'; -import { TextBoxVariableModel } from '../types'; -import { VariableEditorProps } from '../editor/types'; import { VariableSectionHeader } from '../editor/VariableSectionHeader'; import { VariableTextField } from '../editor/VariableTextField'; -import { selectors } from '@grafana/e2e-selectors'; +import { VariableEditorProps } from '../editor/types'; +import { TextBoxVariableModel } from '../types'; export interface Props extends VariableEditorProps {} diff --git a/public/app/features/variables/textbox/TextBoxVariablePicker.tsx b/public/app/features/variables/textbox/TextBoxVariablePicker.tsx index 7ad4152683d..14d9251d9a7 100644 --- a/public/app/features/variables/textbox/TextBoxVariablePicker.tsx +++ b/public/app/features/variables/textbox/TextBoxVariablePicker.tsx @@ -1,12 +1,13 @@ import React, { ChangeEvent, FocusEvent, KeyboardEvent, ReactElement, useCallback, useEffect, useState } from 'react'; - -import { TextBoxVariableModel } from '../types'; -import { changeVariableProp } from '../state/sharedReducer'; -import { VariablePickerProps } from '../pickers/types'; -import { Input } from '@grafana/ui'; -import { variableAdapters } from '../adapters'; import { useDispatch } from 'react-redux'; + +import { Input } from '@grafana/ui'; + +import { variableAdapters } from '../adapters'; +import { VariablePickerProps } from '../pickers/types'; import { toKeyedAction } from '../state/keyedVariablesReducer'; +import { changeVariableProp } from '../state/sharedReducer'; +import { TextBoxVariableModel } from '../types'; import { toVariablePayload } from '../utils'; export interface Props extends VariablePickerProps {} diff --git a/public/app/features/variables/textbox/actions.test.ts b/public/app/features/variables/textbox/actions.test.ts index 4c38b863523..117e41a5cb5 100644 --- a/public/app/features/variables/textbox/actions.test.ts +++ b/public/app/features/variables/textbox/actions.test.ts @@ -1,16 +1,18 @@ -import { variableAdapters } from '../adapters'; -import { createTextBoxVariableAdapter } from './adapter'; -import { reduxTester } from '../../../../test/core/redux/reduxTester'; -import { setTextBoxVariableOptionsFromUrl, updateTextBoxVariableOptions } from './actions'; -import { getRootReducer, RootReducerType } from '../state/helpers'; -import { VariableOption } from '../types'; -import { createTextBoxOptions } from './reducer'; -import { addVariable, changeVariableProp, setCurrentVariableValue } from '../state/sharedReducer'; -import { textboxBuilder } from '../shared/testing/builders'; import { locationService } from '@grafana/runtime'; + +import { reduxTester } from '../../../../test/core/redux/reduxTester'; +import { variableAdapters } from '../adapters'; +import { textboxBuilder } from '../shared/testing/builders'; +import { getRootReducer, RootReducerType } from '../state/helpers'; import { toKeyedAction } from '../state/keyedVariablesReducer'; +import { addVariable, changeVariableProp, setCurrentVariableValue } from '../state/sharedReducer'; +import { VariableOption } from '../types'; import { toKeyedVariableIdentifier, toVariablePayload } from '../utils'; +import { setTextBoxVariableOptionsFromUrl, updateTextBoxVariableOptions } from './actions'; +import { createTextBoxVariableAdapter } from './adapter'; +import { createTextBoxOptions } from './reducer'; + jest.mock('@grafana/runtime', () => { const original = jest.requireActual('@grafana/runtime'); diff --git a/public/app/features/variables/textbox/actions.ts b/public/app/features/variables/textbox/actions.ts index 4e10c499168..c01d82948ff 100644 --- a/public/app/features/variables/textbox/actions.ts +++ b/public/app/features/variables/textbox/actions.ts @@ -1,14 +1,16 @@ -import { TextBoxVariableModel } from '../types'; -import { ThunkResult } from '../../../types'; -import { getVariable } from '../state/selectors'; -import { variableAdapters } from '../adapters'; -import { createTextBoxOptions } from './reducer'; -import { KeyedVariableIdentifier } from '../state/types'; -import { setOptionFromUrl } from '../state/actions'; import { UrlQueryValue } from '@grafana/data'; -import { changeVariableProp } from '../state/sharedReducer'; -import { ensureStringValues, toKeyedVariableIdentifier, toVariablePayload } from '../utils'; + +import { ThunkResult } from '../../../types'; +import { variableAdapters } from '../adapters'; +import { setOptionFromUrl } from '../state/actions'; import { toKeyedAction } from '../state/keyedVariablesReducer'; +import { getVariable } from '../state/selectors'; +import { changeVariableProp } from '../state/sharedReducer'; +import { KeyedVariableIdentifier } from '../state/types'; +import { TextBoxVariableModel } from '../types'; +import { ensureStringValues, toKeyedVariableIdentifier, toVariablePayload } from '../utils'; + +import { createTextBoxOptions } from './reducer'; export const updateTextBoxVariableOptions = (identifier: KeyedVariableIdentifier): ThunkResult => { return async (dispatch, getState) => { diff --git a/public/app/features/variables/textbox/adapter.test.ts b/public/app/features/variables/textbox/adapter.test.ts index f28b7fd5c7c..93098078ad9 100644 --- a/public/app/features/variables/textbox/adapter.test.ts +++ b/public/app/features/variables/textbox/adapter.test.ts @@ -1,8 +1,9 @@ import { variableAdapters } from '../adapters'; -import { createTextBoxVariableAdapter } from './adapter'; import { textboxBuilder } from '../shared/testing/builders'; import { VariableHide } from '../types'; +import { createTextBoxVariableAdapter } from './adapter'; + variableAdapters.setInit(() => [createTextBoxVariableAdapter()]); describe('createTextBoxVariableAdapter', () => { diff --git a/public/app/features/variables/textbox/adapter.ts b/public/app/features/variables/textbox/adapter.ts index a916520eaca..9b6784ccd9d 100644 --- a/public/app/features/variables/textbox/adapter.ts +++ b/public/app/features/variables/textbox/adapter.ts @@ -1,15 +1,16 @@ import { cloneDeep } from 'lodash'; -import { TextBoxVariableModel } from '../types'; -import { initialTextBoxVariableModelState, textBoxVariableReducer } from './reducer'; import { dispatch } from '../../../store/store'; -import { setOptionAsCurrent } from '../state/actions'; import { VariableAdapter } from '../adapters'; -import { TextBoxVariablePicker } from './TextBoxVariablePicker'; -import { TextBoxVariableEditor } from './TextBoxVariableEditor'; -import { setTextBoxVariableOptionsFromUrl, updateTextBoxVariableOptions } from './actions'; +import { setOptionAsCurrent } from '../state/actions'; +import { TextBoxVariableModel } from '../types'; import { toKeyedVariableIdentifier } from '../utils'; +import { TextBoxVariableEditor } from './TextBoxVariableEditor'; +import { TextBoxVariablePicker } from './TextBoxVariablePicker'; +import { setTextBoxVariableOptionsFromUrl, updateTextBoxVariableOptions } from './actions'; +import { initialTextBoxVariableModelState, textBoxVariableReducer } from './reducer'; + export const createTextBoxVariableAdapter = (): VariableAdapter => { return { id: 'textbox', diff --git a/public/app/features/variables/textbox/reducer.test.ts b/public/app/features/variables/textbox/reducer.test.ts index fbd83a44318..d8ff2eacc22 100644 --- a/public/app/features/variables/textbox/reducer.test.ts +++ b/public/app/features/variables/textbox/reducer.test.ts @@ -1,12 +1,14 @@ -import { reducerTester } from '../../../../test/core/redux/reducerTester'; import { cloneDeep } from 'lodash'; + +import { reducerTester } from '../../../../test/core/redux/reducerTester'; import { getVariableTestContext } from '../state/helpers'; import { VariablesState } from '../state/types'; -import { createTextBoxOptions, textBoxVariableReducer } from './reducer'; import { TextBoxVariableModel } from '../types'; -import { createTextBoxVariableAdapter } from './adapter'; import { toVariablePayload } from '../utils'; +import { createTextBoxVariableAdapter } from './adapter'; +import { createTextBoxOptions, textBoxVariableReducer } from './reducer'; + describe('textBoxVariableReducer', () => { const adapter = createTextBoxVariableAdapter(); diff --git a/public/app/features/variables/textbox/reducer.ts b/public/app/features/variables/textbox/reducer.ts index 405cde2da91..9195c3ea456 100644 --- a/public/app/features/variables/textbox/reducer.ts +++ b/public/app/features/variables/textbox/reducer.ts @@ -1,8 +1,8 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit'; -import { initialVariableModelState, TextBoxVariableModel, VariableOption } from '../types'; -import { initialVariablesState, VariablePayload, VariablesState } from '../state/types'; import { getInstanceState } from '../state/selectors'; +import { initialVariablesState, VariablePayload, VariablesState } from '../state/types'; +import { initialVariableModelState, TextBoxVariableModel, VariableOption } from '../types'; export const initialTextBoxVariableModelState: TextBoxVariableModel = { ...initialVariableModelState, diff --git a/public/app/features/variables/types.ts b/public/app/features/variables/types.ts index 5d894ab35b8..22d7a35bf6c 100644 --- a/public/app/features/variables/types.ts +++ b/public/app/features/variables/types.ts @@ -1,4 +1,5 @@ import { ComponentType } from 'react'; + import { BusEventWithPayload, DataQuery, diff --git a/public/app/features/variables/utils.test.ts b/public/app/features/variables/utils.test.ts index a7b2ca13f89..4c22a0fc842 100644 --- a/public/app/features/variables/utils.test.ts +++ b/public/app/features/variables/utils.test.ts @@ -1,3 +1,6 @@ +import { UrlQueryMap } from '@grafana/data'; + +import { VariableRefresh } from './types'; import { containsVariable, ensureStringValues, @@ -6,8 +9,6 @@ import { getVariableRefresh, isAllVariable, } from './utils'; -import { VariableRefresh } from './types'; -import { UrlQueryMap } from '@grafana/data'; describe('isAllVariable', () => { it.each` diff --git a/public/app/features/variables/utils.ts b/public/app/features/variables/utils.ts index dfe00845608..9c555024cf7 100644 --- a/public/app/features/variables/utils.ts +++ b/public/app/features/variables/utils.ts @@ -1,16 +1,18 @@ import { isArray, isEqual } from 'lodash'; + import { ScopedVars, UrlQueryMap, UrlQueryValue, VariableType } from '@grafana/data'; import { getTemplateSrv } from '@grafana/runtime'; - -import { ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE } from './constants'; -import { QueryVariableModel, TransactionStatus, VariableModel, VariableRefresh } from './types'; -import { getTimeSrv } from '../dashboard/services/TimeSrv'; -import { variableAdapters } from './adapters'; import { safeStringifyValue } from 'app/core/utils/explore'; -import { StoreState } from '../../types'; + import { getState } from '../../store/store'; +import { StoreState } from '../../types'; +import { getTimeSrv } from '../dashboard/services/TimeSrv'; + +import { variableAdapters } from './adapters'; +import { ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE } from './constants'; import { getVariablesState } from './state/selectors'; import { KeyedVariableIdentifier, VariableIdentifier, VariablePayload } from './state/types'; +import { QueryVariableModel, TransactionStatus, VariableModel, VariableRefresh } from './types'; /* * This regex matches 3 types of variable reference with an optional format specifier diff --git a/public/app/plugins/datasource/alertmanager/ConfigEditor.tsx b/public/app/plugins/datasource/alertmanager/ConfigEditor.tsx index 86c92977ea9..fdb4710782e 100644 --- a/public/app/plugins/datasource/alertmanager/ConfigEditor.tsx +++ b/public/app/plugins/datasource/alertmanager/ConfigEditor.tsx @@ -1,6 +1,8 @@ +import React from 'react'; + import { DataSourcePluginOptionsEditorProps, SelectableValue } from '@grafana/data'; import { DataSourceHttpSettings, InlineFormLabel, Select } from '@grafana/ui'; -import React from 'react'; + import { AlertManagerDataSourceJsonData, AlertManagerImplementation } from './types'; export type Props = DataSourcePluginOptionsEditorProps; diff --git a/public/app/plugins/datasource/alertmanager/DataSource.ts b/public/app/plugins/datasource/alertmanager/DataSource.ts index 4ccb773c3e5..e091184a458 100644 --- a/public/app/plugins/datasource/alertmanager/DataSource.ts +++ b/public/app/plugins/datasource/alertmanager/DataSource.ts @@ -1,6 +1,8 @@ import { lastValueFrom, Observable, of } from 'rxjs'; + import { DataQuery, DataQueryResponse, DataSourceApi, DataSourceInstanceSettings } from '@grafana/data'; import { BackendSrvRequest, getBackendSrv } from '@grafana/runtime'; + import { AlertManagerDataSourceJsonData, AlertManagerImplementation } from './types'; export type AlertManagerQuery = { diff --git a/public/app/plugins/datasource/alertmanager/module.ts b/public/app/plugins/datasource/alertmanager/module.ts index b8bb42a2b97..a79d84f71e0 100644 --- a/public/app/plugins/datasource/alertmanager/module.ts +++ b/public/app/plugins/datasource/alertmanager/module.ts @@ -1,4 +1,5 @@ import { DataSourcePlugin } from '@grafana/data'; + import { ConfigEditor } from './ConfigEditor'; import { AlertManagerDatasource } from './DataSource'; diff --git a/public/app/plugins/datasource/cloud-monitoring/CloudMonitoringMetricFindQuery.ts b/public/app/plugins/datasource/cloud-monitoring/CloudMonitoringMetricFindQuery.ts index b8132e06bae..d787b538b3e 100644 --- a/public/app/plugins/datasource/cloud-monitoring/CloudMonitoringMetricFindQuery.ts +++ b/public/app/plugins/datasource/cloud-monitoring/CloudMonitoringMetricFindQuery.ts @@ -1,8 +1,9 @@ import { isString } from 'lodash'; + +import { SelectableValue } from '@grafana/data'; + import { ALIGNMENT_PERIODS, SELECTORS } from './constants'; import CloudMonitoringDatasource from './datasource'; -import { CloudMonitoringVariableQuery, MetricDescriptor, MetricFindQueryTypes, MetricKind, ValueTypes } from './types'; -import { SelectableValue } from '@grafana/data'; import { extractServicesFromMetricDescriptors, getAggregationOptionsByMetric, @@ -10,6 +11,7 @@ import { getLabelKeys, getMetricTypesByService, } from './functions'; +import { CloudMonitoringVariableQuery, MetricDescriptor, MetricFindQueryTypes, MetricKind, ValueTypes } from './types'; export default class CloudMonitoringMetricFindQuery { constructor(private datasource: CloudMonitoringDatasource) {} diff --git a/public/app/plugins/datasource/cloud-monitoring/components/Aggregation.test.tsx b/public/app/plugins/datasource/cloud-monitoring/components/Aggregation.test.tsx index aa5b3e16202..02fd2285a08 100644 --- a/public/app/plugins/datasource/cloud-monitoring/components/Aggregation.test.tsx +++ b/public/app/plugins/datasource/cloud-monitoring/components/Aggregation.test.tsx @@ -1,11 +1,14 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; import { shallow } from 'enzyme'; -import { Select } from '@grafana/ui'; -import { Aggregation, Props } from './Aggregation'; -import { ValueTypes, MetricKind } from '../types'; +import React from 'react'; import { TemplateSrvStub } from 'test/specs/helpers'; +import { Select } from '@grafana/ui'; + +import { ValueTypes, MetricKind } from '../types'; + +import { Aggregation, Props } from './Aggregation'; + const props: Props = { onChange: () => {}, // @ts-ignore diff --git a/public/app/plugins/datasource/cloud-monitoring/components/Aggregation.tsx b/public/app/plugins/datasource/cloud-monitoring/components/Aggregation.tsx index 0e14f821052..9ca3bf37fa7 100644 --- a/public/app/plugins/datasource/cloud-monitoring/components/Aggregation.tsx +++ b/public/app/plugins/datasource/cloud-monitoring/components/Aggregation.tsx @@ -1,11 +1,13 @@ -import { SelectableValue } from '@grafana/data'; -import { Select } from '@grafana/ui'; import React, { FC, useMemo } from 'react'; -import { QueryEditorField } from '.'; +import { SelectableValue } from '@grafana/data'; +import { Select } from '@grafana/ui'; + import { getAggregationOptionsByMetric } from '../functions'; import { MetricDescriptor, MetricKind, ValueTypes } from '../types'; +import { QueryEditorField } from '.'; + export interface Props { refId: string; onChange: (metricDescriptor: string) => void; diff --git a/public/app/plugins/datasource/cloud-monitoring/components/AliasBy.tsx b/public/app/plugins/datasource/cloud-monitoring/components/AliasBy.tsx index edd714da303..1c0a134fa38 100644 --- a/public/app/plugins/datasource/cloud-monitoring/components/AliasBy.tsx +++ b/public/app/plugins/datasource/cloud-monitoring/components/AliasBy.tsx @@ -1,10 +1,12 @@ -import { Input } from '@grafana/ui'; import { debounce } from 'lodash'; import React, { FunctionComponent, useState } from 'react'; -import { QueryEditorRow } from '.'; +import { Input } from '@grafana/ui'; + import { INPUT_WIDTH } from '../constants'; +import { QueryEditorRow } from '.'; + export interface Props { refId: string; onChange: (alias: any) => void; diff --git a/public/app/plugins/datasource/cloud-monitoring/components/Alignment.tsx b/public/app/plugins/datasource/cloud-monitoring/components/Alignment.tsx index d2fd6862e40..7d4226183df 100644 --- a/public/app/plugins/datasource/cloud-monitoring/components/Alignment.tsx +++ b/public/app/plugins/datasource/cloud-monitoring/components/Alignment.tsx @@ -1,11 +1,13 @@ -import { SelectableValue } from '@grafana/data'; import React, { FC } from 'react'; -import { AlignmentFunction, AlignmentPeriod, AlignmentPeriodLabel, QueryEditorField, QueryEditorRow } from '.'; +import { SelectableValue } from '@grafana/data'; + import { SELECT_WIDTH } from '../constants'; import CloudMonitoringDatasource from '../datasource'; import { CustomMetaData, MetricQuery, SLOQuery } from '../types'; +import { AlignmentFunction, AlignmentPeriod, AlignmentPeriodLabel, QueryEditorField, QueryEditorRow } from '.'; + export interface Props { refId: string; onChange: (query: MetricQuery | SLOQuery) => void; diff --git a/public/app/plugins/datasource/cloud-monitoring/components/AlignmentFunction.tsx b/public/app/plugins/datasource/cloud-monitoring/components/AlignmentFunction.tsx index 0c634f1cc4f..fff6b5f09f0 100644 --- a/public/app/plugins/datasource/cloud-monitoring/components/AlignmentFunction.tsx +++ b/public/app/plugins/datasource/cloud-monitoring/components/AlignmentFunction.tsx @@ -1,6 +1,7 @@ +import React, { FC, useMemo } from 'react'; + import { SelectableValue } from '@grafana/data'; import { Select } from '@grafana/ui'; -import React, { FC, useMemo } from 'react'; import { SELECT_WIDTH } from '../constants'; import { getAlignmentPickerData } from '../functions'; diff --git a/public/app/plugins/datasource/cloud-monitoring/components/AlignmentPeriod.tsx b/public/app/plugins/datasource/cloud-monitoring/components/AlignmentPeriod.tsx index 11afb9ea863..9e75ba2bbaf 100644 --- a/public/app/plugins/datasource/cloud-monitoring/components/AlignmentPeriod.tsx +++ b/public/app/plugins/datasource/cloud-monitoring/components/AlignmentPeriod.tsx @@ -1,6 +1,7 @@ +import React, { useMemo } from 'react'; + import { SelectableValue } from '@grafana/data'; import { Select } from '@grafana/ui'; -import React, { useMemo } from 'react'; import { ALIGNMENT_PERIODS } from '../constants'; import { MetricQuery, SLOQuery } from '../types'; diff --git a/public/app/plugins/datasource/cloud-monitoring/components/AlignmentPeriodLabel.tsx b/public/app/plugins/datasource/cloud-monitoring/components/AlignmentPeriodLabel.tsx index 2a4d1651481..1bfcf1f686a 100644 --- a/public/app/plugins/datasource/cloud-monitoring/components/AlignmentPeriodLabel.tsx +++ b/public/app/plugins/datasource/cloud-monitoring/components/AlignmentPeriodLabel.tsx @@ -1,5 +1,7 @@ import React, { FC, useMemo } from 'react'; + import { rangeUtil } from '@grafana/data'; + import { ALIGNMENTS } from '../constants'; import CloudMonitoringDatasource from '../datasource'; import { CustomMetaData } from '../types'; diff --git a/public/app/plugins/datasource/cloud-monitoring/components/AnnotationQueryEditor.tsx b/public/app/plugins/datasource/cloud-monitoring/components/AnnotationQueryEditor.tsx index b44f4a7e23f..fa24c8ca8d0 100644 --- a/public/app/plugins/datasource/cloud-monitoring/components/AnnotationQueryEditor.tsx +++ b/public/app/plugins/datasource/cloud-monitoring/components/AnnotationQueryEditor.tsx @@ -1,10 +1,12 @@ +import React from 'react'; + import { SelectableValue, toOption } from '@grafana/data'; import { TemplateSrv } from '@grafana/runtime'; import { LegacyForms } from '@grafana/ui'; -import React from 'react'; import CloudMonitoringDatasource from '../datasource'; import { AnnotationTarget, EditorMode, MetricDescriptor, MetricKind } from '../types'; + import { AnnotationsHelp, LabelFilter, Metrics, Project, QueryEditorRow } from './'; const { Input } = LegacyForms; diff --git a/public/app/plugins/datasource/cloud-monitoring/components/CloudMonitoringCheatSheet.tsx b/public/app/plugins/datasource/cloud-monitoring/components/CloudMonitoringCheatSheet.tsx index 5f281cec009..cde823d4ac2 100644 --- a/public/app/plugins/datasource/cloud-monitoring/components/CloudMonitoringCheatSheet.tsx +++ b/public/app/plugins/datasource/cloud-monitoring/components/CloudMonitoringCheatSheet.tsx @@ -1,6 +1,8 @@ -import React, { PureComponent } from 'react'; -import { QueryEditorHelpProps } from '@grafana/data'; import { css } from '@emotion/css'; +import React, { PureComponent } from 'react'; + +import { QueryEditorHelpProps } from '@grafana/data'; + import { CloudMonitoringQuery } from '../types'; export default class CloudMonitoringCheatSheet extends PureComponent< diff --git a/public/app/plugins/datasource/cloud-monitoring/components/ConfigEditor/ConfigEditor.tsx b/public/app/plugins/datasource/cloud-monitoring/components/ConfigEditor/ConfigEditor.tsx index f710279fa9e..8378bfb0e19 100644 --- a/public/app/plugins/datasource/cloud-monitoring/components/ConfigEditor/ConfigEditor.tsx +++ b/public/app/plugins/datasource/cloud-monitoring/components/ConfigEditor/ConfigEditor.tsx @@ -1,8 +1,10 @@ import React, { PureComponent } from 'react'; + import { DataSourcePluginOptionsEditorProps } from '@grafana/data'; -import { CloudMonitoringOptions, CloudMonitoringSecureJsonData } from '../../types'; import { ConnectionConfig } from '@grafana/google-sdk'; +import { CloudMonitoringOptions, CloudMonitoringSecureJsonData } from '../../types'; + export type Props = DataSourcePluginOptionsEditorProps; export class ConfigEditor extends PureComponent { diff --git a/public/app/plugins/datasource/cloud-monitoring/components/Fields.tsx b/public/app/plugins/datasource/cloud-monitoring/components/Fields.tsx index dc612eb735c..e18b176402c 100644 --- a/public/app/plugins/datasource/cloud-monitoring/components/Fields.tsx +++ b/public/app/plugins/datasource/cloud-monitoring/components/Fields.tsx @@ -1,7 +1,8 @@ import { css } from '@emotion/css'; +import React, { FC } from 'react'; + import { SelectableValue } from '@grafana/data'; import { HorizontalGroup, InlineField, InlineLabel, PopoverContent, Select } from '@grafana/ui'; -import React, { FC } from 'react'; import { INNER_LABEL_WIDTH, LABEL_WIDTH } from '../constants'; diff --git a/public/app/plugins/datasource/cloud-monitoring/components/GroupBy.tsx b/public/app/plugins/datasource/cloud-monitoring/components/GroupBy.tsx index 8810d99f936..72357a567c2 100644 --- a/public/app/plugins/datasource/cloud-monitoring/components/GroupBy.tsx +++ b/public/app/plugins/datasource/cloud-monitoring/components/GroupBy.tsx @@ -1,12 +1,14 @@ -import { SelectableValue } from '@grafana/data'; -import { MultiSelect } from '@grafana/ui'; import React, { FunctionComponent, useMemo } from 'react'; -import { Aggregation, QueryEditorRow } from '.'; +import { SelectableValue } from '@grafana/data'; +import { MultiSelect } from '@grafana/ui'; + import { INPUT_WIDTH, SYSTEM_LABELS } from '../constants'; import { labelsToGroupedOptions } from '../functions'; import { MetricDescriptor, MetricQuery } from '../types'; +import { Aggregation, QueryEditorRow } from '.'; + export interface Props { refId: string; variableOptionGroup: SelectableValue; diff --git a/public/app/plugins/datasource/cloud-monitoring/components/LabelFilter.tsx b/public/app/plugins/datasource/cloud-monitoring/components/LabelFilter.tsx index a0f843a5302..194d94947fb 100644 --- a/public/app/plugins/datasource/cloud-monitoring/components/LabelFilter.tsx +++ b/public/app/plugins/datasource/cloud-monitoring/components/LabelFilter.tsx @@ -1,14 +1,16 @@ -import { SelectableValue, toOption } from '@grafana/data'; -import { Button, HorizontalGroup, Select, VerticalGroup } from '@grafana/ui'; -import { CustomControlProps } from '@grafana/ui/src/components/Select/types'; import { flatten } from 'lodash'; import React, { FunctionComponent, useCallback, useMemo } from 'react'; -import { QueryEditorRow } from '.'; +import { SelectableValue, toOption } from '@grafana/data'; +import { Button, HorizontalGroup, Select, VerticalGroup } from '@grafana/ui'; +import { CustomControlProps } from '@grafana/ui/src/components/Select/types'; + import { SELECT_WIDTH } from '../constants'; import { labelsToGroupedOptions, stringArrayToFilters } from '../functions'; import { Filter } from '../types'; +import { QueryEditorRow } from '.'; + export interface Props { labels: { [key: string]: string[] }; filters: string[]; diff --git a/public/app/plugins/datasource/cloud-monitoring/components/MQLQueryEditor.tsx b/public/app/plugins/datasource/cloud-monitoring/components/MQLQueryEditor.tsx index a992c2733e4..48cbd630f49 100644 --- a/public/app/plugins/datasource/cloud-monitoring/components/MQLQueryEditor.tsx +++ b/public/app/plugins/datasource/cloud-monitoring/components/MQLQueryEditor.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { TextArea } from '@grafana/ui'; export interface Props { diff --git a/public/app/plugins/datasource/cloud-monitoring/components/MetricQueryEditor.tsx b/public/app/plugins/datasource/cloud-monitoring/components/MetricQueryEditor.tsx index 31b262b987a..d6ec09e9941 100644 --- a/public/app/plugins/datasource/cloud-monitoring/components/MetricQueryEditor.tsx +++ b/public/app/plugins/datasource/cloud-monitoring/components/MetricQueryEditor.tsx @@ -1,7 +1,7 @@ -import { SelectableValue } from '@grafana/data'; import React, { useCallback, useEffect, useState } from 'react'; -import { AliasBy, Project, VisualMetricQueryEditor } from '.'; +import { SelectableValue } from '@grafana/data'; + import CloudMonitoringDatasource from '../datasource'; import { getAlignmentPickerData } from '../functions'; import { @@ -15,8 +15,11 @@ import { SLOQuery, ValueTypes, } from '../types'; + import { MQLQueryEditor } from './MQLQueryEditor'; +import { AliasBy, Project, VisualMetricQueryEditor } from '.'; + export interface Props { refId: string; customMetaData: CustomMetaData; diff --git a/public/app/plugins/datasource/cloud-monitoring/components/Metrics.tsx b/public/app/plugins/datasource/cloud-monitoring/components/Metrics.tsx index cda52b2590d..3f39b3ea3c2 100644 --- a/public/app/plugins/datasource/cloud-monitoring/components/Metrics.tsx +++ b/public/app/plugins/datasource/cloud-monitoring/components/Metrics.tsx @@ -1,15 +1,17 @@ import { css } from '@emotion/css'; -import { GrafanaTheme2, SelectableValue } from '@grafana/data'; -import { TemplateSrv } from '@grafana/runtime'; -import { getSelectStyles, Select, useStyles2, useTheme2 } from '@grafana/ui'; import { startCase, uniqBy } from 'lodash'; import React, { useCallback, useEffect, useState } from 'react'; -import { QueryEditorField, QueryEditorRow } from '.'; +import { GrafanaTheme2, SelectableValue } from '@grafana/data'; +import { TemplateSrv } from '@grafana/runtime'; +import { getSelectStyles, Select, useStyles2, useTheme2 } from '@grafana/ui'; + import { INNER_LABEL_WIDTH, LABEL_WIDTH, SELECT_WIDTH } from '../constants'; import CloudMonitoringDatasource from '../datasource'; import { MetricDescriptor } from '../types'; +import { QueryEditorField, QueryEditorRow } from '.'; + export interface Props { refId: string; onChange: (metricDescriptor: MetricDescriptor) => void; diff --git a/public/app/plugins/datasource/cloud-monitoring/components/Preprocessor.tsx b/public/app/plugins/datasource/cloud-monitoring/components/Preprocessor.tsx index 1edba340702..1dc72c44ef6 100644 --- a/public/app/plugins/datasource/cloud-monitoring/components/Preprocessor.tsx +++ b/public/app/plugins/datasource/cloud-monitoring/components/Preprocessor.tsx @@ -1,8 +1,11 @@ import React, { FunctionComponent, useMemo } from 'react'; + import { SelectableValue } from '@grafana/data'; import { RadioButtonGroup } from '@grafana/ui'; -import { MetricDescriptor, MetricKind, MetricQuery, PreprocessorType, ValueTypes } from '../types'; + import { getAlignmentPickerData } from '../functions'; +import { MetricDescriptor, MetricKind, MetricQuery, PreprocessorType, ValueTypes } from '../types'; + import { QueryEditorRow } from '.'; const NONE_OPTION = { label: 'None', value: PreprocessorType.None }; diff --git a/public/app/plugins/datasource/cloud-monitoring/components/Project.tsx b/public/app/plugins/datasource/cloud-monitoring/components/Project.tsx index 72ff1829ccc..8f0fb7c9291 100644 --- a/public/app/plugins/datasource/cloud-monitoring/components/Project.tsx +++ b/public/app/plugins/datasource/cloud-monitoring/components/Project.tsx @@ -1,11 +1,13 @@ -import { SelectableValue } from '@grafana/data'; -import { Select } from '@grafana/ui'; import React, { useEffect, useMemo, useState } from 'react'; -import { QueryEditorRow } from '.'; +import { SelectableValue } from '@grafana/data'; +import { Select } from '@grafana/ui'; + import { SELECT_WIDTH } from '../constants'; import CloudMonitoringDatasource from '../datasource'; +import { QueryEditorRow } from '.'; + export interface Props { refId: string; datasource: CloudMonitoringDatasource; diff --git a/public/app/plugins/datasource/cloud-monitoring/components/QueryEditor.tsx b/public/app/plugins/datasource/cloud-monitoring/components/QueryEditor.tsx index a4124efbd09..bd2fd416c79 100644 --- a/public/app/plugins/datasource/cloud-monitoring/components/QueryEditor.tsx +++ b/public/app/plugins/datasource/cloud-monitoring/components/QueryEditor.tsx @@ -1,15 +1,18 @@ import { css } from '@emotion/css'; +import React, { PureComponent } from 'react'; + import { QueryEditorProps, toOption } from '@grafana/data'; import { Button, Select } from '@grafana/ui'; -import React, { PureComponent } from 'react'; import { QUERY_TYPES, SELECT_WIDTH } from '../constants'; import CloudMonitoringDatasource from '../datasource'; import { CloudMonitoringQuery, EditorMode, MetricQuery, QueryType, SLOQuery, CloudMonitoringOptions } from '../types'; -import { MetricQueryEditor, QueryEditorRow, SLOQueryEditor } from './'; + import { defaultQuery } from './MetricQueryEditor'; import { defaultQuery as defaultSLOQuery } from './SLO/SLOQueryEditor'; +import { MetricQueryEditor, QueryEditorRow, SLOQueryEditor } from './'; + export type Props = QueryEditorProps; export class QueryEditor extends PureComponent { diff --git a/public/app/plugins/datasource/cloud-monitoring/components/SLO/SLO.tsx b/public/app/plugins/datasource/cloud-monitoring/components/SLO/SLO.tsx index 064e7f5ae31..c62d8246095 100644 --- a/public/app/plugins/datasource/cloud-monitoring/components/SLO/SLO.tsx +++ b/public/app/plugins/datasource/cloud-monitoring/components/SLO/SLO.tsx @@ -1,6 +1,7 @@ +import React, { useEffect, useState } from 'react'; + import { SelectableValue } from '@grafana/data'; import { Select } from '@grafana/ui'; -import React, { useEffect, useState } from 'react'; import { QueryEditorRow } from '..'; import { SELECT_WIDTH } from '../../constants'; diff --git a/public/app/plugins/datasource/cloud-monitoring/components/SLO/SLOQueryEditor.tsx b/public/app/plugins/datasource/cloud-monitoring/components/SLO/SLOQueryEditor.tsx index 2605c007e6a..f33fe4e826b 100644 --- a/public/app/plugins/datasource/cloud-monitoring/components/SLO/SLOQueryEditor.tsx +++ b/public/app/plugins/datasource/cloud-monitoring/components/SLO/SLOQueryEditor.tsx @@ -1,12 +1,14 @@ -import { SelectableValue } from '@grafana/data'; import React from 'react'; -import { Selector, Service, SLO } from '.'; +import { SelectableValue } from '@grafana/data'; + import { AliasBy, AlignmentPeriod, AlignmentPeriodLabel, Project, QueryEditorRow } from '..'; import { SELECT_WIDTH } from '../../constants'; import CloudMonitoringDatasource from '../../datasource'; import { AlignmentTypes, CustomMetaData, SLOQuery } from '../../types'; +import { Selector, Service, SLO } from '.'; + export interface Props { refId: string; customMetaData: CustomMetaData; diff --git a/public/app/plugins/datasource/cloud-monitoring/components/SLO/Selector.tsx b/public/app/plugins/datasource/cloud-monitoring/components/SLO/Selector.tsx index 4357501b29d..02f4a066d14 100644 --- a/public/app/plugins/datasource/cloud-monitoring/components/SLO/Selector.tsx +++ b/public/app/plugins/datasource/cloud-monitoring/components/SLO/Selector.tsx @@ -1,6 +1,7 @@ +import React from 'react'; + import { SelectableValue } from '@grafana/data'; import { Select } from '@grafana/ui'; -import React from 'react'; import { QueryEditorRow } from '..'; import { SELECT_WIDTH, SELECTORS } from '../../constants'; diff --git a/public/app/plugins/datasource/cloud-monitoring/components/SLO/Service.tsx b/public/app/plugins/datasource/cloud-monitoring/components/SLO/Service.tsx index a5d5c433d28..ef158a7ce70 100644 --- a/public/app/plugins/datasource/cloud-monitoring/components/SLO/Service.tsx +++ b/public/app/plugins/datasource/cloud-monitoring/components/SLO/Service.tsx @@ -1,6 +1,7 @@ +import React, { useEffect, useState } from 'react'; + import { SelectableValue } from '@grafana/data'; import { Select } from '@grafana/ui'; -import React, { useEffect, useState } from 'react'; import { QueryEditorRow } from '..'; import { SELECT_WIDTH } from '../../constants'; diff --git a/public/app/plugins/datasource/cloud-monitoring/components/VariableQueryEditor.test.tsx b/public/app/plugins/datasource/cloud-monitoring/components/VariableQueryEditor.test.tsx index 8012edb6e97..8b4bd47c29a 100644 --- a/public/app/plugins/datasource/cloud-monitoring/components/VariableQueryEditor.test.tsx +++ b/public/app/plugins/datasource/cloud-monitoring/components/VariableQueryEditor.test.tsx @@ -1,11 +1,14 @@ import React from 'react'; // @ts-ignore import renderer from 'react-test-renderer'; -import { CloudMonitoringVariableQueryEditor, Props } from './VariableQueryEditor'; -import { CloudMonitoringVariableQuery, MetricFindQueryTypes } from '../types'; -import CloudMonitoringDatasource from '../datasource'; + import { VariableModel } from '@grafana/data'; +import CloudMonitoringDatasource from '../datasource'; +import { CloudMonitoringVariableQuery, MetricFindQueryTypes } from '../types'; + +import { CloudMonitoringVariableQueryEditor, Props } from './VariableQueryEditor'; + jest.mock('../functions', () => ({ getMetricTypes: (): any => ({ metricTypes: [], selectedMetricType: '' }), extractServicesFromMetricDescriptors: (): any[] => [], diff --git a/public/app/plugins/datasource/cloud-monitoring/components/VariableQueryEditor.tsx b/public/app/plugins/datasource/cloud-monitoring/components/VariableQueryEditor.tsx index 9cb564fb573..2c7458c149e 100644 --- a/public/app/plugins/datasource/cloud-monitoring/components/VariableQueryEditor.tsx +++ b/public/app/plugins/datasource/cloud-monitoring/components/VariableQueryEditor.tsx @@ -1,9 +1,9 @@ import React, { PureComponent } from 'react'; -import { getTemplateSrv } from '@grafana/runtime'; import { QueryEditorProps } from '@grafana/data'; +import { getTemplateSrv } from '@grafana/runtime'; -import { VariableQueryField } from './'; +import CloudMonitoringDatasource from '../datasource'; import { extractServicesFromMetricDescriptors, getLabelKeys, getMetricTypes } from '../functions'; import { CloudMonitoringOptions, @@ -13,7 +13,8 @@ import { MetricFindQueryTypes, VariableQueryData, } from '../types'; -import CloudMonitoringDatasource from '../datasource'; + +import { VariableQueryField } from './'; export type Props = QueryEditorProps< CloudMonitoringDatasource, diff --git a/public/app/plugins/datasource/cloud-monitoring/components/VisualMetricQueryEditor.tsx b/public/app/plugins/datasource/cloud-monitoring/components/VisualMetricQueryEditor.tsx index c48ce93baf4..79bb0b228c8 100644 --- a/public/app/plugins/datasource/cloud-monitoring/components/VisualMetricQueryEditor.tsx +++ b/public/app/plugins/datasource/cloud-monitoring/components/VisualMetricQueryEditor.tsx @@ -1,10 +1,12 @@ -import { SelectableValue } from '@grafana/data'; import React from 'react'; -import { Alignment, GroupBy, LabelFilter, Metrics, Preprocessor } from '.'; +import { SelectableValue } from '@grafana/data'; + import CloudMonitoringDatasource from '../datasource'; import { CustomMetaData, MetricDescriptor, MetricQuery, SLOQuery } from '../types'; +import { Alignment, GroupBy, LabelFilter, Metrics, Preprocessor } from '.'; + export interface Props { refId: string; customMetaData: CustomMetaData; diff --git a/public/app/plugins/datasource/cloud-monitoring/constants.ts b/public/app/plugins/datasource/cloud-monitoring/constants.ts index e87bcd7e092..df640dcaabf 100644 --- a/public/app/plugins/datasource/cloud-monitoring/constants.ts +++ b/public/app/plugins/datasource/cloud-monitoring/constants.ts @@ -1,6 +1,7 @@ -import { MetricKind, QueryType, ValueTypes } from './types'; import { GoogleAuthType } from '@grafana/google-sdk'; +import { MetricKind, QueryType, ValueTypes } from './types'; + // not super excited about using uneven numbers, but this makes it align perfectly with rows that has two fields export const INPUT_WIDTH = 71; export const LABEL_WIDTH = 19; diff --git a/public/app/plugins/datasource/cloud-monitoring/datasource.ts b/public/app/plugins/datasource/cloud-monitoring/datasource.ts index 7e75a680907..d1e84261f16 100644 --- a/public/app/plugins/datasource/cloud-monitoring/datasource.ts +++ b/public/app/plugins/datasource/cloud-monitoring/datasource.ts @@ -1,6 +1,7 @@ import { chunk, flatten, isString, isArray } from 'lodash'; import { from, lastValueFrom, Observable, of } from 'rxjs'; import { map, mergeMap } from 'rxjs/operators'; + import { DataQueryRequest, DataQueryResponse, @@ -9,9 +10,9 @@ import { SelectableValue, } from '@grafana/data'; import { DataSourceWithBackend, getBackendSrv, toDataQueryResponse } from '@grafana/runtime'; - -import { getTemplateSrv, TemplateSrv } from 'app/features/templating/template_srv'; import { getTimeSrv, TimeSrv } from 'app/features/dashboard/services/TimeSrv'; +import { getTemplateSrv, TemplateSrv } from 'app/features/templating/template_srv'; + import { CloudMonitoringOptions, CloudMonitoringQuery, diff --git a/public/app/plugins/datasource/cloud-monitoring/functions.ts b/public/app/plugins/datasource/cloud-monitoring/functions.ts index 6c37c962ec6..0dd7bc46ed0 100644 --- a/public/app/plugins/datasource/cloud-monitoring/functions.ts +++ b/public/app/plugins/datasource/cloud-monitoring/functions.ts @@ -1,6 +1,7 @@ -import { getTemplateSrv, TemplateSrv } from '@grafana/runtime'; import { chunk, initial, startCase, uniqBy } from 'lodash'; +import { getTemplateSrv, TemplateSrv } from '@grafana/runtime'; + import { AGGREGATIONS, ALIGNMENTS, SYSTEM_LABELS } from './constants'; import CloudMonitoringDatasource from './datasource'; import { AlignmentTypes, MetricDescriptor, MetricKind, PreprocessorType, ValueTypes } from './types'; diff --git a/public/app/plugins/datasource/cloud-monitoring/module.ts b/public/app/plugins/datasource/cloud-monitoring/module.ts index 32508fe8efb..64f25908f59 100644 --- a/public/app/plugins/datasource/cloud-monitoring/module.ts +++ b/public/app/plugins/datasource/cloud-monitoring/module.ts @@ -1,11 +1,11 @@ import { DataSourcePlugin } from '@grafana/data'; -import CloudMonitoringDatasource from './datasource'; -import { QueryEditor } from './components/QueryEditor'; -import { ConfigEditor } from './components/ConfigEditor/ConfigEditor'; -import CloudMonitoringCheatSheet from './components/CloudMonitoringCheatSheet'; import { CloudMonitoringAnnotationsQueryCtrl } from './annotations_query_ctrl'; +import CloudMonitoringCheatSheet from './components/CloudMonitoringCheatSheet'; +import { ConfigEditor } from './components/ConfigEditor/ConfigEditor'; +import { QueryEditor } from './components/QueryEditor'; import { CloudMonitoringVariableQueryEditor } from './components/VariableQueryEditor'; +import CloudMonitoringDatasource from './datasource'; import { CloudMonitoringQuery } from './types'; export const plugin = new DataSourcePlugin(CloudMonitoringDatasource) diff --git a/public/app/plugins/datasource/cloud-monitoring/specs/datasource.test.ts b/public/app/plugins/datasource/cloud-monitoring/specs/datasource.test.ts index a223de820ce..9cfc69d10e0 100644 --- a/public/app/plugins/datasource/cloud-monitoring/specs/datasource.test.ts +++ b/public/app/plugins/datasource/cloud-monitoring/specs/datasource.test.ts @@ -1,14 +1,15 @@ import { of, throwError } from 'rxjs'; -import { DataSourceInstanceSettings, toUtc } from '@grafana/data'; +import { createFetchResponse } from 'test/helpers/createFetchResponse'; -import CloudMonitoringDataSource from '../datasource'; -import { TemplateSrv } from 'app/features/templating/template_srv'; -import { CloudMonitoringOptions } from '../types'; +import { DataSourceInstanceSettings, toUtc } from '@grafana/data'; import { backendSrv } from 'app/core/services/backend_srv'; // will use the version in __mocks__ import { TimeSrv } from 'app/features/dashboard/services/TimeSrv'; -import { CustomVariableModel } from '../../../../features/variables/types'; +import { TemplateSrv } from 'app/features/templating/template_srv'; + import { initialCustomVariableModelState } from '../../../../features/variables/custom/reducer'; -import { createFetchResponse } from 'test/helpers/createFetchResponse'; +import { CustomVariableModel } from '../../../../features/variables/types'; +import CloudMonitoringDataSource from '../datasource'; +import { CloudMonitoringOptions } from '../types'; jest.mock('@grafana/runtime', () => ({ ...(jest.requireActual('@grafana/runtime') as unknown as object), diff --git a/public/app/plugins/datasource/cloud-monitoring/variables.ts b/public/app/plugins/datasource/cloud-monitoring/variables.ts index 181e9f07a82..0dfb2ea49e0 100644 --- a/public/app/plugins/datasource/cloud-monitoring/variables.ts +++ b/public/app/plugins/datasource/cloud-monitoring/variables.ts @@ -1,11 +1,12 @@ import { from, Observable } from 'rxjs'; import { map, mergeMap } from 'rxjs/operators'; + import { CustomVariableSupport, DataQueryRequest, DataQueryResponse } from '@grafana/data'; -import CloudMonitoringDatasource from './datasource'; -import { CloudMonitoringVariableQuery } from './types'; import CloudMonitoringMetricFindQuery from './CloudMonitoringMetricFindQuery'; import { CloudMonitoringVariableQueryEditor } from './components/VariableQueryEditor'; +import CloudMonitoringDatasource from './datasource'; +import { CloudMonitoringVariableQuery } from './types'; export class CloudMonitoringVariableSupport extends CustomVariableSupport< CloudMonitoringDatasource, diff --git a/public/app/plugins/datasource/cloudwatch/__mocks__/CloudWatchDataSource.ts b/public/app/plugins/datasource/cloudwatch/__mocks__/CloudWatchDataSource.ts index e5701c7898b..f846d4e254c 100644 --- a/public/app/plugins/datasource/cloudwatch/__mocks__/CloudWatchDataSource.ts +++ b/public/app/plugins/datasource/cloudwatch/__mocks__/CloudWatchDataSource.ts @@ -1,9 +1,10 @@ +import { of } from 'rxjs'; + import { dateTime } from '@grafana/data'; import { setBackendSrv } from '@grafana/runtime'; import { TemplateSrv } from 'app/features/templating/template_srv'; import { initialCustomVariableModelState } from 'app/features/variables/custom/reducer'; import { CustomVariableModel } from 'app/features/variables/types'; -import { of } from 'rxjs'; import { TemplateSrvMock } from '../../../../features/templating/template_srv.mock'; import { CloudWatchDatasource } from '../datasource'; diff --git a/public/app/plugins/datasource/cloudwatch/__mocks__/monarch/Monaco.ts b/public/app/plugins/datasource/cloudwatch/__mocks__/monarch/Monaco.ts index 42a6c7f5d2f..db6d58c52ff 100644 --- a/public/app/plugins/datasource/cloudwatch/__mocks__/monarch/Monaco.ts +++ b/public/app/plugins/datasource/cloudwatch/__mocks__/monarch/Monaco.ts @@ -1,4 +1,5 @@ import { monacoTypes } from '@grafana/ui'; + import { Monaco } from '../../monarch/types'; import * as SQLTestData from '../cloudwatch-sql-test-data'; import * as MetricMathTestData from '../metric-math-test-data'; diff --git a/public/app/plugins/datasource/cloudwatch/annotations_query_ctrl.ts b/public/app/plugins/datasource/cloudwatch/annotations_query_ctrl.ts index 360c8cce6a6..93ee1f1c19f 100644 --- a/public/app/plugins/datasource/cloudwatch/annotations_query_ctrl.ts +++ b/public/app/plugins/datasource/cloudwatch/annotations_query_ctrl.ts @@ -1,4 +1,5 @@ import { defaultsDeep } from 'lodash'; + import { CloudWatchAnnotationQuery } from './types'; export class CloudWatchAnnotationsQueryCtrl { diff --git a/public/app/plugins/datasource/cloudwatch/cloudwatch-sql/SQLGenerator.test.ts b/public/app/plugins/datasource/cloudwatch/cloudwatch-sql/SQLGenerator.test.ts index fb757d3b150..765ed6f3abb 100644 --- a/public/app/plugins/datasource/cloudwatch/cloudwatch-sql/SQLGenerator.test.ts +++ b/public/app/plugins/datasource/cloudwatch/cloudwatch-sql/SQLGenerator.test.ts @@ -1,6 +1,5 @@ import { TemplateSrv } from 'app/features/templating/template_srv'; -import { QueryEditorExpressionType } from '../expressions'; -import { SQLExpression } from '../types'; + import { aggregationvariable, labelsVariable, @@ -15,6 +14,9 @@ import { createFunction, createProperty, } from '../__mocks__/sqlUtils'; +import { QueryEditorExpressionType } from '../expressions'; +import { SQLExpression } from '../types'; + import SQLGenerator from './SQLGenerator'; describe('SQLGenerator', () => { diff --git a/public/app/plugins/datasource/cloudwatch/cloudwatch-sql/SQLGenerator.ts b/public/app/plugins/datasource/cloudwatch/cloudwatch-sql/SQLGenerator.ts index ba47ea4df17..3b04844200e 100644 --- a/public/app/plugins/datasource/cloudwatch/cloudwatch-sql/SQLGenerator.ts +++ b/public/app/plugins/datasource/cloudwatch/cloudwatch-sql/SQLGenerator.ts @@ -1,5 +1,5 @@ import { getTemplateSrv, TemplateSrv } from 'app/features/templating/template_srv'; -import { SQLExpression } from '../types'; + import { QueryEditorArrayExpression, QueryEditorExpression, @@ -8,6 +8,7 @@ import { QueryEditorOperatorExpression, QueryEditorPropertyExpression, } from '../expressions'; +import { SQLExpression } from '../types'; export default class SQLGenerator { constructor(private templateSrv: TemplateSrv = getTemplateSrv()) {} diff --git a/public/app/plugins/datasource/cloudwatch/cloudwatch-sql/completion/CompletionItemProvider.ts b/public/app/plugins/datasource/cloudwatch/cloudwatch-sql/completion/CompletionItemProvider.ts index 64842ca96b5..ef347cf42d9 100644 --- a/public/app/plugins/datasource/cloudwatch/cloudwatch-sql/completion/CompletionItemProvider.ts +++ b/public/app/plugins/datasource/cloudwatch/cloudwatch-sql/completion/CompletionItemProvider.ts @@ -1,9 +1,13 @@ -import type { Monaco, monacoTypes } from '@grafana/ui'; import { uniq } from 'lodash'; -import { TRIGGER_SUGGEST } from '../../monarch/commands'; + +import { getTemplateSrv, TemplateSrv } from '@grafana/runtime'; +import type { Monaco, monacoTypes } from '@grafana/ui'; + +import { CloudWatchDatasource } from '../../datasource'; +import { CompletionItemProvider } from '../../monarch/CompletionItemProvider'; import { LinkedToken } from '../../monarch/LinkedToken'; +import { TRIGGER_SUGGEST } from '../../monarch/commands'; import { SuggestionKind, CompletionItemPriority, StatementPosition } from '../../monarch/types'; -import { SQLTokenTypes } from './types'; import { BY, FROM, @@ -19,12 +23,11 @@ import { LOGICAL_OPERATORS, STATISTICS, } from '../language'; -import { getMetricNameToken, getNamespaceToken } from './tokenUtils'; -import { CompletionItemProvider } from '../../monarch/CompletionItemProvider'; -import { CloudWatchDatasource } from '../../datasource'; -import { getTemplateSrv, TemplateSrv } from '@grafana/runtime'; + import { getStatementPosition } from './statementPosition'; import { getSuggestionKinds } from './suggestionKind'; +import { getMetricNameToken, getNamespaceToken } from './tokenUtils'; +import { SQLTokenTypes } from './types'; type CompletionItem = monacoTypes.languages.CompletionItem; diff --git a/public/app/plugins/datasource/cloudwatch/cloudwatch-sql/completion/statementPosition.test.ts b/public/app/plugins/datasource/cloudwatch/cloudwatch-sql/completion/statementPosition.test.ts index 878411e3954..40ed83ee21a 100644 --- a/public/app/plugins/datasource/cloudwatch/cloudwatch-sql/completion/statementPosition.test.ts +++ b/public/app/plugins/datasource/cloudwatch/cloudwatch-sql/completion/statementPosition.test.ts @@ -1,16 +1,18 @@ import { monacoTypes } from '@grafana/ui'; -import MonacoMock from '../../__mocks__/monarch/Monaco'; -import TextModel from '../../__mocks__/monarch/TextModel'; + import { multiLineFullQuery, singleLineFullQuery, singleLineEmptyQuery, singleLineTwoQueries, } from '../../__mocks__/cloudwatch-sql-test-data'; +import MonacoMock from '../../__mocks__/monarch/Monaco'; +import TextModel from '../../__mocks__/monarch/TextModel'; import { linkedTokenBuilder } from '../../monarch/linkedTokenBuilder'; import { StatementPosition } from '../../monarch/types'; -import { getStatementPosition } from './statementPosition'; import cloudWatchSqlLanguageDefinition from '../definition'; + +import { getStatementPosition } from './statementPosition'; import { SQLTokenTypes } from './types'; describe('statementPosition', () => { diff --git a/public/app/plugins/datasource/cloudwatch/cloudwatch-sql/completion/statementPosition.ts b/public/app/plugins/datasource/cloudwatch/cloudwatch-sql/completion/statementPosition.ts index b1af5f11d09..91e8c3abdc1 100644 --- a/public/app/plugins/datasource/cloudwatch/cloudwatch-sql/completion/statementPosition.ts +++ b/public/app/plugins/datasource/cloudwatch/cloudwatch-sql/completion/statementPosition.ts @@ -1,6 +1,7 @@ -import { AND, ASC, BY, DESC, EQUALS, FROM, GROUP, NOT_EQUALS, ORDER, SCHEMA, SELECT, WHERE } from '../language'; import { LinkedToken } from '../../monarch/LinkedToken'; import { StatementPosition } from '../../monarch/types'; +import { AND, ASC, BY, DESC, EQUALS, FROM, GROUP, NOT_EQUALS, ORDER, SCHEMA, SELECT, WHERE } from '../language'; + import { SQLTokenTypes } from './types'; export function getStatementPosition(currentToken: LinkedToken | null): StatementPosition { diff --git a/public/app/plugins/datasource/cloudwatch/cloudwatch-sql/completion/tokenUtils.test.ts b/public/app/plugins/datasource/cloudwatch/cloudwatch-sql/completion/tokenUtils.test.ts index 762162864d5..a1bab84f7a3 100644 --- a/public/app/plugins/datasource/cloudwatch/cloudwatch-sql/completion/tokenUtils.test.ts +++ b/public/app/plugins/datasource/cloudwatch/cloudwatch-sql/completion/tokenUtils.test.ts @@ -1,18 +1,20 @@ import { monacoTypes } from '@grafana/ui'; -import MonacoMock from '../../__mocks__/monarch/Monaco'; -import TextModel from '../../__mocks__/monarch/TextModel'; + import { multiLineFullQuery, singleLineFullQuery, singleLineTwoQueries, multiLineIncompleteQueryWithoutNamespace, } from '../../__mocks__/cloudwatch-sql-test-data'; +import MonacoMock from '../../__mocks__/monarch/Monaco'; +import TextModel from '../../__mocks__/monarch/TextModel'; import { LinkedToken } from '../../monarch/LinkedToken'; import { linkedTokenBuilder } from '../../monarch/linkedTokenBuilder'; -import { SQLTokenTypes } from './types'; -import { getMetricNameToken, getNamespaceToken, getSelectStatisticToken, getSelectToken } from './tokenUtils'; -import { SELECT } from '../language'; import cloudWatchSqlLanguageDefinition from '../definition'; +import { SELECT } from '../language'; + +import { getMetricNameToken, getNamespaceToken, getSelectStatisticToken, getSelectToken } from './tokenUtils'; +import { SQLTokenTypes } from './types'; const getToken = ( query: string, diff --git a/public/app/plugins/datasource/cloudwatch/cloudwatch-sql/completion/tokenUtils.ts b/public/app/plugins/datasource/cloudwatch/cloudwatch-sql/completion/tokenUtils.ts index d9a1762efe4..820c1c4d481 100644 --- a/public/app/plugins/datasource/cloudwatch/cloudwatch-sql/completion/tokenUtils.ts +++ b/public/app/plugins/datasource/cloudwatch/cloudwatch-sql/completion/tokenUtils.ts @@ -1,5 +1,6 @@ import { LinkedToken } from '../../monarch/LinkedToken'; import { FROM, SCHEMA, SELECT } from '../language'; + import { SQLTokenTypes } from './types'; export const getSelectToken = (currentToken: LinkedToken | null) => diff --git a/public/app/plugins/datasource/cloudwatch/components/Alias.tsx b/public/app/plugins/datasource/cloudwatch/components/Alias.tsx index 3b1ead48981..2f3ddd8d8b5 100644 --- a/public/app/plugins/datasource/cloudwatch/components/Alias.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/Alias.tsx @@ -1,5 +1,6 @@ -import React, { FunctionComponent, useState } from 'react'; import { debounce } from 'lodash'; +import React, { FunctionComponent, useState } from 'react'; + import { Input } from '@grafana/ui'; export interface Props { diff --git a/public/app/plugins/datasource/cloudwatch/components/AnnotationQueryEditor.test.tsx b/public/app/plugins/datasource/cloudwatch/components/AnnotationQueryEditor.test.tsx index ea0fec67e6d..be67800951f 100644 --- a/public/app/plugins/datasource/cloudwatch/components/AnnotationQueryEditor.test.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/AnnotationQueryEditor.test.tsx @@ -1,8 +1,9 @@ -import React from 'react'; -import '@testing-library/jest-dom'; import { render, screen, waitFor } from '@testing-library/react'; +import React from 'react'; + import { setupMockedDataSource } from '../__mocks__/CloudWatchDataSource'; import { CloudWatchAnnotationQuery } from '../types'; + import { AnnotationQueryEditor } from './AnnotationQueryEditor'; const ds = setupMockedDataSource({ diff --git a/public/app/plugins/datasource/cloudwatch/components/AnnotationQueryEditor.tsx b/public/app/plugins/datasource/cloudwatch/components/AnnotationQueryEditor.tsx index 099aa55ff41..72bb082d99e 100644 --- a/public/app/plugins/datasource/cloudwatch/components/AnnotationQueryEditor.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/AnnotationQueryEditor.tsx @@ -1,10 +1,13 @@ import React, { ChangeEvent } from 'react'; + import { PanelData } from '@grafana/data'; import { EditorField, EditorHeader, EditorRow, InlineSelect, Space } from '@grafana/experimental'; import { Input, Switch } from '@grafana/ui'; + import { CloudWatchDatasource } from '../datasource'; import { useRegions } from '../hooks'; import { CloudWatchAnnotationQuery, CloudWatchMetricsQuery } from '../types'; + import { MetricStatEditor } from './MetricStatEditor'; export type Props = { diff --git a/public/app/plugins/datasource/cloudwatch/components/CloudWatchLink.tsx b/public/app/plugins/datasource/cloudwatch/components/CloudWatchLink.tsx index 41035992ab1..e8324be8989 100644 --- a/public/app/plugins/datasource/cloudwatch/components/CloudWatchLink.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/CloudWatchLink.tsx @@ -1,10 +1,11 @@ import React, { Component } from 'react'; -import { CloudWatchLogsQuery } from '../types'; import { PanelData } from '@grafana/data'; import { Icon } from '@grafana/ui'; + import { encodeUrl, AwsUrl } from '../aws_url'; import { CloudWatchDatasource } from '../datasource'; +import { CloudWatchLogsQuery } from '../types'; interface Props { query: CloudWatchLogsQuery; diff --git a/public/app/plugins/datasource/cloudwatch/components/ConfigEditor.test.tsx b/public/app/plugins/datasource/cloudwatch/components/ConfigEditor.test.tsx index be8613e29ab..3947939384f 100644 --- a/public/app/plugins/datasource/cloudwatch/components/ConfigEditor.test.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/ConfigEditor.test.tsx @@ -1,6 +1,8 @@ -import React from 'react'; import { shallow } from 'enzyme'; +import React from 'react'; + import { AwsAuthType } from '@grafana/aws-sdk'; + import { ConfigEditor, Props } from './ConfigEditor'; jest.mock('app/features/plugins/datasource_srv', () => ({ diff --git a/public/app/plugins/datasource/cloudwatch/components/ConfigEditor.tsx b/public/app/plugins/datasource/cloudwatch/components/ConfigEditor.tsx index 3179bdc7d9c..5dc682a3a36 100644 --- a/public/app/plugins/datasource/cloudwatch/components/ConfigEditor.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/ConfigEditor.tsx @@ -1,21 +1,22 @@ import React, { FC, useEffect, useState } from 'react'; import { useDebounce } from 'react-use'; -import { Input, InlineField } from '@grafana/ui'; + +import { ConnectionConfig } from '@grafana/aws-sdk'; import { rangeUtil, DataSourcePluginOptionsEditorProps, onUpdateDatasourceJsonDataOption, updateDatasourcePluginJsonDataOption, } from '@grafana/data'; -import { ConnectionConfig } from '@grafana/aws-sdk'; - -import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; -import { store } from 'app/store/store'; +import { Input, InlineField } from '@grafana/ui'; import { notifyApp } from 'app/core/actions'; import { createWarningNotification } from 'app/core/copy/appNotification'; +import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; +import { store } from 'app/store/store'; -import { CloudWatchJsonData, CloudWatchSecureJsonData } from '../types'; import { CloudWatchDatasource } from '../datasource'; +import { CloudWatchJsonData, CloudWatchSecureJsonData } from '../types'; + import { XrayLinkConfig } from './XrayLinkConfig'; export type Props = DataSourcePluginOptionsEditorProps; diff --git a/public/app/plugins/datasource/cloudwatch/components/Dimensions/Dimensions.test.tsx b/public/app/plugins/datasource/cloudwatch/components/Dimensions/Dimensions.test.tsx index 7e38c356722..3cd88220ee6 100644 --- a/public/app/plugins/datasource/cloudwatch/components/Dimensions/Dimensions.test.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/Dimensions/Dimensions.test.tsx @@ -1,9 +1,10 @@ -import React from 'react'; import { fireEvent, render, screen, within } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import React from 'react'; + +import { Dimensions } from '..'; import { setupMockedDataSource } from '../../__mocks__/CloudWatchDataSource'; import { CloudWatchMetricsQuery } from '../../types'; -import userEvent from '@testing-library/user-event'; -import { Dimensions } from '..'; const ds = setupMockedDataSource({ variables: [], diff --git a/public/app/plugins/datasource/cloudwatch/components/Dimensions/Dimensions.tsx b/public/app/plugins/datasource/cloudwatch/components/Dimensions/Dimensions.tsx index baccc38d70e..a016b35ae83 100644 --- a/public/app/plugins/datasource/cloudwatch/components/Dimensions/Dimensions.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/Dimensions/Dimensions.tsx @@ -1,9 +1,12 @@ import { isEqual } from 'lodash'; import React, { useEffect, useState } from 'react'; + import { SelectableValue } from '@grafana/data'; import { EditorList } from '@grafana/experimental'; + import { CloudWatchDatasource } from '../../datasource'; import { Dimensions as DimensionsType, DimensionsQuery } from '../../types'; + import { FilterItem } from './FilterItem'; export interface Props { diff --git a/public/app/plugins/datasource/cloudwatch/components/Dimensions/FilterItem.tsx b/public/app/plugins/datasource/cloudwatch/components/Dimensions/FilterItem.tsx index 649d706f390..9ffc5847392 100644 --- a/public/app/plugins/datasource/cloudwatch/components/Dimensions/FilterItem.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/Dimensions/FilterItem.tsx @@ -1,12 +1,15 @@ -import React, { FunctionComponent, useMemo } from 'react'; import { css, cx } from '@emotion/css'; +import React, { FunctionComponent, useMemo } from 'react'; import { useAsyncFn } from 'react-use'; + import { GrafanaTheme2, SelectableValue, toOption } from '@grafana/data'; import { InputGroup, AccessoryButton } from '@grafana/experimental'; import { Select, stylesFactory, useTheme2 } from '@grafana/ui'; + import { CloudWatchDatasource } from '../../datasource'; import { Dimensions, DimensionsQuery } from '../../types'; import { appendTemplateVariables } from '../../utils/utils'; + import { DimensionFilterCondition } from './Dimensions'; export interface Props { diff --git a/public/app/plugins/datasource/cloudwatch/components/Forms.tsx b/public/app/plugins/datasource/cloudwatch/components/Forms.tsx index b7b4d36239e..6afcbf38960 100644 --- a/public/app/plugins/datasource/cloudwatch/components/Forms.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/Forms.tsx @@ -1,4 +1,5 @@ import React, { InputHTMLAttributes, FunctionComponent } from 'react'; + import { InlineFormLabel } from '@grafana/ui'; export interface Props extends InputHTMLAttributes { diff --git a/public/app/plugins/datasource/cloudwatch/components/LogsCheatSheet.tsx b/public/app/plugins/datasource/cloudwatch/components/LogsCheatSheet.tsx index b5d8261f435..87aa2ae1df7 100644 --- a/public/app/plugins/datasource/cloudwatch/components/LogsCheatSheet.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/LogsCheatSheet.tsx @@ -1,10 +1,12 @@ -import React, { PureComponent } from 'react'; -import { stripIndent, stripIndents } from 'common-tags'; -import { QueryEditorHelpProps } from '@grafana/data'; -import Prism from 'prismjs'; -import tokenizer from '../syntax'; -import { flattenTokens } from '@grafana/ui/src/slate-plugins/slate-prism'; import { css, cx } from '@emotion/css'; +import { stripIndent, stripIndents } from 'common-tags'; +import Prism from 'prismjs'; +import React, { PureComponent } from 'react'; + +import { QueryEditorHelpProps } from '@grafana/data'; +import { flattenTokens } from '@grafana/ui/src/slate-plugins/slate-prism'; + +import tokenizer from '../syntax'; import { CloudWatchQuery } from '../types'; interface QueryExample { diff --git a/public/app/plugins/datasource/cloudwatch/components/LogsQueryEditor.tsx b/public/app/plugins/datasource/cloudwatch/components/LogsQueryEditor.tsx index 8691e3ec8ed..00c24307ef9 100644 --- a/public/app/plugins/datasource/cloudwatch/components/LogsQueryEditor.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/LogsQueryEditor.tsx @@ -1,14 +1,16 @@ // Libraries +import { css } from '@emotion/css'; import React, { memo } from 'react'; // Types import { AbsoluteTimeRange, QueryEditorProps } from '@grafana/data'; import { InlineFormLabel } from '@grafana/ui'; + import { CloudWatchDatasource } from '../datasource'; import { CloudWatchJsonData, CloudWatchLogsQuery, CloudWatchQuery } from '../types'; -import { CloudWatchLogsQueryField } from './LogsQueryField'; + import CloudWatchLink from './CloudWatchLink'; -import { css } from '@emotion/css'; +import { CloudWatchLogsQueryField } from './LogsQueryField'; type Props = QueryEditorProps & { allowCustomValue?: boolean; diff --git a/public/app/plugins/datasource/cloudwatch/components/LogsQueryField.test.tsx b/public/app/plugins/datasource/cloudwatch/components/LogsQueryField.test.tsx index ef60536b5d5..0aed8959533 100644 --- a/public/app/plugins/datasource/cloudwatch/components/LogsQueryField.test.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/LogsQueryField.test.tsx @@ -1,14 +1,16 @@ -import React from 'react'; -import { shallow } from 'enzyme'; -import { CloudWatchLogsQueryField } from './LogsQueryField'; -import { ExploreId } from '../../../../types'; -import { DescribeLogGroupsRequest } from '../types'; -import { SelectableValue } from '@grafana/data'; -// eslint-disable-next-line lodash/import-scope -import _, { DebouncedFunc } from 'lodash'; import { render, screen, fireEvent } from '@testing-library/react'; +import { shallow } from 'enzyme'; +import _, { DebouncedFunc } from 'lodash'; // eslint-disable-line lodash/import-scope +import React from 'react'; import { act } from 'react-dom/test-utils'; + +import { SelectableValue } from '@grafana/data'; + +import { ExploreId } from '../../../../types'; import { setupMockedDataSource } from '../__mocks__/CloudWatchDataSource'; +import { DescribeLogGroupsRequest } from '../types'; + +import { CloudWatchLogsQueryField } from './LogsQueryField'; jest .spyOn(_, 'debounce') diff --git a/public/app/plugins/datasource/cloudwatch/components/LogsQueryField.tsx b/public/app/plugins/datasource/cloudwatch/components/LogsQueryField.tsx index 005e2aed266..050de9a2324 100644 --- a/public/app/plugins/datasource/cloudwatch/components/LogsQueryField.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/LogsQueryField.tsx @@ -1,7 +1,10 @@ -// Libraries -import React, { ReactNode } from 'react'; +import { css } from '@emotion/css'; import { intersectionBy, debounce, unionBy } from 'lodash'; +import { LanguageMap, languages as prismLanguages } from 'prismjs'; +import React, { ReactNode } from 'react'; +import { Editor, Node, Plugin } from 'slate'; +import { AbsoluteTimeRange, QueryEditorProps, SelectableValue } from '@grafana/data'; import { BracesPlugin, LegacyForms, @@ -11,25 +14,18 @@ import { TypeaheadInput, TypeaheadOutput, } from '@grafana/ui'; - -// Utils & Services -// dom also includes Element polyfills -import { Editor, Node, Plugin } from 'slate'; -import syntax from '../syntax'; - -// Types -import { AbsoluteTimeRange, QueryEditorProps, SelectableValue } from '@grafana/data'; -import { CloudWatchJsonData, CloudWatchLogsQuery, CloudWatchQuery } from '../types'; -import { CloudWatchDatasource } from '../datasource'; -import { LanguageMap, languages as prismLanguages } from 'prismjs'; -import { CloudWatchLanguageProvider } from '../language_provider'; -import { css } from '@emotion/css'; -import { ExploreId } from 'app/types'; -import { dispatch } from 'app/store/store'; +import { InputActionMeta } from '@grafana/ui/src/components/Select/types'; import { notifyApp } from 'app/core/actions'; import { createErrorNotification } from 'app/core/copy/appNotification'; -import { InputActionMeta } from '@grafana/ui/src/components/Select/types'; +import { dispatch } from 'app/store/store'; +import { ExploreId } from 'app/types'; + +import { CloudWatchDatasource } from '../datasource'; +import { CloudWatchLanguageProvider } from '../language_provider'; +import syntax from '../syntax'; +import { CloudWatchJsonData, CloudWatchLogsQuery, CloudWatchQuery } from '../types'; import { getStatsGroups } from '../utils/query/getStatsGroups'; + import QueryHeader from './QueryHeader'; export interface CloudWatchLogsQueryFieldProps diff --git a/public/app/plugins/datasource/cloudwatch/components/MathExpressionQueryField.tsx b/public/app/plugins/datasource/cloudwatch/components/MathExpressionQueryField.tsx index b8a42a2837d..b9e89f2daa1 100644 --- a/public/app/plugins/datasource/cloudwatch/components/MathExpressionQueryField.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/MathExpressionQueryField.tsx @@ -1,10 +1,12 @@ -import React, { useCallback, useRef } from 'react'; -import { CodeEditor, Monaco } from '@grafana/ui'; -import language from '../metric-math/definition'; -import { registerLanguage } from '../monarch/register'; import type * as monacoType from 'monaco-editor/esm/vs/editor/editor.api'; -import { TRIGGER_SUGGEST } from '../monarch/commands'; +import React, { useCallback, useRef } from 'react'; + +import { CodeEditor, Monaco } from '@grafana/ui'; + import { CloudWatchDatasource } from '../datasource'; +import language from '../metric-math/definition'; +import { TRIGGER_SUGGEST } from '../monarch/commands'; +import { registerLanguage } from '../monarch/register'; export interface Props { onChange: (query: string) => void; diff --git a/public/app/plugins/datasource/cloudwatch/components/MetaInspector.tsx b/public/app/plugins/datasource/cloudwatch/components/MetaInspector.tsx index 6259e651420..923e79c6118 100644 --- a/public/app/plugins/datasource/cloudwatch/components/MetaInspector.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/MetaInspector.tsx @@ -1,8 +1,10 @@ +import { groupBy } from 'lodash'; import React, { useMemo } from 'react'; + import { MetadataInspectorProps } from '@grafana/data'; + import { CloudWatchDatasource } from '../datasource'; import { CloudWatchQuery, CloudWatchJsonData } from '../types'; -import { groupBy } from 'lodash'; export type Props = MetadataInspectorProps; diff --git a/public/app/plugins/datasource/cloudwatch/components/MetricStatEditor/MetricStatEditor.test.tsx b/public/app/plugins/datasource/cloudwatch/components/MetricStatEditor/MetricStatEditor.test.tsx index 09b053731ae..9f6818fbaf4 100644 --- a/public/app/plugins/datasource/cloudwatch/components/MetricStatEditor/MetricStatEditor.test.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/MetricStatEditor/MetricStatEditor.test.tsx @@ -1,10 +1,11 @@ -import React from 'react'; import { fireEvent, render, screen, act, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import React from 'react'; import selectEvent from 'react-select-event'; + +import { MetricStatEditor } from '..'; import { setupMockedDataSource } from '../../__mocks__/CloudWatchDataSource'; import { CloudWatchMetricsQuery } from '../../types'; -import userEvent from '@testing-library/user-event'; -import { MetricStatEditor } from '..'; const ds = setupMockedDataSource({ variables: [], diff --git a/public/app/plugins/datasource/cloudwatch/components/MetricStatEditor/MetricStatEditor.tsx b/public/app/plugins/datasource/cloudwatch/components/MetricStatEditor/MetricStatEditor.tsx index 18260abdf0a..079b53d3010 100644 --- a/public/app/plugins/datasource/cloudwatch/components/MetricStatEditor/MetricStatEditor.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/MetricStatEditor/MetricStatEditor.tsx @@ -1,12 +1,14 @@ import React from 'react'; + +import { SelectableValue } from '@grafana/data'; import { EditorField, EditorFieldGroup, EditorRow, EditorRows } from '@grafana/experimental'; import { Select, Switch } from '@grafana/ui'; + import { Dimensions } from '..'; import { CloudWatchDatasource } from '../../datasource'; import { useDimensionKeys, useMetrics, useNamespaces } from '../../hooks'; import { CloudWatchMetricsQuery } from '../../types'; import { appendTemplateVariables, toOption } from '../../utils/utils'; -import { SelectableValue } from '@grafana/data'; export type Props = { query: CloudWatchMetricsQuery; diff --git a/public/app/plugins/datasource/cloudwatch/components/MetricsQueryEditor.test.tsx b/public/app/plugins/datasource/cloudwatch/components/MetricsQueryEditor.test.tsx index f05ee8835ec..73dd9d21e2b 100644 --- a/public/app/plugins/datasource/cloudwatch/components/MetricsQueryEditor.test.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/MetricsQueryEditor.test.tsx @@ -1,14 +1,17 @@ -import React from 'react'; -import renderer from 'react-test-renderer'; import { render, screen, act } from '@testing-library/react'; +import React from 'react'; import selectEvent from 'react-select-event'; +import renderer from 'react-test-renderer'; + import { DataSourceInstanceSettings } from '@grafana/data'; import { TemplateSrv } from 'app/features/templating/template_srv'; -import { MetricsQueryEditor, normalizeQuery, Props } from './MetricsQueryEditor'; -import { CloudWatchDatasource } from '../datasource'; + import { CustomVariableModel, initialVariableModelState } from '../../../../features/variables/types'; +import { CloudWatchDatasource } from '../datasource'; import { CloudWatchJsonData, MetricEditorMode, MetricQueryType } from '../types'; +import { MetricsQueryEditor, normalizeQuery, Props } from './MetricsQueryEditor'; + const setup = () => { const instanceSettings = { jsonData: { defaultRegion: 'us-east-1' }, diff --git a/public/app/plugins/datasource/cloudwatch/components/MetricsQueryEditor.tsx b/public/app/plugins/datasource/cloudwatch/components/MetricsQueryEditor.tsx index 556d35022ed..38f63c9b58f 100644 --- a/public/app/plugins/datasource/cloudwatch/components/MetricsQueryEditor.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/MetricsQueryEditor.tsx @@ -1,7 +1,9 @@ import React, { ChangeEvent, PureComponent } from 'react'; + import { QueryEditorProps } from '@grafana/data'; import { EditorField, EditorRow, Space } from '@grafana/experimental'; import { Input } from '@grafana/ui'; + import { CloudWatchDatasource } from '../datasource'; import { isMetricsQuery } from '../guards'; import { @@ -11,9 +13,11 @@ import { MetricEditorMode, MetricQueryType, } from '../types'; -import { Alias, MathExpressionQueryField, MetricStatEditor, SQLBuilderEditor, SQLCodeEditor } from './'; + import QueryHeader from './QueryHeader'; +import { Alias, MathExpressionQueryField, MetricStatEditor, SQLBuilderEditor, SQLCodeEditor } from './'; + export type Props = QueryEditorProps; interface State { diff --git a/public/app/plugins/datasource/cloudwatch/components/MetricsQueryHeader.test.tsx b/public/app/plugins/datasource/cloudwatch/components/MetricsQueryHeader.test.tsx index 14a5dfc9961..eaf5d1d616f 100644 --- a/public/app/plugins/datasource/cloudwatch/components/MetricsQueryHeader.test.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/MetricsQueryHeader.test.tsx @@ -1,8 +1,10 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; +import React from 'react'; import { act } from 'react-dom/test-utils'; -import { CloudWatchMetricsQuery, MetricEditorMode, MetricQueryType } from '../types'; + import { setupMockedDataSource } from '../__mocks__/CloudWatchDataSource'; +import { CloudWatchMetricsQuery, MetricEditorMode, MetricQueryType } from '../types'; + import MetricsQueryHeader from './MetricsQueryHeader'; const ds = setupMockedDataSource({ diff --git a/public/app/plugins/datasource/cloudwatch/components/MetricsQueryHeader.tsx b/public/app/plugins/datasource/cloudwatch/components/MetricsQueryHeader.tsx index 1523c7ad4b9..29c08845ce5 100644 --- a/public/app/plugins/datasource/cloudwatch/components/MetricsQueryHeader.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/MetricsQueryHeader.tsx @@ -1,8 +1,8 @@ import React, { useCallback, useState } from 'react'; import { SelectableValue } from '@grafana/data'; -import { Button, ConfirmModal, RadioButtonGroup } from '@grafana/ui'; import { InlineSelect, FlexItem } from '@grafana/experimental'; +import { Button, ConfirmModal, RadioButtonGroup } from '@grafana/ui'; import { CloudWatchDatasource } from '../datasource'; import { CloudWatchMetricsQuery, CloudWatchQuery, MetricEditorMode, MetricQueryType } from '../types'; diff --git a/public/app/plugins/datasource/cloudwatch/components/PanelQueryEditor.tsx b/public/app/plugins/datasource/cloudwatch/components/PanelQueryEditor.tsx index 811f342f18d..3c9938b98df 100644 --- a/public/app/plugins/datasource/cloudwatch/components/PanelQueryEditor.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/PanelQueryEditor.tsx @@ -1,9 +1,12 @@ import React, { PureComponent } from 'react'; + import { QueryEditorProps, ExploreMode } from '@grafana/data'; -import { CloudWatchJsonData, CloudWatchQuery } from '../types'; + import { CloudWatchDatasource } from '../datasource'; -import { MetricsQueryEditor } from './MetricsQueryEditor'; +import { CloudWatchJsonData, CloudWatchQuery } from '../types'; + import LogsQueryEditor from './LogsQueryEditor'; +import { MetricsQueryEditor } from './MetricsQueryEditor'; export type Props = QueryEditorProps; diff --git a/public/app/plugins/datasource/cloudwatch/components/QueryHeader.test.tsx b/public/app/plugins/datasource/cloudwatch/components/QueryHeader.test.tsx index 7809e45c614..220d1ad669b 100644 --- a/public/app/plugins/datasource/cloudwatch/components/QueryHeader.test.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/QueryHeader.test.tsx @@ -1,7 +1,9 @@ -import React from 'react'; import { render, screen, waitFor, act } from '@testing-library/react'; -import { CloudWatchLogsQuery, CloudWatchMetricsQuery, MetricEditorMode, MetricQueryType } from '../types'; +import React from 'react'; + import { setupMockedDataSource } from '../__mocks__/CloudWatchDataSource'; +import { CloudWatchLogsQuery, CloudWatchMetricsQuery, MetricEditorMode, MetricQueryType } from '../types'; + import QueryHeader from './QueryHeader'; const ds = setupMockedDataSource({ diff --git a/public/app/plugins/datasource/cloudwatch/components/QueryHeader.tsx b/public/app/plugins/datasource/cloudwatch/components/QueryHeader.tsx index 268abb355e1..ed7b475311f 100644 --- a/public/app/plugins/datasource/cloudwatch/components/QueryHeader.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/QueryHeader.tsx @@ -1,11 +1,13 @@ -import { ExploreMode, SelectableValue } from '@grafana/data'; -import { EditorHeader, InlineSelect } from '@grafana/experimental'; import { pick } from 'lodash'; import React from 'react'; +import { ExploreMode, SelectableValue } from '@grafana/data'; +import { EditorHeader, InlineSelect } from '@grafana/experimental'; + import { CloudWatchDatasource } from '../datasource'; import { useRegions } from '../hooks'; import { CloudWatchQuery, CloudWatchQueryMode } from '../types'; + import MetricsQueryHeader from './MetricsQueryHeader'; interface QueryHeaderProps { diff --git a/public/app/plugins/datasource/cloudwatch/components/SQLBuilderEditor/SQLBuilderEditor.test.tsx b/public/app/plugins/datasource/cloudwatch/components/SQLBuilderEditor/SQLBuilderEditor.test.tsx index 785d4f3925d..24296da0c21 100644 --- a/public/app/plugins/datasource/cloudwatch/components/SQLBuilderEditor/SQLBuilderEditor.test.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/SQLBuilderEditor/SQLBuilderEditor.test.tsx @@ -1,9 +1,10 @@ -import React from 'react'; -import { SQLBuilderEditor } from '..'; import { render, screen, waitFor } from '@testing-library/react'; -import { CloudWatchMetricsQuery, MetricEditorMode, MetricQueryType, SQLExpression } from '../../types'; +import React from 'react'; + +import { SQLBuilderEditor } from '..'; import { setupMockedDataSource } from '../../__mocks__/CloudWatchDataSource'; import { QueryEditorExpressionType, QueryEditorPropertyType } from '../../expressions'; +import { CloudWatchMetricsQuery, MetricEditorMode, MetricQueryType, SQLExpression } from '../../types'; const { datasource } = setupMockedDataSource(); diff --git a/public/app/plugins/datasource/cloudwatch/components/SQLBuilderEditor/SQLBuilderEditor.tsx b/public/app/plugins/datasource/cloudwatch/components/SQLBuilderEditor/SQLBuilderEditor.tsx index 9b7aaf204e5..174fdbb5a6c 100644 --- a/public/app/plugins/datasource/cloudwatch/components/SQLBuilderEditor/SQLBuilderEditor.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/SQLBuilderEditor/SQLBuilderEditor.tsx @@ -1,9 +1,12 @@ import React, { useCallback, useEffect, useState } from 'react'; + import { EditorField, EditorRow, EditorRows } from '@grafana/experimental'; import { Input } from '@grafana/ui'; + import SQLGenerator from '../../cloudwatch-sql/SQLGenerator'; import { CloudWatchDatasource } from '../../datasource'; import { CloudWatchMetricsQuery } from '../../types'; + import SQLBuilderSelectRow from './SQLBuilderSelectRow'; import SQLFilter from './SQLFilter'; import SQLGroupBy from './SQLGroupBy'; diff --git a/public/app/plugins/datasource/cloudwatch/components/SQLBuilderEditor/SQLBuilderSelectRow.test.tsx b/public/app/plugins/datasource/cloudwatch/components/SQLBuilderEditor/SQLBuilderSelectRow.test.tsx index 55dac72aa8d..e8948a5be53 100644 --- a/public/app/plugins/datasource/cloudwatch/components/SQLBuilderEditor/SQLBuilderSelectRow.test.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/SQLBuilderEditor/SQLBuilderSelectRow.test.tsx @@ -1,9 +1,12 @@ -import React from 'react'; -import { selectOptionInTest } from '@grafana/ui'; import { act, render, screen } from '@testing-library/react'; -import { CloudWatchMetricsQuery, MetricEditorMode, MetricQueryType, SQLExpression } from '../../types'; +import React from 'react'; + +import { selectOptionInTest } from '@grafana/ui'; + import { setupMockedDataSource } from '../../__mocks__/CloudWatchDataSource'; import { QueryEditorExpressionType, QueryEditorPropertyType } from '../../expressions'; +import { CloudWatchMetricsQuery, MetricEditorMode, MetricQueryType, SQLExpression } from '../../types'; + import SQLBuilderSelectRow from './SQLBuilderSelectRow'; const { datasource } = setupMockedDataSource(); diff --git a/public/app/plugins/datasource/cloudwatch/components/SQLBuilderEditor/SQLBuilderSelectRow.tsx b/public/app/plugins/datasource/cloudwatch/components/SQLBuilderEditor/SQLBuilderSelectRow.tsx index 1c49d73aba0..4caa43aa03d 100644 --- a/public/app/plugins/datasource/cloudwatch/components/SQLBuilderEditor/SQLBuilderSelectRow.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/SQLBuilderEditor/SQLBuilderSelectRow.tsx @@ -1,12 +1,15 @@ import React, { useEffect, useMemo } from 'react'; + import { SelectableValue, toOption } from '@grafana/data'; import { EditorField, EditorFieldGroup } from '@grafana/experimental'; import { Select, Switch } from '@grafana/ui'; + import { STATISTICS } from '../../cloudwatch-sql/language'; import { CloudWatchDatasource } from '../../datasource'; import { useDimensionKeys, useMetrics, useNamespaces } from '../../hooks'; import { CloudWatchMetricsQuery } from '../../types'; import { appendTemplateVariables } from '../../utils/utils'; + import { getMetricNameFromExpression, getNamespaceFromExpression, diff --git a/public/app/plugins/datasource/cloudwatch/components/SQLBuilderEditor/SQLFilter.tsx b/public/app/plugins/datasource/cloudwatch/components/SQLBuilderEditor/SQLFilter.tsx index a87f16155f9..d42f7e98079 100644 --- a/public/app/plugins/datasource/cloudwatch/components/SQLBuilderEditor/SQLFilter.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/SQLBuilderEditor/SQLFilter.tsx @@ -1,14 +1,17 @@ import React, { useMemo, useState } from 'react'; import { useAsyncFn } from 'react-use'; + import { SelectableValue, toOption } from '@grafana/data'; import { AccessoryButton, EditorList, InputGroup } from '@grafana/experimental'; import { Select } from '@grafana/ui'; + import { COMPARISON_OPERATORS, EQUALS } from '../../cloudwatch-sql/language'; import { CloudWatchDatasource } from '../../datasource'; import { QueryEditorExpressionType, QueryEditorOperatorExpression, QueryEditorPropertyType } from '../../expressions'; import { useDimensionKeys } from '../../hooks'; import { CloudWatchMetricsQuery } from '../../types'; import { appendTemplateVariables } from '../../utils/utils'; + import { getFlattenedFilters, getMetricNameFromExpression, diff --git a/public/app/plugins/datasource/cloudwatch/components/SQLBuilderEditor/SQLGroupBy.test.tsx b/public/app/plugins/datasource/cloudwatch/components/SQLBuilderEditor/SQLGroupBy.test.tsx index b68113c586f..c3eb94fa6c1 100644 --- a/public/app/plugins/datasource/cloudwatch/components/SQLBuilderEditor/SQLGroupBy.test.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/SQLBuilderEditor/SQLGroupBy.test.tsx @@ -1,9 +1,11 @@ -import React from 'react'; import { render, screen, waitFor } from '@testing-library/react'; +import React from 'react'; import selectEvent from 'react-select-event'; -import { CloudWatchMetricsQuery, MetricEditorMode, MetricQueryType, SQLExpression } from '../../types'; + import { setupMockedDataSource } from '../../__mocks__/CloudWatchDataSource'; import { createArray, createGroupBy } from '../../__mocks__/sqlUtils'; +import { CloudWatchMetricsQuery, MetricEditorMode, MetricQueryType, SQLExpression } from '../../types'; + import SQLGroupBy from './SQLGroupBy'; const { datasource } = setupMockedDataSource(); diff --git a/public/app/plugins/datasource/cloudwatch/components/SQLBuilderEditor/SQLGroupBy.tsx b/public/app/plugins/datasource/cloudwatch/components/SQLBuilderEditor/SQLGroupBy.tsx index f7634236e8d..5a1c00d9bb4 100644 --- a/public/app/plugins/datasource/cloudwatch/components/SQLBuilderEditor/SQLGroupBy.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/SQLBuilderEditor/SQLGroupBy.tsx @@ -1,11 +1,14 @@ import React, { useMemo, useState } from 'react'; + import { SelectableValue, toOption } from '@grafana/data'; import { AccessoryButton, EditorList, InputGroup } from '@grafana/experimental'; import { Select } from '@grafana/ui'; + import { CloudWatchDatasource } from '../../datasource'; import { QueryEditorExpressionType, QueryEditorGroupByExpression, QueryEditorPropertyType } from '../../expressions'; import { useDimensionKeys } from '../../hooks'; import { CloudWatchMetricsQuery } from '../../types'; + import { getFlattenedGroupBys, getMetricNameFromExpression, diff --git a/public/app/plugins/datasource/cloudwatch/components/SQLBuilderEditor/SQLOrderByGroup.tsx b/public/app/plugins/datasource/cloudwatch/components/SQLBuilderEditor/SQLOrderByGroup.tsx index d516d68d59e..67d24c6811d 100644 --- a/public/app/plugins/datasource/cloudwatch/components/SQLBuilderEditor/SQLOrderByGroup.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/SQLBuilderEditor/SQLOrderByGroup.tsx @@ -1,11 +1,14 @@ import React from 'react'; + import { SelectableValue, toOption } from '@grafana/data'; import { AccessoryButton, EditorField, EditorFieldGroup } from '@grafana/experimental'; import { Select } from '@grafana/ui'; + import { ASC, DESC, STATISTICS } from '../../cloudwatch-sql/language'; import { CloudWatchDatasource } from '../../datasource'; import { CloudWatchMetricsQuery } from '../../types'; import { appendTemplateVariables } from '../../utils/utils'; + import { setOrderBy, setSql } from './utils'; interface SQLBuilderSelectRowProps { diff --git a/public/app/plugins/datasource/cloudwatch/components/SQLBuilderEditor/utils.ts b/public/app/plugins/datasource/cloudwatch/components/SQLBuilderEditor/utils.ts index a0b28ca62f4..9c474543fa0 100644 --- a/public/app/plugins/datasource/cloudwatch/components/SQLBuilderEditor/utils.ts +++ b/public/app/plugins/datasource/cloudwatch/components/SQLBuilderEditor/utils.ts @@ -1,4 +1,3 @@ -import { SelectableValue } from './../../../../../../../packages/grafana-data/src/types/select'; import { SCHEMA } from '../../cloudwatch-sql/language'; import { QueryEditorExpressionType, @@ -10,6 +9,8 @@ import { } from '../../expressions'; import { SQLExpression, CloudWatchMetricsQuery, Dimensions } from '../../types'; +import { SelectableValue } from './../../../../../../../packages/grafana-data/src/types/select'; + export function getMetricNameFromExpression(selectExpression: SQLExpression['select']): string | undefined { return selectExpression?.parameters?.[0].name; } diff --git a/public/app/plugins/datasource/cloudwatch/components/SQLCodeEditor.tsx b/public/app/plugins/datasource/cloudwatch/components/SQLCodeEditor.tsx index 65bb944ec70..03ca4b998fc 100644 --- a/public/app/plugins/datasource/cloudwatch/components/SQLCodeEditor.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/SQLCodeEditor.tsx @@ -1,8 +1,10 @@ -import React, { FunctionComponent, useCallback, useEffect } from 'react'; import type * as monacoType from 'monaco-editor/esm/vs/editor/editor.api'; +import React, { FunctionComponent, useCallback, useEffect } from 'react'; + import { CodeEditor, Monaco } from '@grafana/ui'; -import { CloudWatchDatasource } from '../datasource'; + import language from '../cloudwatch-sql/definition'; +import { CloudWatchDatasource } from '../datasource'; import { TRIGGER_SUGGEST } from '../monarch/commands'; import { registerLanguage } from '../monarch/register'; diff --git a/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableQueryEditor.test.tsx b/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableQueryEditor.test.tsx index 942bf5e7a83..fffb71a724a 100644 --- a/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableQueryEditor.test.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableQueryEditor.test.tsx @@ -1,8 +1,10 @@ import { render, screen, waitFor, within } from '@testing-library/react'; import React from 'react'; import { select } from 'react-select-event'; -import { Dimensions, VariableQueryType } from '../../types'; + import { setupMockedDataSource } from '../../__mocks__/CloudWatchDataSource'; +import { Dimensions, VariableQueryType } from '../../types'; + import { VariableQueryEditor, Props } from './VariableQueryEditor'; const defaultQuery = { diff --git a/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableQueryEditor.tsx b/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableQueryEditor.tsx index c95173f860a..62aca6bac92 100644 --- a/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableQueryEditor.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableQueryEditor.tsx @@ -1,14 +1,16 @@ import React from 'react'; import { QueryEditorProps, SelectableValue } from '@grafana/data'; -import { VariableTextField } from './VariableTextField'; +import { InlineField } from '@grafana/ui'; + +import { Dimensions } from '..'; import { CloudWatchDatasource } from '../../datasource'; import { useDimensionKeys, useMetrics, useNamespaces, useRegions } from '../../hooks'; -import { CloudWatchJsonData, CloudWatchQuery, VariableQuery, VariableQueryType } from '../../types'; import { migrateVariableQuery } from '../../migrations'; +import { CloudWatchJsonData, CloudWatchQuery, VariableQuery, VariableQueryType } from '../../types'; + import { VariableQueryField } from './VariableQueryField'; -import { Dimensions } from '..'; -import { InlineField } from '@grafana/ui'; +import { VariableTextField } from './VariableTextField'; export type Props = QueryEditorProps; diff --git a/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableQueryField.tsx b/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableQueryField.tsx index 890f00ba2c0..53a32f5db91 100644 --- a/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableQueryField.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableQueryField.tsx @@ -1,6 +1,8 @@ +import React from 'react'; + import { SelectableValue } from '@grafana/data'; import { InlineField, Select } from '@grafana/ui'; -import React from 'react'; + import { VariableQueryType } from '../../types'; const LABEL_WIDTH = 20; diff --git a/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableTextField.tsx b/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableTextField.tsx index 7a8ec664de3..2e095bb4f00 100644 --- a/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableTextField.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/VariableQueryEditor/VariableTextField.tsx @@ -1,6 +1,7 @@ -import { InlineField, Input } from '@grafana/ui'; import React, { FC, useState } from 'react'; +import { InlineField, Input } from '@grafana/ui'; + const LABEL_WIDTH = 20; interface VariableTextFieldProps { diff --git a/public/app/plugins/datasource/cloudwatch/components/XrayLinkConfig.tsx b/public/app/plugins/datasource/cloudwatch/components/XrayLinkConfig.tsx index 16789f12cb5..9efd3c75164 100644 --- a/public/app/plugins/datasource/cloudwatch/components/XrayLinkConfig.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/XrayLinkConfig.tsx @@ -1,10 +1,10 @@ -import React from 'react'; import { css } from '@emotion/css'; -import { Alert, InlineField, useStyles2 } from '@grafana/ui'; -import { GrafanaTheme2 } from '@grafana/data'; +import React from 'react'; -import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; +import { GrafanaTheme2 } from '@grafana/data'; import { DataSourcePicker } from '@grafana/runtime'; +import { Alert, InlineField, useStyles2 } from '@grafana/ui'; +import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; const getStyles = (theme: GrafanaTheme2) => ({ infoText: css` diff --git a/public/app/plugins/datasource/cloudwatch/datasource.test.ts b/public/app/plugins/datasource/cloudwatch/datasource.test.ts index 5a06bce1476..c4baf75a911 100644 --- a/public/app/plugins/datasource/cloudwatch/datasource.test.ts +++ b/public/app/plugins/datasource/cloudwatch/datasource.test.ts @@ -1,8 +1,9 @@ -import { ArrayVector, DataFrame, dataFrameToJSON, dateTime, Field, MutableDataFrame } from '@grafana/data'; -import { setDataSourceSrv } from '@grafana/runtime'; import { lastValueFrom, of } from 'rxjs'; import { toArray } from 'rxjs/operators'; +import { ArrayVector, DataFrame, dataFrameToJSON, dateTime, Field, MutableDataFrame } from '@grafana/data'; +import { setDataSourceSrv } from '@grafana/runtime'; + import { labelsVariable, limitVariable, diff --git a/public/app/plugins/datasource/cloudwatch/datasource.ts b/public/app/plugins/datasource/cloudwatch/datasource.ts index 059377a8c17..6d7cdebe903 100644 --- a/public/app/plugins/datasource/cloudwatch/datasource.ts +++ b/public/app/plugins/datasource/cloudwatch/datasource.ts @@ -1,3 +1,8 @@ +import { cloneDeep, find, findLast, isEmpty, isString, set } from 'lodash'; +import React from 'react'; +import { from, lastValueFrom, merge, Observable, of, throwError, zip } from 'rxjs'; +import { catchError, concatMap, finalize, map, mergeMap, repeat, scan, share, takeWhile, tap } from 'rxjs/operators'; + import { DataFrame, DataQueryError, @@ -25,10 +30,6 @@ import { getTemplateSrv, TemplateSrv } from 'app/features/templating/template_sr import { VariableWithMultiSupport } from 'app/features/variables/types'; import { store } from 'app/store/store'; import { AppNotificationTimeout } from 'app/types'; -import { cloneDeep, find, findLast, isEmpty, isString, set } from 'lodash'; -import React from 'react'; -import { from, lastValueFrom, merge, Observable, of, throwError, zip } from 'rxjs'; -import { catchError, concatMap, finalize, map, mergeMap, repeat, scan, share, takeWhile, tap } from 'rxjs/operators'; import { SQLCompletionItemProvider } from './cloudwatch-sql/completion/CompletionItemProvider'; import { ThrottlingErrorMessage } from './components/ThrottlingErrorMessage'; diff --git a/public/app/plugins/datasource/cloudwatch/hooks.ts b/public/app/plugins/datasource/cloudwatch/hooks.ts index ee8a8ea63ab..0ee791f7dfa 100644 --- a/public/app/plugins/datasource/cloudwatch/hooks.ts +++ b/public/app/plugins/datasource/cloudwatch/hooks.ts @@ -1,10 +1,12 @@ import { useEffect, useState } from 'react'; -import { SelectableValue, toOption } from '@grafana/data'; -import { appendTemplateVariables } from './utils/utils'; -import { Dimensions } from './types'; -import { CloudWatchDatasource } from './datasource'; import { useDeepCompareEffect } from 'react-use'; +import { SelectableValue, toOption } from '@grafana/data'; + +import { CloudWatchDatasource } from './datasource'; +import { Dimensions } from './types'; +import { appendTemplateVariables } from './utils/utils'; + export const useRegions = (datasource: CloudWatchDatasource): [Array>, boolean] => { const [regionsIsLoading, setRegionsIsLoading] = useState(false); const [regions, setRegions] = useState>>([{ label: 'default', value: 'default' }]); diff --git a/public/app/plugins/datasource/cloudwatch/language_provider.test.ts b/public/app/plugins/datasource/cloudwatch/language_provider.test.ts index 38743252743..f69ad66c303 100644 --- a/public/app/plugins/datasource/cloudwatch/language_provider.test.ts +++ b/public/app/plugins/datasource/cloudwatch/language_provider.test.ts @@ -1,9 +1,10 @@ -import { Value } from 'slate'; -import { TypeaheadOutput } from '@grafana/ui'; -import { CloudWatchDatasource } from './datasource'; -import { GetLogGroupFieldsResponse } from './types'; -import { CloudWatchLanguageProvider } from './language_provider'; import Prism, { Token } from 'prismjs'; +import { Value } from 'slate'; + +import { TypeaheadOutput } from '@grafana/ui'; + +import { CloudWatchDatasource } from './datasource'; +import { CloudWatchLanguageProvider } from './language_provider'; import { AGGREGATION_FUNCTIONS_STATS, BOOLEAN_FUNCTIONS, @@ -14,6 +15,7 @@ import { STRING_FUNCTIONS, FIELD_AND_FILTER_FUNCTIONS, } from './syntax'; +import { GetLogGroupFieldsResponse } from './types'; const fields = ['field1', '@message']; diff --git a/public/app/plugins/datasource/cloudwatch/language_provider.ts b/public/app/plugins/datasource/cloudwatch/language_provider.ts index 24ec295638c..75848971262 100644 --- a/public/app/plugins/datasource/cloudwatch/language_provider.ts +++ b/public/app/plugins/datasource/cloudwatch/language_provider.ts @@ -1,9 +1,11 @@ import { sortedUniq } from 'lodash'; -import { lastValueFrom } from 'rxjs'; import Prism, { Grammar } from 'prismjs'; +import { lastValueFrom } from 'rxjs'; + import { AbsoluteTimeRange, HistoryItem, LanguageProvider } from '@grafana/data'; import { CompletionItemGroup, SearchFunctionType, Token, TypeaheadInput, TypeaheadOutput } from '@grafana/ui'; +import { CloudWatchDatasource } from './datasource'; import syntax, { AGGREGATION_FUNCTIONS_STATS, BOOLEAN_FUNCTIONS, @@ -15,7 +17,6 @@ import syntax, { STRING_FUNCTIONS, } from './syntax'; import { CloudWatchQuery, TSDBResponse } from './types'; -import { CloudWatchDatasource } from './datasource'; export type CloudWatchHistoryItem = HistoryItem; diff --git a/public/app/plugins/datasource/cloudwatch/metric-math/completion/CompletionItemProvider.test.ts b/public/app/plugins/datasource/cloudwatch/metric-math/completion/CompletionItemProvider.test.ts index 9495b07c24d..19c8873cb70 100644 --- a/public/app/plugins/datasource/cloudwatch/metric-math/completion/CompletionItemProvider.test.ts +++ b/public/app/plugins/datasource/cloudwatch/metric-math/completion/CompletionItemProvider.test.ts @@ -1,10 +1,11 @@ +import { getTemplateSrv } from '@grafana/runtime'; +import { Monaco, monacoTypes } from '@grafana/ui'; + +import * as MetricMathTestData from '../../__mocks__/metric-math-test-data'; import MonacoMock from '../../__mocks__/monarch/Monaco'; import TextModel from '../../__mocks__/monarch/TextModel'; -import { MetricMathCompletionItemProvider } from './CompletionItemProvider'; -import { getTemplateSrv } from '@grafana/runtime'; import { CloudWatchDatasource } from '../../datasource'; import cloudWatchMetricMathLanguageDefinition from '../definition'; -import { Monaco, monacoTypes } from '@grafana/ui'; import { METRIC_MATH_FNS, METRIC_MATH_KEYWORDS, @@ -12,7 +13,8 @@ import { METRIC_MATH_PERIODS, METRIC_MATH_STATISTIC_KEYWORD_STRINGS, } from '../language'; -import * as MetricMathTestData from '../../__mocks__/metric-math-test-data'; + +import { MetricMathCompletionItemProvider } from './CompletionItemProvider'; const getSuggestions = async (value: string, position: monacoTypes.IPosition) => { const setup = new MetricMathCompletionItemProvider( diff --git a/public/app/plugins/datasource/cloudwatch/metric-math/completion/CompletionItemProvider.ts b/public/app/plugins/datasource/cloudwatch/metric-math/completion/CompletionItemProvider.ts index 20b86ff0f16..f8feb524b8f 100644 --- a/public/app/plugins/datasource/cloudwatch/metric-math/completion/CompletionItemProvider.ts +++ b/public/app/plugins/datasource/cloudwatch/metric-math/completion/CompletionItemProvider.ts @@ -1,7 +1,11 @@ +import { getTemplateSrv, TemplateSrv } from '@grafana/runtime'; import type { Monaco, monacoTypes } from '@grafana/ui'; + +import { CloudWatchDatasource } from '../../datasource'; +import { CompletionItemProvider } from '../../monarch/CompletionItemProvider'; +import { LinkedToken } from '../../monarch/LinkedToken'; import { TRIGGER_SUGGEST } from '../../monarch/commands'; import { SuggestionKind, CompletionItemPriority, StatementPosition } from '../../monarch/types'; -import { LinkedToken } from '../../monarch/LinkedToken'; import { METRIC_MATH_FNS, METRIC_MATH_KEYWORDS, @@ -9,12 +13,10 @@ import { METRIC_MATH_PERIODS, METRIC_MATH_STATISTIC_KEYWORD_STRINGS, } from '../language'; -import { CompletionItemProvider } from '../../monarch/CompletionItemProvider'; -import { MetricMathTokenTypes } from './types'; -import { CloudWatchDatasource } from '../../datasource'; -import { getTemplateSrv, TemplateSrv } from '@grafana/runtime'; + import { getStatementPosition } from './statementPosition'; import { getSuggestionKinds } from './suggestionKind'; +import { MetricMathTokenTypes } from './types'; type CompletionItem = monacoTypes.languages.CompletionItem; diff --git a/public/app/plugins/datasource/cloudwatch/metric-math/completion/statementPosition.test.ts b/public/app/plugins/datasource/cloudwatch/metric-math/completion/statementPosition.test.ts index a4b32712015..ab7aa911e86 100644 --- a/public/app/plugins/datasource/cloudwatch/metric-math/completion/statementPosition.test.ts +++ b/public/app/plugins/datasource/cloudwatch/metric-math/completion/statementPosition.test.ts @@ -1,11 +1,13 @@ import { monacoTypes } from '@grafana/ui'; + +import * as MetricMathTestQueries from '../../__mocks__/metric-math-test-data'; import MonacoMock from '../../__mocks__/monarch/Monaco'; import TextModel from '../../__mocks__/monarch/TextModel'; -import * as MetricMathTestQueries from '../../__mocks__/metric-math-test-data'; import { linkedTokenBuilder } from '../../monarch/linkedTokenBuilder'; import { StatementPosition } from '../../monarch/types'; -import { getStatementPosition } from './statementPosition'; import cloudWatchSqlLanguageDefinition from '../definition'; + +import { getStatementPosition } from './statementPosition'; import { MetricMathTokenTypes } from './types'; describe('statementPosition', () => { diff --git a/public/app/plugins/datasource/cloudwatch/metric-math/completion/statementPosition.ts b/public/app/plugins/datasource/cloudwatch/metric-math/completion/statementPosition.ts index 2e86bb446e4..099186363e8 100644 --- a/public/app/plugins/datasource/cloudwatch/metric-math/completion/statementPosition.ts +++ b/public/app/plugins/datasource/cloudwatch/metric-math/completion/statementPosition.ts @@ -1,5 +1,6 @@ import { LinkedToken } from '../../monarch/LinkedToken'; import { StatementPosition } from '../../monarch/types'; + import { MetricMathTokenTypes } from './types'; export function getStatementPosition(currentToken: LinkedToken | null): StatementPosition { diff --git a/public/app/plugins/datasource/cloudwatch/migration.test.ts b/public/app/plugins/datasource/cloudwatch/migration.test.ts index 7f92bc72411..4745efa9151 100644 --- a/public/app/plugins/datasource/cloudwatch/migration.test.ts +++ b/public/app/plugins/datasource/cloudwatch/migration.test.ts @@ -1,4 +1,5 @@ import { DataQuery } from '@grafana/data'; + import { migrateMultipleStatsAnnotationQuery, migrateMultipleStatsMetricsQuery, diff --git a/public/app/plugins/datasource/cloudwatch/migrations.ts b/public/app/plugins/datasource/cloudwatch/migrations.ts index 5bac7b8f45f..d03cd7661ec 100644 --- a/public/app/plugins/datasource/cloudwatch/migrations.ts +++ b/public/app/plugins/datasource/cloudwatch/migrations.ts @@ -1,5 +1,6 @@ import { AnnotationQuery, DataQuery } from '@grafana/data'; import { getNextRefIdChar } from 'app/core/utils/query'; + import { MetricEditorMode, CloudWatchAnnotationQuery, diff --git a/public/app/plugins/datasource/cloudwatch/module.tsx b/public/app/plugins/datasource/cloudwatch/module.tsx index 4309c2e307f..2cd9a287e5f 100644 --- a/public/app/plugins/datasource/cloudwatch/module.tsx +++ b/public/app/plugins/datasource/cloudwatch/module.tsx @@ -1,12 +1,13 @@ import { DataSourcePlugin } from '@grafana/data'; -import { ConfigEditor } from './components/ConfigEditor'; -import { CloudWatchDatasource } from './datasource'; + import { CloudWatchAnnotationsQueryCtrl } from './annotations_query_ctrl'; -import { CloudWatchJsonData, CloudWatchQuery } from './types'; -import { CloudWatchLogsQueryEditor } from './components/LogsQueryEditor'; -import { PanelQueryEditor } from './components/PanelQueryEditor'; -import { MetaInspector } from './components/MetaInspector'; +import { ConfigEditor } from './components/ConfigEditor'; import LogsCheatSheet from './components/LogsCheatSheet'; +import { CloudWatchLogsQueryEditor } from './components/LogsQueryEditor'; +import { MetaInspector } from './components/MetaInspector'; +import { PanelQueryEditor } from './components/PanelQueryEditor'; +import { CloudWatchDatasource } from './datasource'; +import { CloudWatchJsonData, CloudWatchQuery } from './types'; export const plugin = new DataSourcePlugin( CloudWatchDatasource diff --git a/public/app/plugins/datasource/cloudwatch/monarch/CompletionItemProvider.ts b/public/app/plugins/datasource/cloudwatch/monarch/CompletionItemProvider.ts index 06404442925..cf2d1dfed30 100644 --- a/public/app/plugins/datasource/cloudwatch/monarch/CompletionItemProvider.ts +++ b/public/app/plugins/datasource/cloudwatch/monarch/CompletionItemProvider.ts @@ -1,9 +1,10 @@ -import type { Monaco, monacoTypes } from '@grafana/ui'; import { getTemplateSrv, TemplateSrv } from '@grafana/runtime'; +import type { Monaco, monacoTypes } from '@grafana/ui'; + import { CloudWatchDatasource } from '../datasource'; -import { linkedTokenBuilder } from './linkedTokenBuilder'; import { LinkedToken } from './LinkedToken'; +import { linkedTokenBuilder } from './linkedTokenBuilder'; import { LanguageDefinition } from './register'; import { StatementPosition, SuggestionKind, TokenTypes } from './types'; diff --git a/public/app/plugins/datasource/cloudwatch/monarch/LinkedToken.ts b/public/app/plugins/datasource/cloudwatch/monarch/LinkedToken.ts index 227057efecf..86e8a11168c 100644 --- a/public/app/plugins/datasource/cloudwatch/monarch/LinkedToken.ts +++ b/public/app/plugins/datasource/cloudwatch/monarch/LinkedToken.ts @@ -1,4 +1,5 @@ import { monacoTypes } from '@grafana/ui'; + import { TokenTypes } from './types'; export class LinkedToken { diff --git a/public/app/plugins/datasource/cloudwatch/monarch/linkedTokenBuilder.test.ts b/public/app/plugins/datasource/cloudwatch/monarch/linkedTokenBuilder.test.ts index 89907a66e85..3025302bb05 100644 --- a/public/app/plugins/datasource/cloudwatch/monarch/linkedTokenBuilder.test.ts +++ b/public/app/plugins/datasource/cloudwatch/monarch/linkedTokenBuilder.test.ts @@ -1,11 +1,13 @@ import { monacoTypes } from '@grafana/ui'; + +import { multiLineFullQuery, singleLineFullQuery } from '../__mocks__/cloudwatch-sql-test-data'; import MonacoMock from '../__mocks__/monarch/Monaco'; import TextModel from '../__mocks__/monarch/TextModel'; -import { multiLineFullQuery, singleLineFullQuery } from '../__mocks__/cloudwatch-sql-test-data'; -import { linkedTokenBuilder } from './linkedTokenBuilder'; -import { DESC, SELECT } from '../cloudwatch-sql/language'; -import cloudWatchSqlLanguageDefinition from '../cloudwatch-sql/definition'; import { SQLTokenTypes } from '../cloudwatch-sql/completion/types'; +import cloudWatchSqlLanguageDefinition from '../cloudwatch-sql/definition'; +import { DESC, SELECT } from '../cloudwatch-sql/language'; + +import { linkedTokenBuilder } from './linkedTokenBuilder'; describe('linkedTokenBuilder', () => { describe('singleLineFullQuery', () => { diff --git a/public/app/plugins/datasource/cloudwatch/monarch/linkedTokenBuilder.ts b/public/app/plugins/datasource/cloudwatch/monarch/linkedTokenBuilder.ts index f43002fcb1f..e468752c426 100644 --- a/public/app/plugins/datasource/cloudwatch/monarch/linkedTokenBuilder.ts +++ b/public/app/plugins/datasource/cloudwatch/monarch/linkedTokenBuilder.ts @@ -1,8 +1,8 @@ import type { monacoTypes } from '@grafana/ui'; import { LinkedToken } from './LinkedToken'; -import { Monaco, TokenTypes } from './types'; import { LanguageDefinition } from './register'; +import { Monaco, TokenTypes } from './types'; export function linkedTokenBuilder( monaco: Monaco, diff --git a/public/app/plugins/datasource/cloudwatch/monarch/register.ts b/public/app/plugins/datasource/cloudwatch/monarch/register.ts index 2a69e7156ae..3a3f7b4e2d6 100644 --- a/public/app/plugins/datasource/cloudwatch/monarch/register.ts +++ b/public/app/plugins/datasource/cloudwatch/monarch/register.ts @@ -1,7 +1,9 @@ -import { Monaco } from '@grafana/ui'; -import { CompletionItemProvider } from './CompletionItemProvider'; import type * as monacoType from 'monaco-editor/esm/vs/editor/editor.api'; +import { Monaco } from '@grafana/ui'; + +import { CompletionItemProvider } from './CompletionItemProvider'; + export type LanguageDefinition = { id: string; extensions: string[]; diff --git a/public/app/plugins/datasource/cloudwatch/specs/datasource.test.ts b/public/app/plugins/datasource/cloudwatch/specs/datasource.test.ts index 6e91e209b2a..72dfae2fe70 100644 --- a/public/app/plugins/datasource/cloudwatch/specs/datasource.test.ts +++ b/public/app/plugins/datasource/cloudwatch/specs/datasource.test.ts @@ -1,4 +1,7 @@ import { interval, lastValueFrom, of, throwError } from 'rxjs'; +import { createFetchResponse } from 'test/helpers/createFetchResponse'; +import { getTemplateSrvDependencies } from 'test/helpers/getTemplateSrvDependencies'; + import { DataFrame, DataQueryErrorType, @@ -6,10 +9,14 @@ import { dateMath, getFrameDisplayName, } from '@grafana/data'; - -import * as redux from 'app/store/store'; -import { CloudWatchDatasource } from '../datasource'; +import { backendSrv } from 'app/core/services/backend_srv'; // will use the version in __mocks__ +import { TimeSrv } from 'app/features/dashboard/services/TimeSrv'; import { TemplateSrv } from 'app/features/templating/template_srv'; +import * as redux from 'app/store/store'; + +import { convertToStoreState } from '../../../../../test/helpers/convertToStoreState'; +import { CustomVariableModel, initialVariableModelState, VariableHide } from '../../../../features/variables/types'; +import { CloudWatchDatasource } from '../datasource'; import { CloudWatchJsonData, CloudWatchLogsQuery, @@ -19,14 +26,7 @@ import { MetricEditorMode, MetricQueryType, } from '../types'; -import { backendSrv } from 'app/core/services/backend_srv'; // will use the version in __mocks__ -import { TimeSrv } from 'app/features/dashboard/services/TimeSrv'; -import { convertToStoreState } from '../../../../../test/helpers/convertToStoreState'; -import { getTemplateSrvDependencies } from 'test/helpers/getTemplateSrvDependencies'; -import { CustomVariableModel, initialVariableModelState, VariableHide } from '../../../../features/variables/types'; - import * as rxjsUtils from '../utils/rxjs/increasingInterval'; -import { createFetchResponse } from 'test/helpers/createFetchResponse'; jest.mock('@grafana/runtime', () => ({ ...(jest.requireActual('@grafana/runtime') as unknown as object), diff --git a/public/app/plugins/datasource/cloudwatch/syntax.ts b/public/app/plugins/datasource/cloudwatch/syntax.ts index 92c279ec527..742db4e4908 100644 --- a/public/app/plugins/datasource/cloudwatch/syntax.ts +++ b/public/app/plugins/datasource/cloudwatch/syntax.ts @@ -1,4 +1,5 @@ import { Grammar } from 'prismjs'; + import { CompletionItem } from '@grafana/ui'; export const QUERY_COMMANDS: CompletionItem[] = [ diff --git a/public/app/plugins/datasource/cloudwatch/types.ts b/public/app/plugins/datasource/cloudwatch/types.ts index c3f661b5333..0380c8a1d78 100644 --- a/public/app/plugins/datasource/cloudwatch/types.ts +++ b/public/app/plugins/datasource/cloudwatch/types.ts @@ -1,5 +1,5 @@ -import { DataQuery, DataSourceRef, SelectableValue } from '@grafana/data'; import { AwsAuthDataSourceSecureJsonData, AwsAuthDataSourceJsonData } from '@grafana/aws-sdk'; +import { DataQuery, DataSourceRef, SelectableValue } from '@grafana/data'; export interface Dimensions { [key: string]: string | string[]; diff --git a/public/app/plugins/datasource/cloudwatch/utils/datalinks.test.ts b/public/app/plugins/datasource/cloudwatch/utils/datalinks.test.ts index c8ccb1ba9fa..25edfd33b16 100644 --- a/public/app/plugins/datasource/cloudwatch/utils/datalinks.test.ts +++ b/public/app/plugins/datasource/cloudwatch/utils/datalinks.test.ts @@ -1,7 +1,8 @@ import { DataQueryResponse, dateMath } from '@grafana/data'; -import { addDataLinksToLogsResponse } from './datalinks'; import { setDataSourceSrv } from '@grafana/runtime'; +import { addDataLinksToLogsResponse } from './datalinks'; + describe('addDataLinksToLogsResponse', () => { it('should add data links to response', async () => { const mockResponse: DataQueryResponse = { diff --git a/public/app/plugins/datasource/cloudwatch/utils/datalinks.ts b/public/app/plugins/datasource/cloudwatch/utils/datalinks.ts index 897c4441d60..05f19e61925 100644 --- a/public/app/plugins/datasource/cloudwatch/utils/datalinks.ts +++ b/public/app/plugins/datasource/cloudwatch/utils/datalinks.ts @@ -1,8 +1,9 @@ import { DataFrame, DataLink, DataQueryRequest, DataQueryResponse, ScopedVars, TimeRange } from '@grafana/data'; -import { CloudWatchLogsQuery, CloudWatchQuery } from '../types'; -import { AwsUrl, encodeUrl } from '../aws_url'; import { getDataSourceSrv } from '@grafana/runtime'; +import { AwsUrl, encodeUrl } from '../aws_url'; +import { CloudWatchLogsQuery, CloudWatchQuery } from '../types'; + type ReplaceFn = ( target?: string, scopedVars?: ScopedVars, diff --git a/public/app/plugins/datasource/cloudwatch/utils/logsRetry.test.ts b/public/app/plugins/datasource/cloudwatch/utils/logsRetry.test.ts index d6103230c12..fd4c854bd55 100644 --- a/public/app/plugins/datasource/cloudwatch/utils/logsRetry.test.ts +++ b/public/app/plugins/datasource/cloudwatch/utils/logsRetry.test.ts @@ -1,10 +1,13 @@ -import { runWithRetry } from './logsRetry'; -import { toArray } from 'rxjs/operators'; import { lastValueFrom, of, throwError } from 'rxjs'; +import { toArray } from 'rxjs/operators'; + import { dataFrameToJSON, MutableDataFrame } from '@grafana/data'; import { DataResponse, FetchError } from '@grafana/runtime'; + import { StartQueryRequest } from '../types'; +import { runWithRetry } from './logsRetry'; + describe('runWithRetry', () => { const timeoutPass = () => false; const timeoutFail = () => true; diff --git a/public/app/plugins/datasource/cloudwatch/utils/logsRetry.ts b/public/app/plugins/datasource/cloudwatch/utils/logsRetry.ts index 06db908daa2..9ff34b37737 100644 --- a/public/app/plugins/datasource/cloudwatch/utils/logsRetry.ts +++ b/public/app/plugins/datasource/cloudwatch/utils/logsRetry.ts @@ -1,7 +1,9 @@ import { Observable, Subscription } from 'rxjs'; -import { FetchError, toDataQueryResponse } from '@grafana/runtime'; -import { StartQueryRequest } from '../types'; + import { DataFrame, DataFrameJSON, DataQueryError } from '@grafana/data'; +import { FetchError, toDataQueryResponse } from '@grafana/runtime'; + +import { StartQueryRequest } from '../types'; type Result = { frames: DataFrameJSON[]; error?: string }; diff --git a/public/app/plugins/datasource/cloudwatch/utils/utils.ts b/public/app/plugins/datasource/cloudwatch/utils/utils.ts index 9ca92516fcf..d0f626cb2a1 100644 --- a/public/app/plugins/datasource/cloudwatch/utils/utils.ts +++ b/public/app/plugins/datasource/cloudwatch/utils/utils.ts @@ -1,4 +1,5 @@ import { SelectableValue } from '@grafana/data'; + import { CloudWatchDatasource } from './../datasource'; export const toOption = (value: string) => ({ label: value, value }); diff --git a/public/app/plugins/datasource/cloudwatch/variables.test.ts b/public/app/plugins/datasource/cloudwatch/variables.test.ts index 5b2d09e77da..592506cba98 100644 --- a/public/app/plugins/datasource/cloudwatch/variables.test.ts +++ b/public/app/plugins/datasource/cloudwatch/variables.test.ts @@ -1,6 +1,6 @@ +import { setupMockedDataSource } from './__mocks__/CloudWatchDataSource'; import { VariableQuery, VariableQueryType } from './types'; import { CloudWatchVariableSupport } from './variables'; -import { setupMockedDataSource } from './__mocks__/CloudWatchDataSource'; const defaultQuery: VariableQuery = { queryType: VariableQueryType.Regions, diff --git a/public/app/plugins/datasource/cloudwatch/variables.ts b/public/app/plugins/datasource/cloudwatch/variables.ts index cea8084b049..3a6932b3ca7 100644 --- a/public/app/plugins/datasource/cloudwatch/variables.ts +++ b/public/app/plugins/datasource/cloudwatch/variables.ts @@ -1,11 +1,12 @@ import { from, Observable } from 'rxjs'; import { map } from 'rxjs/operators'; + import { CustomVariableSupport, DataQueryRequest, DataQueryResponse } from '@grafana/data'; -import { CloudWatchDatasource } from './datasource'; -import { VariableQuery, VariableQueryType } from './types'; -import { migrateVariableQuery } from './migrations'; import { VariableQueryEditor } from './components/VariableQueryEditor/VariableQueryEditor'; +import { CloudWatchDatasource } from './datasource'; +import { migrateVariableQuery } from './migrations'; +import { VariableQuery, VariableQueryType } from './types'; export class CloudWatchVariableSupport extends CustomVariableSupport { private readonly datasource: CloudWatchDatasource; diff --git a/public/app/plugins/datasource/dashboard/DashboardQueryEditor.test.tsx b/public/app/plugins/datasource/dashboard/DashboardQueryEditor.test.tsx index 2d8ad850609..0a98f2bd947 100644 --- a/public/app/plugins/datasource/dashboard/DashboardQueryEditor.test.tsx +++ b/public/app/plugins/datasource/dashboard/DashboardQueryEditor.test.tsx @@ -1,13 +1,15 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import React from 'react'; + import { getDefaultTimeRange, LoadingState } from '@grafana/data'; -import { SHARED_DASHBOARD_QUERY } from './types'; -import { DashboardQueryEditor } from './DashboardQueryEditor'; -import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv'; -import { DashboardModel } from 'app/features/dashboard/state'; import { setDataSourceSrv } from '@grafana/runtime'; import { mockDataSource, MockDataSourceSrv } from 'app/features/alerting/unified/mocks'; +import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv'; +import { DashboardModel } from 'app/features/dashboard/state'; + +import { DashboardQueryEditor } from './DashboardQueryEditor'; +import { SHARED_DASHBOARD_QUERY } from './types'; jest.mock('app/core/config', () => ({ ...(jest.requireActual('app/core/config') as unknown as object), diff --git a/public/app/plugins/datasource/dashboard/DashboardQueryEditor.tsx b/public/app/plugins/datasource/dashboard/DashboardQueryEditor.tsx index 6ce8d461fb7..6a7cc23a35f 100644 --- a/public/app/plugins/datasource/dashboard/DashboardQueryEditor.tsx +++ b/public/app/plugins/datasource/dashboard/DashboardQueryEditor.tsx @@ -1,19 +1,18 @@ -import React, { useCallback, useMemo } from 'react'; import { css } from '@emotion/css'; -import pluralize from 'pluralize'; import { useId } from '@react-aria/utils'; +import pluralize from 'pluralize'; +import React, { useCallback, useMemo } from 'react'; import { useAsync } from 'react-use'; -import { InlineField, Select, useStyles2, VerticalGroup } from '@grafana/ui'; import { DataQuery, GrafanaTheme2, PanelData, SelectableValue } from '@grafana/data'; - +import { InlineField, Select, useStyles2, VerticalGroup } from '@grafana/ui'; import config from 'app/core/config'; -import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; -import { PanelModel } from 'app/features/dashboard/state'; import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv'; +import { PanelModel } from 'app/features/dashboard/state'; +import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; import { filterPanelDataToQuery } from 'app/features/query/components/QueryEditorRow'; -import { DashboardQueryRow } from './DashboardQueryRow'; +import { DashboardQueryRow } from './DashboardQueryRow'; import { DashboardQuery, ResultInfo, SHARED_DASHBOARD_QUERY } from './types'; function getQueryDisplayText(query: DataQuery): string { diff --git a/public/app/plugins/datasource/dashboard/DashboardQueryRow.tsx b/public/app/plugins/datasource/dashboard/DashboardQueryRow.tsx index 5b3d957f170..426798625c9 100644 --- a/public/app/plugins/datasource/dashboard/DashboardQueryRow.tsx +++ b/public/app/plugins/datasource/dashboard/DashboardQueryRow.tsx @@ -1,7 +1,8 @@ -import React, { ReactElement } from 'react'; import { css } from '@emotion/css'; -import { Icon, useStyles } from '@grafana/ui'; +import React, { ReactElement } from 'react'; + import { GrafanaTheme } from '@grafana/data'; +import { Icon, useStyles } from '@grafana/ui'; import { ResultInfo } from './types'; diff --git a/public/app/plugins/datasource/dashboard/datasource.ts b/public/app/plugins/datasource/dashboard/datasource.ts index 0f7f8d8d3f3..e4d9465c04c 100644 --- a/public/app/plugins/datasource/dashboard/datasource.ts +++ b/public/app/plugins/datasource/dashboard/datasource.ts @@ -1,4 +1,5 @@ import { DataSourceApi, DataQueryRequest, DataQueryResponse, DataSourceInstanceSettings } from '@grafana/data'; + import { DashboardQuery } from './types'; /** diff --git a/public/app/plugins/datasource/dashboard/module.ts b/public/app/plugins/datasource/dashboard/module.ts index ac32bca87e3..1fa8553046e 100644 --- a/public/app/plugins/datasource/dashboard/module.ts +++ b/public/app/plugins/datasource/dashboard/module.ts @@ -1,4 +1,5 @@ -import { DashboardDatasource } from './datasource'; import { DataSourcePlugin } from '@grafana/data'; +import { DashboardDatasource } from './datasource'; + export const plugin = new DataSourcePlugin(DashboardDatasource); diff --git a/public/app/plugins/datasource/dashboard/runSharedRequest.test.ts b/public/app/plugins/datasource/dashboard/runSharedRequest.test.ts index ad6c4a6dd52..956c9bea66f 100644 --- a/public/app/plugins/datasource/dashboard/runSharedRequest.test.ts +++ b/public/app/plugins/datasource/dashboard/runSharedRequest.test.ts @@ -1,6 +1,7 @@ -import { isSharedDashboardQuery } from './runSharedRequest'; import { DataSourceApi } from '@grafana/data'; +import { isSharedDashboardQuery } from './runSharedRequest'; + describe('SharedQueryRunner', () => { it('should identify shared queries', () => { expect(isSharedDashboardQuery('-- Dashboard --')).toBe(true); diff --git a/public/app/plugins/datasource/dashboard/runSharedRequest.ts b/public/app/plugins/datasource/dashboard/runSharedRequest.ts index 6ec3412ac17..4b7ee2782b1 100644 --- a/public/app/plugins/datasource/dashboard/runSharedRequest.ts +++ b/public/app/plugins/datasource/dashboard/runSharedRequest.ts @@ -1,7 +1,5 @@ import { Observable } from 'rxjs'; -import { QueryRunnerOptions } from 'app/features/query/state/PanelQueryRunner'; -import { DashboardQuery, SHARED_DASHBOARD_QUERY } from './types'; -import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv'; + import { DataQuery, DataQueryRequest, @@ -11,6 +9,10 @@ import { LoadingState, PanelData, } from '@grafana/data'; +import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv'; +import { QueryRunnerOptions } from 'app/features/query/state/PanelQueryRunner'; + +import { DashboardQuery, SHARED_DASHBOARD_QUERY } from './types'; export function isSharedDashboardQuery(datasource: string | DataSourceRef | DataSourceApi | null) { if (!datasource) { diff --git a/public/app/plugins/datasource/elasticsearch/components/AddRemove.test.tsx b/public/app/plugins/datasource/elasticsearch/components/AddRemove.test.tsx index 7b7dd7dfec9..8c2feee10ab 100644 --- a/public/app/plugins/datasource/elasticsearch/components/AddRemove.test.tsx +++ b/public/app/plugins/datasource/elasticsearch/components/AddRemove.test.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; +import React from 'react'; + import { AddRemove } from './AddRemove'; const noop = () => {}; diff --git a/public/app/plugins/datasource/elasticsearch/components/AddRemove.tsx b/public/app/plugins/datasource/elasticsearch/components/AddRemove.tsx index 4e210830ea0..935167f9ae0 100644 --- a/public/app/plugins/datasource/elasticsearch/components/AddRemove.tsx +++ b/public/app/plugins/datasource/elasticsearch/components/AddRemove.tsx @@ -1,5 +1,6 @@ import { css } from '@emotion/css'; import React from 'react'; + import { IconButton } from './IconButton'; interface Props { diff --git a/public/app/plugins/datasource/elasticsearch/components/IconButton.tsx b/public/app/plugins/datasource/elasticsearch/components/IconButton.tsx index 51fb6b179ac..8758f405cd1 100644 --- a/public/app/plugins/datasource/elasticsearch/components/IconButton.tsx +++ b/public/app/plugins/datasource/elasticsearch/components/IconButton.tsx @@ -1,7 +1,8 @@ -import { Icon } from '@grafana/ui'; import { cx, css } from '@emotion/css'; import React, { ComponentProps, ButtonHTMLAttributes } from 'react'; +import { Icon } from '@grafana/ui'; + const SROnly = css` clip: rect(0 0 0 0); clip-path: inset(50%); diff --git a/public/app/plugins/datasource/elasticsearch/components/MetricPicker.tsx b/public/app/plugins/datasource/elasticsearch/components/MetricPicker.tsx index 8a46e71b2f7..3c6c4e1824c 100644 --- a/public/app/plugins/datasource/elasticsearch/components/MetricPicker.tsx +++ b/public/app/plugins/datasource/elasticsearch/components/MetricPicker.tsx @@ -1,8 +1,11 @@ -import React from 'react'; import { css, cx } from '@emotion/css'; +import React from 'react'; + import { SelectableValue } from '@grafana/data'; import { Segment } from '@grafana/ui'; + import { describeMetric } from '../utils'; + import { MetricAggregation } from './QueryEditor/MetricAggregationsEditor/aggregations'; const noWrap = css` diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/BucketAggregationEditor.tsx b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/BucketAggregationEditor.tsx index b1f069f5730..16a29633d50 100644 --- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/BucketAggregationEditor.tsx +++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/BucketAggregationEditor.tsx @@ -1,11 +1,14 @@ +import React from 'react'; + import { SelectableValue } from '@grafana/data'; import { InlineSegmentGroup, Segment, SegmentAsync } from '@grafana/ui'; -import React from 'react'; + import { useFields } from '../../../hooks/useFields'; import { useDispatch } from '../../../hooks/useStatelessReducer'; import { segmentStyles } from '../styles'; -import { BucketAggregation, BucketAggregationType, isBucketAggregationWithField } from './aggregations'; + import { SettingsEditor } from './SettingsEditor'; +import { BucketAggregation, BucketAggregationType, isBucketAggregationWithField } from './aggregations'; import { changeBucketAggregationField, changeBucketAggregationType } from './state/actions'; import { bucketAggregationConfig } from './utils'; diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/SettingsEditor/DateHistogramSettingsEditor.tsx b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/SettingsEditor/DateHistogramSettingsEditor.tsx index bae48b2e382..5a459dbe752 100644 --- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/SettingsEditor/DateHistogramSettingsEditor.tsx +++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/SettingsEditor/DateHistogramSettingsEditor.tsx @@ -1,14 +1,17 @@ +import { uniqueId } from 'lodash'; import React, { useRef } from 'react'; import { GroupBase, OptionsOrGroups } from 'react-select'; -import { InlineField, Input, Select, TimeZonePicker } from '@grafana/ui'; -import { DateHistogram } from '../aggregations'; -import { bucketAggregationConfig } from '../utils'; -import { useDispatch } from '../../../../hooks/useStatelessReducer'; + import { InternalTimeZones, SelectableValue } from '@grafana/data'; -import { changeBucketAggregationSetting } from '../state/actions'; -import { inlineFieldProps } from '.'; -import { uniqueId } from 'lodash'; +import { InlineField, Input, Select, TimeZonePicker } from '@grafana/ui'; + +import { useDispatch } from '../../../../hooks/useStatelessReducer'; import { useCreatableSelectPersistedBehaviour } from '../../../hooks/useCreatableSelectPersistedBehaviour'; +import { DateHistogram } from '../aggregations'; +import { changeBucketAggregationSetting } from '../state/actions'; +import { bucketAggregationConfig } from '../utils'; + +import { inlineFieldProps } from '.'; const defaultIntervalOptions: Array> = [ { label: 'auto', value: 'auto' }, diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/SettingsEditor/FiltersSettingsEditor/index.tsx b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/SettingsEditor/FiltersSettingsEditor/index.tsx index 883251e803e..2e26f480e9f 100644 --- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/SettingsEditor/FiltersSettingsEditor/index.tsx +++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/SettingsEditor/FiltersSettingsEditor/index.tsx @@ -1,13 +1,16 @@ -import { InlineField, Input, QueryField } from '@grafana/ui'; import { css } from '@emotion/css'; +import { uniqueId } from 'lodash'; import React, { useEffect, useRef } from 'react'; -import { AddRemove } from '../../../../AddRemove'; + +import { InlineField, Input, QueryField } from '@grafana/ui'; + import { useDispatch, useStatelessReducer } from '../../../../../hooks/useStatelessReducer'; +import { AddRemove } from '../../../../AddRemove'; import { Filters } from '../../aggregations'; import { changeBucketAggregationSetting } from '../../state/actions'; + import { addFilter, changeFilter, removeFilter } from './state/actions'; import { reducer as filtersReducer } from './state/reducer'; -import { uniqueId } from 'lodash'; interface Props { bucketAgg: Filters; diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/SettingsEditor/FiltersSettingsEditor/state/actions.ts b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/SettingsEditor/FiltersSettingsEditor/state/actions.ts index 90f823e9149..5c24b3dd003 100644 --- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/SettingsEditor/FiltersSettingsEditor/state/actions.ts +++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/SettingsEditor/FiltersSettingsEditor/state/actions.ts @@ -1,4 +1,5 @@ import { createAction } from '@reduxjs/toolkit'; + import { Filter } from '../../../aggregations'; export const addFilter = createAction('@bucketAggregations/filter/add'); diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/SettingsEditor/FiltersSettingsEditor/state/reducer.test.ts b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/SettingsEditor/FiltersSettingsEditor/state/reducer.test.ts index ee947026028..aa532275d5e 100644 --- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/SettingsEditor/FiltersSettingsEditor/state/reducer.test.ts +++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/SettingsEditor/FiltersSettingsEditor/state/reducer.test.ts @@ -1,5 +1,7 @@ import { reducerTester } from 'test/core/redux/reducerTester'; + import { Filter } from '../../../aggregations'; + import { addFilter, changeFilter, removeFilter } from './actions'; import { reducer } from './reducer'; diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/SettingsEditor/FiltersSettingsEditor/state/reducer.ts b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/SettingsEditor/FiltersSettingsEditor/state/reducer.ts index dfe5c518c21..05d89aaa6ef 100644 --- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/SettingsEditor/FiltersSettingsEditor/state/reducer.ts +++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/SettingsEditor/FiltersSettingsEditor/state/reducer.ts @@ -1,6 +1,8 @@ import { Action } from 'redux'; + import { Filter } from '../../../aggregations'; import { defaultFilter } from '../utils'; + import { addFilter, changeFilter, removeFilter } from './actions'; export const reducer = (state: Filter[] = [], action: Action) => { diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/SettingsEditor/TermsSettingsEditor.test.tsx b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/SettingsEditor/TermsSettingsEditor.test.tsx index 3243378b00a..7760ff681fa 100644 --- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/SettingsEditor/TermsSettingsEditor.test.tsx +++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/SettingsEditor/TermsSettingsEditor.test.tsx @@ -1,12 +1,15 @@ import { screen } from '@testing-library/react'; -import { ElasticsearchQuery } from '../../../../types'; import React from 'react'; +import selectEvent from 'react-select-event'; + +import { describeMetric } from 'app/plugins/datasource/elasticsearch/utils'; + import { renderWithESProvider } from '../../../../test-helpers/render'; +import { ElasticsearchQuery } from '../../../../types'; import { Average, Derivative, TopMetrics } from '../../MetricAggregationsEditor/aggregations'; import { Terms } from '../aggregations'; + import { TermsSettingsEditor } from './TermsSettingsEditor'; -import selectEvent from 'react-select-event'; -import { describeMetric } from 'app/plugins/datasource/elasticsearch/utils'; describe('Terms Settings Editor', () => { it('Pipeline aggregations should not be in "order by" options', () => { diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/SettingsEditor/TermsSettingsEditor.tsx b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/SettingsEditor/TermsSettingsEditor.tsx index fba98d56409..1a7fc93eebb 100644 --- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/SettingsEditor/TermsSettingsEditor.tsx +++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/SettingsEditor/TermsSettingsEditor.tsx @@ -1,14 +1,13 @@ +import { uniqueId } from 'lodash'; import React, { useRef } from 'react'; -import { InlineField, Select, Input } from '@grafana/ui'; -import { Terms } from '../aggregations'; -import { useDispatch } from '../../../../hooks/useStatelessReducer'; -import { inlineFieldProps } from '.'; -import { bucketAggregationConfig, orderByOptions, orderOptions, sizeOptions } from '../utils'; -import { useCreatableSelectPersistedBehaviour } from '../../../hooks/useCreatableSelectPersistedBehaviour'; -import { changeBucketAggregationSetting } from '../state/actions'; -import { useQuery } from '../../ElasticsearchQueryContext'; + import { SelectableValue } from '@grafana/data'; +import { InlineField, Select, Input } from '@grafana/ui'; + +import { useDispatch } from '../../../../hooks/useStatelessReducer'; import { describeMetric } from '../../../../utils'; +import { useCreatableSelectPersistedBehaviour } from '../../../hooks/useCreatableSelectPersistedBehaviour'; +import { useQuery } from '../../ElasticsearchQueryContext'; import { ExtendedStatMetaType, ExtendedStats, @@ -16,7 +15,11 @@ import { MetricAggregation, Percentiles, } from '../../MetricAggregationsEditor/aggregations'; -import { uniqueId } from 'lodash'; +import { Terms } from '../aggregations'; +import { changeBucketAggregationSetting } from '../state/actions'; +import { bucketAggregationConfig, orderByOptions, orderOptions, sizeOptions } from '../utils'; + +import { inlineFieldProps } from '.'; interface Props { bucketAgg: Terms; diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/SettingsEditor/index.tsx b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/SettingsEditor/index.tsx index a4b8051f93b..079a744e52e 100644 --- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/SettingsEditor/index.tsx +++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/SettingsEditor/index.tsx @@ -1,15 +1,18 @@ -import { InlineField, Input } from '@grafana/ui'; +import { uniqueId } from 'lodash'; import React, { ComponentProps, useRef } from 'react'; + +import { InlineField, Input } from '@grafana/ui'; + import { useDispatch } from '../../../../hooks/useStatelessReducer'; import { SettingsEditorContainer } from '../../SettingsEditorContainer'; -import { changeBucketAggregationSetting } from '../state/actions'; import { BucketAggregation } from '../aggregations'; +import { changeBucketAggregationSetting } from '../state/actions'; import { bucketAggregationConfig } from '../utils'; -import { FiltersSettingsEditor } from './FiltersSettingsEditor'; -import { useDescription } from './useDescription'; + import { DateHistogramSettingsEditor } from './DateHistogramSettingsEditor'; +import { FiltersSettingsEditor } from './FiltersSettingsEditor'; import { TermsSettingsEditor } from './TermsSettingsEditor'; -import { uniqueId } from 'lodash'; +import { useDescription } from './useDescription'; export const inlineFieldProps: Partial> = { labelWidth: 16, diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/index.tsx b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/index.tsx index 428015f7071..969c90f9b08 100644 --- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/index.tsx +++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/index.tsx @@ -1,11 +1,13 @@ import React from 'react'; -import { BucketAggregationEditor } from './BucketAggregationEditor'; + import { useDispatch } from '../../../hooks/useStatelessReducer'; -import { addBucketAggregation, removeBucketAggregation } from './state/actions'; -import { BucketAggregation } from './aggregations'; +import { IconButton } from '../../IconButton'; import { useQuery } from '../ElasticsearchQueryContext'; import { QueryEditorRow } from '../QueryEditorRow'; -import { IconButton } from '../../IconButton'; + +import { BucketAggregationEditor } from './BucketAggregationEditor'; +import { BucketAggregation } from './aggregations'; +import { addBucketAggregation, removeBucketAggregation } from './state/actions'; interface Props { nextId: BucketAggregation['id']; diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/state/actions.ts b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/state/actions.ts index 124577ba350..44d1efa68d5 100644 --- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/state/actions.ts +++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/state/actions.ts @@ -1,4 +1,5 @@ import { createAction } from '@reduxjs/toolkit'; + import { BucketAggregation, BucketAggregationType, BucketAggregationWithField } from '../aggregations'; export const addBucketAggregation = createAction('@bucketAggs/add'); diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/state/reducer.test.ts b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/state/reducer.test.ts index b97ef8d913d..e85a55b7f0a 100644 --- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/state/reducer.test.ts +++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/state/reducer.test.ts @@ -1,8 +1,13 @@ -import { defaultBucketAgg } from 'app/plugins/datasource/elasticsearch/query_def'; import { reducerTester } from 'test/core/redux/reducerTester'; + +import { defaultBucketAgg } from 'app/plugins/datasource/elasticsearch/query_def'; +import { ElasticsearchQuery } from 'app/plugins/datasource/elasticsearch/types'; + import { changeMetricType } from '../../MetricAggregationsEditor/state/actions'; +import { initQuery } from '../../state'; import { BucketAggregation, DateHistogram } from '../aggregations'; import { bucketAggregationConfig } from '../utils'; + import { addBucketAggregation, changeBucketAggregationField, @@ -11,8 +16,6 @@ import { removeBucketAggregation, } from './actions'; import { createReducer } from './reducer'; -import { initQuery } from '../../state'; -import { ElasticsearchQuery } from 'app/plugins/datasource/elasticsearch/types'; describe('Bucket Aggregations Reducer', () => { it('Should correctly add new aggregations', () => { diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/state/reducer.ts b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/state/reducer.ts index 5456e937198..cc62fee5d54 100644 --- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/state/reducer.ts +++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/state/reducer.ts @@ -1,11 +1,14 @@ +import { Action } from '@reduxjs/toolkit'; + import { defaultBucketAgg } from '../../../../query_def'; import { ElasticsearchQuery } from '../../../../types'; -import { metricAggregationConfig } from '../../MetricAggregationsEditor/utils'; -import { BucketAggregation, Terms } from '../aggregations'; -import { initQuery } from '../../state'; -import { bucketAggregationConfig } from '../utils'; import { removeEmpty } from '../../../../utils'; -import { Action } from '@reduxjs/toolkit'; +import { changeMetricType } from '../../MetricAggregationsEditor/state/actions'; +import { metricAggregationConfig } from '../../MetricAggregationsEditor/utils'; +import { initQuery } from '../../state'; +import { BucketAggregation, Terms } from '../aggregations'; +import { bucketAggregationConfig } from '../utils'; + import { addBucketAggregation, changeBucketAggregationField, @@ -13,7 +16,6 @@ import { changeBucketAggregationType, removeBucketAggregation, } from './actions'; -import { changeMetricType } from '../../MetricAggregationsEditor/state/actions'; export const createReducer = (defaultTimeField: string) => diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/utils.ts b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/utils.ts index 56673b91236..d37876d090e 100644 --- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/utils.ts +++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/utils.ts @@ -1,7 +1,9 @@ -import { BucketsConfiguration } from '../../../types'; -import { defaultFilter } from './SettingsEditor/FiltersSettingsEditor/utils'; import { InternalTimeZones, SelectableValue } from '@grafana/data'; +import { BucketsConfiguration } from '../../../types'; + +import { defaultFilter } from './SettingsEditor/FiltersSettingsEditor/utils'; + export const bucketAggregationConfig: BucketsConfiguration = { terms: { label: 'Terms', diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/ElasticsearchQueryContext.test.tsx b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/ElasticsearchQueryContext.test.tsx index d95eb6f4678..1ba546ccac2 100644 --- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/ElasticsearchQueryContext.test.tsx +++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/ElasticsearchQueryContext.test.tsx @@ -1,11 +1,14 @@ -import React, { PropsWithChildren } from 'react'; -import { renderHook } from '@testing-library/react-hooks'; import { render } from '@testing-library/react'; -import { ElasticsearchProvider, useQuery } from './ElasticsearchQueryContext'; -import { ElasticsearchQuery } from '../../types'; -import { ElasticDatasource } from '../../datasource'; +import { renderHook } from '@testing-library/react-hooks'; +import React, { PropsWithChildren } from 'react'; + import { getDefaultTimeRange } from '@grafana/data'; +import { ElasticDatasource } from '../../datasource'; +import { ElasticsearchQuery } from '../../types'; + +import { ElasticsearchProvider, useQuery } from './ElasticsearchQueryContext'; + const query: ElasticsearchQuery = { refId: 'A', query: '', diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/ElasticsearchQueryContext.tsx b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/ElasticsearchQueryContext.tsx index 1f7be0820d6..77fbf6966c8 100644 --- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/ElasticsearchQueryContext.tsx +++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/ElasticsearchQueryContext.tsx @@ -1,12 +1,14 @@ import React, { Context, createContext, PropsWithChildren, useCallback, useContext } from 'react'; + +import { TimeRange } from '@grafana/data'; + import { ElasticDatasource } from '../../datasource'; import { combineReducers, useStatelessReducer, DispatchContext } from '../../hooks/useStatelessReducer'; import { ElasticsearchQuery } from '../../types'; -import { reducer as metricsReducer } from './MetricAggregationsEditor/state/reducer'; import { createReducer as createBucketAggsReducer } from './BucketAggregationsEditor/state/reducer'; +import { reducer as metricsReducer } from './MetricAggregationsEditor/state/reducer'; import { aliasPatternReducer, queryReducer, initQuery } from './state'; -import { TimeRange } from '@grafana/data'; const DatasourceContext = createContext(undefined); const QueryContext = createContext(undefined); diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/MetricEditor.test.tsx b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/MetricEditor.test.tsx index 1e9ab8c9862..df7b812ed98 100644 --- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/MetricEditor.test.tsx +++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/MetricEditor.test.tsx @@ -1,14 +1,17 @@ import { act, fireEvent, render, screen } from '@testing-library/react'; -import { ElasticsearchProvider } from '../ElasticsearchQueryContext'; -import { MetricEditor } from './MetricEditor'; import React, { ReactNode, PropsWithChildren } from 'react'; -import { ElasticDatasource } from '../../../datasource'; -import { getDefaultTimeRange } from '@grafana/data'; -import { ElasticsearchQuery } from '../../../types'; -import { Average, UniqueCount } from './aggregations'; -import { defaultBucketAgg, defaultMetricAgg } from '../../../query_def'; import { from } from 'rxjs'; +import { getDefaultTimeRange } from '@grafana/data'; + +import { ElasticDatasource } from '../../../datasource'; +import { defaultBucketAgg, defaultMetricAgg } from '../../../query_def'; +import { ElasticsearchQuery } from '../../../types'; +import { ElasticsearchProvider } from '../ElasticsearchQueryContext'; + +import { MetricEditor } from './MetricEditor'; +import { Average, UniqueCount } from './aggregations'; + describe('Metric Editor', () => { it('Should display a "None" option for "field" if the metric supports inline script', async () => { const avg: Average = { diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/MetricEditor.tsx b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/MetricEditor.tsx index 2c4d5619b68..b8b57fb7342 100644 --- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/MetricEditor.tsx +++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/MetricEditor.tsx @@ -1,15 +1,17 @@ -import { SelectableValue } from '@grafana/data'; -import { InlineSegmentGroup, Segment, SegmentAsync, useTheme2 } from '@grafana/ui'; import { cx } from '@emotion/css'; import React, { useCallback } from 'react'; -import { useDatasource, useQuery } from '../ElasticsearchQueryContext'; +import { satisfies } from 'semver'; + +import { SelectableValue } from '@grafana/data'; +import { InlineSegmentGroup, Segment, SegmentAsync, useTheme2 } from '@grafana/ui'; + +import { useFields } from '../../../hooks/useFields'; import { useDispatch } from '../../../hooks/useStatelessReducer'; -import { getStyles } from './styles'; -import { SettingsEditor } from './SettingsEditor'; -import { metricAggregationConfig } from './utils'; -import { changeMetricField, changeMetricType } from './state/actions'; import { MetricPicker } from '../../MetricPicker'; +import { useDatasource, useQuery } from '../ElasticsearchQueryContext'; import { segmentStyles } from '../styles'; + +import { SettingsEditor } from './SettingsEditor'; import { isMetricAggregationWithField, isMetricAggregationWithInlineScript, @@ -19,8 +21,9 @@ import { MetricAggregation, MetricAggregationType, } from './aggregations'; -import { useFields } from '../../../hooks/useFields'; -import { satisfies } from 'semver'; +import { changeMetricField, changeMetricType } from './state/actions'; +import { getStyles } from './styles'; +import { metricAggregationConfig } from './utils'; const toOption = (metric: MetricAggregation) => ({ label: metricAggregationConfig[metric.type].label, diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/SettingsEditor/BucketScriptSettingsEditor/index.tsx b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/SettingsEditor/BucketScriptSettingsEditor/index.tsx index a0780c6b15f..23b1a763ebb 100644 --- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/SettingsEditor/BucketScriptSettingsEditor/index.tsx +++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/SettingsEditor/BucketScriptSettingsEditor/index.tsx @@ -1,20 +1,23 @@ -import React, { Fragment, useEffect } from 'react'; -import { Input, InlineLabel } from '@grafana/ui'; -import { changeMetricAttribute } from '../../state/actions'; import { css } from '@emotion/css'; -import { AddRemove } from '../../../../AddRemove'; +import { uniqueId } from 'lodash'; +import React, { Fragment, useEffect } from 'react'; + +import { Input, InlineLabel } from '@grafana/ui'; + import { useStatelessReducer, useDispatch } from '../../../../../hooks/useStatelessReducer'; +import { AddRemove } from '../../../../AddRemove'; import { MetricPicker } from '../../../../MetricPicker'; -import { reducer } from './state/reducer'; +import { BucketScript, MetricAggregation } from '../../aggregations'; +import { changeMetricAttribute } from '../../state/actions'; +import { SettingField } from '../SettingField'; + import { addPipelineVariable, removePipelineVariable, renamePipelineVariable, changePipelineVariableMetric, } from './state/actions'; -import { SettingField } from '../SettingField'; -import { BucketScript, MetricAggregation } from '../../aggregations'; -import { uniqueId } from 'lodash'; +import { reducer } from './state/reducer'; interface Props { value: BucketScript; diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/SettingsEditor/BucketScriptSettingsEditor/state/reducer.test.ts b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/SettingsEditor/BucketScriptSettingsEditor/state/reducer.test.ts index df26707ce18..ad8e45702e2 100644 --- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/SettingsEditor/BucketScriptSettingsEditor/state/reducer.test.ts +++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/SettingsEditor/BucketScriptSettingsEditor/state/reducer.test.ts @@ -1,5 +1,7 @@ import { reducerTester } from 'test/core/redux/reducerTester'; + import { PipelineVariable } from '../../../aggregations'; + import { addPipelineVariable, changePipelineVariableMetric, diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/SettingsEditor/BucketScriptSettingsEditor/state/reducer.ts b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/SettingsEditor/BucketScriptSettingsEditor/state/reducer.ts index 563189fe426..3312758021a 100644 --- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/SettingsEditor/BucketScriptSettingsEditor/state/reducer.ts +++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/SettingsEditor/BucketScriptSettingsEditor/state/reducer.ts @@ -1,6 +1,8 @@ import { Action } from '@reduxjs/toolkit'; + import { PipelineVariable } from '../../../aggregations'; import { defaultPipelineVariable, generatePipelineVariableName } from '../utils'; + import { addPipelineVariable, changePipelineVariableMetric, diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/SettingsEditor/MovingAverageSettingsEditor.tsx b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/SettingsEditor/MovingAverageSettingsEditor.tsx index 98e208042a1..4d0793888e5 100644 --- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/SettingsEditor/MovingAverageSettingsEditor.tsx +++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/SettingsEditor/MovingAverageSettingsEditor.tsx @@ -1,10 +1,13 @@ -import { Input, InlineField, Select, InlineSwitch } from '@grafana/ui'; import { uniqueId } from 'lodash'; import React, { useRef } from 'react'; + +import { Input, InlineField, Select, InlineSwitch } from '@grafana/ui'; + import { useDispatch } from '../../../../hooks/useStatelessReducer'; import { movingAvgModelOptions } from '../../../../query_def'; import { isEWMAMovingAverage, isHoltMovingAverage, isHoltWintersMovingAverage, MovingAverage } from '../aggregations'; import { changeMetricSetting } from '../state/actions'; + import { SettingField } from './SettingField'; interface Props { diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/SettingsEditor/SettingField.tsx b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/SettingsEditor/SettingField.tsx index e25ff580464..2c44c6d80cb 100644 --- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/SettingsEditor/SettingField.tsx +++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/SettingsEditor/SettingField.tsx @@ -1,11 +1,13 @@ +import { uniqueId } from 'lodash'; import React, { ComponentProps, useState } from 'react'; + import { InlineField, Input } from '@grafana/ui'; +import { getScriptValue } from 'app/plugins/datasource/elasticsearch/utils'; + import { useDispatch } from '../../../../hooks/useStatelessReducer'; -import { changeMetricSetting } from '../state/actions'; import { SettingKeyOf } from '../../../types'; import { MetricAggregationWithInlineScript, MetricAggregationWithSettings } from '../aggregations'; -import { uniqueId } from 'lodash'; -import { getScriptValue } from 'app/plugins/datasource/elasticsearch/utils'; +import { changeMetricSetting } from '../state/actions'; interface Props> { label: string; diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/SettingsEditor/TopMetricsSettingsEditor.tsx b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/SettingsEditor/TopMetricsSettingsEditor.tsx index f8f5c5ba63d..2b3a5d88255 100644 --- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/SettingsEditor/TopMetricsSettingsEditor.tsx +++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/SettingsEditor/TopMetricsSettingsEditor.tsx @@ -1,12 +1,14 @@ -import { AsyncMultiSelect, InlineField, SegmentAsync, Select } from '@grafana/ui'; +import { css } from '@emotion/css'; import React, { FunctionComponent } from 'react'; -import { useDispatch } from '../../../../hooks/useStatelessReducer'; + +import { SelectableValue } from '@grafana/data'; +import { AsyncMultiSelect, InlineField, SegmentAsync, Select } from '@grafana/ui'; + import { useFields } from '../../../../hooks/useFields'; +import { useDispatch } from '../../../../hooks/useStatelessReducer'; +import { orderOptions } from '../../BucketAggregationsEditor/utils'; import { TopMetrics } from '../aggregations'; import { changeMetricSetting } from '../state/actions'; -import { orderOptions } from '../../BucketAggregationsEditor/utils'; -import { css } from '@emotion/css'; -import { SelectableValue } from '@grafana/data'; interface Props { metric: TopMetrics; diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/SettingsEditor/index.test.tsx b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/SettingsEditor/index.test.tsx index 88c8a3aa23b..f3753a70540 100644 --- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/SettingsEditor/index.test.tsx +++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/SettingsEditor/index.test.tsx @@ -1,10 +1,13 @@ -import React from 'react'; import { fireEvent, render, screen } from '@testing-library/react'; -import { SettingsEditor } from '.'; -import { ElasticsearchProvider } from '../../ElasticsearchQueryContext'; +import React from 'react'; + +import { getDefaultTimeRange } from '@grafana/data'; + import { ElasticDatasource } from '../../../../datasource'; import { ElasticsearchQuery } from '../../../../types'; -import { getDefaultTimeRange } from '@grafana/data'; +import { ElasticsearchProvider } from '../../ElasticsearchQueryContext'; + +import { SettingsEditor } from '.'; describe('Settings Editor', () => { describe('Raw Data', () => { diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/SettingsEditor/index.tsx b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/SettingsEditor/index.tsx index af31e49b830..50f7f82394a 100644 --- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/SettingsEditor/index.tsx +++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/SettingsEditor/index.tsx @@ -1,23 +1,26 @@ -import { InlineField, Input, InlineSwitch, Select } from '@grafana/ui'; +import { uniqueId } from 'lodash'; import React, { ComponentProps, useRef, useState } from 'react'; -import { extendedStats } from '../../../../query_def'; + +import { InlineField, Input, InlineSwitch, Select } from '@grafana/ui'; + import { useDispatch } from '../../../../hooks/useStatelessReducer'; -import { changeMetricMeta, changeMetricSetting } from '../state/actions'; +import { extendedStats } from '../../../../query_def'; +import { useQuery } from '../../ElasticsearchQueryContext'; +import { SettingsEditorContainer } from '../../SettingsEditorContainer'; import { MetricAggregation, isMetricAggregationWithInlineScript, isMetricAggregationWithMissingSupport, ExtendedStat, } from '../aggregations'; -import { BucketScriptSettingsEditor } from './BucketScriptSettingsEditor'; -import { SettingField } from './SettingField'; -import { SettingsEditorContainer } from '../../SettingsEditorContainer'; -import { useDescription } from './useDescription'; -import { MovingAverageSettingsEditor } from './MovingAverageSettingsEditor'; -import { TopMetricsSettingsEditor } from './TopMetricsSettingsEditor'; -import { uniqueId } from 'lodash'; +import { changeMetricMeta, changeMetricSetting } from '../state/actions'; import { metricAggregationConfig } from '../utils'; -import { useQuery } from '../../ElasticsearchQueryContext'; + +import { BucketScriptSettingsEditor } from './BucketScriptSettingsEditor'; +import { MovingAverageSettingsEditor } from './MovingAverageSettingsEditor'; +import { SettingField } from './SettingField'; +import { TopMetricsSettingsEditor } from './TopMetricsSettingsEditor'; +import { useDescription } from './useDescription'; // TODO: Move this somewhere and share it with BucketsAggregation Editor const inlineFieldProps: Partial> = { diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/index.tsx b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/index.tsx index f00699af7f5..bd607a814dd 100644 --- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/index.tsx +++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/index.tsx @@ -1,12 +1,14 @@ import React from 'react'; -import { MetricEditor } from './MetricEditor'; + import { useDispatch } from '../../../hooks/useStatelessReducer'; -import { metricAggregationConfig } from './utils'; -import { addMetric, removeMetric, toggleMetricVisibility } from './state/actions'; -import { MetricAggregation } from './aggregations'; +import { IconButton } from '../../IconButton'; import { useQuery } from '../ElasticsearchQueryContext'; import { QueryEditorRow } from '../QueryEditorRow'; -import { IconButton } from '../../IconButton'; + +import { MetricEditor } from './MetricEditor'; +import { MetricAggregation } from './aggregations'; +import { addMetric, removeMetric, toggleMetricVisibility } from './state/actions'; +import { metricAggregationConfig } from './utils'; interface Props { nextId: MetricAggregation['id']; diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/state/actions.ts b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/state/actions.ts index 8b52fa01df3..024ae207a71 100644 --- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/state/actions.ts +++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/state/actions.ts @@ -1,4 +1,5 @@ import { createAction } from '@reduxjs/toolkit'; + import { MetricAggregation, MetricAggregationWithMeta, MetricAggregationWithSettings } from '../aggregations'; export const addMetric = createAction('@metrics/add'); diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/state/reducer.test.ts b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/state/reducer.test.ts index e9ee62bfec2..12ccc4c167b 100644 --- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/state/reducer.test.ts +++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/state/reducer.test.ts @@ -1,5 +1,12 @@ import { reducerTester } from 'test/core/redux/reducerTester'; -import { reducer } from './reducer'; + +import { ElasticsearchQuery } from 'app/plugins/datasource/elasticsearch/types'; + +import { defaultMetricAgg } from '../../../../query_def'; +import { initQuery } from '../../state'; +import { Derivative, ExtendedStats, MetricAggregation } from '../aggregations'; +import { metricAggregationConfig } from '../utils'; + import { addMetric, changeMetricAttribute, @@ -10,11 +17,7 @@ import { removeMetric, toggleMetricVisibility, } from './actions'; -import { Derivative, ExtendedStats, MetricAggregation } from '../aggregations'; -import { defaultMetricAgg } from '../../../../query_def'; -import { metricAggregationConfig } from '../utils'; -import { initQuery } from '../../state'; -import { ElasticsearchQuery } from 'app/plugins/datasource/elasticsearch/types'; +import { reducer } from './reducer'; describe('Metric Aggregations Reducer', () => { it('should correctly add new aggregations', () => { diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/state/reducer.ts b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/state/reducer.ts index c1919640f9a..9f58c7a40bb 100644 --- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/state/reducer.ts +++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/state/reducer.ts @@ -1,4 +1,5 @@ import { Action } from '@reduxjs/toolkit'; + import { defaultMetricAgg } from '../../../../query_def'; import { ElasticsearchQuery } from '../../../../types'; import { removeEmpty } from '../../../../utils'; @@ -10,6 +11,7 @@ import { MetricAggregation, } from '../aggregations'; import { getChildren, metricAggregationConfig } from '../utils'; + import { addMetric, changeMetricAttribute, diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/styles.ts b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/styles.ts index 603997462c5..7497dec0d7b 100644 --- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/styles.ts +++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/styles.ts @@ -1,6 +1,7 @@ -import { GrafanaTheme2 } from '@grafana/data'; import { css } from '@emotion/css'; +import { GrafanaTheme2 } from '@grafana/data'; + export const getStyles = (theme: GrafanaTheme2, hidden: boolean) => { return { color: diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/utils.ts b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/utils.ts index 2828ee85c34..ae5b8cee37f 100644 --- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/utils.ts +++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/utils.ts @@ -1,14 +1,15 @@ import { MetricsConfiguration } from '../../../types'; + +import { + defaultPipelineVariable, + generatePipelineVariableName, +} from './SettingsEditor/BucketScriptSettingsEditor/utils'; import { isMetricAggregationWithField, isPipelineAggregationWithMultipleBucketPaths, MetricAggregation, PipelineMetricAggregationType, } from './aggregations'; -import { - defaultPipelineVariable, - generatePipelineVariableName, -} from './SettingsEditor/BucketScriptSettingsEditor/utils'; export const metricAggregationConfig: MetricsConfiguration = { count: { diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/QueryEditorRow.tsx b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/QueryEditorRow.tsx index 9b9af1a5667..155ed2942bc 100644 --- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/QueryEditorRow.tsx +++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/QueryEditorRow.tsx @@ -1,9 +1,10 @@ -import { GrafanaTheme2 } from '@grafana/data'; -import { IconButton, InlineFieldRow, InlineLabel, InlineSegmentGroup, useStyles2 } from '@grafana/ui'; import { css } from '@emotion/css'; import { noop } from 'lodash'; import React, { PropsWithChildren } from 'react'; +import { GrafanaTheme2 } from '@grafana/data'; +import { IconButton, InlineFieldRow, InlineLabel, InlineSegmentGroup, useStyles2 } from '@grafana/ui'; + interface Props { label: string; onRemoveClick?: false | (() => void); diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/SettingsEditorContainer.tsx b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/SettingsEditorContainer.tsx index 6dbbcc0a239..a7d64e95f93 100644 --- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/SettingsEditorContainer.tsx +++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/SettingsEditorContainer.tsx @@ -1,7 +1,9 @@ -import { GrafanaTheme2 } from '@grafana/data'; -import { Icon, InlineSegmentGroup, useTheme2 } from '@grafana/ui'; import { css, cx } from '@emotion/css'; import React, { PropsWithChildren, useState } from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; +import { Icon, InlineSegmentGroup, useTheme2 } from '@grafana/ui'; + import { segmentStyles } from './styles'; const getStyles = (theme: GrafanaTheme2, hidden: boolean) => { diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/index.test.tsx b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/index.test.tsx index 73e002b87c8..24775ff5691 100644 --- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/index.test.tsx +++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/index.test.tsx @@ -1,9 +1,11 @@ -import React from 'react'; import { fireEvent, render, screen } from '@testing-library/react'; -import { QueryEditor } from '.'; +import React from 'react'; + import { ElasticDatasource } from '../../datasource'; import { ElasticsearchQuery } from '../../types'; +import { QueryEditor } from '.'; + const noop = () => void 0; describe('QueryEditor', () => { diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/index.tsx b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/index.tsx index 947f86cb7c3..1e7c9d32d56 100644 --- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/index.tsx +++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/index.tsx @@ -1,16 +1,19 @@ -import React from 'react'; -import { getDefaultTimeRange, GrafanaTheme2, QueryEditorProps } from '@grafana/data'; -import { ElasticDatasource } from '../../datasource'; -import { ElasticsearchOptions, ElasticsearchQuery } from '../../types'; -import { ElasticsearchProvider } from './ElasticsearchQueryContext'; -import { InlineField, InlineLabel, Input, QueryField, useStyles2 } from '@grafana/ui'; -import { changeAliasPattern, changeQuery } from './state'; -import { MetricAggregationsEditor } from './MetricAggregationsEditor'; -import { BucketAggregationsEditor } from './BucketAggregationsEditor'; -import { useDispatch } from '../../hooks/useStatelessReducer'; -import { useNextId } from '../../hooks/useNextId'; -import { metricAggregationConfig } from './MetricAggregationsEditor/utils'; import { css } from '@emotion/css'; +import React from 'react'; + +import { getDefaultTimeRange, GrafanaTheme2, QueryEditorProps } from '@grafana/data'; +import { InlineField, InlineLabel, Input, QueryField, useStyles2 } from '@grafana/ui'; + +import { ElasticDatasource } from '../../datasource'; +import { useNextId } from '../../hooks/useNextId'; +import { useDispatch } from '../../hooks/useStatelessReducer'; +import { ElasticsearchOptions, ElasticsearchQuery } from '../../types'; + +import { BucketAggregationsEditor } from './BucketAggregationsEditor'; +import { ElasticsearchProvider } from './ElasticsearchQueryContext'; +import { MetricAggregationsEditor } from './MetricAggregationsEditor'; +import { metricAggregationConfig } from './MetricAggregationsEditor/utils'; +import { changeAliasPattern, changeQuery } from './state'; export type ElasticQueryEditorProps = QueryEditorProps; diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/state.test.ts b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/state.test.ts index 6cb0b041b4e..bb7ea5a161f 100644 --- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/state.test.ts +++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/state.test.ts @@ -1,5 +1,7 @@ import { reducerTester } from 'test/core/redux/reducerTester'; + import { ElasticsearchQuery } from '../../types'; + import { aliasPatternReducer, changeAliasPattern, changeQuery, initQuery, queryReducer } from './state'; describe('Query Reducer', () => { diff --git a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/state.ts b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/state.ts index 8601a3b0180..98182f056d6 100644 --- a/public/app/plugins/datasource/elasticsearch/components/QueryEditor/state.ts +++ b/public/app/plugins/datasource/elasticsearch/components/QueryEditor/state.ts @@ -1,4 +1,5 @@ import { Action, createAction } from '@reduxjs/toolkit'; + import { ElasticsearchQuery } from '../../types'; /** diff --git a/public/app/plugins/datasource/elasticsearch/components/hooks/useCreatableSelectPersistedBehaviour.test.tsx b/public/app/plugins/datasource/elasticsearch/components/hooks/useCreatableSelectPersistedBehaviour.test.tsx index c8a2e756467..6196f538acd 100644 --- a/public/app/plugins/datasource/elasticsearch/components/hooks/useCreatableSelectPersistedBehaviour.test.tsx +++ b/public/app/plugins/datasource/elasticsearch/components/hooks/useCreatableSelectPersistedBehaviour.test.tsx @@ -1,8 +1,10 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; -import { Select, InlineField } from '@grafana/ui'; -import { useCreatableSelectPersistedBehaviour } from './useCreatableSelectPersistedBehaviour'; import userEvent from '@testing-library/user-event'; +import React from 'react'; + +import { Select, InlineField } from '@grafana/ui'; + +import { useCreatableSelectPersistedBehaviour } from './useCreatableSelectPersistedBehaviour'; describe('useCreatableSelectPersistedBehaviour', () => { it('Should make a Select accept custom values', async () => { diff --git a/public/app/plugins/datasource/elasticsearch/components/hooks/useCreatableSelectPersistedBehaviour.ts b/public/app/plugins/datasource/elasticsearch/components/hooks/useCreatableSelectPersistedBehaviour.ts index fd94ac0ce21..6cebb31516d 100644 --- a/public/app/plugins/datasource/elasticsearch/components/hooks/useCreatableSelectPersistedBehaviour.ts +++ b/public/app/plugins/datasource/elasticsearch/components/hooks/useCreatableSelectPersistedBehaviour.ts @@ -1,6 +1,7 @@ -import { SelectableValue } from '@grafana/data'; import { useState } from 'react'; +import { SelectableValue } from '@grafana/data'; + const hasValue = (searchValue: T['value']) => ({ value }: T) => diff --git a/public/app/plugins/datasource/elasticsearch/configuration/ConfigEditor.test.tsx b/public/app/plugins/datasource/elasticsearch/configuration/ConfigEditor.test.tsx index ecf6cc97ea3..ce6f7a4c2b5 100644 --- a/public/app/plugins/datasource/elasticsearch/configuration/ConfigEditor.test.tsx +++ b/public/app/plugins/datasource/elasticsearch/configuration/ConfigEditor.test.tsx @@ -1,7 +1,9 @@ -import React from 'react'; import { mount, shallow } from 'enzyme'; -import { ConfigEditor } from './ConfigEditor'; +import React from 'react'; + import { DataSourceHttpSettings } from '@grafana/ui'; + +import { ConfigEditor } from './ConfigEditor'; import { ElasticDetails } from './ElasticDetails'; import { LogsConfig } from './LogsConfig'; import { createDefaultConfigOptions } from './mocks'; diff --git a/public/app/plugins/datasource/elasticsearch/configuration/ConfigEditor.tsx b/public/app/plugins/datasource/elasticsearch/configuration/ConfigEditor.tsx index 003f19efed3..b1c7b9e6236 100644 --- a/public/app/plugins/datasource/elasticsearch/configuration/ConfigEditor.tsx +++ b/public/app/plugins/datasource/elasticsearch/configuration/ConfigEditor.tsx @@ -1,11 +1,14 @@ import React, { useEffect } from 'react'; -import { Alert, DataSourceHttpSettings } from '@grafana/ui'; + import { DataSourcePluginOptionsEditorProps } from '@grafana/data'; +import { Alert, DataSourceHttpSettings } from '@grafana/ui'; +import { config } from 'app/core/config'; + import { ElasticsearchOptions } from '../types'; + +import { DataLinks } from './DataLinks'; import { ElasticDetails } from './ElasticDetails'; import { LogsConfig } from './LogsConfig'; -import { DataLinks } from './DataLinks'; -import { config } from 'app/core/config'; import { coerceOptions, isValidOptions } from './utils'; export type Props = DataSourcePluginOptionsEditorProps; diff --git a/public/app/plugins/datasource/elasticsearch/configuration/DataLink.tsx b/public/app/plugins/datasource/elasticsearch/configuration/DataLink.tsx index cbd29a74d3b..69cd5fb740a 100644 --- a/public/app/plugins/datasource/elasticsearch/configuration/DataLink.tsx +++ b/public/app/plugins/datasource/elasticsearch/configuration/DataLink.tsx @@ -1,11 +1,14 @@ -import React, { Dispatch, SetStateAction, useEffect, useState } from 'react'; import { css } from '@emotion/css'; +import React, { Dispatch, SetStateAction, useEffect, useState } from 'react'; +import { usePrevious } from 'react-use'; + import { VariableSuggestion } from '@grafana/data'; import { DataSourcePicker } from '@grafana/runtime'; import { Button, LegacyForms, DataLinkInput, stylesFactory } from '@grafana/ui'; -const { FormField, Switch } = LegacyForms; + import { DataLinkConfig } from '../types'; -import { usePrevious } from 'react-use'; + +const { FormField, Switch } = LegacyForms; const getStyles = stylesFactory(() => ({ firstRow: css` diff --git a/public/app/plugins/datasource/elasticsearch/configuration/DataLinks.test.tsx b/public/app/plugins/datasource/elasticsearch/configuration/DataLinks.test.tsx index d6665b89b94..7e33ac2e2af 100644 --- a/public/app/plugins/datasource/elasticsearch/configuration/DataLinks.test.tsx +++ b/public/app/plugins/datasource/elasticsearch/configuration/DataLinks.test.tsx @@ -1,10 +1,12 @@ -import React from 'react'; import { mount } from 'enzyme'; -import { DataLinks } from './DataLinks'; -import { Button } from '@grafana/ui'; -import { DataLink } from './DataLink'; +import React from 'react'; import { act } from 'react-dom/test-utils'; +import { Button } from '@grafana/ui'; + +import { DataLink } from './DataLink'; +import { DataLinks } from './DataLinks'; + describe('DataLinks', () => { let originalGetSelection: typeof window.getSelection; beforeAll(() => { diff --git a/public/app/plugins/datasource/elasticsearch/configuration/DataLinks.tsx b/public/app/plugins/datasource/elasticsearch/configuration/DataLinks.tsx index cb92fcf5475..910cb5cb8e2 100644 --- a/public/app/plugins/datasource/elasticsearch/configuration/DataLinks.tsx +++ b/public/app/plugins/datasource/elasticsearch/configuration/DataLinks.tsx @@ -1,8 +1,11 @@ -import React from 'react'; import { css } from '@emotion/css'; -import { Button, useStyles2 } from '@grafana/ui'; +import React from 'react'; + import { GrafanaTheme2, VariableOrigin, DataLinkBuiltInVars } from '@grafana/data'; +import { Button, useStyles2 } from '@grafana/ui'; + import { DataLinkConfig } from '../types'; + import { DataLink } from './DataLink'; const getStyles = (theme: GrafanaTheme2) => { diff --git a/public/app/plugins/datasource/elasticsearch/configuration/ElasticDetails.test.tsx b/public/app/plugins/datasource/elasticsearch/configuration/ElasticDetails.test.tsx index 95996d3b892..444c41707e9 100644 --- a/public/app/plugins/datasource/elasticsearch/configuration/ElasticDetails.test.tsx +++ b/public/app/plugins/datasource/elasticsearch/configuration/ElasticDetails.test.tsx @@ -1,8 +1,9 @@ +import { render, screen } from '@testing-library/react'; import React from 'react'; +import selectEvent from 'react-select-event'; + import { ElasticDetails } from './ElasticDetails'; import { createDefaultConfigOptions } from './mocks'; -import { render, screen } from '@testing-library/react'; -import selectEvent from 'react-select-event'; describe('ElasticDetails', () => { describe('Max concurrent Shard Requests', () => { diff --git a/public/app/plugins/datasource/elasticsearch/configuration/ElasticDetails.tsx b/public/app/plugins/datasource/elasticsearch/configuration/ElasticDetails.tsx index 9fa9ef356d3..117e97b3e18 100644 --- a/public/app/plugins/datasource/elasticsearch/configuration/ElasticDetails.tsx +++ b/public/app/plugins/datasource/elasticsearch/configuration/ElasticDetails.tsx @@ -1,8 +1,11 @@ import React from 'react'; -import { FieldSet, InlineField, Input, Select, InlineSwitch } from '@grafana/ui'; -import { ElasticsearchOptions, Interval } from '../types'; -import { DataSourceSettings, SelectableValue } from '@grafana/data'; import { gte, lt, valid } from 'semver'; + +import { DataSourceSettings, SelectableValue } from '@grafana/data'; +import { FieldSet, InlineField, Input, Select, InlineSwitch } from '@grafana/ui'; + +import { ElasticsearchOptions, Interval } from '../types'; + import { isTruthy } from './utils'; const indexPatternTypes: Array> = [ diff --git a/public/app/plugins/datasource/elasticsearch/configuration/LogsConfig.test.tsx b/public/app/plugins/datasource/elasticsearch/configuration/LogsConfig.test.tsx index 4e967640d1d..861ed7cdfc1 100644 --- a/public/app/plugins/datasource/elasticsearch/configuration/LogsConfig.test.tsx +++ b/public/app/plugins/datasource/elasticsearch/configuration/LogsConfig.test.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { render, screen, fireEvent } from '@testing-library/react'; +import React from 'react'; + import { LogsConfig } from './LogsConfig'; import { createDefaultConfigOptions } from './mocks'; diff --git a/public/app/plugins/datasource/elasticsearch/configuration/LogsConfig.tsx b/public/app/plugins/datasource/elasticsearch/configuration/LogsConfig.tsx index 9694cc3759d..3f5d64038bf 100644 --- a/public/app/plugins/datasource/elasticsearch/configuration/LogsConfig.tsx +++ b/public/app/plugins/datasource/elasticsearch/configuration/LogsConfig.tsx @@ -1,5 +1,7 @@ import React from 'react'; + import { Input, InlineField, FieldSet } from '@grafana/ui'; + import { ElasticsearchOptions } from '../types'; type Props = { diff --git a/public/app/plugins/datasource/elasticsearch/configuration/mocks.ts b/public/app/plugins/datasource/elasticsearch/configuration/mocks.ts index f80d702d3e3..1d63b322bbe 100644 --- a/public/app/plugins/datasource/elasticsearch/configuration/mocks.ts +++ b/public/app/plugins/datasource/elasticsearch/configuration/mocks.ts @@ -1,6 +1,7 @@ import { DataSourceSettings } from '@grafana/data'; -import { ElasticsearchOptions } from '../types'; + import { createDatasourceSettings } from '../../../../features/datasources/mocks'; +import { ElasticsearchOptions } from '../types'; export function createDefaultConfigOptions( options?: Partial diff --git a/public/app/plugins/datasource/elasticsearch/configuration/utils.ts b/public/app/plugins/datasource/elasticsearch/configuration/utils.ts index e88d768e8f5..d476a0801a0 100644 --- a/public/app/plugins/datasource/elasticsearch/configuration/utils.ts +++ b/public/app/plugins/datasource/elasticsearch/configuration/utils.ts @@ -1,7 +1,10 @@ -import { DataSourceSettings } from '@grafana/data'; import { valid } from 'semver'; + +import { DataSourceSettings } from '@grafana/data'; + import { ElasticsearchOptions } from '../types'; import { coerceESVersion } from '../utils'; + import { defaultMaxConcurrentShardRequests } from './ElasticDetails'; export const coerceOptions = ( diff --git a/public/app/plugins/datasource/elasticsearch/datasource.test.ts b/public/app/plugins/datasource/elasticsearch/datasource.test.ts index 4881f057dc3..dca0bbfe1be 100644 --- a/public/app/plugins/datasource/elasticsearch/datasource.test.ts +++ b/public/app/plugins/datasource/elasticsearch/datasource.test.ts @@ -1,5 +1,6 @@ import { map } from 'lodash'; import { Observable, of, throwError } from 'rxjs'; + import { ArrayVector, CoreApp, @@ -16,13 +17,14 @@ import { toUtc, } from '@grafana/data'; import { BackendSrvRequest, FetchResponse } from '@grafana/runtime'; - -import { ElasticDatasource, enhanceDataFrame } from './datasource'; import { backendSrv } from 'app/core/services/backend_srv'; // will use the version in __mocks__ -import { ElasticsearchOptions, ElasticsearchQuery } from './types'; -import { Filters } from './components/QueryEditor/BucketAggregationsEditor/aggregations'; + import { createFetchResponse } from '../../../../test/helpers/createFetchResponse'; +import { Filters } from './components/QueryEditor/BucketAggregationsEditor/aggregations'; +import { ElasticDatasource, enhanceDataFrame } from './datasource'; +import { ElasticsearchOptions, ElasticsearchQuery } from './types'; + const ELASTICSEARCH_MOCK_URL = 'http://elasticsearch.local'; jest.mock('@grafana/runtime', () => ({ diff --git a/public/app/plugins/datasource/elasticsearch/datasource.ts b/public/app/plugins/datasource/elasticsearch/datasource.ts index d9837dcf364..98d5f91399b 100644 --- a/public/app/plugins/datasource/elasticsearch/datasource.ts +++ b/public/app/plugins/datasource/elasticsearch/datasource.ts @@ -2,7 +2,7 @@ import { cloneDeep, find, first as _first, isNumber, isObject, isString, map as import { generate, lastValueFrom, Observable, of, throwError } from 'rxjs'; import { catchError, first, map, mergeMap, skipWhile, throwIfEmpty } from 'rxjs/operators'; import { gte, lt, satisfies } from 'semver'; -import { BackendSrvRequest, getBackendSrv, getDataSourceSrv } from '@grafana/runtime'; + import { DataFrame, DataLink, @@ -26,27 +26,29 @@ import { TimeRange, toUtc, } from '@grafana/data'; -import LanguageProvider from './language_provider'; -import { ElasticResponse } from './elastic_response'; -import { IndexPattern } from './index_pattern'; -import { ElasticQueryBuilder } from './query_builder'; -import { defaultBucketAgg, hasMetricOfType } from './query_def'; -import { getTemplateSrv, TemplateSrv } from 'app/features/templating/template_srv'; -import { DataLinkConfig, ElasticsearchOptions, ElasticsearchQuery, TermsQuery } from './types'; +import { BackendSrvRequest, getBackendSrv, getDataSourceSrv } from '@grafana/runtime'; import { RowContextOptions } from '@grafana/ui/src/components/Logs/LogRowContextProvider'; -import { metricAggregationConfig } from './components/QueryEditor/MetricAggregationsEditor/utils'; +import { queryLogsVolume } from 'app/core/logs_model'; +import { getTemplateSrv, TemplateSrv } from 'app/features/templating/template_srv'; + +import { + BucketAggregation, + isBucketAggregationWithField, +} from './components/QueryEditor/BucketAggregationsEditor/aggregations'; +import { bucketAggregationConfig } from './components/QueryEditor/BucketAggregationsEditor/utils'; import { isMetricAggregationWithField, isPipelineAggregationWithMultipleBucketPaths, Logs, } from './components/QueryEditor/MetricAggregationsEditor/aggregations'; -import { bucketAggregationConfig } from './components/QueryEditor/BucketAggregationsEditor/utils'; -import { - BucketAggregation, - isBucketAggregationWithField, -} from './components/QueryEditor/BucketAggregationsEditor/aggregations'; +import { metricAggregationConfig } from './components/QueryEditor/MetricAggregationsEditor/utils'; +import { ElasticResponse } from './elastic_response'; +import { IndexPattern } from './index_pattern'; +import LanguageProvider from './language_provider'; +import { ElasticQueryBuilder } from './query_builder'; +import { defaultBucketAgg, hasMetricOfType } from './query_def'; +import { DataLinkConfig, ElasticsearchOptions, ElasticsearchQuery, TermsQuery } from './types'; import { coerceESVersion, getScriptValue } from './utils'; -import { queryLogsVolume } from 'app/core/logs_model'; // Those are metadata fields as defined in https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-fields.html#_identity_metadata_fields. // custom fields can start with underscores, therefore is not safe to exclude anything that starts with one. diff --git a/public/app/plugins/datasource/elasticsearch/elastic_response.ts b/public/app/plugins/datasource/elasticsearch/elastic_response.ts index b52d36e85d6..6d2952e35e5 100644 --- a/public/app/plugins/datasource/elasticsearch/elastic_response.ts +++ b/public/app/plugins/datasource/elasticsearch/elastic_response.ts @@ -1,7 +1,5 @@ import { clone, filter, find, identity, isArray, keys, map, uniq, values as _values } from 'lodash'; -import flatten from 'app/core/utils/flatten'; -import * as queryDef from './query_def'; -import TableModel from 'app/core/table_model'; + import { DataQueryResponse, DataFrame, @@ -10,14 +8,18 @@ import { MutableDataFrame, PreferredVisualisationType, } from '@grafana/data'; -import { ElasticsearchAggregation, ElasticsearchQuery } from './types'; +import TableModel from 'app/core/table_model'; +import flatten from 'app/core/utils/flatten'; + import { ExtendedStatMetaType, isMetricAggregationWithField, TopMetrics, } from './components/QueryEditor/MetricAggregationsEditor/aggregations'; -import { describeMetric, getScriptValue } from './utils'; import { metricAggregationConfig } from './components/QueryEditor/MetricAggregationsEditor/utils'; +import * as queryDef from './query_def'; +import { ElasticsearchAggregation, ElasticsearchQuery } from './types'; +import { describeMetric, getScriptValue } from './utils'; const HIGHLIGHT_TAGS_EXP = `${queryDef.highlightTags.pre}([^@]+)${queryDef.highlightTags.post}`; type TopMetricMetric = Record; diff --git a/public/app/plugins/datasource/elasticsearch/hooks/useFields.test.tsx b/public/app/plugins/datasource/elasticsearch/hooks/useFields.test.tsx index 0af4be1bb55..33ee2cea2e4 100644 --- a/public/app/plugins/datasource/elasticsearch/hooks/useFields.test.tsx +++ b/public/app/plugins/datasource/elasticsearch/hooks/useFields.test.tsx @@ -1,14 +1,17 @@ -import React, { PropsWithChildren } from 'react'; -import { ElasticDatasource } from '../datasource'; -import { from } from 'rxjs'; -import { ElasticsearchProvider } from '../components/QueryEditor/ElasticsearchQueryContext'; -import { getDefaultTimeRange } from '@grafana/data'; -import { ElasticsearchQuery } from '../types'; -import { defaultBucketAgg, defaultMetricAgg } from '../query_def'; import { renderHook } from '@testing-library/react-hooks'; -import { useFields } from './useFields'; -import { MetricAggregationType } from '../components/QueryEditor/MetricAggregationsEditor/aggregations'; +import React, { PropsWithChildren } from 'react'; +import { from } from 'rxjs'; + +import { getDefaultTimeRange } from '@grafana/data'; + import { BucketAggregationType } from '../components/QueryEditor/BucketAggregationsEditor/aggregations'; +import { ElasticsearchProvider } from '../components/QueryEditor/ElasticsearchQueryContext'; +import { MetricAggregationType } from '../components/QueryEditor/MetricAggregationsEditor/aggregations'; +import { ElasticDatasource } from '../datasource'; +import { defaultBucketAgg, defaultMetricAgg } from '../query_def'; +import { ElasticsearchQuery } from '../types'; + +import { useFields } from './useFields'; describe('useFields hook', () => { // TODO: If we move the field type to the configuration objects as described in the hook's source diff --git a/public/app/plugins/datasource/elasticsearch/hooks/useFields.ts b/public/app/plugins/datasource/elasticsearch/hooks/useFields.ts index 780b3c89fad..d4a75a1f3b9 100644 --- a/public/app/plugins/datasource/elasticsearch/hooks/useFields.ts +++ b/public/app/plugins/datasource/elasticsearch/hooks/useFields.ts @@ -1,5 +1,7 @@ import { lastValueFrom } from 'rxjs'; + import { MetricFindValue, SelectableValue } from '@grafana/data'; + import { BucketAggregationType, isBucketAggregationType, diff --git a/public/app/plugins/datasource/elasticsearch/hooks/useNextId.test.tsx b/public/app/plugins/datasource/elasticsearch/hooks/useNextId.test.tsx index 1da0067d016..fce53afa44a 100644 --- a/public/app/plugins/datasource/elasticsearch/hooks/useNextId.test.tsx +++ b/public/app/plugins/datasource/elasticsearch/hooks/useNextId.test.tsx @@ -1,10 +1,13 @@ -import React, { PropsWithChildren } from 'react'; import { renderHook } from '@testing-library/react-hooks'; -import { ElasticsearchProvider } from '../components/QueryEditor/ElasticsearchQueryContext'; -import { useNextId } from './useNextId'; -import { ElasticsearchQuery } from '../types'; +import React, { PropsWithChildren } from 'react'; + import { getDefaultTimeRange } from '@grafana/data'; +import { ElasticsearchProvider } from '../components/QueryEditor/ElasticsearchQueryContext'; +import { ElasticsearchQuery } from '../types'; + +import { useNextId } from './useNextId'; + describe('useNextId', () => { it('Should return the next available id', () => { const query: ElasticsearchQuery = { diff --git a/public/app/plugins/datasource/elasticsearch/hooks/useNextId.ts b/public/app/plugins/datasource/elasticsearch/hooks/useNextId.ts index 8d0d994e4c4..4a682c43b6a 100644 --- a/public/app/plugins/datasource/elasticsearch/hooks/useNextId.ts +++ b/public/app/plugins/datasource/elasticsearch/hooks/useNextId.ts @@ -1,6 +1,7 @@ import { useMemo } from 'react'; -import { useQuery } from '../components/QueryEditor/ElasticsearchQueryContext'; + import { BucketAggregation } from '../components/QueryEditor/BucketAggregationsEditor/aggregations'; +import { useQuery } from '../components/QueryEditor/ElasticsearchQueryContext'; import { MetricAggregation } from '../components/QueryEditor/MetricAggregationsEditor/aggregations'; const toId = (e: T): T['id'] => e.id; diff --git a/public/app/plugins/datasource/elasticsearch/hooks/useStatelessReducer.test.tsx b/public/app/plugins/datasource/elasticsearch/hooks/useStatelessReducer.test.tsx index 2543888b23e..509f027d696 100644 --- a/public/app/plugins/datasource/elasticsearch/hooks/useStatelessReducer.test.tsx +++ b/public/app/plugins/datasource/elasticsearch/hooks/useStatelessReducer.test.tsx @@ -1,5 +1,6 @@ -import React, { PropsWithChildren } from 'react'; import { renderHook } from '@testing-library/react-hooks'; +import React, { PropsWithChildren } from 'react'; + import { useStatelessReducer, useDispatch, DispatchContext, combineReducers } from './useStatelessReducer'; describe('useStatelessReducer Hook', () => { diff --git a/public/app/plugins/datasource/elasticsearch/hooks/useStatelessReducer.ts b/public/app/plugins/datasource/elasticsearch/hooks/useStatelessReducer.ts index 4bd1f7c397b..1713f6d6cfb 100644 --- a/public/app/plugins/datasource/elasticsearch/hooks/useStatelessReducer.ts +++ b/public/app/plugins/datasource/elasticsearch/hooks/useStatelessReducer.ts @@ -1,5 +1,5 @@ -import { createContext, useCallback, useContext } from 'react'; import { Action } from '@reduxjs/toolkit'; +import { createContext, useCallback, useContext } from 'react'; export type Reducer = (state: S, action: A) => S; diff --git a/public/app/plugins/datasource/elasticsearch/index_pattern.ts b/public/app/plugins/datasource/elasticsearch/index_pattern.ts index 386ebd92396..bc95849a9fa 100644 --- a/public/app/plugins/datasource/elasticsearch/index_pattern.ts +++ b/public/app/plugins/datasource/elasticsearch/index_pattern.ts @@ -1,4 +1,5 @@ import { toUtc, dateTime, DateTime, DurationUnit } from '@grafana/data'; + import { Interval } from './types'; type IntervalMap = Record< diff --git a/public/app/plugins/datasource/elasticsearch/language_provider.test.ts b/public/app/plugins/datasource/elasticsearch/language_provider.test.ts index e5864cfd954..630b2fd700d 100644 --- a/public/app/plugins/datasource/elasticsearch/language_provider.test.ts +++ b/public/app/plugins/datasource/elasticsearch/language_provider.test.ts @@ -1,9 +1,11 @@ -import LanguageProvider from './language_provider'; -import { ElasticDatasource } from './datasource'; import { AbstractLabelOperator, AbstractQuery, DataSourceInstanceSettings } from '@grafana/data'; -import { ElasticsearchOptions, ElasticsearchQuery } from './types'; + import { TemplateSrv } from '../../../features/templating/template_srv'; +import { ElasticDatasource } from './datasource'; +import LanguageProvider from './language_provider'; +import { ElasticsearchOptions, ElasticsearchQuery } from './types'; + const templateSrvStub = { getAdhocFilters: jest.fn(() => [] as any[]), replace: jest.fn((a: string) => a), diff --git a/public/app/plugins/datasource/elasticsearch/module.ts b/public/app/plugins/datasource/elasticsearch/module.ts index 1ac22e392ab..055cc2c9d64 100644 --- a/public/app/plugins/datasource/elasticsearch/module.ts +++ b/public/app/plugins/datasource/elasticsearch/module.ts @@ -1,7 +1,8 @@ import { DataSourcePlugin } from '@grafana/data'; -import { ElasticDatasource } from './datasource'; -import { ConfigEditor } from './configuration/ConfigEditor'; + import { QueryEditor } from './components/QueryEditor'; +import { ConfigEditor } from './configuration/ConfigEditor'; +import { ElasticDatasource } from './datasource'; class ElasticAnnotationsQueryCtrl { static templateUrl = 'partials/annotations.editor.html'; diff --git a/public/app/plugins/datasource/elasticsearch/query_builder.ts b/public/app/plugins/datasource/elasticsearch/query_builder.ts index 0f21c96b6f6..8727f3cb80d 100644 --- a/public/app/plugins/datasource/elasticsearch/query_builder.ts +++ b/public/app/plugins/datasource/elasticsearch/query_builder.ts @@ -1,5 +1,7 @@ -import { InternalTimeZones } from '@grafana/data'; import { gte, lt } from 'semver'; + +import { InternalTimeZones } from '@grafana/data'; + import { Filters, Histogram, diff --git a/public/app/plugins/datasource/elasticsearch/specs/elastic_response.test.ts b/public/app/plugins/datasource/elasticsearch/specs/elastic_response.test.ts index d7377b8a805..6232fc526e9 100644 --- a/public/app/plugins/datasource/elasticsearch/specs/elastic_response.test.ts +++ b/public/app/plugins/datasource/elasticsearch/specs/elastic_response.test.ts @@ -1,8 +1,9 @@ import { DataFrameView, FieldCache, KeyValue, MutableDataFrame } from '@grafana/data'; -import { ElasticResponse } from '../elastic_response'; import flatten from 'app/core/utils/flatten'; -import { ElasticsearchQuery } from '../types'; + +import { ElasticResponse } from '../elastic_response'; import { highlightTags } from '../query_def'; +import { ElasticsearchQuery } from '../types'; describe('ElasticResponse', () => { let targets: ElasticsearchQuery[]; diff --git a/public/app/plugins/datasource/elasticsearch/specs/index_pattern.test.ts b/public/app/plugins/datasource/elasticsearch/specs/index_pattern.test.ts index 76a96794dd3..0fa98df9696 100644 --- a/public/app/plugins/datasource/elasticsearch/specs/index_pattern.test.ts +++ b/public/app/plugins/datasource/elasticsearch/specs/index_pattern.test.ts @@ -1,8 +1,9 @@ /// -import { IndexPattern } from '../index_pattern'; import { toUtc, getLocale, setLocale, dateTime } from '@grafana/data'; +import { IndexPattern } from '../index_pattern'; + describe('IndexPattern', () => { const originalLocale = getLocale(); afterEach(() => setLocale(originalLocale)); diff --git a/public/app/plugins/datasource/elasticsearch/specs/query_builder.test.ts b/public/app/plugins/datasource/elasticsearch/specs/query_builder.test.ts index 1ed2b6d3540..f3c00db43cf 100644 --- a/public/app/plugins/datasource/elasticsearch/specs/query_builder.test.ts +++ b/public/app/plugins/datasource/elasticsearch/specs/query_builder.test.ts @@ -1,4 +1,5 @@ import { gte, lt } from 'semver'; + import { ElasticQueryBuilder } from '../query_builder'; import { ElasticsearchQuery } from '../types'; diff --git a/public/app/plugins/datasource/elasticsearch/test-helpers/render.tsx b/public/app/plugins/datasource/elasticsearch/test-helpers/render.tsx index 1b5e68db9f8..236f8e65c11 100644 --- a/public/app/plugins/datasource/elasticsearch/test-helpers/render.tsx +++ b/public/app/plugins/datasource/elasticsearch/test-helpers/render.tsx @@ -1,8 +1,10 @@ -import React, { ComponentProps, ReactNode } from 'react'; import { render } from '@testing-library/react'; +import React, { ComponentProps, ReactNode } from 'react'; + import { getDefaultTimeRange } from '@grafana/data'; -import { ElasticDatasource } from '../datasource'; + import { ElasticsearchProvider } from '../components/QueryEditor/ElasticsearchQueryContext'; +import { ElasticDatasource } from '../datasource'; const defaultProviderProps = { datasource: {} as ElasticDatasource, diff --git a/public/app/plugins/datasource/elasticsearch/types.ts b/public/app/plugins/datasource/elasticsearch/types.ts index 8b0cd31af18..758acd48bf1 100644 --- a/public/app/plugins/datasource/elasticsearch/types.ts +++ b/public/app/plugins/datasource/elasticsearch/types.ts @@ -1,4 +1,5 @@ import { DataQuery, DataSourceJsonData } from '@grafana/data'; + import { BucketAggregation, BucketAggregationType, diff --git a/public/app/plugins/datasource/elasticsearch/utils.ts b/public/app/plugins/datasource/elasticsearch/utils.ts index e7969adb974..24280b2abb5 100644 --- a/public/app/plugins/datasource/elasticsearch/utils.ts +++ b/public/app/plugins/datasource/elasticsearch/utils.ts @@ -1,10 +1,11 @@ +import { valid } from 'semver'; + import { isMetricAggregationWithField, MetricAggregation, MetricAggregationWithInlineScript, } from './components/QueryEditor/MetricAggregationsEditor/aggregations'; import { metricAggregationConfig } from './components/QueryEditor/MetricAggregationsEditor/utils'; -import { valid } from 'semver'; export const describeMetric = (metric: MetricAggregation) => { if (!isMetricAggregationWithField(metric)) { diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/__mocks__/instanceSettings.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/__mocks__/instanceSettings.ts index 6857d6e0c5c..caf93081ac1 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/__mocks__/instanceSettings.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/__mocks__/instanceSettings.ts @@ -1,4 +1,5 @@ import { DataSourcePluginMeta } from '@grafana/data'; + import { AzureDataSourceInstanceSettings } from '../types'; export const createMockInstanceSetttings = (): AzureDataSourceInstanceSettings => ({ diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_log_analytics/azure_log_analytics_datasource.test.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_log_analytics/azure_log_analytics_datasource.test.ts index 9f3a7fd0903..5da7a4ab09f 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_log_analytics/azure_log_analytics_datasource.test.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_log_analytics/azure_log_analytics_datasource.test.ts @@ -5,6 +5,7 @@ import createMockQuery from '../__mocks__/query'; import { singleVariable } from '../__mocks__/variables'; import AzureMonitorDatasource from '../datasource'; import { AzureMonitorQuery, AzureQueryType, DatasourceValidationResult } from '../types'; + import FakeSchemaData from './__mocks__/schema'; import AzureLogAnalyticsDatasource from './azure_log_analytics_datasource'; diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_log_analytics/azure_log_analytics_datasource.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_log_analytics/azure_log_analytics_datasource.ts index 6f1ece771ba..192f84692bc 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_log_analytics/azure_log_analytics_datasource.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_log_analytics/azure_log_analytics_datasource.ts @@ -1,3 +1,7 @@ +import { map } from 'lodash'; +import { from, Observable } from 'rxjs'; +import { mergeMap } from 'rxjs/operators'; + import { DataQueryRequest, DataQueryResponse, @@ -6,9 +10,6 @@ import { ScopedVars, } from '@grafana/data'; import { DataSourceWithBackend, getTemplateSrv } from '@grafana/runtime'; -import { map } from 'lodash'; -import { from, Observable } from 'rxjs'; -import { mergeMap } from 'rxjs/operators'; import { isGUIDish } from '../components/ResourcePicker/utils'; import { getAuthType, getAzureCloud, getAzurePortalUrl } from '../credentials'; @@ -21,6 +22,7 @@ import { DatasourceValidationResult, } from '../types'; import { interpolateVariable, routeNames } from '../utils/common'; + import ResponseParser, { transformMetadataToKustoSchema } from './response_parser'; interface AdhocQuery { diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_log_analytics/response_parser.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_log_analytics/response_parser.ts index bce81329529..8d70eeea6de 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_log_analytics/response_parser.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_log_analytics/response_parser.ts @@ -1,6 +1,7 @@ -import { AnnotationEvent, dateTime, TimeSeries, VariableModel } from '@grafana/data'; import { concat, find, flattenDeep, forEach, get, map } from 'lodash'; +import { AnnotationEvent, dateTime, TimeSeries, VariableModel } from '@grafana/data'; + import { AzureLogsTableData, AzureLogsVariable } from '../types'; import { AzureLogAnalyticsMetadata } from '../types/logAnalyticsMetadata'; diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_datasource.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_datasource.ts index 8e257114e0b..fbc474e63ac 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_datasource.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_datasource.ts @@ -1,7 +1,8 @@ +import { filter, startsWith } from 'lodash'; + import { DataSourceInstanceSettings, ScopedVars } from '@grafana/data'; import { DataSourceWithBackend, getTemplateSrv } from '@grafana/runtime'; import { getTimeSrv, TimeSrv } from 'app/features/dashboard/services/TimeSrv'; -import { filter, startsWith } from 'lodash'; import { resourceTypeDisplayNames } from '../azureMetadata'; import { getAuthType, getAzureCloud, getAzurePortalUrl } from '../credentials'; @@ -21,6 +22,7 @@ import { GetMetricMetadataQuery, } from '../types'; import { routeNames } from '../utils/common'; + import ResponseParser from './response_parser'; import SupportedNamespaces from './supported_namespaces'; import UrlBuilder from './url_builder'; diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/response_parser.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/response_parser.ts index c2011e53967..640a127591e 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/response_parser.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/response_parser.ts @@ -1,4 +1,5 @@ import { find, get } from 'lodash'; + import TimeGrainConverter from '../time_grain_converter'; import { AzureMonitorLocalizedValue, diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_resource_graph/azure_resource_graph_datasource.test.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_resource_graph/azure_resource_graph_datasource.test.ts index d5ac3c2ca60..a0e3f2514aa 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_resource_graph/azure_resource_graph_datasource.test.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_resource_graph/azure_resource_graph_datasource.test.ts @@ -1,10 +1,12 @@ -import { TemplateSrv } from 'app/features/templating/template_srv'; import { backendSrv } from 'app/core/services/backend_srv'; -import AzureResourceGraphDatasource from './azure_resource_graph_datasource'; -import { multiVariable, singleVariable, subscriptionsVariable } from '../__mocks__/variables'; -import { AzureQueryType } from '../types'; -import AzureMonitorDatasource from '../datasource'; +import { TemplateSrv } from 'app/features/templating/template_srv'; + import createMockQuery from '../__mocks__/query'; +import { multiVariable, singleVariable, subscriptionsVariable } from '../__mocks__/variables'; +import AzureMonitorDatasource from '../datasource'; +import { AzureQueryType } from '../types'; + +import AzureResourceGraphDatasource from './azure_resource_graph_datasource'; const templateSrv = new TemplateSrv({ getVariables: () => [subscriptionsVariable, singleVariable, multiVariable], diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_resource_graph/azure_resource_graph_datasource.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_resource_graph/azure_resource_graph_datasource.ts index e768b9d2d77..5543b2baee7 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_resource_graph/azure_resource_graph_datasource.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_resource_graph/azure_resource_graph_datasource.ts @@ -1,8 +1,10 @@ // eslint-disable-next-line lodash/import-scope import _ from 'lodash'; -import { AzureMonitorQuery, AzureDataSourceJsonData, AzureQueryType } from '../types'; + import { ScopedVars } from '@grafana/data'; import { getTemplateSrv, DataSourceWithBackend } from '@grafana/runtime'; + +import { AzureMonitorQuery, AzureDataSourceJsonData, AzureQueryType } from '../types'; import { interpolateVariable } from '../utils/common'; export default class AzureResourceGraphDatasource extends DataSourceWithBackend< diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ArgQueryEditor/ArgQueryEditor.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ArgQueryEditor/ArgQueryEditor.tsx index 490af50d0b9..cfc0dbba3f4 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ArgQueryEditor/ArgQueryEditor.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ArgQueryEditor/ArgQueryEditor.tsx @@ -1,8 +1,11 @@ import React, { useEffect, useState, useRef } from 'react'; -import { AzureMonitorErrorish, AzureMonitorOption, AzureMonitorQuery } from '../../types'; -import Datasource from '../../datasource'; + import { InlineFieldRow } from '@grafana/ui'; + +import Datasource from '../../datasource'; +import { AzureMonitorErrorish, AzureMonitorOption, AzureMonitorQuery } from '../../types'; import SubscriptionField from '../SubscriptionField'; + import QueryField from './QueryField'; interface LogsQueryEditorProps { diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ArgQueryEditor/QueryField.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ArgQueryEditor/QueryField.tsx index 9f05f8a16ee..9ce83b50797 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ArgQueryEditor/QueryField.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ArgQueryEditor/QueryField.tsx @@ -1,5 +1,7 @@ -import { CodeEditor } from '@grafana/ui'; import React, { useCallback } from 'react'; + +import { CodeEditor } from '@grafana/ui'; + import { AzureQueryEditorFieldProps } from '../../types'; const QueryField: React.FC = ({ query, onQueryChange }) => { diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/AzureCredentialsForm.test.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/AzureCredentialsForm.test.tsx index 3afa70a9763..5b4f4f0e061 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/AzureCredentialsForm.test.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/AzureCredentialsForm.test.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { render, screen, waitFor } from '@testing-library/react'; +import React from 'react'; + import AzureCredentialsForm, { Props } from './AzureCredentialsForm'; const setup = (propsFunc?: (props: Props) => Props) => { diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/AzureCredentialsForm.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/AzureCredentialsForm.tsx index 2d7429cbdc0..caebcda67dc 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/AzureCredentialsForm.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/AzureCredentialsForm.tsx @@ -1,8 +1,10 @@ import React, { ChangeEvent, FunctionComponent, useEffect, useReducer, useState } from 'react'; + import { SelectableValue } from '@grafana/data'; import { InlineFormLabel, LegacyForms, Button, Select } from '@grafana/ui'; -import { AzureAuthType, AzureCredentials } from '../types'; + import { isCredentialsComplete } from '../credentials'; +import { AzureAuthType, AzureCredentials } from '../types'; const { Input } = LegacyForms; export interface Props { diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ConfigEditor.test.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ConfigEditor.test.tsx index 688a560d000..39c29eb5098 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ConfigEditor.test.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ConfigEditor.test.tsx @@ -1,5 +1,6 @@ import { render, screen } from '@testing-library/react'; import React from 'react'; + import ConfigEditor from './ConfigEditor'; describe('AppInsights ConfigEditor', () => { diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ConfigEditor.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ConfigEditor.tsx index 07bf6c63827..685c313c390 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ConfigEditor.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ConfigEditor.tsx @@ -1,15 +1,17 @@ +import React, { PureComponent } from 'react'; + import { DataSourcePluginOptionsEditorProps, SelectableValue, updateDatasourcePluginOption } from '@grafana/data'; import { getBackendSrv, getTemplateSrv, TemplateSrv } from '@grafana/runtime'; import { Alert } from '@grafana/ui'; -import React, { PureComponent } from 'react'; import ResponseParser from '../azure_monitor/response_parser'; import { AzureDataSourceJsonData, AzureDataSourceSecureJsonData, AzureDataSourceSettings } from '../types'; import { routeNames } from '../utils/common'; + +import { MonitorConfig } from './MonitorConfig'; import { AnalyticsConfig } from './deprecated/components/AnalyticsConfig'; import { InsightsConfig } from './deprecated/components/InsightsConfig'; import { gtGrafana9, isAppInsightsConfigured } from './deprecated/utils'; -import { MonitorConfig } from './MonitorConfig'; export type Props = DataSourcePluginOptionsEditorProps; diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/Field.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/Field.tsx index 6105bbc02eb..a40992d93a6 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/Field.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/Field.tsx @@ -1,5 +1,6 @@ -import { InlineField } from '@grafana/ui'; import React from 'react'; + +import { InlineField } from '@grafana/ui'; import { Props as InlineFieldProps } from '@grafana/ui/src/components/Forms/InlineField'; const DEFAULT_LABEL_WIDTH = 18; diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/LogsQueryEditor/FormatAsField.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/LogsQueryEditor/FormatAsField.tsx index 727bc5420e2..75c86f58680 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/LogsQueryEditor/FormatAsField.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/LogsQueryEditor/FormatAsField.tsx @@ -1,8 +1,11 @@ import React, { useCallback, useMemo } from 'react'; + import { SelectableValue } from '@grafana/data'; import { Select } from '@grafana/ui'; + import { AzureQueryEditorFieldProps } from '../../types'; import { Field } from '../Field'; + import { setFormatAs } from './setQueryValue'; const FORMAT_OPTIONS: Array> = [ diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/LogsQueryEditor/LogsQueryEditor.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/LogsQueryEditor/LogsQueryEditor.tsx index 4e63ac97ed5..d81ac96920b 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/LogsQueryEditor/LogsQueryEditor.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/LogsQueryEditor/LogsQueryEditor.tsx @@ -1,13 +1,16 @@ import React from 'react'; -import { AzureMonitorErrorish, AzureMonitorOption, AzureMonitorQuery } from '../../types'; -import Datasource from '../../datasource'; + import { Alert, InlineFieldRow } from '@grafana/ui'; -import { ResourceRowType } from '../ResourcePicker/types'; + +import Datasource from '../../datasource'; +import { AzureMonitorErrorish, AzureMonitorOption, AzureMonitorQuery } from '../../types'; import ResourceField from '../ResourceField'; -import QueryField from './QueryField'; +import { ResourceRowType } from '../ResourcePicker/types'; + import FormatAsField from './FormatAsField'; -import useMigrations from './useMigrations'; +import QueryField from './QueryField'; import { setResource } from './setQueryValue'; +import useMigrations from './useMigrations'; interface LogsQueryEditorProps { query: AzureMonitorQuery; diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/LogsQueryEditor/QueryField.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/LogsQueryEditor/QueryField.tsx index b435ca4955f..9c32ea61699 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/LogsQueryEditor/QueryField.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/LogsQueryEditor/QueryField.tsx @@ -1,8 +1,10 @@ -import { CodeEditor, Monaco, MonacoEditor } from '@grafana/ui'; -import { Deferred } from 'app/core/utils/deferred'; import React, { useCallback, useEffect, useRef } from 'react'; +import { CodeEditor, Monaco, MonacoEditor } from '@grafana/ui'; +import { Deferred } from 'app/core/utils/deferred'; + import { AzureQueryEditorFieldProps } from '../../types'; + import { setKustoQuery } from './setQueryValue'; interface MonacoPromise { diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/LogsQueryEditor/useMigrations.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/LogsQueryEditor/useMigrations.ts index f91af739520..33ba224000e 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/LogsQueryEditor/useMigrations.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/LogsQueryEditor/useMigrations.ts @@ -1,6 +1,7 @@ import { useEffect, useState } from 'react'; -import { AzureMonitorQuery } from '../../types'; + import Datasource from '../../datasource'; +import { AzureMonitorQuery } from '../../types'; import { isGUIDish } from '../ResourcePicker/utils'; async function migrateWorkspaceQueryToResourceQuery( diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/AggregationField.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/AggregationField.tsx index 3d921b7fc43..abdc1bda308 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/AggregationField.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/AggregationField.tsx @@ -1,9 +1,11 @@ import React, { useCallback, useMemo } from 'react'; -import { Select } from '@grafana/ui'; -import { SelectableValue } from '@grafana/data'; -import { Field } from '../Field'; +import { SelectableValue } from '@grafana/data'; +import { Select } from '@grafana/ui'; + import { AzureQueryEditorFieldProps, AzureMonitorOption } from '../../types'; +import { Field } from '../Field'; + import { setAggregation } from './setQueryValue'; interface AggregationFieldProps extends AzureQueryEditorFieldProps { diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/DimensionFields.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/DimensionFields.tsx index c53138d86a5..664c9b31f61 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/DimensionFields.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/DimensionFields.tsx @@ -1,8 +1,10 @@ import React, { useMemo } from 'react'; + import { Button, Select, Input, HorizontalGroup, VerticalGroup, InlineLabel } from '@grafana/ui'; -import { Field } from '../Field'; import { AzureMetricDimension, AzureMonitorOption, AzureQueryEditorFieldProps } from '../../types'; +import { Field } from '../Field'; + import { appendDimensionFilter, removeDimensionFilter, setDimensionFilterValue } from './setQueryValue'; interface DimensionFieldsProps extends AzureQueryEditorFieldProps { diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/LegendFormatField.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/LegendFormatField.tsx index 4b8522819f6..31ddc067e9b 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/LegendFormatField.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/LegendFormatField.tsx @@ -1,8 +1,10 @@ import React, { useCallback, useState } from 'react'; + import { Input } from '@grafana/ui'; -import { Field } from '../Field'; import { AzureQueryEditorFieldProps } from '../../types'; +import { Field } from '../Field'; + import { setLegendAlias } from './setQueryValue'; const LegendFormatField: React.FC = ({ onQueryChange, query }) => { diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/MetricNameField.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/MetricNameField.tsx index f7ec6d3b2b1..5cd903b7875 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/MetricNameField.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/MetricNameField.tsx @@ -1,9 +1,11 @@ import React, { useCallback, useMemo } from 'react'; -import { Select } from '@grafana/ui'; -import { SelectableValue } from '@grafana/data'; -import { Field } from '../Field'; +import { SelectableValue } from '@grafana/data'; +import { Select } from '@grafana/ui'; + import { AzureQueryEditorFieldProps, AzureMonitorOption } from '../../types'; +import { Field } from '../Field'; + import { setMetricName } from './setQueryValue'; interface MetricNameProps extends AzureQueryEditorFieldProps { diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/MetricNamespaceField.test.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/MetricNamespaceField.test.tsx index 7fbd74de615..0f4ccda07bd 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/MetricNamespaceField.test.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/MetricNamespaceField.test.tsx @@ -1,10 +1,12 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; -import MetricNamespaceField from './MetricNamespaceField'; -import createMockQuery from '../../__mocks__/query'; +import React from 'react'; + import createMockDatasource from '../../__mocks__/datasource'; +import createMockQuery from '../../__mocks__/query'; import { AzureMonitorOption } from '../../types'; +import MetricNamespaceField from './MetricNamespaceField'; + const props = { metricNamespaces: [], query: createMockQuery(), diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/MetricNamespaceField.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/MetricNamespaceField.tsx index 579d34dff33..8dff6139894 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/MetricNamespaceField.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/MetricNamespaceField.tsx @@ -1,9 +1,11 @@ import React, { useCallback, useMemo } from 'react'; -import { Select } from '@grafana/ui'; -import { SelectableValue } from '@grafana/data'; -import { Field } from '../Field'; +import { SelectableValue } from '@grafana/data'; +import { Select } from '@grafana/ui'; + import { AzureQueryEditorFieldProps, AzureMonitorOption } from '../../types'; +import { Field } from '../Field'; + import { setMetricNamespace } from './setQueryValue'; interface MetricNamespaceFieldProps extends AzureQueryEditorFieldProps { diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/MetricsQueryEditor.test.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/MetricsQueryEditor.test.tsx index 76f0c7e8f9c..fde54f35f09 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/MetricsQueryEditor.test.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/MetricsQueryEditor.test.tsx @@ -1,11 +1,12 @@ -import React from 'react'; import { render, screen, waitFor } from '@testing-library/react'; +import React from 'react'; + import { selectOptionInTest } from '@grafana/ui'; -import MetricsQueryEditor from './MetricsQueryEditor'; - -import createMockQuery from '../../__mocks__/query'; import createMockDatasource from '../../__mocks__/datasource'; +import createMockQuery from '../../__mocks__/query'; + +import MetricsQueryEditor from './MetricsQueryEditor'; const variableOptionGroup = { label: 'Template variables', diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/MetricsQueryEditor.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/MetricsQueryEditor.tsx index bfbcd9091ff..d2a2adedab8 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/MetricsQueryEditor.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/MetricsQueryEditor.tsx @@ -1,19 +1,21 @@ import React from 'react'; +import { InlineFieldRow } from '@grafana/ui'; + import Datasource from '../../datasource'; import { AzureMonitorQuery, AzureMonitorOption, AzureMonitorErrorish } from '../../types'; import SubscriptionField from '../SubscriptionField'; + +import AggregationField from './AggregationField'; +import DimensionFields from './DimensionFields'; +import LegendFormatField from './LegendFormatField'; +import MetricNameField from './MetricNameField'; import MetricNamespaceField from './MetricNamespaceField'; -import ResourceTypeField from './ResourceTypeField'; import ResourceGroupsField from './ResourceGroupsField'; import ResourceNameField from './ResourceNameField'; -import MetricNameField from './MetricNameField'; -import AggregationField from './AggregationField'; +import ResourceTypeField from './ResourceTypeField'; import TimeGrainField from './TimeGrainField'; -import DimensionFields from './DimensionFields'; import TopField from './TopField'; -import LegendFormatField from './LegendFormatField'; -import { InlineFieldRow } from '@grafana/ui'; import { useMetricNames, useMetricNamespaces, diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/ResourceGroupsField.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/ResourceGroupsField.tsx index 8b052c9d4c8..83bf5c6d7ae 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/ResourceGroupsField.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/ResourceGroupsField.tsx @@ -1,9 +1,11 @@ import React, { useCallback, useMemo } from 'react'; -import { Select } from '@grafana/ui'; -import { SelectableValue } from '@grafana/data'; -import { Field } from '../Field'; +import { SelectableValue } from '@grafana/data'; +import { Select } from '@grafana/ui'; + import { AzureQueryEditorFieldProps, AzureMonitorOption } from '../../types'; +import { Field } from '../Field'; + import { setResourceGroup } from './setQueryValue'; interface ResourceGroupsFieldProps extends AzureQueryEditorFieldProps { diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/ResourceNameField.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/ResourceNameField.tsx index 63c3c5780b2..9736ff704f7 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/ResourceNameField.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/ResourceNameField.tsx @@ -1,9 +1,11 @@ import React, { useCallback, useMemo } from 'react'; -import { Select } from '@grafana/ui'; -import { SelectableValue } from '@grafana/data'; -import { Field } from '../Field'; +import { SelectableValue } from '@grafana/data'; +import { Select } from '@grafana/ui'; + import { AzureQueryEditorFieldProps, AzureMonitorOption } from '../../types'; +import { Field } from '../Field'; + import { setResourceName } from './setQueryValue'; interface ResourceNameFieldProps extends AzureQueryEditorFieldProps { diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/ResourceTypeField.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/ResourceTypeField.tsx index f7abefb9cdb..ed7671ad2af 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/ResourceTypeField.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/ResourceTypeField.tsx @@ -1,9 +1,11 @@ import React, { useCallback, useMemo } from 'react'; -import { Select } from '@grafana/ui'; -import { SelectableValue } from '@grafana/data'; -import { Field } from '../Field'; +import { SelectableValue } from '@grafana/data'; +import { Select } from '@grafana/ui'; + import { AzureQueryEditorFieldProps, AzureMonitorOption } from '../../types'; +import { Field } from '../Field'; + import { setResourceType } from './setQueryValue'; interface NamespaceFieldProps extends AzureQueryEditorFieldProps { diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/TimeGrainField.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/TimeGrainField.tsx index b3cd7cb7914..d48fb0e2bb8 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/TimeGrainField.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/TimeGrainField.tsx @@ -1,10 +1,12 @@ import React, { useCallback, useMemo } from 'react'; -import { Select } from '@grafana/ui'; -import { SelectableValue } from '@grafana/data'; -import { Field } from '../Field'; +import { SelectableValue } from '@grafana/data'; +import { Select } from '@grafana/ui'; + import TimegrainConverter from '../../time_grain_converter'; import { AzureQueryEditorFieldProps, AzureMonitorOption } from '../../types'; +import { Field } from '../Field'; + import { setTimeGrain } from './setQueryValue'; interface TimeGrainFieldProps extends AzureQueryEditorFieldProps { diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/TopField.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/TopField.tsx index d384a42f0be..b13a41f2517 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/TopField.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/TopField.tsx @@ -1,8 +1,10 @@ import React, { useCallback, useState } from 'react'; + import { Input } from '@grafana/ui'; -import { Field } from '../Field'; import { AzureQueryEditorFieldProps } from '../../types'; +import { Field } from '../Field'; + import { setTop } from './setQueryValue'; const TopField: React.FC = ({ onQueryChange, query }) => { diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/dataHooks.test.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/dataHooks.test.ts index 97a50e4bb6a..1c7f84d40da 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/dataHooks.test.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/dataHooks.test.ts @@ -3,6 +3,7 @@ import { renderHook } from '@testing-library/react-hooks'; import createMockDatasource from '../../__mocks__/datasource'; import Datasource from '../../datasource'; import { AzureMetricQuery, AzureMonitorOption, AzureMonitorQuery, AzureQueryType } from '../../types'; + import { DataHook, updateSubscriptions, diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/dataHooks.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/dataHooks.ts index 76259355994..146bab298da 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/dataHooks.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MetricsQueryEditor/dataHooks.ts @@ -4,6 +4,7 @@ import Datasource from '../../datasource'; import { AzureMonitorErrorish, AzureMonitorOption, AzureMonitorQuery } from '../../types'; import { hasOption, toOption } from '../../utils/common'; import { useAsyncState } from '../../utils/useAsyncState'; + import { setMetricNamespace, setSubscriptionID } from './setQueryValue'; export interface MetricMetadata { diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MonitorConfig.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MonitorConfig.tsx index aeaf1514c73..3f92cea8f1c 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MonitorConfig.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/MonitorConfig.tsx @@ -1,9 +1,12 @@ import React, { FunctionComponent, useMemo } from 'react'; + import { SelectableValue } from '@grafana/data'; import { config } from '@grafana/runtime'; -import { AzureCredentialsForm } from './AzureCredentialsForm'; -import { AzureDataSourceSettings, AzureCredentials } from '../types'; + import { getCredentials, updateCredentials } from '../credentials'; +import { AzureDataSourceSettings, AzureCredentials } from '../types'; + +import { AzureCredentialsForm } from './AzureCredentialsForm'; const azureClouds = [ { value: 'azuremonitor', label: 'Azure' }, diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/NewMetricsQueryEditor/MetricsQueryEditor.test.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/NewMetricsQueryEditor/MetricsQueryEditor.test.tsx index d39c0e787c7..4a0400bec9e 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/NewMetricsQueryEditor/MetricsQueryEditor.test.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/NewMetricsQueryEditor/MetricsQueryEditor.test.tsx @@ -1,11 +1,11 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import React from 'react'; + import { selectOptionInTest } from '@grafana/ui'; -import MetricsQueryEditor from './MetricsQueryEditor'; -import createMockQuery from '../../__mocks__/query'; import createMockDatasource from '../../__mocks__/datasource'; +import createMockQuery from '../../__mocks__/query'; import createMockResourcePickerData from '../../__mocks__/resourcePickerData'; import { createMockResourceGroupsBySubscription, @@ -13,6 +13,8 @@ import { mockResourcesByResourceGroup, } from '../../__mocks__/resourcePickerRows'; +import MetricsQueryEditor from './MetricsQueryEditor'; + const variableOptionGroup = { label: 'Template variables', options: [], diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/NewMetricsQueryEditor/MetricsQueryEditor.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/NewMetricsQueryEditor/MetricsQueryEditor.tsx index 97e6bb3b0e1..7b77f645cea 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/NewMetricsQueryEditor/MetricsQueryEditor.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/NewMetricsQueryEditor/MetricsQueryEditor.tsx @@ -1,18 +1,21 @@ import React from 'react'; + import { InlineFieldRow } from '@grafana/ui'; + +import type Datasource from '../../datasource'; +import type { AzureMonitorQuery, AzureMonitorOption, AzureMonitorErrorish } from '../../types'; import AggregationField from '../MetricsQueryEditor/AggregationField'; +import DimensionFields from '../MetricsQueryEditor/DimensionFields'; +import LegendFormatField from '../MetricsQueryEditor/LegendFormatField'; import MetricNameField from '../MetricsQueryEditor/MetricNameField'; import MetricNamespaceField from '../MetricsQueryEditor/MetricNamespaceField'; import TimeGrainField from '../MetricsQueryEditor/TimeGrainField'; -import DimensionFields from '../MetricsQueryEditor/DimensionFields'; import TopField from '../MetricsQueryEditor/TopField'; -import LegendFormatField from '../MetricsQueryEditor/LegendFormatField'; +import { setResource } from '../MetricsQueryEditor/setQueryValue'; import ResourceField from '../ResourceField'; import { ResourceRowType } from '../ResourcePicker/types'; -import type Datasource from '../../datasource'; -import type { AzureMonitorQuery, AzureMonitorOption, AzureMonitorErrorish } from '../../types'; + import { useMetricNames, useMetricNamespaces, useMetricMetadata } from './dataHooks'; -import { setResource } from '../MetricsQueryEditor/setQueryValue'; interface MetricsQueryEditorProps { query: AzureMonitorQuery; diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/NewMetricsQueryEditor/dataHooks.test.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/NewMetricsQueryEditor/dataHooks.test.ts index b50d71a24af..fc27d5077f3 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/NewMetricsQueryEditor/dataHooks.test.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/NewMetricsQueryEditor/dataHooks.test.ts @@ -4,6 +4,7 @@ import createMockDatasource from '../../__mocks__/datasource'; import Datasource from '../../datasource'; import { AzureMetricQuery, AzureMonitorOption, AzureMonitorQuery, AzureQueryType } from '../../types'; import { DataHook } from '../MetricsQueryEditor/dataHooks'; + import { useMetricNames, useMetricNamespaces } from './dataHooks'; const WAIT_OPTIONS = { diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/QueryEditor/QueryEditor.test.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/QueryEditor/QueryEditor.test.tsx index 891327b463d..1ef54499861 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/QueryEditor/QueryEditor.test.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/QueryEditor/QueryEditor.test.tsx @@ -1,13 +1,15 @@ -import * as ui from '@grafana/ui'; -import { config } from '@grafana/runtime'; import { render, screen, waitFor } from '@testing-library/react'; import React from 'react'; import selectEvent from 'react-select-event'; +import { config } from '@grafana/runtime'; +import * as ui from '@grafana/ui'; + import createMockDatasource from '../../__mocks__/datasource'; import { invalidNamespaceError } from '../../__mocks__/errors'; import createMockQuery from '../../__mocks__/query'; import { AzureQueryType, DeprecatedAzureQueryType } from '../../types'; + import QueryEditor from './QueryEditor'; // Have to mock CodeEditor because it doesnt seem to work in tests??? diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/QueryEditor/QueryEditor.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/QueryEditor/QueryEditor.tsx index dbc618bc6bf..f0d168ef5c6 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/QueryEditor/QueryEditor.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/QueryEditor/QueryEditor.tsx @@ -1,10 +1,10 @@ -import { QueryEditorProps } from '@grafana/data'; -import { Alert } from '@grafana/ui'; -import { config } from '@grafana/runtime'; - import { debounce } from 'lodash'; import React, { useCallback, useMemo } from 'react'; +import { QueryEditorProps } from '@grafana/data'; +import { config } from '@grafana/runtime'; +import { Alert } from '@grafana/ui'; + import AzureMonitorDatasource from '../../datasource'; import { AzureDataSourceJsonData, @@ -16,13 +16,14 @@ import { } from '../../types'; import useLastError from '../../utils/useLastError'; import ArgQueryEditor from '../ArgQueryEditor'; -import ApplicationInsightsEditor from '../deprecated/components/ApplicationInsightsEditor'; -import InsightsAnalyticsEditor from '../deprecated/components/InsightsAnalyticsEditor'; -import { gtGrafana9 } from '../deprecated/utils'; import LogsQueryEditor from '../LogsQueryEditor'; import MetricsQueryEditor from '../MetricsQueryEditor'; import NewMetricsQueryEditor from '../NewMetricsQueryEditor/MetricsQueryEditor'; import { Space } from '../Space'; +import ApplicationInsightsEditor from '../deprecated/components/ApplicationInsightsEditor'; +import InsightsAnalyticsEditor from '../deprecated/components/InsightsAnalyticsEditor'; +import { gtGrafana9 } from '../deprecated/utils'; + import QueryTypeField from './QueryTypeField'; import usePreparedQuery from './usePreparedQuery'; diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/QueryEditor/QueryTypeField.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/QueryEditor/QueryTypeField.tsx index d6bdd088398..0ea008631cd 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/QueryEditor/QueryTypeField.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/QueryEditor/QueryTypeField.tsx @@ -1,10 +1,11 @@ -import { SelectableValue } from '@grafana/data'; -import { Select } from '@grafana/ui'; import React, { useCallback, useState } from 'react'; +import { SelectableValue } from '@grafana/data'; +import { Select } from '@grafana/ui'; + import { AzureMonitorQuery, AzureQueryType, DeprecatedAzureQueryType } from '../../types'; -import { gtGrafana9 } from '../deprecated/utils'; import { Field } from '../Field'; +import { gtGrafana9 } from '../deprecated/utils'; interface QueryTypeFieldProps { query: AzureMonitorQuery; diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/QueryEditor/usePreparedQuery.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/QueryEditor/usePreparedQuery.ts index 4a33d06a5de..560d734cbf6 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/QueryEditor/usePreparedQuery.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/QueryEditor/usePreparedQuery.ts @@ -1,7 +1,8 @@ -import { useEffect, useMemo } from 'react'; -import { defaults } from 'lodash'; -import { AzureMonitorQuery, AzureQueryType } from '../../types'; import deepEqual from 'fast-deep-equal'; +import { defaults } from 'lodash'; +import { useEffect, useMemo } from 'react'; + +import { AzureMonitorQuery, AzureQueryType } from '../../types'; import migrateQuery from '../../utils/migrateQuery'; const DEFAULT_QUERY = { diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourceField/ResourceField.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourceField/ResourceField.tsx index fedcda00464..2a2bb98b879 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourceField/ResourceField.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourceField/ResourceField.tsx @@ -1,7 +1,8 @@ import { css } from '@emotion/css'; +import React, { useCallback, useEffect, useState } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { Button, Icon, Modal, useStyles2 } from '@grafana/ui'; -import React, { useCallback, useEffect, useState } from 'react'; import Datasource from '../../datasource'; import { AzureQueryEditorFieldProps, AzureMonitorQuery, AzureResourceSummaryItem } from '../../types'; diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourcePicker/EntryIcon.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourcePicker/EntryIcon.tsx index c24861fc235..b37b3583c25 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourcePicker/EntryIcon.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourcePicker/EntryIcon.tsx @@ -1,6 +1,7 @@ -import { Icon } from '@grafana/ui'; import React from 'react'; +import { Icon } from '@grafana/ui'; + import { ResourceRow, ResourceRowType } from './types'; interface EntryIconProps { diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourcePicker/NestedEntry.test.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourcePicker/NestedEntry.test.tsx index c0df55eb04b..7fab7fcc12e 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourcePicker/NestedEntry.test.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourcePicker/NestedEntry.test.tsx @@ -1,5 +1,6 @@ import { render, screen } from '@testing-library/react'; import React from 'react'; + import { NestedEntry } from './NestedEntry'; import { ResourceRowType } from './types'; diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourcePicker/NestedEntry.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourcePicker/NestedEntry.tsx index dbdabcac023..4dba5bf0666 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourcePicker/NestedEntry.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourcePicker/NestedEntry.tsx @@ -1,8 +1,10 @@ import { cx } from '@emotion/css'; -import { Checkbox, IconButton, useStyles2, useTheme2 } from '@grafana/ui'; import React, { useCallback, useEffect } from 'react'; +import { Checkbox, IconButton, useStyles2, useTheme2 } from '@grafana/ui'; + import { Space } from '../Space'; + import { EntryIcon } from './EntryIcon'; import getStyles from './styles'; import { ResourceRow } from './types'; diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourcePicker/NestedResourceTable.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourcePicker/NestedResourceTable.tsx index 267cfaebc7a..29bf6f20ef5 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourcePicker/NestedResourceTable.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourcePicker/NestedResourceTable.tsx @@ -1,5 +1,5 @@ -import React from 'react'; import { cx } from '@emotion/css'; +import React from 'react'; import { useStyles2 } from '@grafana/ui'; diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourcePicker/NestedRow.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourcePicker/NestedRow.tsx index be4955a0604..62583286bf1 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourcePicker/NestedRow.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourcePicker/NestedRow.tsx @@ -1,7 +1,8 @@ import { cx } from '@emotion/css'; -import { FadeTransition, LoadingPlaceholder, useStyles2 } from '@grafana/ui'; import React, { useEffect, useState } from 'react'; +import { FadeTransition, LoadingPlaceholder, useStyles2 } from '@grafana/ui'; + import { NestedEntry } from './NestedEntry'; import NestedRows from './NestedRows'; import getStyles from './styles'; diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourcePicker/NestedRows.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourcePicker/NestedRows.tsx index b66d622aa57..df223499781 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourcePicker/NestedRows.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourcePicker/NestedRows.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import NestedRow from './NestedRow'; +import NestedRow from './NestedRow'; import { ResourceRow, ResourceRowGroup, ResourceRowType } from './types'; interface NestedRowsProps { diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourcePicker/ResourcePicker.test.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourcePicker/ResourcePicker.test.tsx index fa19e3fe1f2..26196935b62 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourcePicker/ResourcePicker.test.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourcePicker/ResourcePicker.test.tsx @@ -2,15 +2,17 @@ import { act, render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; -import ResourcePicker from '.'; import createMockResourcePickerData from '../../__mocks__/resourcePickerData'; import { createMockResourceGroupsBySubscription, createMockSubscriptions, mockResourcesByResourceGroup, } from '../../__mocks__/resourcePickerRows'; + import { ResourceRowType } from './types'; +import ResourcePicker from '.'; + const noResourceURI = ''; const singleSubscriptionSelectionURI = '/subscriptions/def-456'; const singleResourceGroupSelectionURI = '/subscriptions/def-456/resourceGroups/dev-3'; diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourcePicker/ResourcePicker.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourcePicker/ResourcePicker.tsx index 03c335b6690..16edcf26bf0 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourcePicker/ResourcePicker.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourcePicker/ResourcePicker.tsx @@ -1,11 +1,13 @@ import { css } from '@emotion/css'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { Alert, Button, Icon, Input, LoadingPlaceholder, Tooltip, useStyles2, Collapse, Label } from '@grafana/ui'; -import React, { useCallback, useEffect, useMemo, useState } from 'react'; import ResourcePickerData from '../../resourcePicker/resourcePickerData'; import messageFromError from '../../utils/messageFromError'; import { Space } from '../Space'; + import NestedResourceTable from './NestedResourceTable'; import { ResourceRow, ResourceRowGroup, ResourceRowType } from './types'; import { addResources, findRow, parseResourceURI } from './utils'; diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourcePicker/styles.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourcePicker/styles.ts index 957fec90642..9a1d65d2a24 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourcePicker/styles.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourcePicker/styles.ts @@ -1,4 +1,5 @@ import { css } from '@emotion/css'; + import { GrafanaTheme2 } from '@grafana/data'; const getStyles = (theme: GrafanaTheme2) => ({ diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourcePicker/utils.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourcePicker/utils.ts index 7595a0ff2ba..9f29cd59b1c 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourcePicker/utils.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ResourcePicker/utils.ts @@ -1,4 +1,5 @@ import produce from 'immer'; + import { ResourceRow, ResourceRowGroup } from './types'; // This regex matches URIs representing: diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/Space.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/Space.tsx index 7b215ec1e64..b1fd5e33922 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/Space.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/Space.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { css, cx } from '@emotion/css'; +import React from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { stylesFactory, useTheme2 } from '@grafana/ui'; diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/SubscriptionField.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/SubscriptionField.tsx index 1c7fefef304..3e0b2e75b49 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/SubscriptionField.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/SubscriptionField.tsx @@ -1,9 +1,11 @@ import React, { useCallback, useMemo } from 'react'; + import { SelectableValue } from '@grafana/data'; import { Select, MultiSelect } from '@grafana/ui'; import { AzureMonitorQuery, AzureQueryEditorFieldProps, AzureMonitorOption, AzureQueryType } from '../types'; import { findOptions } from '../utils/common'; + import { Field } from './Field'; interface SubscriptionFieldProps extends AzureQueryEditorFieldProps { diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/VariableEditor/VariableEditor.test.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/VariableEditor/VariableEditor.test.tsx index d9385aab47d..f3e7ada507d 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/VariableEditor/VariableEditor.test.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/VariableEditor/VariableEditor.test.tsx @@ -1,11 +1,14 @@ -import React from 'react'; import { render, screen, waitFor } from '@testing-library/react'; -import VariableEditor from './VariableEditor'; import userEvent from '@testing-library/user-event'; +import React from 'react'; +import { select } from 'react-select-event'; + +import * as ui from '@grafana/ui'; + import createMockDatasource from '../../__mocks__/datasource'; import { AzureMonitorQuery, AzureQueryType } from '../../types'; -import { select } from 'react-select-event'; -import * as ui from '@grafana/ui'; + +import VariableEditor from './VariableEditor'; // Have to mock CodeEditor because it doesnt seem to work in tests??? jest.mock('@grafana/ui', () => ({ diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/VariableEditor/VariableEditor.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/VariableEditor/VariableEditor.tsx index c29bb1fb66d..7dca2a9fdae 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/VariableEditor/VariableEditor.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/VariableEditor/VariableEditor.tsx @@ -1,12 +1,14 @@ +import React, { ChangeEvent, useCallback, useEffect, useState } from 'react'; + import { SelectableValue } from '@grafana/data'; import { Alert, InlineField, Input, Select } from '@grafana/ui'; -import React, { ChangeEvent, useCallback, useEffect, useState } from 'react'; -import { AzureMonitorQuery, AzureQueryType } from '../../types'; -import LogsQueryEditor from '../LogsQueryEditor'; + import DataSource from '../../datasource'; -import useLastError from '../../utils/useLastError'; -import { Space } from '../Space'; import { migrateStringQueriesToObjectQueries } from '../../grafanaTemplateVariableFns'; +import { AzureMonitorQuery, AzureQueryType } from '../../types'; +import useLastError from '../../utils/useLastError'; +import LogsQueryEditor from '../LogsQueryEditor'; +import { Space } from '../Space'; const AZURE_QUERY_VARIABLE_TYPE_OPTIONS = [ { label: 'Grafana Query Function', value: AzureQueryType.GrafanaTemplateVariableFn }, diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/deprecated/app_insights/app_insights_datasource.test.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/deprecated/app_insights/app_insights_datasource.test.ts index 84a43170278..bd50d3b34c1 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/deprecated/app_insights/app_insights_datasource.test.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/deprecated/app_insights/app_insights_datasource.test.ts @@ -1,9 +1,10 @@ import { lastValueFrom, of } from 'rxjs'; + import { DataFrame, getFrameDisplayName, toUtc } from '@grafana/data'; import { setBackendSrv } from '@grafana/runtime'; - -import { TemplateSrv } from 'app/features/templating/template_srv'; import { backendSrv } from 'app/core/services/backend_srv'; +import { TemplateSrv } from 'app/features/templating/template_srv'; + import AppInsightsDatasource from './app_insights_datasource'; const templateSrv = new TemplateSrv(); diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/deprecated/app_insights/app_insights_datasource.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/deprecated/app_insights/app_insights_datasource.ts index 15931a06bbf..c94a9dad515 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/deprecated/app_insights/app_insights_datasource.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/deprecated/app_insights/app_insights_datasource.ts @@ -1,6 +1,7 @@ +import { isString } from 'lodash'; + import { DataQueryRequest, DataSourceInstanceSettings, ScopedVars } from '@grafana/data'; import { DataSourceWithBackend, getTemplateSrv } from '@grafana/runtime'; -import { isString } from 'lodash'; import TimegrainConverter from '../../../time_grain_converter'; import { @@ -10,6 +11,7 @@ import { DeprecatedAzureQueryType, } from '../../../types'; import { routeNames } from '../../../utils/common'; + import ResponseParser from './response_parser'; export interface LogAnalyticsColumn { diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/deprecated/app_insights/response_parser.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/deprecated/app_insights/response_parser.ts index fbf8349c05a..bdba5d2640c 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/deprecated/app_insights/response_parser.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/deprecated/app_insights/response_parser.ts @@ -1,4 +1,5 @@ import { concat, filter, find, forEach, indexOf, intersection, isObject, map, without, keys as _keys } from 'lodash'; + import { dateTime } from '@grafana/data'; export default class ResponseParser { diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/deprecated/components/AnalyticsConfig.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/deprecated/components/AnalyticsConfig.tsx index 17df310498e..b3276e4ab78 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/deprecated/components/AnalyticsConfig.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/deprecated/components/AnalyticsConfig.tsx @@ -1,6 +1,7 @@ -import { Alert, Button } from '@grafana/ui'; import React, { FunctionComponent, useMemo } from 'react'; +import { Alert, Button } from '@grafana/ui'; + import { getCredentials } from '../../../credentials'; import { AzureDataSourceSettings } from '../../../types'; import { AzureCredentialsForm } from '../../AzureCredentialsForm'; diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/deprecated/components/ApplicationInsightsEditor/index.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/deprecated/components/ApplicationInsightsEditor/index.tsx index 8f9d46ec30a..51adf3971f4 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/deprecated/components/ApplicationInsightsEditor/index.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/deprecated/components/ApplicationInsightsEditor/index.tsx @@ -1,6 +1,7 @@ -import { Alert, Input } from '@grafana/ui'; import React from 'react'; +import { Alert, Input } from '@grafana/ui'; + import { Field } from '../../../Field'; import { DeprecatedAzureMonitorQuery } from '../../types'; diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/deprecated/components/InsightsAnalyticsEditor/index.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/deprecated/components/InsightsAnalyticsEditor/index.tsx index 3c489130394..e1a69edfc5e 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/deprecated/components/InsightsAnalyticsEditor/index.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/deprecated/components/InsightsAnalyticsEditor/index.tsx @@ -1,6 +1,7 @@ -import { Alert, CodeEditor, Select } from '@grafana/ui'; import React from 'react'; +import { Alert, CodeEditor, Select } from '@grafana/ui'; + import { AzureMonitorOption } from '../../../../types'; import { Field } from '../../../Field'; import { Space } from '../../../Space'; diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/deprecated/components/InsightsConfig.test.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/deprecated/components/InsightsConfig.test.tsx index 3c3e579701d..8137ed0319f 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/deprecated/components/InsightsConfig.test.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/deprecated/components/InsightsConfig.test.tsx @@ -1,8 +1,10 @@ -import { Button, LegacyForms } from '@grafana/ui'; import { shallow } from 'enzyme'; import React from 'react'; +import { Button, LegacyForms } from '@grafana/ui'; + import { Props } from '../../ConfigEditor'; + import InsightsConfig from './InsightsConfig'; const { Input } = LegacyForms; diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/deprecated/components/InsightsConfig.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/deprecated/components/InsightsConfig.tsx index 52669126a5e..a4ecf31bdee 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/deprecated/components/InsightsConfig.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/deprecated/components/InsightsConfig.tsx @@ -1,10 +1,11 @@ +import React, { PureComponent } from 'react'; + import { updateDatasourcePluginJsonDataOption, updateDatasourcePluginResetOption, updateDatasourcePluginSecureJsonDataOption, } from '@grafana/data'; import { Alert, Button, InlineFormLabel, LegacyForms } from '@grafana/ui'; -import React, { PureComponent } from 'react'; import { AzureDataSourceJsonData, AzureDataSourceSecureJsonData } from '../../../types'; import { Props } from '../../ConfigEditor'; diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/deprecated/utils.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/deprecated/utils.tsx index ddf958cb4db..6c0e96bd4cd 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/deprecated/utils.tsx +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/deprecated/utils.tsx @@ -1,6 +1,7 @@ -import { config } from '@grafana/runtime'; import { gt, valid } from 'semver'; +import { config } from '@grafana/runtime'; + import { AzureDataSourceSettings } from '../../types'; export function isAppInsightsConfigured(options: AzureDataSourceSettings) { diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/datasource.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/datasource.ts index 2f9e008fca6..81ea72a8997 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/datasource.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/datasource.ts @@ -1,3 +1,7 @@ +import { cloneDeep, upperFirst } from 'lodash'; +import { forkJoin, Observable, of } from 'rxjs'; +import { map } from 'rxjs/operators'; + import { DataFrame, DataQueryRequest, @@ -8,9 +12,6 @@ import { ScopedVars, } from '@grafana/data'; import { getTemplateSrv, TemplateSrv } from 'app/features/templating/template_srv'; -import { cloneDeep, upperFirst } from 'lodash'; -import { forkJoin, Observable, of } from 'rxjs'; -import { map } from 'rxjs/operators'; import AzureLogAnalyticsDatasource from './azure_log_analytics/azure_log_analytics_datasource'; import AzureMonitorDatasource from './azure_monitor/azure_monitor_datasource'; diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/grafanaTemplateVariableFns.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/grafanaTemplateVariableFns.ts index a9574e60b9a..3cdc108ba53 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/grafanaTemplateVariableFns.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/grafanaTemplateVariableFns.ts @@ -1,5 +1,6 @@ -import { AzureMonitorQuery, AzureQueryType } from './types'; +import { isGUIDish } from './components/ResourcePicker/utils'; import DataSource from './datasource'; +import { AzureMonitorQuery, AzureQueryType } from './types'; import { AppInsightsGroupByQuery, AppInsightsMetricNameQuery, @@ -12,7 +13,6 @@ import { SubscriptionsQuery, WorkspacesQuery, } from './types/templateVariables'; -import { isGUIDish } from './components/ResourcePicker/utils'; /* Grafana Template Variable Functions diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/grafanaTemplateVariables.test.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/grafanaTemplateVariables.test.ts index 0a98869d0a9..f3e1df0554c 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/grafanaTemplateVariables.test.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/grafanaTemplateVariables.test.ts @@ -1,6 +1,6 @@ +import createMockDatasource from './__mocks__/datasource'; import { migrateStringQueriesToObjectQueries } from './grafanaTemplateVariableFns'; import { AzureMonitorQuery, AzureQueryType } from './types'; -import createMockDatasource from './__mocks__/datasource'; describe('migrateStringQueriesToObjectQueries', () => { const expectedMigrations: Array<{ input: string; output: AzureMonitorQuery }> = [ diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/log_analytics/querystring_builder.test.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/log_analytics/querystring_builder.test.ts index d9ef473760e..9c6f2e3a707 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/log_analytics/querystring_builder.test.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/log_analytics/querystring_builder.test.ts @@ -1,6 +1,7 @@ -import LogAnalyticsQuerystringBuilder from './querystring_builder'; import { dateTime } from '@grafana/data'; +import LogAnalyticsQuerystringBuilder from './querystring_builder'; + describe('LogAnalyticsDatasource', () => { let builder: LogAnalyticsQuerystringBuilder; diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/module.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/module.ts index 1215c103b32..04653d79235 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/module.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/module.ts @@ -1,7 +1,8 @@ import { DataSourcePlugin } from '@grafana/data'; -import Datasource from './datasource'; + import { ConfigEditor } from './components/ConfigEditor'; import AzureMonitorQueryEditor from './components/QueryEditor'; +import Datasource from './datasource'; import { AzureMonitorQuery, AzureDataSourceJsonData } from './types'; export const plugin = new DataSourcePlugin(Datasource) diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/resourcePicker/resourcePickerData.test.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/resourcePicker/resourcePickerData.test.ts index 4942b5089ca..5268dfca451 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/resourcePicker/resourcePickerData.test.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/resourcePicker/resourcePickerData.test.ts @@ -4,9 +4,10 @@ import { createMockARGSubscriptionResponse, } from '../__mocks__/argResourcePickerResponse'; import { createMockInstanceSetttings } from '../__mocks__/instanceSettings'; -import ResourcePickerData from './resourcePickerData'; import { AzureGraphResponse } from '../types'; +import ResourcePickerData from './resourcePickerData'; + const createResourcePickerData = (responses: AzureGraphResponse[]) => { const instanceSettings = createMockInstanceSetttings(); const resourcePickerData = new ResourcePickerData(instanceSettings); diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/time_grain_converter.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/time_grain_converter.ts index 2688f012aaa..66f8a689ebf 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/time_grain_converter.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/time_grain_converter.ts @@ -1,4 +1,5 @@ import { includes, filter } from 'lodash'; + import { rangeUtil } from '@grafana/data'; export default class TimeGrainConverter { diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/types/query.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/types/query.ts index 86c9a2df88c..c312af6eae1 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/types/query.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/types/query.ts @@ -1,4 +1,5 @@ import { DeprecatedAzureMonitorQuery } from '../components/deprecated/types'; + import { GrafanaTemplateVariableQuery } from './templateVariables'; export enum AzureQueryType { diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/types/types.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/types/types.ts index 34c105b668c..3c4bbe31ac5 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/types/types.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/types/types.ts @@ -1,6 +1,7 @@ import { DataSourceInstanceSettings, DataSourceJsonData, DataSourceSettings, TableData } from '@grafana/data'; import Datasource from '../datasource'; + import { AzureMonitorQuery } from './query'; export type AzureDataSourceSettings = DataSourceSettings; diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/common.test.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/common.test.ts index e16c273a14b..71630897de5 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/common.test.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/common.test.ts @@ -1,4 +1,5 @@ import { initialCustomVariableModelState } from 'app/features/variables/custom/reducer'; + import { hasOption, interpolateVariable } from './common'; describe('AzureMonitor: hasOption', () => { diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/common.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/common.ts index 9bcfae999d6..a07b6e7df10 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/common.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/common.ts @@ -1,5 +1,7 @@ import { map } from 'lodash'; + import { rangeUtil } from '@grafana/data'; + import TimegrainConverter from '../time_grain_converter'; import { AzureMonitorOption } from '../types'; diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/messageFromError.test.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/messageFromError.test.ts index 9b178d93035..8af0b8c8e45 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/messageFromError.test.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/messageFromError.test.ts @@ -1,4 +1,5 @@ import { invalidNamespaceError } from '../__mocks__/errors'; + import messageFromError from './messageFromError'; describe('AzureMonitor: messageFromError', () => { diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/migrateAnnotation.test.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/migrateAnnotation.test.ts index 6d3380a76ab..c55c9a4e985 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/migrateAnnotation.test.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/migrateAnnotation.test.ts @@ -1,5 +1,7 @@ import { AnnotationQuery } from '@grafana/data'; + import { AzureMonitorQuery, AzureQueryType } from '../types'; + import migrateAnnotation from './migrateAnnotation'; const OLD_ANNOTATION: AnnotationQuery = { diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/migrateAnnotation.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/migrateAnnotation.ts index 3dc8098e1fc..c630d34805f 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/migrateAnnotation.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/migrateAnnotation.ts @@ -1,6 +1,7 @@ -import { AzureMonitorQuery, AzureQueryType } from '../types'; import { AnnotationQuery } from '@grafana/data'; +import { AzureMonitorQuery, AzureQueryType } from '../types'; + // The old Angular annotations editor put some properties (rawQuery, workspace, subscription) // on the root annotation object, rather than down in the 'targets' query value // This migration moves them to a Log Analytics query compatible with the React query editor diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/migrateQuery.test.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/migrateQuery.test.ts index 1dcd9e772f4..aaec47fc341 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/migrateQuery.test.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/migrateQuery.test.ts @@ -1,4 +1,5 @@ import { AzureMonitorQuery, AzureQueryType } from '../types'; + import migrateQuery from './migrateQuery'; const azureMonitorQueryV7 = { diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/migrateQuery.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/migrateQuery.ts index 78e55d70bf2..1c55b1c5b5e 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/migrateQuery.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/migrateQuery.ts @@ -1,10 +1,10 @@ +import UrlBuilder from '../azure_monitor/url_builder'; import { setKustoQuery } from '../components/LogsQueryEditor/setQueryValue'; import { appendDimensionFilter, setTimeGrain as setMetricsTimeGrain, } from '../components/MetricsQueryEditor/setQueryValue'; import TimegrainConverter from '../time_grain_converter'; -import UrlBuilder from '../azure_monitor/url_builder'; import { AzureMonitorQuery, AzureQueryType, DeprecatedAzureQueryType } from '../types'; const OLD_DEFAULT_DROPDOWN_VALUE = 'select'; diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/useAsyncState.test.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/useAsyncState.test.ts index ddbfb2b5cc0..9d8cdb9d922 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/useAsyncState.test.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/useAsyncState.test.ts @@ -1,4 +1,5 @@ import { renderHook } from '@testing-library/react-hooks'; + import { useAsyncState } from './useAsyncState'; interface WaitableMock extends jest.Mock { diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/useLastError.test.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/useLastError.test.ts index 7fbccbe3a50..a725cc4cec5 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/useLastError.test.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/useLastError.test.ts @@ -1,4 +1,5 @@ import { renderHook, act } from '@testing-library/react-hooks'; + import useLastError from './useLastError'; describe('AzureMonitor: useLastError', () => { diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/useLastError.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/useLastError.ts index 851c3106b8c..8fb0246e1d5 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/useLastError.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/useLastError.ts @@ -1,5 +1,7 @@ import { useState, useCallback, useMemo } from 'react'; + import { AzureMonitorErrorish } from '../types'; + import messageFromError from './messageFromError'; type SourcedError = [string, AzureMonitorErrorish]; diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/variables.test.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/variables.test.ts index 82c6a566e37..21518be17c9 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/variables.test.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/variables.test.ts @@ -1,6 +1,7 @@ -import { DataQueryRequest, DataQueryResponseData, toDataFrame } from '@grafana/data'; import { from } from 'rxjs'; +import { DataQueryRequest, DataQueryResponseData, toDataFrame } from '@grafana/data'; + import createMockDatasource from './__mocks__/datasource'; import { invalidSubscriptionError } from './__mocks__/errors'; import { AzureMonitorQuery, AzureQueryType } from './types'; diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/variables.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/variables.ts index abe9901a3df..c544ba116c7 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/variables.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/variables.ts @@ -1,3 +1,5 @@ +import { from, lastValueFrom, Observable } from 'rxjs'; + import { CustomVariableSupport, DataQueryRequest, @@ -6,7 +8,6 @@ import { toDataFrame, } from '@grafana/data'; import { getTemplateSrv } from '@grafana/runtime'; -import { from, lastValueFrom, Observable } from 'rxjs'; import VariableEditor from './components/VariableEditor/VariableEditor'; import DataSource from './datasource'; diff --git a/public/app/plugins/datasource/grafana/components/AnnotationQueryEditor.test.tsx b/public/app/plugins/datasource/grafana/components/AnnotationQueryEditor.test.tsx index 961b02ae012..dfcac6c3e7a 100644 --- a/public/app/plugins/datasource/grafana/components/AnnotationQueryEditor.test.tsx +++ b/public/app/plugins/datasource/grafana/components/AnnotationQueryEditor.test.tsx @@ -1,7 +1,8 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; +import React from 'react'; import { GrafanaAnnotationQuery, GrafanaAnnotationType, GrafanaQueryType } from '../types'; + import AnnotationQueryEditor from './AnnotationQueryEditor'; describe('AnnotationQueryEditor', () => { diff --git a/public/app/plugins/datasource/grafana/components/AnnotationQueryEditor.tsx b/public/app/plugins/datasource/grafana/components/AnnotationQueryEditor.tsx index 0e956cd7e1b..10eec6cf254 100644 --- a/public/app/plugins/datasource/grafana/components/AnnotationQueryEditor.tsx +++ b/public/app/plugins/datasource/grafana/components/AnnotationQueryEditor.tsx @@ -1,12 +1,13 @@ +import { css } from '@emotion/css'; import React from 'react'; + import { SelectableValue } from '@grafana/data'; import { Field, FieldSet, Select, Switch } from '@grafana/ui'; -import { css } from '@emotion/css'; - import { TagFilter } from 'app/core/components/TagFilter/TagFilter'; -import { GrafanaAnnotationQuery, GrafanaAnnotationType, GrafanaQuery } from '../types'; import { getAnnotationTags } from 'app/features/annotations/api'; +import { GrafanaAnnotationQuery, GrafanaAnnotationType, GrafanaQuery } from '../types'; + const matchTooltipContent = 'Enabling this returns annotations that match any of the tags specified below'; const tagsTooltipContent = ( diff --git a/public/app/plugins/datasource/grafana/components/QueryEditor.tsx b/public/app/plugins/datasource/grafana/components/QueryEditor.tsx index 992fcf4f0e9..7fcaeea6464 100644 --- a/public/app/plugins/datasource/grafana/components/QueryEditor.tsx +++ b/public/app/plugins/datasource/grafana/components/QueryEditor.tsx @@ -1,5 +1,5 @@ import React, { PureComponent } from 'react'; -import { InlineField, Select, Alert, Input, InlineFieldRow } from '@grafana/ui'; + import { QueryEditorProps, SelectableValue, @@ -8,9 +8,11 @@ import { DataQueryRequest, DataFrame, } from '@grafana/data'; +import { config, getBackendSrv, getDataSourceSrv } from '@grafana/runtime'; +import { InlineField, Select, Alert, Input, InlineFieldRow } from '@grafana/ui'; + import { GrafanaDatasource } from '../datasource'; import { defaultQuery, GrafanaQuery, GrafanaQueryType } from '../types'; -import { config, getBackendSrv, getDataSourceSrv } from '@grafana/runtime'; type Props = QueryEditorProps; diff --git a/public/app/plugins/datasource/grafana/datasource.test.ts b/public/app/plugins/datasource/grafana/datasource.test.ts index daccdcd1bf5..a1a2183442d 100644 --- a/public/app/plugins/datasource/grafana/datasource.test.ts +++ b/public/app/plugins/datasource/grafana/datasource.test.ts @@ -1,6 +1,6 @@ import { AnnotationQueryRequest, DataSourceInstanceSettings, dateTime } from '@grafana/data'; - import { backendSrv } from 'app/core/services/backend_srv'; // will use the version in __mocks__ + import { GrafanaDatasource } from './datasource'; import { GrafanaAnnotationQuery, GrafanaAnnotationType, GrafanaQuery } from './types'; diff --git a/public/app/plugins/datasource/grafana/datasource.ts b/public/app/plugins/datasource/grafana/datasource.ts index 56c505af516..f9df9d68291 100644 --- a/public/app/plugins/datasource/grafana/datasource.ts +++ b/public/app/plugins/datasource/grafana/datasource.ts @@ -1,11 +1,7 @@ +import { isString } from 'lodash'; import { from, merge, Observable, of } from 'rxjs'; -import { - DataSourceWithBackend, - getBackendSrv, - getGrafanaLiveSrv, - getTemplateSrv, - StreamingFrameOptions, -} from '@grafana/runtime'; +import { map } from 'rxjs/operators'; + import { AnnotationQuery, AnnotationQueryRequest, @@ -19,13 +15,19 @@ import { parseLiveChannelAddress, toDataFrame, } from '@grafana/data'; - -import { GrafanaAnnotationQuery, GrafanaAnnotationType, GrafanaQuery, GrafanaQueryType } from './types'; -import AnnotationQueryEditor from './components/AnnotationQueryEditor'; -import { getDashboardSrv } from '../../../features/dashboard/services/DashboardSrv'; -import { isString } from 'lodash'; +import { + DataSourceWithBackend, + getBackendSrv, + getGrafanaLiveSrv, + getTemplateSrv, + StreamingFrameOptions, +} from '@grafana/runtime'; import { migrateDatasourceNameToRef } from 'app/features/dashboard/state/DashboardMigrator'; -import { map } from 'rxjs/operators'; + +import { getDashboardSrv } from '../../../features/dashboard/services/DashboardSrv'; + +import AnnotationQueryEditor from './components/AnnotationQueryEditor'; +import { GrafanaAnnotationQuery, GrafanaAnnotationType, GrafanaQuery, GrafanaQueryType } from './types'; let counter = 100; diff --git a/public/app/plugins/datasource/grafana/module.ts b/public/app/plugins/datasource/grafana/module.ts index 4fc4b8aaad4..930d5a4e680 100644 --- a/public/app/plugins/datasource/grafana/module.ts +++ b/public/app/plugins/datasource/grafana/module.ts @@ -1,6 +1,7 @@ import { DataSourcePlugin } from '@grafana/data'; -import { GrafanaDatasource } from './datasource'; + import { QueryEditor } from './components/QueryEditor'; +import { GrafanaDatasource } from './datasource'; import { GrafanaQuery } from './types'; export const plugin = new DataSourcePlugin(GrafanaDatasource).setQueryEditor( diff --git a/public/app/plugins/datasource/graphite/components/AddGraphiteFunction.tsx b/public/app/plugins/datasource/graphite/components/AddGraphiteFunction.tsx index 938494d6f43..1689697b554 100644 --- a/public/app/plugins/datasource/graphite/components/AddGraphiteFunction.tsx +++ b/public/app/plugins/datasource/graphite/components/AddGraphiteFunction.tsx @@ -1,12 +1,15 @@ +import { css, cx } from '@emotion/css'; import React, { useEffect, useMemo, useState } from 'react'; + +import { GrafanaTheme2, SelectableValue } from '@grafana/data'; import { Button, Segment, useStyles2 } from '@grafana/ui'; + import { FuncDefs } from '../gfunc'; import { actions } from '../state/actions'; -import { GrafanaTheme2, SelectableValue } from '@grafana/data'; -import { css, cx } from '@emotion/css'; -import { mapFuncDefsToSelectables } from './helpers'; import { useDispatch } from '../state/context'; +import { mapFuncDefsToSelectables } from './helpers'; + type Props = { funcDefs: FuncDefs; }; diff --git a/public/app/plugins/datasource/graphite/components/FunctionEditor.test.tsx b/public/app/plugins/datasource/graphite/components/FunctionEditor.test.tsx index b8527aa1a4c..b9a6d609919 100644 --- a/public/app/plugins/datasource/graphite/components/FunctionEditor.test.tsx +++ b/public/app/plugins/datasource/graphite/components/FunctionEditor.test.tsx @@ -1,8 +1,10 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; -import { FunctionEditor } from './FunctionEditor'; +import React from 'react'; + import { FuncInstance } from '../gfunc'; +import { FunctionEditor } from './FunctionEditor'; + function mockFunctionInstance(name: string, unknown?: boolean): FuncInstance { const def = { category: 'category', diff --git a/public/app/plugins/datasource/graphite/components/FunctionEditor.tsx b/public/app/plugins/datasource/graphite/components/FunctionEditor.tsx index eecbf5b8673..1666614d0b7 100644 --- a/public/app/plugins/datasource/graphite/components/FunctionEditor.tsx +++ b/public/app/plugins/datasource/graphite/components/FunctionEditor.tsx @@ -1,9 +1,12 @@ -import React from 'react'; -import { Icon, Tooltip, useStyles2 } from '@grafana/ui'; -import { FunctionEditorControls, FunctionEditorControlsProps } from './FunctionEditorControls'; -import { FuncInstance } from '../gfunc'; import { css } from '@emotion/css'; +import React from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; +import { Icon, Tooltip, useStyles2 } from '@grafana/ui'; + +import { FuncInstance } from '../gfunc'; + +import { FunctionEditorControls, FunctionEditorControlsProps } from './FunctionEditorControls'; interface FunctionEditorProps extends FunctionEditorControlsProps { func: FuncInstance; diff --git a/public/app/plugins/datasource/graphite/components/FunctionEditorControls.tsx b/public/app/plugins/datasource/graphite/components/FunctionEditorControls.tsx index f4d1fa52fa8..facd0b2511e 100644 --- a/public/app/plugins/datasource/graphite/components/FunctionEditorControls.tsx +++ b/public/app/plugins/datasource/graphite/components/FunctionEditorControls.tsx @@ -1,5 +1,7 @@ import React, { Suspense } from 'react'; + import { Icon, Tooltip } from '@grafana/ui'; + import { FuncInstance } from '../gfunc'; export interface FunctionEditorControlsProps { diff --git a/public/app/plugins/datasource/graphite/components/FunctionParamEditor.tsx b/public/app/plugins/datasource/graphite/components/FunctionParamEditor.tsx index 62847a932bb..d3306f4aab9 100644 --- a/public/app/plugins/datasource/graphite/components/FunctionParamEditor.tsx +++ b/public/app/plugins/datasource/graphite/components/FunctionParamEditor.tsx @@ -1,7 +1,8 @@ -import React from 'react'; -import { Segment, SegmentInput, useStyles2 } from '@grafana/ui'; -import { GrafanaTheme2, SelectableValue } from '@grafana/data'; import { css } from '@emotion/css'; +import React from 'react'; + +import { GrafanaTheme2, SelectableValue } from '@grafana/data'; +import { Segment, SegmentInput, useStyles2 } from '@grafana/ui'; export type EditableParam = { name: string; diff --git a/public/app/plugins/datasource/graphite/components/FunctionsSection.tsx b/public/app/plugins/datasource/graphite/components/FunctionsSection.tsx index 81cce8c702a..0cbf5fb67a9 100644 --- a/public/app/plugins/datasource/graphite/components/FunctionsSection.tsx +++ b/public/app/plugins/datasource/graphite/components/FunctionsSection.tsx @@ -1,9 +1,12 @@ import React from 'react'; -import { FuncDefs, FuncInstance } from '../gfunc'; -import { GraphiteFunctionEditor } from './GraphiteFunctionEditor'; -import { AddGraphiteFunction } from './AddGraphiteFunction'; + import { SegmentSection } from '@grafana/ui'; +import { FuncDefs, FuncInstance } from '../gfunc'; + +import { AddGraphiteFunction } from './AddGraphiteFunction'; +import { GraphiteFunctionEditor } from './GraphiteFunctionEditor'; + type Props = { functions: FuncInstance[]; funcDefs: FuncDefs; diff --git a/public/app/plugins/datasource/graphite/components/GraphiteFunctionEditor.tsx b/public/app/plugins/datasource/graphite/components/GraphiteFunctionEditor.tsx index fcf1b93cef3..aae6ce304c9 100644 --- a/public/app/plugins/datasource/graphite/components/GraphiteFunctionEditor.tsx +++ b/public/app/plugins/datasource/graphite/components/GraphiteFunctionEditor.tsx @@ -1,14 +1,17 @@ -import React, { useState } from 'react'; -import { HorizontalGroup, InlineLabel, useStyles2 } from '@grafana/ui'; -import { GrafanaTheme2 } from '@grafana/data'; import { css, cx } from '@emotion/css'; +import React, { useState } from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; +import { HorizontalGroup, InlineLabel, useStyles2 } from '@grafana/ui'; + import { FuncInstance } from '../gfunc'; -import { EditableParam, FunctionParamEditor } from './FunctionParamEditor'; import { actions } from '../state/actions'; -import { FunctionEditor } from './FunctionEditor'; -import { mapFuncInstanceToParams } from './helpers'; import { useDispatch } from '../state/context'; +import { FunctionEditor } from './FunctionEditor'; +import { EditableParam, FunctionParamEditor } from './FunctionParamEditor'; +import { mapFuncInstanceToParams } from './helpers'; + export type FunctionEditorProps = { func: FuncInstance; }; diff --git a/public/app/plugins/datasource/graphite/components/GraphiteQueryEditor.tsx b/public/app/plugins/datasource/graphite/components/GraphiteQueryEditor.tsx index 567e086d891..2e0947bb503 100644 --- a/public/app/plugins/datasource/graphite/components/GraphiteQueryEditor.tsx +++ b/public/app/plugins/datasource/graphite/components/GraphiteQueryEditor.tsx @@ -1,12 +1,15 @@ +import { css } from '@emotion/css'; import React from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; -import { actions } from '../state/actions'; import { Button, useStyles2 } from '@grafana/ui'; + +import { actions } from '../state/actions'; import { GraphiteQueryEditorContext, GraphiteQueryEditorProps, useDispatch, useGraphiteState } from '../state/context'; + +import { FunctionsSection } from './FunctionsSection'; import { GraphiteTextEditor } from './GraphiteTextEditor'; import { SeriesSection } from './SeriesSection'; -import { FunctionsSection } from './FunctionsSection'; -import { css } from '@emotion/css'; export function GraphiteQueryEditor({ datasource, diff --git a/public/app/plugins/datasource/graphite/components/GraphiteTextEditor.tsx b/public/app/plugins/datasource/graphite/components/GraphiteTextEditor.tsx index 5941a4e3953..849b2477936 100644 --- a/public/app/plugins/datasource/graphite/components/GraphiteTextEditor.tsx +++ b/public/app/plugins/datasource/graphite/components/GraphiteTextEditor.tsx @@ -1,5 +1,7 @@ import React, { useCallback } from 'react'; + import { QueryField } from '@grafana/ui'; + import { actions } from '../state/actions'; import { useDispatch } from '../state/context'; diff --git a/public/app/plugins/datasource/graphite/components/MetricSegment.tsx b/public/app/plugins/datasource/graphite/components/MetricSegment.tsx index ff4717fb7cb..af66dbfb5bf 100644 --- a/public/app/plugins/datasource/graphite/components/MetricSegment.tsx +++ b/public/app/plugins/datasource/graphite/components/MetricSegment.tsx @@ -1,12 +1,14 @@ -import React, { useCallback, useMemo } from 'react'; -import { SegmentAsync } from '@grafana/ui'; -import { actions } from '../state/actions'; -import { GraphiteSegment } from '../types'; -import { SelectableValue } from '@grafana/data'; -import { getAltSegmentsSelectables } from '../state/providers'; import { debounce } from 'lodash'; -import { GraphiteQueryEditorState } from '../state/store'; +import React, { useCallback, useMemo } from 'react'; + +import { SelectableValue } from '@grafana/data'; +import { SegmentAsync } from '@grafana/ui'; + +import { actions } from '../state/actions'; import { useDispatch } from '../state/context'; +import { getAltSegmentsSelectables } from '../state/providers'; +import { GraphiteQueryEditorState } from '../state/store'; +import { GraphiteSegment } from '../types'; type Props = { segment: GraphiteSegment; diff --git a/public/app/plugins/datasource/graphite/components/MetricTankMetaInspector.tsx b/public/app/plugins/datasource/graphite/components/MetricTankMetaInspector.tsx index 3a7ce13b615..f6fa47839b5 100644 --- a/public/app/plugins/datasource/graphite/components/MetricTankMetaInspector.tsx +++ b/public/app/plugins/datasource/graphite/components/MetricTankMetaInspector.tsx @@ -1,12 +1,14 @@ import { css, cx } from '@emotion/css'; import React, { PureComponent } from 'react'; + import { MetadataInspectorProps, rangeUtil } from '@grafana/data'; -import { GraphiteDatasource } from '../datasource'; -import { GraphiteQuery, GraphiteOptions, MetricTankSeriesMeta } from '../types'; -import { parseSchemaRetentions, getRollupNotice, getRuntimeConsolidationNotice } from '../meta'; import { stylesFactory } from '@grafana/ui'; import { config } from 'app/core/config'; +import { GraphiteDatasource } from '../datasource'; +import { parseSchemaRetentions, getRollupNotice, getRuntimeConsolidationNotice } from '../meta'; +import { GraphiteQuery, GraphiteOptions, MetricTankSeriesMeta } from '../types'; + export type Props = MetadataInspectorProps; export interface State { diff --git a/public/app/plugins/datasource/graphite/components/MetricsSection.tsx b/public/app/plugins/datasource/graphite/components/MetricsSection.tsx index 34fb24160d4..28887f26a25 100644 --- a/public/app/plugins/datasource/graphite/components/MetricsSection.tsx +++ b/public/app/plugins/datasource/graphite/components/MetricsSection.tsx @@ -1,6 +1,8 @@ import React from 'react'; -import { GraphiteSegment } from '../types'; + import { GraphiteQueryEditorState } from '../state/store'; +import { GraphiteSegment } from '../types'; + import { MetricSegment } from './MetricSegment'; type Props = { diff --git a/public/app/plugins/datasource/graphite/components/PlayButton.tsx b/public/app/plugins/datasource/graphite/components/PlayButton.tsx index d17bf490632..18d76fefe7b 100644 --- a/public/app/plugins/datasource/graphite/components/PlayButton.tsx +++ b/public/app/plugins/datasource/graphite/components/PlayButton.tsx @@ -1,5 +1,7 @@ import React, { useCallback } from 'react'; + import { Button } from '@grafana/ui'; + import { actions } from '../state/actions'; import { useDispatch } from '../state/context'; diff --git a/public/app/plugins/datasource/graphite/components/SeriesSection.tsx b/public/app/plugins/datasource/graphite/components/SeriesSection.tsx index 17d5f47a598..5b76e2d897c 100644 --- a/public/app/plugins/datasource/graphite/components/SeriesSection.tsx +++ b/public/app/plugins/datasource/graphite/components/SeriesSection.tsx @@ -1,9 +1,12 @@ import React from 'react'; -import { GraphiteQueryEditorState } from '../state/store'; -import { TagsSection } from './TagsSection'; -import { MetricsSection } from './MetricsSection'; + import { SegmentSection } from '@grafana/ui'; +import { GraphiteQueryEditorState } from '../state/store'; + +import { MetricsSection } from './MetricsSection'; +import { TagsSection } from './TagsSection'; + type Props = { state: GraphiteQueryEditorState; }; diff --git a/public/app/plugins/datasource/graphite/components/TagEditor.tsx b/public/app/plugins/datasource/graphite/components/TagEditor.tsx index 4a3f02f8aca..fe69a1bbad6 100644 --- a/public/app/plugins/datasource/graphite/components/TagEditor.tsx +++ b/public/app/plugins/datasource/graphite/components/TagEditor.tsx @@ -1,11 +1,13 @@ +import { debounce } from 'lodash'; import React, { useCallback, useMemo } from 'react'; + import { Segment, SegmentAsync } from '@grafana/ui'; + import { actions } from '../state/actions'; -import { GraphiteTag, GraphiteTagOperator } from '../types'; +import { useDispatch } from '../state/context'; import { getTagOperatorsSelectables, getTagsSelectables, getTagValuesSelectables } from '../state/providers'; import { GraphiteQueryEditorState } from '../state/store'; -import { debounce } from 'lodash'; -import { useDispatch } from '../state/context'; +import { GraphiteTag, GraphiteTagOperator } from '../types'; type Props = { tag: GraphiteTag; diff --git a/public/app/plugins/datasource/graphite/components/TagsSection.tsx b/public/app/plugins/datasource/graphite/components/TagsSection.tsx index 72b5cb240cf..6c29e212257 100644 --- a/public/app/plugins/datasource/graphite/components/TagsSection.tsx +++ b/public/app/plugins/datasource/graphite/components/TagsSection.tsx @@ -1,16 +1,19 @@ -import React, { useCallback, useMemo } from 'react'; -import { GraphiteSegment } from '../types'; -import { GraphiteTag } from '../graphite_query'; -import { GraphiteQueryEditorState } from '../state/store'; -import { getTagsAsSegmentsSelectables } from '../state/providers'; -import { Button, SegmentAsync, useStyles2 } from '@grafana/ui'; -import { actions } from '../state/actions'; -import { GrafanaTheme2 } from '@grafana/data'; import { css } from '@emotion/css'; -import { TagEditor } from './TagEditor'; import { debounce } from 'lodash'; +import React, { useCallback, useMemo } from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; +import { Button, SegmentAsync, useStyles2 } from '@grafana/ui'; + +import { GraphiteTag } from '../graphite_query'; +import { actions } from '../state/actions'; import { useDispatch } from '../state/context'; +import { getTagsAsSegmentsSelectables } from '../state/providers'; +import { GraphiteQueryEditorState } from '../state/store'; +import { GraphiteSegment } from '../types'; + import { PlayButton } from './PlayButton'; +import { TagEditor } from './TagEditor'; type Props = { tags: GraphiteTag[]; diff --git a/public/app/plugins/datasource/graphite/components/helpers.test.ts b/public/app/plugins/datasource/graphite/components/helpers.test.ts index 25e179f23d4..52c8b1595f9 100644 --- a/public/app/plugins/datasource/graphite/components/helpers.test.ts +++ b/public/app/plugins/datasource/graphite/components/helpers.test.ts @@ -1,6 +1,7 @@ -import { mapFuncDefsToSelectables, mapFuncInstanceToParams } from './helpers'; import { FuncDef, FuncDefs, FuncInstance } from '../gfunc'; + import { EditableParam } from './FunctionParamEditor'; +import { mapFuncDefsToSelectables, mapFuncInstanceToParams } from './helpers'; function createFunctionInstance(funcDef: FuncDef, currentParams: string[]): FuncInstance { let funcInstance: FuncInstance = new FuncInstance(funcDef); diff --git a/public/app/plugins/datasource/graphite/components/helpers.ts b/public/app/plugins/datasource/graphite/components/helpers.ts index 39578b7edd7..1b40ad11950 100644 --- a/public/app/plugins/datasource/graphite/components/helpers.ts +++ b/public/app/plugins/datasource/graphite/components/helpers.ts @@ -1,9 +1,12 @@ -import { FuncDefs, FuncInstance, ParamDef } from '../gfunc'; import { forEach, sortBy } from 'lodash'; + import { SelectableValue } from '@grafana/data'; -import { EditableParam } from './FunctionParamEditor'; + +import { FuncDefs, FuncInstance, ParamDef } from '../gfunc'; import { GraphiteSegment } from '../types'; +import { EditableParam } from './FunctionParamEditor'; + export function mapStringsToSelectables(values: T[]): Array> { return values.map((value) => ({ value, diff --git a/public/app/plugins/datasource/graphite/configuration/ConfigEditor.tsx b/public/app/plugins/datasource/graphite/configuration/ConfigEditor.tsx index 88528f40237..ffe43a80037 100644 --- a/public/app/plugins/datasource/graphite/configuration/ConfigEditor.tsx +++ b/public/app/plugins/datasource/graphite/configuration/ConfigEditor.tsx @@ -1,18 +1,21 @@ import React, { PureComponent } from 'react'; -import { Alert, DataSourceHttpSettings, InlineFormLabel, LegacyForms } from '@grafana/ui'; -const { Select, Switch } = LegacyForms; + import { DataSourcePluginOptionsEditorProps, updateDatasourcePluginJsonDataOption, onUpdateDatasourceJsonDataOptionSelect, onUpdateDatasourceJsonDataOptionChecked, } from '@grafana/data'; -import { GraphiteOptions, GraphiteType } from '../types'; -import { DEFAULT_GRAPHITE_VERSION, GRAPHITE_VERSIONS } from '../versions'; -import { MappingsConfiguration } from './MappingsConfiguration'; -import { fromString, toString } from './parseLokiLabelMappings'; +import { Alert, DataSourceHttpSettings, InlineFormLabel, LegacyForms } from '@grafana/ui'; import store from 'app/core/store'; +import { GraphiteOptions, GraphiteType } from '../types'; +import { DEFAULT_GRAPHITE_VERSION, GRAPHITE_VERSIONS } from '../versions'; + +import { MappingsConfiguration } from './MappingsConfiguration'; +import { fromString, toString } from './parseLokiLabelMappings'; + +const { Select, Switch } = LegacyForms; export const SHOW_MAPPINGS_HELP_KEY = 'grafana.datasources.graphite.config.showMappingsHelp'; const graphiteVersions = GRAPHITE_VERSIONS.map((version) => ({ label: `${version}.x`, value: version })); diff --git a/public/app/plugins/datasource/graphite/configuration/MappingsConfiguration.tsx b/public/app/plugins/datasource/graphite/configuration/MappingsConfiguration.tsx index c5cd2e5a401..bb593a1edb0 100644 --- a/public/app/plugins/datasource/graphite/configuration/MappingsConfiguration.tsx +++ b/public/app/plugins/datasource/graphite/configuration/MappingsConfiguration.tsx @@ -1,5 +1,7 @@ import React, { ChangeEvent, useState } from 'react'; + import { Button, Icon, InlineField, InlineFieldRow, Input } from '@grafana/ui'; + import MappingsHelp from './MappingsHelp'; type Props = { diff --git a/public/app/plugins/datasource/graphite/configuration/MappingsHelp.tsx b/public/app/plugins/datasource/graphite/configuration/MappingsHelp.tsx index a314ee7440d..a3b7b4f0dac 100644 --- a/public/app/plugins/datasource/graphite/configuration/MappingsHelp.tsx +++ b/public/app/plugins/datasource/graphite/configuration/MappingsHelp.tsx @@ -1,6 +1,7 @@ -import { Alert } from '@grafana/ui'; import React from 'react'; +import { Alert } from '@grafana/ui'; + type Props = { onDismiss: () => void; }; diff --git a/public/app/plugins/datasource/graphite/datasource.test.ts b/public/app/plugins/datasource/graphite/datasource.test.ts index ed4a60ce3ee..23c5695a8ff 100644 --- a/public/app/plugins/datasource/graphite/datasource.test.ts +++ b/public/app/plugins/datasource/graphite/datasource.test.ts @@ -1,13 +1,14 @@ -import { GraphiteDatasource } from './datasource'; import { isArray } from 'lodash'; - -import { TemplateSrv } from 'app/features/templating/template_srv'; -import { AbstractLabelMatcher, AbstractLabelOperator, dateTime, getFrameDisplayName } from '@grafana/data'; -import { backendSrv } from 'app/core/services/backend_srv'; // will use the version in __mocks__ import { of } from 'rxjs'; import { createFetchResponse } from 'test/helpers/createFetchResponse'; -import { DEFAULT_GRAPHITE_VERSION } from './versions'; + +import { AbstractLabelMatcher, AbstractLabelOperator, dateTime, getFrameDisplayName } from '@grafana/data'; +import { backendSrv } from 'app/core/services/backend_srv'; // will use the version in __mocks__ +import { TemplateSrv } from 'app/features/templating/template_srv'; + import { fromString } from './configuration/parseLokiLabelMappings'; +import { GraphiteDatasource } from './datasource'; +import { DEFAULT_GRAPHITE_VERSION } from './versions'; jest.mock('@grafana/runtime', () => ({ ...(jest.requireActual('@grafana/runtime') as unknown as object), diff --git a/public/app/plugins/datasource/graphite/datasource.ts b/public/app/plugins/datasource/graphite/datasource.ts index f09ea680694..4a464822859 100644 --- a/public/app/plugins/datasource/graphite/datasource.ts +++ b/public/app/plugins/datasource/graphite/datasource.ts @@ -1,7 +1,7 @@ import { each, indexOf, isArray, isString, map as _map } from 'lodash'; import { lastValueFrom, Observable, of, OperatorFunction, pipe, throwError } from 'rxjs'; import { catchError, map } from 'rxjs/operators'; -import { getBackendSrv } from '@grafana/runtime'; + import { DataFrame, DataQueryRequest, @@ -18,11 +18,15 @@ import { TimeRange, toDataFrame, } from '@grafana/data'; - +import { getBackendSrv } from '@grafana/runtime'; import { isVersionGtOrEq, SemVersion } from 'app/core/utils/version'; -import gfunc, { FuncDefs, FuncInstance } from './gfunc'; import { getTemplateSrv, TemplateSrv } from 'app/features/templating/template_srv'; -// Types +import { getRollupNotice, getRuntimeConsolidationNotice } from 'app/plugins/datasource/graphite/meta'; + +import { getSearchFilterScopedVar } from '../../../features/variables/utils'; + +import gfunc, { FuncDefs, FuncInstance } from './gfunc'; +import { default as GraphiteQueryModel } from './graphite_query'; import { GraphiteLokiMapping, GraphiteMetricLokiMatcher, @@ -32,11 +36,8 @@ import { GraphiteType, MetricTankRequestMeta, } from './types'; -import { getRollupNotice, getRuntimeConsolidationNotice } from 'app/plugins/datasource/graphite/meta'; -import { getSearchFilterScopedVar } from '../../../features/variables/utils'; -import { DEFAULT_GRAPHITE_VERSION } from './versions'; import { reduceError } from './utils'; -import { default as GraphiteQueryModel } from './graphite_query'; +import { DEFAULT_GRAPHITE_VERSION } from './versions'; const GRAPHITE_TAG_COMPARATORS = { '=': AbstractLabelOperator.Equal, diff --git a/public/app/plugins/datasource/graphite/gfunc.ts b/public/app/plugins/datasource/graphite/gfunc.ts index aee41af7dd3..44609e30824 100644 --- a/public/app/plugins/datasource/graphite/gfunc.ts +++ b/public/app/plugins/datasource/graphite/gfunc.ts @@ -1,6 +1,7 @@ import { assign, each, filter, forEach, get, includes, isString, last, map, toString, isFinite } from 'lodash'; -import { isVersionGtOrEq } from 'app/core/utils/version'; + import { InterpolateFunction } from '@grafana/data'; +import { isVersionGtOrEq } from 'app/core/utils/version'; export type ParamDef = { name: string; diff --git a/public/app/plugins/datasource/graphite/graphite_query.ts b/public/app/plugins/datasource/graphite/graphite_query.ts index da76d351e42..40232d19dfe 100644 --- a/public/app/plugins/datasource/graphite/graphite_query.ts +++ b/public/app/plugins/datasource/graphite/graphite_query.ts @@ -1,11 +1,13 @@ import { compact, each, findIndex, flatten, get, join, keyBy, last, map, reduce, without } from 'lodash'; -import { arrayMove } from 'app/core/utils/arrayMove'; -import { Parser } from './parser'; -import { TemplateSrv } from '@grafana/runtime'; + import { ScopedVars } from '@grafana/data'; -import { FuncInstance } from './gfunc'; -import { GraphiteSegment } from './types'; +import { TemplateSrv } from '@grafana/runtime'; +import { arrayMove } from 'app/core/utils/arrayMove'; + import { GraphiteDatasource } from './datasource'; +import { FuncInstance } from './gfunc'; +import { Parser } from './parser'; +import { GraphiteSegment } from './types'; export type GraphiteTagOperator = '=' | '=~' | '!=' | '!=~'; diff --git a/public/app/plugins/datasource/graphite/meta.ts b/public/app/plugins/datasource/graphite/meta.ts index 6bd24bd9406..1b1bcaf0631 100644 --- a/public/app/plugins/datasource/graphite/meta.ts +++ b/public/app/plugins/datasource/graphite/meta.ts @@ -1,6 +1,7 @@ -import { MetricTankSeriesMeta } from './types'; import { QueryResultMetaNotice } from '@grafana/data'; +import { MetricTankSeriesMeta } from './types'; + // https://github.com/grafana/metrictank/blob/master/scripts/config/storage-schemas.conf#L15-L46 export interface RetentionInfo { diff --git a/public/app/plugins/datasource/graphite/module.ts b/public/app/plugins/datasource/graphite/module.ts index 677be4fa678..39873ae4109 100644 --- a/public/app/plugins/datasource/graphite/module.ts +++ b/public/app/plugins/datasource/graphite/module.ts @@ -1,8 +1,9 @@ -import { GraphiteDatasource } from './datasource'; import { DataSourcePlugin } from '@grafana/data'; -import { ConfigEditor } from './configuration/ConfigEditor'; -import { MetricTankMetaInspector } from './components/MetricTankMetaInspector'; + import { GraphiteQueryEditor } from './components/GraphiteQueryEditor'; +import { MetricTankMetaInspector } from './components/MetricTankMetaInspector'; +import { ConfigEditor } from './configuration/ConfigEditor'; +import { GraphiteDatasource } from './datasource'; class AnnotationsQueryCtrl { static templateUrl = 'partials/annotations.editor.html'; diff --git a/public/app/plugins/datasource/graphite/specs/graphite_query.test.ts b/public/app/plugins/datasource/graphite/specs/graphite_query.test.ts index 16ab9616b01..0d0f516f474 100644 --- a/public/app/plugins/datasource/graphite/specs/graphite_query.test.ts +++ b/public/app/plugins/datasource/graphite/specs/graphite_query.test.ts @@ -1,6 +1,7 @@ +import { TemplateSrvStub } from 'test/specs/helpers'; + import gfunc from '../gfunc'; import GraphiteQuery from '../graphite_query'; -import { TemplateSrvStub } from 'test/specs/helpers'; describe('Graphite query model', () => { const ctx: any = { diff --git a/public/app/plugins/datasource/graphite/specs/store.test.ts b/public/app/plugins/datasource/graphite/specs/store.test.ts index b0e15713c1e..262e606e741 100644 --- a/public/app/plugins/datasource/graphite/specs/store.test.ts +++ b/public/app/plugins/datasource/graphite/specs/store.test.ts @@ -1,6 +1,8 @@ -import { dispatch } from 'app/store/store'; -import gfunc from '../gfunc'; import { TemplateSrvStub } from 'test/specs/helpers'; + +import { dispatch } from 'app/store/store'; + +import gfunc from '../gfunc'; import { actions } from '../state/actions'; import { getAltSegmentsSelectables, @@ -8,8 +10,8 @@ import { getTagsAsSegmentsSelectables, getTagValuesSelectables, } from '../state/providers'; -import { GraphiteSegment } from '../types'; import { createStore } from '../state/store'; +import { GraphiteSegment } from '../types'; jest.mock('app/angular/promiseToDigest', () => ({ promiseToDigest: (scope: any) => { diff --git a/public/app/plugins/datasource/graphite/state/actions.ts b/public/app/plugins/datasource/graphite/state/actions.ts index 555a1639b0e..2022da0de92 100644 --- a/public/app/plugins/datasource/graphite/state/actions.ts +++ b/public/app/plugins/datasource/graphite/state/actions.ts @@ -1,8 +1,10 @@ -import { GraphiteQuery, GraphiteQueryEditorDependencies, GraphiteSegment, GraphiteTag } from '../types'; import { createAction } from '@reduxjs/toolkit'; -import { FuncInstance } from '../gfunc'; + import { TimeRange } from '@grafana/data'; +import { FuncInstance } from '../gfunc'; +import { GraphiteQuery, GraphiteQueryEditorDependencies, GraphiteSegment, GraphiteTag } from '../types'; + /** * List of possible actions changing the state of QueryEditor */ diff --git a/public/app/plugins/datasource/graphite/state/context.tsx b/public/app/plugins/datasource/graphite/state/context.tsx index 2a4f303e62b..2565431e5bc 100644 --- a/public/app/plugins/datasource/graphite/state/context.tsx +++ b/public/app/plugins/datasource/graphite/state/context.tsx @@ -1,12 +1,15 @@ -import React, { createContext, Dispatch, PropsWithChildren, useContext, useEffect, useMemo, useState } from 'react'; import { AnyAction } from '@reduxjs/toolkit'; +import React, { createContext, Dispatch, PropsWithChildren, useContext, useEffect, useMemo, useState } from 'react'; +import { usePrevious } from 'react-use'; + import { QueryEditorProps } from '@grafana/data'; +import { getTemplateSrv } from 'app/features/templating/template_srv'; + import { GraphiteDatasource } from '../datasource'; import { GraphiteOptions, GraphiteQuery } from '../types'; -import { createStore, GraphiteQueryEditorState } from './store'; -import { getTemplateSrv } from 'app/features/templating/template_srv'; + import { actions } from './actions'; -import { usePrevious } from 'react-use'; +import { createStore, GraphiteQueryEditorState } from './store'; const DispatchContext = createContext>({} as Dispatch); const GraphiteStateContext = createContext({} as GraphiteQueryEditorState); diff --git a/public/app/plugins/datasource/graphite/state/helpers.ts b/public/app/plugins/datasource/graphite/state/helpers.ts index 6c235d77280..3378edf16a2 100644 --- a/public/app/plugins/datasource/graphite/state/helpers.ts +++ b/public/app/plugins/datasource/graphite/state/helpers.ts @@ -1,11 +1,13 @@ -import { GraphiteQueryEditorState } from './store'; import { clone } from 'lodash'; -import { dispatch } from '../../../../store/store'; -import { notifyApp } from '../../../../core/reducers/appNotification'; + import { createErrorNotification } from '../../../../core/copy/appNotification'; +import { notifyApp } from '../../../../core/reducers/appNotification'; +import { dispatch } from '../../../../store/store'; import { FuncInstance } from '../gfunc'; import { GraphiteQuery, GraphiteTagOperator } from '../types'; +import { GraphiteQueryEditorState } from './store'; + /** * Helpers used by reducers and providers. They modify state object directly so should operate on a copy of the state. */ diff --git a/public/app/plugins/datasource/graphite/state/providers.ts b/public/app/plugins/datasource/graphite/state/providers.ts index bc2d73e3e56..6db0021d96a 100644 --- a/public/app/plugins/datasource/graphite/state/providers.ts +++ b/public/app/plugins/datasource/graphite/state/providers.ts @@ -1,14 +1,17 @@ -import { GraphiteQueryEditorState } from './store'; import { eachRight, map, remove } from 'lodash'; + +import { SelectableValue } from '@grafana/data'; + +import { mapSegmentsToSelectables, mapStringsToSelectables } from '../components/helpers'; +import { GraphiteSegment, GraphiteTag, GraphiteTagOperator } from '../types'; + import { TAG_PREFIX, GRAPHITE_TAG_OPERATORS, handleMetricsAutoCompleteError, handleTagsAutoCompleteError, } from './helpers'; -import { GraphiteSegment, GraphiteTag, GraphiteTagOperator } from '../types'; -import { mapSegmentsToSelectables, mapStringsToSelectables } from '../components/helpers'; -import { SelectableValue } from '@grafana/data'; +import { GraphiteQueryEditorState } from './store'; /** * All auto-complete lists are updated while typing. To avoid performance issues we do not render more diff --git a/public/app/plugins/datasource/graphite/state/store.ts b/public/app/plugins/datasource/graphite/state/store.ts index 4aeb9ea3e9c..2bd3842df78 100644 --- a/public/app/plugins/datasource/graphite/state/store.ts +++ b/public/app/plugins/datasource/graphite/state/store.ts @@ -1,9 +1,16 @@ +import { AnyAction } from '@reduxjs/toolkit'; +import { Action, Dispatch } from 'redux'; + +import { DataQuery, TimeRange } from '@grafana/data'; +import { getTemplateSrv } from '@grafana/runtime'; + +import { TemplateSrv } from '../../../../features/templating/template_srv'; +import { GraphiteDatasource } from '../datasource'; +import { FuncDefs } from '../gfunc'; import GraphiteQuery, { GraphiteTarget } from '../graphite_query'; import { GraphiteSegment, GraphiteTagOperator } from '../types'; -import { GraphiteDatasource } from '../datasource'; -import { TemplateSrv } from '../../../../features/templating/template_srv'; + import { actions } from './actions'; -import { getTemplateSrv } from '@grafana/runtime'; import { addSeriesByTagFunc, buildSegments, @@ -16,10 +23,6 @@ import { smartlyHandleNewAliasByNode, spliceSegments, } from './helpers'; -import { Action, Dispatch } from 'redux'; -import { FuncDefs } from '../gfunc'; -import { AnyAction } from '@reduxjs/toolkit'; -import { DataQuery, TimeRange } from '@grafana/data'; export type GraphiteQueryEditorState = { // external dependencies diff --git a/public/app/plugins/datasource/graphite/types.ts b/public/app/plugins/datasource/graphite/types.ts index 64387b1b56e..ce5d5436d85 100644 --- a/public/app/plugins/datasource/graphite/types.ts +++ b/public/app/plugins/datasource/graphite/types.ts @@ -1,7 +1,9 @@ import { DataQuery, DataSourceJsonData, TimeRange } from '@grafana/data'; -import { GraphiteDatasource } from './datasource'; + import { TemplateSrv } from '../../../features/templating/template_srv'; +import { GraphiteDatasource } from './datasource'; + export interface GraphiteQuery extends DataQuery { target?: string; } diff --git a/public/app/plugins/datasource/influxdb/components/ConfigEditor.test.tsx b/public/app/plugins/datasource/influxdb/components/ConfigEditor.test.tsx index 8e8e6ed069d..b77656b1dfe 100644 --- a/public/app/plugins/datasource/influxdb/components/ConfigEditor.test.tsx +++ b/public/app/plugins/datasource/influxdb/components/ConfigEditor.test.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { shallow } from 'enzyme'; +import React from 'react'; + import ConfigEditor, { Props } from './ConfigEditor'; jest.mock('lodash', () => { diff --git a/public/app/plugins/datasource/influxdb/components/ConfigEditor.tsx b/public/app/plugins/datasource/influxdb/components/ConfigEditor.tsx index e742899e8ba..acffd37a53f 100644 --- a/public/app/plugins/datasource/influxdb/components/ConfigEditor.tsx +++ b/public/app/plugins/datasource/influxdb/components/ConfigEditor.tsx @@ -1,5 +1,6 @@ -import React, { PureComponent } from 'react'; import { uniqueId } from 'lodash'; +import React, { PureComponent } from 'react'; + import { DataSourcePluginOptionsEditorProps, SelectableValue, @@ -11,6 +12,7 @@ import { updateDatasourcePluginJsonDataOption, } from '@grafana/data'; import { Alert, DataSourceHttpSettings, InfoBox, InlineField, InlineFormLabel, LegacyForms, Select } from '@grafana/ui'; + const { Input, SecretFormField } = LegacyForms; import { InfluxOptions, InfluxSecureJsonData, InfluxVersion } from '../types'; diff --git a/public/app/plugins/datasource/influxdb/components/FluxQueryEditor.tsx b/public/app/plugins/datasource/influxdb/components/FluxQueryEditor.tsx index 19211ed4381..feaa90b2503 100644 --- a/public/app/plugins/datasource/influxdb/components/FluxQueryEditor.tsx +++ b/public/app/plugins/datasource/influxdb/components/FluxQueryEditor.tsx @@ -1,7 +1,8 @@ -import React, { PureComponent } from 'react'; -import { InfluxQuery } from '../types'; -import { SelectableValue } from '@grafana/data'; import { cx, css } from '@emotion/css'; +import React, { PureComponent } from 'react'; + +import { SelectableValue } from '@grafana/data'; +import { getTemplateSrv } from '@grafana/runtime'; import { InlineFormLabel, LinkButton, @@ -11,8 +12,9 @@ import { CodeEditorSuggestionItem, CodeEditorSuggestionItemKind, } from '@grafana/ui'; -import { getTemplateSrv } from '@grafana/runtime'; + import InfluxDatasource from '../datasource'; +import { InfluxQuery } from '../types'; type Props = { onChange: (query: InfluxQuery) => void; diff --git a/public/app/plugins/datasource/influxdb/components/InfluxStartPage.tsx b/public/app/plugins/datasource/influxdb/components/InfluxStartPage.tsx index 846d0155ea7..f5ac86a24d2 100644 --- a/public/app/plugins/datasource/influxdb/components/InfluxStartPage.tsx +++ b/public/app/plugins/datasource/influxdb/components/InfluxStartPage.tsx @@ -1,5 +1,7 @@ import React, { PureComponent } from 'react'; + import { QueryEditorHelpProps } from '@grafana/data'; + import InfluxCheatSheet from './InfluxCheatSheet'; export default class InfluxStartPage extends PureComponent { diff --git a/public/app/plugins/datasource/influxdb/components/QueryEditor.tsx b/public/app/plugins/datasource/influxdb/components/QueryEditor.tsx index 3501a793e37..9d736ba9b7d 100644 --- a/public/app/plugins/datasource/influxdb/components/QueryEditor.tsx +++ b/public/app/plugins/datasource/influxdb/components/QueryEditor.tsx @@ -1,13 +1,16 @@ -import React from 'react'; import { css } from '@emotion/css'; +import React from 'react'; + import { QueryEditorProps } from '@grafana/data'; -import { InfluxOptions, InfluxQuery } from '../types'; + import InfluxDatasource from '../datasource'; +import { buildRawQuery } from '../queryUtils'; +import { InfluxOptions, InfluxQuery } from '../types'; + import { FluxQueryEditor } from './FluxQueryEditor'; +import { QueryEditorModeSwitcher } from './QueryEditorModeSwitcher'; import { RawInfluxQLEditor } from './RawInfluxQLEditor'; import { Editor as VisualInfluxQLEditor } from './VisualInfluxQLEditor/Editor'; -import { QueryEditorModeSwitcher } from './QueryEditorModeSwitcher'; -import { buildRawQuery } from '../queryUtils'; type Props = QueryEditorProps; diff --git a/public/app/plugins/datasource/influxdb/components/QueryEditorModeSwitcher.tsx b/public/app/plugins/datasource/influxdb/components/QueryEditorModeSwitcher.tsx index 745f5849ac3..539ee63f4d5 100644 --- a/public/app/plugins/datasource/influxdb/components/QueryEditorModeSwitcher.tsx +++ b/public/app/plugins/datasource/influxdb/components/QueryEditorModeSwitcher.tsx @@ -1,4 +1,5 @@ import React, { useEffect, useState } from 'react'; + import { Button, ConfirmModal } from '@grafana/ui'; type Props = { diff --git a/public/app/plugins/datasource/influxdb/components/RawInfluxQLEditor.test.tsx b/public/app/plugins/datasource/influxdb/components/RawInfluxQLEditor.test.tsx index 54ad496b2b1..58b9a93e0f7 100644 --- a/public/app/plugins/datasource/influxdb/components/RawInfluxQLEditor.test.tsx +++ b/public/app/plugins/datasource/influxdb/components/RawInfluxQLEditor.test.tsx @@ -1,10 +1,13 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import React from 'react'; + import { selectOptionInTest } from '@grafana/ui'; -import { RawInfluxQLEditor } from './RawInfluxQLEditor'; + import { InfluxQuery } from '../types'; +import { RawInfluxQLEditor } from './RawInfluxQLEditor'; + const query: InfluxQuery = { refId: 'A', query: 'test query 1', diff --git a/public/app/plugins/datasource/influxdb/components/RawInfluxQLEditor.tsx b/public/app/plugins/datasource/influxdb/components/RawInfluxQLEditor.tsx index d0cf13302a8..b815d191556 100644 --- a/public/app/plugins/datasource/influxdb/components/RawInfluxQLEditor.tsx +++ b/public/app/plugins/datasource/influxdb/components/RawInfluxQLEditor.tsx @@ -1,9 +1,12 @@ import React from 'react'; + import { TextArea, InlineFormLabel, Input, Select, HorizontalGroup } from '@grafana/ui'; + import { InfluxQuery } from '../types'; + +import { RESULT_FORMATS, DEFAULT_RESULT_FORMAT } from './constants'; import { useShadowedState } from './useShadowedState'; import { useUniqueId } from './useUniqueId'; -import { RESULT_FORMATS, DEFAULT_RESULT_FORMAT } from './constants'; type Props = { query: InfluxQuery; diff --git a/public/app/plugins/datasource/influxdb/components/VariableQueryEditor.tsx b/public/app/plugins/datasource/influxdb/components/VariableQueryEditor.tsx index 0ca9b6958c9..bf5c9170945 100644 --- a/public/app/plugins/datasource/influxdb/components/VariableQueryEditor.tsx +++ b/public/app/plugins/datasource/influxdb/components/VariableQueryEditor.tsx @@ -1,6 +1,9 @@ import React, { PureComponent } from 'react'; -import InfluxDatasource from '../datasource'; + import { InlineFormLabel, TextArea } from '@grafana/ui'; + +import InfluxDatasource from '../datasource'; + import { FluxQueryEditor } from './FluxQueryEditor'; interface Props { diff --git a/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/AddButton.tsx b/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/AddButton.tsx index 2e7248eca68..8e9cde460d0 100644 --- a/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/AddButton.tsx +++ b/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/AddButton.tsx @@ -1,5 +1,7 @@ import React from 'react'; + import { SelectableValue } from '@grafana/data'; + import { Seg } from './Seg'; import { unwrap } from './unwrap'; diff --git a/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/Editor.tags.test.tsx b/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/Editor.tags.test.tsx index 0b3c7d8169d..eccbb4d4d3a 100644 --- a/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/Editor.tags.test.tsx +++ b/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/Editor.tags.test.tsx @@ -1,10 +1,12 @@ -import React from 'react'; -import { InfluxQuery } from '../../types'; -import InfluxDatasource from '../../datasource'; import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { Editor } from './Editor'; +import React from 'react'; + +import InfluxDatasource from '../../datasource'; import * as mockedMeta from '../../influxQLMetadataQuery'; +import { InfluxQuery } from '../../types'; + +import { Editor } from './Editor'; jest.mock('../../influxQLMetadataQuery', () => { return { diff --git a/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/Editor.test.tsx b/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/Editor.test.tsx index 32772721c3e..a45d8d0f462 100644 --- a/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/Editor.test.tsx +++ b/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/Editor.test.tsx @@ -1,7 +1,9 @@ -import React from 'react'; -import { InfluxQuery } from '../../types'; -import InfluxDatasource from '../../datasource'; import { render } from '@testing-library/react'; +import React from 'react'; + +import InfluxDatasource from '../../datasource'; +import { InfluxQuery } from '../../types'; + import { Editor } from './Editor'; // we mock the @grafana/ui components we use to make sure they just show their "value". diff --git a/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/Editor.tsx b/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/Editor.tsx index c32be940678..4000c6d422f 100644 --- a/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/Editor.tsx +++ b/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/Editor.tsx @@ -1,12 +1,11 @@ +import { css } from '@emotion/css'; import React, { useMemo } from 'react'; -import { InfluxQuery, InfluxQueryTag } from '../../types'; + +import { GrafanaTheme2 } from '@grafana/data'; import { getTemplateSrv } from '@grafana/runtime'; +import { InlineLabel, SegmentSection, useStyles2 } from '@grafana/ui'; + import InfluxDatasource from '../../datasource'; -import { FromSection } from './FromSection'; -import { TagsSection } from './TagsSection'; -import { PartListSection } from './PartListSection'; -import { OrderByTimeSection } from './OrderByTimeSection'; -import { InputSection } from './InputSection'; import { getAllMeasurementsForTags, getAllPolicies, @@ -23,14 +22,18 @@ import { changeSelectPart, changeGroupByPart, } from '../../queryUtils'; -import { FormatAsSection } from './FormatAsSection'; +import { InfluxQuery, InfluxQueryTag } from '../../types'; import { DEFAULT_RESULT_FORMAT } from '../constants'; -import { getNewSelectPartOptions, getNewGroupByPartOptions, makePartList } from './partListUtils'; -import { InlineLabel, SegmentSection, useStyles2 } from '@grafana/ui'; -import { GrafanaTheme2 } from '@grafana/data'; -import { css } from '@emotion/css'; import { useUniqueId } from '../useUniqueId'; +import { FormatAsSection } from './FormatAsSection'; +import { FromSection } from './FromSection'; +import { InputSection } from './InputSection'; +import { OrderByTimeSection } from './OrderByTimeSection'; +import { PartListSection } from './PartListSection'; +import { TagsSection } from './TagsSection'; +import { getNewSelectPartOptions, getNewGroupByPartOptions, makePartList } from './partListUtils'; + type Props = { query: InfluxQuery; onChange: (query: InfluxQuery) => void; diff --git a/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/FormatAsSection.tsx b/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/FormatAsSection.tsx index 20598e649f0..f691181cb48 100644 --- a/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/FormatAsSection.tsx +++ b/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/FormatAsSection.tsx @@ -1,10 +1,13 @@ -import { Select } from '@grafana/ui'; import { cx } from '@emotion/css'; -import { ResultFormat } from '../../types'; import React from 'react'; -import { unwrap } from './unwrap'; + +import { Select } from '@grafana/ui'; + +import { ResultFormat } from '../../types'; import { RESULT_FORMATS } from '../constants'; + import { paddingRightClass } from './styles'; +import { unwrap } from './unwrap'; type Props = { inputId?: string; diff --git a/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/FromSection.tsx b/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/FromSection.tsx index 8ad227edf63..d3b4c7920ac 100644 --- a/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/FromSection.tsx +++ b/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/FromSection.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { Seg } from './Seg'; import { toSelectableValue } from './toSelectableValue'; diff --git a/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/InputSection.tsx b/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/InputSection.tsx index 70edef5b984..3ecb355f552 100644 --- a/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/InputSection.tsx +++ b/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/InputSection.tsx @@ -1,7 +1,10 @@ -import React from 'react'; import { cx } from '@emotion/css'; +import React from 'react'; + import { Input } from '@grafana/ui'; + import { useShadowedState } from '../useShadowedState'; + import { paddingRightClass } from './styles'; type Props = { diff --git a/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/OrderByTimeSection.tsx b/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/OrderByTimeSection.tsx index 90f38aae79e..f870e518e4f 100644 --- a/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/OrderByTimeSection.tsx +++ b/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/OrderByTimeSection.tsx @@ -1,9 +1,11 @@ -import React from 'react'; import { cx } from '@emotion/css'; +import React from 'react'; + import { SelectableValue } from '@grafana/data'; -import { unwrap } from './unwrap'; import { Select } from '@grafana/ui'; + import { paddingRightClass } from './styles'; +import { unwrap } from './unwrap'; type Mode = 'ASC' | 'DESC'; diff --git a/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/PartListSection.tsx b/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/PartListSection.tsx index 54c3bc1fbd1..23d3a94a75c 100644 --- a/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/PartListSection.tsx +++ b/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/PartListSection.tsx @@ -1,11 +1,13 @@ -import React, { useMemo } from 'react'; import { cx, css } from '@emotion/css'; -import { MenuItem, WithContextMenu, MenuGroup, useTheme2 } from '@grafana/ui'; +import React, { useMemo } from 'react'; + import { SelectableValue, GrafanaTheme2 } from '@grafana/data'; -import { Seg } from './Seg'; -import { unwrap } from './unwrap'; -import { toSelectableValue } from './toSelectableValue'; +import { MenuItem, WithContextMenu, MenuGroup, useTheme2 } from '@grafana/ui'; + import { AddButton } from './AddButton'; +import { Seg } from './Seg'; +import { toSelectableValue } from './toSelectableValue'; +import { unwrap } from './unwrap'; export type PartParams = Array<{ value: string; diff --git a/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/Seg.tsx b/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/Seg.tsx index d7ee73c1ba4..a64203668e0 100644 --- a/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/Seg.tsx +++ b/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/Seg.tsx @@ -1,9 +1,11 @@ -import React, { useState, useEffect } from 'react'; -import debouncePromise from 'debounce-promise'; import { cx, css } from '@emotion/css'; -import { SelectableValue } from '@grafana/data'; +import debouncePromise from 'debounce-promise'; +import React, { useState, useEffect } from 'react'; import { useAsyncFn } from 'react-use'; + +import { SelectableValue } from '@grafana/data'; import { InlineLabel, Select, AsyncSelect, Input } from '@grafana/ui'; + import { useShadowedState } from '../useShadowedState'; // this file is a simpler version of `grafana-ui / SegmentAsync.tsx` diff --git a/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/TagsSection.test.tsx b/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/TagsSection.test.tsx index c276373684a..e6589b62b16 100644 --- a/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/TagsSection.test.tsx +++ b/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/TagsSection.test.tsx @@ -1,8 +1,10 @@ -import React from 'react'; import { fireEvent, render, screen, act, waitFor } from '@testing-library/react'; -import { TagsSection } from './TagsSection'; +import React from 'react'; + import { InfluxQueryTag } from '../../types'; +import { TagsSection } from './TagsSection'; + function getTagKeys() { return Promise.resolve(['t1', 't2', 't3', 't4', 't5', 't6']); } diff --git a/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/TagsSection.tsx b/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/TagsSection.tsx index eb4a067cb68..051c2f1ae9f 100644 --- a/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/TagsSection.tsx +++ b/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/TagsSection.tsx @@ -1,10 +1,13 @@ import React from 'react'; + import { SelectableValue } from '@grafana/data'; -import { Seg } from './Seg'; + import { InfluxQueryTag } from '../../types'; -import { toSelectableValue } from './toSelectableValue'; -import { adjustOperatorIfNeeded, getCondition, getOperator } from './tagUtils'; + import { AddButton } from './AddButton'; +import { Seg } from './Seg'; +import { adjustOperatorIfNeeded, getCondition, getOperator } from './tagUtils'; +import { toSelectableValue } from './toSelectableValue'; type KnownOperator = '=' | '!=' | '<>' | '<' | '>' | '=~' | '!~'; const knownOperators: KnownOperator[] = ['=', '!=', '<>', '<', '>', '=~', '!~']; diff --git a/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/partListUtils.tsx b/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/partListUtils.tsx index bd5eb0663bc..c3b76c1002b 100644 --- a/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/partListUtils.tsx +++ b/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/partListUtils.tsx @@ -1,12 +1,14 @@ -import { InfluxQuery, InfluxQueryPart } from '../../types'; import { SelectableValue } from '@grafana/data'; -import { PartParams } from './PartListSection'; -import InfluxQueryModel from '../../influx_query_model'; -import { unwrap } from './unwrap'; -import queryPart from '../../query_part'; -import { toSelectableValue } from './toSelectableValue'; import { QueryPartDef } from 'app/features/alerting/state/query_part'; +import InfluxQueryModel from '../../influx_query_model'; +import queryPart from '../../query_part'; +import { InfluxQuery, InfluxQueryPart } from '../../types'; + +import { PartParams } from './PartListSection'; +import { toSelectableValue } from './toSelectableValue'; +import { unwrap } from './unwrap'; + type Categories = Record; export function getNewSelectPartOptions(): SelectableValue[] { diff --git a/public/app/plugins/datasource/influxdb/components/constants.ts b/public/app/plugins/datasource/influxdb/components/constants.ts index 9e80560a598..dcf1910b359 100644 --- a/public/app/plugins/datasource/influxdb/components/constants.ts +++ b/public/app/plugins/datasource/influxdb/components/constants.ts @@ -1,4 +1,5 @@ import { SelectableValue } from '@grafana/data'; + import { ResultFormat } from '../types'; export const RESULT_FORMATS: Array> = [ diff --git a/public/app/plugins/datasource/influxdb/components/useShadowedState.test.ts b/public/app/plugins/datasource/influxdb/components/useShadowedState.test.ts index 1e38b366e33..d339123ef40 100644 --- a/public/app/plugins/datasource/influxdb/components/useShadowedState.test.ts +++ b/public/app/plugins/datasource/influxdb/components/useShadowedState.test.ts @@ -1,4 +1,5 @@ import { renderHook, act } from '@testing-library/react-hooks'; + import { useShadowedState } from './useShadowedState'; describe('useShadowedState', () => { diff --git a/public/app/plugins/datasource/influxdb/components/useUniqueId.test.ts b/public/app/plugins/datasource/influxdb/components/useUniqueId.test.ts index ade77dd8c8c..57c5483cc50 100644 --- a/public/app/plugins/datasource/influxdb/components/useUniqueId.test.ts +++ b/public/app/plugins/datasource/influxdb/components/useUniqueId.test.ts @@ -1,4 +1,5 @@ import { renderHook } from '@testing-library/react-hooks'; + import { useUniqueId } from './useUniqueId'; describe('useUniqueId', () => { diff --git a/public/app/plugins/datasource/influxdb/components/useUniqueId.ts b/public/app/plugins/datasource/influxdb/components/useUniqueId.ts index 8790060b794..6ff4ab7c4b0 100644 --- a/public/app/plugins/datasource/influxdb/components/useUniqueId.ts +++ b/public/app/plugins/datasource/influxdb/components/useUniqueId.ts @@ -1,5 +1,5 @@ -import { useRef } from 'react'; import { uniqueId } from 'lodash'; +import { useRef } from 'react'; export function useUniqueId(): string { // we need to lazy-init this ref. diff --git a/public/app/plugins/datasource/influxdb/datasource.ts b/public/app/plugins/datasource/influxdb/datasource.ts index 2a26e4ccd5f..3001fcd2467 100644 --- a/public/app/plugins/datasource/influxdb/datasource.ts +++ b/public/app/plugins/datasource/influxdb/datasource.ts @@ -2,13 +2,7 @@ import { cloneDeep, extend, get, groupBy, has, isString, map as _map, omit, pick import { lastValueFrom, Observable, of, throwError } from 'rxjs'; import { catchError, map } from 'rxjs/operators'; import { v4 as uuidv4 } from 'uuid'; -import { - BackendDataSourceResponse, - DataSourceWithBackend, - FetchResponse, - frameToMetricFindValue, - getBackendSrv, -} from '@grafana/runtime'; + import { AnnotationEvent, ArrayVector, @@ -29,15 +23,23 @@ import { TimeSeries, AnnotationQueryRequest, } from '@grafana/data'; -import InfluxSeries from './influx_series'; -import InfluxQueryModel from './influx_query_model'; -import ResponseParser from './response_parser'; -import { InfluxQueryBuilder } from './query_builder'; -import { InfluxOptions, InfluxQuery, InfluxVersion } from './types'; -import { getTemplateSrv, TemplateSrv } from 'app/features/templating/template_srv'; -import { FluxQueryEditor } from './components/FluxQueryEditor'; -import { buildRawQuery } from './queryUtils'; +import { + BackendDataSourceResponse, + DataSourceWithBackend, + FetchResponse, + frameToMetricFindValue, + getBackendSrv, +} from '@grafana/runtime'; import config from 'app/core/config'; +import { getTemplateSrv, TemplateSrv } from 'app/features/templating/template_srv'; + +import { FluxQueryEditor } from './components/FluxQueryEditor'; +import InfluxQueryModel from './influx_query_model'; +import InfluxSeries from './influx_series'; +import { buildRawQuery } from './queryUtils'; +import { InfluxQueryBuilder } from './query_builder'; +import ResponseParser from './response_parser'; +import { InfluxOptions, InfluxQuery, InfluxVersion } from './types'; // we detect the field type based on the value-array function getFieldType(values: unknown[]): FieldType { diff --git a/public/app/plugins/datasource/influxdb/influxQLMetadataQuery.ts b/public/app/plugins/datasource/influxdb/influxQLMetadataQuery.ts index c03a1b0d16b..edd35d3f0ac 100644 --- a/public/app/plugins/datasource/influxdb/influxQLMetadataQuery.ts +++ b/public/app/plugins/datasource/influxdb/influxQLMetadataQuery.ts @@ -1,6 +1,6 @@ -import { InfluxQueryTag } from './types'; import InfluxDatasource from './datasource'; import { InfluxQueryBuilder } from './query_builder'; +import { InfluxQueryTag } from './types'; const runExploreQuery = ( type: string, diff --git a/public/app/plugins/datasource/influxdb/influx_query_model.ts b/public/app/plugins/datasource/influxdb/influx_query_model.ts index 78f69e666af..cbb6a7ab98c 100644 --- a/public/app/plugins/datasource/influxdb/influx_query_model.ts +++ b/public/app/plugins/datasource/influxdb/influx_query_model.ts @@ -1,9 +1,11 @@ import { map, find, filter, indexOf } from 'lodash'; -import queryPart from './query_part'; -import kbn from 'app/core/utils/kbn'; -import { InfluxQuery, InfluxQueryTag } from './types'; + import { ScopedVars } from '@grafana/data'; import { TemplateSrv } from '@grafana/runtime'; +import kbn from 'app/core/utils/kbn'; + +import queryPart from './query_part'; +import { InfluxQuery, InfluxQueryTag } from './types'; export default class InfluxQueryModel { target: InfluxQuery; diff --git a/public/app/plugins/datasource/influxdb/influx_series.ts b/public/app/plugins/datasource/influxdb/influx_series.ts index c60d394d45e..2776592155b 100644 --- a/public/app/plugins/datasource/influxdb/influx_series.ts +++ b/public/app/plugins/datasource/influxdb/influx_series.ts @@ -1,6 +1,7 @@ import { each, map, includes, flatten, keys } from 'lodash'; -import TableModel from 'app/core/table_model'; + import { FieldType, QueryResultMeta, TimeSeries, TableData } from '@grafana/data'; +import TableModel from 'app/core/table_model'; export default class InfluxSeries { refId?: string; diff --git a/public/app/plugins/datasource/influxdb/module.ts b/public/app/plugins/datasource/influxdb/module.ts index 6c6dd21b6f4..24d9e767648 100644 --- a/public/app/plugins/datasource/influxdb/module.ts +++ b/public/app/plugins/datasource/influxdb/module.ts @@ -1,9 +1,10 @@ -import InfluxDatasource from './datasource'; -import { QueryEditor } from './components/QueryEditor'; -import InfluxStartPage from './components/InfluxStartPage'; import { DataSourcePlugin } from '@grafana/data'; + import ConfigEditor from './components/ConfigEditor'; +import InfluxStartPage from './components/InfluxStartPage'; +import { QueryEditor } from './components/QueryEditor'; import VariableQueryEditor from './components/VariableQueryEditor'; +import InfluxDatasource from './datasource'; class InfluxAnnotationsQueryCtrl { static templateUrl = 'partials/annotations.editor.html'; diff --git a/public/app/plugins/datasource/influxdb/queryUtils.test.ts b/public/app/plugins/datasource/influxdb/queryUtils.test.ts index 1dc9649a54b..531c5446705 100644 --- a/public/app/plugins/datasource/influxdb/queryUtils.test.ts +++ b/public/app/plugins/datasource/influxdb/queryUtils.test.ts @@ -1,6 +1,7 @@ import { cloneDeep } from 'lodash'; -import { InfluxQuery } from './types'; + import { buildRawQuery, normalizeQuery, changeSelectPart, changeGroupByPart } from './queryUtils'; +import { InfluxQuery } from './types'; describe('InfluxDB query utils', () => { describe('buildRawQuery', () => { diff --git a/public/app/plugins/datasource/influxdb/queryUtils.ts b/public/app/plugins/datasource/influxdb/queryUtils.ts index 9db6c905735..4e29614906c 100644 --- a/public/app/plugins/datasource/influxdb/queryUtils.ts +++ b/public/app/plugins/datasource/influxdb/queryUtils.ts @@ -1,4 +1,5 @@ import { cloneDeep } from 'lodash'; + import InfluxQueryModel from './influx_query_model'; import { InfluxQuery } from './types'; diff --git a/public/app/plugins/datasource/influxdb/query_builder.ts b/public/app/plugins/datasource/influxdb/query_builder.ts index 49b8a0089d5..ba044d436b6 100644 --- a/public/app/plugins/datasource/influxdb/query_builder.ts +++ b/public/app/plugins/datasource/influxdb/query_builder.ts @@ -1,4 +1,5 @@ import { reduce } from 'lodash'; + import kbn from 'app/core/utils/kbn'; function renderTagCondition(tag: { operator: any; value: string; condition: any; key: string }, index: number) { diff --git a/public/app/plugins/datasource/influxdb/query_part.ts b/public/app/plugins/datasource/influxdb/query_part.ts index 98d7cdc55f9..b8914ecabb8 100644 --- a/public/app/plugins/datasource/influxdb/query_part.ts +++ b/public/app/plugins/datasource/influxdb/query_part.ts @@ -1,4 +1,5 @@ import { map, clone } from 'lodash'; + import { QueryPartDef, QueryPart, functionRenderer, suffixRenderer } from 'app/features/alerting/state/query_part'; const index: any[] = []; diff --git a/public/app/plugins/datasource/influxdb/response_parser.ts b/public/app/plugins/datasource/influxdb/response_parser.ts index 93544aded31..459da8b441e 100644 --- a/public/app/plugins/datasource/influxdb/response_parser.ts +++ b/public/app/plugins/datasource/influxdb/response_parser.ts @@ -1,7 +1,9 @@ +import { each, flatten, groupBy, isArray } from 'lodash'; + import { AnnotationEvent, DataFrame, DataQuery, FieldType, QueryResultMeta } from '@grafana/data'; import { toDataQueryResponse } from '@grafana/runtime'; import TableModel from 'app/core/table_model'; -import { each, flatten, groupBy, isArray } from 'lodash'; + import { InfluxQuery } from './types'; export default class ResponseParser { diff --git a/public/app/plugins/datasource/influxdb/specs/datasource.test.ts b/public/app/plugins/datasource/influxdb/specs/datasource.test.ts index eb3fcc2e556..604e9c53a36 100644 --- a/public/app/plugins/datasource/influxdb/specs/datasource.test.ts +++ b/public/app/plugins/datasource/influxdb/specs/datasource.test.ts @@ -1,10 +1,11 @@ import { lastValueFrom, of } from 'rxjs'; +import { TemplateSrvStub } from 'test/specs/helpers'; + import { FetchResponse } from '@grafana/runtime'; +import config from 'app/core/config'; +import { backendSrv } from 'app/core/services/backend_srv'; // will use the version in __mocks__ import InfluxDatasource from '../datasource'; -import { TemplateSrvStub } from 'test/specs/helpers'; -import { backendSrv } from 'app/core/services/backend_srv'; // will use the version in __mocks__ -import config from 'app/core/config'; //@ts-ignore const templateSrv = new TemplateSrvStub(); diff --git a/public/app/plugins/datasource/influxdb/specs/influx_series.test.ts b/public/app/plugins/datasource/influxdb/specs/influx_series.test.ts index d65b92916bd..ade1587f87e 100644 --- a/public/app/plugins/datasource/influxdb/specs/influx_series.test.ts +++ b/public/app/plugins/datasource/influxdb/specs/influx_series.test.ts @@ -1,4 +1,5 @@ import produce from 'immer'; + import InfluxSeries from '../influx_series'; describe('when generating timeseries from influxdb response', () => { diff --git a/public/app/plugins/datasource/influxdb/specs/response_parser.test.ts b/public/app/plugins/datasource/influxdb/specs/response_parser.test.ts index b9f988c497c..4ce76c6fa05 100644 --- a/public/app/plugins/datasource/influxdb/specs/response_parser.test.ts +++ b/public/app/plugins/datasource/influxdb/specs/response_parser.test.ts @@ -1,13 +1,15 @@ import { size } from 'lodash'; -import ResponseParser, { getSelectedParams } from '../response_parser'; -import InfluxQueryModel from '../influx_query_model'; -import { FieldType, MutableDataFrame } from '@grafana/data'; -import { backendSrv } from 'app/core/services/backend_srv'; // will use the version in __mocks__ -import InfluxDatasource from '../datasource'; import { of } from 'rxjs'; -import { FetchResponse } from '@grafana/runtime'; import { TemplateSrvStub } from 'test/specs/helpers'; + +import { FieldType, MutableDataFrame } from '@grafana/data'; +import { FetchResponse } from '@grafana/runtime'; import config from 'app/core/config'; +import { backendSrv } from 'app/core/services/backend_srv'; // will use the version in __mocks__ + +import InfluxDatasource from '../datasource'; +import InfluxQueryModel from '../influx_query_model'; +import ResponseParser, { getSelectedParams } from '../response_parser'; //@ts-ignore const templateSrv = new TemplateSrvStub(); diff --git a/public/app/plugins/datasource/jaeger/components/AdvancedOptions.tsx b/public/app/plugins/datasource/jaeger/components/AdvancedOptions.tsx index dff7cc564fc..ff7c497ea95 100644 --- a/public/app/plugins/datasource/jaeger/components/AdvancedOptions.tsx +++ b/public/app/plugins/datasource/jaeger/components/AdvancedOptions.tsx @@ -1,8 +1,10 @@ import { css } from '@emotion/css'; -import { GrafanaTheme } from '@grafana/data'; -import { Icon, InlineField, InlineFieldRow, InlineLabel, Input, useStyles } from '@grafana/ui'; import React, { useState } from 'react'; import { CSSTransition } from 'react-transition-group'; + +import { GrafanaTheme } from '@grafana/data'; +import { Icon, InlineField, InlineFieldRow, InlineLabel, Input, useStyles } from '@grafana/ui'; + import { JaegerQuery } from '../types'; const durationPlaceholder = 'e.g. 1.2s, 100ms, 500us'; diff --git a/public/app/plugins/datasource/jaeger/components/ConfigEditor.tsx b/public/app/plugins/datasource/jaeger/components/ConfigEditor.tsx index 7ad0fe8ead0..114a7ef8a3e 100644 --- a/public/app/plugins/datasource/jaeger/components/ConfigEditor.tsx +++ b/public/app/plugins/datasource/jaeger/components/ConfigEditor.tsx @@ -1,8 +1,9 @@ +import React from 'react'; + import { DataSourcePluginOptionsEditorProps } from '@grafana/data'; import { DataSourceHttpSettings } from '@grafana/ui'; import { NodeGraphSettings } from 'app/core/components/NodeGraphSettings'; import { TraceToLogsSettings } from 'app/core/components/TraceToLogs/TraceToLogsSettings'; -import React from 'react'; export type Props = DataSourcePluginOptionsEditorProps; diff --git a/public/app/plugins/datasource/jaeger/components/QueryEditor.tsx b/public/app/plugins/datasource/jaeger/components/QueryEditor.tsx index 2a2ed26ddb7..29de17cf6d6 100644 --- a/public/app/plugins/datasource/jaeger/components/QueryEditor.tsx +++ b/public/app/plugins/datasource/jaeger/components/QueryEditor.tsx @@ -1,9 +1,12 @@ import { css } from '@emotion/css'; +import React from 'react'; + import { QueryEditorProps } from '@grafana/data'; import { FileDropzone, InlineField, InlineFieldRow, QueryField, RadioButtonGroup, useTheme2 } from '@grafana/ui'; -import React from 'react'; + import { JaegerDatasource } from '../datasource'; import { JaegerQuery, JaegerQueryType } from '../types'; + import { SearchForm } from './SearchForm'; type Props = QueryEditorProps; diff --git a/public/app/plugins/datasource/jaeger/components/SearchForm.test.tsx b/public/app/plugins/datasource/jaeger/components/SearchForm.test.tsx index f7059afb903..00171650969 100644 --- a/public/app/plugins/datasource/jaeger/components/SearchForm.test.tsx +++ b/public/app/plugins/datasource/jaeger/components/SearchForm.test.tsx @@ -1,15 +1,18 @@ import { render, screen, waitFor } from '@testing-library/react'; -import { backendSrv } from 'app/core/services/backend_srv'; -import { createFetchResponse } from 'test/helpers/createFetchResponse'; -import { DataQueryRequest, DataSourceInstanceSettings, dateTime, PluginType } from '@grafana/data'; -import { of } from 'rxjs'; -import { JaegerDatasource, JaegerJsonData } from '../datasource'; -import { JaegerQuery } from '../types'; -import React from 'react'; -import SearchForm from './SearchForm'; -import { testResponse } from '../testResponse'; import userEvent from '@testing-library/user-event'; import { UserEvent } from '@testing-library/user-event/dist/types/setup'; +import React from 'react'; +import { of } from 'rxjs'; +import { createFetchResponse } from 'test/helpers/createFetchResponse'; + +import { DataQueryRequest, DataSourceInstanceSettings, dateTime, PluginType } from '@grafana/data'; +import { backendSrv } from 'app/core/services/backend_srv'; + +import { JaegerDatasource, JaegerJsonData } from '../datasource'; +import { testResponse } from '../testResponse'; +import { JaegerQuery } from '../types'; + +import SearchForm from './SearchForm'; describe('SearchForm', () => { it('should call the `onChange` function on click of the Input', async () => { diff --git a/public/app/plugins/datasource/jaeger/components/SearchForm.tsx b/public/app/plugins/datasource/jaeger/components/SearchForm.tsx index c362314bbed..22d563ad651 100644 --- a/public/app/plugins/datasource/jaeger/components/SearchForm.tsx +++ b/public/app/plugins/datasource/jaeger/components/SearchForm.tsx @@ -1,14 +1,17 @@ import { css } from '@emotion/css'; +import React, { useCallback, useEffect, useState } from 'react'; + import { SelectableValue } from '@grafana/data'; import { AsyncSelect, InlineField, InlineFieldRow, Input } from '@grafana/ui'; -import React, { useCallback, useEffect, useState } from 'react'; +import { notifyApp } from 'app/core/actions'; +import { createErrorNotification } from 'app/core/copy/appNotification'; +import { dispatch } from 'app/store/store'; + import { JaegerDatasource } from '../datasource'; import { JaegerQuery } from '../types'; import { transformToLogfmt } from '../util'; + import { AdvancedOptions } from './AdvancedOptions'; -import { dispatch } from 'app/store/store'; -import { notifyApp } from 'app/core/actions'; -import { createErrorNotification } from 'app/core/copy/appNotification'; type Props = { datasource: JaegerDatasource; diff --git a/public/app/plugins/datasource/jaeger/datasource.test.ts b/public/app/plugins/datasource/jaeger/datasource.test.ts index 6d7284f635c..f9af99e4de5 100644 --- a/public/app/plugins/datasource/jaeger/datasource.test.ts +++ b/public/app/plugins/datasource/jaeger/datasource.test.ts @@ -1,4 +1,6 @@ import { lastValueFrom, of, throwError } from 'rxjs'; +import { createFetchResponse } from 'test/helpers/createFetchResponse'; + import { DataQueryRequest, DataSourceInstanceSettings, @@ -7,9 +9,8 @@ import { PluginType, ScopedVars, } from '@grafana/data'; - import { backendSrv } from 'app/core/services/backend_srv'; -import { createFetchResponse } from 'test/helpers/createFetchResponse'; + import { ALL_OPERATIONS_KEY } from './components/SearchForm'; import { JaegerDatasource, JaegerJsonData } from './datasource'; import mockJson from './mockJsonResponse.json'; diff --git a/public/app/plugins/datasource/jaeger/datasource.ts b/public/app/plugins/datasource/jaeger/datasource.ts index 83581fcc816..d042b271f23 100644 --- a/public/app/plugins/datasource/jaeger/datasource.ts +++ b/public/app/plugins/datasource/jaeger/datasource.ts @@ -1,6 +1,7 @@ import { identity, omit, pick, pickBy } from 'lodash'; import { lastValueFrom, Observable, of } from 'rxjs'; import { catchError, map } from 'rxjs/operators'; + import { DataQueryRequest, DataQueryResponse, @@ -13,15 +14,15 @@ import { MutableDataFrame, } from '@grafana/data'; import { BackendSrvRequest, getBackendSrv, getTemplateSrv } from '@grafana/runtime'; - +import { NodeGraphOptions } from 'app/core/components/NodeGraphSettings'; import { serializeParams } from 'app/core/utils/fetch'; import { getTimeSrv, TimeSrv } from 'app/features/dashboard/services/TimeSrv'; -import { createTableFrame, createTraceFrame } from './responseTransform'; + +import { ALL_OPERATIONS_KEY } from './components/SearchForm'; import { createGraphFrames } from './graphTransform'; +import { createTableFrame, createTraceFrame } from './responseTransform'; import { JaegerQuery } from './types'; import { convertTagsLogfmt } from './util'; -import { ALL_OPERATIONS_KEY } from './components/SearchForm'; -import { NodeGraphOptions } from 'app/core/components/NodeGraphSettings'; export interface JaegerJsonData extends DataSourceJsonData { nodeGraph?: NodeGraphOptions; diff --git a/public/app/plugins/datasource/jaeger/graphTransform.ts b/public/app/plugins/datasource/jaeger/graphTransform.ts index ae866449687..357b36774ba 100644 --- a/public/app/plugins/datasource/jaeger/graphTransform.ts +++ b/public/app/plugins/datasource/jaeger/graphTransform.ts @@ -1,7 +1,9 @@ import { DataFrame, NodeGraphDataFrameFieldNames as Fields } from '@grafana/data'; -import { Span, TraceResponse } from './types'; + import { getNonOverlappingDuration, getStats, makeFrames, makeSpanMap } from '../../../core/utils/tracing'; +import { Span, TraceResponse } from './types'; + interface Node { [Fields.id]: string; [Fields.title]: string; diff --git a/public/app/plugins/datasource/jaeger/module.ts b/public/app/plugins/datasource/jaeger/module.ts index d81c4807cc4..07dca616b63 100644 --- a/public/app/plugins/datasource/jaeger/module.ts +++ b/public/app/plugins/datasource/jaeger/module.ts @@ -1,6 +1,7 @@ import { DataSourcePlugin } from '@grafana/data'; -import { JaegerDatasource } from './datasource'; -import { QueryEditor } from './components/QueryEditor'; + import { ConfigEditor } from './components/ConfigEditor'; +import { QueryEditor } from './components/QueryEditor'; +import { JaegerDatasource } from './datasource'; export const plugin = new DataSourcePlugin(JaegerDatasource).setConfigEditor(ConfigEditor).setQueryEditor(QueryEditor); diff --git a/public/app/plugins/datasource/jaeger/responseTransform.test.ts b/public/app/plugins/datasource/jaeger/responseTransform.test.ts index b24d01f7a3b..24cab644e37 100644 --- a/public/app/plugins/datasource/jaeger/responseTransform.test.ts +++ b/public/app/plugins/datasource/jaeger/responseTransform.test.ts @@ -1,6 +1,7 @@ +import { MutableDataFrame } from '@grafana/data'; + import { createTraceFrame, transformToJaeger } from './responseTransform'; import { testResponse, testResponseDataFrameFields } from './testResponse'; -import { MutableDataFrame } from '@grafana/data'; describe('createTraceFrame', () => { it('creates data frame from jaeger response', () => { diff --git a/public/app/plugins/datasource/jaeger/responseTransform.ts b/public/app/plugins/datasource/jaeger/responseTransform.ts index f15763f1ec6..4e6e8683aa7 100644 --- a/public/app/plugins/datasource/jaeger/responseTransform.ts +++ b/public/app/plugins/datasource/jaeger/responseTransform.ts @@ -7,6 +7,7 @@ import { TraceSpanRow, } from '@grafana/data'; import { transformTraceData } from '@jaegertracing/jaeger-ui-components'; + import { JaegerResponse, Span, TraceProcess, TraceResponse } from './types'; export function createTraceFrame(data: TraceResponse): DataFrame { diff --git a/public/app/plugins/datasource/jaeger/testResponse.ts b/public/app/plugins/datasource/jaeger/testResponse.ts index e9627249eae..026de7cbc44 100644 --- a/public/app/plugins/datasource/jaeger/testResponse.ts +++ b/public/app/plugins/datasource/jaeger/testResponse.ts @@ -1,6 +1,7 @@ -import { TraceResponse } from './types'; import { ArrayVector, FieldDTO } from '@grafana/data'; +import { TraceResponse } from './types'; + export const testResponse: TraceResponse = { traceID: '3fa414edcef6ad90', spans: [ diff --git a/public/app/plugins/datasource/loki/add_label_to_query.ts b/public/app/plugins/datasource/loki/add_label_to_query.ts index 5d345703438..d4e6c1a62bd 100644 --- a/public/app/plugins/datasource/loki/add_label_to_query.ts +++ b/public/app/plugins/datasource/loki/add_label_to_query.ts @@ -1,7 +1,9 @@ import { chain, isEqual } from 'lodash'; -import { LOKI_KEYWORDS } from './syntax'; + import { PROM_KEYWORDS, OPERATORS, LOGICAL_OPERATORS } from 'app/plugins/datasource/prometheus/promql'; +import { LOKI_KEYWORDS } from './syntax'; + const builtInWords = [...PROM_KEYWORDS, ...OPERATORS, ...LOGICAL_OPERATORS, ...LOKI_KEYWORDS]; // We want to extract all possible metrics and also keywords diff --git a/public/app/plugins/datasource/loki/backendResultTransformer.test.ts b/public/app/plugins/datasource/loki/backendResultTransformer.test.ts index f4fb69f3db4..ec4ab229322 100644 --- a/public/app/plugins/datasource/loki/backendResultTransformer.test.ts +++ b/public/app/plugins/datasource/loki/backendResultTransformer.test.ts @@ -1,6 +1,7 @@ -import { ArrayVector, DataFrame, DataQueryResponse, FieldType } from '@grafana/data'; import { cloneDeep } from 'lodash'; +import { ArrayVector, DataFrame, DataQueryResponse, FieldType } from '@grafana/data'; + import { transformBackendResult } from './backendResultTransformer'; const LOKI_EXPR = '{level="info"} |= "thing1"'; diff --git a/public/app/plugins/datasource/loki/backendResultTransformer.ts b/public/app/plugins/datasource/loki/backendResultTransformer.ts index ba4a6b3ebf0..2422359c74e 100644 --- a/public/app/plugins/datasource/loki/backendResultTransformer.ts +++ b/public/app/plugins/datasource/loki/backendResultTransformer.ts @@ -7,9 +7,10 @@ import { ArrayVector, Labels, } from '@grafana/data'; -import { LokiQuery, LokiQueryType } from './types'; + import { makeTableFrames } from './makeTableFrames'; import { formatQuery, getHighlighterExpressionsFromQuery } from './query_utils'; +import { LokiQuery, LokiQueryType } from './types'; function isMetricFrame(frame: DataFrame): boolean { return frame.fields.every((field) => field.type === FieldType.time || field.type === FieldType.number); diff --git a/public/app/plugins/datasource/loki/components/AnnotationsQueryEditor.tsx b/public/app/plugins/datasource/loki/components/AnnotationsQueryEditor.tsx index 5883726011c..babf897af12 100644 --- a/public/app/plugins/datasource/loki/components/AnnotationsQueryEditor.tsx +++ b/public/app/plugins/datasource/loki/components/AnnotationsQueryEditor.tsx @@ -1,10 +1,12 @@ // Libraries import React, { memo } from 'react'; + // Types -import { LokiQuery } from '../types'; -import { LokiQueryField } from './LokiQueryField'; -import { LokiOptionFields } from './LokiOptionFields'; import { LokiDatasource } from '../datasource'; +import { LokiQuery } from '../types'; + +import { LokiOptionFields } from './LokiOptionFields'; +import { LokiQueryField } from './LokiQueryField'; interface Props { expr: string; diff --git a/public/app/plugins/datasource/loki/components/LokiCheatSheet.tsx b/public/app/plugins/datasource/loki/components/LokiCheatSheet.tsx index 924f12b52e9..cead9587a9c 100644 --- a/public/app/plugins/datasource/loki/components/LokiCheatSheet.tsx +++ b/public/app/plugins/datasource/loki/components/LokiCheatSheet.tsx @@ -1,6 +1,8 @@ -import React, { PureComponent } from 'react'; import { shuffle } from 'lodash'; +import React, { PureComponent } from 'react'; + import { QueryEditorHelpProps } from '@grafana/data'; + import LokiLanguageProvider from '../language_provider'; import { LokiQuery } from '../types'; diff --git a/public/app/plugins/datasource/loki/components/LokiExploreQueryEditor.test.tsx b/public/app/plugins/datasource/loki/components/LokiExploreQueryEditor.test.tsx index c8fbc9e6fdb..d2ee8a6c956 100644 --- a/public/app/plugins/datasource/loki/components/LokiExploreQueryEditor.test.tsx +++ b/public/app/plugins/datasource/loki/components/LokiExploreQueryEditor.test.tsx @@ -1,13 +1,16 @@ -import React from 'react'; import { mount, shallow } from 'enzyme'; +import React from 'react'; import { act } from 'react-dom/test-utils'; + +import { ExploreMode, LoadingState, PanelData, toUtc, TimeRange } from '@grafana/data'; + +import { LokiDatasource } from '../datasource'; +import LokiLanguageProvider from '../language_provider'; +import { makeMockLokiDatasource } from '../mocks'; +import { LokiQuery } from '../types'; + import { LokiExploreQueryEditor } from './LokiExploreQueryEditor'; import { LokiOptionFields } from './LokiOptionFields'; -import { LokiDatasource } from '../datasource'; -import { LokiQuery } from '../types'; -import { ExploreMode, LoadingState, PanelData, toUtc, TimeRange } from '@grafana/data'; -import { makeMockLokiDatasource } from '../mocks'; -import LokiLanguageProvider from '../language_provider'; const setup = (renderMethod: any, propOverrides?: object) => { const datasource: LokiDatasource = makeMockLokiDatasource({}); diff --git a/public/app/plugins/datasource/loki/components/LokiExploreQueryEditor.tsx b/public/app/plugins/datasource/loki/components/LokiExploreQueryEditor.tsx index c78ef98047d..6fcfde57716 100644 --- a/public/app/plugins/datasource/loki/components/LokiExploreQueryEditor.tsx +++ b/public/app/plugins/datasource/loki/components/LokiExploreQueryEditor.tsx @@ -3,10 +3,12 @@ import React, { memo } from 'react'; // Types import { QueryEditorProps } from '@grafana/data'; + import { LokiDatasource } from '../datasource'; import { LokiQuery, LokiOptions } from '../types'; -import { LokiQueryField } from './LokiQueryField'; + import { LokiOptionFields } from './LokiOptionFields'; +import { LokiQueryField } from './LokiQueryField'; type Props = QueryEditorProps; diff --git a/public/app/plugins/datasource/loki/components/LokiLabelBrowser.test.tsx b/public/app/plugins/datasource/loki/components/LokiLabelBrowser.test.tsx index 4f5468438f7..06f745f7482 100644 --- a/public/app/plugins/datasource/loki/components/LokiLabelBrowser.test.tsx +++ b/public/app/plugins/datasource/loki/components/LokiLabelBrowser.test.tsx @@ -1,8 +1,11 @@ -import React from 'react'; import { render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import React from 'react'; import { createTheme } from '@grafana/data'; + +import LokiLanguageProvider from '../language_provider'; + import { buildSelector, facetLabels, @@ -10,7 +13,6 @@ import { UnthemedLokiLabelBrowser, BrowserProps, } from './LokiLabelBrowser'; -import LokiLanguageProvider from '../language_provider'; describe('buildSelector()', () => { it('returns an empty selector for no labels', () => { diff --git a/public/app/plugins/datasource/loki/components/LokiLabelBrowser.tsx b/public/app/plugins/datasource/loki/components/LokiLabelBrowser.tsx index ca5f45dfeaf..d5ff9246194 100644 --- a/public/app/plugins/datasource/loki/components/LokiLabelBrowser.tsx +++ b/public/app/plugins/datasource/loki/components/LokiLabelBrowser.tsx @@ -1,4 +1,9 @@ +import { css, cx } from '@emotion/css'; +import { sortBy } from 'lodash'; import React, { ChangeEvent } from 'react'; +import { FixedSizeList } from 'react-window'; + +import { GrafanaTheme2 } from '@grafana/data'; import { Button, HighlightPart, @@ -10,12 +15,9 @@ import { BrowserLabel as LokiLabel, fuzzyMatch, } from '@grafana/ui'; -import LokiLanguageProvider from '../language_provider'; + import PromQlLanguageProvider from '../../prometheus/language_provider'; -import { css, cx } from '@emotion/css'; -import { FixedSizeList } from 'react-window'; -import { GrafanaTheme2 } from '@grafana/data'; -import { sortBy } from 'lodash'; +import LokiLanguageProvider from '../language_provider'; // Hard limit on labels to render const MAX_LABEL_COUNT = 1000; diff --git a/public/app/plugins/datasource/loki/components/LokiOptionFields.test.tsx b/public/app/plugins/datasource/loki/components/LokiOptionFields.test.tsx index c91d0546c89..89e51d201cd 100644 --- a/public/app/plugins/datasource/loki/components/LokiOptionFields.test.tsx +++ b/public/app/plugins/datasource/loki/components/LokiOptionFields.test.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; +import React from 'react'; + import { LokiOptionFieldsProps, LokiOptionFields } from './LokiOptionFields'; const setup = (propOverrides?: LokiOptionFieldsProps) => { diff --git a/public/app/plugins/datasource/loki/components/LokiOptionFields.tsx b/public/app/plugins/datasource/loki/components/LokiOptionFields.tsx index a997c94760b..d0bab159be0 100644 --- a/public/app/plugins/datasource/loki/components/LokiOptionFields.tsx +++ b/public/app/plugins/datasource/loki/components/LokiOptionFields.tsx @@ -1,12 +1,13 @@ // Libraries -import React, { memo } from 'react'; import { css, cx } from '@emotion/css'; import { map } from 'lodash'; +import React, { memo } from 'react'; // Types -import { InlineFormLabel, RadioButtonGroup, InlineField, Input, Select } from '@grafana/ui'; import { SelectableValue } from '@grafana/data'; import { config } from '@grafana/runtime'; +import { InlineFormLabel, RadioButtonGroup, InlineField, Input, Select } from '@grafana/ui'; + import { LokiQuery, LokiQueryType } from '../types'; export interface LokiOptionFieldsProps { diff --git a/public/app/plugins/datasource/loki/components/LokiQueryEditor.test.tsx b/public/app/plugins/datasource/loki/components/LokiQueryEditor.test.tsx index 53485f9db95..b1d5caa1188 100644 --- a/public/app/plugins/datasource/loki/components/LokiQueryEditor.test.tsx +++ b/public/app/plugins/datasource/loki/components/LokiQueryEditor.test.tsx @@ -1,11 +1,13 @@ -import React from 'react'; import { shallow } from 'enzyme'; +import React from 'react'; + import { toUtc } from '@grafana/data'; -import { LokiQueryEditor } from './LokiQueryEditor'; import { LokiDatasource } from '../datasource'; import { LokiQuery } from '../types'; +import { LokiQueryEditor } from './LokiQueryEditor'; + const createMockRequestRange = (from: string, to: string) => { return { from: toUtc(from, 'YYYY-MM-DD'), diff --git a/public/app/plugins/datasource/loki/components/LokiQueryEditor.tsx b/public/app/plugins/datasource/loki/components/LokiQueryEditor.tsx index 5aa42a64dcb..3e2aff5db27 100644 --- a/public/app/plugins/datasource/loki/components/LokiQueryEditor.tsx +++ b/public/app/plugins/datasource/loki/components/LokiQueryEditor.tsx @@ -3,8 +3,9 @@ import React from 'react'; // Types import { InlineFormLabel } from '@grafana/ui'; -import { LokiQueryField } from './LokiQueryField'; + import { LokiOptionFields } from './LokiOptionFields'; +import { LokiQueryField } from './LokiQueryField'; import { LokiQueryEditorProps } from './types'; export function LokiQueryEditor(props: LokiQueryEditorProps) { diff --git a/public/app/plugins/datasource/loki/components/LokiQueryEditorByApp.test.tsx b/public/app/plugins/datasource/loki/components/LokiQueryEditorByApp.test.tsx index 65e2bdd558e..e52790a9817 100644 --- a/public/app/plugins/datasource/loki/components/LokiQueryEditorByApp.test.tsx +++ b/public/app/plugins/datasource/loki/components/LokiQueryEditorByApp.test.tsx @@ -1,12 +1,15 @@ -import React from 'react'; import { render, RenderResult } from '@testing-library/react'; -import { CoreApp } from '@grafana/data'; import { noop } from 'lodash'; +import React from 'react'; + +import { CoreApp } from '@grafana/data'; + import { LokiDatasource } from '../datasource'; -import { testIds as alertingTestIds } from './LokiQueryEditorForAlerting'; -import { testIds as regularTestIds } from './LokiQueryEditor'; + import { testIds as exploreTestIds } from './LokiExploreQueryEditor'; +import { testIds as regularTestIds } from './LokiQueryEditor'; import { LokiQueryEditorByApp } from './LokiQueryEditorByApp'; +import { testIds as alertingTestIds } from './LokiQueryEditorForAlerting'; function setup(app: CoreApp): RenderResult { const dataSource = { diff --git a/public/app/plugins/datasource/loki/components/LokiQueryEditorByApp.tsx b/public/app/plugins/datasource/loki/components/LokiQueryEditorByApp.tsx index e49db26d3e1..bd3b6c91654 100644 --- a/public/app/plugins/datasource/loki/components/LokiQueryEditorByApp.tsx +++ b/public/app/plugins/datasource/loki/components/LokiQueryEditorByApp.tsx @@ -1,11 +1,14 @@ import React, { memo } from 'react'; + import { CoreApp } from '@grafana/data'; -import { LokiQueryEditorProps } from './types'; +import { config } from '@grafana/runtime'; + +import { LokiQueryEditorSelector } from '../querybuilder/components/LokiQueryEditorSelector'; + +import { LokiExploreQueryEditor } from './LokiExploreQueryEditor'; import { LokiQueryEditor } from './LokiQueryEditor'; import { LokiQueryEditorForAlerting } from './LokiQueryEditorForAlerting'; -import { LokiExploreQueryEditor } from './LokiExploreQueryEditor'; -import { LokiQueryEditorSelector } from '../querybuilder/components/LokiQueryEditorSelector'; -import { config } from '@grafana/runtime'; +import { LokiQueryEditorProps } from './types'; export function LokiQueryEditorByApp(props: LokiQueryEditorProps) { const { app } = props; diff --git a/public/app/plugins/datasource/loki/components/LokiQueryEditorForAlerting.tsx b/public/app/plugins/datasource/loki/components/LokiQueryEditorForAlerting.tsx index c7878af05a3..a7a77698071 100644 --- a/public/app/plugins/datasource/loki/components/LokiQueryEditorForAlerting.tsx +++ b/public/app/plugins/datasource/loki/components/LokiQueryEditorForAlerting.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { LokiQueryField } from './LokiQueryField'; import { LokiQueryEditorProps } from './types'; diff --git a/public/app/plugins/datasource/loki/components/LokiQueryField.test.tsx b/public/app/plugins/datasource/loki/components/LokiQueryField.test.tsx index 19be0fbaec1..61abf95b8e1 100644 --- a/public/app/plugins/datasource/loki/components/LokiQueryField.test.tsx +++ b/public/app/plugins/datasource/loki/components/LokiQueryField.test.tsx @@ -1,8 +1,10 @@ -import React, { ComponentProps } from 'react'; import { render } from '@testing-library/react'; -import { LokiQueryField } from './LokiQueryField'; +import React, { ComponentProps } from 'react'; + import { dateTime } from '@grafana/data'; +import { LokiQueryField } from './LokiQueryField'; + type Props = ComponentProps; const defaultProps: Props = { diff --git a/public/app/plugins/datasource/loki/components/LokiQueryField.tsx b/public/app/plugins/datasource/loki/components/LokiQueryField.tsx index 6e139928c6b..1be894153a0 100644 --- a/public/app/plugins/datasource/loki/components/LokiQueryField.tsx +++ b/public/app/plugins/datasource/loki/components/LokiQueryField.tsx @@ -1,4 +1,8 @@ +import { LanguageMap, languages as prismLanguages } from 'prismjs'; import React, { ReactNode } from 'react'; +import { Plugin, Node } from 'slate'; + +import { QueryEditorProps } from '@grafana/data'; import { SlatePrism, TypeaheadOutput, @@ -9,15 +13,14 @@ import { DOMUtil, Icon, } from '@grafana/ui'; -import { Plugin, Node } from 'slate'; -import { LokiLabelBrowser } from './LokiLabelBrowser'; -import { QueryEditorProps } from '@grafana/data'; -import { LokiQuery, LokiOptions } from '../types'; -import { LanguageMap, languages as prismLanguages } from 'prismjs'; +import { LocalStorageValueProvider } from 'app/core/components/LocalStorageValueProvider'; + +import { LokiDatasource } from '../datasource'; import LokiLanguageProvider from '../language_provider'; import { shouldRefreshLabels } from '../language_utils'; -import { LokiDatasource } from '../datasource'; -import { LocalStorageValueProvider } from 'app/core/components/LocalStorageValueProvider'; +import { LokiQuery, LokiOptions } from '../types'; + +import { LokiLabelBrowser } from './LokiLabelBrowser'; const LAST_USED_LABELS_KEY = 'grafana.datasources.loki.browser.labels'; diff --git a/public/app/plugins/datasource/loki/components/types.ts b/public/app/plugins/datasource/loki/components/types.ts index 95a671428f5..afea710b1b9 100644 --- a/public/app/plugins/datasource/loki/components/types.ts +++ b/public/app/plugins/datasource/loki/components/types.ts @@ -1,4 +1,5 @@ import { QueryEditorProps } from '@grafana/data'; + import { LokiDatasource } from '../datasource'; import { LokiOptions, LokiQuery } from '../types'; diff --git a/public/app/plugins/datasource/loki/configuration/ConfigEditor.test.tsx b/public/app/plugins/datasource/loki/configuration/ConfigEditor.test.tsx index 39f2a3bcf07..5aa387d9555 100644 --- a/public/app/plugins/datasource/loki/configuration/ConfigEditor.test.tsx +++ b/public/app/plugins/datasource/loki/configuration/ConfigEditor.test.tsx @@ -1,8 +1,11 @@ -import React from 'react'; import { mount } from 'enzyme'; -import { ConfigEditor } from './ConfigEditor'; -import { createDefaultConfigOptions } from '../mocks'; +import React from 'react'; + import { DataSourceHttpSettings } from '@grafana/ui'; + +import { createDefaultConfigOptions } from '../mocks'; + +import { ConfigEditor } from './ConfigEditor'; import { DerivedFields } from './DerivedFields'; describe('ConfigEditor', () => { diff --git a/public/app/plugins/datasource/loki/configuration/ConfigEditor.tsx b/public/app/plugins/datasource/loki/configuration/ConfigEditor.tsx index 82d841b4540..f2d58e33821 100644 --- a/public/app/plugins/datasource/loki/configuration/ConfigEditor.tsx +++ b/public/app/plugins/datasource/loki/configuration/ConfigEditor.tsx @@ -1,11 +1,14 @@ import React from 'react'; + import { DataSourcePluginOptionsEditorProps, DataSourceSettings } from '@grafana/data'; import { AlertingSettings, DataSourceHttpSettings } from '@grafana/ui'; -import { LokiOptions } from '../types'; -import { MaxLinesField } from './MaxLinesField'; -import { DerivedFields } from './DerivedFields'; import { getAllAlertmanagerDataSources } from 'app/features/alerting/unified/utils/alertmanager'; +import { LokiOptions } from '../types'; + +import { DerivedFields } from './DerivedFields'; +import { MaxLinesField } from './MaxLinesField'; + export type Props = DataSourcePluginOptionsEditorProps; const makeJsonUpdater = diff --git a/public/app/plugins/datasource/loki/configuration/DebugSection.test.tsx b/public/app/plugins/datasource/loki/configuration/DebugSection.test.tsx index d1aaac6c77a..82d6b2064ea 100644 --- a/public/app/plugins/datasource/loki/configuration/DebugSection.test.tsx +++ b/public/app/plugins/datasource/loki/configuration/DebugSection.test.tsx @@ -1,11 +1,13 @@ -import React from 'react'; import { mount } from 'enzyme'; +import React from 'react'; + import { dateTime, TimeRange } from '@grafana/data'; import { setTemplateSrv } from '@grafana/runtime'; -import { DebugSection } from './DebugSection'; import { getLinkSrv, LinkService, LinkSrv, setLinkSrv } from '../../../../features/panel/panellinks/link_srv'; +import { DebugSection } from './DebugSection'; + // We do not need more here and TimeSrv is hard to setup fully. jest.mock('app/features/dashboard/services/TimeSrv', () => ({ getTimeSrv: () => ({ diff --git a/public/app/plugins/datasource/loki/configuration/DebugSection.tsx b/public/app/plugins/datasource/loki/configuration/DebugSection.tsx index 580847b4f76..49f8c958e5e 100644 --- a/public/app/plugins/datasource/loki/configuration/DebugSection.tsx +++ b/public/app/plugins/datasource/loki/configuration/DebugSection.tsx @@ -1,11 +1,14 @@ -import React, { useState } from 'react'; import { css } from '@emotion/css'; import cx from 'classnames'; -import { LegacyForms } from '@grafana/ui'; -const { FormField } = LegacyForms; -import { DerivedFieldConfig } from '../types'; +import React, { useState } from 'react'; + import { ArrayVector, Field, FieldType, LinkModel } from '@grafana/data'; +import { LegacyForms } from '@grafana/ui'; + import { getFieldLinksForExplore } from '../../../../features/explore/utils/links'; +import { DerivedFieldConfig } from '../types'; + +const { FormField } = LegacyForms; type Props = { derivedFields?: DerivedFieldConfig[]; diff --git a/public/app/plugins/datasource/loki/configuration/DerivedField.test.tsx b/public/app/plugins/datasource/loki/configuration/DerivedField.test.tsx index cc65287af2b..8e63f6e7966 100644 --- a/public/app/plugins/datasource/loki/configuration/DerivedField.test.tsx +++ b/public/app/plugins/datasource/loki/configuration/DerivedField.test.tsx @@ -1,8 +1,10 @@ -import React from 'react'; import { shallow } from 'enzyme'; -import { DerivedField } from './DerivedField'; -import { DataSourcePicker } from '@grafana/runtime'; +import React from 'react'; + import { DataSourceInstanceSettings } from '@grafana/data'; +import { DataSourcePicker } from '@grafana/runtime'; + +import { DerivedField } from './DerivedField'; jest.mock('app/features/plugins/datasource_srv', () => ({ getDatasourceSrv() { diff --git a/public/app/plugins/datasource/loki/configuration/DerivedField.tsx b/public/app/plugins/datasource/loki/configuration/DerivedField.tsx index b09642036f4..34997247f3d 100644 --- a/public/app/plugins/datasource/loki/configuration/DerivedField.tsx +++ b/public/app/plugins/datasource/loki/configuration/DerivedField.tsx @@ -1,10 +1,12 @@ -import React, { useEffect, useState } from 'react'; import { css } from '@emotion/css'; -import { Button, DataLinkInput, stylesFactory, LegacyForms } from '@grafana/ui'; +import React, { useEffect, useState } from 'react'; +import { usePrevious } from 'react-use'; + import { VariableSuggestion } from '@grafana/data'; import { DataSourcePicker } from '@grafana/runtime'; +import { Button, DataLinkInput, stylesFactory, LegacyForms } from '@grafana/ui'; + import { DerivedFieldConfig } from '../types'; -import { usePrevious } from 'react-use'; const { Switch, FormField } = LegacyForms; diff --git a/public/app/plugins/datasource/loki/configuration/DerivedFields.test.tsx b/public/app/plugins/datasource/loki/configuration/DerivedFields.test.tsx index 1e0c3ac8482..aafaf7a2816 100644 --- a/public/app/plugins/datasource/loki/configuration/DerivedFields.test.tsx +++ b/public/app/plugins/datasource/loki/configuration/DerivedFields.test.tsx @@ -1,10 +1,12 @@ -import React from 'react'; import { mount } from 'enzyme'; -import { DerivedFields } from './DerivedFields'; -import { Button } from '@grafana/ui'; -import { DerivedField } from './DerivedField'; +import React from 'react'; import { act } from 'react-dom/test-utils'; +import { Button } from '@grafana/ui'; + +import { DerivedField } from './DerivedField'; +import { DerivedFields } from './DerivedFields'; + describe('DerivedFields', () => { let originalGetSelection: typeof window.getSelection; beforeAll(() => { diff --git a/public/app/plugins/datasource/loki/configuration/DerivedFields.tsx b/public/app/plugins/datasource/loki/configuration/DerivedFields.tsx index 4d2ffa00806..fd7ef7ff1b5 100644 --- a/public/app/plugins/datasource/loki/configuration/DerivedFields.tsx +++ b/public/app/plugins/datasource/loki/configuration/DerivedFields.tsx @@ -1,10 +1,13 @@ -import React, { useState } from 'react'; import { css } from '@emotion/css'; -import { Button, useTheme2 } from '@grafana/ui'; +import React, { useState } from 'react'; + import { GrafanaTheme2, VariableOrigin, DataLinkBuiltInVars } from '@grafana/data'; +import { Button, useTheme2 } from '@grafana/ui'; + import { DerivedFieldConfig } from '../types'; -import { DerivedField } from './DerivedField'; + import { DebugSection } from './DebugSection'; +import { DerivedField } from './DerivedField'; const getStyles = (theme: GrafanaTheme2) => ({ infoText: css` diff --git a/public/app/plugins/datasource/loki/configuration/MaxLinesField.tsx b/public/app/plugins/datasource/loki/configuration/MaxLinesField.tsx index 5d3ddddf844..424499a6083 100644 --- a/public/app/plugins/datasource/loki/configuration/MaxLinesField.tsx +++ b/public/app/plugins/datasource/loki/configuration/MaxLinesField.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { LegacyForms } from '@grafana/ui'; const { FormField } = LegacyForms; diff --git a/public/app/plugins/datasource/loki/datasource.test.ts b/public/app/plugins/datasource/loki/datasource.test.ts index 38ebf6cedfd..9bc7587cbfb 100644 --- a/public/app/plugins/datasource/loki/datasource.test.ts +++ b/public/app/plugins/datasource/loki/datasource.test.ts @@ -1,5 +1,8 @@ import { lastValueFrom, of, throwError } from 'rxjs'; import { take } from 'rxjs/operators'; +import { createFetchResponse } from 'test/helpers/createFetchResponse'; +import { getQueryOptions } from 'test/helpers/getQueryOptions'; + import { AbstractLabelOperator, AnnotationQueryRequest, @@ -13,16 +16,16 @@ import { toUtc, } from '@grafana/data'; import { BackendSrvRequest, FetchResponse } from '@grafana/runtime'; -import { isMetricsQuery, LokiDatasource, RangeQueryOptions } from './datasource'; -import { LokiQuery, LokiResponse, LokiResultType } from './types'; -import { getQueryOptions } from 'test/helpers/getQueryOptions'; -import { TemplateSrv } from 'app/features/templating/template_srv'; -import { TimeSrv } from 'app/features/dashboard/services/TimeSrv'; import { backendSrv } from 'app/core/services/backend_srv'; -import { CustomVariableModel } from '../../../features/variables/types'; +import { TimeSrv } from 'app/features/dashboard/services/TimeSrv'; +import { TemplateSrv } from 'app/features/templating/template_srv'; + import { initialCustomVariableModelState } from '../../../features/variables/custom/reducer'; +import { CustomVariableModel } from '../../../features/variables/types'; + +import { isMetricsQuery, LokiDatasource, RangeQueryOptions } from './datasource'; import { makeMockLokiDatasource } from './mocks'; -import { createFetchResponse } from 'test/helpers/createFetchResponse'; +import { LokiQuery, LokiResponse, LokiResultType } from './types'; jest.mock('@grafana/runtime', () => ({ // @ts-ignore diff --git a/public/app/plugins/datasource/loki/datasource.ts b/public/app/plugins/datasource/loki/datasource.ts index 96a2357254b..9897ae2cc15 100644 --- a/public/app/plugins/datasource/loki/datasource.ts +++ b/public/app/plugins/datasource/loki/datasource.ts @@ -1,8 +1,8 @@ // Libraries import { cloneDeep, isEmpty, map as lodashMap } from 'lodash'; +import Prism from 'prismjs'; import { lastValueFrom, merge, Observable, of, throwError } from 'rxjs'; import { catchError, map, switchMap } from 'rxjs/operators'; -import Prism from 'prismjs'; // Types import { @@ -36,14 +36,25 @@ import { toUtc, } from '@grafana/data'; import { BackendSrvRequest, FetchError, getBackendSrv, config, DataSourceWithBackend } from '@grafana/runtime'; -import { getTemplateSrv, TemplateSrv } from 'app/features/templating/template_srv'; -import { addLabelToQuery } from './add_label_to_query'; -import { getTimeSrv, TimeSrv } from 'app/features/dashboard/services/TimeSrv'; +import { RowContextOptions } from '@grafana/ui/src/components/Logs/LogRowContextProvider'; +import { queryLogsVolume } from 'app/core/logs_model'; import { convertToWebSocketUrl } from 'app/core/utils/explore'; -import { lokiResultsToTableModel, lokiStreamsToDataFrames, processRangeQueryResponse } from './result_transformer'; -import { transformBackendResult } from './backendResultTransformer'; -import { addParsedLabelToQuery, getNormalizedLokiQuery, queryHasPipeParser } from './query_utils'; +import { getTimeSrv, TimeSrv } from 'app/features/dashboard/services/TimeSrv'; +import { getTemplateSrv, TemplateSrv } from 'app/features/templating/template_srv'; +import { serializeParams } from '../../../core/utils/fetch'; +import { renderLegendFormat } from '../prometheus/legend'; + +import { addLabelToQuery } from './add_label_to_query'; +import { transformBackendResult } from './backendResultTransformer'; +import { DEFAULT_RESOLUTION } from './components/LokiOptionFields'; +import LanguageProvider from './language_provider'; +import { LiveStreams, LokiLiveTarget } from './live_streams'; +import { addParsedLabelToQuery, getNormalizedLokiQuery, queryHasPipeParser } from './query_utils'; +import { lokiResultsToTableModel, lokiStreamsToDataFrames, processRangeQueryResponse } from './result_transformer'; +import { sortDataFrameByTime } from './sortDataFrame'; +import { doLokiChannelStream } from './streaming'; +import syntax from './syntax'; import { LokiOptions, LokiQuery, @@ -53,16 +64,6 @@ import { LokiResultType, LokiStreamResponse, } from './types'; -import { LiveStreams, LokiLiveTarget } from './live_streams'; -import LanguageProvider from './language_provider'; -import { serializeParams } from '../../../core/utils/fetch'; -import { RowContextOptions } from '@grafana/ui/src/components/Logs/LogRowContextProvider'; -import syntax from './syntax'; -import { DEFAULT_RESOLUTION } from './components/LokiOptionFields'; -import { queryLogsVolume } from 'app/core/logs_model'; -import { doLokiChannelStream } from './streaming'; -import { renderLegendFormat } from '../prometheus/legend'; -import { sortDataFrameByTime } from './sortDataFrame'; export type RangeQueryOptions = DataQueryRequest | AnnotationQueryRequest; export const DEFAULT_MAX_LINES = 1000; diff --git a/public/app/plugins/datasource/loki/language_provider.test.ts b/public/app/plugins/datasource/loki/language_provider.test.ts index 70ad8daeb10..168d696855e 100644 --- a/public/app/plugins/datasource/loki/language_provider.test.ts +++ b/public/app/plugins/datasource/loki/language_provider.test.ts @@ -1,11 +1,11 @@ import Plain from 'slate-plain-serializer'; -import LanguageProvider, { LokiHistoryItem } from './language_provider'; +import { AbstractLabelOperator } from '@grafana/data'; import { TypeaheadInput } from '@grafana/ui'; -import { makeMockLokiDatasource } from './mocks'; import { LokiDatasource } from './datasource'; -import { AbstractLabelOperator } from '@grafana/data'; +import LanguageProvider, { LokiHistoryItem } from './language_provider'; +import { makeMockLokiDatasource } from './mocks'; import { LokiQueryType } from './types'; jest.mock('app/store/store', () => ({ diff --git a/public/app/plugins/datasource/loki/language_provider.ts b/public/app/plugins/datasource/loki/language_provider.ts index 1fd83b96c9d..330df0562a2 100644 --- a/public/app/plugins/datasource/loki/language_provider.ts +++ b/public/app/plugins/datasource/loki/language_provider.ts @@ -1,23 +1,19 @@ -// Libraries import { chain, difference } from 'lodash'; import LRU from 'lru-cache'; +import Prism, { Grammar } from 'prismjs'; -// Services & Utils +import { dateTime, AbsoluteTimeRange, LanguageProvider, HistoryItem, AbstractQuery } from '@grafana/data'; +import { CompletionItem, TypeaheadInput, TypeaheadOutput, CompletionItemGroup } from '@grafana/ui'; import { extractLabelMatchers, parseSelector, processLabels, toPromLikeExpr, } from 'app/plugins/datasource/prometheus/language_utils'; -import syntax, { FUNCTIONS, PIPE_PARSERS, PIPE_OPERATORS } from './syntax'; - -// Types -import { LokiQuery, LokiQueryType } from './types'; -import { dateTime, AbsoluteTimeRange, LanguageProvider, HistoryItem, AbstractQuery } from '@grafana/data'; import { LokiDatasource } from './datasource'; -import { CompletionItem, TypeaheadInput, TypeaheadOutput, CompletionItemGroup } from '@grafana/ui'; -import Prism, { Grammar } from 'prismjs'; +import syntax, { FUNCTIONS, PIPE_PARSERS, PIPE_OPERATORS } from './syntax'; +import { LokiQuery, LokiQueryType } from './types'; const DEFAULT_KEYS = ['job', 'namespace']; const EMPTY_SELECTOR = '{}'; diff --git a/public/app/plugins/datasource/loki/live_streams.test.ts b/public/app/plugins/datasource/loki/live_streams.test.ts index 810b229f3dd..8919e5d71fa 100644 --- a/public/app/plugins/datasource/loki/live_streams.test.ts +++ b/public/app/plugins/datasource/loki/live_streams.test.ts @@ -1,9 +1,11 @@ +import { noop } from 'lodash'; import { Observable, Subject, of, throwError, concat } from 'rxjs'; import { mergeMap } from 'rxjs/operators'; import * as rxJsWebSocket from 'rxjs/webSocket'; -import { LiveStreams } from './live_streams'; + import { DataFrame, DataFrameView, formatLabels, Labels } from '@grafana/data'; -import { noop } from 'lodash'; + +import { LiveStreams } from './live_streams'; import { LokiTailResponse } from './types'; let fakeSocket: Subject; diff --git a/public/app/plugins/datasource/loki/live_streams.ts b/public/app/plugins/datasource/loki/live_streams.ts index a2a68ec9fd6..82319bec041 100644 --- a/public/app/plugins/datasource/loki/live_streams.ts +++ b/public/app/plugins/datasource/loki/live_streams.ts @@ -1,9 +1,11 @@ -import { DataFrame, FieldType, parseLabels, KeyValue, CircularDataFrame } from '@grafana/data'; import { Observable, throwError, timer } from 'rxjs'; -import { webSocket } from 'rxjs/webSocket'; -import { LokiTailResponse } from './types'; import { finalize, map, retryWhen, mergeMap } from 'rxjs/operators'; +import { webSocket } from 'rxjs/webSocket'; + +import { DataFrame, FieldType, parseLabels, KeyValue, CircularDataFrame } from '@grafana/data'; + import { appendResponseToBufferedData } from './result_transformer'; +import { LokiTailResponse } from './types'; /** * Maps directly to a query in the UI (refId is key) diff --git a/public/app/plugins/datasource/loki/makeTableFrames.test.ts b/public/app/plugins/datasource/loki/makeTableFrames.test.ts index 2f33edf8792..2fbb072e24b 100644 --- a/public/app/plugins/datasource/loki/makeTableFrames.test.ts +++ b/public/app/plugins/datasource/loki/makeTableFrames.test.ts @@ -1,4 +1,5 @@ import { ArrayVector, DataFrame, FieldType } from '@grafana/data'; + import { makeTableFrames } from './makeTableFrames'; const frame1: DataFrame = { diff --git a/public/app/plugins/datasource/loki/makeTableFrames.ts b/public/app/plugins/datasource/loki/makeTableFrames.ts index ac0fd971cfa..5baf3721b41 100644 --- a/public/app/plugins/datasource/loki/makeTableFrames.ts +++ b/public/app/plugins/datasource/loki/makeTableFrames.ts @@ -1,6 +1,7 @@ -import { DataFrame, Field, FieldType, ArrayVector } from '@grafana/data'; import { groupBy } from 'lodash'; +import { DataFrame, Field, FieldType, ArrayVector } from '@grafana/data'; + export function makeTableFrames(instantMetricFrames: DataFrame[]): DataFrame[] { // first we remove frames that have no refId // (we will group them by refId, so we need it to be set) diff --git a/public/app/plugins/datasource/loki/mocks.ts b/public/app/plugins/datasource/loki/mocks.ts index 35d37f6e0ef..9d5e7b0ca44 100644 --- a/public/app/plugins/datasource/loki/mocks.ts +++ b/public/app/plugins/datasource/loki/mocks.ts @@ -1,8 +1,10 @@ -import { LokiDatasource, LOKI_ENDPOINT } from './datasource'; import { DataSourceSettings } from '@grafana/data'; -import { LokiOptions } from './types'; + import { createDatasourceSettings } from '../../../features/datasources/mocks'; +import { LokiDatasource, LOKI_ENDPOINT } from './datasource'; +import { LokiOptions } from './types'; + interface Labels { [label: string]: string[]; } diff --git a/public/app/plugins/datasource/loki/module.ts b/public/app/plugins/datasource/loki/module.ts index fe7b4beb67d..6880f9da640 100644 --- a/public/app/plugins/datasource/loki/module.ts +++ b/public/app/plugins/datasource/loki/module.ts @@ -1,10 +1,10 @@ import { DataSourcePlugin } from '@grafana/data'; -import { LokiDatasource } from './datasource'; +import { LokiAnnotationsQueryCtrl } from './LokiAnnotationsQueryCtrl'; import LokiCheatSheet from './components/LokiCheatSheet'; import LokiQueryEditorByApp from './components/LokiQueryEditorByApp'; -import { LokiAnnotationsQueryCtrl } from './LokiAnnotationsQueryCtrl'; import { ConfigEditor } from './configuration/ConfigEditor'; +import { LokiDatasource } from './datasource'; export const plugin = new DataSourcePlugin(LokiDatasource) .setQueryEditor(LokiQueryEditorByApp) diff --git a/public/app/plugins/datasource/loki/query_utils.test.ts b/public/app/plugins/datasource/loki/query_utils.test.ts index 4e087955488..43cb219f30d 100644 --- a/public/app/plugins/datasource/loki/query_utils.test.ts +++ b/public/app/plugins/datasource/loki/query_utils.test.ts @@ -1,5 +1,5 @@ -import { LokiQuery, LokiQueryType } from './types'; import { getHighlighterExpressionsFromQuery, getNormalizedLokiQuery } from './query_utils'; +import { LokiQuery, LokiQueryType } from './types'; describe('getHighlighterExpressionsFromQuery', () => { it('returns no expressions for empty query', () => { diff --git a/public/app/plugins/datasource/loki/query_utils.ts b/public/app/plugins/datasource/loki/query_utils.ts index f4432345045..1f9ede7022f 100644 --- a/public/app/plugins/datasource/loki/query_utils.ts +++ b/public/app/plugins/datasource/loki/query_utils.ts @@ -1,4 +1,5 @@ import { escapeRegExp } from 'lodash'; + import { PIPE_PARSERS } from './syntax'; import { LokiQuery, LokiQueryType } from './types'; diff --git a/public/app/plugins/datasource/loki/querybuilder/LokiQueryModeller.ts b/public/app/plugins/datasource/loki/querybuilder/LokiQueryModeller.ts index 1139e312a9a..34f76b74a77 100644 --- a/public/app/plugins/datasource/loki/querybuilder/LokiQueryModeller.ts +++ b/public/app/plugins/datasource/loki/querybuilder/LokiQueryModeller.ts @@ -1,5 +1,6 @@ import { LokiAndPromQueryModellerBase } from '../../prometheus/querybuilder/shared/LokiAndPromQueryModellerBase'; import { QueryBuilderLabelFilter } from '../../prometheus/querybuilder/shared/types'; + import { getOperationDefinitions } from './operations'; import { LokiOperationId, LokiQueryPattern, LokiVisualQueryOperationCategory } from './types'; diff --git a/public/app/plugins/datasource/loki/querybuilder/binaryScalarOperations.ts b/public/app/plugins/datasource/loki/querybuilder/binaryScalarOperations.ts index cb2b7f1ea9a..a5759ff3060 100644 --- a/public/app/plugins/datasource/loki/querybuilder/binaryScalarOperations.ts +++ b/public/app/plugins/datasource/loki/querybuilder/binaryScalarOperations.ts @@ -4,6 +4,7 @@ import { QueryBuilderOperationDef, QueryBuilderOperationParamDef, } from '../../prometheus/querybuilder/shared/types'; + import { LokiOperationId, LokiVisualQueryOperationCategory } from './types'; export const binaryScalarDefs = [ diff --git a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.test.tsx b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.test.tsx index 6d9177d979d..293d3852e73 100644 --- a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.test.tsx +++ b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.test.tsx @@ -1,10 +1,13 @@ -import React from 'react'; import { render, screen, getAllByRole, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { LokiQueryBuilder } from './LokiQueryBuilder'; +import React from 'react'; + +import { PanelData } from '@grafana/data'; + import { LokiDatasource } from '../../datasource'; import { LokiOperationId, LokiVisualQuery } from '../types'; -import { PanelData } from '@grafana/data'; + +import { LokiQueryBuilder } from './LokiQueryBuilder'; const defaultQuery: LokiVisualQuery = { labels: [{ op: '=', label: 'baz', value: 'bar' }], diff --git a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.tsx b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.tsx index 01f000e0e29..4ea05365853 100644 --- a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.tsx +++ b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.tsx @@ -1,13 +1,16 @@ import React, { useMemo } from 'react'; -import { LokiOperationId, LokiVisualQuery } from '../types'; -import { LokiDatasource } from '../../datasource'; -import { LabelFilters } from 'app/plugins/datasource/prometheus/querybuilder/shared/LabelFilters'; -import { OperationList } from 'app/plugins/datasource/prometheus/querybuilder/shared/OperationList'; -import { QueryBuilderLabelFilter } from 'app/plugins/datasource/prometheus/querybuilder/shared/types'; -import { lokiQueryModeller } from '../LokiQueryModeller'; + import { DataSourceApi, SelectableValue } from '@grafana/data'; import { EditorRow } from '@grafana/experimental'; +import { LabelFilters } from 'app/plugins/datasource/prometheus/querybuilder/shared/LabelFilters'; +import { OperationList } from 'app/plugins/datasource/prometheus/querybuilder/shared/OperationList'; import { OperationsEditorRow } from 'app/plugins/datasource/prometheus/querybuilder/shared/OperationsEditorRow'; +import { QueryBuilderLabelFilter } from 'app/plugins/datasource/prometheus/querybuilder/shared/types'; + +import { LokiDatasource } from '../../datasource'; +import { lokiQueryModeller } from '../LokiQueryModeller'; +import { LokiOperationId, LokiVisualQuery } from '../types'; + import { NestedQueryList } from './NestedQueryList'; export interface Props { diff --git a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderContainer.test.tsx b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderContainer.test.tsx index 599e88674a1..170939451b6 100644 --- a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderContainer.test.tsx +++ b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderContainer.test.tsx @@ -1,9 +1,12 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; -import { LokiQueryBuilderContainer } from './LokiQueryBuilderContainer'; -import { LokiDatasource } from '../../datasource'; +import React from 'react'; + import { addOperation } from 'app/plugins/datasource/prometheus/querybuilder/shared/OperationList.testUtils'; +import { LokiDatasource } from '../../datasource'; + +import { LokiQueryBuilderContainer } from './LokiQueryBuilderContainer'; + describe('LokiQueryBuilderContainer', () => { it('translates query between string and model', async () => { const props = { diff --git a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderContainer.tsx b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderContainer.tsx index 32390a99fa3..3e20f62bcf3 100644 --- a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderContainer.tsx +++ b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderContainer.tsx @@ -1,12 +1,14 @@ +import { createSlice, PayloadAction } from '@reduxjs/toolkit'; import React, { useEffect, useReducer } from 'react'; + import { LokiDatasource } from '../../datasource'; import { LokiQuery } from '../../types'; -import { buildVisualQueryFromString } from '../parsing'; import { lokiQueryModeller } from '../LokiQueryModeller'; +import { buildVisualQueryFromString } from '../parsing'; +import { LokiVisualQuery } from '../types'; + import { LokiQueryBuilder } from './LokiQueryBuilder'; import { QueryPreview } from './QueryPreview'; -import { LokiVisualQuery } from '../types'; -import { createSlice, PayloadAction } from '@reduxjs/toolkit'; export interface Props { query: LokiQuery; diff --git a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderExplained.tsx b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderExplained.tsx index 9b53334a453..257ff64722c 100644 --- a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderExplained.tsx +++ b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderExplained.tsx @@ -1,10 +1,12 @@ import React from 'react'; -import { LokiVisualQuery } from '../types'; + import { Stack } from '@grafana/experimental'; -import { lokiQueryModeller } from '../LokiQueryModeller'; -import { OperationListExplained } from 'app/plugins/datasource/prometheus/querybuilder/shared/OperationListExplained'; import { OperationExplainedBox } from 'app/plugins/datasource/prometheus/querybuilder/shared/OperationExplainedBox'; +import { OperationListExplained } from 'app/plugins/datasource/prometheus/querybuilder/shared/OperationListExplained'; + +import { lokiQueryModeller } from '../LokiQueryModeller'; import { buildVisualQueryFromString } from '../parsing'; +import { LokiVisualQuery } from '../types'; export interface Props { query: string; diff --git a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderOptions.test.tsx b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderOptions.test.tsx index 4690fb6e3eb..511bc2d7374 100644 --- a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderOptions.test.tsx +++ b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderOptions.test.tsx @@ -1,8 +1,10 @@ -import React from 'react'; import { fireEvent, render, screen } from '@testing-library/react'; -import { LokiQuery, LokiQueryType } from '../../types'; -import { LokiQueryBuilderOptions } from './LokiQueryBuilderOptions'; import userEvent from '@testing-library/user-event'; +import React from 'react'; + +import { LokiQuery, LokiQueryType } from '../../types'; + +import { LokiQueryBuilderOptions } from './LokiQueryBuilderOptions'; describe('LokiQueryBuilderOptions', () => { it('Can change query type', async () => { diff --git a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderOptions.tsx b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderOptions.tsx index 92b1501f740..209c2e725fe 100644 --- a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderOptions.tsx +++ b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderOptions.tsx @@ -1,12 +1,14 @@ import React from 'react'; -import { EditorRow, EditorField } from '@grafana/experimental'; + import { SelectableValue } from '@grafana/data'; +import { EditorRow, EditorField } from '@grafana/experimental'; import { RadioButtonGroup, Select } from '@grafana/ui'; -import { LokiQuery, LokiQueryType } from '../../types'; -import { QueryOptionGroup } from 'app/plugins/datasource/prometheus/querybuilder/shared/QueryOptionGroup'; -import { preprocessMaxLines, queryTypeOptions, RESOLUTION_OPTIONS } from '../../components/LokiOptionFields'; import { AutoSizeInput } from 'app/plugins/datasource/prometheus/querybuilder/shared/AutoSizeInput'; +import { QueryOptionGroup } from 'app/plugins/datasource/prometheus/querybuilder/shared/QueryOptionGroup'; + +import { preprocessMaxLines, queryTypeOptions, RESOLUTION_OPTIONS } from '../../components/LokiOptionFields'; import { isMetricsQuery } from '../../datasource'; +import { LokiQuery, LokiQueryType } from '../../types'; export interface Props { query: LokiQuery; diff --git a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryCodeEditor.tsx b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryCodeEditor.tsx index 41e6bc2937e..1354458a7ac 100644 --- a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryCodeEditor.tsx +++ b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryCodeEditor.tsx @@ -1,10 +1,12 @@ -import React from 'react'; -import { testIds } from '../../components/LokiQueryEditor'; -import { useStyles2 } from '@grafana/ui'; import { css } from '@emotion/css'; +import React from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; -import { LokiQueryEditorProps } from '../../components/types'; +import { useStyles2 } from '@grafana/ui'; + +import { testIds } from '../../components/LokiQueryEditor'; import { LokiQueryField } from '../../components/LokiQueryField'; +import { LokiQueryEditorProps } from '../../components/types'; export function LokiQueryCodeEditor({ query, datasource, range, onRunQuery, onChange, data }: LokiQueryEditorProps) { const styles = useStyles2(getStyles); diff --git a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryEditorSelector.test.tsx b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryEditorSelector.test.tsx index ed29bb1c83f..1b483c53dd1 100644 --- a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryEditorSelector.test.tsx +++ b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryEditorSelector.test.tsx @@ -1,12 +1,15 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { LokiDatasource } from '../../datasource'; import { cloneDeep, defaultsDeep } from 'lodash'; -import { LokiQuery, LokiQueryType } from '../../types'; -import { LokiQueryEditorSelector } from './LokiQueryEditorSelector'; +import React from 'react'; + import { QueryEditorMode } from 'app/plugins/datasource/prometheus/querybuilder/shared/types'; +import { LokiDatasource } from '../../datasource'; +import { LokiQuery, LokiQueryType } from '../../types'; + +import { LokiQueryEditorSelector } from './LokiQueryEditorSelector'; + const defaultQuery = { refId: 'A', expr: '{label1="foo", label2="bar"}', diff --git a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryEditorSelector.tsx b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryEditorSelector.tsx index 94271bfc2b9..fe2c798aac7 100644 --- a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryEditorSelector.tsx +++ b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryEditorSelector.tsx @@ -1,19 +1,22 @@ +import React, { SyntheticEvent, useCallback, useEffect, useState } from 'react'; + import { LoadingState } from '@grafana/data'; import { EditorHeader, EditorRows, FlexItem, InlineSelect, Space } from '@grafana/experimental'; import { Button, ConfirmModal } from '@grafana/ui'; import { QueryEditorModeToggle } from 'app/plugins/datasource/prometheus/querybuilder/shared/QueryEditorModeToggle'; +import { QueryHeaderSwitch } from 'app/plugins/datasource/prometheus/querybuilder/shared/QueryHeaderSwitch'; import { QueryEditorMode } from 'app/plugins/datasource/prometheus/querybuilder/shared/types'; -import React, { SyntheticEvent, useCallback, useEffect, useState } from 'react'; + import { LokiQueryEditorProps } from '../../components/types'; +import { LokiQuery } from '../../types'; import { lokiQueryModeller } from '../LokiQueryModeller'; +import { buildVisualQueryFromString } from '../parsing'; import { getQueryWithDefaults } from '../state'; + import { LokiQueryBuilderContainer } from './LokiQueryBuilderContainer'; import { LokiQueryBuilderExplained } from './LokiQueryBuilderExplained'; import { LokiQueryBuilderOptions } from './LokiQueryBuilderOptions'; import { LokiQueryCodeEditor } from './LokiQueryCodeEditor'; -import { buildVisualQueryFromString } from '../parsing'; -import { QueryHeaderSwitch } from 'app/plugins/datasource/prometheus/querybuilder/shared/QueryHeaderSwitch'; -import { LokiQuery } from '../../types'; export const LokiQueryEditorSelector = React.memo((props) => { const { onChange, onRunQuery, data } = props; diff --git a/public/app/plugins/datasource/loki/querybuilder/components/NestedQuery.tsx b/public/app/plugins/datasource/loki/querybuilder/components/NestedQuery.tsx index 64ba7faee5a..0c88536906f 100644 --- a/public/app/plugins/datasource/loki/querybuilder/components/NestedQuery.tsx +++ b/public/app/plugins/datasource/loki/querybuilder/components/NestedQuery.tsx @@ -1,13 +1,16 @@ import { css } from '@emotion/css'; +import React from 'react'; + import { GrafanaTheme2, toOption } from '@grafana/data'; import { EditorRows, FlexItem } from '@grafana/experimental'; import { IconButton, Select, useStyles2 } from '@grafana/ui'; -import React from 'react'; +import { AutoSizeInput } from 'app/plugins/datasource/prometheus/querybuilder/shared/AutoSizeInput'; + +import { LokiDatasource } from '../../datasource'; import { binaryScalarDefs } from '../binaryScalarOperations'; import { LokiVisualQueryBinary } from '../types'; -import { LokiDatasource } from '../../datasource'; + import { LokiQueryBuilder } from './LokiQueryBuilder'; -import { AutoSizeInput } from 'app/plugins/datasource/prometheus/querybuilder/shared/AutoSizeInput'; export interface Props { nestedQuery: LokiVisualQueryBinary; diff --git a/public/app/plugins/datasource/loki/querybuilder/components/NestedQueryList.tsx b/public/app/plugins/datasource/loki/querybuilder/components/NestedQueryList.tsx index d90bb2dbe60..f527ffd6d3e 100644 --- a/public/app/plugins/datasource/loki/querybuilder/components/NestedQueryList.tsx +++ b/public/app/plugins/datasource/loki/querybuilder/components/NestedQueryList.tsx @@ -1,7 +1,10 @@ -import { Stack } from '@grafana/experimental'; import React from 'react'; + +import { Stack } from '@grafana/experimental'; + import { LokiDatasource } from '../../datasource'; import { LokiVisualQuery, LokiVisualQueryBinary } from '../types'; + import { NestedQuery } from './NestedQuery'; export interface Props { diff --git a/public/app/plugins/datasource/loki/querybuilder/components/QueryPreview.tsx b/public/app/plugins/datasource/loki/querybuilder/components/QueryPreview.tsx index 4fd6592d8b6..e7726df257c 100644 --- a/public/app/plugins/datasource/loki/querybuilder/components/QueryPreview.tsx +++ b/public/app/plugins/datasource/loki/querybuilder/components/QueryPreview.tsx @@ -1,9 +1,11 @@ -import React from 'react'; -import { useTheme2 } from '@grafana/ui'; -import { GrafanaTheme2 } from '@grafana/data'; import { css, cx } from '@emotion/css'; -import { EditorField, EditorFieldGroup, EditorRow } from '@grafana/experimental'; import Prism from 'prismjs'; +import React from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; +import { EditorField, EditorFieldGroup, EditorRow } from '@grafana/experimental'; +import { useTheme2 } from '@grafana/ui'; + import { lokiGrammar } from '../../syntax'; export interface Props { diff --git a/public/app/plugins/datasource/loki/querybuilder/operations.ts b/public/app/plugins/datasource/loki/querybuilder/operations.ts index 25c1cac13f2..b0c7f481406 100644 --- a/public/app/plugins/datasource/loki/querybuilder/operations.ts +++ b/public/app/plugins/datasource/loki/querybuilder/operations.ts @@ -10,6 +10,7 @@ import { VisualQueryModeller, } from '../../prometheus/querybuilder/shared/types'; import { FUNCTIONS } from '../syntax'; + import { binaryScalarOperations } from './binaryScalarOperations'; import { LokiOperationId, LokiOperationOrder, LokiVisualQuery, LokiVisualQueryOperationCategory } from './types'; diff --git a/public/app/plugins/datasource/loki/querybuilder/parsing.ts b/public/app/plugins/datasource/loki/querybuilder/parsing.ts index 43168019c2e..39b38c0f848 100644 --- a/public/app/plugins/datasource/loki/querybuilder/parsing.ts +++ b/public/app/plugins/datasource/loki/querybuilder/parsing.ts @@ -1,5 +1,7 @@ -import { parser } from '@grafana/lezer-logql'; import { SyntaxNode } from '@lezer/common'; + +import { parser } from '@grafana/lezer-logql'; + import { ErrorName, getAllByType, @@ -10,6 +12,7 @@ import { replaceVariables, } from '../../prometheus/querybuilder/shared/parsingUtils'; import { QueryBuilderLabelFilter, QueryBuilderOperation } from '../../prometheus/querybuilder/shared/types'; + import { binaryScalarDefs } from './binaryScalarOperations'; import { LokiVisualQuery, LokiVisualQueryBinary } from './types'; diff --git a/public/app/plugins/datasource/loki/querybuilder/state.ts b/public/app/plugins/datasource/loki/querybuilder/state.ts index 2c719adca94..741a0fbcd3e 100644 --- a/public/app/plugins/datasource/loki/querybuilder/state.ts +++ b/public/app/plugins/datasource/loki/querybuilder/state.ts @@ -1,4 +1,5 @@ import store from 'app/core/store'; + import { QueryEditorMode } from '../../prometheus/querybuilder/shared/types'; import { LokiQuery, LokiQueryType } from '../types'; diff --git a/public/app/plugins/datasource/loki/result_transformer.test.ts b/public/app/plugins/datasource/loki/result_transformer.test.ts index c43d3f99b0d..8ed8a779dde 100644 --- a/public/app/plugins/datasource/loki/result_transformer.test.ts +++ b/public/app/plugins/datasource/loki/result_transformer.test.ts @@ -1,4 +1,8 @@ import { CircularDataFrame, FieldCache, FieldType, MutableDataFrame } from '@grafana/data'; +import { setTemplateSrv } from '@grafana/runtime'; +import { TemplateSrv } from 'app/features/templating/template_srv'; + +import * as ResultTransformer from './result_transformer'; import { LokiStreamResult, LokiTailResponse, @@ -7,9 +11,6 @@ import { TransformerOptions, LokiMatrixResult, } from './types'; -import * as ResultTransformer from './result_transformer'; -import { setTemplateSrv } from '@grafana/runtime'; -import { TemplateSrv } from 'app/features/templating/template_srv'; const streamResult: LokiStreamResult[] = [ { diff --git a/public/app/plugins/datasource/loki/result_transformer.ts b/public/app/plugins/datasource/loki/result_transformer.ts index 38df63a95f1..e32974fb18a 100644 --- a/public/app/plugins/datasource/loki/result_transformer.ts +++ b/public/app/plugins/datasource/loki/result_transformer.ts @@ -1,6 +1,6 @@ import { capitalize, groupBy, isEmpty } from 'lodash'; -import { v5 as uuidv5 } from 'uuid'; import { of } from 'rxjs'; +import { v5 as uuidv5 } from 'uuid'; import { FieldType, @@ -19,9 +19,11 @@ import { ScopedVars, toDataFrame, } from '@grafana/data'; - import { getTemplateSrv, getDataSourceSrv } from '@grafana/runtime'; import TableModel from 'app/core/table_model'; + +import { renderLegendFormat } from '../prometheus/legend'; + import { formatQuery, getHighlighterExpressionsFromQuery } from './query_utils'; import { LokiRangeQueryRequest, @@ -38,7 +40,6 @@ import { LokiStreamResponse, LokiStats, } from './types'; -import { renderLegendFormat } from '../prometheus/legend'; const UUID_NAMESPACE = '6ec946da-0f49-47a8-983a-1d76d17e7c92'; diff --git a/public/app/plugins/datasource/loki/sortDataFrame.test.ts b/public/app/plugins/datasource/loki/sortDataFrame.test.ts index 19b35cd7dc3..165fc7cddfe 100644 --- a/public/app/plugins/datasource/loki/sortDataFrame.test.ts +++ b/public/app/plugins/datasource/loki/sortDataFrame.test.ts @@ -1,4 +1,5 @@ import { ArrayVector, DataFrame, FieldType } from '@grafana/data'; + import { sortDataFrameByTime } from './sortDataFrame'; const inputFrame: DataFrame = { diff --git a/public/app/plugins/datasource/loki/streaming.ts b/public/app/plugins/datasource/loki/streaming.ts index 723d00852f9..0ebadf190b0 100644 --- a/public/app/plugins/datasource/loki/streaming.ts +++ b/public/app/plugins/datasource/loki/streaming.ts @@ -1,9 +1,11 @@ +import { map, Observable, defer, mergeMap } from 'rxjs'; + import { DataFrameJSON, DataQueryRequest, DataQueryResponse, LiveChannelScope, LoadingState } from '@grafana/data'; import { getGrafanaLiveSrv } from '@grafana/runtime'; -import { map, Observable, defer, mergeMap } from 'rxjs'; +import { StreamingDataFrame } from 'app/features/live/data/StreamingDataFrame'; + import { LokiDatasource } from './datasource'; import { LokiQuery } from './types'; -import { StreamingDataFrame } from 'app/features/live/data/StreamingDataFrame'; /** * Calculate a unique key for the query. The key is used to pick a channel and should diff --git a/public/app/plugins/datasource/loki/syntax.test.ts b/public/app/plugins/datasource/loki/syntax.test.ts index b2d88150907..a000eb990b0 100644 --- a/public/app/plugins/datasource/loki/syntax.test.ts +++ b/public/app/plugins/datasource/loki/syntax.test.ts @@ -1,6 +1,7 @@ -import syntax from './syntax'; import Prism from 'prismjs'; +import syntax from './syntax'; + describe('Loki syntax', () => { it('should highlight Loki query correctly', () => { expect(Prism.highlight('{key="val#ue"}', syntax, 'loki')).toBe( diff --git a/public/app/plugins/datasource/loki/syntax.ts b/public/app/plugins/datasource/loki/syntax.ts index de340b9c22f..94a5e54dab4 100644 --- a/public/app/plugins/datasource/loki/syntax.ts +++ b/public/app/plugins/datasource/loki/syntax.ts @@ -1,4 +1,5 @@ import { Grammar } from 'prismjs'; + import { CompletionItem } from '@grafana/ui'; const AGGREGATION_OPERATORS: CompletionItem[] = [ diff --git a/public/app/plugins/datasource/loki/types.ts b/public/app/plugins/datasource/loki/types.ts index 59d0456cddd..39ae33dbded 100644 --- a/public/app/plugins/datasource/loki/types.ts +++ b/public/app/plugins/datasource/loki/types.ts @@ -1,4 +1,5 @@ import { DataQuery, DataSourceJsonData, QueryResultMeta, ScopedVars } from '@grafana/data'; + import { QueryEditorMode } from '../prometheus/querybuilder/shared/types'; export interface LokiInstantQueryRequest { diff --git a/public/app/plugins/datasource/mixed/MixedDataSource.test.ts b/public/app/plugins/datasource/mixed/MixedDataSource.test.ts index 66de6af748c..d94588780aa 100644 --- a/public/app/plugins/datasource/mixed/MixedDataSource.test.ts +++ b/public/app/plugins/datasource/mixed/MixedDataSource.test.ts @@ -1,7 +1,9 @@ -import { LoadingState } from '@grafana/data'; import { lastValueFrom } from 'rxjs'; import { getQueryOptions } from 'test/helpers/getQueryOptions'; import { DatasourceSrvMock, MockObservableDataSourceApi } from 'test/mocks/datasource_srv'; + +import { LoadingState } from '@grafana/data'; + import { MIXED_DATASOURCE_NAME } from './MixedDataSource'; import { MixedDatasource } from './module'; diff --git a/public/app/plugins/datasource/mixed/MixedDataSource.ts b/public/app/plugins/datasource/mixed/MixedDataSource.ts index c5b6837216d..a266215149c 100644 --- a/public/app/plugins/datasource/mixed/MixedDataSource.ts +++ b/public/app/plugins/datasource/mixed/MixedDataSource.ts @@ -1,3 +1,7 @@ +import { cloneDeep, groupBy } from 'lodash'; +import { forkJoin, from, Observable, of, OperatorFunction } from 'rxjs'; +import { catchError, map, mergeAll, mergeMap, reduce, toArray } from 'rxjs/operators'; + import { DataQuery, DataQueryRequest, @@ -7,9 +11,6 @@ import { LoadingState, } from '@grafana/data'; import { getDataSourceSrv, toDataQueryError } from '@grafana/runtime'; -import { cloneDeep, groupBy } from 'lodash'; -import { forkJoin, from, Observable, of, OperatorFunction } from 'rxjs'; -import { catchError, map, mergeAll, mergeMap, reduce, toArray } from 'rxjs/operators'; export const MIXED_DATASOURCE_NAME = '-- Mixed --'; diff --git a/public/app/plugins/datasource/mssql/datasource.ts b/public/app/plugins/datasource/mssql/datasource.ts index 6c65b747381..879cd972b50 100644 --- a/public/app/plugins/datasource/mssql/datasource.ts +++ b/public/app/plugins/datasource/mssql/datasource.ts @@ -1,13 +1,14 @@ import { map as _map } from 'lodash'; import { lastValueFrom, of } from 'rxjs'; import { catchError, map, mapTo } from 'rxjs/operators'; -import { BackendDataSourceResponse, DataSourceWithBackend, FetchResponse, getBackendSrv } from '@grafana/runtime'; + import { AnnotationEvent, DataSourceInstanceSettings, MetricFindValue, ScopedVars, TimeRange } from '@grafana/data'; +import { BackendDataSourceResponse, DataSourceWithBackend, FetchResponse, getBackendSrv } from '@grafana/runtime'; +import { toTestingStatus } from '@grafana/runtime/src/utils/queryResponse'; +import { getTemplateSrv, TemplateSrv } from 'app/features/templating/template_srv'; import ResponseParser from './response_parser'; -import { getTemplateSrv, TemplateSrv } from 'app/features/templating/template_srv'; import { MssqlOptions, MssqlQuery, MssqlQueryForInterpolation } from './types'; -import { toTestingStatus } from '@grafana/runtime/src/utils/queryResponse'; export class MssqlDatasource extends DataSourceWithBackend { id: any; diff --git a/public/app/plugins/datasource/mssql/module.ts b/public/app/plugins/datasource/mssql/module.ts index 093ebaa13ca..2426595a230 100644 --- a/public/app/plugins/datasource/mssql/module.ts +++ b/public/app/plugins/datasource/mssql/module.ts @@ -1,8 +1,9 @@ +import { DataSourcePlugin } from '@grafana/data'; + +import { MssqlConfigCtrl } from './config_ctrl'; import { MssqlDatasource } from './datasource'; import { MssqlQueryCtrl } from './query_ctrl'; -import { MssqlConfigCtrl } from './config_ctrl'; import { MssqlQuery } from './types'; -import { DataSourcePlugin } from '@grafana/data'; const defaultQuery = `SELECT as time, diff --git a/public/app/plugins/datasource/mssql/query_ctrl.ts b/public/app/plugins/datasource/mssql/query_ctrl.ts index 3dd7663209b..2876cbd7395 100644 --- a/public/app/plugins/datasource/mssql/query_ctrl.ts +++ b/public/app/plugins/datasource/mssql/query_ctrl.ts @@ -1,6 +1,8 @@ -import { QueryCtrl } from 'app/plugins/sdk'; import { auto } from 'angular'; + import { PanelEvents, QueryResultMeta } from '@grafana/data'; +import { QueryCtrl } from 'app/plugins/sdk'; + import { MssqlQuery } from './types'; const defaultQuery = `SELECT diff --git a/public/app/plugins/datasource/mssql/specs/datasource.test.ts b/public/app/plugins/datasource/mssql/specs/datasource.test.ts index a25e192b9ce..d0c9feaa8b8 100644 --- a/public/app/plugins/datasource/mssql/specs/datasource.test.ts +++ b/public/app/plugins/datasource/mssql/specs/datasource.test.ts @@ -1,12 +1,13 @@ import { of } from 'rxjs'; -import { dataFrameToJSON, dateTime, MetricFindValue, MutableDataFrame } from '@grafana/data'; - -import { MssqlDatasource } from '../datasource'; -import { TemplateSrv } from 'app/features/templating/template_srv'; -import { backendSrv } from 'app/core/services/backend_srv'; -import { initialCustomVariableModelState } from '../../../../features/variables/custom/reducer'; import { createFetchResponse } from 'test/helpers/createFetchResponse'; +import { dataFrameToJSON, dateTime, MetricFindValue, MutableDataFrame } from '@grafana/data'; +import { backendSrv } from 'app/core/services/backend_srv'; +import { TemplateSrv } from 'app/features/templating/template_srv'; + +import { initialCustomVariableModelState } from '../../../../features/variables/custom/reducer'; +import { MssqlDatasource } from '../datasource'; + jest.mock('@grafana/runtime', () => ({ ...(jest.requireActual('@grafana/runtime') as unknown as object), getBackendSrv: () => backendSrv, diff --git a/public/app/plugins/datasource/mysql/datasource.ts b/public/app/plugins/datasource/mysql/datasource.ts index 87e52893b11..904099254e0 100644 --- a/public/app/plugins/datasource/mysql/datasource.ts +++ b/public/app/plugins/datasource/mysql/datasource.ts @@ -1,15 +1,17 @@ import { map as _map } from 'lodash'; import { lastValueFrom, of } from 'rxjs'; import { catchError, map, mapTo } from 'rxjs/operators'; -import { BackendDataSourceResponse, DataSourceWithBackend, FetchResponse, getBackendSrv } from '@grafana/runtime'; -import { AnnotationEvent, DataSourceInstanceSettings, MetricFindValue, ScopedVars } from '@grafana/data'; +import { AnnotationEvent, DataSourceInstanceSettings, MetricFindValue, ScopedVars } from '@grafana/data'; +import { BackendDataSourceResponse, DataSourceWithBackend, FetchResponse, getBackendSrv } from '@grafana/runtime'; +import { toTestingStatus } from '@grafana/runtime/src/utils/queryResponse'; +import { getTemplateSrv, TemplateSrv } from 'app/features/templating/template_srv'; import MySQLQueryModel from 'app/plugins/datasource/mysql/mysql_query_model'; + +import { getSearchFilterScopedVar } from '../../../features/variables/utils'; + import ResponseParser from './response_parser'; import { MySQLOptions, MySQLQuery, MysqlQueryForInterpolation } from './types'; -import { getTemplateSrv, TemplateSrv } from 'app/features/templating/template_srv'; -import { getSearchFilterScopedVar } from '../../../features/variables/utils'; -import { toTestingStatus } from '@grafana/runtime/src/utils/queryResponse'; export class MysqlDatasource extends DataSourceWithBackend { id: any; diff --git a/public/app/plugins/datasource/mysql/module.ts b/public/app/plugins/datasource/mysql/module.ts index 4ab4d16496d..e412a473cc5 100644 --- a/public/app/plugins/datasource/mysql/module.ts +++ b/public/app/plugins/datasource/mysql/module.ts @@ -1,12 +1,14 @@ -import { MysqlDatasource } from './datasource'; -import { MysqlQueryCtrl } from './query_ctrl'; +import { DataSourcePlugin } from '@grafana/data'; + import { createChangeHandler, createResetHandler, PasswordFieldEnum, } from '../../../features/datasources/utils/passwordHandlers'; + +import { MysqlDatasource } from './datasource'; +import { MysqlQueryCtrl } from './query_ctrl'; import { MySQLQuery } from './types'; -import { DataSourcePlugin } from '@grafana/data'; class MysqlConfigCtrl { static templateUrl = 'partials/config.html'; diff --git a/public/app/plugins/datasource/mysql/mysql_query_model.ts b/public/app/plugins/datasource/mysql/mysql_query_model.ts index efa62919b0e..4fc106f9072 100644 --- a/public/app/plugins/datasource/mysql/mysql_query_model.ts +++ b/public/app/plugins/datasource/mysql/mysql_query_model.ts @@ -1,6 +1,7 @@ import { find, map } from 'lodash'; -import { TemplateSrv } from '@grafana/runtime'; + import { ScopedVars } from '@grafana/data'; +import { TemplateSrv } from '@grafana/runtime'; export default class MySQLQueryModel { target: any; diff --git a/public/app/plugins/datasource/mysql/query_ctrl.ts b/public/app/plugins/datasource/mysql/query_ctrl.ts index 0e012386c29..62a9d69cf93 100644 --- a/public/app/plugins/datasource/mysql/query_ctrl.ts +++ b/public/app/plugins/datasource/mysql/query_ctrl.ts @@ -1,15 +1,18 @@ +import { auto } from 'angular'; import { clone, filter, find, findIndex, indexOf, map } from 'lodash'; -import appEvents from 'app/core/app_events'; -import { MysqlMetaQuery } from './meta_query'; -import { QueryCtrl } from 'app/plugins/sdk'; + +import { PanelEvents, QueryResultMeta } from '@grafana/data'; +import { TemplateSrv } from '@grafana/runtime'; import { SqlPart } from 'app/angular/components/sql_part/sql_part'; +import appEvents from 'app/core/app_events'; +import { VariableWithMultiSupport } from 'app/features/variables/types'; +import { QueryCtrl } from 'app/plugins/sdk'; + +import { ShowConfirmModalEvent } from '../../../types/events'; + +import { MysqlMetaQuery } from './meta_query'; import MySQLQueryModel from './mysql_query_model'; import sqlPart from './sql_part'; -import { auto } from 'angular'; -import { PanelEvents, QueryResultMeta } from '@grafana/data'; -import { VariableWithMultiSupport } from 'app/features/variables/types'; -import { TemplateSrv } from '@grafana/runtime'; -import { ShowConfirmModalEvent } from '../../../types/events'; const defaultQuery = `SELECT UNIX_TIMESTAMP() as time_sec, diff --git a/public/app/plugins/datasource/mysql/specs/datasource.test.ts b/public/app/plugins/datasource/mysql/specs/datasource.test.ts index d55c28c0768..54ab5575079 100644 --- a/public/app/plugins/datasource/mysql/specs/datasource.test.ts +++ b/public/app/plugins/datasource/mysql/specs/datasource.test.ts @@ -1,4 +1,5 @@ import { of } from 'rxjs'; + import { dataFrameToJSON, DataQueryRequest, @@ -6,12 +7,13 @@ import { dateTime, MutableDataFrame, } from '@grafana/data'; - -import { MysqlDatasource } from '../datasource'; +import { FetchResponse, setBackendSrv } from '@grafana/runtime'; import { backendSrv } from 'app/core/services/backend_srv'; // will use the version in __mocks__ import { TemplateSrv } from 'app/features/templating/template_srv'; + import { initialCustomVariableModelState } from '../../../../features/variables/custom/reducer'; -import { FetchResponse, setBackendSrv } from '@grafana/runtime'; +import { MysqlDatasource } from '../datasource'; + import { MySQLOptions, MySQLQuery } from './../types'; describe('MySQLDatasource', () => { diff --git a/public/app/plugins/datasource/opentsdb/components/ConfigEditor.tsx b/public/app/plugins/datasource/opentsdb/components/ConfigEditor.tsx index dc0bc712c0a..fc0cf8395cf 100644 --- a/public/app/plugins/datasource/opentsdb/components/ConfigEditor.tsx +++ b/public/app/plugins/datasource/opentsdb/components/ConfigEditor.tsx @@ -1,9 +1,12 @@ import React from 'react'; -import { DataSourceHttpSettings } from '@grafana/ui'; + import { DataSourcePluginOptionsEditorProps } from '@grafana/data'; -import { OpenTsdbDetails } from './OpenTsdbDetails'; +import { DataSourceHttpSettings } from '@grafana/ui'; + import { OpenTsdbOptions } from '../types'; +import { OpenTsdbDetails } from './OpenTsdbDetails'; + export const ConfigEditor = (props: DataSourcePluginOptionsEditorProps) => { const { options, onOptionsChange } = props; diff --git a/public/app/plugins/datasource/opentsdb/components/OpenTsdbDetails.tsx b/public/app/plugins/datasource/opentsdb/components/OpenTsdbDetails.tsx index 4d15ea73ff1..f99b3c06a47 100644 --- a/public/app/plugins/datasource/opentsdb/components/OpenTsdbDetails.tsx +++ b/public/app/plugins/datasource/opentsdb/components/OpenTsdbDetails.tsx @@ -1,9 +1,12 @@ import React, { SyntheticEvent } from 'react'; -import { InlineFormLabel, LegacyForms } from '@grafana/ui'; -const { Select, Input } = LegacyForms; + import { DataSourceSettings, SelectableValue } from '@grafana/data'; -import { OpenTsdbOptions } from '../types'; +import { InlineFormLabel, LegacyForms } from '@grafana/ui'; + import { useUniqueId } from '../../influxdb/components/useUniqueId'; +import { OpenTsdbOptions } from '../types'; + +const { Select, Input } = LegacyForms; const tsdbVersions = [ { label: '<=2.1', value: 1 }, diff --git a/public/app/plugins/datasource/opentsdb/datasource.ts b/public/app/plugins/datasource/opentsdb/datasource.ts index 34d904d45ea..ca681e730a1 100644 --- a/public/app/plugins/datasource/opentsdb/datasource.ts +++ b/public/app/plugins/datasource/opentsdb/datasource.ts @@ -15,7 +15,7 @@ import { } from 'lodash'; import { lastValueFrom, Observable, of } from 'rxjs'; import { catchError, map } from 'rxjs/operators'; -import { FetchResponse, getBackendSrv } from '@grafana/runtime'; + import { AnnotationEvent, DataQueryRequest, @@ -24,8 +24,9 @@ import { dateMath, ScopedVars, } from '@grafana/data'; - +import { FetchResponse, getBackendSrv } from '@grafana/runtime'; import { getTemplateSrv, TemplateSrv } from 'app/features/templating/template_srv'; + import { OpenTsdbOptions, OpenTsdbQuery } from './types'; export default class OpenTsDatasource extends DataSourceApi { diff --git a/public/app/plugins/datasource/opentsdb/module.ts b/public/app/plugins/datasource/opentsdb/module.ts index 768025c026f..f84df8875aa 100644 --- a/public/app/plugins/datasource/opentsdb/module.ts +++ b/public/app/plugins/datasource/opentsdb/module.ts @@ -1,7 +1,8 @@ +import { DataSourcePlugin } from '@grafana/data'; + +import { ConfigEditor } from './components/ConfigEditor'; import OpenTsDatasource from './datasource'; import { OpenTsQueryCtrl } from './query_ctrl'; -import { DataSourcePlugin } from '@grafana/data'; -import { ConfigEditor } from './components/ConfigEditor'; class AnnotationsQueryCtrl { static templateUrl = 'partials/annotations.editor.html'; diff --git a/public/app/plugins/datasource/opentsdb/query_ctrl.ts b/public/app/plugins/datasource/opentsdb/query_ctrl.ts index be0d7895e73..dc6bec377a3 100644 --- a/public/app/plugins/datasource/opentsdb/query_ctrl.ts +++ b/public/app/plugins/datasource/opentsdb/query_ctrl.ts @@ -1,7 +1,8 @@ -import { map, size, has } from 'lodash'; -import { QueryCtrl } from 'app/plugins/sdk'; import { auto } from 'angular'; +import { map, size, has } from 'lodash'; + import { textUtil, rangeUtil } from '@grafana/data'; +import { QueryCtrl } from 'app/plugins/sdk'; export class OpenTsQueryCtrl extends QueryCtrl { static templateUrl = 'partials/query.editor.html'; diff --git a/public/app/plugins/datasource/opentsdb/specs/datasource.test.ts b/public/app/plugins/datasource/opentsdb/specs/datasource.test.ts index ecbe4ec2ca5..ab019ade067 100644 --- a/public/app/plugins/datasource/opentsdb/specs/datasource.test.ts +++ b/public/app/plugins/datasource/opentsdb/specs/datasource.test.ts @@ -1,9 +1,11 @@ -import OpenTsDatasource from '../datasource'; -import { backendSrv } from 'app/core/services/backend_srv'; // will use the version in __mocks__ -import { OpenTsdbQuery } from '../types'; -import { createFetchResponse } from '../../../../../test/helpers/createFetchResponse'; import { of } from 'rxjs'; +import { backendSrv } from 'app/core/services/backend_srv'; // will use the version in __mocks__ + +import { createFetchResponse } from '../../../../../test/helpers/createFetchResponse'; +import OpenTsDatasource from '../datasource'; +import { OpenTsdbQuery } from '../types'; + jest.mock('@grafana/runtime', () => ({ ...(jest.requireActual('@grafana/runtime') as unknown as object), getBackendSrv: () => backendSrv, diff --git a/public/app/plugins/datasource/postgres/config_ctrl.ts b/public/app/plugins/datasource/postgres/config_ctrl.ts index d3759cc6971..f2bc26e8da6 100644 --- a/public/app/plugins/datasource/postgres/config_ctrl.ts +++ b/public/app/plugins/datasource/postgres/config_ctrl.ts @@ -1,10 +1,12 @@ import { find } from 'lodash'; + +import { DatasourceSrv } from 'app/features/plugins/datasource_srv'; + import { createChangeHandler, createResetHandler, PasswordFieldEnum, } from '../../../features/datasources/utils/passwordHandlers'; -import { DatasourceSrv } from 'app/features/plugins/datasource_srv'; export class PostgresConfigCtrl { static templateUrl = 'partials/config.html'; diff --git a/public/app/plugins/datasource/postgres/datasource.test.ts b/public/app/plugins/datasource/postgres/datasource.test.ts index a0f86c5976d..deafceeb4e1 100644 --- a/public/app/plugins/datasource/postgres/datasource.test.ts +++ b/public/app/plugins/datasource/postgres/datasource.test.ts @@ -1,6 +1,8 @@ -import { backendSrv } from 'app/core/services/backend_srv'; import { of, throwError } from 'rxjs'; import { createFetchResponse } from 'test/helpers/createFetchResponse'; + +import { backendSrv } from 'app/core/services/backend_srv'; + import { PostgresDatasource } from './datasource'; jest.mock('@grafana/runtime', () => ({ diff --git a/public/app/plugins/datasource/postgres/datasource.ts b/public/app/plugins/datasource/postgres/datasource.ts index 84d6d3a65cd..073b3306a55 100644 --- a/public/app/plugins/datasource/postgres/datasource.ts +++ b/public/app/plugins/datasource/postgres/datasource.ts @@ -1,16 +1,17 @@ import { map as _map } from 'lodash'; import { lastValueFrom, of } from 'rxjs'; import { map, catchError } from 'rxjs/operators'; -import { BackendDataSourceResponse, DataSourceWithBackend, FetchResponse, getBackendSrv } from '@grafana/runtime'; + import { AnnotationEvent, DataSourceInstanceSettings, MetricFindValue, ScopedVars, TimeRange } from '@grafana/data'; +import { BackendDataSourceResponse, DataSourceWithBackend, FetchResponse, getBackendSrv } from '@grafana/runtime'; +import { toTestingStatus } from '@grafana/runtime/src/utils/queryResponse'; +import { getTemplateSrv, TemplateSrv } from 'app/features/templating/template_srv'; +import PostgresQueryModel from 'app/plugins/datasource/postgres/postgres_query_model'; + +import { getSearchFilterScopedVar } from '../../../features/variables/utils'; import ResponseParser from './response_parser'; -import PostgresQueryModel from 'app/plugins/datasource/postgres/postgres_query_model'; -import { getTemplateSrv, TemplateSrv } from 'app/features/templating/template_srv'; -//Types import { PostgresOptions, PostgresQuery, PostgresQueryForInterpolation } from './types'; -import { getSearchFilterScopedVar } from '../../../features/variables/utils'; -import { toTestingStatus } from '@grafana/runtime/src/utils/queryResponse'; export class PostgresDatasource extends DataSourceWithBackend { id: any; diff --git a/public/app/plugins/datasource/postgres/module.ts b/public/app/plugins/datasource/postgres/module.ts index 52ddcfb40e1..28891a1e862 100644 --- a/public/app/plugins/datasource/postgres/module.ts +++ b/public/app/plugins/datasource/postgres/module.ts @@ -1,8 +1,9 @@ +import { DataSourcePlugin } from '@grafana/data'; + +import { PostgresConfigCtrl } from './config_ctrl'; import { PostgresDatasource } from './datasource'; import { PostgresQueryCtrl } from './query_ctrl'; -import { PostgresConfigCtrl } from './config_ctrl'; import { PostgresQuery } from './types'; -import { DataSourcePlugin } from '@grafana/data'; const defaultQuery = `SELECT extract(epoch from time_column) AS time, diff --git a/public/app/plugins/datasource/postgres/postgres_query_model.ts b/public/app/plugins/datasource/postgres/postgres_query_model.ts index 0fce8b38993..287b4ba1e0a 100644 --- a/public/app/plugins/datasource/postgres/postgres_query_model.ts +++ b/public/app/plugins/datasource/postgres/postgres_query_model.ts @@ -1,6 +1,7 @@ import { find, map } from 'lodash'; -import { TemplateSrv } from '@grafana/runtime'; + import { ScopedVars } from '@grafana/data'; +import { TemplateSrv } from '@grafana/runtime'; export default class PostgresQueryModel { target: any; diff --git a/public/app/plugins/datasource/postgres/query_ctrl.ts b/public/app/plugins/datasource/postgres/query_ctrl.ts index 0ef5dadf739..9e8e2cd31ec 100644 --- a/public/app/plugins/datasource/postgres/query_ctrl.ts +++ b/public/app/plugins/datasource/postgres/query_ctrl.ts @@ -1,15 +1,17 @@ +import { auto } from 'angular'; import { clone, filter, find, findIndex, indexOf, map } from 'lodash'; -import appEvents from 'app/core/app_events'; -import { PostgresMetaQuery } from './meta_query'; -import { QueryCtrl } from 'app/plugins/sdk'; + +import { PanelEvents, QueryResultMeta } from '@grafana/data'; +import { TemplateSrv } from '@grafana/runtime'; import { SqlPart } from 'app/angular/components/sql_part/sql_part'; +import appEvents from 'app/core/app_events'; +import { VariableWithMultiSupport } from 'app/features/variables/types'; +import { QueryCtrl } from 'app/plugins/sdk'; +import { ShowConfirmModalEvent } from 'app/types/events'; + +import { PostgresMetaQuery } from './meta_query'; import PostgresQueryModel from './postgres_query_model'; import sqlPart from './sql_part'; -import { auto } from 'angular'; -import { PanelEvents, QueryResultMeta } from '@grafana/data'; -import { VariableWithMultiSupport } from 'app/features/variables/types'; -import { TemplateSrv } from '@grafana/runtime'; -import { ShowConfirmModalEvent } from 'app/types/events'; const defaultQuery = `SELECT $__time(time_column), diff --git a/public/app/plugins/datasource/postgres/specs/datasource.test.ts b/public/app/plugins/datasource/postgres/specs/datasource.test.ts index 6cc80e1a8d0..c83486e15e4 100644 --- a/public/app/plugins/datasource/postgres/specs/datasource.test.ts +++ b/public/app/plugins/datasource/postgres/specs/datasource.test.ts @@ -1,6 +1,6 @@ import { of } from 'rxjs'; import { TestScheduler } from 'rxjs/testing'; -import { FetchResponse } from '@grafana/runtime'; + import { dataFrameToJSON, DataQueryRequest, @@ -8,11 +8,12 @@ import { dateTime, MutableDataFrame, } from '@grafana/data'; - -import { PostgresDatasource } from '../datasource'; +import { FetchResponse } from '@grafana/runtime'; import { backendSrv } from 'app/core/services/backend_srv'; // will use the version in __mocks__ import { TemplateSrv } from 'app/features/templating/template_srv'; + import { initialCustomVariableModelState } from '../../../../features/variables/custom/reducer'; +import { PostgresDatasource } from '../datasource'; import { PostgresOptions, PostgresQuery } from '../types'; jest.mock('@grafana/runtime', () => ({ diff --git a/public/app/plugins/datasource/postgres/specs/postgres_query.test.ts b/public/app/plugins/datasource/postgres/specs/postgres_query.test.ts index e2057b6a5cc..a1c65523f92 100644 --- a/public/app/plugins/datasource/postgres/specs/postgres_query.test.ts +++ b/public/app/plugins/datasource/postgres/specs/postgres_query.test.ts @@ -1,6 +1,7 @@ -import PostgresQueryModel from '../postgres_query_model'; import { TemplateSrv } from 'app/features/templating/template_srv'; +import PostgresQueryModel from '../postgres_query_model'; + describe('PostgresQuery', () => { // @ts-ignore const templateSrv: TemplateSrv = { diff --git a/public/app/plugins/datasource/prometheus/add_label_to_query.ts b/public/app/plugins/datasource/prometheus/add_label_to_query.ts index 85c1a1511fe..b8db62e88db 100644 --- a/public/app/plugins/datasource/prometheus/add_label_to_query.ts +++ b/public/app/plugins/datasource/prometheus/add_label_to_query.ts @@ -1,6 +1,7 @@ import { parser } from 'lezer-promql'; -import { buildVisualQueryFromString } from './querybuilder/parsing'; + import { PromQueryModeller } from './querybuilder/PromQueryModeller'; +import { buildVisualQueryFromString } from './querybuilder/parsing'; import { QueryBuilderLabelFilter } from './querybuilder/shared/types'; import { PromVisualQuery } from './querybuilder/types'; diff --git a/public/app/plugins/datasource/prometheus/components/PromCheatSheet.tsx b/public/app/plugins/datasource/prometheus/components/PromCheatSheet.tsx index c0e7c2736d2..c26952aae2d 100644 --- a/public/app/plugins/datasource/prometheus/components/PromCheatSheet.tsx +++ b/public/app/plugins/datasource/prometheus/components/PromCheatSheet.tsx @@ -1,5 +1,7 @@ import React from 'react'; + import { QueryEditorHelpProps } from '@grafana/data'; + import { PromQuery } from '../types'; const CHEAT_SHEET_ITEMS = [ diff --git a/public/app/plugins/datasource/prometheus/components/PromExemplarField.tsx b/public/app/plugins/datasource/prometheus/components/PromExemplarField.tsx index fb125be09de..e09a6260c98 100644 --- a/public/app/plugins/datasource/prometheus/components/PromExemplarField.tsx +++ b/public/app/plugins/datasource/prometheus/components/PromExemplarField.tsx @@ -1,8 +1,10 @@ -import { GrafanaTheme2 } from '@grafana/data'; -import { IconButton, InlineLabel, Tooltip, useStyles2 } from '@grafana/ui'; import { css, cx } from '@emotion/css'; import React, { useEffect, useState } from 'react'; import { usePrevious } from 'react-use'; + +import { GrafanaTheme2 } from '@grafana/data'; +import { IconButton, InlineLabel, Tooltip, useStyles2 } from '@grafana/ui'; + import { PrometheusDatasource } from '../datasource'; import { PromQuery } from '../types'; diff --git a/public/app/plugins/datasource/prometheus/components/PromExploreExtraField.test.tsx b/public/app/plugins/datasource/prometheus/components/PromExploreExtraField.test.tsx index 8ca87275707..b654037d06a 100644 --- a/public/app/plugins/datasource/prometheus/components/PromExploreExtraField.test.tsx +++ b/public/app/plugins/datasource/prometheus/components/PromExploreExtraField.test.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; +import React from 'react'; + import { PromExploreExtraFieldProps, PromExploreExtraField, testIds } from './PromExploreExtraField'; const setup = (propOverrides?: PromExploreExtraFieldProps) => { diff --git a/public/app/plugins/datasource/prometheus/components/PromExploreExtraField.tsx b/public/app/plugins/datasource/prometheus/components/PromExploreExtraField.tsx index d8b2087cca9..3e6f2c17677 100644 --- a/public/app/plugins/datasource/prometheus/components/PromExploreExtraField.tsx +++ b/public/app/plugins/datasource/prometheus/components/PromExploreExtraField.tsx @@ -1,11 +1,14 @@ +import { css, cx } from '@emotion/css'; +import { isEqual } from 'lodash'; import React, { memo, useCallback } from 'react'; import { usePrevious } from 'react-use'; -import { isEqual } from 'lodash'; -import { css, cx } from '@emotion/css'; + import { InlineFormLabel, RadioButtonGroup } from '@grafana/ui'; -import { PromQuery } from '../types'; -import { PromExemplarField } from './PromExemplarField'; + import { PrometheusDatasource } from '../datasource'; +import { PromQuery } from '../types'; + +import { PromExemplarField } from './PromExemplarField'; export interface PromExploreExtraFieldProps { query: PromQuery; diff --git a/public/app/plugins/datasource/prometheus/components/PromExploreQueryEditor.test.tsx b/public/app/plugins/datasource/prometheus/components/PromExploreQueryEditor.test.tsx index 5fc77456d14..f8b9d9486ae 100644 --- a/public/app/plugins/datasource/prometheus/components/PromExploreQueryEditor.test.tsx +++ b/public/app/plugins/datasource/prometheus/components/PromExploreQueryEditor.test.tsx @@ -1,10 +1,13 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; -import { PromExploreQueryEditor, testIds } from './PromExploreQueryEditor'; -import { testIds as extraFieldTestIds } from './PromExploreExtraField'; +import React from 'react'; + +import { LoadingState, PanelData, toUtc, TimeRange } from '@grafana/data'; + import { PrometheusDatasource } from '../datasource'; import { PromQuery } from '../types'; -import { LoadingState, PanelData, toUtc, TimeRange } from '@grafana/data'; + +import { testIds as extraFieldTestIds } from './PromExploreExtraField'; +import { PromExploreQueryEditor, testIds } from './PromExploreQueryEditor'; // the monaco-based editor uses lazy-loading and that does not work // well with this test, and we do not need the monaco-related diff --git a/public/app/plugins/datasource/prometheus/components/PromExploreQueryEditor.tsx b/public/app/plugins/datasource/prometheus/components/PromExploreQueryEditor.tsx index 140b1f66cd6..5517ef1c8da 100644 --- a/public/app/plugins/datasource/prometheus/components/PromExploreQueryEditor.tsx +++ b/public/app/plugins/datasource/prometheus/components/PromExploreQueryEditor.tsx @@ -1,9 +1,12 @@ import React, { memo, useEffect } from 'react'; + import { QueryEditorProps, CoreApp } from '@grafana/data'; + import { PrometheusDatasource } from '../datasource'; import { PromQuery, PromOptions } from '../types'; -import PromQueryField from './PromQueryField'; + import { PromExploreExtraField } from './PromExploreExtraField'; +import PromQueryField from './PromQueryField'; export type Props = QueryEditorProps; diff --git a/public/app/plugins/datasource/prometheus/components/PromLink.test.tsx b/public/app/plugins/datasource/prometheus/components/PromLink.test.tsx index 2cb10367a86..408d48c0071 100644 --- a/public/app/plugins/datasource/prometheus/components/PromLink.test.tsx +++ b/public/app/plugins/datasource/prometheus/components/PromLink.test.tsx @@ -1,8 +1,11 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; +import React from 'react'; + import { PanelData } from '@grafana/data'; -import { PromQuery } from '../types'; + import { PrometheusDatasource } from '../datasource'; +import { PromQuery } from '../types'; + import PromLink from './PromLink'; jest.mock('@grafana/data', () => ({ diff --git a/public/app/plugins/datasource/prometheus/components/PromLink.tsx b/public/app/plugins/datasource/prometheus/components/PromLink.tsx index f50189edb2d..8264eb83866 100644 --- a/public/app/plugins/datasource/prometheus/components/PromLink.tsx +++ b/public/app/plugins/datasource/prometheus/components/PromLink.tsx @@ -1,9 +1,10 @@ import { map } from 'lodash'; import React, { FC, useEffect, useState, memo } from 'react'; +import { DataQueryRequest, PanelData, ScopedVars, textUtil, rangeUtil } from '@grafana/data'; + import { PrometheusDatasource } from '../datasource'; import { PromQuery } from '../types'; -import { DataQueryRequest, PanelData, ScopedVars, textUtil, rangeUtil } from '@grafana/data'; interface Props { datasource: PrometheusDatasource; diff --git a/public/app/plugins/datasource/prometheus/components/PromQueryEditor.test.tsx b/public/app/plugins/datasource/prometheus/components/PromQueryEditor.test.tsx index 988b25419de..b54fe94a74d 100644 --- a/public/app/plugins/datasource/prometheus/components/PromQueryEditor.test.tsx +++ b/public/app/plugins/datasource/prometheus/components/PromQueryEditor.test.tsx @@ -1,11 +1,13 @@ -import React from 'react'; -import { dateTime, CoreApp } from '@grafana/data'; import { screen, render } from '@testing-library/react'; +import React from 'react'; + +import { dateTime, CoreApp } from '@grafana/data'; -import { PromQueryEditor, testIds } from './PromQueryEditor'; import { PrometheusDatasource } from '../datasource'; import { PromQuery } from '../types'; +import { PromQueryEditor, testIds } from './PromQueryEditor'; + jest.mock('app/features/dashboard/services/TimeSrv', () => { return { getTimeSrv: () => ({ diff --git a/public/app/plugins/datasource/prometheus/components/PromQueryEditor.tsx b/public/app/plugins/datasource/prometheus/components/PromQueryEditor.tsx index 5de3e7b3358..05e1a55cc5d 100644 --- a/public/app/plugins/datasource/prometheus/components/PromQueryEditor.tsx +++ b/public/app/plugins/datasource/prometheus/components/PromQueryEditor.tsx @@ -2,13 +2,14 @@ import { map } from 'lodash'; import React, { PureComponent } from 'react'; // Types -import { InlineFormLabel, LegacyForms, Select } from '@grafana/ui'; import { CoreApp, SelectableValue } from '@grafana/data'; +import { InlineFormLabel, LegacyForms, Select } from '@grafana/ui'; + import { PromQuery } from '../types'; -import PromQueryField from './PromQueryField'; -import PromLink from './PromLink'; import { PromExemplarField } from './PromExemplarField'; +import PromLink from './PromLink'; +import PromQueryField from './PromQueryField'; import { PromQueryEditorProps } from './types'; const { Switch } = LegacyForms; diff --git a/public/app/plugins/datasource/prometheus/components/PromQueryEditorByApp.test.tsx b/public/app/plugins/datasource/prometheus/components/PromQueryEditorByApp.test.tsx index f9de8f77ed1..45f257cfabe 100644 --- a/public/app/plugins/datasource/prometheus/components/PromQueryEditorByApp.test.tsx +++ b/public/app/plugins/datasource/prometheus/components/PromQueryEditorByApp.test.tsx @@ -1,12 +1,15 @@ -import React from 'react'; import { render, RenderResult } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { PromQueryEditorByApp } from './PromQueryEditorByApp'; -import { CoreApp } from '@grafana/data'; import { noop } from 'lodash'; +import React from 'react'; + +import { CoreApp } from '@grafana/data'; + import { PrometheusDatasource } from '../datasource'; -import { testIds as alertingTestIds } from './PromQueryEditorForAlerting'; + import { testIds as regularTestIds } from './PromQueryEditor'; +import { PromQueryEditorByApp } from './PromQueryEditorByApp'; +import { testIds as alertingTestIds } from './PromQueryEditorForAlerting'; // the monaco-based editor uses lazy-loading and that does not work // well with this test, and we do not need the monaco-related diff --git a/public/app/plugins/datasource/prometheus/components/PromQueryEditorByApp.tsx b/public/app/plugins/datasource/prometheus/components/PromQueryEditorByApp.tsx index 9b1e9ed6fca..3e15b9a297d 100644 --- a/public/app/plugins/datasource/prometheus/components/PromQueryEditorByApp.tsx +++ b/public/app/plugins/datasource/prometheus/components/PromQueryEditorByApp.tsx @@ -1,11 +1,14 @@ import React, { memo } from 'react'; + import { CoreApp } from '@grafana/data'; -import { PromQueryEditorProps } from './types'; +import { config } from '@grafana/runtime'; + +import { PromQueryEditorSelector } from '../querybuilder/components/PromQueryEditorSelector'; + +import { PromExploreQueryEditor } from './PromExploreQueryEditor'; import { PromQueryEditor } from './PromQueryEditor'; import { PromQueryEditorForAlerting } from './PromQueryEditorForAlerting'; -import { config } from '@grafana/runtime'; -import { PromQueryEditorSelector } from '../querybuilder/components/PromQueryEditorSelector'; -import { PromExploreQueryEditor } from './PromExploreQueryEditor'; +import { PromQueryEditorProps } from './types'; export function PromQueryEditorByApp(props: PromQueryEditorProps) { const { app } = props; diff --git a/public/app/plugins/datasource/prometheus/components/PromQueryEditorForAlerting.tsx b/public/app/plugins/datasource/prometheus/components/PromQueryEditorForAlerting.tsx index effb68b1703..b7b57071d8e 100644 --- a/public/app/plugins/datasource/prometheus/components/PromQueryEditorForAlerting.tsx +++ b/public/app/plugins/datasource/prometheus/components/PromQueryEditorForAlerting.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import PromQueryField from './PromQueryField'; import { PromQueryEditorProps } from './types'; diff --git a/public/app/plugins/datasource/prometheus/components/PromQueryField.test.tsx b/public/app/plugins/datasource/prometheus/components/PromQueryField.test.tsx index f07db3c5929..4a047c07ac8 100644 --- a/public/app/plugins/datasource/prometheus/components/PromQueryField.test.tsx +++ b/public/app/plugins/datasource/prometheus/components/PromQueryField.test.tsx @@ -1,11 +1,14 @@ +import { render, screen } from '@testing-library/react'; // @ts-ignore import RCCascader from 'rc-cascader'; import React from 'react'; -import PromQlLanguageProvider from '../language_provider'; -import PromQueryField from './PromQueryField'; + import { DataSourceInstanceSettings, PanelData, LoadingState, DataFrame } from '@grafana/data'; + +import PromQlLanguageProvider from '../language_provider'; import { PromOptions } from '../types'; -import { render, screen } from '@testing-library/react'; + +import PromQueryField from './PromQueryField'; // the monaco-based editor uses lazy-loading and that does not work // well with this test, and we do not need the monaco-related diff --git a/public/app/plugins/datasource/prometheus/components/PromQueryField.tsx b/public/app/plugins/datasource/prometheus/components/PromQueryField.tsx index 8de4357985f..113e53386e9 100644 --- a/public/app/plugins/datasource/prometheus/components/PromQueryField.tsx +++ b/public/app/plugins/datasource/prometheus/components/PromQueryField.tsx @@ -1,6 +1,8 @@ +import { LanguageMap, languages as prismLanguages } from 'prismjs'; import React, { ReactNode } from 'react'; - import { Plugin } from 'slate'; + +import { QueryEditorProps, QueryHint, isDataFrame, toLegacyResponseData, TimeRange, CoreApp } from '@grafana/data'; import { SlatePrism, TypeaheadInput, @@ -10,18 +12,15 @@ import { SuggestionsState, Icon, } from '@grafana/ui'; - -import { LanguageMap, languages as prismLanguages } from 'prismjs'; - -// dom also includes Element polyfills -import { PromQuery, PromOptions } from '../types'; -import { roundMsToMin } from '../language_utils'; +import { LocalStorageValueProvider } from 'app/core/components/LocalStorageValueProvider'; import { CancelablePromise, makePromiseCancelable } from 'app/core/utils/CancelablePromise'; -import { QueryEditorProps, QueryHint, isDataFrame, toLegacyResponseData, TimeRange, CoreApp } from '@grafana/data'; + import { PrometheusDatasource } from '../datasource'; +import { roundMsToMin } from '../language_utils'; +import { PromQuery, PromOptions } from '../types'; + import { PrometheusMetricsBrowser } from './PrometheusMetricsBrowser'; import { MonacoQueryFieldWrapper } from './monaco-query-field/MonacoQueryFieldWrapper'; -import { LocalStorageValueProvider } from 'app/core/components/LocalStorageValueProvider'; export const RECORDING_RULES_GROUP = '__recording_rules__'; const LAST_USED_LABELS_KEY = 'grafana.datasources.prometheus.browser.labels'; diff --git a/public/app/plugins/datasource/prometheus/components/PrometheusMetricsBrowser.test.tsx b/public/app/plugins/datasource/prometheus/components/PrometheusMetricsBrowser.test.tsx index 13ef5c7a4bf..42b51c096f0 100644 --- a/public/app/plugins/datasource/prometheus/components/PrometheusMetricsBrowser.test.tsx +++ b/public/app/plugins/datasource/prometheus/components/PrometheusMetricsBrowser.test.tsx @@ -1,8 +1,11 @@ -import React from 'react'; import { render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import React from 'react'; import { getTheme } from '@grafana/ui'; + +import PromQlLanguageProvider from '../language_provider'; + import { buildSelector, facetLabels, @@ -10,7 +13,6 @@ import { UnthemedPrometheusMetricsBrowser, BrowserProps, } from './PrometheusMetricsBrowser'; -import PromQlLanguageProvider from '../language_provider'; describe('buildSelector()', () => { it('returns an empty selector for no labels', () => { diff --git a/public/app/plugins/datasource/prometheus/components/PrometheusMetricsBrowser.tsx b/public/app/plugins/datasource/prometheus/components/PrometheusMetricsBrowser.tsx index eaa70ee0d1e..7c04ab494ae 100644 --- a/public/app/plugins/datasource/prometheus/components/PrometheusMetricsBrowser.tsx +++ b/public/app/plugins/datasource/prometheus/components/PrometheusMetricsBrowser.tsx @@ -1,4 +1,8 @@ +import { css, cx } from '@emotion/css'; import React, { ChangeEvent } from 'react'; +import { FixedSizeList } from 'react-window'; + +import { GrafanaTheme } from '@grafana/data'; import { Button, HorizontalGroup, @@ -9,12 +13,9 @@ import { withTheme, BrowserLabel as PromLabel, } from '@grafana/ui'; + import PromQlLanguageProvider from '../language_provider'; import { escapeLabelValueInExactSelector, escapeLabelValueInRegexSelector } from '../language_utils'; -import { css, cx } from '@emotion/css'; -import { FixedSizeList } from 'react-window'; - -import { GrafanaTheme } from '@grafana/data'; // Hard limit on labels to render const EMPTY_SELECTOR = '{}'; diff --git a/public/app/plugins/datasource/prometheus/components/monaco-query-field/MonacoQueryField.tsx b/public/app/plugins/datasource/prometheus/components/monaco-query-field/MonacoQueryField.tsx index 7e095b07ee7..7ad26256ea9 100644 --- a/public/app/plugins/datasource/prometheus/components/monaco-query-field/MonacoQueryField.tsx +++ b/public/app/plugins/datasource/prometheus/components/monaco-query-field/MonacoQueryField.tsx @@ -1,13 +1,15 @@ -import React, { useRef, useEffect } from 'react'; -import { useTheme2, ReactMonacoEditor, Monaco, monacoTypes } from '@grafana/ui'; -import { GrafanaTheme2 } from '@grafana/data'; import { css } from '@emotion/css'; -import { useLatest } from 'react-use'; import { promLanguageDefinition } from 'monaco-promql'; +import React, { useRef, useEffect } from 'react'; +import { useLatest } from 'react-use'; + +import { GrafanaTheme2 } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; -import { getCompletionProvider, getSuggestOptions } from './monaco-completion-provider'; +import { useTheme2, ReactMonacoEditor, Monaco, monacoTypes } from '@grafana/ui'; + import { Props } from './MonacoQueryFieldProps'; import { getOverrideServices } from './getOverrideServices'; +import { getCompletionProvider, getSuggestOptions } from './monaco-completion-provider'; const options: monacoTypes.editor.IStandaloneEditorConstructionOptions = { codeLens: false, diff --git a/public/app/plugins/datasource/prometheus/components/monaco-query-field/MonacoQueryFieldLazy.tsx b/public/app/plugins/datasource/prometheus/components/monaco-query-field/MonacoQueryFieldLazy.tsx index 2dee83c6e2e..f303f19932a 100644 --- a/public/app/plugins/datasource/prometheus/components/monaco-query-field/MonacoQueryFieldLazy.tsx +++ b/public/app/plugins/datasource/prometheus/components/monaco-query-field/MonacoQueryFieldLazy.tsx @@ -1,4 +1,5 @@ import React, { Suspense } from 'react'; + import { Props } from './MonacoQueryFieldProps'; const Field = React.lazy(() => import(/* webpackChunkName: "prom-query-field" */ './MonacoQueryField')); diff --git a/public/app/plugins/datasource/prometheus/components/monaco-query-field/MonacoQueryFieldProps.ts b/public/app/plugins/datasource/prometheus/components/monaco-query-field/MonacoQueryFieldProps.ts index 9c8f95e4c43..2a54c89d116 100644 --- a/public/app/plugins/datasource/prometheus/components/monaco-query-field/MonacoQueryFieldProps.ts +++ b/public/app/plugins/datasource/prometheus/components/monaco-query-field/MonacoQueryFieldProps.ts @@ -1,6 +1,7 @@ import { HistoryItem } from '@grafana/data'; -import { PromQuery } from '../../types'; + import type PromQlLanguageProvider from '../../language_provider'; +import { PromQuery } from '../../types'; // we need to store this in a separate file, // because we have an async-wrapper around, diff --git a/public/app/plugins/datasource/prometheus/components/monaco-query-field/MonacoQueryFieldWrapper.tsx b/public/app/plugins/datasource/prometheus/components/monaco-query-field/MonacoQueryFieldWrapper.tsx index 398a43ec63a..60295a3a83e 100644 --- a/public/app/plugins/datasource/prometheus/components/monaco-query-field/MonacoQueryFieldWrapper.tsx +++ b/public/app/plugins/datasource/prometheus/components/monaco-query-field/MonacoQueryFieldWrapper.tsx @@ -1,4 +1,5 @@ import React, { useRef } from 'react'; + import { MonacoQueryFieldLazy } from './MonacoQueryFieldLazy'; import { Props as MonacoProps } from './MonacoQueryFieldProps'; diff --git a/public/app/plugins/datasource/prometheus/components/monaco-query-field/monaco-completion-provider/completions.ts b/public/app/plugins/datasource/prometheus/components/monaco-query-field/monaco-completion-provider/completions.ts index 53035523f29..08524be1340 100644 --- a/public/app/plugins/datasource/prometheus/components/monaco-query-field/monaco-completion-provider/completions.ts +++ b/public/app/plugins/datasource/prometheus/components/monaco-query-field/monaco-completion-provider/completions.ts @@ -1,8 +1,9 @@ +import { escapeLabelValueInExactSelector } from '../../../language_utils'; +import { FUNCTIONS } from '../../../promql'; + import type { Situation, Label } from './situation'; import { NeverCaseError } from './util'; // FIXME: we should not load this from the "outside", but we cannot do that while we have the "old" query-field too -import { FUNCTIONS } from '../../../promql'; -import { escapeLabelValueInExactSelector } from '../../../language_utils'; export type CompletionType = 'HISTORY' | 'FUNCTION' | 'METRIC_NAME' | 'DURATION' | 'LABEL_NAME' | 'LABEL_VALUE'; diff --git a/public/app/plugins/datasource/prometheus/components/monaco-query-field/monaco-completion-provider/index.ts b/public/app/plugins/datasource/prometheus/components/monaco-query-field/monaco-completion-provider/index.ts index 3075a9b4570..5f44f77adbf 100644 --- a/public/app/plugins/datasource/prometheus/components/monaco-query-field/monaco-completion-provider/index.ts +++ b/public/app/plugins/datasource/prometheus/components/monaco-query-field/monaco-completion-provider/index.ts @@ -1,7 +1,7 @@ import type { Monaco, monacoTypes } from '@grafana/ui'; -import { getSituation } from './situation'; import { getCompletions, DataProvider, CompletionType } from './completions'; +import { getSituation } from './situation'; import { NeverCaseError } from './util'; export function getSuggestOptions(): monacoTypes.editor.ISuggestOptions { diff --git a/public/app/plugins/datasource/prometheus/components/monaco-query-field/monaco-completion-provider/situation.ts b/public/app/plugins/datasource/prometheus/components/monaco-query-field/monaco-completion-provider/situation.ts index 8b37ca2cd08..4205a0b5945 100644 --- a/public/app/plugins/datasource/prometheus/components/monaco-query-field/monaco-completion-provider/situation.ts +++ b/public/app/plugins/datasource/prometheus/components/monaco-query-field/monaco-completion-provider/situation.ts @@ -1,5 +1,6 @@ -import { parser } from 'lezer-promql'; import type { Tree, SyntaxNode } from '@lezer/common'; +import { parser } from 'lezer-promql'; + import { NeverCaseError } from './util'; type Direction = 'parent' | 'firstChild' | 'lastChild' | 'nextSibling'; diff --git a/public/app/plugins/datasource/prometheus/components/types.ts b/public/app/plugins/datasource/prometheus/components/types.ts index b7bb280cafb..419b86ea5bd 100644 --- a/public/app/plugins/datasource/prometheus/components/types.ts +++ b/public/app/plugins/datasource/prometheus/components/types.ts @@ -1,4 +1,5 @@ import { QueryEditorProps } from '@grafana/data'; + import { PrometheusDatasource } from '../datasource'; import { PromOptions, PromQuery } from '../types'; diff --git a/public/app/plugins/datasource/prometheus/configuration/AzureAuthSettings.tsx b/public/app/plugins/datasource/prometheus/configuration/AzureAuthSettings.tsx index 77246455cd0..1108dff3a9c 100644 --- a/public/app/plugins/datasource/prometheus/configuration/AzureAuthSettings.tsx +++ b/public/app/plugins/datasource/prometheus/configuration/AzureAuthSettings.tsx @@ -1,10 +1,12 @@ import React, { FunctionComponent, useMemo } from 'react'; -import { InlineFormLabel, Input } from '@grafana/ui'; + import { config } from '@grafana/runtime'; +import { InlineFormLabel, Input } from '@grafana/ui'; +import { HttpSettingsBaseProps } from '@grafana/ui/src/components/DataSourceSettings/types'; + import { KnownAzureClouds, AzureCredentials } from './AzureCredentials'; import { getCredentials, updateCredentials } from './AzureCredentialsConfig'; import { AzureCredentialsForm } from './AzureCredentialsForm'; -import { HttpSettingsBaseProps } from '@grafana/ui/src/components/DataSourceSettings/types'; export const AzureAuthSettings: FunctionComponent = (props: HttpSettingsBaseProps) => { const { dataSourceConfig, onChange } = props; diff --git a/public/app/plugins/datasource/prometheus/configuration/AzureCredentialsConfig.ts b/public/app/plugins/datasource/prometheus/configuration/AzureCredentialsConfig.ts index abf91a2ab7f..f48cf44b34d 100644 --- a/public/app/plugins/datasource/prometheus/configuration/AzureCredentialsConfig.ts +++ b/public/app/plugins/datasource/prometheus/configuration/AzureCredentialsConfig.ts @@ -1,5 +1,6 @@ import { DataSourceSettings } from '@grafana/data'; import { config } from '@grafana/runtime'; + import { AzureCloud, AzureCredentials, ConcealedSecret } from './AzureCredentials'; const concealed: ConcealedSecret = Symbol('Concealed client secret'); diff --git a/public/app/plugins/datasource/prometheus/configuration/AzureCredentialsForm.test.tsx b/public/app/plugins/datasource/prometheus/configuration/AzureCredentialsForm.test.tsx index 52a403a246b..4e4a38f4024 100644 --- a/public/app/plugins/datasource/prometheus/configuration/AzureCredentialsForm.test.tsx +++ b/public/app/plugins/datasource/prometheus/configuration/AzureCredentialsForm.test.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { shallow } from 'enzyme'; +import React from 'react'; + import AzureCredentialsForm, { Props } from './AzureCredentialsForm'; const setup = (propsFunc?: (props: Props) => Props) => { diff --git a/public/app/plugins/datasource/prometheus/configuration/AzureCredentialsForm.tsx b/public/app/plugins/datasource/prometheus/configuration/AzureCredentialsForm.tsx index 14db924aa29..9847155a9a6 100644 --- a/public/app/plugins/datasource/prometheus/configuration/AzureCredentialsForm.tsx +++ b/public/app/plugins/datasource/prometheus/configuration/AzureCredentialsForm.tsx @@ -1,8 +1,10 @@ import React, { ChangeEvent, FunctionComponent, useEffect, useReducer, useState } from 'react'; + import { SelectableValue } from '@grafana/data'; import { InlineFormLabel, Button } from '@grafana/ui/src/components'; -import { Select } from '@grafana/ui/src/components/Forms/Legacy/Select/Select'; import { Input } from '@grafana/ui/src/components/Forms/Legacy/Input/Input'; +import { Select } from '@grafana/ui/src/components/Forms/Legacy/Select/Select'; + import { AzureAuthType, AzureCredentials, isCredentialsComplete } from './AzureCredentials'; export interface Props { diff --git a/public/app/plugins/datasource/prometheus/configuration/ConfigEditor.tsx b/public/app/plugins/datasource/prometheus/configuration/ConfigEditor.tsx index 67a396e8bed..1f10fde398f 100644 --- a/public/app/plugins/datasource/prometheus/configuration/ConfigEditor.tsx +++ b/public/app/plugins/datasource/prometheus/configuration/ConfigEditor.tsx @@ -1,13 +1,16 @@ import React from 'react'; -import { AlertingSettings, DataSourceHttpSettings, Alert } from '@grafana/ui'; + import { DataSourcePluginOptionsEditorProps, DataSourceSettings } from '@grafana/data'; +import { AlertingSettings, DataSourceHttpSettings, Alert } from '@grafana/ui'; import { config } from 'app/core/config'; -import { PromOptions } from '../types'; -import { AzureAuthSettings } from './AzureAuthSettings'; -import { PromSettings } from './PromSettings'; -import { hasCredentials, setDefaultCredentials, resetCredentials } from './AzureCredentialsConfig'; import { getAllAlertmanagerDataSources } from 'app/features/alerting/unified/utils/alertmanager'; +import { PromOptions } from '../types'; + +import { AzureAuthSettings } from './AzureAuthSettings'; +import { hasCredentials, setDefaultCredentials, resetCredentials } from './AzureCredentialsConfig'; +import { PromSettings } from './PromSettings'; + export type Props = DataSourcePluginOptionsEditorProps; export const ConfigEditor = (props: Props) => { const { options, onOptionsChange } = props; diff --git a/public/app/plugins/datasource/prometheus/configuration/ExemplarSetting.tsx b/public/app/plugins/datasource/prometheus/configuration/ExemplarSetting.tsx index 34e258fa67c..25836d31c41 100644 --- a/public/app/plugins/datasource/prometheus/configuration/ExemplarSetting.tsx +++ b/public/app/plugins/datasource/prometheus/configuration/ExemplarSetting.tsx @@ -1,8 +1,10 @@ import { css } from '@emotion/css'; +import React, { useState } from 'react'; + import { selectors } from '@grafana/e2e-selectors'; import { DataSourcePicker } from '@grafana/runtime'; import { Button, InlineField, InlineSwitch, Input } from '@grafana/ui'; -import React, { useState } from 'react'; + import { ExemplarTraceIdDestination } from '../types'; type Props = { diff --git a/public/app/plugins/datasource/prometheus/configuration/ExemplarsSettings.tsx b/public/app/plugins/datasource/prometheus/configuration/ExemplarsSettings.tsx index d31b64e9435..3fbd5a7a154 100644 --- a/public/app/plugins/datasource/prometheus/configuration/ExemplarsSettings.tsx +++ b/public/app/plugins/datasource/prometheus/configuration/ExemplarsSettings.tsx @@ -1,8 +1,11 @@ import { css } from '@emotion/css'; +import React from 'react'; + import { selectors } from '@grafana/e2e-selectors'; import { Button } from '@grafana/ui'; -import React from 'react'; + import { ExemplarTraceIdDestination } from '../types'; + import ExemplarSetting from './ExemplarSetting'; type Props = { diff --git a/public/app/plugins/datasource/prometheus/configuration/PromSettings.test.tsx b/public/app/plugins/datasource/prometheus/configuration/PromSettings.test.tsx index 9cdd0fd8084..0cb1cb7bfab 100644 --- a/public/app/plugins/datasource/prometheus/configuration/PromSettings.test.tsx +++ b/public/app/plugins/datasource/prometheus/configuration/PromSettings.test.tsx @@ -1,7 +1,9 @@ -import React, { SyntheticEvent } from 'react'; import { render, screen } from '@testing-library/react'; -import { EventsWithValidation } from '@grafana/ui'; +import React, { SyntheticEvent } from 'react'; + import { SelectableValue } from '@grafana/data'; +import { EventsWithValidation } from '@grafana/ui'; + import { getValueFromEventItem, promSettingsValidationEvents, PromSettings } from './PromSettings'; import { createDefaultConfigOptions } from './mocks'; diff --git a/public/app/plugins/datasource/prometheus/configuration/PromSettings.tsx b/public/app/plugins/datasource/prometheus/configuration/PromSettings.tsx index 2d2a99d83ad..c04f8e74cdf 100644 --- a/public/app/plugins/datasource/prometheus/configuration/PromSettings.tsx +++ b/public/app/plugins/datasource/prometheus/configuration/PromSettings.tsx @@ -1,3 +1,5 @@ +import React, { SyntheticEvent } from 'react'; + import { DataSourcePluginOptionsEditorProps, onUpdateDatasourceJsonDataOptionChecked, @@ -5,8 +7,9 @@ import { updateDatasourcePluginJsonDataOption, } from '@grafana/data'; import { EventsWithValidation, InlineFormLabel, LegacyForms, regexValidation } from '@grafana/ui'; -import React, { SyntheticEvent } from 'react'; + import { PromOptions } from '../types'; + import { ExemplarsSettings } from './ExemplarsSettings'; const { Select, Input, FormField, Switch } = LegacyForms; diff --git a/public/app/plugins/datasource/prometheus/configuration/mocks.ts b/public/app/plugins/datasource/prometheus/configuration/mocks.ts index 76d9a61fa24..d741c1fe11e 100644 --- a/public/app/plugins/datasource/prometheus/configuration/mocks.ts +++ b/public/app/plugins/datasource/prometheus/configuration/mocks.ts @@ -1,6 +1,7 @@ import { DataSourceSettings } from '@grafana/data'; -import { PromOptions } from '../types'; + import { createDatasourceSettings } from '../../../../features/datasources/mocks'; +import { PromOptions } from '../types'; export function createDefaultConfigOptions(): DataSourceSettings { return createDatasourceSettings({ diff --git a/public/app/plugins/datasource/prometheus/datasource.test.ts b/public/app/plugins/datasource/prometheus/datasource.test.ts index 4d79fb5527f..6da512d0faa 100644 --- a/public/app/plugins/datasource/prometheus/datasource.test.ts +++ b/public/app/plugins/datasource/prometheus/datasource.test.ts @@ -1,5 +1,6 @@ import { cloneDeep } from 'lodash'; import { of, throwError } from 'rxjs'; + import { CoreApp, DataQueryRequest, @@ -11,6 +12,10 @@ import { LoadingState, toDataFrame, } from '@grafana/data'; +import { QueryOptions } from 'app/types'; + +import { describe } from '../../../../test/lib/common'; +import { VariableHide } from '../../../features/variables/types'; import { alignRange, @@ -20,9 +25,6 @@ import { prometheusSpecialRegexEscape, } from './datasource'; import { PromOptions, PromQuery } from './types'; -import { VariableHide } from '../../../features/variables/types'; -import { describe } from '../../../../test/lib/common'; -import { QueryOptions } from 'app/types'; const fetchMock = jest.fn().mockReturnValue(of(createDefaultPromResponse())); diff --git a/public/app/plugins/datasource/prometheus/datasource.tsx b/public/app/plugins/datasource/prometheus/datasource.tsx index 307684109c0..b0a9b914beb 100644 --- a/public/app/plugins/datasource/prometheus/datasource.tsx +++ b/public/app/plugins/datasource/prometheus/datasource.tsx @@ -1,8 +1,9 @@ -import React from 'react'; import { cloneDeep, defaults } from 'lodash'; +import LRU from 'lru-cache'; +import React from 'react'; import { forkJoin, lastValueFrom, merge, Observable, of, OperatorFunction, pipe, throwError } from 'rxjs'; import { catchError, filter, map, tap } from 'rxjs/operators'; -import LRU from 'lru-cache'; + import { AnnotationEvent, CoreApp, @@ -31,13 +32,18 @@ import { BackendDataSourceResponse, toDataQueryResponse, } from '@grafana/runtime'; - +import { Badge, BadgeColor, Tooltip } from '@grafana/ui'; import { safeStringifyValue } from 'app/core/utils/explore'; +import { fetchDataSourceBuildInfo } from 'app/features/alerting/unified/api/buildInfo'; import { getTimeSrv, TimeSrv } from 'app/features/dashboard/services/TimeSrv'; import { getTemplateSrv, TemplateSrv } from 'app/features/templating/template_srv'; +import { PromApplication, PromBuildInfo } from 'app/types/unified-alerting-dto'; + import { addLabelToQuery } from './add_label_to_query'; import PrometheusLanguageProvider from './language_provider'; import { expandRecordingRules } from './language_utils'; +import { renderLegendFormat } from './legend'; +import PrometheusMetricFindQuery from './metric_find_query'; import { getInitHints, getQueryHints } from './query_hints'; import { getOriginalMetricName, transform, transformV2 } from './result_transformer'; import { @@ -54,11 +60,6 @@ import { PromVectorData, } from './types'; import { PrometheusVariableSupport } from './variables'; -import PrometheusMetricFindQuery from './metric_find_query'; -import { renderLegendFormat } from './legend'; -import { fetchDataSourceBuildInfo } from 'app/features/alerting/unified/api/buildInfo'; -import { PromApplication, PromBuildInfo } from 'app/types/unified-alerting-dto'; -import { Badge, BadgeColor, Tooltip } from '@grafana/ui'; export const ANNOTATION_QUERY_STEP_DEFAULT = '60s'; const GET_AND_POST_METADATA_ENDPOINTS = ['api/v1/query', 'api/v1/query_range', 'api/v1/series', 'api/v1/labels']; diff --git a/public/app/plugins/datasource/prometheus/language_provider.test.ts b/public/app/plugins/datasource/prometheus/language_provider.test.ts index a9adfcd8950..258ebc1802f 100644 --- a/public/app/plugins/datasource/prometheus/language_provider.test.ts +++ b/public/app/plugins/datasource/prometheus/language_provider.test.ts @@ -1,12 +1,15 @@ -import Plain from 'slate-plain-serializer'; import { Editor as SlateEditor } from 'slate'; -import LanguageProvider from './language_provider'; -import { PrometheusDatasource } from './datasource'; +import Plain from 'slate-plain-serializer'; + import { AbstractLabelOperator, HistoryItem } from '@grafana/data'; -import { PromQuery } from './types'; -import Mock = jest.Mock; import { SearchFunctionType } from '@grafana/ui'; +import { PrometheusDatasource } from './datasource'; +import LanguageProvider from './language_provider'; +import { PromQuery } from './types'; + +import Mock = jest.Mock; + describe('Language completion provider', () => { const datasource: PrometheusDatasource = { metadataRequest: () => ({ data: { data: [] as any[] } }), diff --git a/public/app/plugins/datasource/prometheus/language_provider.ts b/public/app/plugins/datasource/prometheus/language_provider.ts index 599aec95224..66bf546a016 100644 --- a/public/app/plugins/datasource/prometheus/language_provider.ts +++ b/public/app/plugins/datasource/prometheus/language_provider.ts @@ -1,7 +1,7 @@ import { once, chain, difference } from 'lodash'; import LRU from 'lru-cache'; -import { Value } from 'slate'; import Prism from 'prismjs'; +import { Value } from 'slate'; import { AbstractLabelMatcher, @@ -13,6 +13,7 @@ import { } from '@grafana/data'; import { CompletionItem, CompletionItemGroup, SearchFunctionType, TypeaheadInput, TypeaheadOutput } from '@grafana/ui'; +import { PrometheusDatasource } from './datasource'; import { addLimitInfo, extractLabelMatchers, @@ -24,8 +25,6 @@ import { toPromLikeQuery, } from './language_utils'; import PromqlSyntax, { FUNCTIONS, RATE_RANGES } from './promql'; - -import { PrometheusDatasource } from './datasource'; import { PromMetricsMetadata, PromQuery } from './types'; const DEFAULT_KEYS = ['job', 'instance']; diff --git a/public/app/plugins/datasource/prometheus/language_utils.test.ts b/public/app/plugins/datasource/prometheus/language_utils.test.ts index d824947ac8b..5066ef72169 100644 --- a/public/app/plugins/datasource/prometheus/language_utils.test.ts +++ b/public/app/plugins/datasource/prometheus/language_utils.test.ts @@ -1,4 +1,5 @@ import { AbstractLabelOperator, AbstractQuery } from '@grafana/data'; + import { escapeLabelValueInExactSelector, escapeLabelValueInRegexSelector, diff --git a/public/app/plugins/datasource/prometheus/language_utils.ts b/public/app/plugins/datasource/prometheus/language_utils.ts index fac108a8b4e..978866163f7 100644 --- a/public/app/plugins/datasource/prometheus/language_utils.ts +++ b/public/app/plugins/datasource/prometheus/language_utils.ts @@ -1,9 +1,11 @@ -import { PromMetricsMetadata, PromMetricsMetadataItem } from './types'; +import { invert } from 'lodash'; +import { Token } from 'prismjs'; + +import { DataQuery, AbstractQuery, AbstractLabelOperator, AbstractLabelMatcher } from '@grafana/data'; + import { addLabelToQuery } from './add_label_to_query'; import { SUGGESTIONS_LIMIT } from './language_provider'; -import { DataQuery, AbstractQuery, AbstractLabelOperator, AbstractLabelMatcher } from '@grafana/data'; -import { Token } from 'prismjs'; -import { invert } from 'lodash'; +import { PromMetricsMetadata, PromMetricsMetadataItem } from './types'; export const processHistogramMetrics = (metrics: string[]) => { const resultSet: Set = new Set(); diff --git a/public/app/plugins/datasource/prometheus/metric_find_query.test.ts b/public/app/plugins/datasource/prometheus/metric_find_query.test.ts index 6573269cbd4..c13a538f9c6 100644 --- a/public/app/plugins/datasource/prometheus/metric_find_query.test.ts +++ b/public/app/plugins/datasource/prometheus/metric_find_query.test.ts @@ -1,12 +1,13 @@ import 'whatwg-fetch'; // fetch polyfill needed backendSrv import { of } from 'rxjs'; + import { DataSourceInstanceSettings, toUtc } from '@grafana/data'; +import { FetchResponse } from '@grafana/runtime'; +import { backendSrv } from 'app/core/services/backend_srv'; // will use the version in __mocks__ import { PrometheusDatasource } from './datasource'; import PrometheusMetricFindQuery from './metric_find_query'; -import { backendSrv } from 'app/core/services/backend_srv'; // will use the version in __mocks__ import { PromOptions } from './types'; -import { FetchResponse } from '@grafana/runtime'; jest.mock('@grafana/runtime', () => ({ ...(jest.requireActual('@grafana/runtime') as unknown as object), diff --git a/public/app/plugins/datasource/prometheus/metric_find_query.ts b/public/app/plugins/datasource/prometheus/metric_find_query.ts index 2ef7b7e2b09..87c900d002e 100644 --- a/public/app/plugins/datasource/prometheus/metric_find_query.ts +++ b/public/app/plugins/datasource/prometheus/metric_find_query.ts @@ -1,11 +1,12 @@ import { chain, map as _map, uniq } from 'lodash'; import { lastValueFrom } from 'rxjs'; import { map } from 'rxjs/operators'; + import { MetricFindValue, TimeRange } from '@grafana/data'; +import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv'; import { PrometheusDatasource } from './datasource'; import { PromQueryRequest } from './types'; -import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv'; export default class PrometheusMetricFindQuery { range: TimeRange; diff --git a/public/app/plugins/datasource/prometheus/module.test.ts b/public/app/plugins/datasource/prometheus/module.test.ts index 2b0473a3791..af031a9ee84 100644 --- a/public/app/plugins/datasource/prometheus/module.test.ts +++ b/public/app/plugins/datasource/prometheus/module.test.ts @@ -1,5 +1,5 @@ -import { plugin as PrometheusDatasourcePlugin } from './module'; import { ANNOTATION_QUERY_STEP_DEFAULT } from './datasource'; +import { plugin as PrometheusDatasourcePlugin } from './module'; describe('module', () => { it('should have metrics query field in panels and Explore', () => { diff --git a/public/app/plugins/datasource/prometheus/module.ts b/public/app/plugins/datasource/prometheus/module.ts index f570f7c5150..06c047eeaf2 100644 --- a/public/app/plugins/datasource/prometheus/module.ts +++ b/public/app/plugins/datasource/prometheus/module.ts @@ -1,10 +1,9 @@ import { DataSourcePlugin } from '@grafana/data'; -import { ANNOTATION_QUERY_STEP_DEFAULT, PrometheusDatasource } from './datasource'; -import PromQueryEditorByApp from './components/PromQueryEditorByApp'; import PromCheatSheet from './components/PromCheatSheet'; - +import PromQueryEditorByApp from './components/PromQueryEditorByApp'; import { ConfigEditor } from './configuration/ConfigEditor'; +import { ANNOTATION_QUERY_STEP_DEFAULT, PrometheusDatasource } from './datasource'; class PrometheusAnnotationsQueryCtrl { static templateUrl = 'partials/annotations.editor.html'; diff --git a/public/app/plugins/datasource/prometheus/promql.test.ts b/public/app/plugins/datasource/prometheus/promql.test.ts index 2b0cc20fd1e..ff78a805ef2 100644 --- a/public/app/plugins/datasource/prometheus/promql.test.ts +++ b/public/app/plugins/datasource/prometheus/promql.test.ts @@ -1,6 +1,7 @@ -import promql from './promql'; import Prism from 'prismjs'; +import promql from './promql'; + describe('Loki syntax', () => { it('should highlight Loki query correctly', () => { expect(Prism.highlight('{key="val#ue"}', promql, 'promql')).toBe( diff --git a/public/app/plugins/datasource/prometheus/promql.ts b/public/app/plugins/datasource/prometheus/promql.ts index 48bc2361ff7..7d0f2134819 100644 --- a/public/app/plugins/datasource/prometheus/promql.ts +++ b/public/app/plugins/datasource/prometheus/promql.ts @@ -1,4 +1,5 @@ import { Grammar } from 'prismjs'; + import { CompletionItem } from '@grafana/ui'; // When changing RATE_RANGES, check if Loki/LogQL ranges should be changed too diff --git a/public/app/plugins/datasource/prometheus/query_hints.test.ts b/public/app/plugins/datasource/prometheus/query_hints.test.ts index 66b97fa7d33..9f48bb3fa1b 100644 --- a/public/app/plugins/datasource/prometheus/query_hints.test.ts +++ b/public/app/plugins/datasource/prometheus/query_hints.test.ts @@ -1,5 +1,5 @@ -import { getQueryHints, SUM_HINT_THRESHOLD_COUNT } from './query_hints'; import { PrometheusDatasource } from './datasource'; +import { getQueryHints, SUM_HINT_THRESHOLD_COUNT } from './query_hints'; describe('getQueryHints()', () => { it('returns no hints for no series', () => { diff --git a/public/app/plugins/datasource/prometheus/query_hints.ts b/public/app/plugins/datasource/prometheus/query_hints.ts index 50bb918b958..0b6be60ed99 100644 --- a/public/app/plugins/datasource/prometheus/query_hints.ts +++ b/public/app/plugins/datasource/prometheus/query_hints.ts @@ -1,5 +1,7 @@ import { size } from 'lodash'; + import { QueryHint, QueryFix } from '@grafana/data'; + import { PrometheusDatasource } from './datasource'; /** diff --git a/public/app/plugins/datasource/prometheus/querybuilder/PromQueryModeller.ts b/public/app/plugins/datasource/prometheus/querybuilder/PromQueryModeller.ts index 558e7e52a15..b205620ea76 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/PromQueryModeller.ts +++ b/public/app/plugins/datasource/prometheus/querybuilder/PromQueryModeller.ts @@ -1,4 +1,5 @@ import { FUNCTIONS } from '../promql'; + import { getAggregationOperations } from './aggregations'; import { getOperationDefinitions } from './operations'; import { LokiAndPromQueryModellerBase } from './shared/LokiAndPromQueryModellerBase'; diff --git a/public/app/plugins/datasource/prometheus/querybuilder/binaryScalarOperations.ts b/public/app/plugins/datasource/prometheus/querybuilder/binaryScalarOperations.ts index 6a7876f7432..49b87f6fb53 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/binaryScalarOperations.ts +++ b/public/app/plugins/datasource/prometheus/querybuilder/binaryScalarOperations.ts @@ -1,6 +1,6 @@ +import { defaultAddOperationHandler } from './shared/operationUtils'; import { QueryBuilderOperation, QueryBuilderOperationDef, QueryBuilderOperationParamDef } from './shared/types'; import { PromOperationId, PromVisualQueryOperationCategory } from './types'; -import { defaultAddOperationHandler } from './shared/operationUtils'; export const binaryScalarDefs = [ { @@ -71,6 +71,14 @@ export const binaryScalarDefs = [ }, ]; +export const binaryScalarOperatorToOperatorName = binaryScalarDefs.reduce((acc, def) => { + acc[def.sign] = { + id: def.id, + comparison: def.comparison, + }; + return acc; +}, {} as Record); + // Not sure about this one. It could also be a more generic 'Simple math operation' where user specifies // both the operator and the operand in a single input export const binaryScalarOperations: QueryBuilderOperationDef[] = binaryScalarDefs.map((opDef) => { diff --git a/public/app/plugins/datasource/prometheus/querybuilder/components/LabelParamEditor.tsx b/public/app/plugins/datasource/prometheus/querybuilder/components/LabelParamEditor.tsx index a12886c7b52..dad000f4a87 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/components/LabelParamEditor.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/components/LabelParamEditor.tsx @@ -1,6 +1,8 @@ +import React, { useState } from 'react'; + import { DataSourceApi, SelectableValue, toOption } from '@grafana/data'; import { Select } from '@grafana/ui'; -import React, { useState } from 'react'; + import { PrometheusDatasource } from '../../datasource'; import { promQueryModeller } from '../PromQueryModeller'; import { getOperationParamId } from '../shared/operationUtils'; diff --git a/public/app/plugins/datasource/prometheus/querybuilder/components/MetricSelect.test.tsx b/public/app/plugins/datasource/prometheus/querybuilder/components/MetricSelect.test.tsx index 6ae33d440fe..ce7c12f35fd 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/components/MetricSelect.test.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/components/MetricSelect.test.tsx @@ -1,6 +1,7 @@ -import React from 'react'; import { render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import React from 'react'; + import { MetricSelect } from './MetricSelect'; const props = { diff --git a/public/app/plugins/datasource/prometheus/querybuilder/components/MetricSelect.tsx b/public/app/plugins/datasource/prometheus/querybuilder/components/MetricSelect.tsx index 86e7b676686..671a2c95d93 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/components/MetricSelect.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/components/MetricSelect.tsx @@ -1,10 +1,13 @@ -import { Select, FormatOptionLabelMeta, useStyles2 } from '@grafana/ui'; +import { css } from '@emotion/css'; import React, { useCallback, useState } from 'react'; -import { PromVisualQuery } from '../types'; +// @ts-ignore +import Highlighter from 'react-highlight-words'; + import { SelectableValue, toOption, GrafanaTheme2 } from '@grafana/data'; import { EditorField, EditorFieldGroup } from '@grafana/experimental'; -import { css } from '@emotion/css'; -import Highlighter from 'react-highlight-words'; +import { Select, FormatOptionLabelMeta, useStyles2 } from '@grafana/ui'; + +import { PromVisualQuery } from '../types'; // We are matching words split with space const splitSeparator = ' '; diff --git a/public/app/plugins/datasource/prometheus/querybuilder/components/NestedQuery.tsx b/public/app/plugins/datasource/prometheus/querybuilder/components/NestedQuery.tsx index 5c1780ad76f..80034621982 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/components/NestedQuery.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/components/NestedQuery.tsx @@ -1,13 +1,16 @@ import { css } from '@emotion/css'; +import React from 'react'; + import { GrafanaTheme2, toOption } from '@grafana/data'; import { EditorRows, FlexItem } from '@grafana/experimental'; import { IconButton, Select, useStyles2 } from '@grafana/ui'; -import React from 'react'; + import { PrometheusDatasource } from '../../datasource'; +import { binaryScalarDefs } from '../binaryScalarOperations'; import { AutoSizeInput } from '../shared/AutoSizeInput'; import { PromVisualQueryBinary } from '../types'; + import { PromQueryBuilder } from './PromQueryBuilder'; -import { binaryScalarDefs } from '../binaryScalarOperations'; export interface Props { nestedQuery: PromVisualQueryBinary; diff --git a/public/app/plugins/datasource/prometheus/querybuilder/components/NestedQueryList.tsx b/public/app/plugins/datasource/prometheus/querybuilder/components/NestedQueryList.tsx index dad37b8f1b3..ada41ecbaa0 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/components/NestedQueryList.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/components/NestedQueryList.tsx @@ -1,7 +1,10 @@ -import { Stack } from '@grafana/experimental'; import React from 'react'; + +import { Stack } from '@grafana/experimental'; + import { PrometheusDatasource } from '../../datasource'; import { PromVisualQuery, PromVisualQueryBinary } from '../types'; + import { NestedQuery } from './NestedQuery'; export interface Props { diff --git a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilder.test.tsx b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilder.test.tsx index ec4b47beade..d12b99b8193 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilder.test.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilder.test.tsx @@ -1,14 +1,17 @@ -import React from 'react'; import { render, screen, getByText, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { PromQueryBuilder } from './PromQueryBuilder'; -import { PrometheusDatasource } from '../../datasource'; -import { EmptyLanguageProviderMock } from '../../language_provider.mock'; -import PromQlLanguageProvider from '../../language_provider'; -import { PromVisualQuery } from '../types'; -import { getLabelSelects } from '../testUtils'; +import React from 'react'; + import { LoadingState, MutableDataFrame, PanelData, TimeRange } from '@grafana/data'; +import { PrometheusDatasource } from '../../datasource'; +import PromQlLanguageProvider from '../../language_provider'; +import { EmptyLanguageProviderMock } from '../../language_provider.mock'; +import { getLabelSelects } from '../testUtils'; +import { PromVisualQuery } from '../types'; + +import { PromQueryBuilder } from './PromQueryBuilder'; + const defaultQuery: PromVisualQuery = { metric: 'random_metric', labels: [], diff --git a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilder.tsx b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilder.tsx index 0b4504e7dc6..3fba042d304 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilder.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilder.tsx @@ -1,17 +1,20 @@ import React, { useCallback } from 'react'; -import { MetricSelect } from './MetricSelect'; -import { PromVisualQuery } from '../types'; + +import { DataSourceApi, PanelData, SelectableValue } from '@grafana/data'; +import { EditorRow } from '@grafana/experimental'; + +import { PrometheusDatasource } from '../../datasource'; +import { getMetadataString } from '../../language_provider'; +import { promQueryModeller } from '../PromQueryModeller'; import { LabelFilters } from '../shared/LabelFilters'; import { OperationList } from '../shared/OperationList'; -import { EditorRow } from '@grafana/experimental'; -import { PrometheusDatasource } from '../../datasource'; -import { NestedQueryList } from './NestedQueryList'; -import { promQueryModeller } from '../PromQueryModeller'; -import { QueryBuilderLabelFilter } from '../shared/types'; -import { DataSourceApi, PanelData, SelectableValue } from '@grafana/data'; import { OperationsEditorRow } from '../shared/OperationsEditorRow'; +import { QueryBuilderLabelFilter } from '../shared/types'; +import { PromVisualQuery } from '../types'; + +import { MetricSelect } from './MetricSelect'; +import { NestedQueryList } from './NestedQueryList'; import { PromQueryBuilderHints } from './PromQueryBuilderHints'; -import { getMetadataString } from '../../language_provider'; export interface Props { query: PromVisualQuery; diff --git a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilderContainer.test.tsx b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilderContainer.test.tsx index 09c75180021..341308e2e37 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilderContainer.test.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilderContainer.test.tsx @@ -1,14 +1,16 @@ -import React from 'react'; import { render, screen, waitFor } from '@testing-library/react'; -import { PromQueryBuilderContainer } from './PromQueryBuilderContainer'; -import { PrometheusDatasource } from '../../datasource'; -import { EmptyLanguageProviderMock } from '../../language_provider.mock'; -import PromQlLanguageProvider from '../../language_provider'; -import { addOperation } from '../shared/OperationList.testUtils'; -import { PromQuery } from '../../types'; import userEvent from '@testing-library/user-event'; +import React from 'react'; + +import { PrometheusDatasource } from '../../datasource'; +import PromQlLanguageProvider from '../../language_provider'; +import { EmptyLanguageProviderMock } from '../../language_provider.mock'; +import { PromQuery } from '../../types'; +import { addOperation } from '../shared/OperationList.testUtils'; import { getOperationParamId } from '../shared/operationUtils'; +import { PromQueryBuilderContainer } from './PromQueryBuilderContainer'; + describe('PromQueryBuilderContainer', () => { it('translates query between string and model', async () => { const { props } = setup({ expr: 'rate(metric_test{job="testjob"}[$__rate_interval])' }); diff --git a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilderContainer.tsx b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilderContainer.tsx index 5a46feaa0ac..d7cc0ab0a32 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilderContainer.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilderContainer.tsx @@ -1,12 +1,14 @@ -import { PanelData } from '@grafana/data'; import { createSlice, PayloadAction } from '@reduxjs/toolkit'; import React, { useEffect, useReducer } from 'react'; +import { PanelData } from '@grafana/data'; + import { PrometheusDatasource } from '../../datasource'; import { PromQuery } from '../../types'; -import { buildVisualQueryFromString } from '../parsing'; import { promQueryModeller } from '../PromQueryModeller'; +import { buildVisualQueryFromString } from '../parsing'; import { PromVisualQuery } from '../types'; + import { PromQueryBuilder } from './PromQueryBuilder'; import { QueryPreview } from './QueryPreview'; diff --git a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilderExplained.tsx b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilderExplained.tsx index ad50f64a1ce..422f4b3b231 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilderExplained.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilderExplained.tsx @@ -1,10 +1,12 @@ import React from 'react'; -import { PromVisualQuery } from '../types'; + import { Stack } from '@grafana/experimental'; + import { promQueryModeller } from '../PromQueryModeller'; -import { OperationListExplained } from '../shared/OperationListExplained'; -import { OperationExplainedBox } from '../shared/OperationExplainedBox'; import { buildVisualQueryFromString } from '../parsing'; +import { OperationExplainedBox } from '../shared/OperationExplainedBox'; +import { OperationListExplained } from '../shared/OperationListExplained'; +import { PromVisualQuery } from '../types'; export interface Props { query: string; diff --git a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilderHints.tsx b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilderHints.tsx index 7fe177d6ab1..404e4ed8818 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilderHints.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilderHints.tsx @@ -1,11 +1,13 @@ +import { css } from '@emotion/css'; import React, { useState, useEffect } from 'react'; -import { PromVisualQuery } from '../types'; + +import { GrafanaTheme2, PanelData, QueryHint } from '@grafana/data'; +import { Button, Tooltip, useStyles2 } from '@grafana/ui'; + import { PrometheusDatasource } from '../../datasource'; import { promQueryModeller } from '../PromQueryModeller'; -import { GrafanaTheme2, PanelData, QueryHint } from '@grafana/data'; import { buildVisualQueryFromString } from '../parsing'; -import { Button, Tooltip, useStyles2 } from '@grafana/ui'; -import { css } from '@emotion/css'; +import { PromVisualQuery } from '../types'; export interface Props { query: PromVisualQuery; diff --git a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilderOptions.test.tsx b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilderOptions.test.tsx index dcc03f3e4aa..a4df0c00284 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilderOptions.test.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilderOptions.test.tsx @@ -1,10 +1,13 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; +import React from 'react'; + +import { CoreApp } from '@grafana/data'; +import { selectOptionInTest } from '@grafana/ui'; + import { PromQuery } from '../../types'; import { getQueryWithDefaults } from '../state'; -import { CoreApp } from '@grafana/data'; + import { PromQueryBuilderOptions } from './PromQueryBuilderOptions'; -import { selectOptionInTest } from '@grafana/ui'; describe('PromQueryBuilderOptions', () => { it('Can change query type', async () => { diff --git a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilderOptions.tsx b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilderOptions.tsx index 74d1067fedb..f4a6b0f141c 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilderOptions.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilderOptions.tsx @@ -1,13 +1,16 @@ import React, { SyntheticEvent } from 'react'; -import { EditorRow, EditorField } from '@grafana/experimental'; + import { CoreApp, SelectableValue } from '@grafana/data'; +import { EditorRow, EditorField } from '@grafana/experimental'; import { RadioButtonGroup, Select, Switch } from '@grafana/ui'; -import { QueryOptionGroup } from '../shared/QueryOptionGroup'; -import { PromQuery } from '../../types'; -import { FORMAT_OPTIONS, INTERVAL_FACTOR_OPTIONS } from '../../components/PromQueryEditor'; + import { getQueryTypeChangeHandler, getQueryTypeOptions } from '../../components/PromExploreExtraField'; -import { getLegendModeLabel, PromQueryLegendEditor } from './PromQueryLegendEditor'; +import { FORMAT_OPTIONS, INTERVAL_FACTOR_OPTIONS } from '../../components/PromQueryEditor'; +import { PromQuery } from '../../types'; import { AutoSizeInput } from '../shared/AutoSizeInput'; +import { QueryOptionGroup } from '../shared/QueryOptionGroup'; + +import { getLegendModeLabel, PromQueryLegendEditor } from './PromQueryLegendEditor'; export interface Props { query: PromQuery; diff --git a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryCodeEditor.tsx b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryCodeEditor.tsx index 7ab11a6c11e..f4138dcf48a 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryCodeEditor.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryCodeEditor.tsx @@ -1,10 +1,12 @@ -import React from 'react'; -import { PromQueryEditorProps } from '../../components/types'; -import PromQueryField from '../../components/PromQueryField'; -import { testIds } from '../../components/PromQueryEditor'; -import { useStyles2 } from '@grafana/ui'; import { css } from '@emotion/css'; +import React from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; +import { useStyles2 } from '@grafana/ui'; + +import { testIds } from '../../components/PromQueryEditor'; +import PromQueryField from '../../components/PromQueryField'; +import { PromQueryEditorProps } from '../../components/types'; export function PromQueryCodeEditor({ query, diff --git a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryEditorSelector.test.tsx b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryEditorSelector.test.tsx index e754eafebbd..73c5613b1db 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryEditorSelector.test.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryEditorSelector.test.tsx @@ -1,13 +1,15 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { PromQueryEditorSelector } from './PromQueryEditorSelector'; -import { PrometheusDatasource } from '../../datasource'; -import { QueryEditorMode } from '../shared/types'; -import { EmptyLanguageProviderMock } from '../../language_provider.mock'; -import PromQlLanguageProvider from '../../language_provider'; import { cloneDeep, defaultsDeep } from 'lodash'; +import React from 'react'; + +import { PrometheusDatasource } from '../../datasource'; +import PromQlLanguageProvider from '../../language_provider'; +import { EmptyLanguageProviderMock } from '../../language_provider.mock'; import { PromQuery } from '../../types'; +import { QueryEditorMode } from '../shared/types'; + +import { PromQueryEditorSelector } from './PromQueryEditorSelector'; // We need to mock this because it seems jest has problem importing monaco in tests jest.mock('../../components/monaco-query-field/MonacoQueryFieldWrapper', () => { diff --git a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryEditorSelector.tsx b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryEditorSelector.tsx index 7261e2d8ae4..754c0b6c455 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryEditorSelector.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryEditorSelector.tsx @@ -1,21 +1,24 @@ import React, { SyntheticEvent, useCallback, useEffect, useState } from 'react'; + import { LoadingState } from '@grafana/data'; -import { reportInteraction } from '@grafana/runtime'; import { EditorHeader, EditorRows, FlexItem, InlineSelect, Space } from '@grafana/experimental'; +import { reportInteraction } from '@grafana/runtime'; import { Button, ConfirmModal } from '@grafana/ui'; + import { PromQueryEditorProps } from '../../components/types'; +import { PromQuery } from '../../types'; import { promQueryModeller } from '../PromQueryModeller'; +import { buildVisualQueryFromString } from '../parsing'; +import { FeedbackLink } from '../shared/FeedbackLink'; import { QueryEditorModeToggle } from '../shared/QueryEditorModeToggle'; import { QueryHeaderSwitch } from '../shared/QueryHeaderSwitch'; import { QueryEditorMode } from '../shared/types'; -import { PromQueryBuilderExplained } from './PromQueryBuilderExplained'; -import { buildVisualQueryFromString } from '../parsing'; -import { PromQueryCodeEditor } from './PromQueryCodeEditor'; -import { PromQueryBuilderContainer } from './PromQueryBuilderContainer'; -import { PromQueryBuilderOptions } from './PromQueryBuilderOptions'; import { changeEditorMode, getQueryWithDefaults } from '../state'; -import { PromQuery } from '../../types'; -import { FeedbackLink } from '../shared/FeedbackLink'; + +import { PromQueryBuilderContainer } from './PromQueryBuilderContainer'; +import { PromQueryBuilderExplained } from './PromQueryBuilderExplained'; +import { PromQueryBuilderOptions } from './PromQueryBuilderOptions'; +import { PromQueryCodeEditor } from './PromQueryCodeEditor'; export const PromQueryEditorSelector = React.memo((props) => { const { onChange, onRunQuery, data, app } = props; diff --git a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryLegendEditor.tsx b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryLegendEditor.tsx index 737248f61a8..3d4e512d86f 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryLegendEditor.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryLegendEditor.tsx @@ -1,7 +1,9 @@ import React, { useRef } from 'react'; -import { EditorField } from '@grafana/experimental'; + import { SelectableValue } from '@grafana/data'; +import { EditorField } from '@grafana/experimental'; import { Select } from '@grafana/ui'; + import { LegendFormatMode } from '../../types'; import { AutoSizeInput } from '../shared/AutoSizeInput'; diff --git a/public/app/plugins/datasource/prometheus/querybuilder/components/QueryPreview.tsx b/public/app/plugins/datasource/prometheus/querybuilder/components/QueryPreview.tsx index cd7a267e542..7ff6bfcb9f4 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/components/QueryPreview.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/components/QueryPreview.tsx @@ -1,9 +1,11 @@ -import React from 'react'; -import { useTheme2 } from '@grafana/ui'; -import { GrafanaTheme2 } from '@grafana/data'; import { css, cx } from '@emotion/css'; -import { EditorField, EditorFieldGroup, EditorRow } from '@grafana/experimental'; import Prism from 'prismjs'; +import React from 'react'; + +import { GrafanaTheme2 } from '@grafana/data'; +import { EditorField, EditorFieldGroup, EditorRow } from '@grafana/experimental'; +import { useTheme2 } from '@grafana/ui'; + import { promqlGrammar } from '../../promql'; export interface Props { diff --git a/public/app/plugins/datasource/prometheus/querybuilder/operations.ts b/public/app/plugins/datasource/prometheus/querybuilder/operations.ts index 77d207b38d5..5be37ffbb47 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/operations.ts +++ b/public/app/plugins/datasource/prometheus/querybuilder/operations.ts @@ -1,3 +1,4 @@ +import { binaryScalarOperations } from './binaryScalarOperations'; import { LabelParamEditor } from './components/LabelParamEditor'; import { defaultAddOperationHandler, @@ -15,7 +16,6 @@ import { VisualQueryModeller, } from './shared/types'; import { PromOperationId, PromVisualQuery, PromVisualQueryOperationCategory } from './types'; -import { binaryScalarOperations } from './binaryScalarOperations'; export function getOperationDefinitions(): QueryBuilderOperationDef[] { const list: QueryBuilderOperationDef[] = [ diff --git a/public/app/plugins/datasource/prometheus/querybuilder/parsing.ts b/public/app/plugins/datasource/prometheus/querybuilder/parsing.ts index 0db7f39daed..03b0a72c556 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/parsing.ts +++ b/public/app/plugins/datasource/prometheus/querybuilder/parsing.ts @@ -1,8 +1,7 @@ -import { parser } from 'lezer-promql'; import { SyntaxNode } from '@lezer/common'; -import { QueryBuilderLabelFilter, QueryBuilderOperation } from './shared/types'; -import { PromVisualQuery, PromVisualQueryBinary } from './types'; -import { binaryScalarDefs } from './binaryScalarOperations'; +import { parser } from 'lezer-promql'; + +import { binaryScalarOperatorToOperatorName } from './binaryScalarOperations'; import { ErrorName, getAllByType, @@ -12,6 +11,8 @@ import { makeError, replaceVariables, } from './shared/parsingUtils'; +import { QueryBuilderLabelFilter, QueryBuilderOperation } from './shared/types'; +import { PromVisualQuery, PromVisualQueryBinary } from './types'; /** * Parses a PromQL query into a visual query model. @@ -277,14 +278,6 @@ function updateFunctionArgs(expr: string, node: SyntaxNode | null, context: Cont } } -const operatorToOpName = binaryScalarDefs.reduce((acc, def) => { - acc[def.sign] = { - id: def.id, - comparison: def.comparison, - }; - return acc; -}, {} as Record); - /** * Right now binary expressions can be represented in 2 way in visual query. As additional operation in case it is * just operation with scalar or it creates a binaryQuery when it's 2 queries. @@ -300,7 +293,7 @@ function handleBinary(expr: string, node: SyntaxNode, context: Context) { const right = node.lastChild!; - const opDef = operatorToOpName[op]; + const opDef = binaryScalarOperatorToOperatorName[op]; const leftNumber = left.getChild('NumberLiteral'); const rightNumber = right.getChild('NumberLiteral'); diff --git a/public/app/plugins/datasource/prometheus/querybuilder/shared/AutoSizeInput.test.tsx b/public/app/plugins/datasource/prometheus/querybuilder/shared/AutoSizeInput.test.tsx index 0e0ef42b541..1bd9458fb50 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/shared/AutoSizeInput.test.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/shared/AutoSizeInput.test.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { screen, render, fireEvent } from '@testing-library/react'; +import React from 'react'; + import { AutoSizeInput } from './AutoSizeInput'; jest.mock('@grafana/ui', () => { diff --git a/public/app/plugins/datasource/prometheus/querybuilder/shared/AutoSizeInput.tsx b/public/app/plugins/datasource/prometheus/querybuilder/shared/AutoSizeInput.tsx index a0223f596c7..a81e3c91010 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/shared/AutoSizeInput.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/shared/AutoSizeInput.tsx @@ -1,6 +1,7 @@ +import React, { useEffect } from 'react'; + import { Input, measureText } from '@grafana/ui'; import { Props as InputProps } from '@grafana/ui/src/components/Input/Input'; -import React, { useEffect } from 'react'; export interface Props extends InputProps { /** Sets the min-width to a multiple of 8px. Default value is 10*/ minWidth?: number; diff --git a/public/app/plugins/datasource/prometheus/querybuilder/shared/FeedbackLink.tsx b/public/app/plugins/datasource/prometheus/querybuilder/shared/FeedbackLink.tsx index 70b799046af..6aca403220c 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/shared/FeedbackLink.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/shared/FeedbackLink.tsx @@ -1,9 +1,10 @@ import { css } from '@emotion/css'; +import React from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { Stack } from '@grafana/experimental'; import { config } from '@grafana/runtime'; import { Icon, useStyles2 } from '@grafana/ui'; -import React from 'react'; export interface Props { feedbackUrl?: string; diff --git a/public/app/plugins/datasource/prometheus/querybuilder/shared/LabelFilterItem.tsx b/public/app/plugins/datasource/prometheus/querybuilder/shared/LabelFilterItem.tsx index e2eccbf9045..f1fc4442ee6 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/shared/LabelFilterItem.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/shared/LabelFilterItem.tsx @@ -1,8 +1,10 @@ import React, { useState } from 'react'; -import { Select } from '@grafana/ui'; + import { SelectableValue, toOption } from '@grafana/data'; -import { QueryBuilderLabelFilter } from './types'; import { AccessoryButton, InputGroup } from '@grafana/experimental'; +import { Select } from '@grafana/ui'; + +import { QueryBuilderLabelFilter } from './types'; export interface Props { defaultOp: string; diff --git a/public/app/plugins/datasource/prometheus/querybuilder/shared/LabelFilters.test.tsx b/public/app/plugins/datasource/prometheus/querybuilder/shared/LabelFilters.test.tsx index 58d8f7b1f1b..3ca21a0bfaf 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/shared/LabelFilters.test.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/shared/LabelFilters.test.tsx @@ -1,10 +1,12 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import React from 'react'; + +import { selectOptionInTest } from '../../../../../../../packages/grafana-ui'; +import { getLabelSelects } from '../testUtils'; + import { LabelFilters } from './LabelFilters'; import { QueryBuilderLabelFilter } from './types'; -import { getLabelSelects } from '../testUtils'; -import { selectOptionInTest } from '../../../../../../../packages/grafana-ui'; describe('LabelFilters', () => { it('renders empty input without labels', async () => { diff --git a/public/app/plugins/datasource/prometheus/querybuilder/shared/LabelFilters.tsx b/public/app/plugins/datasource/prometheus/querybuilder/shared/LabelFilters.tsx index 87632d740f5..b8dd900bd06 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/shared/LabelFilters.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/shared/LabelFilters.tsx @@ -1,9 +1,12 @@ +import { isEqual } from 'lodash'; +import React, { useEffect, useState } from 'react'; + import { SelectableValue } from '@grafana/data'; import { EditorFieldGroup, EditorList } from '@grafana/experimental'; import { Field } from '@grafana/ui'; -import { isEqual } from 'lodash'; -import React, { useEffect, useState } from 'react'; + import { QueryBuilderLabelFilter } from '../shared/types'; + import { LabelFilterItem } from './LabelFilterItem'; export interface Props { diff --git a/public/app/plugins/datasource/prometheus/querybuilder/shared/LokiAndPromQueryModellerBase.ts b/public/app/plugins/datasource/prometheus/querybuilder/shared/LokiAndPromQueryModellerBase.ts index e3ac4ec6f79..98e929e831e 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/shared/LokiAndPromQueryModellerBase.ts +++ b/public/app/plugins/datasource/prometheus/querybuilder/shared/LokiAndPromQueryModellerBase.ts @@ -1,5 +1,7 @@ import { Registry } from '@grafana/data'; + import { PromVisualQueryOperationCategory } from '../types'; + import { QueryBuilderLabelFilter, QueryBuilderOperation, QueryBuilderOperationDef, VisualQueryModeller } from './types'; export interface VisualQueryBinary { diff --git a/public/app/plugins/datasource/prometheus/querybuilder/shared/OperationEditor.tsx b/public/app/plugins/datasource/prometheus/querybuilder/shared/OperationEditor.tsx index 92df358c34a..205c4802b58 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/shared/OperationEditor.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/shared/OperationEditor.tsx @@ -1,9 +1,11 @@ import { css, cx } from '@emotion/css'; +import React, { useEffect, useState } from 'react'; +import { Draggable } from 'react-beautiful-dnd'; + import { DataSourceApi, GrafanaTheme2 } from '@grafana/data'; import { Stack } from '@grafana/experimental'; import { Button, Icon, Tooltip, useStyles2 } from '@grafana/ui'; -import React, { useEffect, useState } from 'react'; -import { Draggable } from 'react-beautiful-dnd'; + import { VisualQueryModeller, QueryBuilderOperation, @@ -11,6 +13,7 @@ import { QueryBuilderOperationDef, QueryBuilderOperationParamDef, } from '../shared/types'; + import { OperationHeader } from './OperationHeader'; import { getOperationParamEditor } from './OperationParamEditor'; import { getOperationParamId } from './operationUtils'; diff --git a/public/app/plugins/datasource/prometheus/querybuilder/shared/OperationExplainedBox.tsx b/public/app/plugins/datasource/prometheus/querybuilder/shared/OperationExplainedBox.tsx index 5a42ec31ef2..867c03b2cb2 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/shared/OperationExplainedBox.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/shared/OperationExplainedBox.tsx @@ -1,7 +1,8 @@ import { css } from '@emotion/css'; +import React from 'react'; + import { GrafanaTheme2, renderMarkdown } from '@grafana/data'; import { useStyles2 } from '@grafana/ui'; -import React from 'react'; export interface Props { title: string; diff --git a/public/app/plugins/datasource/prometheus/querybuilder/shared/OperationHeader.tsx b/public/app/plugins/datasource/prometheus/querybuilder/shared/OperationHeader.tsx index 0f5e723c76f..7ca2d4630d4 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/shared/OperationHeader.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/shared/OperationHeader.tsx @@ -1,8 +1,10 @@ import { css } from '@emotion/css'; +import React, { useState } from 'react'; + import { GrafanaTheme2, SelectableValue } from '@grafana/data'; import { FlexItem } from '@grafana/experimental'; import { Button, Select, useStyles2 } from '@grafana/ui'; -import React, { useState } from 'react'; + import { OperationInfoButton } from './OperationInfoButton'; import { VisualQueryModeller, QueryBuilderOperation, QueryBuilderOperationDef } from './types'; diff --git a/public/app/plugins/datasource/prometheus/querybuilder/shared/OperationInfoButton.tsx b/public/app/plugins/datasource/prometheus/querybuilder/shared/OperationInfoButton.tsx index 075dd63d5d6..20e21009d08 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/shared/OperationInfoButton.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/shared/OperationInfoButton.tsx @@ -1,9 +1,11 @@ import { css } from '@emotion/css'; +import React, { useState } from 'react'; +import { usePopperTooltip } from 'react-popper-tooltip'; + import { GrafanaTheme2, renderMarkdown } from '@grafana/data'; import { FlexItem } from '@grafana/experimental'; import { Button, Portal, useStyles2 } from '@grafana/ui'; -import React, { useState } from 'react'; -import { usePopperTooltip } from 'react-popper-tooltip'; + import { QueryBuilderOperation, QueryBuilderOperationDef } from './types'; export interface Props { diff --git a/public/app/plugins/datasource/prometheus/querybuilder/shared/OperationList.test.tsx b/public/app/plugins/datasource/prometheus/querybuilder/shared/OperationList.test.tsx index ac9ad278741..3d2943dc058 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/shared/OperationList.test.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/shared/OperationList.test.tsx @@ -1,13 +1,16 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { OperationList } from './OperationList'; -import { promQueryModeller } from '../PromQueryModeller'; -import { EmptyLanguageProviderMock } from '../../language_provider.mock'; -import PromQlLanguageProvider from '../../language_provider'; -import { PromVisualQuery } from '../types'; -import { PrometheusDatasource } from '../../datasource'; +import React from 'react'; + import { DataSourceApi } from '@grafana/data'; + +import { PrometheusDatasource } from '../../datasource'; +import PromQlLanguageProvider from '../../language_provider'; +import { EmptyLanguageProviderMock } from '../../language_provider.mock'; +import { promQueryModeller } from '../PromQueryModeller'; +import { PromVisualQuery } from '../types'; + +import { OperationList } from './OperationList'; import { addOperation } from './OperationList.testUtils'; const defaultQuery: PromVisualQuery = { diff --git a/public/app/plugins/datasource/prometheus/querybuilder/shared/OperationList.tsx b/public/app/plugins/datasource/prometheus/querybuilder/shared/OperationList.tsx index 026d9eaf911..0ed222ef6a6 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/shared/OperationList.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/shared/OperationList.tsx @@ -1,11 +1,14 @@ import { css } from '@emotion/css'; -import { DataSourceApi, GrafanaTheme2 } from '@grafana/data'; -import { Stack } from '@grafana/experimental'; -import { Button, Cascader, CascaderOption, useStyles2 } from '@grafana/ui'; import React, { useState } from 'react'; import { DragDropContext, Droppable, DropResult } from 'react-beautiful-dnd'; import { useMountedState, usePrevious } from 'react-use'; + +import { DataSourceApi, GrafanaTheme2 } from '@grafana/data'; +import { Stack } from '@grafana/experimental'; +import { Button, Cascader, CascaderOption, useStyles2 } from '@grafana/ui'; + import { QueryBuilderOperation, QueryWithOperations, VisualQueryModeller } from '../shared/types'; + import { OperationEditor } from './OperationEditor'; export interface Props { diff --git a/public/app/plugins/datasource/prometheus/querybuilder/shared/OperationListExplained.tsx b/public/app/plugins/datasource/prometheus/querybuilder/shared/OperationListExplained.tsx index 690a8015c58..1bae2ed76db 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/shared/OperationListExplained.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/shared/OperationListExplained.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { OperationExplainedBox } from './OperationExplainedBox'; import { QueryWithOperations, VisualQueryModeller } from './types'; diff --git a/public/app/plugins/datasource/prometheus/querybuilder/shared/OperationParamEditor.tsx b/public/app/plugins/datasource/prometheus/querybuilder/shared/OperationParamEditor.tsx index 4f07523e2d1..2d4ff33a664 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/shared/OperationParamEditor.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/shared/OperationParamEditor.tsx @@ -1,7 +1,10 @@ +import React, { ComponentType } from 'react'; + import { SelectableValue, toOption } from '@grafana/data'; import { Checkbox, Select } from '@grafana/ui'; -import React, { ComponentType } from 'react'; + import { QueryBuilderOperationParamDef, QueryBuilderOperationParamEditorProps } from '../shared/types'; + import { AutoSizeInput } from './AutoSizeInput'; import { getOperationParamId } from './operationUtils'; diff --git a/public/app/plugins/datasource/prometheus/querybuilder/shared/OperationsEditorRow.tsx b/public/app/plugins/datasource/prometheus/querybuilder/shared/OperationsEditorRow.tsx index 991461287b7..6800e86f726 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/shared/OperationsEditorRow.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/shared/OperationsEditorRow.tsx @@ -1,8 +1,9 @@ import { css } from '@emotion/css'; +import React from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { Stack } from '@grafana/experimental'; import { useStyles2 } from '@grafana/ui'; -import React from 'react'; interface Props { children: React.ReactNode; diff --git a/public/app/plugins/datasource/prometheus/querybuilder/shared/QueryEditorModeToggle.tsx b/public/app/plugins/datasource/prometheus/querybuilder/shared/QueryEditorModeToggle.tsx index 61a86aab19f..22070b1d595 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/shared/QueryEditorModeToggle.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/shared/QueryEditorModeToggle.tsx @@ -1,6 +1,8 @@ -import { RadioButtonGroup, Tag } from '@grafana/ui'; -import React from 'react'; import { css } from '@emotion/css'; +import React from 'react'; + +import { RadioButtonGroup, Tag } from '@grafana/ui'; + import { QueryEditorMode } from './types'; export interface Props { diff --git a/public/app/plugins/datasource/prometheus/querybuilder/shared/QueryHeaderSwitch.tsx b/public/app/plugins/datasource/prometheus/querybuilder/shared/QueryHeaderSwitch.tsx index 2df17673f48..3bee386a581 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/shared/QueryHeaderSwitch.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/shared/QueryHeaderSwitch.tsx @@ -1,9 +1,10 @@ import { css } from '@emotion/css'; +import { uniqueId } from 'lodash'; +import React, { HTMLProps, useRef } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { Stack } from '@grafana/experimental'; import { Switch, useStyles2 } from '@grafana/ui'; -import { uniqueId } from 'lodash'; -import React, { HTMLProps, useRef } from 'react'; export interface Props extends Omit, 'value' | 'ref'> { value?: boolean; diff --git a/public/app/plugins/datasource/prometheus/querybuilder/shared/QueryOptionGroup.tsx b/public/app/plugins/datasource/prometheus/querybuilder/shared/QueryOptionGroup.tsx index 84a817a6c47..d3dc219ecd8 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/shared/QueryOptionGroup.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/shared/QueryOptionGroup.tsx @@ -1,9 +1,10 @@ -import React from 'react'; import { css } from '@emotion/css'; +import React from 'react'; +import { useToggle } from 'react-use'; + import { GrafanaTheme2 } from '@grafana/data'; import { Stack } from '@grafana/experimental'; import { Icon, useStyles2 } from '@grafana/ui'; -import { useToggle } from 'react-use'; export interface Props { title: string; diff --git a/public/app/plugins/datasource/prometheus/querybuilder/shared/operationUtils.ts b/public/app/plugins/datasource/prometheus/querybuilder/shared/operationUtils.ts index e685255f42a..ef6689763d3 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/shared/operationUtils.ts +++ b/public/app/plugins/datasource/prometheus/querybuilder/shared/operationUtils.ts @@ -1,4 +1,11 @@ import { capitalize } from 'lodash'; +import pluralize from 'pluralize'; + +import { SelectableValue } from '@grafana/data/src'; + +import { LabelParamEditor } from '../components/LabelParamEditor'; +import { PromVisualQueryOperationCategory } from '../types'; + import { QueryBuilderOperation, QueryBuilderOperationDef, @@ -6,10 +13,6 @@ import { QueryBuilderOperationParamValue, QueryWithOperations, } from './types'; -import { SelectableValue } from '@grafana/data/src'; -import { LabelParamEditor } from '../components/LabelParamEditor'; -import { PromVisualQueryOperationCategory } from '../types'; -import pluralize from 'pluralize'; export function functionRendererLeft(model: QueryBuilderOperation, def: QueryBuilderOperationDef, innerExpr: string) { const params = renderParams(model, def, innerExpr); diff --git a/public/app/plugins/datasource/prometheus/querybuilder/shared/parsingUtils.test.ts b/public/app/plugins/datasource/prometheus/querybuilder/shared/parsingUtils.test.ts index d5b8804a167..700e2dfa744 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/shared/parsingUtils.test.ts +++ b/public/app/plugins/datasource/prometheus/querybuilder/shared/parsingUtils.test.ts @@ -1,6 +1,7 @@ -import { getLeftMostChild, getString, replaceVariables } from './parsingUtils'; import { parser } from 'lezer-promql'; +import { getLeftMostChild, getString, replaceVariables } from './parsingUtils'; + describe('getLeftMostChild', () => { it('return left most child', () => { const tree = parser.parse('sum_over_time(foo{bar="baz"}[5m])'); diff --git a/public/app/plugins/datasource/prometheus/querybuilder/shared/parsingUtils.ts b/public/app/plugins/datasource/prometheus/querybuilder/shared/parsingUtils.ts index e2d89d4db6d..3e6f2a7c6f1 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/shared/parsingUtils.ts +++ b/public/app/plugins/datasource/prometheus/querybuilder/shared/parsingUtils.ts @@ -1,4 +1,5 @@ import { SyntaxNode, TreeCursor } from '@lezer/common'; + import { QueryBuilderOperation } from './types'; // This is used for error type for some reason diff --git a/public/app/plugins/datasource/prometheus/querybuilder/shared/types.ts b/public/app/plugins/datasource/prometheus/querybuilder/shared/types.ts index d56bcddbf74..1b79b22a5a3 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/shared/types.ts +++ b/public/app/plugins/datasource/prometheus/querybuilder/shared/types.ts @@ -2,9 +2,10 @@ * Shared types that can be reused by Loki and other data sources */ -import { DataSourceApi, RegistryItem, SelectableValue } from '@grafana/data'; import { ComponentType } from 'react'; +import { DataSourceApi, RegistryItem, SelectableValue } from '@grafana/data'; + export interface QueryBuilderLabelFilter { label: string; op: string; diff --git a/public/app/plugins/datasource/prometheus/querybuilder/state.test.ts b/public/app/plugins/datasource/prometheus/querybuilder/state.test.ts index f3d3acd77a4..cb05cae6fba 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/state.test.ts +++ b/public/app/plugins/datasource/prometheus/querybuilder/state.test.ts @@ -1,4 +1,5 @@ import { CoreApp } from '@grafana/data'; + import { QueryEditorMode } from './shared/types'; import { changeEditorMode, getQueryWithDefaults } from './state'; diff --git a/public/app/plugins/datasource/prometheus/querybuilder/state.ts b/public/app/plugins/datasource/prometheus/querybuilder/state.ts index 5c59d4bece4..606153c393c 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/state.ts +++ b/public/app/plugins/datasource/prometheus/querybuilder/state.ts @@ -1,6 +1,8 @@ import { CoreApp } from '@grafana/data'; import store from 'app/core/store'; + import { LegendFormatMode, PromQuery } from '../types'; + import { QueryEditorMode } from './shared/types'; const queryEditorModeDefaultLocalStorageKey = 'PrometheusQueryEditorModeDefault'; diff --git a/public/app/plugins/datasource/prometheus/result_transformer.test.ts b/public/app/plugins/datasource/prometheus/result_transformer.test.ts index b7087c11d1e..c58b95c514a 100644 --- a/public/app/plugins/datasource/prometheus/result_transformer.test.ts +++ b/public/app/plugins/datasource/prometheus/result_transformer.test.ts @@ -1,4 +1,5 @@ import { DataFrame, FieldType, DataQueryRequest, DataQueryResponse, MutableDataFrame } from '@grafana/data'; + import { transform, transformV2, transformDFToTable } from './result_transformer'; import { PromQuery } from './types'; diff --git a/public/app/plugins/datasource/prometheus/result_transformer.ts b/public/app/plugins/datasource/prometheus/result_transformer.ts index 62b8d2f3422..103f2500605 100644 --- a/public/app/plugins/datasource/prometheus/result_transformer.ts +++ b/public/app/plugins/datasource/prometheus/result_transformer.ts @@ -1,3 +1,6 @@ +import { descending, deviation } from 'd3'; +import { partition, groupBy } from 'lodash'; + import { ArrayDataFrame, ArrayVector, @@ -20,8 +23,8 @@ import { DataFrameType, } from '@grafana/data'; import { FetchResponse, getDataSourceSrv, getTemplateSrv } from '@grafana/runtime'; -import { partition, groupBy } from 'lodash'; -import { descending, deviation } from 'd3'; + +import { renderLegendFormat } from './legend'; import { ExemplarTraceIdDestination, isExemplarData, @@ -34,7 +37,6 @@ import { PromValue, TransformOptions, } from './types'; -import { renderLegendFormat } from './legend'; const POSITIVE_INFINITY_SAMPLE_VALUE = '+Inf'; const NEGATIVE_INFINITY_SAMPLE_VALUE = '-Inf'; diff --git a/public/app/plugins/datasource/prometheus/types.ts b/public/app/plugins/datasource/prometheus/types.ts index f2c4b494c5e..e9f1776becd 100644 --- a/public/app/plugins/datasource/prometheus/types.ts +++ b/public/app/plugins/datasource/prometheus/types.ts @@ -1,4 +1,5 @@ import { DataQuery, DataSourceJsonData, QueryResultMeta, ScopedVars } from '@grafana/data'; + import { QueryEditorMode } from './querybuilder/shared/types'; export interface PromQuery extends DataQuery { diff --git a/public/app/plugins/datasource/prometheus/variables.ts b/public/app/plugins/datasource/prometheus/variables.ts index 27954f553e7..ac92f27dd0e 100644 --- a/public/app/plugins/datasource/prometheus/variables.ts +++ b/public/app/plugins/datasource/prometheus/variables.ts @@ -1,5 +1,6 @@ import { from, Observable, of } from 'rxjs'; import { map } from 'rxjs/operators'; + import { DataQueryRequest, DataQueryResponse, @@ -9,11 +10,12 @@ import { } from '@grafana/data'; import { getTemplateSrv, TemplateSrv } from '@grafana/runtime'; -import { PrometheusDatasource } from './datasource'; -import { PromQuery } from './types'; -import PrometheusMetricFindQuery from './metric_find_query'; import { getTimeSrv, TimeSrv } from '../../../features/dashboard/services/TimeSrv'; +import { PrometheusDatasource } from './datasource'; +import PrometheusMetricFindQuery from './metric_find_query'; +import { PromQuery } from './types'; + export class PrometheusVariableSupport extends StandardVariableSupport { constructor( private readonly datasource: PrometheusDatasource, diff --git a/public/app/plugins/datasource/tempo/QueryEditor/NativeSearch.test.tsx b/public/app/plugins/datasource/tempo/QueryEditor/NativeSearch.test.tsx index f8372122399..00b8096dd41 100644 --- a/public/app/plugins/datasource/tempo/QueryEditor/NativeSearch.test.tsx +++ b/public/app/plugins/datasource/tempo/QueryEditor/NativeSearch.test.tsx @@ -1,9 +1,11 @@ -import NativeSearch from './NativeSearch'; -import React from 'react'; import { render, screen, waitFor } from '@testing-library/react'; -import { TempoDatasource, TempoQuery } from '../datasource'; import userEvent from '@testing-library/user-event'; import { UserEvent } from '@testing-library/user-event/dist/types/setup'; +import React from 'react'; + +import { TempoDatasource, TempoQuery } from '../datasource'; + +import NativeSearch from './NativeSearch'; const getOptions = jest.fn().mockImplementation(() => { return new Promise((resolve) => { diff --git a/public/app/plugins/datasource/tempo/QueryEditor/NativeSearch.tsx b/public/app/plugins/datasource/tempo/QueryEditor/NativeSearch.tsx index 6ac6ddfc3ef..9606c17b424 100644 --- a/public/app/plugins/datasource/tempo/QueryEditor/NativeSearch.tsx +++ b/public/app/plugins/datasource/tempo/QueryEditor/NativeSearch.tsx @@ -1,4 +1,10 @@ +import { css } from '@emotion/css'; +import { debounce } from 'lodash'; +import Prism from 'prismjs'; import React, { useCallback, useState, useEffect, useMemo } from 'react'; +import { Node } from 'slate'; + +import { GrafanaTheme2, isValidGoDuration, SelectableValue } from '@grafana/data'; import { InlineFieldRow, InlineField, @@ -12,17 +18,13 @@ import { Alert, useStyles2, } from '@grafana/ui'; -import { tokenizer } from '../syntax'; -import Prism from 'prismjs'; -import { Node } from 'slate'; -import { css } from '@emotion/css'; -import { GrafanaTheme2, isValidGoDuration, SelectableValue } from '@grafana/data'; -import TempoLanguageProvider from '../language_provider'; -import { TempoDatasource, TempoQuery } from '../datasource'; -import { debounce } from 'lodash'; -import { dispatch } from 'app/store/store'; import { notifyApp } from 'app/core/actions'; import { createErrorNotification } from 'app/core/copy/appNotification'; +import { dispatch } from 'app/store/store'; + +import { TempoDatasource, TempoQuery } from '../datasource'; +import TempoLanguageProvider from '../language_provider'; +import { tokenizer } from '../syntax'; interface Props { datasource: TempoDatasource; diff --git a/public/app/plugins/datasource/tempo/QueryEditor/QueryField.tsx b/public/app/plugins/datasource/tempo/QueryEditor/QueryField.tsx index 26f1a9f5d27..6c43346b531 100644 --- a/public/app/plugins/datasource/tempo/QueryEditor/QueryField.tsx +++ b/public/app/plugins/datasource/tempo/QueryEditor/QueryField.tsx @@ -1,4 +1,7 @@ import { css } from '@emotion/css'; +import React from 'react'; +import useAsync from 'react-use/lib/useAsync'; + import { QueryEditorProps, SelectableValue } from '@grafana/data'; import { config } from '@grafana/runtime'; import { @@ -12,15 +15,15 @@ import { Themeable2, withTheme2, } from '@grafana/ui'; -import React from 'react'; + import { LokiQueryField } from '../../loki/components/LokiQueryField'; +import { LokiDatasource } from '../../loki/datasource'; import { LokiQuery } from '../../loki/types'; import { TempoDatasource, TempoQuery, TempoQueryType } from '../datasource'; -import { LokiDatasource } from '../../loki/datasource'; -import useAsync from 'react-use/lib/useAsync'; + import NativeSearch from './NativeSearch'; -import { getDS } from './utils'; import { ServiceGraphSection } from './ServiceGraphSection'; +import { getDS } from './utils'; interface Props extends QueryEditorProps, Themeable2 {} diff --git a/public/app/plugins/datasource/tempo/QueryEditor/ServiceGraphSection.tsx b/public/app/plugins/datasource/tempo/QueryEditor/ServiceGraphSection.tsx index 99471de6846..14ff7b7cc83 100644 --- a/public/app/plugins/datasource/tempo/QueryEditor/ServiceGraphSection.tsx +++ b/public/app/plugins/datasource/tempo/QueryEditor/ServiceGraphSection.tsx @@ -1,11 +1,14 @@ import React from 'react'; import useAsync from 'react-use/lib/useAsync'; -import { getDS } from './utils'; + import { InlineField, InlineFieldRow } from '@grafana/ui'; -import { AdHocVariableFilter } from '../../../../features/variables/types'; -import { TempoQuery } from '../datasource'; + import { AdHocFilter } from '../../../../features/variables/adhoc/picker/AdHocFilter'; +import { AdHocVariableFilter } from '../../../../features/variables/types'; import { PrometheusDatasource } from '../../prometheus/datasource'; +import { TempoQuery } from '../datasource'; + +import { getDS } from './utils'; export function ServiceGraphSection({ graphDatasourceUid, diff --git a/public/app/plugins/datasource/tempo/configuration/ConfigEditor.tsx b/public/app/plugins/datasource/tempo/configuration/ConfigEditor.tsx index ac9276770b7..fc21868589b 100644 --- a/public/app/plugins/datasource/tempo/configuration/ConfigEditor.tsx +++ b/public/app/plugins/datasource/tempo/configuration/ConfigEditor.tsx @@ -1,12 +1,14 @@ -import { DataSourcePluginOptionsEditorProps } from '@grafana/data'; -import { DataSourceHttpSettings } from '@grafana/ui'; -import { TraceToLogsSettings } from 'app/core/components/TraceToLogs/TraceToLogsSettings'; import React from 'react'; -import { ServiceGraphSettings } from './ServiceGraphSettings'; + +import { DataSourcePluginOptionsEditorProps } from '@grafana/data'; import { config } from '@grafana/runtime'; -import { SearchSettings } from './SearchSettings'; +import { DataSourceHttpSettings } from '@grafana/ui'; import { NodeGraphSettings } from 'app/core/components/NodeGraphSettings'; +import { TraceToLogsSettings } from 'app/core/components/TraceToLogs/TraceToLogsSettings'; + import { LokiSearchSettings } from './LokiSearchSettings'; +import { SearchSettings } from './SearchSettings'; +import { ServiceGraphSettings } from './ServiceGraphSettings'; export type Props = DataSourcePluginOptionsEditorProps; diff --git a/public/app/plugins/datasource/tempo/configuration/LokiSearchSettings.tsx b/public/app/plugins/datasource/tempo/configuration/LokiSearchSettings.tsx index c0374df4d17..66b939477c8 100644 --- a/public/app/plugins/datasource/tempo/configuration/LokiSearchSettings.tsx +++ b/public/app/plugins/datasource/tempo/configuration/LokiSearchSettings.tsx @@ -1,8 +1,10 @@ import { css } from '@emotion/css'; +import React from 'react'; + import { DataSourcePluginOptionsEditorProps, GrafanaTheme, updateDatasourcePluginJsonDataOption } from '@grafana/data'; import { DataSourcePicker } from '@grafana/runtime'; import { Button, InlineField, InlineFieldRow, useStyles } from '@grafana/ui'; -import React from 'react'; + import { TempoJsonData } from '../datasource'; interface Props extends DataSourcePluginOptionsEditorProps {} diff --git a/public/app/plugins/datasource/tempo/configuration/SearchSettings.tsx b/public/app/plugins/datasource/tempo/configuration/SearchSettings.tsx index 5cbd790d057..1877d7272c0 100644 --- a/public/app/plugins/datasource/tempo/configuration/SearchSettings.tsx +++ b/public/app/plugins/datasource/tempo/configuration/SearchSettings.tsx @@ -1,7 +1,9 @@ import { css } from '@emotion/css'; +import React from 'react'; + import { DataSourcePluginOptionsEditorProps, GrafanaTheme, updateDatasourcePluginJsonDataOption } from '@grafana/data'; import { InlineField, InlineFieldRow, InlineSwitch, useStyles } from '@grafana/ui'; -import React from 'react'; + import { TempoJsonData } from '../datasource'; interface Props extends DataSourcePluginOptionsEditorProps {} diff --git a/public/app/plugins/datasource/tempo/configuration/ServiceGraphSettings.tsx b/public/app/plugins/datasource/tempo/configuration/ServiceGraphSettings.tsx index 557a3fc1890..8e5712ef9f7 100644 --- a/public/app/plugins/datasource/tempo/configuration/ServiceGraphSettings.tsx +++ b/public/app/plugins/datasource/tempo/configuration/ServiceGraphSettings.tsx @@ -1,8 +1,10 @@ import { css } from '@emotion/css'; +import React from 'react'; + import { DataSourcePluginOptionsEditorProps, GrafanaTheme, updateDatasourcePluginJsonDataOption } from '@grafana/data'; import { DataSourcePicker } from '@grafana/runtime'; import { Button, InlineField, InlineFieldRow, useStyles } from '@grafana/ui'; -import React from 'react'; + import { TempoJsonData } from '../datasource'; interface Props extends DataSourcePluginOptionsEditorProps {} diff --git a/public/app/plugins/datasource/tempo/datasource.test.ts b/public/app/plugins/datasource/tempo/datasource.test.ts index e3c14e675b3..9798915f6a7 100644 --- a/public/app/plugins/datasource/tempo/datasource.test.ts +++ b/public/app/plugins/datasource/tempo/datasource.test.ts @@ -1,4 +1,6 @@ import { lastValueFrom, Observable, of } from 'rxjs'; +import { createFetchResponse } from 'test/helpers/createFetchResponse'; + import { DataFrame, dataFrameToJSON, @@ -9,9 +11,8 @@ import { MutableDataFrame, PluginType, } from '@grafana/data'; - -import { createFetchResponse } from 'test/helpers/createFetchResponse'; import { BackendDataSourceResponse, FetchResponse, setBackendSrv, setDataSourceSrv } from '@grafana/runtime'; + import { DEFAULT_LIMIT, TempoJsonData, TempoDatasource, TempoQuery } from './datasource'; import mockJson from './mockJsonResponse.json'; diff --git a/public/app/plugins/datasource/tempo/datasource.ts b/public/app/plugins/datasource/tempo/datasource.ts index 19b734f95d8..c83dfbf9e4d 100644 --- a/public/app/plugins/datasource/tempo/datasource.ts +++ b/public/app/plugins/datasource/tempo/datasource.ts @@ -1,5 +1,7 @@ +import { identity, pick, pickBy, groupBy, startCase } from 'lodash'; import { EMPTY, from, merge, Observable, of, throwError } from 'rxjs'; import { catchError, map, mergeMap, toArray } from 'rxjs/operators'; + import { DataQuery, DataQueryRequest, @@ -10,14 +12,16 @@ import { isValidGoDuration, LoadingState, } from '@grafana/data'; -import { TraceToLogsOptions } from 'app/core/components/TraceToLogs/TraceToLogsSettings'; import { config, BackendSrvRequest, DataSourceWithBackend, getBackendSrv } from '@grafana/runtime'; +import { NodeGraphOptions } from 'app/core/components/NodeGraphSettings'; +import { TraceToLogsOptions } from 'app/core/components/TraceToLogs/TraceToLogsSettings'; import { serializeParams } from 'app/core/utils/fetch'; import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; -import { identity, pick, pickBy, groupBy, startCase } from 'lodash'; + import { LokiOptions, LokiQuery } from '../loki/types'; import { PrometheusDatasource } from '../prometheus/datasource'; import { PromQuery } from '../prometheus/types'; + import { failedMetric, histogramMetric, @@ -31,7 +35,6 @@ import { transformFromOTLP as transformFromOTEL, createTableFrameFromSearch, } from './resultTransformer'; -import { NodeGraphOptions } from 'app/core/components/NodeGraphSettings'; // search = Loki search, nativeSearch = Tempo search for backwards compatibility export type TempoQueryType = 'search' | 'traceId' | 'serviceMap' | 'upload' | 'nativeSearch' | 'clear'; diff --git a/public/app/plugins/datasource/tempo/graphTransform.test.ts b/public/app/plugins/datasource/tempo/graphTransform.test.ts index 666ce5a8945..4e99678ace9 100644 --- a/public/app/plugins/datasource/tempo/graphTransform.test.ts +++ b/public/app/plugins/datasource/tempo/graphTransform.test.ts @@ -1,6 +1,7 @@ +import { ArrayVector, DataFrameView, dateTime, MutableDataFrame } from '@grafana/data'; + import { createGraphFrames, mapPromMetricsToServiceMap } from './graphTransform'; import { bigResponse } from './testResponse'; -import { ArrayVector, DataFrameView, dateTime, MutableDataFrame } from '@grafana/data'; describe('createGraphFrames', () => { it('transforms basic response into nodes and edges frame', async () => { diff --git a/public/app/plugins/datasource/tempo/graphTransform.ts b/public/app/plugins/datasource/tempo/graphTransform.ts index 212fe45fcac..b90dda63a40 100644 --- a/public/app/plugins/datasource/tempo/graphTransform.ts +++ b/public/app/plugins/datasource/tempo/graphTransform.ts @@ -8,6 +8,7 @@ import { NodeGraphDataFrameFieldNames as Fields, TimeRange, } from '@grafana/data'; + import { getNonOverlappingDuration, getStats, makeFrames, makeSpanMap } from '../../../core/utils/tracing'; /** diff --git a/public/app/plugins/datasource/tempo/language_provider.ts b/public/app/plugins/datasource/tempo/language_provider.ts index 7b9f0c1e2a3..27c13e5516e 100644 --- a/public/app/plugins/datasource/tempo/language_provider.ts +++ b/public/app/plugins/datasource/tempo/language_provider.ts @@ -1,6 +1,8 @@ +import { Value } from 'slate'; + import { HistoryItem, LanguageProvider, SelectableValue } from '@grafana/data'; import { CompletionItemGroup, TypeaheadInput, TypeaheadOutput } from '@grafana/ui'; -import { Value } from 'slate'; + import { TempoDatasource } from './datasource'; export default class TempoLanguageProvider extends LanguageProvider { diff --git a/public/app/plugins/datasource/tempo/module.ts b/public/app/plugins/datasource/tempo/module.ts index 595e750d257..5f71f71d1e3 100644 --- a/public/app/plugins/datasource/tempo/module.ts +++ b/public/app/plugins/datasource/tempo/module.ts @@ -1,8 +1,9 @@ import { DataSourcePlugin } from '@grafana/data'; + import CheatSheet from './CheatSheet'; +import { TempoQueryField } from './QueryEditor/QueryField'; import { ConfigEditor } from './configuration/ConfigEditor'; import { TempoDatasource } from './datasource'; -import { TempoQueryField } from './QueryEditor/QueryField'; export const plugin = new DataSourcePlugin(TempoDatasource) .setQueryEditor(TempoQueryField) diff --git a/public/app/plugins/datasource/tempo/resultTransformer.test.ts b/public/app/plugins/datasource/tempo/resultTransformer.test.ts index fef1a862153..b6e25519c8a 100644 --- a/public/app/plugins/datasource/tempo/resultTransformer.test.ts +++ b/public/app/plugins/datasource/tempo/resultTransformer.test.ts @@ -1,3 +1,5 @@ +import { collectorTypes } from '@opentelemetry/exporter-collector'; + import { ArrayVector, FieldType, @@ -6,6 +8,7 @@ import { DataSourceInstanceSettings, dateTime, } from '@grafana/data'; + import { SearchResponse, createTableFrame, @@ -21,7 +24,6 @@ import { otlpResponse, tempoSearchResponse, } from './testResponse'; -import { collectorTypes } from '@opentelemetry/exporter-collector'; const defaultSettings: DataSourceInstanceSettings = { id: 0, diff --git a/public/app/plugins/datasource/tempo/resultTransformer.ts b/public/app/plugins/datasource/tempo/resultTransformer.ts index 89859c62a23..20a1419dd6f 100644 --- a/public/app/plugins/datasource/tempo/resultTransformer.ts +++ b/public/app/plugins/datasource/tempo/resultTransformer.ts @@ -1,3 +1,9 @@ +import { SpanStatus, SpanStatusCode } from '@opentelemetry/api'; +import { collectorTypes } from '@opentelemetry/exporter-collector'; +import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions'; +import differenceInHours from 'date-fns/differenceInHours'; +import formatDistance from 'date-fns/formatDistance'; + import { ArrayVector, DataFrame, @@ -12,11 +18,7 @@ import { TraceSpanRow, dateTimeFormat, } from '@grafana/data'; -import { SpanStatus, SpanStatusCode } from '@opentelemetry/api'; -import { collectorTypes } from '@opentelemetry/exporter-collector'; -import formatDistance from 'date-fns/formatDistance'; -import differenceInHours from 'date-fns/differenceInHours'; -import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions'; + import { createGraphFrames } from './graphTransform'; export function createTableFrame( diff --git a/public/app/plugins/datasource/tempo/syntax.test.ts b/public/app/plugins/datasource/tempo/syntax.test.ts index 092d0f17a72..1b0a732fbdf 100644 --- a/public/app/plugins/datasource/tempo/syntax.test.ts +++ b/public/app/plugins/datasource/tempo/syntax.test.ts @@ -1,6 +1,7 @@ -import { tokenizer } from './syntax'; import Prism from 'prismjs'; +import { tokenizer } from './syntax'; + describe('Loki syntax', () => { it('should highlight Loki query correctly', () => { expect(Prism.highlight('key=value', tokenizer, 'tempo')).toBe( diff --git a/public/app/plugins/datasource/testdata/QueryEditor.test.tsx b/public/app/plugins/datasource/testdata/QueryEditor.test.tsx index 8060ffae023..4713d9752b2 100644 --- a/public/app/plugins/datasource/testdata/QueryEditor.test.tsx +++ b/public/app/plugins/datasource/testdata/QueryEditor.test.tsx @@ -1,9 +1,10 @@ -import React from 'react'; import { fireEvent, render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { defaultQuery } from './constants'; +import React from 'react'; + import { QueryEditor, Props } from './QueryEditor'; import { scenarios } from './__mocks__/scenarios'; +import { defaultQuery } from './constants'; import { defaultStreamQuery } from './runStreams'; beforeEach(() => { diff --git a/public/app/plugins/datasource/testdata/QueryEditor.tsx b/public/app/plugins/datasource/testdata/QueryEditor.tsx index 040be750b3a..38b9021ad6c 100644 --- a/public/app/plugins/datasource/testdata/QueryEditor.tsx +++ b/public/app/plugins/datasource/testdata/QueryEditor.tsx @@ -1,28 +1,25 @@ -// Libraries import React, { ChangeEvent, FormEvent, useMemo } from 'react'; import { useAsync } from 'react-use'; -// Components +import { QueryEditorProps, SelectableValue } from '@grafana/data'; import { selectors as editorSelectors } from '@grafana/e2e-selectors'; import { InlineField, InlineFieldRow, InlineSwitch, Input, Select, TextArea } from '@grafana/ui'; -import { QueryEditorProps, SelectableValue } from '@grafana/data'; -import { RandomWalkEditor, StreamingClientEditor } from './components'; -// Types -import { TestDataDataSource } from './datasource'; -import { CSVWave, NodesQuery, TestDataQuery, USAQuery } from './types'; -import { PredictablePulseEditor } from './components/PredictablePulseEditor'; +import { RandomWalkEditor, StreamingClientEditor } from './components'; +import { CSVContentEditor } from './components/CSVContentEditor'; +import { CSVFileEditor } from './components/CSVFileEditor'; import { CSVWavesEditor } from './components/CSVWaveEditor'; -import { defaultCSVWaveQuery, defaultPulseQuery, defaultQuery } from './constants'; +import ErrorEditor from './components/ErrorEditor'; import { GrafanaLiveEditor } from './components/GrafanaLiveEditor'; import { NodeGraphEditor } from './components/NodeGraphEditor'; +import { PredictablePulseEditor } from './components/PredictablePulseEditor'; import { RawFrameEditor } from './components/RawFrameEditor'; -import { defaultStreamQuery } from './runStreams'; -import { CSVFileEditor } from './components/CSVFileEditor'; -import { CSVContentEditor } from './components/CSVContentEditor'; -import { USAQueryEditor, usaQueryModes } from './components/USAQueryEditor'; -import ErrorEditor from './components/ErrorEditor'; import { SimulationQueryEditor } from './components/SimulationQueryEditor'; +import { USAQueryEditor, usaQueryModes } from './components/USAQueryEditor'; +import { defaultCSVWaveQuery, defaultPulseQuery, defaultQuery } from './constants'; +import { TestDataDataSource } from './datasource'; +import { defaultStreamQuery } from './runStreams'; +import { CSVWave, NodesQuery, TestDataQuery, USAQuery } from './types'; const showLabelsFor = ['random_walk', 'predictable_pulse']; const endpoints = [ diff --git a/public/app/plugins/datasource/testdata/TestInfoTab.tsx b/public/app/plugins/datasource/testdata/TestInfoTab.tsx index 36c54f2ccd1..5ab58f4f621 100644 --- a/public/app/plugins/datasource/testdata/TestInfoTab.tsx +++ b/public/app/plugins/datasource/testdata/TestInfoTab.tsx @@ -1,9 +1,10 @@ // Libraries import React, { PureComponent } from 'react'; + +import { PluginConfigPageProps, DataSourcePluginMeta, DataSourceJsonData } from '@grafana/data'; import { LinkButton } from '@grafana/ui'; // Types -import { PluginConfigPageProps, DataSourcePluginMeta, DataSourceJsonData } from '@grafana/data'; interface Props extends PluginConfigPageProps> {} diff --git a/public/app/plugins/datasource/testdata/components/CSVContentEditor.tsx b/public/app/plugins/datasource/testdata/components/CSVContentEditor.tsx index ed645009971..aa6c2f85c72 100644 --- a/public/app/plugins/datasource/testdata/components/CSVContentEditor.tsx +++ b/public/app/plugins/datasource/testdata/components/CSVContentEditor.tsx @@ -1,5 +1,7 @@ import React from 'react'; + import { CodeEditor } from '@grafana/ui'; + import { EditorProps } from '../QueryEditor'; export const CSVContentEditor = ({ onChange, query }: EditorProps) => { diff --git a/public/app/plugins/datasource/testdata/components/CSVFileEditor.tsx b/public/app/plugins/datasource/testdata/components/CSVFileEditor.tsx index 73c8648dac6..538e2efb0a4 100644 --- a/public/app/plugins/datasource/testdata/components/CSVFileEditor.tsx +++ b/public/app/plugins/datasource/testdata/components/CSVFileEditor.tsx @@ -1,6 +1,8 @@ import React from 'react'; -import { InlineField, InlineFieldRow, Select } from '@grafana/ui'; + import { SelectableValue } from '@grafana/data'; +import { InlineField, InlineFieldRow, Select } from '@grafana/ui'; + import { EditorProps } from '../QueryEditor'; export const CSVFileEditor = ({ onChange, query }: EditorProps) => { diff --git a/public/app/plugins/datasource/testdata/components/CSVWaveEditor.tsx b/public/app/plugins/datasource/testdata/components/CSVWaveEditor.tsx index 35864914139..b1090c2d6c1 100644 --- a/public/app/plugins/datasource/testdata/components/CSVWaveEditor.tsx +++ b/public/app/plugins/datasource/testdata/components/CSVWaveEditor.tsx @@ -1,7 +1,9 @@ import React, { ChangeEvent, PureComponent } from 'react'; + import { Button, InlineField, InlineFieldRow, Input } from '@grafana/ui'; -import { CSVWave } from '../types'; + import { defaultCSVWaveQuery } from '../constants'; +import { CSVWave } from '../types'; interface WavesProps { waves?: CSVWave[]; diff --git a/public/app/plugins/datasource/testdata/components/ErrorEditor.tsx b/public/app/plugins/datasource/testdata/components/ErrorEditor.tsx index a8447118a88..16f5ac7b570 100644 --- a/public/app/plugins/datasource/testdata/components/ErrorEditor.tsx +++ b/public/app/plugins/datasource/testdata/components/ErrorEditor.tsx @@ -1,5 +1,7 @@ -import { InlineField, InlineFieldRow, Select } from '@grafana/ui'; import React from 'react'; + +import { InlineField, InlineFieldRow, Select } from '@grafana/ui'; + import { EditorProps } from '../QueryEditor'; const ERROR_OPTIONS = [ diff --git a/public/app/plugins/datasource/testdata/components/GrafanaLiveEditor.tsx b/public/app/plugins/datasource/testdata/components/GrafanaLiveEditor.tsx index 3eba6dd409a..bc6fc5bd0bd 100644 --- a/public/app/plugins/datasource/testdata/components/GrafanaLiveEditor.tsx +++ b/public/app/plugins/datasource/testdata/components/GrafanaLiveEditor.tsx @@ -1,6 +1,8 @@ import React from 'react'; -import { InlineField, InlineFieldRow, Select } from '@grafana/ui'; + import { SelectableValue } from '@grafana/data'; +import { InlineField, InlineFieldRow, Select } from '@grafana/ui'; + import { EditorProps } from '../QueryEditor'; const liveTestDataChannels = [ diff --git a/public/app/plugins/datasource/testdata/components/NodeGraphEditor.tsx b/public/app/plugins/datasource/testdata/components/NodeGraphEditor.tsx index 15d436a21b2..398b3f8de23 100644 --- a/public/app/plugins/datasource/testdata/components/NodeGraphEditor.tsx +++ b/public/app/plugins/datasource/testdata/components/NodeGraphEditor.tsx @@ -1,5 +1,7 @@ import React from 'react'; + import { Input, InlineFieldRow, InlineField, Select } from '@grafana/ui'; + import { NodesQuery, TestDataQuery } from '../types'; export interface Props { diff --git a/public/app/plugins/datasource/testdata/components/PredictablePulseEditor.tsx b/public/app/plugins/datasource/testdata/components/PredictablePulseEditor.tsx index 393200f63bd..28e27e86afd 100644 --- a/public/app/plugins/datasource/testdata/components/PredictablePulseEditor.tsx +++ b/public/app/plugins/datasource/testdata/components/PredictablePulseEditor.tsx @@ -1,6 +1,8 @@ import React, { ChangeEvent } from 'react'; -import { EditorProps } from '../QueryEditor'; + import { InlineField, InlineFieldRow, Input } from '@grafana/ui'; + +import { EditorProps } from '../QueryEditor'; import { PulseWaveQuery } from '../types'; const fields = [ diff --git a/public/app/plugins/datasource/testdata/components/RandomWalkEditor.tsx b/public/app/plugins/datasource/testdata/components/RandomWalkEditor.tsx index aa842e4bda6..a99a7ab56ab 100644 --- a/public/app/plugins/datasource/testdata/components/RandomWalkEditor.tsx +++ b/public/app/plugins/datasource/testdata/components/RandomWalkEditor.tsx @@ -1,6 +1,8 @@ import React from 'react'; -import { InlineField, InlineFieldRow, Input } from '@grafana/ui'; + import { selectors } from '@grafana/e2e-selectors'; +import { InlineField, InlineFieldRow, Input } from '@grafana/ui'; + import { EditorProps } from '../QueryEditor'; import { TestDataQuery } from '../types'; diff --git a/public/app/plugins/datasource/testdata/components/RawFrameEditor.tsx b/public/app/plugins/datasource/testdata/components/RawFrameEditor.tsx index ea2ff4d7af9..71678a51d55 100644 --- a/public/app/plugins/datasource/testdata/components/RawFrameEditor.tsx +++ b/public/app/plugins/datasource/testdata/components/RawFrameEditor.tsx @@ -1,9 +1,11 @@ -import React, { useState } from 'react'; -import { Alert, CodeEditor } from '@grafana/ui'; -import { EditorProps } from '../QueryEditor'; import { isArray } from 'lodash'; -import { toDataQueryResponse } from '@grafana/runtime'; +import React, { useState } from 'react'; + import { dataFrameToJSON, toDataFrame, toDataFrameDTO } from '@grafana/data'; +import { toDataQueryResponse } from '@grafana/runtime'; +import { Alert, CodeEditor } from '@grafana/ui'; + +import { EditorProps } from '../QueryEditor'; export const RawFrameEditor = ({ onChange, query }: EditorProps) => { const [error, setError] = useState(); diff --git a/public/app/plugins/datasource/testdata/components/SimulationQueryEditor.tsx b/public/app/plugins/datasource/testdata/components/SimulationQueryEditor.tsx index 6016af7b874..abaca3d4a84 100644 --- a/public/app/plugins/datasource/testdata/components/SimulationQueryEditor.tsx +++ b/public/app/plugins/datasource/testdata/components/SimulationQueryEditor.tsx @@ -1,6 +1,8 @@ +import React, { FormEvent } from 'react'; + import { SelectableValue } from '@grafana/data'; import { InlineField, InlineFieldRow, InlineSwitch, Input, Label, Select } from '@grafana/ui'; -import React, { FormEvent } from 'react'; + import { EditorProps } from '../QueryEditor'; import { SimulationQuery } from '../types'; diff --git a/public/app/plugins/datasource/testdata/components/StreamingClientEditor.tsx b/public/app/plugins/datasource/testdata/components/StreamingClientEditor.tsx index c503648d764..262c13616f1 100644 --- a/public/app/plugins/datasource/testdata/components/StreamingClientEditor.tsx +++ b/public/app/plugins/datasource/testdata/components/StreamingClientEditor.tsx @@ -1,6 +1,8 @@ import React, { ChangeEvent } from 'react'; -import { InlineField, InlineFieldRow, Input, Select } from '@grafana/ui'; + import { SelectableValue } from '@grafana/data'; +import { InlineField, InlineFieldRow, Input, Select } from '@grafana/ui'; + import { EditorProps } from '../QueryEditor'; import { StreamingQuery } from '../types'; diff --git a/public/app/plugins/datasource/testdata/components/USAQueryEditor.tsx b/public/app/plugins/datasource/testdata/components/USAQueryEditor.tsx index 1e9338dd930..160a8223a4f 100644 --- a/public/app/plugins/datasource/testdata/components/USAQueryEditor.tsx +++ b/public/app/plugins/datasource/testdata/components/USAQueryEditor.tsx @@ -1,6 +1,8 @@ import React from 'react'; -import { InlineFieldRow, InlineField, Select, MultiSelect, Input } from '@grafana/ui'; + import { SelectableValue } from '@grafana/data'; +import { InlineFieldRow, InlineField, Select, MultiSelect, Input } from '@grafana/ui'; + import { USAQuery } from '../types'; export interface Props { diff --git a/public/app/plugins/datasource/testdata/datasource.ts b/public/app/plugins/datasource/testdata/datasource.ts index b75d23016be..a2deb9e8641 100644 --- a/public/app/plugins/datasource/testdata/datasource.ts +++ b/public/app/plugins/datasource/testdata/datasource.ts @@ -15,13 +15,14 @@ import { ScopedVars, toDataFrame, } from '@grafana/data'; -import { Scenario, TestDataQuery } from './types'; import { DataSourceWithBackend, getBackendSrv, getGrafanaLiveSrv, getTemplateSrv, TemplateSrv } from '@grafana/runtime'; -import { queryMetricTree } from './metricTree'; -import { runStream } from './runStreams'; import { getSearchFilterScopedVar } from 'app/features/variables/utils'; -import { TestDataVariableSupport } from './variables'; + +import { queryMetricTree } from './metricTree'; import { generateRandomNodes, savedNodesResponse } from './nodeGraphUtils'; +import { runStream } from './runStreams'; +import { Scenario, TestDataQuery } from './types'; +import { TestDataVariableSupport } from './variables'; export class TestDataDataSource extends DataSourceWithBackend { scenariosCache?: Promise; diff --git a/public/app/plugins/datasource/testdata/module.tsx b/public/app/plugins/datasource/testdata/module.tsx index 060e1d08699..df57421b387 100644 --- a/public/app/plugins/datasource/testdata/module.tsx +++ b/public/app/plugins/datasource/testdata/module.tsx @@ -1,8 +1,9 @@ import { DataSourcePlugin } from '@grafana/data'; -import { TestDataDataSource } from './datasource'; -import { TestInfoTab } from './TestInfoTab'; + import { ConfigEditor } from './ConfigEditor'; import { QueryEditor } from './QueryEditor'; +import { TestInfoTab } from './TestInfoTab'; +import { TestDataDataSource } from './datasource'; class TestDataAnnotationsQueryCtrl { annotation: any; diff --git a/public/app/plugins/datasource/testdata/nodeGraphUtils.ts b/public/app/plugins/datasource/testdata/nodeGraphUtils.ts index cb1c50a3e15..adcff512206 100644 --- a/public/app/plugins/datasource/testdata/nodeGraphUtils.ts +++ b/public/app/plugins/datasource/testdata/nodeGraphUtils.ts @@ -6,6 +6,7 @@ import { MutableDataFrame, NodeGraphDataFrameFieldNames, } from '@grafana/data'; + import { nodes, edges } from './testData/serviceMapResponse'; export function generateRandomNodes(count = 10) { diff --git a/public/app/plugins/datasource/testdata/runStreams.ts b/public/app/plugins/datasource/testdata/runStreams.ts index 8ebded83338..a033dd4cdf2 100644 --- a/public/app/plugins/datasource/testdata/runStreams.ts +++ b/public/app/plugins/datasource/testdata/runStreams.ts @@ -12,12 +12,12 @@ import { DataFrameSchema, DataFrameData, } from '@grafana/data'; - -import { TestDataQuery, StreamingQuery } from './types'; -import { getRandomLine } from './LogIpsum'; import { liveTimer } from 'app/features/dashboard/dashgrid/liveTimer'; import { StreamingDataFrame } from 'app/features/live/data/StreamingDataFrame'; +import { getRandomLine } from './LogIpsum'; +import { TestDataQuery, StreamingQuery } from './types'; + export const defaultStreamQuery: StreamingQuery = { type: 'signal', speed: 250, // ms diff --git a/public/app/plugins/datasource/zipkin/ConfigEditor.tsx b/public/app/plugins/datasource/zipkin/ConfigEditor.tsx index 59a00826b8e..267dabcf9fc 100644 --- a/public/app/plugins/datasource/zipkin/ConfigEditor.tsx +++ b/public/app/plugins/datasource/zipkin/ConfigEditor.tsx @@ -1,8 +1,9 @@ +import React from 'react'; + import { DataSourcePluginOptionsEditorProps } from '@grafana/data'; import { DataSourceHttpSettings } from '@grafana/ui'; import { NodeGraphSettings } from 'app/core/components/NodeGraphSettings'; import { TraceToLogsSettings } from 'app/core/components/TraceToLogs/TraceToLogsSettings'; -import React from 'react'; export type Props = DataSourcePluginOptionsEditorProps; diff --git a/public/app/plugins/datasource/zipkin/QueryField.test.tsx b/public/app/plugins/datasource/zipkin/QueryField.test.tsx index 9ab560129b4..d7bc97ddc05 100644 --- a/public/app/plugins/datasource/zipkin/QueryField.test.tsx +++ b/public/app/plugins/datasource/zipkin/QueryField.test.tsx @@ -1,9 +1,11 @@ -import { CascaderOption } from '@grafana/ui'; -import { act, renderHook } from '@testing-library/react-hooks'; import { render, screen } from '@testing-library/react'; +import { act, renderHook } from '@testing-library/react-hooks'; import React from 'react'; -import { ZipkinDatasource } from './datasource'; + +import { CascaderOption } from '@grafana/ui'; + import { ZipkinQueryField, useLoadOptions, useServices } from './QueryField'; +import { ZipkinDatasource } from './datasource'; import { ZipkinQuery } from './types'; describe('QueryField', () => { diff --git a/public/app/plugins/datasource/zipkin/QueryField.tsx b/public/app/plugins/datasource/zipkin/QueryField.tsx index 9f2d112d560..ed63da354e1 100644 --- a/public/app/plugins/datasource/zipkin/QueryField.tsx +++ b/public/app/plugins/datasource/zipkin/QueryField.tsx @@ -1,4 +1,9 @@ import { css } from '@emotion/css'; +import { fromPairs } from 'lodash'; +import React, { useCallback, useMemo, useState } from 'react'; +import { useAsyncFn, useMount, useMountedState } from 'react-use'; +import { AsyncState } from 'react-use/lib/useAsyncFn'; + import { GrafanaTheme2, QueryEditorProps } from '@grafana/data'; import { ButtonCascader, @@ -14,10 +19,7 @@ import { import { notifyApp } from 'app/core/actions'; import { createErrorNotification } from 'app/core/copy/appNotification'; import { dispatch } from 'app/store/store'; -import { fromPairs } from 'lodash'; -import React, { useCallback, useMemo, useState } from 'react'; -import { useAsyncFn, useMount, useMountedState } from 'react-use'; -import { AsyncState } from 'react-use/lib/useAsyncFn'; + import { apiPrefix } from './constants'; import { ZipkinDatasource } from './datasource'; import { ZipkinQuery, ZipkinQueryType, ZipkinSpan } from './types'; diff --git a/public/app/plugins/datasource/zipkin/datasource.test.ts b/public/app/plugins/datasource/zipkin/datasource.test.ts index 707c06942ce..853777a00bb 100644 --- a/public/app/plugins/datasource/zipkin/datasource.test.ts +++ b/public/app/plugins/datasource/zipkin/datasource.test.ts @@ -1,8 +1,9 @@ import { lastValueFrom, of } from 'rxjs'; -import { DataSourceInstanceSettings, FieldType } from '@grafana/data'; - -import { backendSrv } from 'app/core/services/backend_srv'; import { createFetchResponse } from 'test/helpers/createFetchResponse'; + +import { DataSourceInstanceSettings, FieldType } from '@grafana/data'; +import { backendSrv } from 'app/core/services/backend_srv'; + import { ZipkinDatasource } from './datasource'; import mockJson from './mockJsonResponse.json'; import { traceFrameFields, zipkinResponse } from './utils/testData'; diff --git a/public/app/plugins/datasource/zipkin/datasource.ts b/public/app/plugins/datasource/zipkin/datasource.ts index 2c814f6c4ef..81af519b902 100644 --- a/public/app/plugins/datasource/zipkin/datasource.ts +++ b/public/app/plugins/datasource/zipkin/datasource.ts @@ -1,6 +1,6 @@ import { lastValueFrom, Observable, of } from 'rxjs'; import { map } from 'rxjs/operators'; -import { BackendSrvRequest, FetchResponse, getBackendSrv } from '@grafana/runtime'; + import { DataQueryRequest, DataQueryResponse, @@ -10,13 +10,15 @@ import { FieldType, MutableDataFrame, } from '@grafana/data'; +import { BackendSrvRequest, FetchResponse, getBackendSrv } from '@grafana/runtime'; +import { NodeGraphOptions } from 'app/core/components/NodeGraphSettings'; import { serializeParams } from '../../../core/utils/fetch'; + import { apiPrefix } from './constants'; import { ZipkinQuery, ZipkinSpan } from './types'; import { createGraphFrames } from './utils/graphTransform'; import { transformResponse } from './utils/transforms'; -import { NodeGraphOptions } from 'app/core/components/NodeGraphSettings'; export interface ZipkinJsonData extends DataSourceJsonData { nodeGraph?: NodeGraphOptions; diff --git a/public/app/plugins/datasource/zipkin/module.ts b/public/app/plugins/datasource/zipkin/module.ts index 4c77c8acd78..c49eaa0a316 100644 --- a/public/app/plugins/datasource/zipkin/module.ts +++ b/public/app/plugins/datasource/zipkin/module.ts @@ -1,7 +1,8 @@ import { DataSourcePlugin } from '@grafana/data'; -import { ZipkinDatasource } from './datasource'; -import { ZipkinQueryField } from './QueryField'; + import { ConfigEditor } from './ConfigEditor'; +import { ZipkinQueryField } from './QueryField'; +import { ZipkinDatasource } from './datasource'; export const plugin = new DataSourcePlugin(ZipkinDatasource) .setQueryEditor(ZipkinQueryField) diff --git a/public/app/plugins/datasource/zipkin/utils/graphTransform.test.ts b/public/app/plugins/datasource/zipkin/utils/graphTransform.test.ts index ab5bb91945b..8fb47987ad5 100644 --- a/public/app/plugins/datasource/zipkin/utils/graphTransform.test.ts +++ b/public/app/plugins/datasource/zipkin/utils/graphTransform.test.ts @@ -1,3 +1,5 @@ +import { ZipkinSpan } from '../types'; + import { createGraphFrames } from './graphTransform'; import { testResponse, @@ -6,7 +8,6 @@ import { toEdgesFrame, toNodesFrame, } from './testResponse'; -import { ZipkinSpan } from '../types'; describe('createGraphFrames', () => { it('transforms basic response into nodes and edges frame', async () => { diff --git a/public/app/plugins/datasource/zipkin/utils/graphTransform.ts b/public/app/plugins/datasource/zipkin/utils/graphTransform.ts index 0efa6f9cb21..03e441b97b9 100644 --- a/public/app/plugins/datasource/zipkin/utils/graphTransform.ts +++ b/public/app/plugins/datasource/zipkin/utils/graphTransform.ts @@ -1,6 +1,7 @@ import { DataFrame, NodeGraphDataFrameFieldNames as Fields } from '@grafana/data'; -import { ZipkinSpan } from '../types'; + import { getNonOverlappingDuration, getStats, makeFrames, makeSpanMap } from '../../../../core/utils/tracing'; +import { ZipkinSpan } from '../types'; interface Node { [Fields.id]: string; diff --git a/public/app/plugins/datasource/zipkin/utils/testData.ts b/public/app/plugins/datasource/zipkin/utils/testData.ts index b49e451f44f..4b01da687e7 100644 --- a/public/app/plugins/datasource/zipkin/utils/testData.ts +++ b/public/app/plugins/datasource/zipkin/utils/testData.ts @@ -1,4 +1,5 @@ import { ArrayVector } from '@grafana/data'; + import { ZipkinSpan } from '../types'; export const zipkinResponse: ZipkinSpan[] = [ diff --git a/public/app/plugins/datasource/zipkin/utils/testResponse.ts b/public/app/plugins/datasource/zipkin/utils/testResponse.ts index 7a6ba459102..50085bdf970 100644 --- a/public/app/plugins/datasource/zipkin/utils/testResponse.ts +++ b/public/app/plugins/datasource/zipkin/utils/testResponse.ts @@ -1,4 +1,5 @@ import { ArrayVector, FieldDTO } from '@grafana/data'; + import { ZipkinSpan } from '../types'; export const testResponse: ZipkinSpan[] = [ diff --git a/public/app/plugins/datasource/zipkin/utils/transforms.test.ts b/public/app/plugins/datasource/zipkin/utils/transforms.test.ts index 169ada60de7..9973ac731e5 100644 --- a/public/app/plugins/datasource/zipkin/utils/transforms.test.ts +++ b/public/app/plugins/datasource/zipkin/utils/transforms.test.ts @@ -1,7 +1,8 @@ -import { transformResponse, transformToZipkin } from './transforms'; -import { traceFrameFields, zipkinResponse } from './testData'; import { MutableDataFrame } from '@grafana/data'; +import { traceFrameFields, zipkinResponse } from './testData'; +import { transformResponse, transformToZipkin } from './transforms'; + describe('transformResponse', () => { it('transforms response', () => { const dataFrame = transformResponse(zipkinResponse); diff --git a/public/app/plugins/datasource/zipkin/utils/transforms.ts b/public/app/plugins/datasource/zipkin/utils/transforms.ts index 0568875c936..81e40508e3f 100644 --- a/public/app/plugins/datasource/zipkin/utils/transforms.ts +++ b/public/app/plugins/datasource/zipkin/utils/transforms.ts @@ -1,7 +1,9 @@ import { identity } from 'lodash'; -import { ZipkinAnnotation, ZipkinEndpoint, ZipkinSpan } from '../types'; + import { DataFrame, FieldType, MutableDataFrame, TraceKeyValuePair, TraceLog, TraceSpanRow } from '@grafana/data'; +import { ZipkinAnnotation, ZipkinEndpoint, ZipkinSpan } from '../types'; + /** * Transforms response to Grafana trace data frame. */ diff --git a/public/app/plugins/panel/alertGroups/AlertGroup.tsx b/public/app/plugins/panel/alertGroups/AlertGroup.tsx index 04f94548cf0..a117c53a8e7 100644 --- a/public/app/plugins/panel/alertGroups/AlertGroup.tsx +++ b/public/app/plugins/panel/alertGroups/AlertGroup.tsx @@ -1,14 +1,14 @@ -import { AlertmanagerGroup, AlertState } from 'app/plugins/datasource/alertmanager/types'; +import { css } from '@emotion/css'; import React, { useState, useEffect } from 'react'; + import { GrafanaTheme2, intervalToAbbreviatedDurationString } from '@grafana/data'; import { useStyles2, LinkButton } from '@grafana/ui'; -import { css } from '@emotion/css'; - import { AlertLabels } from 'app/features/alerting/unified/components/AlertLabels'; -import { AlertGroupHeader } from 'app/features/alerting/unified/components/alert-groups/AlertGroupHeader'; import { CollapseToggle } from 'app/features/alerting/unified/components/CollapseToggle'; +import { AlertGroupHeader } from 'app/features/alerting/unified/components/alert-groups/AlertGroupHeader'; import { getNotificationsTextColors } from 'app/features/alerting/unified/styles/notifications'; import { makeAMLink, makeLabelBasedSilenceLink } from 'app/features/alerting/unified/utils/misc'; +import { AlertmanagerGroup, AlertState } from 'app/plugins/datasource/alertmanager/types'; type Props = { alertManagerSourceName: string; diff --git a/public/app/plugins/panel/alertGroups/AlertGroupsPanel.test.tsx b/public/app/plugins/panel/alertGroups/AlertGroupsPanel.test.tsx index 7c8c737eb2c..fb373206a47 100644 --- a/public/app/plugins/panel/alertGroups/AlertGroupsPanel.test.tsx +++ b/public/app/plugins/panel/alertGroups/AlertGroupsPanel.test.tsx @@ -1,11 +1,10 @@ +import { render, waitFor } from '@testing-library/react'; import React from 'react'; import { Provider } from 'react-redux'; -import { AlertGroupsPanel } from './AlertGroupsPanel'; -import { setDataSourceSrv } from '@grafana/runtime'; import { byTestId } from 'testing-library-selector'; -import { configureStore } from 'app/store/configureStore'; -import { AlertGroupPanelOptions } from './types'; + import { getDefaultTimeRange, LoadingState, PanelProps, FieldConfigSource } from '@grafana/data'; +import { setDataSourceSrv } from '@grafana/runtime'; import { fetchAlertGroups } from 'app/features/alerting/unified/api/alertmanager'; import { mockAlertGroup, @@ -15,7 +14,10 @@ import { } from 'app/features/alerting/unified/mocks'; import { DataSourceType } from 'app/features/alerting/unified/utils/datasource'; import { setDashboardSrv } from 'app/features/dashboard/services/DashboardSrv'; -import { render, waitFor } from '@testing-library/react'; +import { configureStore } from 'app/store/configureStore'; + +import { AlertGroupsPanel } from './AlertGroupsPanel'; +import { AlertGroupPanelOptions } from './types'; jest.mock('app/features/alerting/unified/api/alertmanager'); diff --git a/public/app/plugins/panel/alertGroups/AlertGroupsPanel.tsx b/public/app/plugins/panel/alertGroups/AlertGroupsPanel.tsx index ed1dd043e18..f03a18b217e 100644 --- a/public/app/plugins/panel/alertGroups/AlertGroupsPanel.tsx +++ b/public/app/plugins/panel/alertGroups/AlertGroupsPanel.tsx @@ -1,18 +1,18 @@ import React, { useEffect } from 'react'; import { useDispatch } from 'react-redux'; -import { PanelProps } from '@grafana/data'; -import { CustomScrollbar } from '@grafana/ui'; -import { config } from '@grafana/runtime'; -import { AlertmanagerGroup, Matcher } from 'app/plugins/datasource/alertmanager/types'; -import { fetchAlertGroupsAction } from 'app/features/alerting/unified/state/actions'; -import { initialAsyncRequestState } from 'app/features/alerting/unified/utils/redux'; -import { NOTIFICATIONS_POLL_INTERVAL_MS } from 'app/features/alerting/unified/utils/constants'; +import { PanelProps } from '@grafana/data'; +import { config } from '@grafana/runtime'; +import { CustomScrollbar } from '@grafana/ui'; import { useUnifiedAlertingSelector } from 'app/features/alerting/unified/hooks/useUnifiedAlertingSelector'; +import { fetchAlertGroupsAction } from 'app/features/alerting/unified/state/actions'; +import { parseMatchers } from 'app/features/alerting/unified/utils/alertmanager'; +import { NOTIFICATIONS_POLL_INTERVAL_MS } from 'app/features/alerting/unified/utils/constants'; +import { initialAsyncRequestState } from 'app/features/alerting/unified/utils/redux'; +import { AlertmanagerGroup, Matcher } from 'app/plugins/datasource/alertmanager/types'; import { AlertGroup } from './AlertGroup'; import { AlertGroupPanelOptions } from './types'; -import { parseMatchers } from 'app/features/alerting/unified/utils/alertmanager'; import { useFilteredGroups } from './useFilteredGroups'; export const AlertGroupsPanel = (props: PanelProps) => { diff --git a/public/app/plugins/panel/alertGroups/module.tsx b/public/app/plugins/panel/alertGroups/module.tsx index d1a8ef6b88f..94ccb5c7e26 100644 --- a/public/app/plugins/panel/alertGroups/module.tsx +++ b/public/app/plugins/panel/alertGroups/module.tsx @@ -1,10 +1,12 @@ import React from 'react'; + import { PanelPlugin } from '@grafana/data'; -import { AlertGroupPanelOptions } from './types'; -import { AlertGroupsPanel } from './AlertGroupsPanel'; import { AlertManagerPicker } from 'app/features/alerting/unified/components/AlertManagerPicker'; import { GRAFANA_RULES_SOURCE_NAME } from 'app/features/alerting/unified/utils/datasource'; +import { AlertGroupsPanel } from './AlertGroupsPanel'; +import { AlertGroupPanelOptions } from './types'; + export const plugin = new PanelPlugin(AlertGroupsPanel).setPanelOptions((builder) => { return builder .addCustomEditor({ diff --git a/public/app/plugins/panel/alertGroups/useFilteredGroups.ts b/public/app/plugins/panel/alertGroups/useFilteredGroups.ts index ac3c111d63b..b2aad016a62 100644 --- a/public/app/plugins/panel/alertGroups/useFilteredGroups.ts +++ b/public/app/plugins/panel/alertGroups/useFilteredGroups.ts @@ -1,6 +1,7 @@ +import { useMemo } from 'react'; + import { labelsMatchMatchers } from 'app/features/alerting/unified/utils/alertmanager'; import { AlertmanagerGroup, Matcher } from 'app/plugins/datasource/alertmanager/types'; -import { useMemo } from 'react'; export const useFilteredGroups = (groups: AlertmanagerGroup[], matchers: Matcher[]): AlertmanagerGroup[] => { return useMemo(() => { diff --git a/public/app/plugins/panel/alertlist/AlertInstances.tsx b/public/app/plugins/panel/alertlist/AlertInstances.tsx index 269a3ca0a92..8fd3cd5dfe6 100644 --- a/public/app/plugins/panel/alertlist/AlertInstances.tsx +++ b/public/app/plugins/panel/alertlist/AlertInstances.tsx @@ -1,12 +1,14 @@ -import React, { FC, useCallback, useMemo, useState } from 'react'; -import pluralize from 'pluralize'; -import { Icon, useStyles2 } from '@grafana/ui'; -import { Alert } from 'app/types/unified-alerting'; -import { GrafanaTheme2, PanelProps } from '@grafana/data'; import { css } from '@emotion/css'; -import { GroupMode, UnifiedAlertListOptions } from './types'; +import pluralize from 'pluralize'; +import React, { FC, useCallback, useMemo, useState } from 'react'; + +import { GrafanaTheme2, PanelProps } from '@grafana/data'; +import { Icon, useStyles2 } from '@grafana/ui'; import { AlertInstancesTable } from 'app/features/alerting/unified/components/rules/AlertInstancesTable'; import { sortAlerts } from 'app/features/alerting/unified/utils/misc'; +import { Alert } from 'app/types/unified-alerting'; + +import { GroupMode, UnifiedAlertListOptions } from './types'; import { filterAlerts } from './util'; interface Props { diff --git a/public/app/plugins/panel/alertlist/AlertList.tsx b/public/app/plugins/panel/alertlist/AlertList.tsx index b2f6abe28bb..7fb813a03b8 100644 --- a/public/app/plugins/panel/alertlist/AlertList.tsx +++ b/public/app/plugins/panel/alertlist/AlertList.tsx @@ -1,13 +1,15 @@ -import React, { useState } from 'react'; -import { sortBy } from 'lodash'; -import { dateMath, dateTime, GrafanaTheme, PanelProps } from '@grafana/data'; -import { Card, CustomScrollbar, Icon, stylesFactory, useStyles } from '@grafana/ui'; import { css, cx } from '@emotion/css'; -import { getBackendSrv, getTemplateSrv } from '@grafana/runtime'; +import { sortBy } from 'lodash'; +import React, { useState } from 'react'; import { useAsync } from 'react-use'; + +import { dateMath, dateTime, GrafanaTheme, PanelProps } from '@grafana/data'; +import { getBackendSrv, getTemplateSrv } from '@grafana/runtime'; +import { Card, CustomScrollbar, Icon, stylesFactory, useStyles } from '@grafana/ui'; import alertDef from 'app/features/alerting/state/alertDef'; -import { AlertRuleDTO, AnnotationItemDTO } from 'app/types'; import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv'; +import { AlertRuleDTO, AnnotationItemDTO } from 'app/types'; + import { AlertListOptions, ShowOption, SortOrder } from './types'; export function AlertList(props: PanelProps) { diff --git a/public/app/plugins/panel/alertlist/AlertListMigration.test.ts b/public/app/plugins/panel/alertlist/AlertListMigration.test.ts index 886d405867a..d8cf303def8 100644 --- a/public/app/plugins/panel/alertlist/AlertListMigration.test.ts +++ b/public/app/plugins/panel/alertlist/AlertListMigration.test.ts @@ -1,4 +1,5 @@ import { PanelModel } from '@grafana/data'; + import { alertListPanelMigrationHandler } from './AlertListMigrationHandler'; import { AlertListOptions, ShowOption, SortOrder } from './types'; diff --git a/public/app/plugins/panel/alertlist/AlertListMigrationHandler.ts b/public/app/plugins/panel/alertlist/AlertListMigrationHandler.ts index 5c6ba77c527..2fccfa8ddb5 100644 --- a/public/app/plugins/panel/alertlist/AlertListMigrationHandler.ts +++ b/public/app/plugins/panel/alertlist/AlertListMigrationHandler.ts @@ -1,4 +1,5 @@ import { PanelModel } from '@grafana/data'; + import { AlertListOptions, ShowOption, SortOrder } from './types'; export const alertListPanelMigrationHandler = ( diff --git a/public/app/plugins/panel/alertlist/GroupByWithLoading.tsx b/public/app/plugins/panel/alertlist/GroupByWithLoading.tsx index 8a84dcaa55d..ed3fddc20bb 100644 --- a/public/app/plugins/panel/alertlist/GroupByWithLoading.tsx +++ b/public/app/plugins/panel/alertlist/GroupByWithLoading.tsx @@ -1,18 +1,20 @@ -import React, { FC, useEffect, useMemo } from 'react'; import { isEmpty, uniq } from 'lodash'; -import { Icon, MultiSelect } from '@grafana/ui'; -import { SelectableValue } from '@grafana/data'; +import React, { FC, useEffect, useMemo } from 'react'; import { useDispatch } from 'react-redux'; -import { fetchAllPromRulesAction } from 'app/features/alerting/unified/state/actions'; + +import { SelectableValue } from '@grafana/data'; +import { Icon, MultiSelect } from '@grafana/ui'; import { useUnifiedAlertingSelector } from 'app/features/alerting/unified/hooks/useUnifiedAlertingSelector'; +import { fetchAllPromRulesAction } from 'app/features/alerting/unified/state/actions'; import { getAllRulesSourceNames } from 'app/features/alerting/unified/utils/datasource'; -import { PromRuleType } from 'app/types/unified-alerting-dto'; -import { AlertingRule } from 'app/types/unified-alerting'; -import { isPrivateLabel } from './util'; import { isAsyncRequestMapSliceFulfilled, isAsyncRequestMapSlicePending, } from 'app/features/alerting/unified/utils/redux'; +import { AlertingRule } from 'app/types/unified-alerting'; +import { PromRuleType } from 'app/types/unified-alerting-dto'; + +import { isPrivateLabel } from './util'; interface Props { id: string; diff --git a/public/app/plugins/panel/alertlist/UnifiedAlertList.tsx b/public/app/plugins/panel/alertlist/UnifiedAlertList.tsx index 3c18c0e2b2e..da0feae77c7 100644 --- a/public/app/plugins/panel/alertlist/UnifiedAlertList.tsx +++ b/public/app/plugins/panel/alertlist/UnifiedAlertList.tsx @@ -1,28 +1,28 @@ -import React, { useEffect, useMemo } from 'react'; +import { css } from '@emotion/css'; import { sortBy } from 'lodash'; +import React, { useEffect, useMemo } from 'react'; import { useDispatch } from 'react-redux'; + import { GrafanaTheme2, PanelProps } from '@grafana/data'; import { CustomScrollbar, LoadingPlaceholder, useStyles2 } from '@grafana/ui'; -import { css } from '@emotion/css'; - import alertDef from 'app/features/alerting/state/alertDef'; -import { GroupMode, SortOrder, UnifiedAlertListOptions } from './types'; - -import { flattenRules, getFirstActiveAt } from 'app/features/alerting/unified/utils/rules'; -import { PromRuleWithLocation } from 'app/types/unified-alerting'; -import { fetchAllPromRulesAction } from 'app/features/alerting/unified/state/actions'; import { useUnifiedAlertingSelector } from 'app/features/alerting/unified/hooks/useUnifiedAlertingSelector'; +import { fetchAllPromRulesAction } from 'app/features/alerting/unified/state/actions'; +import { labelsMatchMatchers, parseMatchers } from 'app/features/alerting/unified/utils/alertmanager'; +import { Annotation, RULE_LIST_POLL_INTERVAL_MS } from 'app/features/alerting/unified/utils/constants'; import { getAllRulesSourceNames, GRAFANA_DATASOURCE_NAME, GRAFANA_RULES_SOURCE_NAME, } from 'app/features/alerting/unified/utils/datasource'; +import { flattenRules, getFirstActiveAt } from 'app/features/alerting/unified/utils/rules'; import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv'; -import { Annotation, RULE_LIST_POLL_INTERVAL_MS } from 'app/features/alerting/unified/utils/constants'; +import { PromRuleWithLocation } from 'app/types/unified-alerting'; import { PromAlertingRuleState } from 'app/types/unified-alerting-dto'; -import { labelsMatchMatchers, parseMatchers } from 'app/features/alerting/unified/utils/alertmanager'; -import UngroupedModeView from './unified-alerting/UngroupedView'; + +import { GroupMode, SortOrder, UnifiedAlertListOptions } from './types'; import GroupedModeView from './unified-alerting/GroupedView'; +import UngroupedModeView from './unified-alerting/UngroupedView'; export function UnifiedAlertList(props: PanelProps) { const dispatch = useDispatch(); diff --git a/public/app/plugins/panel/alertlist/module.tsx b/public/app/plugins/panel/alertlist/module.tsx index 30e504971ea..0b3bf28ae80 100644 --- a/public/app/plugins/panel/alertlist/module.tsx +++ b/public/app/plugins/panel/alertlist/module.tsx @@ -1,19 +1,22 @@ import React from 'react'; + import { PanelPlugin } from '@grafana/data'; -import { TagsInput } from '@grafana/ui'; -import { AlertList } from './AlertList'; -import { UnifiedAlertList } from './UnifiedAlertList'; -import { AlertListOptions, GroupMode, ShowOption, SortOrder, UnifiedAlertListOptions } from './types'; -import { alertListPanelMigrationHandler } from './AlertListMigrationHandler'; import { config, DataSourcePicker } from '@grafana/runtime'; +import { TagsInput } from '@grafana/ui'; import { RuleFolderPicker } from 'app/features/alerting/unified/components/rule-editor/RuleFolderPicker'; + import { ALL_FOLDER, GENERAL_FOLDER, ReadonlyFolderPicker, } from '../../../core/components/Select/ReadonlyFolderPicker/ReadonlyFolderPicker'; -import { AlertListSuggestionsSupplier } from './suggestions'; + +import { AlertList } from './AlertList'; +import { alertListPanelMigrationHandler } from './AlertListMigrationHandler'; import { GroupBy } from './GroupByWithLoading'; +import { UnifiedAlertList } from './UnifiedAlertList'; +import { AlertListSuggestionsSupplier } from './suggestions'; +import { AlertListOptions, GroupMode, ShowOption, SortOrder, UnifiedAlertListOptions } from './types'; function showIfCurrentState(options: AlertListOptions) { return options.showOptions === ShowOption.Current; diff --git a/public/app/plugins/panel/alertlist/suggestions.ts b/public/app/plugins/panel/alertlist/suggestions.ts index 7c70b648898..dbae9066a16 100644 --- a/public/app/plugins/panel/alertlist/suggestions.ts +++ b/public/app/plugins/panel/alertlist/suggestions.ts @@ -1,4 +1,5 @@ import { VisualizationSuggestionsBuilder } from '@grafana/data'; + import { AlertListOptions } from './types'; export class AlertListSuggestionsSupplier { diff --git a/public/app/plugins/panel/alertlist/unified-alerting/GroupedView.tsx b/public/app/plugins/panel/alertlist/unified-alerting/GroupedView.tsx index fc2995361e1..2f3106fd3d0 100644 --- a/public/app/plugins/panel/alertlist/unified-alerting/GroupedView.tsx +++ b/public/app/plugins/panel/alertlist/unified-alerting/GroupedView.tsx @@ -1,11 +1,13 @@ import React, { FC, useMemo } from 'react'; + import { useStyles2 } from '@grafana/ui'; import { AlertLabel } from 'app/features/alerting/unified/components/AlertLabel'; -import { AlertInstances } from '../AlertInstances'; -import { GroupedRules, UnifiedAlertListOptions } from '../types'; -import { getStyles } from '../UnifiedAlertList'; import { PromRuleWithLocation } from 'app/types/unified-alerting'; +import { AlertInstances } from '../AlertInstances'; +import { getStyles } from '../UnifiedAlertList'; +import { GroupedRules, UnifiedAlertListOptions } from '../types'; + type GroupedModeProps = { rules: PromRuleWithLocation[]; options: UnifiedAlertListOptions; diff --git a/public/app/plugins/panel/alertlist/unified-alerting/UngroupedView.tsx b/public/app/plugins/panel/alertlist/unified-alerting/UngroupedView.tsx index 8588ec7062f..76805f618d0 100644 --- a/public/app/plugins/panel/alertlist/unified-alerting/UngroupedView.tsx +++ b/public/app/plugins/panel/alertlist/unified-alerting/UngroupedView.tsx @@ -1,14 +1,16 @@ import { css } from '@emotion/css'; +import React, { FC } from 'react'; + import { GrafanaTheme2, intervalToAbbreviatedDurationString } from '@grafana/data'; import { Icon, IconName, useStyles2 } from '@grafana/ui'; import alertDef from 'app/features/alerting/state/alertDef'; import { alertStateToState, getFirstActiveAt } from 'app/features/alerting/unified/utils/rules'; import { PromRuleWithLocation } from 'app/types/unified-alerting'; import { PromAlertingRuleState } from 'app/types/unified-alerting-dto'; -import React, { FC } from 'react'; + import { AlertInstances } from '../AlertInstances'; -import { UnifiedAlertListOptions } from '../types'; import { getStyles } from '../UnifiedAlertList'; +import { UnifiedAlertListOptions } from '../types'; type UngroupedModeProps = { rules: PromRuleWithLocation[]; diff --git a/public/app/plugins/panel/alertlist/util.ts b/public/app/plugins/panel/alertlist/util.ts index 7d00f2237a3..82210cfc44b 100644 --- a/public/app/plugins/panel/alertlist/util.ts +++ b/public/app/plugins/panel/alertlist/util.ts @@ -1,7 +1,9 @@ +import { isEmpty } from 'lodash'; + import { PanelProps } from '@grafana/data'; import { Alert } from 'app/types/unified-alerting'; import { GrafanaAlertState, PromAlertingRuleState } from 'app/types/unified-alerting-dto'; -import { isEmpty } from 'lodash'; + import { UnifiedAlertListOptions } from './types'; export function filterAlerts(options: PanelProps['options'], alerts: Alert[]): Alert[] { diff --git a/public/app/plugins/panel/annolist/AnnoListPanel.test.tsx b/public/app/plugins/panel/annolist/AnnoListPanel.test.tsx index e7ace69adda..ddacc3dbcbf 100644 --- a/public/app/plugins/panel/annolist/AnnoListPanel.test.tsx +++ b/public/app/plugins/panel/annolist/AnnoListPanel.test.tsx @@ -1,14 +1,16 @@ -import React from 'react'; import { render, screen, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import React from 'react'; + +import { AnnotationEvent, FieldConfigSource, getDefaultTimeRange, LoadingState } from '@grafana/data'; +import { locationService } from '@grafana/runtime'; + +import { silenceConsoleOutput } from '../../../../test/core/utils/silenceConsoleOutput'; +import { backendSrv } from '../../../core/services/backend_srv'; +import { setDashboardSrv } from '../../../features/dashboard/services/DashboardSrv'; import { AnnoListPanel, Props } from './AnnoListPanel'; -import { AnnotationEvent, FieldConfigSource, getDefaultTimeRange, LoadingState } from '@grafana/data'; import { AnnoOptions } from './types'; -import { backendSrv } from '../../../core/services/backend_srv'; -import userEvent from '@testing-library/user-event'; -import { silenceConsoleOutput } from '../../../../test/core/utils/silenceConsoleOutput'; -import { setDashboardSrv } from '../../../features/dashboard/services/DashboardSrv'; -import { locationService } from '@grafana/runtime'; jest.mock('@grafana/runtime', () => ({ ...(jest.requireActual('@grafana/runtime') as unknown as object), diff --git a/public/app/plugins/panel/annolist/AnnoListPanel.tsx b/public/app/plugins/panel/annolist/AnnoListPanel.tsx index 705377ce072..f9825179166 100644 --- a/public/app/plugins/panel/annolist/AnnoListPanel.tsx +++ b/public/app/plugins/panel/annolist/AnnoListPanel.tsx @@ -1,7 +1,8 @@ -// Libraries +import { css } from '@emotion/css'; +import { FocusScope } from '@react-aria/focus'; import React, { PureComponent } from 'react'; -// Types -import { AnnoOptions } from './types'; +import { Subscription } from 'rxjs'; + import { AnnotationChangeEvent, AnnotationEvent, @@ -13,14 +14,13 @@ import { PanelProps, } from '@grafana/data'; import { config, getBackendSrv, locationService } from '@grafana/runtime'; -import { AbstractList } from '@grafana/ui/src/components/List/AbstractList'; -import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv'; -import appEvents from 'app/core/app_events'; -import { AnnotationListItem } from './AnnotationListItem'; import { CustomScrollbar, stylesFactory, TagList } from '@grafana/ui'; -import { css } from '@emotion/css'; -import { Subscription } from 'rxjs'; -import { FocusScope } from '@react-aria/focus'; +import { AbstractList } from '@grafana/ui/src/components/List/AbstractList'; +import appEvents from 'app/core/app_events'; +import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv'; + +import { AnnotationListItem } from './AnnotationListItem'; +import { AnnoOptions } from './types'; interface UserInfo { id?: number; diff --git a/public/app/plugins/panel/annolist/AnnotationListItem.tsx b/public/app/plugins/panel/annolist/AnnotationListItem.tsx index 43a5d3a0e32..75f181eedb7 100644 --- a/public/app/plugins/panel/annolist/AnnotationListItem.tsx +++ b/public/app/plugins/panel/annolist/AnnotationListItem.tsx @@ -1,7 +1,9 @@ -import React, { FC, MouseEvent } from 'react'; import { css } from '@emotion/css'; +import React, { FC, MouseEvent } from 'react'; + import { AnnotationEvent, DateTimeInput, GrafanaTheme2, PanelProps } from '@grafana/data'; import { Card, TagList, Tooltip, useStyles2 } from '@grafana/ui'; + import { AnnoOptions } from './types'; interface Props extends Pick, 'options'> { diff --git a/public/app/plugins/panel/annolist/module.tsx b/public/app/plugins/panel/annolist/module.tsx index 52988de51f3..acb17876fb6 100644 --- a/public/app/plugins/panel/annolist/module.tsx +++ b/public/app/plugins/panel/annolist/module.tsx @@ -1,9 +1,11 @@ +import { truncate } from '@sentry/utils'; import React from 'react'; + import { PanelModel, PanelPlugin } from '@grafana/data'; import { TagsInput } from '@grafana/ui'; + import { AnnoListPanel } from './AnnoListPanel'; import { AnnoOptions } from './types'; -import { truncate } from '@sentry/utils'; export const plugin = new PanelPlugin(AnnoListPanel) .setPanelOptions((builder) => { diff --git a/public/app/plugins/panel/barchart/BarChartPanel.tsx b/public/app/plugins/panel/barchart/BarChartPanel.tsx index 61515d561b7..b8058520cdd 100755 --- a/public/app/plugins/panel/barchart/BarChartPanel.tsx +++ b/public/app/plugins/panel/barchart/BarChartPanel.tsx @@ -1,6 +1,6 @@ -import React, { useMemo, useRef, useState } from 'react'; import { css } from '@emotion/css'; -import { LegendDisplayMode } from '@grafana/schema'; +import React, { useMemo, useRef, useState } from 'react'; + import { CartesianCoords2D, compareDataFrameStructures, @@ -11,6 +11,8 @@ import { TimeRange, VizOrientation, } from '@grafana/data'; +import { PanelDataErrorView } from '@grafana/runtime'; +import { LegendDisplayMode } from '@grafana/schema'; import { GraphNG, GraphNGProps, @@ -26,15 +28,15 @@ import { VizLegend, VizTooltipContainer, } from '@grafana/ui'; -import { PanelDataErrorView } from '@grafana/runtime'; import { PropDiffFn } from '@grafana/ui/src/components/GraphNG/GraphNG'; +import { CloseButton } from 'app/core/components/CloseButton/CloseButton'; -import { PanelOptions } from './models.gen'; -import { prepareBarChartDisplayValues, preparePlotConfigBuilder } from './utils'; import { DataHoverView } from '../geomap/components/DataHoverView'; import { getFieldLegendItem } from '../state-timeline/utils'; -import { CloseButton } from 'app/core/components/CloseButton/CloseButton'; + import { HoverEvent, setupConfig } from './config'; +import { PanelOptions } from './models.gen'; +import { prepareBarChartDisplayValues, preparePlotConfigBuilder } from './utils'; const TOOLTIP_OFFSET = 10; diff --git a/public/app/plugins/panel/barchart/TickSpacingEditor.tsx b/public/app/plugins/panel/barchart/TickSpacingEditor.tsx index 01168ab0fc0..a4564cc78d0 100644 --- a/public/app/plugins/panel/barchart/TickSpacingEditor.tsx +++ b/public/app/plugins/panel/barchart/TickSpacingEditor.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { SelectableValue, StandardEditorProps } from '@grafana/data'; import { Checkbox, HorizontalGroup, RadioButtonGroup, Tooltip } from '@grafana/ui'; diff --git a/public/app/plugins/panel/barchart/bars.ts b/public/app/plugins/panel/barchart/bars.ts index 316baf93ecb..841b20cc411 100644 --- a/public/app/plugins/panel/barchart/bars.ts +++ b/public/app/plugins/panel/barchart/bars.ts @@ -1,8 +1,7 @@ import uPlot, { Axis, AlignedData, Scale } from 'uplot'; -import { intersects, pointWithin, Quadtree, Rect } from './quadtree'; -import { distribute, SPACE_BETWEEN } from './distribute'; + import { DataFrame, GrafanaTheme2 } from '@grafana/data'; -import { measureText, PlotTooltipInterpolator } from '@grafana/ui'; +import { alpha } from '@grafana/data/src/themes/colorManipulator'; import { StackingMode, VisibilityMode, @@ -11,10 +10,14 @@ import { VizTextDisplayOptions, VizLegendOptions, } from '@grafana/schema'; -import { preparePlotData2, StackingGroup } from '../../../../../packages/grafana-ui/src/components/uPlot/utils'; -import { alpha } from '@grafana/data/src/themes/colorManipulator'; +import { measureText, PlotTooltipInterpolator } from '@grafana/ui'; import { formatTime } from '@grafana/ui/src/components/uPlot/config/UPlotAxisBuilder'; +import { preparePlotData2, StackingGroup } from '../../../../../packages/grafana-ui/src/components/uPlot/utils'; + +import { distribute, SPACE_BETWEEN } from './distribute'; +import { intersects, pointWithin, Quadtree, Rect } from './quadtree'; + const groupDistr = SPACE_BETWEEN; const barDistr = SPACE_BETWEEN; // min.max font size for value label diff --git a/public/app/plugins/panel/barchart/config.ts b/public/app/plugins/panel/barchart/config.ts index 44652526236..1b8d0b818eb 100644 --- a/public/app/plugins/panel/barchart/config.ts +++ b/public/app/plugins/panel/barchart/config.ts @@ -1,7 +1,8 @@ import { Dispatch, MutableRefObject, SetStateAction } from 'react'; + +import { CartesianCoords2D } from '@grafana/data'; import { UPlotConfigBuilder } from '@grafana/ui'; import { positionTooltip } from '@grafana/ui/src/components/uPlot/plugins/TooltipPlugin'; -import { CartesianCoords2D } from '@grafana/data'; export type HoverEvent = { xIndex: number; diff --git a/public/app/plugins/panel/barchart/module.tsx b/public/app/plugins/panel/barchart/module.tsx index 3dc4e97dbbb..9b2e39b0ae4 100755 --- a/public/app/plugins/panel/barchart/module.tsx +++ b/public/app/plugins/panel/barchart/module.tsx @@ -7,14 +7,15 @@ import { PanelPlugin, VizOrientation, } from '@grafana/data'; -import { BarChartPanel } from './BarChartPanel'; +import { config } from '@grafana/runtime'; import { StackingMode, VisibilityMode } from '@grafana/schema'; import { graphFieldOptions, commonOptionsBuilder } from '@grafana/ui'; + +import { BarChartPanel } from './BarChartPanel'; +import { TickSpacingEditor } from './TickSpacingEditor'; import { BarChartFieldConfig, PanelOptions, defaultBarChartFieldConfig, defaultPanelOptions } from './models.gen'; import { BarChartSuggestionsSupplier } from './suggestions'; import { prepareBarChartDisplayValues } from './utils'; -import { config } from '@grafana/runtime'; -import { TickSpacingEditor } from './TickSpacingEditor'; export const plugin = new PanelPlugin(BarChartPanel) .useFieldConfig({ diff --git a/public/app/plugins/panel/barchart/suggestions.ts b/public/app/plugins/panel/barchart/suggestions.ts index 850435df26d..c5631671f72 100644 --- a/public/app/plugins/panel/barchart/suggestions.ts +++ b/public/app/plugins/panel/barchart/suggestions.ts @@ -1,6 +1,7 @@ import { VisualizationSuggestionsBuilder, VizOrientation } from '@grafana/data'; import { LegendDisplayMode, StackingMode, VisibilityMode } from '@grafana/schema'; import { SuggestionName } from 'app/types/suggestions'; + import { BarChartFieldConfig, PanelOptions } from './models.gen'; export class BarChartSuggestionsSupplier { diff --git a/public/app/plugins/panel/barchart/utils.test.ts b/public/app/plugins/panel/barchart/utils.test.ts index 6fdfbbbd107..9bd75fe23db 100644 --- a/public/app/plugins/panel/barchart/utils.test.ts +++ b/public/app/plugins/panel/barchart/utils.test.ts @@ -1,12 +1,3 @@ -import { BarChartOptionsEX, prepareBarChartDisplayValues, preparePlotConfigBuilder } from './utils'; -import { - LegendDisplayMode, - TooltipDisplayMode, - VisibilityMode, - GraphGradientMode, - StackingMode, - SortOrder, -} from '@grafana/schema'; import { createTheme, DefaultTimeZone, @@ -17,7 +8,17 @@ import { MutableDataFrame, VizOrientation, } from '@grafana/data'; +import { + LegendDisplayMode, + TooltipDisplayMode, + VisibilityMode, + GraphGradientMode, + StackingMode, + SortOrder, +} from '@grafana/schema'; + import { BarChartFieldConfig } from './models.gen'; +import { BarChartOptionsEX, prepareBarChartDisplayValues, preparePlotConfigBuilder } from './utils'; function mockDataFrame() { const df1 = new MutableDataFrame({ diff --git a/public/app/plugins/panel/barchart/utils.ts b/public/app/plugins/panel/barchart/utils.ts index 98752f5613b..77057d7a89c 100644 --- a/public/app/plugins/panel/barchart/utils.ts +++ b/public/app/plugins/panel/barchart/utils.ts @@ -1,3 +1,6 @@ +import { orderBy } from 'lodash'; +import { Padding } from 'uplot'; + import { ArrayVector, DataFrame, @@ -12,11 +15,7 @@ import { reduceField, VizOrientation, } from '@grafana/data'; -import { BarChartFieldConfig, PanelOptions, defaultBarChartFieldConfig } from './models.gen'; -import { BarChartDisplayValues } from './types'; -import { BarsOptions, getConfig } from './bars'; -import { FIXED_UNIT, measureText, UPlotConfigBuilder, UPlotConfigPrepFn, UPLOT_AXIS_FONT_SIZE } from '@grafana/ui'; -import { Padding } from 'uplot'; +import { maybeSortFrame } from '@grafana/data/src/transformations/transformers/joinDataFrames'; import { AxisPlacement, ScaleDirection, @@ -25,10 +24,13 @@ import { StackingMode, VizLegendOptions, } from '@grafana/schema'; -import { orderBy } from 'lodash'; -import { findField } from 'app/features/dimensions'; +import { FIXED_UNIT, measureText, UPlotConfigBuilder, UPlotConfigPrepFn, UPLOT_AXIS_FONT_SIZE } from '@grafana/ui'; import { getStackingGroups } from '@grafana/ui/src/components/uPlot/utils'; -import { maybeSortFrame } from '@grafana/data/src/transformations/transformers/joinDataFrames'; +import { findField } from 'app/features/dimensions'; + +import { BarsOptions, getConfig } from './bars'; +import { BarChartFieldConfig, PanelOptions, defaultBarChartFieldConfig } from './models.gen'; +import { BarChartDisplayValues } from './types'; function getBarCharScaleOrientation(orientation: VizOrientation) { if (orientation === VizOrientation.Vertical) { diff --git a/public/app/plugins/panel/bargauge/BarGaugeMigrations.test.ts b/public/app/plugins/panel/bargauge/BarGaugeMigrations.test.ts index 002552c0a6c..94a034d9cda 100644 --- a/public/app/plugins/panel/bargauge/BarGaugeMigrations.test.ts +++ b/public/app/plugins/panel/bargauge/BarGaugeMigrations.test.ts @@ -1,4 +1,5 @@ import { PanelModel } from '@grafana/data'; + import { barGaugePanelMigrationHandler } from './BarGaugeMigrations'; describe('BarGauge Panel Migrations', () => { diff --git a/public/app/plugins/panel/bargauge/BarGaugeMigrations.ts b/public/app/plugins/panel/bargauge/BarGaugeMigrations.ts index 29c78535f35..dd97201ac9f 100644 --- a/public/app/plugins/panel/bargauge/BarGaugeMigrations.ts +++ b/public/app/plugins/panel/bargauge/BarGaugeMigrations.ts @@ -1,5 +1,6 @@ import { PanelModel } from '@grafana/data'; import { sharedSingleStatMigrationHandler } from '@grafana/ui'; + import { BarGaugeOptions } from './types'; export const barGaugePanelMigrationHandler = (panel: PanelModel): Partial => { diff --git a/public/app/plugins/panel/bargauge/BarGaugePanel.test.tsx b/public/app/plugins/panel/bargauge/BarGaugePanel.test.tsx index 152fbcc90e9..18f64bccbaa 100644 --- a/public/app/plugins/panel/bargauge/BarGaugePanel.test.tsx +++ b/public/app/plugins/panel/bargauge/BarGaugePanel.test.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { mount, ReactWrapper } from 'enzyme'; +import React from 'react'; + import { dateMath, dateTime, @@ -11,8 +12,8 @@ import { toDataFrame, VizOrientation, } from '@grafana/data'; -import { BarGaugeDisplayMode } from '@grafana/ui'; import { selectors } from '@grafana/e2e-selectors'; +import { BarGaugeDisplayMode } from '@grafana/ui'; import { BarGaugePanel } from './BarGaugePanel'; import { BarGaugeOptions } from './types'; diff --git a/public/app/plugins/panel/bargauge/BarGaugePanel.tsx b/public/app/plugins/panel/bargauge/BarGaugePanel.tsx index cca9beb4851..95ce378211c 100644 --- a/public/app/plugins/panel/bargauge/BarGaugePanel.tsx +++ b/public/app/plugins/panel/bargauge/BarGaugePanel.tsx @@ -1,4 +1,6 @@ +import { isNumber } from 'lodash'; import React, { PureComponent } from 'react'; + import { DisplayValueAlignmentFactors, FieldDisplay, @@ -11,11 +13,10 @@ import { VizOrientation, } from '@grafana/data'; import { BarGauge, DataLinksContextMenu, VizRepeater, VizRepeaterRenderValueProps } from '@grafana/ui'; - -import { config } from 'app/core/config'; -import { BarGaugeOptions } from './types'; import { DataLinksContextMenuApi } from '@grafana/ui/src/components/DataLinks/DataLinksContextMenu'; -import { isNumber } from 'lodash'; +import { config } from 'app/core/config'; + +import { BarGaugeOptions } from './types'; export class BarGaugePanel extends PureComponent> { renderComponent = ( diff --git a/public/app/plugins/panel/bargauge/module.tsx b/public/app/plugins/panel/bargauge/module.tsx index 97e7503b8a4..ed78260dbcc 100644 --- a/public/app/plugins/panel/bargauge/module.tsx +++ b/public/app/plugins/panel/bargauge/module.tsx @@ -1,10 +1,12 @@ -import { commonOptionsBuilder, sharedSingleStatPanelChangedHandler } from '@grafana/ui'; import { PanelPlugin, VizOrientation } from '@grafana/data'; -import { BarGaugePanel } from './BarGaugePanel'; -import { BarGaugeOptions, displayModes } from './types'; +import { commonOptionsBuilder, sharedSingleStatPanelChangedHandler } from '@grafana/ui'; + import { addOrientationOption, addStandardDataReduceOptions } from '../stat/types'; + import { barGaugePanelMigrationHandler } from './BarGaugeMigrations'; +import { BarGaugePanel } from './BarGaugePanel'; import { BarGaugeSuggestionsSupplier } from './suggestions'; +import { BarGaugeOptions, displayModes } from './types'; export const plugin = new PanelPlugin(BarGaugePanel) .useFieldConfig() diff --git a/public/app/plugins/panel/bargauge/suggestions.ts b/public/app/plugins/panel/bargauge/suggestions.ts index be937485b4f..2c905c9095a 100644 --- a/public/app/plugins/panel/bargauge/suggestions.ts +++ b/public/app/plugins/panel/bargauge/suggestions.ts @@ -1,6 +1,7 @@ import { VisualizationSuggestionsBuilder, VizOrientation } from '@grafana/data'; import { BarGaugeDisplayMode } from '@grafana/ui'; import { SuggestionName } from 'app/types/suggestions'; + import { BarGaugeOptions } from './types'; export class BarGaugeSuggestionsSupplier { diff --git a/public/app/plugins/panel/bargauge/types.ts b/public/app/plugins/panel/bargauge/types.ts index fd5f52decb8..5b31d9f8ec9 100644 --- a/public/app/plugins/panel/bargauge/types.ts +++ b/public/app/plugins/panel/bargauge/types.ts @@ -1,5 +1,5 @@ -import { SingleStatBaseOptions, BarGaugeDisplayMode } from '@grafana/ui'; import { SelectableValue } from '@grafana/data'; +import { SingleStatBaseOptions, BarGaugeDisplayMode } from '@grafana/ui'; export interface BarGaugeOptions extends SingleStatBaseOptions { displayMode: BarGaugeDisplayMode; diff --git a/public/app/plugins/panel/candlestick/CandlestickPanel.tsx b/public/app/plugins/panel/candlestick/CandlestickPanel.tsx index 1a072900c35..7176739fa1f 100644 --- a/public/app/plugins/panel/candlestick/CandlestickPanel.tsx +++ b/public/app/plugins/panel/candlestick/CandlestickPanel.tsx @@ -2,24 +2,27 @@ // with some extra renderers passed to the component import React, { useMemo } from 'react'; +import uPlot from 'uplot'; + import { Field, getDisplayProcessor, PanelProps } from '@grafana/data'; +import { PanelDataErrorView } from '@grafana/runtime'; import { TooltipDisplayMode } from '@grafana/schema'; import { usePanelContext, TimeSeries, TooltipPlugin, ZoomPlugin, UPlotConfigBuilder, useTheme2 } from '@grafana/ui'; +import { AxisProps } from '@grafana/ui/src/components/uPlot/config/UPlotAxisBuilder'; +import { ScaleProps } from '@grafana/ui/src/components/uPlot/config/UPlotScaleBuilder'; +import { config } from 'app/core/config'; import { getFieldLinksForExplore } from 'app/features/explore/utils/links'; + +import { AnnotationEditorPlugin } from '../timeseries/plugins/AnnotationEditorPlugin'; import { AnnotationsPlugin } from '../timeseries/plugins/AnnotationsPlugin'; import { ContextMenuPlugin } from '../timeseries/plugins/ContextMenuPlugin'; import { ExemplarsPlugin } from '../timeseries/plugins/ExemplarsPlugin'; -import { AnnotationEditorPlugin } from '../timeseries/plugins/AnnotationEditorPlugin'; -import { ThresholdControlsPlugin } from '../timeseries/plugins/ThresholdControlsPlugin'; -import { config } from 'app/core/config'; -import { drawMarkers, FieldIndices } from './utils'; -import { defaultColors, CandlestickOptions, VizDisplayMode } from './models.gen'; -import { ScaleProps } from '@grafana/ui/src/components/uPlot/config/UPlotScaleBuilder'; -import { AxisProps } from '@grafana/ui/src/components/uPlot/config/UPlotAxisBuilder'; -import { prepareCandlestickFields } from './fields'; -import uPlot from 'uplot'; -import { PanelDataErrorView } from '@grafana/runtime'; import { OutsideRangePlugin } from '../timeseries/plugins/OutsideRangePlugin'; +import { ThresholdControlsPlugin } from '../timeseries/plugins/ThresholdControlsPlugin'; + +import { prepareCandlestickFields } from './fields'; +import { defaultColors, CandlestickOptions, VizDisplayMode } from './models.gen'; +import { drawMarkers, FieldIndices } from './utils'; interface CandlestickPanelProps extends PanelProps {} diff --git a/public/app/plugins/panel/candlestick/fields.test.ts b/public/app/plugins/panel/candlestick/fields.test.ts index 01e8abd6e7b..2f68c4bf838 100644 --- a/public/app/plugins/panel/candlestick/fields.test.ts +++ b/public/app/plugins/panel/candlestick/fields.test.ts @@ -1,4 +1,5 @@ import { createTheme, toDataFrame } from '@grafana/data'; + import { prepareCandlestickFields } from './fields'; import { CandlestickOptions, VizDisplayMode } from './models.gen'; diff --git a/public/app/plugins/panel/candlestick/fields.ts b/public/app/plugins/panel/candlestick/fields.ts index be833fbde45..d4c3e17e111 100644 --- a/public/app/plugins/panel/candlestick/fields.ts +++ b/public/app/plugins/panel/candlestick/fields.ts @@ -9,7 +9,9 @@ import { } from '@grafana/data'; import { maybeSortFrame } from '@grafana/data/src/transformations/transformers/joinDataFrames'; import { findField } from 'app/features/dimensions'; + import { prepareGraphableFields } from '../timeseries/utils'; + import { CandlestickOptions, CandlestickFieldMap, VizDisplayMode } from './models.gen'; export interface FieldPickerInfo { diff --git a/public/app/plugins/panel/candlestick/module.tsx b/public/app/plugins/panel/candlestick/module.tsx index c7cf322dc3e..11159394e90 100644 --- a/public/app/plugins/panel/candlestick/module.tsx +++ b/public/app/plugins/panel/candlestick/module.tsx @@ -1,4 +1,3 @@ -import { GraphFieldConfig } from '@grafana/schema'; import { Field, FieldType, @@ -7,8 +6,14 @@ import { PanelPlugin, SelectableValue, } from '@grafana/data'; +import { config } from '@grafana/runtime'; +import { GraphFieldConfig } from '@grafana/schema'; import { commonOptionsBuilder } from '@grafana/ui'; + +import { defaultGraphConfig, getGraphFieldConfig } from '../timeseries/config'; + import { CandlestickPanel } from './CandlestickPanel'; +import { CandlestickData, candlestickFieldsInfo, FieldPickerInfo, prepareCandlestickFields } from './fields'; import { defaultColors, CandlestickOptions, @@ -17,9 +22,6 @@ import { defaultPanelOptions, CandleStyle, } from './models.gen'; -import { defaultGraphConfig, getGraphFieldConfig } from '../timeseries/config'; -import { CandlestickData, candlestickFieldsInfo, FieldPickerInfo, prepareCandlestickFields } from './fields'; -import { config } from '@grafana/runtime'; import { CandlestickSuggestionsSupplier } from './suggestions'; const modeOptions = [ diff --git a/public/app/plugins/panel/candlestick/suggestions.ts b/public/app/plugins/panel/candlestick/suggestions.ts index 19b304e6f3f..bd5981a4664 100644 --- a/public/app/plugins/panel/candlestick/suggestions.ts +++ b/public/app/plugins/panel/candlestick/suggestions.ts @@ -1,6 +1,7 @@ import { VisualizationSuggestionsBuilder, VisualizationSuggestionScore } from '@grafana/data'; import { config } from '@grafana/runtime'; import { SuggestionName } from 'app/types/suggestions'; + import { prepareCandlestickFields } from './fields'; import { CandlestickOptions, defaultPanelOptions } from './models.gen'; diff --git a/public/app/plugins/panel/candlestick/utils.ts b/public/app/plugins/panel/candlestick/utils.ts index 91317119e72..eeae81b9dcc 100644 --- a/public/app/plugins/panel/candlestick/utils.ts +++ b/public/app/plugins/panel/candlestick/utils.ts @@ -1,7 +1,9 @@ -import { VizDisplayMode, ColorStrategy, CandleStyle } from './models.gen'; import uPlot from 'uplot'; + import { colorManipulator } from '@grafana/data'; +import { VizDisplayMode, ColorStrategy, CandleStyle } from './models.gen'; + const { alpha } = colorManipulator; export type FieldIndices = Record; diff --git a/public/app/plugins/panel/canvas/CanvasPanel.tsx b/public/app/plugins/panel/canvas/CanvasPanel.tsx index 31e5d4aeb02..f431a34fb77 100644 --- a/public/app/plugins/panel/canvas/CanvasPanel.tsx +++ b/public/app/plugins/panel/canvas/CanvasPanel.tsx @@ -1,12 +1,14 @@ import { Component } from 'react'; -import { PanelProps } from '@grafana/data'; -import { PanelOptions } from './models.gen'; import { Subscription } from 'rxjs'; -import { PanelEditEnteredEvent, PanelEditExitedEvent } from 'app/types/events'; -import { CanvasGroupOptions } from 'app/features/canvas'; -import { Scene } from 'app/features/canvas/runtime/scene'; + +import { PanelProps } from '@grafana/data'; import { PanelContext, PanelContextRoot } from '@grafana/ui'; +import { CanvasGroupOptions } from 'app/features/canvas'; import { ElementState } from 'app/features/canvas/runtime/element'; +import { Scene } from 'app/features/canvas/runtime/scene'; +import { PanelEditEnteredEvent, PanelEditExitedEvent } from 'app/types/events'; + +import { PanelOptions } from './models.gen'; interface Props extends PanelProps {} diff --git a/public/app/plugins/panel/canvas/editor/APIEditor.tsx b/public/app/plugins/panel/canvas/editor/APIEditor.tsx index 85ddf302ee2..c08072d0e93 100644 --- a/public/app/plugins/panel/canvas/editor/APIEditor.tsx +++ b/public/app/plugins/panel/canvas/editor/APIEditor.tsx @@ -1,7 +1,8 @@ import React, { FC, useCallback } from 'react'; -import { Button, InlineField, InlineFieldRow, JSONFormatter, StringValueEditor } from '@grafana/ui'; + import { AppEvents, StandardEditorProps, StandardEditorsRegistryItem, StringFieldConfigSettings } from '@grafana/data'; import { config, getBackendSrv } from '@grafana/runtime'; +import { Button, InlineField, InlineFieldRow, JSONFormatter, StringValueEditor } from '@grafana/ui'; import { appEvents } from 'app/core/core'; export interface APIEditorConfig { diff --git a/public/app/plugins/panel/canvas/editor/LayerElementListEditor.tsx b/public/app/plugins/panel/canvas/editor/LayerElementListEditor.tsx index f637c153752..75d36be7784 100644 --- a/public/app/plugins/panel/canvas/editor/LayerElementListEditor.tsx +++ b/public/app/plugins/panel/canvas/editor/LayerElementListEditor.tsx @@ -1,20 +1,22 @@ import React, { PureComponent } from 'react'; -import { Button, HorizontalGroup } from '@grafana/ui'; -import { AppEvents, SelectableValue, StandardEditorProps } from '@grafana/data'; import { DropResult } from 'react-beautiful-dnd'; +import { AppEvents, SelectableValue, StandardEditorProps } from '@grafana/data'; +import { Button, HorizontalGroup } from '@grafana/ui'; +import appEvents from 'app/core/app_events'; +import { AddLayerButton } from 'app/core/components/Layers/AddLayerButton'; +import { LayerDragDropList } from 'app/core/components/Layers/LayerDragDropList'; +import { CanvasElementOptions, canvasElementRegistry } from 'app/features/canvas'; +import { notFoundItem } from 'app/features/canvas/elements/notFound'; +import { ElementState } from 'app/features/canvas/runtime/element'; +import { GroupState } from 'app/features/canvas/runtime/group'; +import { SelectionParams } from 'app/features/canvas/runtime/scene'; +import { ShowConfirmModalEvent } from 'app/types/events'; + import { PanelOptions } from '../models.gen'; import { LayerActionID } from '../types'; -import { CanvasElementOptions, canvasElementRegistry } from 'app/features/canvas'; -import appEvents from 'app/core/app_events'; -import { ElementState } from 'app/features/canvas/runtime/element'; -import { notFoundItem } from 'app/features/canvas/elements/notFound'; -import { GroupState } from 'app/features/canvas/runtime/group'; + import { LayerEditorProps } from './layerEditor'; -import { SelectionParams } from 'app/features/canvas/runtime/scene'; -import { ShowConfirmModalEvent } from 'app/types/events'; -import { LayerDragDropList } from 'app/core/components/Layers/LayerDragDropList'; -import { AddLayerButton } from 'app/core/components/Layers/AddLayerButton'; type Props = StandardEditorProps; diff --git a/public/app/plugins/panel/canvas/editor/PlacementEditor.tsx b/public/app/plugins/panel/canvas/editor/PlacementEditor.tsx index c79f5e91bde..a670332b936 100644 --- a/public/app/plugins/panel/canvas/editor/PlacementEditor.tsx +++ b/public/app/plugins/panel/canvas/editor/PlacementEditor.tsx @@ -1,14 +1,16 @@ import React, { FC } from 'react'; import { useObservable } from 'react-use'; import { Subject } from 'rxjs'; -import { Field, InlineField, InlineFieldRow, Select, VerticalGroup } from '@grafana/ui'; -import { SelectableValue, StandardEditorProps } from '@grafana/data'; -import { PanelOptions } from '../models.gen'; -import { CanvasEditorOptions } from './elementEditor'; +import { SelectableValue, StandardEditorProps } from '@grafana/data'; +import { Field, InlineField, InlineFieldRow, Select, VerticalGroup } from '@grafana/ui'; import { HorizontalConstraint, Placement, VerticalConstraint } from 'app/features/canvas'; import { NumberInput } from 'app/features/dimensions/editors/NumberInput'; +import { PanelOptions } from '../models.gen'; + +import { CanvasEditorOptions } from './elementEditor'; + const places: Array = ['top', 'left', 'bottom', 'right', 'width', 'height']; const horizontalOptions: Array> = [ diff --git a/public/app/plugins/panel/canvas/editor/elementEditor.tsx b/public/app/plugins/panel/canvas/editor/elementEditor.tsx index 649900a08cc..e0b75016b7b 100644 --- a/public/app/plugins/panel/canvas/editor/elementEditor.tsx +++ b/public/app/plugins/panel/canvas/editor/elementEditor.tsx @@ -1,11 +1,13 @@ import { get as lodashGet } from 'lodash'; -import { optionBuilder } from './options'; -import { CanvasElementOptions, canvasElementRegistry, DEFAULT_CANVAS_ELEMENT_CONFIG } from 'app/features/canvas'; + import { NestedPanelOptions, NestedValueAccess } from '@grafana/data/src/utils/OptionsUIBuilders'; -import { setOptionImmutably } from 'app/features/dashboard/components/PanelEditor/utils'; +import { CanvasElementOptions, canvasElementRegistry, DEFAULT_CANVAS_ELEMENT_CONFIG } from 'app/features/canvas'; import { ElementState } from 'app/features/canvas/runtime/element'; import { Scene } from 'app/features/canvas/runtime/scene'; +import { setOptionImmutably } from 'app/features/dashboard/components/PanelEditor/utils'; + import { PlacementEditor } from './PlacementEditor'; +import { optionBuilder } from './options'; export interface CanvasEditorOptions { element: ElementState; diff --git a/public/app/plugins/panel/canvas/editor/layerEditor.tsx b/public/app/plugins/panel/canvas/editor/layerEditor.tsx index 917b3e60573..9c07fd425c1 100644 --- a/public/app/plugins/panel/canvas/editor/layerEditor.tsx +++ b/public/app/plugins/panel/canvas/editor/layerEditor.tsx @@ -1,13 +1,16 @@ import { get as lodashGet } from 'lodash'; -import { optionBuilder } from './options'; + import { NestedPanelOptions, NestedValueAccess } from '@grafana/data/src/utils/OptionsUIBuilders'; -import { setOptionImmutably } from 'app/features/dashboard/components/PanelEditor/utils'; -import { InstanceState } from '../CanvasPanel'; -import { LayerElementListEditor } from './LayerElementListEditor'; +import { ElementState } from 'app/features/canvas/runtime/element'; import { GroupState } from 'app/features/canvas/runtime/group'; import { Scene } from 'app/features/canvas/runtime/scene'; -import { ElementState } from 'app/features/canvas/runtime/element'; +import { setOptionImmutably } from 'app/features/dashboard/components/PanelEditor/utils'; + +import { InstanceState } from '../CanvasPanel'; + +import { LayerElementListEditor } from './LayerElementListEditor'; import { PlacementEditor } from './PlacementEditor'; +import { optionBuilder } from './options'; export interface LayerEditorProps { scene: Scene; diff --git a/public/app/plugins/panel/canvas/module.tsx b/public/app/plugins/panel/canvas/module.tsx index 9b00e40f7a0..c0a55f11f4b 100644 --- a/public/app/plugins/panel/canvas/module.tsx +++ b/public/app/plugins/panel/canvas/module.tsx @@ -1,10 +1,10 @@ import { PanelPlugin } from '@grafana/data'; +import { GroupState } from 'app/features/canvas/runtime/group'; import { CanvasPanel, InstanceState } from './CanvasPanel'; -import { PanelOptions } from './models.gen'; import { getElementEditor } from './editor/elementEditor'; import { getLayerEditor } from './editor/layerEditor'; -import { GroupState } from 'app/features/canvas/runtime/group'; +import { PanelOptions } from './models.gen'; export const plugin = new PanelPlugin(CanvasPanel) .setNoPadding() // extend to panel edges diff --git a/public/app/plugins/panel/dashlist/DashList.tsx b/public/app/plugins/panel/dashlist/DashList.tsx index b31f6eaa1c1..54c797899be 100644 --- a/public/app/plugins/panel/dashlist/DashList.tsx +++ b/public/app/plugins/panel/dashlist/DashList.tsx @@ -1,18 +1,19 @@ -import React, { useCallback, useEffect, useMemo, useState } from 'react'; -import { take } from 'lodash'; import { css, cx } from '@emotion/css'; +import { take } from 'lodash'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { GrafanaTheme2, InterpolateFunction, PanelProps } from '@grafana/data'; import { CustomScrollbar, stylesFactory, useStyles2 } from '@grafana/ui'; import { Icon, IconProps } from '@grafana/ui/src/components/Icon/Icon'; import { getFocusStyles } from '@grafana/ui/src/themes/mixins'; import { getBackendSrv } from 'app/core/services/backend_srv'; -import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv'; import impressionSrv from 'app/core/services/impression_srv'; -import { DashboardSearchHit } from 'app/features/search/types'; -import { getStyles } from './styles'; -import { PanelLayout, PanelOptions } from './models.gen'; +import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv'; import { SearchCard } from 'app/features/search/components/SearchCard'; +import { DashboardSearchHit } from 'app/features/search/types'; + +import { PanelLayout, PanelOptions } from './models.gen'; +import { getStyles } from './styles'; type Dashboard = DashboardSearchHit & { isSearchResult?: boolean; isRecent?: boolean }; diff --git a/public/app/plugins/panel/dashlist/module.tsx b/public/app/plugins/panel/dashlist/module.tsx index 742e48d2eb0..d0fa3e8c036 100644 --- a/public/app/plugins/panel/dashlist/module.tsx +++ b/public/app/plugins/panel/dashlist/module.tsx @@ -1,13 +1,16 @@ -import { PanelModel, PanelPlugin } from '@grafana/data'; -import { DashList } from './DashList'; import React from 'react'; + +import { PanelModel, PanelPlugin } from '@grafana/data'; +import { config } from '@grafana/runtime'; import { TagsInput } from '@grafana/ui'; + import { ALL_FOLDER, GENERAL_FOLDER, ReadonlyFolderPicker, } from '../../../core/components/Select/ReadonlyFolderPicker/ReadonlyFolderPicker'; -import { config } from '@grafana/runtime'; + +import { DashList } from './DashList'; import { defaultPanelOptions, PanelLayout, PanelOptions } from './models.gen'; export const plugin = new PanelPlugin(DashList) diff --git a/public/app/plugins/panel/debug/CursorView.tsx b/public/app/plugins/panel/debug/CursorView.tsx index f075666f334..124ea8482e2 100644 --- a/public/app/plugins/panel/debug/CursorView.tsx +++ b/public/app/plugins/panel/debug/CursorView.tsx @@ -1,4 +1,6 @@ import React, { Component } from 'react'; +import { Subscription } from 'rxjs'; + import { EventBus, LegacyGraphHoverEvent, @@ -7,8 +9,8 @@ import { DataHoverClearEvent, BusEventBase, } from '@grafana/data'; -import { Subscription } from 'rxjs'; import { CustomScrollbar } from '@grafana/ui'; + import { DataHoverView } from '../geomap/components/DataHoverView'; interface Props { diff --git a/public/app/plugins/panel/debug/DebugPanel.tsx b/public/app/plugins/panel/debug/DebugPanel.tsx index dc964027353..c3c9f007a63 100644 --- a/public/app/plugins/panel/debug/DebugPanel.tsx +++ b/public/app/plugins/panel/debug/DebugPanel.tsx @@ -1,11 +1,12 @@ import React, { Component } from 'react'; + import { PanelProps } from '@grafana/data'; -import { DebugPanelOptions, DebugMode } from './types'; +import { CursorView } from './CursorView'; import { EventBusLoggerPanel } from './EventBusLogger'; import { RenderInfoViewer } from './RenderInfoViewer'; -import { CursorView } from './CursorView'; import { StateView } from './StateView'; +import { DebugPanelOptions, DebugMode } from './types'; type Props = PanelProps; diff --git a/public/app/plugins/panel/debug/EventBusLogger.tsx b/public/app/plugins/panel/debug/EventBusLogger.tsx index b38824a8cfb..c13501abd61 100644 --- a/public/app/plugins/panel/debug/EventBusLogger.tsx +++ b/public/app/plugins/panel/debug/EventBusLogger.tsx @@ -1,5 +1,6 @@ import React, { PureComponent } from 'react'; -import { CustomScrollbar } from '@grafana/ui'; +import { PartialObserver, Unsubscribable } from 'rxjs'; + import { BusEvent, CircularVector, @@ -8,7 +9,7 @@ import { DataSelectEvent, EventBus, } from '@grafana/data'; -import { PartialObserver, Unsubscribable } from 'rxjs'; +import { CustomScrollbar } from '@grafana/ui'; interface Props { eventBus: EventBus; diff --git a/public/app/plugins/panel/debug/RenderInfoViewer.tsx b/public/app/plugins/panel/debug/RenderInfoViewer.tsx index d090b04d849..3acc8a7798f 100644 --- a/public/app/plugins/panel/debug/RenderInfoViewer.tsx +++ b/public/app/plugins/panel/debug/RenderInfoViewer.tsx @@ -1,4 +1,5 @@ import React, { Component } from 'react'; + import { compareArrayValues, compareDataFrameStructures, @@ -8,9 +9,9 @@ import { PanelProps, ReducerID, } from '@grafana/data'; +import { IconButton } from '@grafana/ui'; import { DebugPanelOptions, UpdateCounters, UpdateConfig } from './types'; -import { IconButton } from '@grafana/ui'; type Props = PanelProps; diff --git a/public/app/plugins/panel/debug/StateView.tsx b/public/app/plugins/panel/debug/StateView.tsx index 76746e25a08..ffee7405a55 100644 --- a/public/app/plugins/panel/debug/StateView.tsx +++ b/public/app/plugins/panel/debug/StateView.tsx @@ -1,6 +1,8 @@ import React, { FormEvent } from 'react'; + import { PanelOptionsEditorProps, PanelProps } from '@grafana/data'; import { Field, Input, usePanelContext } from '@grafana/ui'; + import { DebugPanelOptions } from './types'; export function StateView(props: PanelProps) { diff --git a/public/app/plugins/panel/debug/module.tsx b/public/app/plugins/panel/debug/module.tsx index a2bfecebece..dea12e74bde 100644 --- a/public/app/plugins/panel/debug/module.tsx +++ b/public/app/plugins/panel/debug/module.tsx @@ -1,4 +1,5 @@ import { PanelPlugin } from '@grafana/data'; + import { DebugPanel } from './DebugPanel'; import { StateViewEditor } from './StateView'; import { DebugMode, DebugPanelOptions } from './types'; diff --git a/public/app/plugins/panel/gauge/GaugeMigrations.test.ts b/public/app/plugins/panel/gauge/GaugeMigrations.test.ts index 1f63ae5641b..bc2868c2474 100644 --- a/public/app/plugins/panel/gauge/GaugeMigrations.test.ts +++ b/public/app/plugins/panel/gauge/GaugeMigrations.test.ts @@ -1,4 +1,5 @@ import { PanelModel } from '@grafana/data'; + import { gaugePanelMigrationHandler, gaugePanelChangedHandler } from './GaugeMigrations'; describe('Gauge Panel Migrations', () => { diff --git a/public/app/plugins/panel/gauge/GaugeMigrations.ts b/public/app/plugins/panel/gauge/GaugeMigrations.ts index d4b619aa20c..343e4a00d36 100644 --- a/public/app/plugins/panel/gauge/GaugeMigrations.ts +++ b/public/app/plugins/panel/gauge/GaugeMigrations.ts @@ -1,5 +1,6 @@ -import { sharedSingleStatPanelChangedHandler, sharedSingleStatMigrationHandler } from '@grafana/ui'; import { PanelModel } from '@grafana/data'; +import { sharedSingleStatPanelChangedHandler, sharedSingleStatMigrationHandler } from '@grafana/ui'; + import { GaugeOptions } from './types'; // This is called when the panel first loads diff --git a/public/app/plugins/panel/gauge/GaugePanel.tsx b/public/app/plugins/panel/gauge/GaugePanel.tsx index 950ae77e762..c4b38b6b614 100644 --- a/public/app/plugins/panel/gauge/GaugePanel.tsx +++ b/public/app/plugins/panel/gauge/GaugePanel.tsx @@ -1,12 +1,14 @@ import React, { PureComponent } from 'react'; + import { FieldDisplay, getFieldDisplayValues, PanelProps } from '@grafana/data'; import { DataLinksContextMenu, Gauge, VizRepeater, VizRepeaterRenderValueProps } from '@grafana/ui'; import { DataLinksContextMenuApi } from '@grafana/ui/src/components/DataLinks/DataLinksContextMenu'; - import { config } from 'app/core/config'; -import { GaugeOptions } from './types'; + import { clearNameForSingleSeries } from '../bargauge/BarGaugePanel'; +import { GaugeOptions } from './types'; + export class GaugePanel extends PureComponent> { renderComponent = ( valueProps: VizRepeaterRenderValueProps, diff --git a/public/app/plugins/panel/gauge/module.tsx b/public/app/plugins/panel/gauge/module.tsx index 4b1cd0d52fa..f4bf37140c9 100644 --- a/public/app/plugins/panel/gauge/module.tsx +++ b/public/app/plugins/panel/gauge/module.tsx @@ -1,10 +1,12 @@ import { PanelPlugin } from '@grafana/data'; -import { GaugePanel } from './GaugePanel'; -import { GaugeOptions } from './types'; -import { addOrientationOption, addStandardDataReduceOptions } from '../stat/types'; -import { gaugePanelMigrationHandler, gaugePanelChangedHandler } from './GaugeMigrations'; import { commonOptionsBuilder } from '@grafana/ui'; + +import { addOrientationOption, addStandardDataReduceOptions } from '../stat/types'; + +import { gaugePanelMigrationHandler, gaugePanelChangedHandler } from './GaugeMigrations'; +import { GaugePanel } from './GaugePanel'; import { GaugeSuggestionsSupplier } from './suggestions'; +import { GaugeOptions } from './types'; export const plugin = new PanelPlugin(GaugePanel) .useFieldConfig() diff --git a/public/app/plugins/panel/gauge/suggestions.ts b/public/app/plugins/panel/gauge/suggestions.ts index 5863509b416..edad77f745a 100644 --- a/public/app/plugins/panel/gauge/suggestions.ts +++ b/public/app/plugins/panel/gauge/suggestions.ts @@ -1,5 +1,6 @@ import { ThresholdsMode, VisualizationSuggestionsBuilder } from '@grafana/data'; import { SuggestionName } from 'app/types/suggestions'; + import { GaugeOptions } from './types'; export class GaugeSuggestionsSupplier { diff --git a/public/app/plugins/panel/geomap/GeomapOverlay.tsx b/public/app/plugins/panel/geomap/GeomapOverlay.tsx index b7caeba1387..af999908a77 100644 --- a/public/app/plugins/panel/geomap/GeomapOverlay.tsx +++ b/public/app/plugins/panel/geomap/GeomapOverlay.tsx @@ -1,8 +1,9 @@ +import { css } from '@emotion/css'; import React, { PureComponent } from 'react'; + import { GrafanaTheme } from '@grafana/data'; import { config } from '@grafana/runtime'; import { stylesFactory } from '@grafana/ui'; -import { css } from '@emotion/css'; export interface OverlayProps { topRight?: React.ReactNode[]; diff --git a/public/app/plugins/panel/geomap/GeomapPanel.tsx b/public/app/plugins/panel/geomap/GeomapPanel.tsx index 420a3125a9c..090d38c562e 100644 --- a/public/app/plugins/panel/geomap/GeomapPanel.tsx +++ b/public/app/plugins/panel/geomap/GeomapPanel.tsx @@ -1,14 +1,20 @@ -import React, { Component, ReactNode } from 'react'; -import { DEFAULT_BASEMAP_CONFIG, geomapLayerRegistry } from './layers/registry'; +import { css } from '@emotion/css'; +import { Global } from '@emotion/react'; +import { cloneDeep } from 'lodash'; import { Collection, Map as OpenLayersMap, MapBrowserEvent, PluggableMap, View } from 'ol'; +import { FeatureLike } from 'ol/Feature'; import Attribution from 'ol/control/Attribution'; -import Zoom from 'ol/control/Zoom'; import ScaleLine from 'ol/control/ScaleLine'; +import Zoom from 'ol/control/Zoom'; +import { Coordinate } from 'ol/coordinate'; import { createEmpty, extend, isEmpty } from 'ol/extent'; import { defaults as interactionDefaults } from 'ol/interaction'; +import MouseWheelZoom from 'ol/interaction/MouseWheelZoom'; import BaseLayer from 'ol/layer/Base'; import VectorLayer from 'ol/layer/Vector'; -import MouseWheelZoom from 'ol/interaction/MouseWheelZoom'; +import { fromLonLat, toLonLat } from 'ol/proj'; +import React, { Component, ReactNode } from 'react'; +import { Subject, Subscription } from 'rxjs'; import { PanelData, @@ -21,24 +27,18 @@ import { FrameGeometrySourceMode, } from '@grafana/data'; import { config } from '@grafana/runtime'; +import { PanelContext, PanelContextRoot, stylesFactory } from '@grafana/ui'; +import { PanelEditExitedEvent } from 'app/types/events'; +import { GeomapOverlay, OverlayProps } from './GeomapOverlay'; +import { GeomapTooltip } from './GeomapTooltip'; +import { DebugOverlay } from './components/DebugOverlay'; +import { GeomapHoverPayload, GeomapLayerHover } from './event'; +import { getGlobalStyles } from './globalStyles'; +import { defaultMarkersConfig, MARKERS_LAYER_ID } from './layers/data/markersLayer'; +import { DEFAULT_BASEMAP_CONFIG, geomapLayerRegistry } from './layers/registry'; import { ControlsOptions, GeomapPanelOptions, MapLayerState, MapViewConfig } from './types'; import { centerPointRegistry, MapCenterID } from './view'; -import { fromLonLat, toLonLat } from 'ol/proj'; -import { Coordinate } from 'ol/coordinate'; -import { css } from '@emotion/css'; -import { PanelContext, PanelContextRoot, stylesFactory } from '@grafana/ui'; -import { GeomapOverlay, OverlayProps } from './GeomapOverlay'; -import { DebugOverlay } from './components/DebugOverlay'; -import { getGlobalStyles } from './globalStyles'; -import { Global } from '@emotion/react'; -import { GeomapHoverPayload, GeomapLayerHover } from './event'; -import { Subject, Subscription } from 'rxjs'; -import { PanelEditExitedEvent } from 'app/types/events'; -import { defaultMarkersConfig, MARKERS_LAYER_ID } from './layers/data/markersLayer'; -import { cloneDeep } from 'lodash'; -import { GeomapTooltip } from './GeomapTooltip'; -import { FeatureLike } from 'ol/Feature'; // Allows multiple panels to share the same view instance let sharedView: View | undefined = undefined; diff --git a/public/app/plugins/panel/geomap/GeomapTooltip.tsx b/public/app/plugins/panel/geomap/GeomapTooltip.tsx index 6dd9578e2d5..90b1c2c5b80 100644 --- a/public/app/plugins/panel/geomap/GeomapTooltip.tsx +++ b/public/app/plugins/panel/geomap/GeomapTooltip.tsx @@ -1,7 +1,8 @@ -import React, { createRef } from 'react'; -import { VizTooltipContainer } from '@grafana/ui'; import { useDialog } from '@react-aria/dialog'; import { useOverlay } from '@react-aria/overlays'; +import React, { createRef } from 'react'; + +import { VizTooltipContainer } from '@grafana/ui'; import { ComplexDataHoverView } from './components/ComplexDataHoverView'; import { GeomapHoverPayload } from './event'; diff --git a/public/app/plugins/panel/geomap/components/ComplexDataHoverView.tsx b/public/app/plugins/panel/geomap/components/ComplexDataHoverView.tsx index 75ea827ec2c..767f3f29b8f 100644 --- a/public/app/plugins/panel/geomap/components/ComplexDataHoverView.tsx +++ b/public/app/plugins/panel/geomap/components/ComplexDataHoverView.tsx @@ -1,10 +1,12 @@ import React, { useState } from 'react'; -import { GeomapLayerHover } from '../event'; -import { DataHoverTabs } from './DataHoverTabs'; -import { DataHoverRows } from './DataHoverRows'; import { CloseButton } from 'app/core/components/CloseButton/CloseButton'; +import { GeomapLayerHover } from '../event'; + +import { DataHoverRows } from './DataHoverRows'; +import { DataHoverTabs } from './DataHoverTabs'; + export interface Props { layers?: GeomapLayerHover[]; isOpen: boolean; diff --git a/public/app/plugins/panel/geomap/components/DataHoverRow.tsx b/public/app/plugins/panel/geomap/components/DataHoverRow.tsx index ebb1d8b8499..5c8a38a6480 100644 --- a/public/app/plugins/panel/geomap/components/DataHoverRow.tsx +++ b/public/app/plugins/panel/geomap/components/DataHoverRow.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { FeatureLike } from 'ol/Feature'; +import React from 'react'; + import { ArrayDataFrame, DataFrame } from '@grafana/data'; import { DataHoverView } from './DataHoverView'; diff --git a/public/app/plugins/panel/geomap/components/DataHoverRows.tsx b/public/app/plugins/panel/geomap/components/DataHoverRows.tsx index 0a234a392c4..aac2f77dc8d 100644 --- a/public/app/plugins/panel/geomap/components/DataHoverRows.tsx +++ b/public/app/plugins/panel/geomap/components/DataHoverRows.tsx @@ -1,12 +1,14 @@ -import React, { useState } from 'react'; -import { Collapse, TabContent, useStyles2 } from '@grafana/ui'; -import { DataFrame, FieldType, getFieldDisplayName, GrafanaTheme2 } from '@grafana/data'; import { css } from '@emotion/css'; +import { isString } from 'lodash'; import { FeatureLike } from 'ol/Feature'; +import React, { useState } from 'react'; + +import { DataFrame, FieldType, getFieldDisplayName, GrafanaTheme2 } from '@grafana/data'; +import { Collapse, TabContent, useStyles2 } from '@grafana/ui'; import { GeomapLayerHover } from '../event'; + import { DataHoverRow } from './DataHoverRow'; -import { isString } from 'lodash'; type Props = { layers: GeomapLayerHover[]; diff --git a/public/app/plugins/panel/geomap/components/DataHoverTabs.tsx b/public/app/plugins/panel/geomap/components/DataHoverTabs.tsx index 8ad828f2496..4014d0308f8 100644 --- a/public/app/plugins/panel/geomap/components/DataHoverTabs.tsx +++ b/public/app/plugins/panel/geomap/components/DataHoverTabs.tsx @@ -1,4 +1,5 @@ import React, { Dispatch, SetStateAction } from 'react'; + import { Tab, TabsBar } from '@grafana/ui'; import { GeomapLayerHover } from '../event'; diff --git a/public/app/plugins/panel/geomap/components/DataHoverView.tsx b/public/app/plugins/panel/geomap/components/DataHoverView.tsx index 5f6977b3231..6a7a750ee4e 100644 --- a/public/app/plugins/panel/geomap/components/DataHoverView.tsx +++ b/public/app/plugins/panel/geomap/components/DataHoverView.tsx @@ -1,5 +1,6 @@ +import { css } from '@emotion/css'; import React from 'react'; -import { LinkButton, useStyles2, VerticalGroup } from '@grafana/ui'; + import { arrayUtils, DataFrame, @@ -9,8 +10,8 @@ import { GrafanaTheme2, LinkModel, } from '@grafana/data'; -import { css } from '@emotion/css'; import { SortOrder } from '@grafana/schema'; +import { LinkButton, useStyles2, VerticalGroup } from '@grafana/ui'; export interface Props { data?: DataFrame; // source data diff --git a/public/app/plugins/panel/geomap/components/DebugOverlay.tsx b/public/app/plugins/panel/geomap/components/DebugOverlay.tsx index c47d20aba4c..4cd85540d34 100644 --- a/public/app/plugins/panel/geomap/components/DebugOverlay.tsx +++ b/public/app/plugins/panel/geomap/components/DebugOverlay.tsx @@ -1,12 +1,13 @@ -import React, { PureComponent } from 'react'; -import { Map } from 'ol'; -import { transform } from 'ol/proj'; -import { stylesFactory } from '@grafana/ui'; -import { GrafanaTheme } from '@grafana/data'; import { css } from '@emotion/css'; -import { config } from 'app/core/config'; -import tinycolor from 'tinycolor2'; +import { Map } from 'ol'; import { Coordinate } from 'ol/coordinate'; +import { transform } from 'ol/proj'; +import React, { PureComponent } from 'react'; +import tinycolor from 'tinycolor2'; + +import { GrafanaTheme } from '@grafana/data'; +import { stylesFactory } from '@grafana/ui'; +import { config } from 'app/core/config'; interface Props { map: Map; diff --git a/public/app/plugins/panel/geomap/editor/GeomapStyleRulesEditor.tsx b/public/app/plugins/panel/geomap/editor/GeomapStyleRulesEditor.tsx index c3d1cf1f7f1..369820222f3 100644 --- a/public/app/plugins/panel/geomap/editor/GeomapStyleRulesEditor.tsx +++ b/public/app/plugins/panel/geomap/editor/GeomapStyleRulesEditor.tsx @@ -1,11 +1,13 @@ import React, { FC, useCallback } from 'react'; -import { Button, useTheme2 } from '@grafana/ui'; -import { StandardEditorProps, StandardEditorsRegistryItem } from '@grafana/data'; -import { FeatureStyleConfig } from '../types'; +import { StandardEditorProps, StandardEditorsRegistryItem } from '@grafana/data'; +import { Button, useTheme2 } from '@grafana/ui'; + import { DEFAULT_STYLE_RULE } from '../layers/data/geojsonLayer'; -import { StyleRuleEditor, StyleRuleEditorSettings } from './StyleRuleEditor'; import { defaultStyleConfig } from '../style/types'; +import { FeatureStyleConfig } from '../types'; + +import { StyleRuleEditor, StyleRuleEditorSettings } from './StyleRuleEditor'; export const GeomapStyleRulesEditor: FC> = (props) => { const { value, onChange, context, item } = props; diff --git a/public/app/plugins/panel/geomap/editor/LayersEditor.tsx b/public/app/plugins/panel/geomap/editor/LayersEditor.tsx index c2cfccc89dc..afad49655f9 100644 --- a/public/app/plugins/panel/geomap/editor/LayersEditor.tsx +++ b/public/app/plugins/panel/geomap/editor/LayersEditor.tsx @@ -1,15 +1,17 @@ import React from 'react'; -import { Container } from '@grafana/ui'; -import { StandardEditorProps } from '@grafana/data'; import { DropResult } from 'react-beautiful-dnd'; -import { GeomapPanelOptions, MapLayerState } from '../types'; -import { GeomapInstanceState } from '../GeomapPanel'; -import { geomapLayerRegistry } from '../layers/registry'; -import { dataLayerFilter } from './layerEditor'; +import { StandardEditorProps } from '@grafana/data'; +import { Container } from '@grafana/ui'; import { AddLayerButton } from 'app/core/components/Layers/AddLayerButton'; import { LayerDragDropList } from 'app/core/components/Layers/LayerDragDropList'; +import { GeomapInstanceState } from '../GeomapPanel'; +import { geomapLayerRegistry } from '../layers/registry'; +import { GeomapPanelOptions, MapLayerState } from '../types'; + +import { dataLayerFilter } from './layerEditor'; + type LayersEditorProps = StandardEditorProps; export const LayersEditor = (props: LayersEditorProps) => { diff --git a/public/app/plugins/panel/geomap/editor/MapViewEditor.tsx b/public/app/plugins/panel/geomap/editor/MapViewEditor.tsx index de640f515f4..07109e27eda 100644 --- a/public/app/plugins/panel/geomap/editor/MapViewEditor.tsx +++ b/public/app/plugins/panel/geomap/editor/MapViewEditor.tsx @@ -1,11 +1,13 @@ +import { toLonLat } from 'ol/proj'; import React, { FC, useMemo, useCallback } from 'react'; + import { StandardEditorProps, SelectableValue } from '@grafana/data'; import { Button, InlineField, InlineFieldRow, Select, VerticalGroup } from '@grafana/ui'; +import { NumberInput } from 'app/features/dimensions/editors/NumberInput'; + +import { GeomapInstanceState } from '../GeomapPanel'; import { GeomapPanelOptions, MapViewConfig } from '../types'; import { centerPointRegistry, MapCenterID } from '../view'; -import { NumberInput } from 'app/features/dimensions/editors/NumberInput'; -import { toLonLat } from 'ol/proj'; -import { GeomapInstanceState } from '../GeomapPanel'; export const MapViewEditor: FC> = ({ value, diff --git a/public/app/plugins/panel/geomap/editor/StyleRuleEditor.tsx b/public/app/plugins/panel/geomap/editor/StyleRuleEditor.tsx index 34681cc9330..7bfcf7850f6 100644 --- a/public/app/plugins/panel/geomap/editor/StyleRuleEditor.tsx +++ b/public/app/plugins/panel/geomap/editor/StyleRuleEditor.tsx @@ -1,18 +1,20 @@ -import React, { FC, useCallback, useMemo } from 'react'; -import { GrafanaTheme2, SelectableValue, StandardEditorProps } from '@grafana/data'; -import { ComparisonOperation, FeatureStyleConfig } from '../types'; -import { Button, InlineField, InlineFieldRow, Select, useStyles2 } from '@grafana/ui'; import { css } from '@emotion/css'; -import { StyleEditor } from '../layers/data/StyleEditor'; -import { defaultStyleConfig, StyleConfig } from '../style/types'; -import { DEFAULT_STYLE_RULE } from '../layers/data/geojsonLayer'; -import { Observable } from 'rxjs'; -import { useObservable } from 'react-use'; -import { getUniqueFeatureValues, LayerContentInfo } from '../utils/getFeatures'; import { FeatureLike } from 'ol/Feature'; -import { getSelectionInfo } from '../utils/selection'; +import React, { FC, useCallback, useMemo } from 'react'; +import { useObservable } from 'react-use'; +import { Observable } from 'rxjs'; + +import { GrafanaTheme2, SelectableValue, StandardEditorProps } from '@grafana/data'; +import { Button, InlineField, InlineFieldRow, Select, useStyles2 } from '@grafana/ui'; import { NumberInput } from 'app/features/dimensions/editors/NumberInput'; +import { StyleEditor } from '../layers/data/StyleEditor'; +import { DEFAULT_STYLE_RULE } from '../layers/data/geojsonLayer'; +import { defaultStyleConfig, StyleConfig } from '../style/types'; +import { ComparisonOperation, FeatureStyleConfig } from '../types'; +import { getUniqueFeatureValues, LayerContentInfo } from '../utils/getFeatures'; +import { getSelectionInfo } from '../utils/selection'; + export interface StyleRuleEditorSettings { features: Observable; layerInfo: Observable; diff --git a/public/app/plugins/panel/geomap/editor/layerEditor.tsx b/public/app/plugins/panel/geomap/editor/layerEditor.tsx index 22103c678ac..3ddeb4f0bd3 100644 --- a/public/app/plugins/panel/geomap/editor/layerEditor.tsx +++ b/public/app/plugins/panel/geomap/editor/layerEditor.tsx @@ -1,13 +1,15 @@ -import { FrameGeometrySourceMode, MapLayerOptions, MapLayerRegistryItem, PluginState } from '@grafana/data'; -import { DEFAULT_BASEMAP_CONFIG, geomapLayerRegistry } from '../layers/registry'; -import { NestedPanelOptions, NestedValueAccess } from '@grafana/data/src/utils/OptionsUIBuilders'; -import { defaultMarkersConfig } from '../layers/data/markersLayer'; -import { hasAlphaPanels } from 'app/core/config'; -import { MapLayerState } from '../types'; import { get as lodashGet, isEqual } from 'lodash'; + +import { FrameGeometrySourceMode, MapLayerOptions, MapLayerRegistryItem, PluginState } from '@grafana/data'; +import { NestedPanelOptions, NestedValueAccess } from '@grafana/data/src/utils/OptionsUIBuilders'; +import { hasAlphaPanels } from 'app/core/config'; import { setOptionImmutably } from 'app/features/dashboard/components/PanelEditor/utils'; import { addLocationFields } from 'app/features/geo/editor/locationEditor'; +import { defaultMarkersConfig } from '../layers/data/markersLayer'; +import { DEFAULT_BASEMAP_CONFIG, geomapLayerRegistry } from '../layers/registry'; +import { MapLayerState } from '../types'; + export interface LayerEditorOptions { state: MapLayerState; category: string[]; diff --git a/public/app/plugins/panel/geomap/event.ts b/public/app/plugins/panel/geomap/event.ts index c93478d30fc..885d5cd14de 100644 --- a/public/app/plugins/panel/geomap/event.ts +++ b/public/app/plugins/panel/geomap/event.ts @@ -1,5 +1,7 @@ import { FeatureLike } from 'ol/Feature'; + import { DataHoverPayload } from '@grafana/data'; + import { MapLayerState } from './types'; export interface GeomapLayerHover { diff --git a/public/app/plugins/panel/geomap/globalStyles.ts b/public/app/plugins/panel/geomap/globalStyles.ts index 0610cd7ea86..2d0f6f86001 100644 --- a/public/app/plugins/panel/geomap/globalStyles.ts +++ b/public/app/plugins/panel/geomap/globalStyles.ts @@ -1,4 +1,5 @@ import { css } from '@emotion/react'; + import { GrafanaTheme2 } from '@grafana/data'; import 'ol/ol.css'; diff --git a/public/app/plugins/panel/geomap/layers/basemaps/carto.ts b/public/app/plugins/panel/geomap/layers/basemaps/carto.ts index ed903deb7d4..7245507dc47 100644 --- a/public/app/plugins/panel/geomap/layers/basemaps/carto.ts +++ b/public/app/plugins/panel/geomap/layers/basemaps/carto.ts @@ -1,7 +1,8 @@ -import { MapLayerRegistryItem, MapLayerOptions, GrafanaTheme2 } from '@grafana/data'; import Map from 'ol/Map'; -import XYZ from 'ol/source/XYZ'; import TileLayer from 'ol/layer/Tile'; +import XYZ from 'ol/source/XYZ'; + +import { MapLayerRegistryItem, MapLayerOptions, GrafanaTheme2 } from '@grafana/data'; // https://carto.com/help/building-maps/basemap-list/ diff --git a/public/app/plugins/panel/geomap/layers/basemaps/esri.ts b/public/app/plugins/panel/geomap/layers/basemaps/esri.ts index 06ebaadd42b..e8873235e6a 100644 --- a/public/app/plugins/panel/geomap/layers/basemaps/esri.ts +++ b/public/app/plugins/panel/geomap/layers/basemaps/esri.ts @@ -1,5 +1,7 @@ -import { MapLayerRegistryItem, MapLayerOptions, GrafanaTheme2, RegistryItem, Registry } from '@grafana/data'; import Map from 'ol/Map'; + +import { MapLayerRegistryItem, MapLayerOptions, GrafanaTheme2, RegistryItem, Registry } from '@grafana/data'; + import { xyzTiles, defaultXYZConfig, XYZConfig } from './generic'; interface PublicServiceItem extends RegistryItem { diff --git a/public/app/plugins/panel/geomap/layers/basemaps/generic.ts b/public/app/plugins/panel/geomap/layers/basemaps/generic.ts index 8bb50454719..622a10768e0 100644 --- a/public/app/plugins/panel/geomap/layers/basemaps/generic.ts +++ b/public/app/plugins/panel/geomap/layers/basemaps/generic.ts @@ -1,7 +1,8 @@ -import { MapLayerRegistryItem, MapLayerOptions, GrafanaTheme2 } from '@grafana/data'; import Map from 'ol/Map'; -import XYZ from 'ol/source/XYZ'; import TileLayer from 'ol/layer/Tile'; +import XYZ from 'ol/source/XYZ'; + +import { MapLayerRegistryItem, MapLayerOptions, GrafanaTheme2 } from '@grafana/data'; export interface XYZConfig { url: string; diff --git a/public/app/plugins/panel/geomap/layers/basemaps/osm.ts b/public/app/plugins/panel/geomap/layers/basemaps/osm.ts index 7fcf753a660..e51e181315e 100644 --- a/public/app/plugins/panel/geomap/layers/basemaps/osm.ts +++ b/public/app/plugins/panel/geomap/layers/basemaps/osm.ts @@ -1,7 +1,8 @@ -import { MapLayerRegistryItem, MapLayerOptions } from '@grafana/data'; import Map from 'ol/Map'; -import OSM from 'ol/source/OSM'; import TileLayer from 'ol/layer/Tile'; +import OSM from 'ol/source/OSM'; + +import { MapLayerRegistryItem, MapLayerOptions } from '@grafana/data'; export const standard: MapLayerRegistryItem = { id: 'osm-standard', diff --git a/public/app/plugins/panel/geomap/layers/registry.ts b/public/app/plugins/panel/geomap/layers/registry.ts index 123828a9de1..b346e552f23 100644 --- a/public/app/plugins/panel/geomap/layers/registry.ts +++ b/public/app/plugins/panel/geomap/layers/registry.ts @@ -1,8 +1,10 @@ -import { MapLayerRegistryItem, Registry, MapLayerOptions, GrafanaTheme2 } from '@grafana/data'; import Map from 'ol/Map'; -import { carto } from './basemaps/carto'; + +import { MapLayerRegistryItem, Registry, MapLayerOptions, GrafanaTheme2 } from '@grafana/data'; import { config } from 'app/core/config'; + import { basemapLayers } from './basemaps'; +import { carto } from './basemaps/carto'; import { dataLayers } from './data'; export const DEFAULT_BASEMAP_CONFIG: MapLayerOptions = { diff --git a/public/app/plugins/panel/geomap/migrations.test.ts b/public/app/plugins/panel/geomap/migrations.test.ts index 618051abb74..a100738d189 100644 --- a/public/app/plugins/panel/geomap/migrations.test.ts +++ b/public/app/plugins/panel/geomap/migrations.test.ts @@ -1,4 +1,5 @@ import { PanelModel, FieldConfigSource } from '@grafana/data'; + import { mapMigrationHandler, mapPanelChangedHandler } from './migrations'; describe('Worldmap Migrations', () => { let prevFieldConfig: FieldConfigSource; diff --git a/public/app/plugins/panel/geomap/migrations.ts b/public/app/plugins/panel/geomap/migrations.ts index 07a8a871cfa..68c36caa859 100644 --- a/public/app/plugins/panel/geomap/migrations.ts +++ b/public/app/plugins/panel/geomap/migrations.ts @@ -1,6 +1,8 @@ +import { cloneDeep } from 'lodash'; + import { FieldConfigSource, PanelModel, PanelTypeChangedHandler, Threshold, ThresholdsMode } from '@grafana/data'; import { ResourceDimensionMode } from 'app/features/dimensions'; -import { cloneDeep } from 'lodash'; + import { MarkersConfig } from './layers/data/markersLayer'; import { getMarkerAsPath } from './style/markers'; import { defaultStyleConfig } from './style/types'; diff --git a/public/app/plugins/panel/geomap/module.tsx b/public/app/plugins/panel/geomap/module.tsx index 66edb5fe1f9..655d34ae9ce 100644 --- a/public/app/plugins/panel/geomap/module.tsx +++ b/public/app/plugins/panel/geomap/module.tsx @@ -1,14 +1,16 @@ import React from 'react'; + import { PanelPlugin } from '@grafana/data'; -import { GeomapInstanceState, GeomapPanel } from './GeomapPanel'; -import { MapViewEditor } from './editor/MapViewEditor'; -import { defaultView, GeomapPanelOptions } from './types'; -import { mapPanelChangedHandler, mapMigrationHandler } from './migrations'; -import { getLayerEditor } from './editor/layerEditor'; -import { LayersEditor } from './editor/LayersEditor'; import { config } from '@grafana/runtime'; import { commonOptionsBuilder } from '@grafana/ui'; +import { GeomapInstanceState, GeomapPanel } from './GeomapPanel'; +import { LayersEditor } from './editor/LayersEditor'; +import { MapViewEditor } from './editor/MapViewEditor'; +import { getLayerEditor } from './editor/layerEditor'; +import { mapPanelChangedHandler, mapMigrationHandler } from './migrations'; +import { defaultView, GeomapPanelOptions } from './types'; + export const plugin = new PanelPlugin(GeomapPanel) .setNoPadding() .setPanelChangeHandler(mapPanelChangedHandler) diff --git a/public/app/plugins/panel/geomap/style/markers.ts b/public/app/plugins/panel/geomap/style/markers.ts index 5ebf33f1f67..309dcefed97 100644 --- a/public/app/plugins/panel/geomap/style/markers.ts +++ b/public/app/plugins/panel/geomap/style/markers.ts @@ -1,9 +1,11 @@ import { Fill, RegularShape, Stroke, Circle, Style, Icon, Text } from 'ol/style'; -import { Registry, RegistryItem } from '@grafana/data'; -import { defaultStyleConfig, DEFAULT_SIZE, StyleConfigValues, StyleMaker } from './types'; -import { getPublicOrAbsoluteUrl } from 'app/features/dimensions'; import tinycolor from 'tinycolor2'; + +import { Registry, RegistryItem } from '@grafana/data'; import { config } from '@grafana/runtime'; +import { getPublicOrAbsoluteUrl } from 'app/features/dimensions'; + +import { defaultStyleConfig, DEFAULT_SIZE, StyleConfigValues, StyleMaker } from './types'; interface SymbolMaker extends RegistryItem { aliasIds: string[]; diff --git a/public/app/plugins/panel/geomap/style/types.ts b/public/app/plugins/panel/geomap/style/types.ts index 825e8fbe8f2..5192dbd9afa 100644 --- a/public/app/plugins/panel/geomap/style/types.ts +++ b/public/app/plugins/panel/geomap/style/types.ts @@ -1,3 +1,5 @@ +import { Style } from 'ol/style'; + import { ColorDimensionConfig, DimensionSupplier, @@ -8,7 +10,6 @@ import { ScalarDimensionMode, TextDimensionConfig, } from 'app/features/dimensions'; -import { Style } from 'ol/style'; export enum GeometryTypeId { Point = 'point', diff --git a/public/app/plugins/panel/geomap/style/utils.test.ts b/public/app/plugins/panel/geomap/style/utils.test.ts index b046c705797..ddb4cc4f0e8 100644 --- a/public/app/plugins/panel/geomap/style/utils.test.ts +++ b/public/app/plugins/panel/geomap/style/utils.test.ts @@ -1,4 +1,5 @@ import { ResourceDimensionMode } from 'app/features/dimensions'; + import { StyleConfig } from './types'; import { getStyleConfigState } from './utils'; diff --git a/public/app/plugins/panel/geomap/style/utils.ts b/public/app/plugins/panel/geomap/style/utils.ts index 601b3f5bf38..607ab05f2d8 100644 --- a/public/app/plugins/panel/geomap/style/utils.ts +++ b/public/app/plugins/panel/geomap/style/utils.ts @@ -1,5 +1,6 @@ import { config } from '@grafana/runtime'; import { TextDimensionMode } from 'app/features/dimensions'; + import { getMarkerMaker } from './markers'; import { defaultStyleConfig, StyleConfig, StyleConfigFields, StyleConfigState } from './types'; diff --git a/public/app/plugins/panel/geomap/types.ts b/public/app/plugins/panel/geomap/types.ts index 575ba4f333d..521ceb498e9 100644 --- a/public/app/plugins/panel/geomap/types.ts +++ b/public/app/plugins/panel/geomap/types.ts @@ -1,12 +1,14 @@ +import { FeatureLike } from 'ol/Feature'; +import BaseLayer from 'ol/layer/Base'; +import Units from 'ol/proj/Units'; +import { Subject } from 'rxjs'; + import { MapLayerHandler, MapLayerOptions } from '@grafana/data'; import { HideableFieldConfig } from '@grafana/schema'; import { LayerElement } from 'app/core/components/Layers/types'; -import BaseLayer from 'ol/layer/Base'; -import Units from 'ol/proj/Units'; + import { StyleConfig } from './style/types'; import { MapCenterID } from './view'; -import { Subject } from 'rxjs'; -import { FeatureLike } from 'ol/Feature'; export interface ControlsOptions { // Zoom (upper left) diff --git a/public/app/plugins/panel/geomap/utils/checkFeatureMatchesStyleRule.test.ts b/public/app/plugins/panel/geomap/utils/checkFeatureMatchesStyleRule.test.ts index 65e27150ce9..97c5e6086f4 100644 --- a/public/app/plugins/panel/geomap/utils/checkFeatureMatchesStyleRule.test.ts +++ b/public/app/plugins/panel/geomap/utils/checkFeatureMatchesStyleRule.test.ts @@ -1,5 +1,7 @@ import { Feature } from 'ol'; + import { ComparisonOperation } from '../types'; + import { checkFeatureMatchesStyleRule } from './checkFeatureMatchesStyleRule'; describe('check if feature matches style rule', () => { diff --git a/public/app/plugins/panel/geomap/utils/checkFeatureMatchesStyleRule.ts b/public/app/plugins/panel/geomap/utils/checkFeatureMatchesStyleRule.ts index b5ed69dccb2..19027280de4 100644 --- a/public/app/plugins/panel/geomap/utils/checkFeatureMatchesStyleRule.ts +++ b/public/app/plugins/panel/geomap/utils/checkFeatureMatchesStyleRule.ts @@ -1,4 +1,5 @@ import { FeatureLike } from 'ol/Feature'; + import { FeatureRuleConfig, ComparisonOperation } from '../types'; /** diff --git a/public/app/plugins/panel/geomap/utils/getFeatures.test.ts b/public/app/plugins/panel/geomap/utils/getFeatures.test.ts index fbc8a25a9a6..6bc61033399 100644 --- a/public/app/plugins/panel/geomap/utils/getFeatures.test.ts +++ b/public/app/plugins/panel/geomap/utils/getFeatures.test.ts @@ -1,6 +1,8 @@ import { Feature } from 'ol'; import { Point } from 'ol/geom'; + import { GeometryTypeId } from '../style/types'; + import { getLayerPropertyInfo, getUniqueFeatureValues } from './getFeatures'; describe('get features utils', () => { diff --git a/public/app/plugins/panel/geomap/utils/getFeatures.ts b/public/app/plugins/panel/geomap/utils/getFeatures.ts index 49ea66b85ce..48f37446173 100644 --- a/public/app/plugins/panel/geomap/utils/getFeatures.ts +++ b/public/app/plugins/panel/geomap/utils/getFeatures.ts @@ -1,5 +1,7 @@ -import { SelectableValue } from '@grafana/data'; import { FeatureLike } from 'ol/Feature'; + +import { SelectableValue } from '@grafana/data'; + import { GeometryTypeId } from '../style/types'; export interface LayerContentInfo { diff --git a/public/app/plugins/panel/gettingstarted/GettingStarted.tsx b/public/app/plugins/panel/gettingstarted/GettingStarted.tsx index 9f23ec1fd3a..b432ecd31ff 100644 --- a/public/app/plugins/panel/gettingstarted/GettingStarted.tsx +++ b/public/app/plugins/panel/gettingstarted/GettingStarted.tsx @@ -1,12 +1,14 @@ // Libraries -import React, { PureComponent } from 'react'; -import { PanelProps } from '@grafana/data'; -import { Button, Spinner, stylesFactory } from '@grafana/ui'; -import { config } from '@grafana/runtime'; import { css, cx } from '@emotion/css'; +import React, { PureComponent } from 'react'; + +import { PanelProps } from '@grafana/data'; +import { config } from '@grafana/runtime'; +import { Button, Spinner, stylesFactory } from '@grafana/ui'; import { contextSrv } from 'app/core/core'; import { backendSrv } from 'app/core/services/backend_srv'; import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv'; + import { Step } from './components/Step'; import { getSteps } from './steps'; import { Card, SetupStep } from './types'; diff --git a/public/app/plugins/panel/gettingstarted/components/DocsCard.tsx b/public/app/plugins/panel/gettingstarted/components/DocsCard.tsx index 2a143c61045..d8e85444463 100644 --- a/public/app/plugins/panel/gettingstarted/components/DocsCard.tsx +++ b/public/app/plugins/panel/gettingstarted/components/DocsCard.tsx @@ -1,8 +1,11 @@ -import React, { FC } from 'react'; -import { Card } from '../types'; -import { Icon, stylesFactory, useTheme } from '@grafana/ui'; -import { GrafanaTheme } from '@grafana/data'; import { css } from '@emotion/css'; +import React, { FC } from 'react'; + +import { GrafanaTheme } from '@grafana/data'; +import { Icon, stylesFactory, useTheme } from '@grafana/ui'; + +import { Card } from '../types'; + import { cardContent, cardStyle, iconStyle } from './sharedStyles'; interface Props { diff --git a/public/app/plugins/panel/gettingstarted/components/Step.tsx b/public/app/plugins/panel/gettingstarted/components/Step.tsx index ea2dcbfd6fb..c4e8e26013a 100644 --- a/public/app/plugins/panel/gettingstarted/components/Step.tsx +++ b/public/app/plugins/panel/gettingstarted/components/Step.tsx @@ -1,10 +1,13 @@ -import React, { FC } from 'react'; import { css } from '@emotion/css'; +import React, { FC } from 'react'; + import { GrafanaTheme } from '@grafana/data'; import { stylesFactory, useTheme } from '@grafana/ui'; -import { TutorialCard } from './TutorialCard'; + import { Card, SetupStep, TutorialCardType } from '../types'; + import { DocsCard } from './DocsCard'; +import { TutorialCard } from './TutorialCard'; interface Props { step: SetupStep; diff --git a/public/app/plugins/panel/gettingstarted/components/TutorialCard.tsx b/public/app/plugins/panel/gettingstarted/components/TutorialCard.tsx index d0d4dc38ebb..53006f42c63 100644 --- a/public/app/plugins/panel/gettingstarted/components/TutorialCard.tsx +++ b/public/app/plugins/panel/gettingstarted/components/TutorialCard.tsx @@ -1,11 +1,14 @@ +import { css } from '@emotion/css'; import React, { FC, MouseEvent } from 'react'; + import { GrafanaTheme } from '@grafana/data'; import { Icon, stylesFactory, useTheme } from '@grafana/ui'; -import { css } from '@emotion/css'; import store from 'app/core/store'; -import { cardContent, cardStyle, iconStyle } from './sharedStyles'; + import { TutorialCardType } from '../types'; +import { cardContent, cardStyle, iconStyle } from './sharedStyles'; + interface Props { card: TutorialCardType; } diff --git a/public/app/plugins/panel/gettingstarted/components/sharedStyles.ts b/public/app/plugins/panel/gettingstarted/components/sharedStyles.ts index b89966f84de..8d37e07d00f 100644 --- a/public/app/plugins/panel/gettingstarted/components/sharedStyles.ts +++ b/public/app/plugins/panel/gettingstarted/components/sharedStyles.ts @@ -1,5 +1,6 @@ -import { GrafanaTheme } from '@grafana/data'; import { css } from '@emotion/css'; + +import { GrafanaTheme } from '@grafana/data'; import { stylesFactory } from '@grafana/ui'; export const cardStyle = stylesFactory((theme: GrafanaTheme, complete: boolean) => { diff --git a/public/app/plugins/panel/gettingstarted/module.ts b/public/app/plugins/panel/gettingstarted/module.ts index 6ce86a581aa..2cac3c7922d 100644 --- a/public/app/plugins/panel/gettingstarted/module.ts +++ b/public/app/plugins/panel/gettingstarted/module.ts @@ -1,4 +1,5 @@ import { PanelPlugin } from '@grafana/data'; + import { GettingStarted } from './GettingStarted'; // Simplest possible panel plugin diff --git a/public/app/plugins/panel/gettingstarted/steps.ts b/public/app/plugins/panel/gettingstarted/steps.ts index b69fb9c9d59..2d00cdc2699 100644 --- a/public/app/plugins/panel/gettingstarted/steps.ts +++ b/public/app/plugins/panel/gettingstarted/steps.ts @@ -1,6 +1,7 @@ -import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; import { getBackendSrv } from 'app/core/services/backend_srv'; import store from 'app/core/store'; +import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; + import { SetupStep } from './types'; const step1TutorialTitle = 'Grafana fundamentals'; diff --git a/public/app/plugins/panel/graph/GraphContextMenuCtrl.ts b/public/app/plugins/panel/graph/GraphContextMenuCtrl.ts index 20aed113d9e..3dea4edcb5c 100644 --- a/public/app/plugins/panel/graph/GraphContextMenuCtrl.ts +++ b/public/app/plugins/panel/graph/GraphContextMenuCtrl.ts @@ -1,5 +1,5 @@ -import { MenuItemProps } from '@grafana/ui'; import { FlotDataPoint } from '@grafana/data'; +import { MenuItemProps } from '@grafana/ui'; export class GraphContextMenuCtrl { private source?: FlotDataPoint | null; diff --git a/public/app/plugins/panel/graph/GraphMigrations.test.ts b/public/app/plugins/panel/graph/GraphMigrations.test.ts index a6a2a71f7ba..c9562ee74d9 100644 --- a/public/app/plugins/panel/graph/GraphMigrations.test.ts +++ b/public/app/plugins/panel/graph/GraphMigrations.test.ts @@ -1,4 +1,5 @@ import { PanelModel, FieldConfigSource, DataQuery } from '@grafana/data'; + import { graphPanelMigrationHandler } from './GraphMigrations'; describe('Graph Panel Migrations', () => { diff --git a/public/app/plugins/panel/graph/Legend/Legend.tsx b/public/app/plugins/panel/graph/Legend/Legend.tsx index ae28086d48e..37a72041840 100644 --- a/public/app/plugins/panel/graph/Legend/Legend.tsx +++ b/public/app/plugins/panel/graph/Legend/Legend.tsx @@ -1,7 +1,9 @@ import { sortBy as _sortBy } from 'lodash'; import React, { PureComponent } from 'react'; -import { TimeSeries } from 'app/core/core'; + import { CustomScrollbar, Icon } from '@grafana/ui'; +import { TimeSeries } from 'app/core/core'; + import { LegendStat, LegendItem, LEGEND_STATS } from './LegendSeriesItem'; interface LegendProps { diff --git a/public/app/plugins/panel/graph/Legend/LegendSeriesItem.tsx b/public/app/plugins/panel/graph/Legend/LegendSeriesItem.tsx index d6fabd2db00..f64d00fc59b 100644 --- a/public/app/plugins/panel/graph/Legend/LegendSeriesItem.tsx +++ b/public/app/plugins/panel/graph/Legend/LegendSeriesItem.tsx @@ -1,8 +1,9 @@ -import React, { PureComponent } from 'react'; import classNames from 'classnames'; -import { TimeSeries } from 'app/core/core'; -import { SeriesColorPicker, SeriesIcon } from '@grafana/ui'; +import React, { PureComponent } from 'react'; + import { selectors } from '@grafana/e2e-selectors'; +import { SeriesColorPicker, SeriesIcon } from '@grafana/ui'; +import { TimeSeries } from 'app/core/core'; export const LEGEND_STATS = ['min', 'max', 'avg', 'current', 'total'] as const; export type LegendStat = typeof LEGEND_STATS[number]; diff --git a/public/app/plugins/panel/graph/annotation_tooltip.ts b/public/app/plugins/panel/graph/annotation_tooltip.ts index b27a87861e1..56ba2773a4b 100644 --- a/public/app/plugins/panel/graph/annotation_tooltip.ts +++ b/public/app/plugins/panel/graph/annotation_tooltip.ts @@ -1,9 +1,10 @@ -import { isString, escape } from 'lodash'; import $ from 'jquery'; +import { isString, escape } from 'lodash'; + import coreModule from 'app/angular/core_module'; +import { ContextSrv } from 'app/core/services/context_srv'; import alertDef from 'app/features/alerting/state/alertDef'; import { DashboardSrv } from 'app/features/dashboard/services/DashboardSrv'; -import { ContextSrv } from 'app/core/services/context_srv'; /** @ngInject */ export function annotationTooltipDirective( diff --git a/public/app/plugins/panel/graph/axes_editor.ts b/public/app/plugins/panel/graph/axes_editor.ts index c14cb94c3cc..909620f21fb 100644 --- a/public/app/plugins/panel/graph/axes_editor.ts +++ b/public/app/plugins/panel/graph/axes_editor.ts @@ -1,4 +1,5 @@ import { selectors } from '@grafana/e2e-selectors'; + import { GraphCtrl } from './module'; export class AxesEditorCtrl { diff --git a/public/app/plugins/panel/graph/data_processor.ts b/public/app/plugins/panel/graph/data_processor.ts index edd5973cccf..51d5e068f62 100644 --- a/public/app/plugins/panel/graph/data_processor.ts +++ b/public/app/plugins/panel/graph/data_processor.ts @@ -1,5 +1,5 @@ import { find } from 'lodash'; -import { colors } from '@grafana/ui'; + import { DataFrame, dateTime, @@ -10,9 +10,10 @@ import { getTimeField, TimeRange, } from '@grafana/data'; -import TimeSeries from 'app/core/time_series2'; -import config from 'app/core/config'; +import { colors } from '@grafana/ui'; import { applyNullInsertThreshold } from '@grafana/ui/src/components/GraphNG/nullInsertThreshold'; +import config from 'app/core/config'; +import TimeSeries from 'app/core/time_series2'; type Options = { dataList: DataFrame[]; diff --git a/public/app/plugins/panel/graph/event_editor.ts b/public/app/plugins/panel/graph/event_editor.ts index a2ea2f2972b..a19a2d2a874 100644 --- a/public/app/plugins/panel/graph/event_editor.ts +++ b/public/app/plugins/panel/graph/event_editor.ts @@ -1,10 +1,12 @@ import { cloneDeep, isNumber } from 'lodash'; -import { coreModule } from 'app/angular/core_module'; + import { AnnotationEvent, dateTime } from '@grafana/data'; +import { coreModule } from 'app/angular/core_module'; import { MetricsPanelCtrl } from 'app/angular/panel/metrics_panel_ctrl'; + +import { contextSrv } from '../../../core/services/context_srv'; import { deleteAnnotation, saveAnnotation, updateAnnotation } from '../../../features/annotations/api'; import { getDashboardQueryRunner } from '../../../features/query/state/DashboardQueryRunner/DashboardQueryRunner'; -import { contextSrv } from '../../../core/services/context_srv'; export class EventEditorCtrl { // @ts-ignore initialized through Angular not constructor diff --git a/public/app/plugins/panel/graph/event_manager.ts b/public/app/plugins/panel/graph/event_manager.ts index 19797d0562a..a0f9345b85d 100644 --- a/public/app/plugins/panel/graph/event_manager.ts +++ b/public/app/plugins/panel/graph/event_manager.ts @@ -1,5 +1,7 @@ import { each, filter, keys } from 'lodash'; import tinycolor from 'tinycolor2'; + +import { AnnotationEvent } from '@grafana/data'; import { ALERTING_COLOR, DEFAULT_ANNOTATION_COLOR, @@ -10,8 +12,6 @@ import { } from '@grafana/ui'; import { MetricsPanelCtrl } from 'app/angular/panel/metrics_panel_ctrl'; -import { AnnotationEvent } from '@grafana/data'; - export class EventManager { event: AnnotationEvent | null = null; editorOpen = false; diff --git a/public/app/plugins/panel/graph/graph.ts b/public/app/plugins/panel/graph/graph.ts index 55692cf35be..13467292b78 100644 --- a/public/app/plugins/panel/graph/graph.ts +++ b/public/app/plugins/panel/graph/graph.ts @@ -10,23 +10,9 @@ import './jquery.flot.events'; import $ from 'jquery'; import { clone, find, flatten, isUndefined, map, max as _max, min as _min, sortBy as _sortBy, toNumber } from 'lodash'; -import { tickStep } from 'app/core/utils/ticks'; -import { updateLegendValues } from 'app/core/core'; -import { coreModule } from 'app/angular/core_module'; -import GraphTooltip from './graph_tooltip'; -import { ThresholdManager } from './threshold_manager'; -import { TimeRegionManager } from './time_region_manager'; -import { EventManager } from './event_manager'; -import { convertToHistogramData } from './histogram'; -import { alignYLevel } from './align_yaxes'; -import config from 'app/core/config'; import React from 'react'; import ReactDOM from 'react-dom'; -import { GraphLegendProps, Legend } from './Legend/Legend'; -import { GraphCtrl } from './module'; -import { graphTickFormatter, graphTimeFormat, IconName, MenuItemProps, MenuItemsGroup } from '@grafana/ui'; -import { provideTheme } from 'app/core/utils/ConfigProvider'; import { DataFrame, DataFrameView, @@ -49,11 +35,27 @@ import { PanelEvents, toUtc, } from '@grafana/data'; -import { GraphContextMenuCtrl } from './GraphContextMenuCtrl'; -import { TimeSrv } from 'app/features/dashboard/services/TimeSrv'; +import { graphTickFormatter, graphTimeFormat, IconName, MenuItemProps, MenuItemsGroup } from '@grafana/ui'; +import { coreModule } from 'app/angular/core_module'; +import config from 'app/core/config'; +import { updateLegendValues } from 'app/core/core'; import { ContextSrv } from 'app/core/services/context_srv'; +import { provideTheme } from 'app/core/utils/ConfigProvider'; +import { tickStep } from 'app/core/utils/ticks'; +import { TimeSrv } from 'app/features/dashboard/services/TimeSrv'; import { getFieldLinksSupplier } from 'app/features/panel/panellinks/linkSuppliers'; + import { DashboardModel } from '../../../features/dashboard/state'; + +import { GraphContextMenuCtrl } from './GraphContextMenuCtrl'; +import { GraphLegendProps, Legend } from './Legend/Legend'; +import { alignYLevel } from './align_yaxes'; +import { EventManager } from './event_manager'; +import GraphTooltip from './graph_tooltip'; +import { convertToHistogramData } from './histogram'; +import { GraphCtrl } from './module'; +import { ThresholdManager } from './threshold_manager'; +import { TimeRegionManager } from './time_region_manager'; import { isLegacyGraphHoverEvent } from './utils'; const LegendWithThemeProvider = provideTheme(Legend); diff --git a/public/app/plugins/panel/graph/graph_tooltip.ts b/public/app/plugins/panel/graph/graph_tooltip.ts index fcdef4e8078..86a90bc5789 100644 --- a/public/app/plugins/panel/graph/graph_tooltip.ts +++ b/public/app/plugins/panel/graph/graph_tooltip.ts @@ -1,6 +1,5 @@ import $ from 'jquery'; -import { appEvents } from 'app/core/core'; -import { CoreEvents } from 'app/types'; + import { textUtil, systemDateFormats, @@ -8,6 +7,8 @@ import { LegacyGraphHoverEvent, DataHoverClearEvent, } from '@grafana/data'; +import { appEvents } from 'app/core/core'; +import { CoreEvents } from 'app/types'; export default function GraphTooltip(this: any, elem: any, dashboard: any, scope: any, getSeriesFn: any) { const self = this; diff --git a/public/app/plugins/panel/graph/histogram.ts b/public/app/plugins/panel/graph/histogram.ts index f563fd4864f..17e8f69178a 100644 --- a/public/app/plugins/panel/graph/histogram.ts +++ b/public/app/plugins/panel/graph/histogram.ts @@ -1,6 +1,7 @@ -import TimeSeries from 'app/core/time_series2'; import { histogram } from 'd3'; +import TimeSeries from 'app/core/time_series2'; + /** * Convert series into array of series values. * @param data Array of series diff --git a/public/app/plugins/panel/graph/jquery.flot.events.ts b/public/app/plugins/panel/graph/jquery.flot.events.ts index af0b37248c1..6d680122795 100644 --- a/public/app/plugins/panel/graph/jquery.flot.events.ts +++ b/public/app/plugins/panel/graph/jquery.flot.events.ts @@ -2,6 +2,7 @@ import $ from 'jquery'; import { partition, each } from 'lodash'; //@ts-ignore import Drop from 'tether-drop'; + import { CreatePlotOverlay } from '@grafana/data'; import { getLegacyAngularInjector } from '@grafana/runtime'; diff --git a/public/app/plugins/panel/graph/module.ts b/public/app/plugins/panel/graph/module.ts index cd7a23f6b23..4d04007096a 100644 --- a/public/app/plugins/panel/graph/module.ts +++ b/public/app/plugins/panel/graph/module.ts @@ -5,30 +5,30 @@ import './time_regions_form'; import './annotation_tooltip'; import './event_editor'; -import template from './template'; +import { auto } from 'angular'; import { defaults, find, without } from 'lodash'; -import { DataProcessor } from './data_processor'; -import { axesEditorComponent } from './axes_editor'; +import { DataFrame, FieldConfigProperty, getColorForTheme, PanelEvents, PanelPlugin } from '@grafana/data'; +import { locationService } from '@grafana/runtime'; +import { MetricsPanelCtrl } from 'app/angular/panel/metrics_panel_ctrl'; import config from 'app/core/config'; import TimeSeries from 'app/core/time_series2'; -import { DataFrame, FieldConfigProperty, getColorForTheme, PanelEvents, PanelPlugin } from '@grafana/data'; +import { ThresholdMapper } from 'app/features/alerting/state/ThresholdMapper'; +import { changePanelPlugin } from 'app/features/panel/state/actions'; +import { dispatch } from 'app/store/store'; + +import { appEvents } from '../../../core/core'; +import { loadSnapshotData } from '../../../features/dashboard/utils/loadSnapshotData'; +import { annotationsFromDataFrames } from '../../../features/query/state/DashboardQueryRunner/utils'; +import { ZoomOutEvent } from '../../../types/events'; import { GraphContextMenuCtrl } from './GraphContextMenuCtrl'; import { graphPanelMigrationHandler } from './GraphMigrations'; +import { axesEditorComponent } from './axes_editor'; +import { DataProcessor } from './data_processor'; +import template from './template'; import { DataWarning, GraphFieldConfig, GraphPanelOptions } from './types'; - -import { auto } from 'angular'; -import { locationService } from '@grafana/runtime'; import { getDataTimeRange } from './utils'; -import { changePanelPlugin } from 'app/features/panel/state/actions'; -import { dispatch } from 'app/store/store'; -import { ThresholdMapper } from 'app/features/alerting/state/ThresholdMapper'; -import { appEvents } from '../../../core/core'; -import { ZoomOutEvent } from '../../../types/events'; -import { MetricsPanelCtrl } from 'app/angular/panel/metrics_panel_ctrl'; -import { loadSnapshotData } from '../../../features/dashboard/utils/loadSnapshotData'; -import { annotationsFromDataFrames } from '../../../features/query/state/DashboardQueryRunner/utils'; export class GraphCtrl extends MetricsPanelCtrl { static template = template; diff --git a/public/app/plugins/panel/graph/series_overrides_ctrl.ts b/public/app/plugins/panel/graph/series_overrides_ctrl.ts index 67b1fcdc710..356d4dde79d 100644 --- a/public/app/plugins/panel/graph/series_overrides_ctrl.ts +++ b/public/app/plugins/panel/graph/series_overrides_ctrl.ts @@ -1,6 +1,7 @@ import { map, each, isUndefined } from 'lodash'; -import coreModule from 'app/angular/core_module'; + import { textUtil } from '@grafana/data'; +import coreModule from 'app/angular/core_module'; /** @ngInject */ export function SeriesOverridesCtrl($scope: any, $element: JQuery, popoverSrv: any) { diff --git a/public/app/plugins/panel/graph/specs/data_processor.test.ts b/public/app/plugins/panel/graph/specs/data_processor.test.ts index 6f86c5df091..e0bc733f008 100644 --- a/public/app/plugins/panel/graph/specs/data_processor.test.ts +++ b/public/app/plugins/panel/graph/specs/data_processor.test.ts @@ -1,6 +1,7 @@ -import { DataProcessor } from '../data_processor'; import { getProcessedDataFrames } from 'app/features/query/state/runRequest'; +import { DataProcessor } from '../data_processor'; + describe('Graph DataProcessor', () => { const panel: any = { xaxis: { mode: 'series' }, diff --git a/public/app/plugins/panel/graph/specs/graph.test.ts b/public/app/plugins/panel/graph/specs/graph.test.ts index a902fc3737a..8ef8e73ff1a 100644 --- a/public/app/plugins/panel/graph/specs/graph.test.ts +++ b/public/app/plugins/panel/graph/specs/graph.test.ts @@ -1,13 +1,14 @@ -import { GraphCtrl } from '../module'; +import $ from 'jquery'; + +import { dateTime, EventBusSrv } from '@grafana/data'; import { MetricsPanelCtrl } from 'app/angular/panel/metrics_panel_ctrl'; import { PanelCtrl } from 'app/angular/panel/panel_ctrl'; import config from 'app/core/config'; - import TimeSeries from 'app/core/time_series2'; -import $ from 'jquery'; -import { graphDirective, GraphElement } from '../graph'; -import { dateTime, EventBusSrv } from '@grafana/data'; + import { DashboardModel } from '../../../../features/dashboard/state'; +import { graphDirective, GraphElement } from '../graph'; +import { GraphCtrl } from '../module'; jest.mock('../event_manager', () => ({ EventManager: class EventManagerMock { diff --git a/public/app/plugins/panel/graph/specs/graph_ctrl.test.ts b/public/app/plugins/panel/graph/specs/graph_ctrl.test.ts index 9bab71987be..b88833a337e 100644 --- a/public/app/plugins/panel/graph/specs/graph_ctrl.test.ts +++ b/public/app/plugins/panel/graph/specs/graph_ctrl.test.ts @@ -1,6 +1,7 @@ -import { GraphCtrl } from '../module'; import { dateTime } from '@grafana/data'; +import { GraphCtrl } from '../module'; + jest.mock('../graph', () => ({})); describe.skip('GraphCtrl', () => { diff --git a/public/app/plugins/panel/graph/specs/graph_tooltip.test.ts b/public/app/plugins/panel/graph/specs/graph_tooltip.test.ts index 62e4c9a5cd2..a1ceae25b25 100644 --- a/public/app/plugins/panel/graph/specs/graph_tooltip.test.ts +++ b/public/app/plugins/panel/graph/specs/graph_tooltip.test.ts @@ -1,6 +1,7 @@ jest.mock('app/core/core', () => ({})); import $ from 'jquery'; + import GraphTooltip from '../graph_tooltip'; const scope: any = { diff --git a/public/app/plugins/panel/graph/specs/threshold_manager.test.ts b/public/app/plugins/panel/graph/specs/threshold_manager.test.ts index 9f3d77a6ee3..df216a4761a 100644 --- a/public/app/plugins/panel/graph/specs/threshold_manager.test.ts +++ b/public/app/plugins/panel/graph/specs/threshold_manager.test.ts @@ -1,5 +1,7 @@ import angular from 'angular'; + import TimeSeries from 'app/core/time_series2'; + import { ThresholdManager } from '../threshold_manager'; describe('ThresholdManager', () => { diff --git a/public/app/plugins/panel/graph/specs/time_region_manager.test.ts b/public/app/plugins/panel/graph/specs/time_region_manager.test.ts index 72ad92402e8..960baaa4287 100644 --- a/public/app/plugins/panel/graph/specs/time_region_manager.test.ts +++ b/public/app/plugins/panel/graph/specs/time_region_manager.test.ts @@ -1,6 +1,7 @@ -import { TimeRegionManager, colorModes } from '../time_region_manager'; import { dateTime } from '@grafana/data'; +import { TimeRegionManager, colorModes } from '../time_region_manager'; + describe('TimeRegionManager', () => { function plotOptionsScenario(desc: string, func: any) { describe(desc, () => { diff --git a/public/app/plugins/panel/graph/threshold_manager.ts b/public/app/plugins/panel/graph/threshold_manager.ts index f5ce394e1d5..533ef94392b 100644 --- a/public/app/plugins/panel/graph/threshold_manager.ts +++ b/public/app/plugins/panel/graph/threshold_manager.ts @@ -1,10 +1,11 @@ import 'vendor/flot/jquery.flot'; import $ from 'jquery'; import { isNumber } from 'lodash'; + import { getColorForTheme } from '@grafana/data'; -import { CoreEvents } from 'app/types'; import { PanelCtrl } from 'app/angular/panel/panel_ctrl'; import { config } from 'app/core/config'; +import { CoreEvents } from 'app/types'; export class ThresholdManager { plot: any; diff --git a/public/app/plugins/panel/graph/thresholds_form.ts b/public/app/plugins/panel/graph/thresholds_form.ts index 5609a66b54a..bff1ea0ec75 100644 --- a/public/app/plugins/panel/graph/thresholds_form.ts +++ b/public/app/plugins/panel/graph/thresholds_form.ts @@ -1,6 +1,7 @@ +import tinycolor from 'tinycolor2'; + import coreModule from 'app/angular/core_module'; import config from 'app/core/config'; -import tinycolor from 'tinycolor2'; export class ThresholdFormCtrl { panelCtrl: any; panel: any; diff --git a/public/app/plugins/panel/graph/time_region_manager.ts b/public/app/plugins/panel/graph/time_region_manager.ts index 5d50a2ae34e..cd83a083871 100644 --- a/public/app/plugins/panel/graph/time_region_manager.ts +++ b/public/app/plugins/panel/graph/time_region_manager.ts @@ -1,5 +1,6 @@ import 'vendor/flot/jquery.flot'; import { map } from 'lodash'; + import { getColorForTheme, dateTime, DateTime, AbsoluteTimeRange, GrafanaTheme } from '@grafana/data'; import { config } from 'app/core/config'; diff --git a/public/app/plugins/panel/graph/time_regions_form.ts b/public/app/plugins/panel/graph/time_regions_form.ts index 3c911c59a8e..98eb0f1d207 100644 --- a/public/app/plugins/panel/graph/time_regions_form.ts +++ b/public/app/plugins/panel/graph/time_regions_form.ts @@ -1,4 +1,5 @@ import coreModule from 'app/angular/core_module'; + import { getColorModes } from './time_region_manager'; export class TimeRegionFormCtrl { diff --git a/public/app/plugins/panel/graph/utils.test.ts b/public/app/plugins/panel/graph/utils.test.ts index daa1f03b01b..071ecc5d132 100644 --- a/public/app/plugins/panel/graph/utils.test.ts +++ b/public/app/plugins/panel/graph/utils.test.ts @@ -1,4 +1,5 @@ import { toDataFrame, FieldType } from '@grafana/data'; + import { getDataTimeRange } from './utils'; describe('DataFrame utility functions', () => { diff --git a/public/app/plugins/panel/heatmap-new/HeatmapHoverView.tsx b/public/app/plugins/panel/heatmap-new/HeatmapHoverView.tsx index 8f83d59879f..97b5d3419bf 100644 --- a/public/app/plugins/panel/heatmap-new/HeatmapHoverView.tsx +++ b/public/app/plugins/panel/heatmap-new/HeatmapHoverView.tsx @@ -1,11 +1,12 @@ import React, { useEffect, useRef } from 'react'; -import { Field, FieldType, formattedValueToString, getFieldDisplayName, LinkModel } from '@grafana/data'; -import { HeatmapHoverEvent } from './utils'; -import { BucketLayout, HeatmapData } from './fields'; +import { Field, FieldType, formattedValueToString, getFieldDisplayName, LinkModel } from '@grafana/data'; import { LinkButton, VerticalGroup } from '@grafana/ui'; import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv'; +import { BucketLayout, HeatmapData } from './fields'; +import { HeatmapHoverEvent } from './utils'; + type Props = { data: HeatmapData; hover: HeatmapHoverEvent; diff --git a/public/app/plugins/panel/heatmap-new/HeatmapPanel.tsx b/public/app/plugins/panel/heatmap-new/HeatmapPanel.tsx index 490f66842ff..d1cf7093238 100644 --- a/public/app/plugins/panel/heatmap-new/HeatmapPanel.tsx +++ b/public/app/plugins/panel/heatmap-new/HeatmapPanel.tsx @@ -1,6 +1,8 @@ -import React, { useCallback, useMemo, useRef, useState } from 'react'; import { css } from '@emotion/css'; +import React, { useCallback, useMemo, useRef, useState } from 'react'; + import { GrafanaTheme2, PanelProps, reduceField, ReducerID, TimeRange } from '@grafana/data'; +import { PanelDataErrorView } from '@grafana/runtime'; import { Portal, UPlotChart, @@ -10,15 +12,14 @@ import { VizTooltipContainer, LegendDisplayMode, } from '@grafana/ui'; -import { PanelDataErrorView } from '@grafana/runtime'; +import { CloseButton } from 'app/core/components/CloseButton/CloseButton'; +import { ColorScale } from 'app/core/components/ColorScale/ColorScale'; +import { HeatmapHoverView } from './HeatmapHoverView'; import { HeatmapData, prepareHeatmapData } from './fields'; import { PanelOptions } from './models.gen'; import { quantizeScheme } from './palettes'; import { HeatmapHoverEvent, prepConfig } from './utils'; -import { HeatmapHoverView } from './HeatmapHoverView'; -import { CloseButton } from 'app/core/components/CloseButton/CloseButton'; -import { ColorScale } from 'app/core/components/ColorScale/ColorScale'; interface HeatmapPanelProps extends PanelProps {} diff --git a/public/app/plugins/panel/heatmap-new/fields.test.ts b/public/app/plugins/panel/heatmap-new/fields.test.ts index a8c5e7ee18a..7bc2e1b1441 100644 --- a/public/app/plugins/panel/heatmap-new/fields.test.ts +++ b/public/app/plugins/panel/heatmap-new/fields.test.ts @@ -1,4 +1,5 @@ import { createTheme } from '@grafana/data'; + import { PanelOptions } from './models.gen'; const theme = createTheme(); diff --git a/public/app/plugins/panel/heatmap-new/fields.ts b/public/app/plugins/panel/heatmap-new/fields.ts index 66030132e22..4d120439e38 100644 --- a/public/app/plugins/panel/heatmap-new/fields.ts +++ b/public/app/plugins/panel/heatmap-new/fields.ts @@ -9,6 +9,7 @@ import { GrafanaTheme2, } from '@grafana/data'; import { calculateHeatmapFromData, bucketsToScanlines } from 'app/features/transformers/calculateHeatmap/heatmap'; + import { HeatmapSourceMode, PanelOptions } from './models.gen'; export const enum BucketLayout { diff --git a/public/app/plugins/panel/heatmap-new/migrations.test.ts b/public/app/plugins/panel/heatmap-new/migrations.test.ts index acbfbbdfc9a..43e5465d0c4 100644 --- a/public/app/plugins/panel/heatmap-new/migrations.test.ts +++ b/public/app/plugins/panel/heatmap-new/migrations.test.ts @@ -1,4 +1,5 @@ import { PanelModel, FieldConfigSource } from '@grafana/data'; + import { heatmapChangedHandler } from './migrations'; describe('Heatmap Migrations', () => { diff --git a/public/app/plugins/panel/heatmap-new/migrations.ts b/public/app/plugins/panel/heatmap-new/migrations.ts index a5c00a66abc..9daea701438 100644 --- a/public/app/plugins/panel/heatmap-new/migrations.ts +++ b/public/app/plugins/panel/heatmap-new/migrations.ts @@ -4,6 +4,7 @@ import { HeatmapCalculationMode, HeatmapCalculationOptions, } from 'app/features/transformers/calculateHeatmap/models.gen'; + import { HeatmapSourceMode, PanelOptions, defaultPanelOptions } from './models.gen'; /** diff --git a/public/app/plugins/panel/heatmap-new/module.tsx b/public/app/plugins/panel/heatmap-new/module.tsx index d425a25217d..397e1f0d1fe 100644 --- a/public/app/plugins/panel/heatmap-new/module.tsx +++ b/public/app/plugins/panel/heatmap-new/module.tsx @@ -1,8 +1,14 @@ import React from 'react'; -import { GraphFieldConfig, VisibilityMode } from '@grafana/schema'; + import { Field, FieldType, PanelPlugin } from '@grafana/data'; +import { config } from '@grafana/runtime'; +import { GraphFieldConfig, VisibilityMode } from '@grafana/schema'; import { commonOptionsBuilder } from '@grafana/ui'; +import { ColorScale } from 'app/core/components/ColorScale/ColorScale'; +import { addHeatmapCalculationOptions } from 'app/features/transformers/calculateHeatmap/editor/helper'; + import { HeatmapPanel } from './HeatmapPanel'; +import { heatmapChangedHandler } from './migrations'; import { PanelOptions, defaultPanelOptions, @@ -10,12 +16,8 @@ import { HeatmapColorMode, HeatmapColorScale, } from './models.gen'; -import { HeatmapSuggestionsSupplier } from './suggestions'; -import { heatmapChangedHandler } from './migrations'; -import { addHeatmapCalculationOptions } from 'app/features/transformers/calculateHeatmap/editor/helper'; import { colorSchemes, quantizeScheme } from './palettes'; -import { config } from '@grafana/runtime'; -import { ColorScale } from 'app/core/components/ColorScale/ColorScale'; +import { HeatmapSuggestionsSupplier } from './suggestions'; export const plugin = new PanelPlugin(HeatmapPanel) .useFieldConfig() diff --git a/public/app/plugins/panel/heatmap-new/palettes.ts b/public/app/plugins/panel/heatmap-new/palettes.ts index 50fa0a54f9b..7a4ea65c46d 100644 --- a/public/app/plugins/panel/heatmap-new/palettes.ts +++ b/public/app/plugins/panel/heatmap-new/palettes.ts @@ -1,9 +1,11 @@ -import { GrafanaTheme2 } from '@grafana/data'; import * as d3 from 'd3'; import * as d3ScaleChromatic from 'd3-scale-chromatic'; -import { HeatmapColorOptions, defaultPanelOptions, HeatmapColorMode, HeatmapColorScale } from './models.gen'; import tinycolor from 'tinycolor2'; +import { GrafanaTheme2 } from '@grafana/data'; + +import { HeatmapColorOptions, defaultPanelOptions, HeatmapColorMode, HeatmapColorScale } from './models.gen'; + // https://observablehq.com/@d3/color-schemes?collection=@d3/d3-scale-chromatic // the previous heatmap panel used d3 deps and some code to interpolate to static 9-color palettes. here we just hard-code them for clarity. diff --git a/public/app/plugins/panel/heatmap-new/suggestions.ts b/public/app/plugins/panel/heatmap-new/suggestions.ts index 508c88b0040..70d84a51dbc 100644 --- a/public/app/plugins/panel/heatmap-new/suggestions.ts +++ b/public/app/plugins/panel/heatmap-new/suggestions.ts @@ -1,5 +1,6 @@ import { VisualizationSuggestionsBuilder } from '@grafana/data'; import { config } from '@grafana/runtime'; + import { prepareHeatmapData } from './fields'; import { PanelOptions, defaultPanelOptions } from './models.gen'; diff --git a/public/app/plugins/panel/heatmap-new/utils.ts b/public/app/plugins/panel/heatmap-new/utils.ts index 7026df72f39..11539a30693 100644 --- a/public/app/plugins/panel/heatmap-new/utils.ts +++ b/public/app/plugins/panel/heatmap-new/utils.ts @@ -1,10 +1,12 @@ import { MutableRefObject, RefObject } from 'react'; +import uPlot from 'uplot'; + import { GrafanaTheme2, TimeRange } from '@grafana/data'; import { AxisPlacement, ScaleDirection, ScaleOrientation } from '@grafana/schema'; import { UPlotConfigBuilder } from '@grafana/ui'; -import uPlot from 'uplot'; import { pointWithin, Quadtree, Rect } from '../barchart/quadtree'; + import { BucketLayout, HeatmapData } from './fields'; interface PathbuilderOpts { diff --git a/public/app/plugins/panel/heatmap/color_legend.ts b/public/app/plugins/panel/heatmap/color_legend.ts index bb8c3fa99d1..d6eb9892d21 100644 --- a/public/app/plugins/panel/heatmap/color_legend.ts +++ b/public/app/plugins/panel/heatmap/color_legend.ts @@ -1,12 +1,14 @@ -import { find, isEmpty, isNil, sortBy, uniq } from 'lodash'; -import $ from 'jquery'; import * as d3 from 'd3'; +import $ from 'jquery'; +import { find, isEmpty, isNil, sortBy, uniq } from 'lodash'; + +import { PanelEvents, getColorForTheme } from '@grafana/data'; +import coreModule from 'app/angular/core_module'; +import { config } from 'app/core/config'; import { contextSrv } from 'app/core/core'; import { tickStep } from 'app/core/utils/ticks'; + import { getColorScale, getOpacityScale } from './color_scale'; -import coreModule from 'app/angular/core_module'; -import { PanelEvents, getColorForTheme } from '@grafana/data'; -import { config } from 'app/core/config'; const LEGEND_HEIGHT_PX = 6; const LEGEND_WIDTH_PX = 100; diff --git a/public/app/plugins/panel/heatmap/heatmap_ctrl.ts b/public/app/plugins/panel/heatmap/heatmap_ctrl.ts index c9effe62ba9..0ad0642afbd 100644 --- a/public/app/plugins/panel/heatmap/heatmap_ctrl.ts +++ b/public/app/plugins/panel/heatmap/heatmap_ctrl.ts @@ -1,10 +1,20 @@ -import { MetricsPanelCtrl } from 'app/plugins/sdk'; +import { auto } from 'angular'; import { defaultsDeep, includes, keys, map, reduce, min as _min, max as _max } from 'lodash'; -import kbn from 'app/core/utils/kbn'; + +import { LegacyResponseData, PanelEvents, DataFrame, rangeUtil } from '@grafana/data'; +import appEvents from 'app/core/app_events'; import TimeSeries from 'app/core/time_series2'; +import kbn from 'app/core/utils/kbn'; +import { TimeSrv } from 'app/features/dashboard/services/TimeSrv'; +import { getProcessedDataFrames } from 'app/features/query/state/runRequest'; +import { TemplateSrv } from 'app/features/templating/template_srv'; +import { MetricsPanelCtrl } from 'app/plugins/sdk'; +import { ZoomOutEvent } from 'app/types/events'; + +import { DataProcessor } from '../graph/data_processor'; + import { axesEditor } from './axes_editor'; import { heatmapDisplayEditor } from './display_editor'; -import rendering from './rendering'; import { convertToHeatMap, convertToCards, @@ -12,14 +22,7 @@ import { calculateBucketSize, sortSeriesByLabel, } from './heatmap_data_converter'; -import { auto } from 'angular'; -import { getProcessedDataFrames } from 'app/features/query/state/runRequest'; -import { DataProcessor } from '../graph/data_processor'; -import { LegacyResponseData, PanelEvents, DataFrame, rangeUtil } from '@grafana/data'; -import { TemplateSrv } from 'app/features/templating/template_srv'; -import { TimeSrv } from 'app/features/dashboard/services/TimeSrv'; -import appEvents from 'app/core/app_events'; -import { ZoomOutEvent } from 'app/types/events'; +import rendering from './rendering'; const X_BUCKET_NUMBER_DEFAULT = 30; const Y_BUCKET_NUMBER_DEFAULT = 10; diff --git a/public/app/plugins/panel/heatmap/heatmap_data_converter.ts b/public/app/plugins/panel/heatmap/heatmap_data_converter.ts index 570590adec9..95183a6a7f8 100644 --- a/public/app/plugins/panel/heatmap/heatmap_data_converter.ts +++ b/public/app/plugins/panel/heatmap/heatmap_data_converter.ts @@ -1,5 +1,7 @@ import { concat, forEach, isEmpty, isEqual, isNumber, sortBy } from 'lodash'; + import { TimeSeries } from 'app/core/core'; + import { Bucket, HeatmapCard, HeatmapCardStats, YBucket, XBucket } from './types'; const VALUE_INDEX = 0; diff --git a/public/app/plugins/panel/heatmap/heatmap_tooltip.ts b/public/app/plugins/panel/heatmap/heatmap_tooltip.ts index 3c2614d5f62..e7400ee04e4 100644 --- a/public/app/plugins/panel/heatmap/heatmap_tooltip.ts +++ b/public/app/plugins/panel/heatmap/heatmap_tooltip.ts @@ -1,9 +1,11 @@ import * as d3 from 'd3'; import $ from 'jquery'; import { filter, find, isNumber, map, reduce } from 'lodash'; -import { getValueBucketBound } from './heatmap_data_converter'; + import { getValueFormat, formattedValueToString } from '@grafana/data'; +import { getValueBucketBound } from './heatmap_data_converter'; + const TOOLTIP_PADDING_X = 30; const TOOLTIP_PADDING_Y = 5; const HISTOGRAM_WIDTH = 160; diff --git a/public/app/plugins/panel/heatmap/rendering.ts b/public/app/plugins/panel/heatmap/rendering.ts index 664c0baf68f..a397249286c 100644 --- a/public/app/plugins/panel/heatmap/rendering.ts +++ b/public/app/plugins/panel/heatmap/rendering.ts @@ -1,11 +1,7 @@ -import { find, isEmpty, isNaN, isNil, isString, map, max, min, toNumber } from 'lodash'; -import $ from 'jquery'; import * as d3 from 'd3'; -import { contextSrv } from 'app/core/core'; -import * as ticksUtils from 'app/core/utils/ticks'; -import { HeatmapTooltip } from './heatmap_tooltip'; -import { mergeZeroBuckets } from './heatmap_data_converter'; -import { getColorScale, getOpacityScale } from './color_scale'; +import $ from 'jquery'; +import { find, isEmpty, isNaN, isNil, isString, map, max, min, toNumber } from 'lodash'; + import { dateTimeFormat, formattedValueToString, @@ -18,6 +14,12 @@ import { } from '@grafana/data'; import { graphTimeFormat } from '@grafana/ui'; import { config } from 'app/core/config'; +import { contextSrv } from 'app/core/core'; +import * as ticksUtils from 'app/core/utils/ticks'; + +import { getColorScale, getOpacityScale } from './color_scale'; +import { mergeZeroBuckets } from './heatmap_data_converter'; +import { HeatmapTooltip } from './heatmap_tooltip'; const MIN_CARD_SIZE = 1, CARD_PADDING = 1, diff --git a/public/app/plugins/panel/heatmap/specs/heatmap_ctrl.test.ts b/public/app/plugins/panel/heatmap/specs/heatmap_ctrl.test.ts index 2076cf522d9..8f30bf4c14a 100644 --- a/public/app/plugins/panel/heatmap/specs/heatmap_ctrl.test.ts +++ b/public/app/plugins/panel/heatmap/specs/heatmap_ctrl.test.ts @@ -1,7 +1,8 @@ -import { HeatmapCtrl } from '../heatmap_ctrl'; import { dateTime } from '@grafana/data'; import { TimeSrv } from 'app/features/dashboard/services/TimeSrv'; +import { HeatmapCtrl } from '../heatmap_ctrl'; + describe('HeatmapCtrl', () => { const ctx = {} as any; diff --git a/public/app/plugins/panel/heatmap/specs/heatmap_data_converter.test.ts b/public/app/plugins/panel/heatmap/specs/heatmap_data_converter.test.ts index d29751929a5..7fbcef1b816 100644 --- a/public/app/plugins/panel/heatmap/specs/heatmap_data_converter.test.ts +++ b/public/app/plugins/panel/heatmap/specs/heatmap_data_converter.test.ts @@ -1,6 +1,8 @@ import { cloneDeep, each, map } from 'lodash'; -import { describe, beforeEach, it, expect } from '../../../../../test/lib/common'; + import TimeSeries from 'app/core/time_series2'; + +import { describe, beforeEach, it, expect } from '../../../../../test/lib/common'; import { convertToHeatMap, convertToCards, diff --git a/public/app/plugins/panel/histogram/Histogram.tsx b/public/app/plugins/panel/histogram/Histogram.tsx index 29115ecff96..ae38a2804c6 100644 --- a/public/app/plugins/panel/histogram/Histogram.tsx +++ b/public/app/plugins/panel/histogram/Histogram.tsx @@ -1,5 +1,17 @@ import React from 'react'; import uPlot, { AlignedData } from 'uplot'; + +import { + DataFrame, + formattedValueToString, + getFieldColorModeForField, + getFieldSeriesColor, + GrafanaTheme2, +} from '@grafana/data'; +import { + histogramBucketSizes, + histogramFrameBucketMaxFieldName, +} from '@grafana/data/src/transformations/transformers/histogram'; import { VizLegendOptions, LegendDisplayMode, @@ -8,13 +20,6 @@ import { ScaleDirection, ScaleOrientation, } from '@grafana/schema'; -import { - DataFrame, - formattedValueToString, - getFieldColorModeForField, - getFieldSeriesColor, - GrafanaTheme2, -} from '@grafana/data'; import { Themeable2, UPlotConfigBuilder, @@ -25,10 +30,6 @@ import { UPLOT_AXIS_FONT_SIZE, } from '@grafana/ui'; -import { - histogramBucketSizes, - histogramFrameBucketMaxFieldName, -} from '@grafana/data/src/transformations/transformers/histogram'; import { PanelOptions } from './models.gen'; function incrRoundDn(num: number, incr: number) { diff --git a/public/app/plugins/panel/histogram/HistogramPanel.tsx b/public/app/plugins/panel/histogram/HistogramPanel.tsx index 71b5170dc15..dc459235915 100644 --- a/public/app/plugins/panel/histogram/HistogramPanel.tsx +++ b/public/app/plugins/panel/histogram/HistogramPanel.tsx @@ -1,14 +1,14 @@ import React, { useMemo } from 'react'; + import { PanelProps, buildHistogram, getHistogramFields } from '@grafana/data'; +import { histogramFieldsToFrame } from '@grafana/data/src/transformations/transformers/histogram'; +import { useTheme2 } from '@grafana/ui'; import { Histogram, getBucketSize } from './Histogram'; import { PanelOptions } from './models.gen'; -import { useTheme2 } from '@grafana/ui'; type Props = PanelProps; -import { histogramFieldsToFrame } from '@grafana/data/src/transformations/transformers/histogram'; - export const HistogramPanel: React.FC = ({ data, options, width, height }) => { const theme = useTheme2(); diff --git a/public/app/plugins/panel/histogram/module.tsx b/public/app/plugins/panel/histogram/module.tsx index 8eef08ec341..de820bb09ee 100644 --- a/public/app/plugins/panel/histogram/module.tsx +++ b/public/app/plugins/panel/histogram/module.tsx @@ -1,11 +1,11 @@ import { FieldColorModeId, FieldConfigProperty, PanelPlugin } from '@grafana/data'; -import { HistogramPanel } from './HistogramPanel'; +import { histogramFieldInfo } from '@grafana/data/src/transformations/transformers/histogram'; import { commonOptionsBuilder, graphFieldOptions } from '@grafana/ui'; + +import { HistogramPanel } from './HistogramPanel'; import { PanelFieldConfig, PanelOptions, defaultPanelFieldConfig, defaultPanelOptions } from './models.gen'; import { originalDataHasHistogram } from './utils'; -import { histogramFieldInfo } from '@grafana/data/src/transformations/transformers/histogram'; - export const plugin = new PanelPlugin(HistogramPanel) .setPanelOptions((builder) => { builder diff --git a/public/app/plugins/panel/histogram/utils.ts b/public/app/plugins/panel/histogram/utils.ts index 5f6de56ab79..a98e8768f3d 100644 --- a/public/app/plugins/panel/histogram/utils.ts +++ b/public/app/plugins/panel/histogram/utils.ts @@ -1,5 +1,4 @@ import { DataFrame, FieldType } from '@grafana/data'; - import { histogramFrameBucketMinFieldName, histogramFrameBucketMaxFieldName, diff --git a/public/app/plugins/panel/icon/IconPanel.tsx b/public/app/plugins/panel/icon/IconPanel.tsx index 3ef04b68887..2c679db7084 100644 --- a/public/app/plugins/panel/icon/IconPanel.tsx +++ b/public/app/plugins/panel/icon/IconPanel.tsx @@ -1,8 +1,9 @@ import React, { Component } from 'react'; + import { PanelProps } from '@grafana/data'; -import { PanelOptions } from './models.gen'; -import { ElementState } from 'app/features/canvas/runtime/element'; +import { HorizontalConstraint, VerticalConstraint } from 'app/features/canvas'; import { iconItem } from 'app/features/canvas/elements/icon'; +import { ElementState } from 'app/features/canvas/runtime/element'; import { ColorDimensionConfig, DimensionContext, @@ -16,7 +17,8 @@ import { ScaleDimensionConfig, TextDimensionConfig, } from 'app/features/dimensions'; -import { HorizontalConstraint, VerticalConstraint } from 'app/features/canvas'; + +import { PanelOptions } from './models.gen'; interface Props extends PanelProps {} diff --git a/public/app/plugins/panel/icon/module.tsx b/public/app/plugins/panel/icon/module.tsx index 465dde0e3da..37e8706b0a5 100644 --- a/public/app/plugins/panel/icon/module.tsx +++ b/public/app/plugins/panel/icon/module.tsx @@ -1,10 +1,11 @@ import { FieldConfigProperty, PanelPlugin } from '@grafana/data'; +import { CanvasElementOptions } from 'app/features/canvas'; +import { IconConfig, iconItem } from 'app/features/canvas/elements/icon'; + +import { optionBuilder } from '../canvas/editor/options'; import { IconPanel } from './IconPanel'; import { defaultPanelOptions, PanelOptions } from './models.gen'; -import { IconConfig, iconItem } from 'app/features/canvas/elements/icon'; -import { optionBuilder } from '../canvas/editor/options'; -import { CanvasElementOptions } from 'app/features/canvas'; export const plugin = new PanelPlugin(IconPanel) .setNoPadding() // extend to panel edges diff --git a/public/app/plugins/panel/live/LiveChannelEditor.tsx b/public/app/plugins/panel/live/LiveChannelEditor.tsx index 3f475e1d9b2..2f61b2834f1 100644 --- a/public/app/plugins/panel/live/LiveChannelEditor.tsx +++ b/public/app/plugins/panel/live/LiveChannelEditor.tsx @@ -1,6 +1,6 @@ -import React, { PureComponent } from 'react'; import { css } from '@emotion/css'; -import { Select, Alert, Label, stylesFactory } from '@grafana/ui'; +import React, { PureComponent } from 'react'; + import { LiveChannelScope, LiveChannelAddress, @@ -8,9 +8,10 @@ import { StandardEditorProps, GrafanaTheme, } from '@grafana/data'; +import { Select, Alert, Label, stylesFactory } from '@grafana/ui'; +import { config } from 'app/core/config'; import { LivePanelOptions } from './types'; -import { config } from 'app/core/config'; type Props = StandardEditorProps; diff --git a/public/app/plugins/panel/live/LivePanel.tsx b/public/app/plugins/panel/live/LivePanel.tsx index b84332f7729..e9c2aebb0ab 100755 --- a/public/app/plugins/panel/live/LivePanel.tsx +++ b/public/app/plugins/panel/live/LivePanel.tsx @@ -1,6 +1,8 @@ +import { css, cx } from '@emotion/css'; +import { isEqual } from 'lodash'; import React, { PureComponent } from 'react'; import { Unsubscribable, PartialObserver } from 'rxjs'; -import { Alert, stylesFactory, Button, JSONFormatter, CustomScrollbar, CodeEditor } from '@grafana/ui'; + import { GrafanaTheme, PanelProps, @@ -15,13 +17,14 @@ import { applyFieldOverrides, LiveChannelAddress, } from '@grafana/data'; -import { TablePanel } from '../table/TablePanel'; -import { LivePanelOptions, MessageDisplayMode } from './types'; import { config, getGrafanaLiveSrv } from '@grafana/runtime'; -import { css, cx } from '@emotion/css'; -import { isEqual } from 'lodash'; +import { Alert, stylesFactory, Button, JSONFormatter, CustomScrollbar, CodeEditor } from '@grafana/ui'; import { StreamingDataFrame } from 'app/features/live/data/StreamingDataFrame'; +import { TablePanel } from '../table/TablePanel'; + +import { LivePanelOptions, MessageDisplayMode } from './types'; + interface Props extends PanelProps {} interface State { diff --git a/public/app/plugins/panel/live/module.tsx b/public/app/plugins/panel/live/module.tsx index 113b126cb14..596083f450c 100755 --- a/public/app/plugins/panel/live/module.tsx +++ b/public/app/plugins/panel/live/module.tsx @@ -1,4 +1,5 @@ import { PanelPlugin } from '@grafana/data'; + import { LiveChannelEditor } from './LiveChannelEditor'; import { LivePanel } from './LivePanel'; import { LivePanelOptions, MessageDisplayMode } from './types'; diff --git a/public/app/plugins/panel/logs/LogsPanel.test.tsx b/public/app/plugins/panel/logs/LogsPanel.test.tsx index 048773a294a..99ad2026a78 100644 --- a/public/app/plugins/panel/logs/LogsPanel.test.tsx +++ b/public/app/plugins/panel/logs/LogsPanel.test.tsx @@ -1,6 +1,8 @@ -import React, { ComponentProps } from 'react'; import { render, screen } from '@testing-library/react'; +import React, { ComponentProps } from 'react'; + import { LoadingState, MutableDataFrame, FieldType, LogsSortOrder } from '@grafana/data'; + import { LogsPanel } from './LogsPanel'; type LogsPanelProps = ComponentProps; diff --git a/public/app/plugins/panel/logs/LogsPanel.tsx b/public/app/plugins/panel/logs/LogsPanel.tsx index 72f742ab929..f71bc05bdeb 100644 --- a/public/app/plugins/panel/logs/LogsPanel.tsx +++ b/public/app/plugins/panel/logs/LogsPanel.tsx @@ -1,6 +1,6 @@ -import React, { useCallback, useMemo, useRef, useLayoutEffect, useState } from 'react'; import { css } from '@emotion/css'; -import { LogRows, CustomScrollbar, LogLabels, useStyles2, usePanelContext } from '@grafana/ui'; +import React, { useCallback, useMemo, useRef, useLayoutEffect, useState } from 'react'; + import { PanelProps, Field, @@ -11,12 +11,15 @@ import { DataHoverClearEvent, DataHoverEvent, } from '@grafana/data'; -import { Options } from './types'; +import { LogRows, CustomScrollbar, LogLabels, useStyles2, usePanelContext } from '@grafana/ui'; import { dataFrameToLogsModel, dedupLogRows } from 'app/core/logs_model'; import { getFieldLinksForExplore } from 'app/features/explore/utils/links'; -import { COMMON_LABELS } from '../../../core/logs_model'; import { PanelDataErrorView } from 'app/features/panel/components/PanelDataErrorView'; +import { COMMON_LABELS } from '../../../core/logs_model'; + +import { Options } from './types'; + interface LogsPanelProps extends PanelProps {} export const LogsPanel: React.FunctionComponent = ({ diff --git a/public/app/plugins/panel/logs/module.tsx b/public/app/plugins/panel/logs/module.tsx index 5681d7394b3..09df585c322 100644 --- a/public/app/plugins/panel/logs/module.tsx +++ b/public/app/plugins/panel/logs/module.tsx @@ -1,7 +1,8 @@ import { PanelPlugin, LogsSortOrder, LogsDedupStrategy, LogsDedupDescription } from '@grafana/data'; -import { Options } from './types'; + import { LogsPanel } from './LogsPanel'; import { LogsPanelSuggestionsSupplier } from './suggestions'; +import { Options } from './types'; export const plugin = new PanelPlugin(LogsPanel) .setPanelOptions((builder) => { diff --git a/public/app/plugins/panel/logs/suggestions.ts b/public/app/plugins/panel/logs/suggestions.ts index 5a0562a4296..6f7daa57c05 100644 --- a/public/app/plugins/panel/logs/suggestions.ts +++ b/public/app/plugins/panel/logs/suggestions.ts @@ -1,5 +1,6 @@ import { VisualizationSuggestionsBuilder, VisualizationSuggestionScore } from '@grafana/data'; import { SuggestionName } from 'app/types/suggestions'; + import { Options } from './types'; export class LogsPanelSuggestionsSupplier { diff --git a/public/app/plugins/panel/news/NewsPanel.tsx b/public/app/plugins/panel/news/NewsPanel.tsx index e75390bb65a..7e3a58ff365 100755 --- a/public/app/plugins/panel/news/NewsPanel.tsx +++ b/public/app/plugins/panel/news/NewsPanel.tsx @@ -1,22 +1,18 @@ -// Libraries -import React, { PureComponent } from 'react'; - -// Utils & Services -import { CustomScrollbar, stylesFactory } from '@grafana/ui'; - -import config from 'app/core/config'; -import { feedToDataFrame } from './utils'; -import { loadFeed } from './feed'; - -// Types -import { PanelProps, DataFrameView, dateTimeFormat, GrafanaTheme2, textUtil } from '@grafana/data'; -import { NewsItem } from './types'; -import { PanelOptions } from './models.gen'; -import { DEFAULT_FEED_URL } from './constants'; import { css, cx } from '@emotion/css'; -import { RefreshEvent } from '@grafana/runtime'; +import React, { PureComponent } from 'react'; import { Unsubscribable } from 'rxjs'; +import { PanelProps, DataFrameView, dateTimeFormat, GrafanaTheme2, textUtil } from '@grafana/data'; +import { RefreshEvent } from '@grafana/runtime'; +import { CustomScrollbar, stylesFactory } from '@grafana/ui'; +import config from 'app/core/config'; + +import { DEFAULT_FEED_URL } from './constants'; +import { loadFeed } from './feed'; +import { PanelOptions } from './models.gen'; +import { NewsItem } from './types'; +import { feedToDataFrame } from './utils'; + interface Props extends PanelProps {} interface State { diff --git a/public/app/plugins/panel/news/atom.test.ts b/public/app/plugins/panel/news/atom.test.ts index 731c597187d..57d5a1a93bc 100644 --- a/public/app/plugins/panel/news/atom.test.ts +++ b/public/app/plugins/panel/news/atom.test.ts @@ -1,6 +1,7 @@ -import { parseAtomFeed } from './atom'; import fs from 'fs'; +import { parseAtomFeed } from './atom'; + describe('Atom feed parser', () => { it('should successfully parse an atom feed', async () => { const atomFile = fs.readFileSync(`${__dirname}/fixtures/atom.xml`, 'utf8'); diff --git a/public/app/plugins/panel/news/module.tsx b/public/app/plugins/panel/news/module.tsx index 382cddb2c7b..13c2448b1ca 100755 --- a/public/app/plugins/panel/news/module.tsx +++ b/public/app/plugins/panel/news/module.tsx @@ -1,7 +1,8 @@ import { PanelPlugin } from '@grafana/data'; + import { NewsPanel } from './NewsPanel'; -import { PanelOptions, defaultPanelOptions } from './models.gen'; import { DEFAULT_FEED_URL } from './constants'; +import { PanelOptions, defaultPanelOptions } from './models.gen'; export const plugin = new PanelPlugin(NewsPanel).setPanelOptions((builder) => { builder diff --git a/public/app/plugins/panel/news/rss.test.ts b/public/app/plugins/panel/news/rss.test.ts index 5c30bcc0e00..d4cbbd80a1a 100644 --- a/public/app/plugins/panel/news/rss.test.ts +++ b/public/app/plugins/panel/news/rss.test.ts @@ -1,6 +1,7 @@ -import { parseRSSFeed } from './rss'; import fs from 'fs'; +import { parseRSSFeed } from './rss'; + describe('RSS feed parser', () => { it('should successfully parse an rss feed', async () => { const rssFile = fs.readFileSync(`${__dirname}/fixtures/rss.xml`, 'utf8'); diff --git a/public/app/plugins/panel/news/utils.test.ts b/public/app/plugins/panel/news/utils.test.ts index fee1cbf2ffb..b0424446c42 100644 --- a/public/app/plugins/panel/news/utils.test.ts +++ b/public/app/plugins/panel/news/utils.test.ts @@ -1,7 +1,8 @@ -import { feedToDataFrame } from './utils'; -import { Feed, NewsItem } from './types'; import { DataFrameView } from '@grafana/data'; +import { Feed, NewsItem } from './types'; +import { feedToDataFrame } from './utils'; + describe('news', () => { test('convert RssFeed to DataFrame', () => { const frame = feedToDataFrame(grafana20191216); diff --git a/public/app/plugins/panel/news/utils.ts b/public/app/plugins/panel/news/utils.ts index 1b737221548..f36d7a48cb1 100644 --- a/public/app/plugins/panel/news/utils.ts +++ b/public/app/plugins/panel/news/utils.ts @@ -1,6 +1,7 @@ -import { Feed } from './types'; import { ArrayVector, FieldType, DataFrame, dateTime } from '@grafana/data'; +import { Feed } from './types'; + export function feedToDataFrame(feed: Feed): DataFrame { const date = new ArrayVector([]); const title = new ArrayVector([]); diff --git a/public/app/plugins/panel/nodeGraph/Edge.tsx b/public/app/plugins/panel/nodeGraph/Edge.tsx index 9e8c3ebd51d..e6b8ced56dc 100644 --- a/public/app/plugins/panel/nodeGraph/Edge.tsx +++ b/public/app/plugins/panel/nodeGraph/Edge.tsx @@ -1,4 +1,5 @@ import React, { MouseEvent, memo } from 'react'; + import { EdgeDatum, NodeDatum } from './types'; import { shortenLine } from './utils'; diff --git a/public/app/plugins/panel/nodeGraph/EdgeLabel.tsx b/public/app/plugins/panel/nodeGraph/EdgeLabel.tsx index e97f56f4754..03cebc01343 100644 --- a/public/app/plugins/panel/nodeGraph/EdgeLabel.tsx +++ b/public/app/plugins/panel/nodeGraph/EdgeLabel.tsx @@ -1,8 +1,10 @@ -import React, { memo } from 'react'; -import { EdgeDatum, NodeDatum } from './types'; import { css } from '@emotion/css'; +import React, { memo } from 'react'; + import { GrafanaTheme2 } from '@grafana/data'; import { useStyles2 } from '@grafana/ui'; + +import { EdgeDatum, NodeDatum } from './types'; import { shortenLine } from './utils'; const getStyles = (theme: GrafanaTheme2) => { diff --git a/public/app/plugins/panel/nodeGraph/Legend.test.tsx b/public/app/plugins/panel/nodeGraph/Legend.test.tsx index 2fe9fddeb94..fb9ac756ee5 100644 --- a/public/app/plugins/panel/nodeGraph/Legend.test.tsx +++ b/public/app/plugins/panel/nodeGraph/Legend.test.tsx @@ -1,6 +1,8 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; +import React from 'react'; + import { FieldColorModeId } from '@grafana/data'; + import { Legend } from './Legend'; import { NodeDatum } from './types'; diff --git a/public/app/plugins/panel/nodeGraph/Legend.tsx b/public/app/plugins/panel/nodeGraph/Legend.tsx index a46a12b51d7..f2f7184b16e 100644 --- a/public/app/plugins/panel/nodeGraph/Legend.tsx +++ b/public/app/plugins/panel/nodeGraph/Legend.tsx @@ -1,12 +1,14 @@ -import React, { useCallback } from 'react'; -import { NodeDatum } from './types'; -import { Field, FieldColorModeId, getColorForTheme, GrafanaTheme } from '@grafana/data'; -import { identity } from 'lodash'; -import { Config } from './layout'; import { css } from '@emotion/css'; +import { identity } from 'lodash'; +import React, { useCallback } from 'react'; + +import { Field, FieldColorModeId, getColorForTheme, GrafanaTheme } from '@grafana/data'; import { LegendDisplayMode } from '@grafana/schema'; import { Icon, useStyles, useTheme, VizLegend, VizLegendItem, VizLegendListItem } from '@grafana/ui'; +import { Config } from './layout'; +import { NodeDatum } from './types'; + function getStyles() { return { item: css` diff --git a/public/app/plugins/panel/nodeGraph/Marker.tsx b/public/app/plugins/panel/nodeGraph/Marker.tsx index 89ef5c9512f..8f73d3912a1 100644 --- a/public/app/plugins/panel/nodeGraph/Marker.tsx +++ b/public/app/plugins/panel/nodeGraph/Marker.tsx @@ -1,9 +1,11 @@ -import React, { MouseEvent, memo } from 'react'; -import { NodesMarker } from './types'; -import { GrafanaTheme } from '@grafana/data'; import { css } from '@emotion/css'; +import React, { MouseEvent, memo } from 'react'; + +import { GrafanaTheme } from '@grafana/data'; import { stylesFactory, useTheme } from '@grafana/ui'; +import { NodesMarker } from './types'; + const nodeR = 40; const getStyles = stylesFactory((theme: GrafanaTheme) => ({ diff --git a/public/app/plugins/panel/nodeGraph/Node.tsx b/public/app/plugins/panel/nodeGraph/Node.tsx index 44772bad586..61aae2373fc 100644 --- a/public/app/plugins/panel/nodeGraph/Node.tsx +++ b/public/app/plugins/panel/nodeGraph/Node.tsx @@ -1,10 +1,12 @@ -import React, { MouseEvent, memo } from 'react'; +import { css } from '@emotion/css'; import cx from 'classnames'; +import React, { MouseEvent, memo } from 'react'; +import tinycolor from 'tinycolor2'; + import { Field, getFieldColorModeForField, GrafanaTheme2 } from '@grafana/data'; import { useStyles2, useTheme2 } from '@grafana/ui'; + import { NodeDatum } from './types'; -import { css } from '@emotion/css'; -import tinycolor from 'tinycolor2'; import { statToString } from './utils'; const nodeR = 40; diff --git a/public/app/plugins/panel/nodeGraph/NodeGraph.test.tsx b/public/app/plugins/panel/nodeGraph/NodeGraph.test.tsx index c693cf8dbd4..55f907a4492 100644 --- a/public/app/plugins/panel/nodeGraph/NodeGraph.test.tsx +++ b/public/app/plugins/panel/nodeGraph/NodeGraph.test.tsx @@ -1,6 +1,7 @@ -import React from 'react'; import { render, screen, fireEvent, waitFor, getByText } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import React from 'react'; + import { NodeGraph } from './NodeGraph'; import { makeEdgesDataFrame, makeNodesDataFrame } from './utils'; diff --git a/public/app/plugins/panel/nodeGraph/NodeGraph.tsx b/public/app/plugins/panel/nodeGraph/NodeGraph.tsx index ad026f468aa..0c851b95a76 100644 --- a/public/app/plugins/panel/nodeGraph/NodeGraph.tsx +++ b/public/app/plugins/panel/nodeGraph/NodeGraph.tsx @@ -1,25 +1,27 @@ -import React, { memo, MouseEvent, MutableRefObject, useCallback, useMemo, useState } from 'react'; -import cx from 'classnames'; -import useMeasure from 'react-use/lib/useMeasure'; -import { Icon, Spinner, useStyles2, useTheme2 } from '@grafana/ui'; -import { usePanning } from './usePanning'; -import { EdgeDatum, NodeDatum, NodesMarker } from './types'; -import { Node } from './Node'; -import { Edge } from './Edge'; -import { ViewControls } from './ViewControls'; -import { DataFrame, GrafanaTheme2, LinkModel } from '@grafana/data'; -import { useZoom } from './useZoom'; -import { Config, defaultConfig, useLayout } from './layout'; -import { EdgeArrowMarker } from './EdgeArrowMarker'; import { css } from '@emotion/css'; -import { useCategorizeFrames } from './useCategorizeFrames'; +import cx from 'classnames'; +import React, { memo, MouseEvent, MutableRefObject, useCallback, useMemo, useState } from 'react'; +import useMeasure from 'react-use/lib/useMeasure'; + +import { DataFrame, GrafanaTheme2, LinkModel } from '@grafana/data'; +import { Icon, Spinner, useStyles2, useTheme2 } from '@grafana/ui'; + +import { Edge } from './Edge'; +import { EdgeArrowMarker } from './EdgeArrowMarker'; import { EdgeLabel } from './EdgeLabel'; -import { useContextMenu } from './useContextMenu'; -import { processNodes, Bounds } from './utils'; -import { Marker } from './Marker'; import { Legend } from './Legend'; -import { useHighlight } from './useHighlight'; +import { Marker } from './Marker'; +import { Node } from './Node'; +import { ViewControls } from './ViewControls'; +import { Config, defaultConfig, useLayout } from './layout'; +import { EdgeDatum, NodeDatum, NodesMarker } from './types'; +import { useCategorizeFrames } from './useCategorizeFrames'; +import { useContextMenu } from './useContextMenu'; import { useFocusPositionOnLayout } from './useFocusPositionOnLayout'; +import { useHighlight } from './useHighlight'; +import { usePanning } from './usePanning'; +import { useZoom } from './useZoom'; +import { processNodes, Bounds } from './utils'; const getStyles = (theme: GrafanaTheme2) => ({ wrapper: css` diff --git a/public/app/plugins/panel/nodeGraph/NodeGraphPanel.tsx b/public/app/plugins/panel/nodeGraph/NodeGraphPanel.tsx index 5e1394a5b2f..d98d0597789 100644 --- a/public/app/plugins/panel/nodeGraph/NodeGraphPanel.tsx +++ b/public/app/plugins/panel/nodeGraph/NodeGraphPanel.tsx @@ -1,11 +1,14 @@ -import React from 'react'; -import { PanelProps } from '@grafana/data'; import memoizeOne from 'memoize-one'; -import { Options } from './types'; -import { NodeGraph } from './NodeGraph'; -import { getNodeGraphDataFrames } from './utils'; +import React from 'react'; + +import { PanelProps } from '@grafana/data'; + import { useLinks } from '../../../features/explore/utils/links'; +import { NodeGraph } from './NodeGraph'; +import { Options } from './types'; +import { getNodeGraphDataFrames } from './utils'; + export const NodeGraphPanel: React.FunctionComponent> = ({ width, height, data }) => { const getLinks = useLinks(data.timeRange); if (!data || !data.series.length) { diff --git a/public/app/plugins/panel/nodeGraph/ViewControls.tsx b/public/app/plugins/panel/nodeGraph/ViewControls.tsx index abcd9484304..1b3a7316014 100644 --- a/public/app/plugins/panel/nodeGraph/ViewControls.tsx +++ b/public/app/plugins/panel/nodeGraph/ViewControls.tsx @@ -1,6 +1,7 @@ -import React, { useState } from 'react'; -import { Button, HorizontalGroup, useStyles, VerticalGroup } from '@grafana/ui'; import { css } from '@emotion/css'; +import React, { useState } from 'react'; + +import { Button, HorizontalGroup, useStyles, VerticalGroup } from '@grafana/ui'; function getStyles() { return { diff --git a/public/app/plugins/panel/nodeGraph/layout.test.ts b/public/app/plugins/panel/nodeGraph/layout.test.ts index 4783832bfad..0c45d4b3a04 100644 --- a/public/app/plugins/panel/nodeGraph/layout.test.ts +++ b/public/app/plugins/panel/nodeGraph/layout.test.ts @@ -1,4 +1,5 @@ import { renderHook } from '@testing-library/react-hooks'; + import { useLayout } from './layout'; import { EdgeDatum, NodeDatum } from './types'; diff --git a/public/app/plugins/panel/nodeGraph/layout.ts b/public/app/plugins/panel/nodeGraph/layout.ts index 688a31b6a1e..30e4b57a6d7 100644 --- a/public/app/plugins/panel/nodeGraph/layout.ts +++ b/public/app/plugins/panel/nodeGraph/layout.ts @@ -1,11 +1,13 @@ import { useEffect, useMemo, useRef, useState } from 'react'; -import { EdgeDatum, EdgeDatumLayout, NodeDatum } from './types'; -import { Field } from '@grafana/data'; -import { useNodeLimit } from './useNodeLimit'; -import useMountedState from 'react-use/lib/useMountedState'; -import { graphBounds } from './utils'; -import { createWorker } from './createLayoutWorker'; import { useUnmount } from 'react-use'; +import useMountedState from 'react-use/lib/useMountedState'; + +import { Field } from '@grafana/data'; + +import { createWorker } from './createLayoutWorker'; +import { EdgeDatum, EdgeDatumLayout, NodeDatum } from './types'; +import { useNodeLimit } from './useNodeLimit'; +import { graphBounds } from './utils'; export interface Config { linkDistance: number; diff --git a/public/app/plugins/panel/nodeGraph/module.tsx b/public/app/plugins/panel/nodeGraph/module.tsx index 60aec529aac..15416636639 100644 --- a/public/app/plugins/panel/nodeGraph/module.tsx +++ b/public/app/plugins/panel/nodeGraph/module.tsx @@ -1,4 +1,5 @@ import { PanelPlugin } from '@grafana/data'; + import { NodeGraphPanel } from './NodeGraphPanel'; import { Options } from './types'; diff --git a/public/app/plugins/panel/nodeGraph/types.ts b/public/app/plugins/panel/nodeGraph/types.ts index 91b4103afee..1c15b9e5688 100644 --- a/public/app/plugins/panel/nodeGraph/types.ts +++ b/public/app/plugins/panel/nodeGraph/types.ts @@ -1,4 +1,5 @@ import { SimulationNodeDatum, SimulationLinkDatum } from 'd3-force'; + import { Field } from '@grafana/data'; export interface Options {} diff --git a/public/app/plugins/panel/nodeGraph/useCategorizeFrames.ts b/public/app/plugins/panel/nodeGraph/useCategorizeFrames.ts index 3e37efd6661..28cf65ca32e 100644 --- a/public/app/plugins/panel/nodeGraph/useCategorizeFrames.ts +++ b/public/app/plugins/panel/nodeGraph/useCategorizeFrames.ts @@ -1,4 +1,5 @@ import { useMemo } from 'react'; + import { DataFrame } from '@grafana/data'; /** diff --git a/public/app/plugins/panel/nodeGraph/useContextMenu.tsx b/public/app/plugins/panel/nodeGraph/useContextMenu.tsx index c3c55b0407b..3df2c7d37ed 100644 --- a/public/app/plugins/panel/nodeGraph/useContextMenu.tsx +++ b/public/app/plugins/panel/nodeGraph/useContextMenu.tsx @@ -1,11 +1,13 @@ -import React, { MouseEvent, useCallback, useState } from 'react'; -import { EdgeDatum, NodeDatum } from './types'; -import { DataFrame, Field, GrafanaTheme, LinkModel } from '@grafana/data'; -import { getEdgeFields, getNodeFields } from './utils'; import { css } from '@emotion/css'; -import { Config } from './layout'; +import React, { MouseEvent, useCallback, useState } from 'react'; + +import { DataFrame, Field, GrafanaTheme, LinkModel } from '@grafana/data'; import { ContextMenu, MenuGroup, MenuItem, stylesFactory, useTheme } from '@grafana/ui'; +import { Config } from './layout'; +import { EdgeDatum, NodeDatum } from './types'; +import { getEdgeFields, getNodeFields } from './utils'; + /** * Hook that contains state of the context menu, both for edges and nodes and provides appropriate component when * opened context menu should be opened. diff --git a/public/app/plugins/panel/nodeGraph/useFocusPositionOnLayout.ts b/public/app/plugins/panel/nodeGraph/useFocusPositionOnLayout.ts index 22da763b92e..807cbe06467 100644 --- a/public/app/plugins/panel/nodeGraph/useFocusPositionOnLayout.ts +++ b/public/app/plugins/panel/nodeGraph/useFocusPositionOnLayout.ts @@ -1,4 +1,5 @@ import usePrevious from 'react-use/lib/usePrevious'; + import { Config } from './layout'; import { NodeDatum } from './types'; diff --git a/public/app/plugins/panel/nodeGraph/useNodeLimit.ts b/public/app/plugins/panel/nodeGraph/useNodeLimit.ts index 6f0cbb07680..ab39b303099 100644 --- a/public/app/plugins/panel/nodeGraph/useNodeLimit.ts +++ b/public/app/plugins/panel/nodeGraph/useNodeLimit.ts @@ -1,7 +1,8 @@ import { fromPairs, uniq } from 'lodash'; import { useMemo } from 'react'; -import { EdgeDatumLayout, NodeDatum, NodesMarker } from './types'; + import { Config } from './layout'; +import { EdgeDatumLayout, NodeDatum, NodesMarker } from './types'; type NodesMap = Record; type EdgesMap = Record; diff --git a/public/app/plugins/panel/nodeGraph/usePanning.ts b/public/app/plugins/panel/nodeGraph/usePanning.ts index e83ff2bdd86..77563e5638d 100644 --- a/public/app/plugins/panel/nodeGraph/usePanning.ts +++ b/public/app/plugins/panel/nodeGraph/usePanning.ts @@ -1,8 +1,9 @@ import { useEffect, useRef, RefObject, useState, useMemo } from 'react'; import useMountedState from 'react-use/lib/useMountedState'; -import { Bounds } from './utils'; import usePrevious from 'react-use/lib/usePrevious'; +import { Bounds } from './utils'; + export interface State { isPanning: boolean; position: { diff --git a/public/app/plugins/panel/nodeGraph/utils.test.ts b/public/app/plugins/panel/nodeGraph/utils.test.ts index d95e4e72fdd..9ca99d86ac5 100644 --- a/public/app/plugins/panel/nodeGraph/utils.test.ts +++ b/public/app/plugins/panel/nodeGraph/utils.test.ts @@ -1,4 +1,5 @@ import { ArrayVector, createTheme, DataFrame, FieldType, MutableDataFrame } from '@grafana/data'; + import { getEdgeFields, getNodeFields, diff --git a/public/app/plugins/panel/nodeGraph/utils.ts b/public/app/plugins/panel/nodeGraph/utils.ts index 0aac55cedf8..2de6eb997ef 100644 --- a/public/app/plugins/panel/nodeGraph/utils.ts +++ b/public/app/plugins/panel/nodeGraph/utils.ts @@ -8,6 +8,7 @@ import { MutableDataFrame, NodeGraphDataFrameFieldNames, } from '@grafana/data'; + import { EdgeDatum, NodeDatum } from './types'; type Line = { x1: number; y1: number; x2: number; y2: number }; diff --git a/public/app/plugins/panel/piechart/PieChart.tsx b/public/app/plugins/panel/piechart/PieChart.tsx index f264034a7bd..70c2adeb175 100644 --- a/public/app/plugins/panel/piechart/PieChart.tsx +++ b/public/app/plugins/panel/piechart/PieChart.tsx @@ -1,5 +1,13 @@ +import { css } from '@emotion/css'; +import { localPoint } from '@visx/event'; +import { RadialGradient } from '@visx/gradient'; +import { Group } from '@visx/group'; +import Pie, { PieArcDatum, ProvidedProps } from '@visx/shape/lib/shapes/Pie'; +import { useTooltip, useTooltipInPortal } from '@visx/tooltip'; +import { UseTooltipParams } from '@visx/tooltip/lib/hooks/useTooltip'; import React, { FC, useCallback } from 'react'; -import { VizTooltipOptions } from '@grafana/schema'; +import tinycolor from 'tinycolor2'; + import { FieldDisplay, FALLBACK_COLOR, @@ -8,6 +16,8 @@ import { DataHoverClearEvent, DataHoverEvent, } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; +import { VizTooltipOptions } from '@grafana/schema'; import { useTheme2, useStyles2, @@ -16,19 +26,10 @@ import { SeriesTable, usePanelContext, } from '@grafana/ui'; -import { PieChartType, PieChartLabels } from './types'; -import { useTooltip, useTooltipInPortal } from '@visx/tooltip'; -import Pie, { PieArcDatum, ProvidedProps } from '@visx/shape/lib/shapes/Pie'; -import { UseTooltipParams } from '@visx/tooltip/lib/hooks/useTooltip'; -import { RadialGradient } from '@visx/gradient'; -import { localPoint } from '@visx/event'; -import { Group } from '@visx/group'; -import tinycolor from 'tinycolor2'; -import { css } from '@emotion/css'; - -import { useComponentInstanceId } from '@grafana/ui/src/utils/useComponetInstanceId'; import { getTooltipContainerStyles } from '@grafana/ui/src/themes/mixins'; -import { selectors } from '@grafana/e2e-selectors'; +import { useComponentInstanceId } from '@grafana/ui/src/utils/useComponetInstanceId'; + +import { PieChartType, PieChartLabels } from './types'; import { filterDisplayItems, sumDisplayItemsReducer } from './utils'; /** diff --git a/public/app/plugins/panel/piechart/PieChartPanel.tsx b/public/app/plugins/panel/piechart/PieChartPanel.tsx index d8eeeb59efd..c5dbd94bf75 100644 --- a/public/app/plugins/panel/piechart/PieChartPanel.tsx +++ b/public/app/plugins/panel/piechart/PieChartPanel.tsx @@ -1,5 +1,6 @@ import React, { useEffect, useState } from 'react'; -import { LegendDisplayMode } from '@grafana/schema'; +import { Subscription } from 'rxjs'; + import { DataHoverClearEvent, DataHoverEvent, @@ -9,11 +10,8 @@ import { getFieldDisplayValues, PanelProps, } from '@grafana/data'; - -import { PieChart } from './PieChart'; - -import { PieChartLegendOptions, PieChartLegendValues, PieChartOptions } from './types'; -import { Subscription } from 'rxjs'; +import { PanelDataErrorView } from '@grafana/runtime'; +import { LegendDisplayMode } from '@grafana/schema'; import { SeriesVisibilityChangeBehavior, usePanelContext, @@ -22,8 +20,10 @@ import { VizLegend, VizLegendItem, } from '@grafana/ui'; + +import { PieChart } from './PieChart'; +import { PieChartLegendOptions, PieChartLegendValues, PieChartOptions } from './types'; import { filterDisplayItems, sumDisplayItemsReducer } from './utils'; -import { PanelDataErrorView } from '@grafana/runtime'; const defaultLegendOptions: PieChartLegendOptions = { displayMode: LegendDisplayMode.List, diff --git a/public/app/plugins/panel/piechart/migrations.test.ts b/public/app/plugins/panel/piechart/migrations.test.ts index 1d63e0b4555..b11c492658d 100644 --- a/public/app/plugins/panel/piechart/migrations.test.ts +++ b/public/app/plugins/panel/piechart/migrations.test.ts @@ -1,5 +1,6 @@ import { FieldColorModeId, FieldConfigProperty, FieldMatcherID, PanelModel } from '@grafana/data'; import { LegendDisplayMode } from '@grafana/schema'; + import { PieChartPanelChangedHandler } from './migrations'; import { PieChartLabels } from './types'; diff --git a/public/app/plugins/panel/piechart/migrations.ts b/public/app/plugins/panel/piechart/migrations.ts index 1d12c83b6a1..fa42a9cb766 100644 --- a/public/app/plugins/panel/piechart/migrations.ts +++ b/public/app/plugins/panel/piechart/migrations.ts @@ -1,5 +1,6 @@ import { FieldColorModeId, FieldConfigProperty, FieldMatcherID, PanelModel } from '@grafana/data'; import { LegendDisplayMode } from '@grafana/schema'; + import { PieChartOptions, PieChartLabels, PieChartLegendValues, PieChartType } from './types'; export const PieChartPanelChangedHandler = ( diff --git a/public/app/plugins/panel/piechart/module.tsx b/public/app/plugins/panel/piechart/module.tsx index 57c1ec8d209..ccb0ae7f892 100644 --- a/public/app/plugins/panel/piechart/module.tsx +++ b/public/app/plugins/panel/piechart/module.tsx @@ -1,11 +1,13 @@ import { FieldColorModeId, FieldConfigProperty, PanelPlugin } from '@grafana/data'; -import { PieChartPanel } from './PieChartPanel'; -import { PieChartOptions, PieChartType, PieChartLabels, PieChartLegendValues } from './types'; import { LegendDisplayMode } from '@grafana/schema'; import { commonOptionsBuilder } from '@grafana/ui'; -import { PieChartPanelChangedHandler } from './migrations'; + import { addStandardDataReduceOptions } from '../stat/types'; + +import { PieChartPanel } from './PieChartPanel'; +import { PieChartPanelChangedHandler } from './migrations'; import { PieChartSuggestionsSupplier } from './suggestions'; +import { PieChartOptions, PieChartType, PieChartLabels, PieChartLegendValues } from './types'; export const plugin = new PanelPlugin(PieChartPanel) .setPanelChangeHandler(PieChartPanelChangedHandler) diff --git a/public/app/plugins/panel/piechart/suggestions.ts b/public/app/plugins/panel/piechart/suggestions.ts index aa3f0b055cc..4eae227cd4e 100644 --- a/public/app/plugins/panel/piechart/suggestions.ts +++ b/public/app/plugins/panel/piechart/suggestions.ts @@ -1,6 +1,7 @@ import { VisualizationSuggestionsBuilder } from '@grafana/data'; import { LegendDisplayMode } from '@grafana/schema'; import { SuggestionName } from 'app/types/suggestions'; + import { PieChartLabels, PieChartOptions, PieChartType } from './types'; export class PieChartSuggestionsSupplier { diff --git a/public/app/plugins/panel/stat/StatMigrations.test.ts b/public/app/plugins/panel/stat/StatMigrations.test.ts index 46b5ce23a18..df6f173e1eb 100644 --- a/public/app/plugins/panel/stat/StatMigrations.test.ts +++ b/public/app/plugins/panel/stat/StatMigrations.test.ts @@ -1,8 +1,9 @@ import { PanelModel } from '@grafana/data'; -import { statPanelChangedHandler } from './StatMigrations'; import { BigValueGraphMode, BigValueColorMode } from '@grafana/ui'; import { BigValueTextMode } from '@grafana/ui/src/components/BigValue/BigValue'; +import { statPanelChangedHandler } from './StatMigrations'; + describe('Stat Panel Migrations', () => { it('change from angular singlestat sparkline disabled', () => { const old: any = { diff --git a/public/app/plugins/panel/stat/StatMigrations.ts b/public/app/plugins/panel/stat/StatMigrations.ts index f7f7bfb49b6..69415e97c65 100644 --- a/public/app/plugins/panel/stat/StatMigrations.ts +++ b/public/app/plugins/panel/stat/StatMigrations.ts @@ -1,8 +1,9 @@ -import { sharedSingleStatPanelChangedHandler, BigValueGraphMode, BigValueColorMode } from '@grafana/ui'; import { FieldColorModeId, FieldConfigSource, PanelModel } from '@grafana/data'; -import { StatPanelOptions } from './types'; +import { sharedSingleStatPanelChangedHandler, BigValueGraphMode, BigValueColorMode } from '@grafana/ui'; import { BigValueTextMode } from '@grafana/ui/src/components/BigValue/BigValue'; +import { StatPanelOptions } from './types'; + // This is called when the panel changes from another panel export const statPanelChangedHandler = ( panel: PanelModel> | any, diff --git a/public/app/plugins/panel/stat/StatPanel.tsx b/public/app/plugins/panel/stat/StatPanel.tsx index 13a62627b47..8515457b970 100644 --- a/public/app/plugins/panel/stat/StatPanel.tsx +++ b/public/app/plugins/panel/stat/StatPanel.tsx @@ -1,12 +1,6 @@ +import { isNumber } from 'lodash'; import React, { PureComponent } from 'react'; -import { - BigValue, - BigValueGraphMode, - DataLinksContextMenu, - VizRepeater, - VizRepeaterRenderValueProps, - BigValueTextMode, -} from '@grafana/ui'; + import { DisplayValueAlignmentFactors, FieldDisplay, @@ -16,12 +10,19 @@ import { NumericRange, PanelProps, } from '@grafana/data'; - -import { config } from 'app/core/config'; -import { StatPanelOptions } from './types'; -import { DataLinksContextMenuApi } from '@grafana/ui/src/components/DataLinks/DataLinksContextMenu'; import { findNumericFieldMinMax } from '@grafana/data/src/field/fieldOverrides'; -import { isNumber } from 'lodash'; +import { + BigValue, + BigValueGraphMode, + DataLinksContextMenu, + VizRepeater, + VizRepeaterRenderValueProps, + BigValueTextMode, +} from '@grafana/ui'; +import { DataLinksContextMenuApi } from '@grafana/ui/src/components/DataLinks/DataLinksContextMenu'; +import { config } from 'app/core/config'; + +import { StatPanelOptions } from './types'; export class StatPanel extends PureComponent> { renderComponent = ( diff --git a/public/app/plugins/panel/stat/module.tsx b/public/app/plugins/panel/stat/module.tsx index 411a5607ee4..8b4cfd2a7ed 100644 --- a/public/app/plugins/panel/stat/module.tsx +++ b/public/app/plugins/panel/stat/module.tsx @@ -1,14 +1,15 @@ +import { PanelPlugin } from '@grafana/data'; import { BigValueColorMode, BigValueTextMode, commonOptionsBuilder, sharedSingleStatMigrationHandler, } from '@grafana/ui'; -import { PanelPlugin } from '@grafana/data'; -import { addOrientationOption, addStandardDataReduceOptions, StatPanelOptions } from './types'; -import { StatPanel } from './StatPanel'; + import { statPanelChangedHandler } from './StatMigrations'; +import { StatPanel } from './StatPanel'; import { StatSuggestionsSupplier } from './suggestions'; +import { addOrientationOption, addStandardDataReduceOptions, StatPanelOptions } from './types'; export const plugin = new PanelPlugin(StatPanel) .useFieldConfig() diff --git a/public/app/plugins/panel/stat/suggestions.ts b/public/app/plugins/panel/stat/suggestions.ts index b94620205d4..60346f9b456 100644 --- a/public/app/plugins/panel/stat/suggestions.ts +++ b/public/app/plugins/panel/stat/suggestions.ts @@ -1,6 +1,7 @@ import { VisualizationSuggestionsBuilder } from '@grafana/data'; import { BigValueColorMode, BigValueGraphMode } from '@grafana/ui'; import { SuggestionName } from 'app/types/suggestions'; + import { StatPanelOptions } from './types'; export class StatSuggestionsSupplier { diff --git a/public/app/plugins/panel/stat/types.ts b/public/app/plugins/panel/stat/types.ts index b43c6248609..049d778af8e 100644 --- a/public/app/plugins/panel/stat/types.ts +++ b/public/app/plugins/panel/stat/types.ts @@ -1,10 +1,3 @@ -import { - SingleStatBaseOptions, - BigValueColorMode, - BigValueGraphMode, - BigValueJustifyMode, - BigValueTextMode, -} from '@grafana/ui'; import { ReducerID, standardEditorsRegistry, @@ -14,6 +7,13 @@ import { VizOrientation, PanelOptionsEditorBuilder, } from '@grafana/data'; +import { + SingleStatBaseOptions, + BigValueColorMode, + BigValueGraphMode, + BigValueJustifyMode, + BigValueTextMode, +} from '@grafana/ui'; // Structure copied from angular export interface StatPanelOptions extends SingleStatBaseOptions { diff --git a/public/app/plugins/panel/state-timeline/StateTimelinePanel.tsx b/public/app/plugins/panel/state-timeline/StateTimelinePanel.tsx index eab594d6d89..54d5ea2f0b0 100755 --- a/public/app/plugins/panel/state-timeline/StateTimelinePanel.tsx +++ b/public/app/plugins/panel/state-timeline/StateTimelinePanel.tsx @@ -1,13 +1,16 @@ import React, { useCallback, useMemo } from 'react'; + import { DataFrame, FieldType, PanelProps } from '@grafana/data'; import { TooltipPlugin, useTheme2, ZoomPlugin, usePanelContext } from '@grafana/ui'; -import { TimelineMode, TimelineOptions } from './types'; -import { TimelineChart } from './TimelineChart'; -import { prepareTimelineFields, prepareTimelineLegendItems } from './utils'; -import { StateTimelineTooltip } from './StateTimelineTooltip'; import { getLastStreamingDataFramePacket } from 'app/features/live/data/StreamingDataFrame'; + import { OutsideRangePlugin } from '../timeseries/plugins/OutsideRangePlugin'; +import { StateTimelineTooltip } from './StateTimelineTooltip'; +import { TimelineChart } from './TimelineChart'; +import { TimelineMode, TimelineOptions } from './types'; +import { prepareTimelineFields, prepareTimelineLegendItems } from './utils'; + interface TimelinePanelProps extends PanelProps {} /** diff --git a/public/app/plugins/panel/state-timeline/StateTimelineTooltip.tsx b/public/app/plugins/panel/state-timeline/StateTimelineTooltip.tsx index c846ab5235a..b09926cdb73 100644 --- a/public/app/plugins/panel/state-timeline/StateTimelineTooltip.tsx +++ b/public/app/plugins/panel/state-timeline/StateTimelineTooltip.tsx @@ -1,6 +1,8 @@ import React from 'react'; + import { DataFrame, FALLBACK_COLOR, getDisplayProcessor, getFieldDisplayName, TimeZone } from '@grafana/data'; import { SeriesTableRow, useTheme2 } from '@grafana/ui'; + import { findNextStateIndex, fmtDuration } from './utils'; interface StateTimelineTooltipProps { diff --git a/public/app/plugins/panel/state-timeline/TimelineChart.tsx b/public/app/plugins/panel/state-timeline/TimelineChart.tsx index 72ee7e27640..3d13fc495cf 100755 --- a/public/app/plugins/panel/state-timeline/TimelineChart.tsx +++ b/public/app/plugins/panel/state-timeline/TimelineChart.tsx @@ -1,4 +1,6 @@ import React from 'react'; + +import { DataFrame, FALLBACK_COLOR, FieldType, TimeRange } from '@grafana/data'; import { LegendDisplayMode, VisibilityMode } from '@grafana/schema'; import { PanelContext, @@ -10,9 +12,9 @@ import { VizLegend, VizLegendItem, } from '@grafana/ui'; -import { DataFrame, FALLBACK_COLOR, FieldType, TimeRange } from '@grafana/data'; -import { preparePlotConfigBuilder } from './utils'; + import { TimelineMode, TimelineOptions, TimelineValueAlignment } from './types'; +import { preparePlotConfigBuilder } from './utils'; /** * @alpha diff --git a/public/app/plugins/panel/state-timeline/migrations.test.ts b/public/app/plugins/panel/state-timeline/migrations.test.ts index e93d6aa067b..f849be085c0 100644 --- a/public/app/plugins/panel/state-timeline/migrations.test.ts +++ b/public/app/plugins/panel/state-timeline/migrations.test.ts @@ -1,4 +1,5 @@ import { PanelModel } from 'app/features/dashboard/state'; + import { timelinePanelChangedHandler } from './migrations'; describe('Timeline Migrations', () => { diff --git a/public/app/plugins/panel/state-timeline/migrations.ts b/public/app/plugins/panel/state-timeline/migrations.ts index 83a3f1ef46f..35707074624 100644 --- a/public/app/plugins/panel/state-timeline/migrations.ts +++ b/public/app/plugins/panel/state-timeline/migrations.ts @@ -1,7 +1,9 @@ -import { FieldConfigSource, MappingType, PanelModel, ValueMap } from '@grafana/data'; -import { TimelineFieldConfig, TimelineOptions } from './types'; import { isArray } from 'lodash'; +import { FieldConfigSource, MappingType, PanelModel, ValueMap } from '@grafana/data'; + +import { TimelineFieldConfig, TimelineOptions } from './types'; + // This is called when the panel changes from another panel export const timelinePanelChangedHandler = ( panel: PanelModel> | any, diff --git a/public/app/plugins/panel/state-timeline/module.tsx b/public/app/plugins/panel/state-timeline/module.tsx index 2aed7c0165b..b807fb42f4a 100755 --- a/public/app/plugins/panel/state-timeline/module.tsx +++ b/public/app/plugins/panel/state-timeline/module.tsx @@ -5,13 +5,15 @@ import { identityOverrideProcessor, PanelPlugin, } from '@grafana/data'; -import { StateTimelinePanel } from './StateTimelinePanel'; -import { TimelineOptions, TimelineFieldConfig, defaultPanelOptions, defaultTimelineFieldConfig } from './types'; import { VisibilityMode } from '@grafana/schema'; import { commonOptionsBuilder } from '@grafana/ui'; + +import { SpanNullsEditor } from '../timeseries/SpanNullsEditor'; + +import { StateTimelinePanel } from './StateTimelinePanel'; import { timelinePanelChangedHandler } from './migrations'; import { StatTimelineSuggestionsSupplier } from './suggestions'; -import { SpanNullsEditor } from '../timeseries/SpanNullsEditor'; +import { TimelineOptions, TimelineFieldConfig, defaultPanelOptions, defaultTimelineFieldConfig } from './types'; export const plugin = new PanelPlugin(StateTimelinePanel) .setPanelChangeHandler(timelinePanelChangedHandler) diff --git a/public/app/plugins/panel/state-timeline/suggestions.ts b/public/app/plugins/panel/state-timeline/suggestions.ts index 1fe768bf381..31ec82210a2 100644 --- a/public/app/plugins/panel/state-timeline/suggestions.ts +++ b/public/app/plugins/panel/state-timeline/suggestions.ts @@ -1,5 +1,6 @@ import { VisualizationSuggestionsBuilder } from '@grafana/data'; import { SuggestionName } from 'app/types/suggestions'; + import { TimelineFieldConfig, TimelineOptions } from './types'; export class StatTimelineSuggestionsSupplier { diff --git a/public/app/plugins/panel/state-timeline/timeline.ts b/public/app/plugins/panel/state-timeline/timeline.ts index d81d2384db8..317b2540340 100644 --- a/public/app/plugins/panel/state-timeline/timeline.ts +++ b/public/app/plugins/panel/state-timeline/timeline.ts @@ -1,11 +1,13 @@ import uPlot, { Cursor, Series } from 'uplot'; -import { FIXED_UNIT } from '@grafana/ui/src/components/GraphNG/GraphNG'; -import { pointWithin, Quadtree, Rect } from 'app/plugins/panel/barchart/quadtree'; -import { distribute, SPACE_BETWEEN } from 'app/plugins/panel/barchart/distribute'; -import { TimelineFieldConfig, TimelineMode, TimelineValueAlignment } from './types'; + import { GrafanaTheme2, TimeRange } from '@grafana/data'; -import { VisibilityMode } from '@grafana/schema'; import { alpha } from '@grafana/data/src/themes/colorManipulator'; +import { VisibilityMode } from '@grafana/schema'; +import { FIXED_UNIT } from '@grafana/ui/src/components/GraphNG/GraphNG'; +import { distribute, SPACE_BETWEEN } from 'app/plugins/panel/barchart/distribute'; +import { pointWithin, Quadtree, Rect } from 'app/plugins/panel/barchart/quadtree'; + +import { TimelineFieldConfig, TimelineMode, TimelineValueAlignment } from './types'; const { round, min, ceil } = Math; diff --git a/public/app/plugins/panel/state-timeline/utils.test.ts b/public/app/plugins/panel/state-timeline/utils.test.ts index 0382bf21bd0..19dc9f188bf 100644 --- a/public/app/plugins/panel/state-timeline/utils.test.ts +++ b/public/app/plugins/panel/state-timeline/utils.test.ts @@ -1,5 +1,6 @@ import { ArrayVector, createTheme, FieldType, ThresholdsMode, toDataFrame } from '@grafana/data'; import { LegendDisplayMode } from '@grafana/schema'; + import { findNextStateIndex, fmtDuration, diff --git a/public/app/plugins/panel/state-timeline/utils.ts b/public/app/plugins/panel/state-timeline/utils.ts index e84b6a87fbb..9d0e7e44625 100644 --- a/public/app/plugins/panel/state-timeline/utils.ts +++ b/public/app/plugins/panel/state-timeline/utils.ts @@ -1,4 +1,6 @@ import React from 'react'; +import uPlot from 'uplot'; + import { ArrayVector, DataFrame, @@ -20,6 +22,7 @@ import { getFieldConfigWithMinMax, ThresholdsMode, } from '@grafana/data'; +import { VizLegendOptions, AxisPlacement, ScaleDirection, ScaleOrientation } from '@grafana/schema'; import { FIXED_UNIT, SeriesVisibilityChangeMode, @@ -27,12 +30,12 @@ import { UPlotConfigPrepFn, VizLegendItem, } from '@grafana/ui'; -import { getConfig, TimelineCoreOptions } from './timeline'; -import { VizLegendOptions, AxisPlacement, ScaleDirection, ScaleOrientation } from '@grafana/schema'; -import { TimelineFieldConfig, TimelineOptions } from './types'; import { PlotTooltipInterpolator } from '@grafana/ui/src/components/uPlot/types'; + import { preparePlotData2, getStackingGroups } from '../../../../../packages/grafana-ui/src/components/uPlot/utils'; -import uPlot from 'uplot'; + +import { getConfig, TimelineCoreOptions } from './timeline'; +import { TimelineFieldConfig, TimelineOptions } from './types'; const defaultConfig: TimelineFieldConfig = { lineWidth: 0, diff --git a/public/app/plugins/panel/status-history/StatusHistoryPanel.tsx b/public/app/plugins/panel/status-history/StatusHistoryPanel.tsx index 4c62207981e..3cfea9dc0cb 100755 --- a/public/app/plugins/panel/status-history/StatusHistoryPanel.tsx +++ b/public/app/plugins/panel/status-history/StatusHistoryPanel.tsx @@ -1,12 +1,15 @@ import React, { useMemo } from 'react'; + import { PanelProps } from '@grafana/data'; import { TooltipPlugin, useTheme2, ZoomPlugin } from '@grafana/ui'; -import { StatusPanelOptions } from './types'; + import { TimelineChart } from '../state-timeline/TimelineChart'; import { TimelineMode } from '../state-timeline/types'; import { prepareTimelineFields, prepareTimelineLegendItems } from '../state-timeline/utils'; import { OutsideRangePlugin } from '../timeseries/plugins/OutsideRangePlugin'; +import { StatusPanelOptions } from './types'; + interface TimelinePanelProps extends PanelProps {} /** diff --git a/public/app/plugins/panel/status-history/module.tsx b/public/app/plugins/panel/status-history/module.tsx index 65be04c368b..1f961295ce6 100755 --- a/public/app/plugins/panel/status-history/module.tsx +++ b/public/app/plugins/panel/status-history/module.tsx @@ -1,9 +1,10 @@ import { FieldColorModeId, FieldConfigProperty, PanelPlugin } from '@grafana/data'; -import { StatusHistoryPanel } from './StatusHistoryPanel'; -import { StatusPanelOptions, StatusFieldConfig, defaultStatusFieldConfig } from './types'; import { VisibilityMode } from '@grafana/schema'; import { commonOptionsBuilder } from '@grafana/ui'; + +import { StatusHistoryPanel } from './StatusHistoryPanel'; import { StatusHistorySuggestionsSupplier } from './suggestions'; +import { StatusPanelOptions, StatusFieldConfig, defaultStatusFieldConfig } from './types'; export const plugin = new PanelPlugin(StatusHistoryPanel) .useFieldConfig({ diff --git a/public/app/plugins/panel/status-history/suggestions.ts b/public/app/plugins/panel/status-history/suggestions.ts index cac89f49d8c..37745263c81 100644 --- a/public/app/plugins/panel/status-history/suggestions.ts +++ b/public/app/plugins/panel/status-history/suggestions.ts @@ -1,5 +1,6 @@ import { FieldColorModeId, VisualizationSuggestionsBuilder } from '@grafana/data'; import { SuggestionName } from 'app/types/suggestions'; + import { StatusPanelOptions, StatusFieldConfig } from './types'; export class StatusHistorySuggestionsSupplier { diff --git a/public/app/plugins/panel/table-old/column_options.ts b/public/app/plugins/panel/table-old/column_options.ts index b196e85a9fd..c3543167e1c 100644 --- a/public/app/plugins/panel/table-old/column_options.ts +++ b/public/app/plugins/panel/table-old/column_options.ts @@ -1,4 +1,5 @@ import { map, without } from 'lodash'; + import { getValueFormats } from '@grafana/data'; export class ColumnOptionsCtrl { diff --git a/public/app/plugins/panel/table-old/editor.ts b/public/app/plugins/panel/table-old/editor.ts index 15a60dc32fa..858de542fb3 100644 --- a/public/app/plugins/panel/table-old/editor.ts +++ b/public/app/plugins/panel/table-old/editor.ts @@ -1,4 +1,5 @@ import { find, map, without } from 'lodash'; + import { transformers } from './transformers'; import { ColumnStyle } from './types'; diff --git a/public/app/plugins/panel/table-old/module.ts b/public/app/plugins/panel/table-old/module.ts index 854ba22dd1e..548a828f87d 100644 --- a/public/app/plugins/panel/table-old/module.ts +++ b/public/app/plugins/panel/table-old/module.ts @@ -1,15 +1,17 @@ -import { defaults } from 'lodash'; import $ from 'jquery'; -import { MetricsPanelCtrl } from 'app/plugins/sdk'; -import config from 'app/core/config'; -import { transformDataToTable } from './transformers'; -import { tablePanelEditor } from './editor'; -import { columnOptionsTab } from './column_options'; -import { TableRenderer } from './renderer'; -import { isTableData, PanelEvents, PanelPlugin, PanelProps } from '@grafana/data'; -import { dispatch } from 'app/store/store'; +import { defaults } from 'lodash'; import { ComponentType } from 'react'; + +import { isTableData, PanelEvents, PanelPlugin, PanelProps } from '@grafana/data'; +import config from 'app/core/config'; import { applyFilterFromTable } from 'app/features/variables/adhoc/actions'; +import { MetricsPanelCtrl } from 'app/plugins/sdk'; +import { dispatch } from 'app/store/store'; + +import { columnOptionsTab } from './column_options'; +import { tablePanelEditor } from './editor'; +import { TableRenderer } from './renderer'; +import { transformDataToTable } from './transformers'; export class TablePanelCtrl extends MetricsPanelCtrl { static templateUrl = 'module.html'; diff --git a/public/app/plugins/panel/table-old/renderer.ts b/public/app/plugins/panel/table-old/renderer.ts index 43b0520617f..550ad34adc9 100644 --- a/public/app/plugins/panel/table-old/renderer.ts +++ b/public/app/plugins/panel/table-old/renderer.ts @@ -1,4 +1,5 @@ import { find, first, isArray, isString, escape } from 'lodash'; + import { escapeStringForRegex, formattedValueToString, @@ -15,8 +16,9 @@ import { GrafanaTheme, } from '@grafana/data'; import { getTemplateSrv, TemplateSrv } from '@grafana/runtime'; -import { ColumnRender, TableRenderModel, ColumnStyle } from './types'; + import { ColumnOptionsCtrl } from './column_options'; +import { ColumnRender, TableRenderModel, ColumnStyle } from './types'; export class TableRenderer { formatters: any[] = []; diff --git a/public/app/plugins/panel/table-old/specs/renderer.test.ts b/public/app/plugins/panel/table-old/specs/renderer.test.ts index 25c99781f91..0b9120e037f 100644 --- a/public/app/plugins/panel/table-old/specs/renderer.test.ts +++ b/public/app/plugins/panel/table-old/specs/renderer.test.ts @@ -1,9 +1,11 @@ import { each } from 'lodash'; -import TableModel from 'app/core/table_model'; -import { TableRenderer } from '../renderer'; + import { ScopedVars, TimeZone } from '@grafana/data'; -import { ColumnRender } from '../types'; import { getTheme } from '@grafana/ui'; +import TableModel from 'app/core/table_model'; + +import { TableRenderer } from '../renderer'; +import { ColumnRender } from '../types'; const utc: TimeZone = 'utc'; diff --git a/public/app/plugins/panel/table-old/transformers.ts b/public/app/plugins/panel/table-old/transformers.ts index b3b1c987613..c4b50796c4e 100644 --- a/public/app/plugins/panel/table-old/transformers.ts +++ b/public/app/plugins/panel/table-old/transformers.ts @@ -1,9 +1,11 @@ import { findIndex, isObject, map } from 'lodash'; -import flatten from 'app/core/utils/flatten'; -import TimeSeries from 'app/core/time_series2'; -import TableModel, { mergeTablesIntoModel } from 'app/core/table_model'; -import { TableTransform } from './types'; + import { Column, TableData } from '@grafana/data'; +import TableModel, { mergeTablesIntoModel } from 'app/core/table_model'; +import TimeSeries from 'app/core/time_series2'; +import flatten from 'app/core/utils/flatten'; + +import { TableTransform } from './types'; const transformers: { [key: string]: TableTransform } = {}; export const timeSeriesFormatFilterer = (data: any): any[] => { diff --git a/public/app/plugins/panel/table-old/types.ts b/public/app/plugins/panel/table-old/types.ts index 21c49166de0..a98f04d5837 100644 --- a/public/app/plugins/panel/table-old/types.ts +++ b/public/app/plugins/panel/table-old/types.ts @@ -1,5 +1,5 @@ -import TableModel from 'app/core/table_model'; import { Column } from '@grafana/data'; +import TableModel from 'app/core/table_model'; export interface TableTransform { description: string; diff --git a/public/app/plugins/panel/table/PaginationEditor.tsx b/public/app/plugins/panel/table/PaginationEditor.tsx index 241d3137de1..5d25249d845 100644 --- a/public/app/plugins/panel/table/PaginationEditor.tsx +++ b/public/app/plugins/panel/table/PaginationEditor.tsx @@ -1,6 +1,7 @@ +import React from 'react'; + import { StandardEditorProps } from '@grafana/data'; import { Switch } from '@grafana/ui'; -import React from 'react'; export function PaginationEditor({ onChange, value, context }: StandardEditorProps) { const changeValue = (event: React.FormEvent | undefined) => { diff --git a/public/app/plugins/panel/table/TablePanel.tsx b/public/app/plugins/panel/table/TablePanel.tsx index a55e7e21e2e..d5e16979514 100644 --- a/public/app/plugins/panel/table/TablePanel.tsx +++ b/public/app/plugins/panel/table/TablePanel.tsx @@ -1,5 +1,6 @@ +import { css } from '@emotion/css'; import React, { Component } from 'react'; -import { Select, Table } from '@grafana/ui'; + import { DataFrame, FieldMatcherID, @@ -8,16 +9,18 @@ import { PanelProps, SelectableValue, } from '@grafana/data'; -import { PanelOptions } from './models.gen'; -import { css } from '@emotion/css'; -import { config } from 'app/core/config'; -import { FilterItem, TableSortByFieldState } from '@grafana/ui/src/components/Table/types'; -import { dispatch } from '../../../store/store'; -import { applyFilterFromTable } from '../../../features/variables/adhoc/actions'; -import { getDashboardSrv } from '../../../features/dashboard/services/DashboardSrv'; -import { getFooterCells } from './footer'; -import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; import { PanelDataErrorView } from '@grafana/runtime'; +import { Select, Table } from '@grafana/ui'; +import { FilterItem, TableSortByFieldState } from '@grafana/ui/src/components/Table/types'; +import { config } from 'app/core/config'; +import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; + +import { getDashboardSrv } from '../../../features/dashboard/services/DashboardSrv'; +import { applyFilterFromTable } from '../../../features/variables/adhoc/actions'; +import { dispatch } from '../../../store/store'; + +import { getFooterCells } from './footer'; +import { PanelOptions } from './models.gen'; interface Props extends PanelProps {} diff --git a/public/app/plugins/panel/table/footer.ts b/public/app/plugins/panel/table/footer.ts index 3611cbbd371..0ac8fa5c80d 100644 --- a/public/app/plugins/panel/table/footer.ts +++ b/public/app/plugins/panel/table/footer.ts @@ -8,9 +8,10 @@ import { fieldReducers, } from '@grafana/data'; import { FooterItem } from '@grafana/ui/src/components/Table/types'; -import { TableFooterCalc } from './models.gen'; import { config } from 'app/core/config'; +import { TableFooterCalc } from './models.gen'; + export function getFooterCells(frame: DataFrame, options?: TableFooterCalc): FooterItem[] { return frame.fields.map((field, i) => { if (field.type !== FieldType.number) { diff --git a/public/app/plugins/panel/table/migrations.test.ts b/public/app/plugins/panel/table/migrations.test.ts index 2f767d0f95d..587d7907a7b 100644 --- a/public/app/plugins/panel/table/migrations.test.ts +++ b/public/app/plugins/panel/table/migrations.test.ts @@ -1,4 +1,5 @@ import { PanelModel } from '@grafana/data'; + import { tablePanelChangedHandler } from './migrations'; describe('Table Migrations', () => { diff --git a/public/app/plugins/panel/table/migrations.ts b/public/app/plugins/panel/table/migrations.ts index fc461d66ed2..5b30adf3dc7 100644 --- a/public/app/plugins/panel/table/migrations.ts +++ b/public/app/plugins/panel/table/migrations.ts @@ -1,3 +1,5 @@ +import { omitBy, isNil, isNumber, defaultTo } from 'lodash'; + import { PanelModel, FieldMatcherID, @@ -7,7 +9,7 @@ import { FieldConfig, } from '@grafana/data'; import { ReduceTransformerOptions } from '@grafana/data/src/transformations/transformers/reduce'; -import { omitBy, isNil, isNumber, defaultTo } from 'lodash'; + import { PanelOptions } from './models.gen'; /** diff --git a/public/app/plugins/panel/table/module.tsx b/public/app/plugins/panel/table/module.tsx index bfc3dfdccd0..655597ec4c0 100644 --- a/public/app/plugins/panel/table/module.tsx +++ b/public/app/plugins/panel/table/module.tsx @@ -6,13 +6,14 @@ import { ReducerID, standardEditorsRegistry, } from '@grafana/data'; -import { TablePanel } from './TablePanel'; -import { PanelOptions, defaultPanelOptions, defaultPanelFieldConfig } from './models.gen'; import { TableFieldOptions } from '@grafana/schema'; -import { tableMigrationHandler, tablePanelChangedHandler } from './migrations'; import { TableCellDisplayMode } from '@grafana/ui'; -import { TableSuggestionsSupplier } from './suggestions'; + import { PaginationEditor } from './PaginationEditor'; +import { TablePanel } from './TablePanel'; +import { tableMigrationHandler, tablePanelChangedHandler } from './migrations'; +import { PanelOptions, defaultPanelOptions, defaultPanelFieldConfig } from './models.gen'; +import { TableSuggestionsSupplier } from './suggestions'; export const plugin = new PanelPlugin(TablePanel) .setPanelChangeHandler(tablePanelChangedHandler) diff --git a/public/app/plugins/panel/table/suggestions.ts b/public/app/plugins/panel/table/suggestions.ts index 3294de7839d..c9b1d89a7fc 100644 --- a/public/app/plugins/panel/table/suggestions.ts +++ b/public/app/plugins/panel/table/suggestions.ts @@ -1,6 +1,7 @@ import { VisualizationSuggestionsBuilder } from '@grafana/data'; import { TableFieldOptions } from '@grafana/schema'; import { SuggestionName } from 'app/types/suggestions'; + import { PanelOptions } from './models.gen'; export class TableSuggestionsSupplier { diff --git a/public/app/plugins/panel/text/TextPanel.tsx b/public/app/plugins/panel/text/TextPanel.tsx index b9e918ce259..f2808f00cf8 100644 --- a/public/app/plugins/panel/text/TextPanel.tsx +++ b/public/app/plugins/panel/text/TextPanel.tsx @@ -1,14 +1,16 @@ // Libraries -import React, { PureComponent } from 'react'; -import { debounce } from 'lodash'; -import { PanelProps, renderTextPanelMarkdown, textUtil } from '@grafana/data'; -// Utils -import config from 'app/core/config'; -// Types -import { PanelOptions, TextMode } from './models.gen'; -import { CustomScrollbar, stylesFactory } from '@grafana/ui'; import { css, cx } from '@emotion/css'; import DangerouslySetHtmlContent from 'dangerously-set-html-content'; +import { debounce } from 'lodash'; +import React, { PureComponent } from 'react'; + +import { PanelProps, renderTextPanelMarkdown, textUtil } from '@grafana/data'; +// Utils +import { CustomScrollbar, stylesFactory } from '@grafana/ui'; +import config from 'app/core/config'; + +// Types +import { PanelOptions, TextMode } from './models.gen'; interface Props extends PanelProps {} diff --git a/public/app/plugins/panel/text/TextPanelEditor.tsx b/public/app/plugins/panel/text/TextPanelEditor.tsx index a8c1a351c2f..a44e161f1fc 100644 --- a/public/app/plugins/panel/text/TextPanelEditor.tsx +++ b/public/app/plugins/panel/text/TextPanelEditor.tsx @@ -1,6 +1,8 @@ -import React, { FC, useMemo } from 'react'; import { css, cx } from '@emotion/css'; +import React, { FC, useMemo } from 'react'; import AutoSizer from 'react-virtualized-auto-sizer'; + +import { GrafanaTheme, StandardEditorProps } from '@grafana/data'; import { CodeEditor, stylesFactory, @@ -8,7 +10,6 @@ import { CodeEditorSuggestionItem, variableSuggestionToCodeEditorSuggestion, } from '@grafana/ui'; -import { GrafanaTheme, StandardEditorProps } from '@grafana/data'; import { PanelOptions, TextMode } from './models.gen'; diff --git a/public/app/plugins/panel/text/module.tsx b/public/app/plugins/panel/text/module.tsx index f30a4492ca7..66f6b127a1e 100644 --- a/public/app/plugins/panel/text/module.tsx +++ b/public/app/plugins/panel/text/module.tsx @@ -1,9 +1,9 @@ import { PanelPlugin } from '@grafana/data'; import { TextPanel } from './TextPanel'; -import { textPanelMigrationHandler } from './textPanelMigrationHandler'; import { TextPanelEditor } from './TextPanelEditor'; import { defaultPanelOptions, PanelOptions, TextMode } from './models.gen'; +import { textPanelMigrationHandler } from './textPanelMigrationHandler'; export const plugin = new PanelPlugin(TextPanel) .setPanelOptions((builder) => { diff --git a/public/app/plugins/panel/text/textPanelMigrationHandler.test.ts b/public/app/plugins/panel/text/textPanelMigrationHandler.test.ts index 1d9c6e0b809..39a072a8c23 100644 --- a/public/app/plugins/panel/text/textPanelMigrationHandler.test.ts +++ b/public/app/plugins/panel/text/textPanelMigrationHandler.test.ts @@ -1,7 +1,8 @@ -import { textPanelMigrationHandler } from './textPanelMigrationHandler'; -import { TextMode, PanelOptions } from './models.gen'; import { FieldConfigSource, PanelModel } from '@grafana/data'; +import { TextMode, PanelOptions } from './models.gen'; +import { textPanelMigrationHandler } from './textPanelMigrationHandler'; + describe('textPanelMigrationHandler', () => { describe('when invoked and previous version was old Angular text panel', () => { it('then should migrate options', () => { diff --git a/public/app/plugins/panel/text/textPanelMigrationHandler.ts b/public/app/plugins/panel/text/textPanelMigrationHandler.ts index 23ffcaeb927..c3eeed14f8b 100644 --- a/public/app/plugins/panel/text/textPanelMigrationHandler.ts +++ b/public/app/plugins/panel/text/textPanelMigrationHandler.ts @@ -1,4 +1,5 @@ import { PanelModel } from '@grafana/data'; + import { TextMode, PanelOptions } from './models.gen'; export const textPanelMigrationHandler = (panel: PanelModel): Partial => { diff --git a/public/app/plugins/panel/timeseries/FillBelowToEditor.tsx b/public/app/plugins/panel/timeseries/FillBelowToEditor.tsx index a8ca720f466..d2614d3ae71 100644 --- a/public/app/plugins/panel/timeseries/FillBelowToEditor.tsx +++ b/public/app/plugins/panel/timeseries/FillBelowToEditor.tsx @@ -1,4 +1,5 @@ import React, { useMemo } from 'react'; + import { FieldOverrideEditorProps, FieldType, getFieldDisplayName, SelectableValue } from '@grafana/data'; import { Select } from '@grafana/ui'; diff --git a/public/app/plugins/panel/timeseries/LineStyleEditor.tsx b/public/app/plugins/panel/timeseries/LineStyleEditor.tsx index 75a089ce70e..8807bbe118f 100644 --- a/public/app/plugins/panel/timeseries/LineStyleEditor.tsx +++ b/public/app/plugins/panel/timeseries/LineStyleEditor.tsx @@ -1,6 +1,7 @@ import React, { useMemo } from 'react'; -import { LineStyle } from '@grafana/schema'; + import { FieldOverrideEditorProps, SelectableValue } from '@grafana/data'; +import { LineStyle } from '@grafana/schema'; import { HorizontalGroup, IconButton, RadioButtonGroup, Select } from '@grafana/ui'; type LineFill = 'solid' | 'dash' | 'dot'; diff --git a/public/app/plugins/panel/timeseries/SpanNullsEditor.tsx b/public/app/plugins/panel/timeseries/SpanNullsEditor.tsx index 12525dd73bf..119ff689238 100644 --- a/public/app/plugins/panel/timeseries/SpanNullsEditor.tsx +++ b/public/app/plugins/panel/timeseries/SpanNullsEditor.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { FieldOverrideEditorProps, rangeUtil, SelectableValue } from '@grafana/data'; import { HorizontalGroup, Input, RadioButtonGroup } from '@grafana/ui'; diff --git a/public/app/plugins/panel/timeseries/ThresholdsStyleEditor.tsx b/public/app/plugins/panel/timeseries/ThresholdsStyleEditor.tsx index 83e202cd16e..40bd69deb83 100644 --- a/public/app/plugins/panel/timeseries/ThresholdsStyleEditor.tsx +++ b/public/app/plugins/panel/timeseries/ThresholdsStyleEditor.tsx @@ -1,6 +1,7 @@ import React, { useCallback } from 'react'; -import { GraphTresholdsStyleMode } from '@grafana/schema'; + import { FieldOverrideEditorProps, SelectableValue } from '@grafana/data'; +import { GraphTresholdsStyleMode } from '@grafana/schema'; import { Select } from '@grafana/ui'; export const ThresholdsStyleEditor: React.FC< diff --git a/public/app/plugins/panel/timeseries/TimeSeriesPanel.tsx b/public/app/plugins/panel/timeseries/TimeSeriesPanel.tsx index 06c19a7a434..9e143d4f976 100644 --- a/public/app/plugins/panel/timeseries/TimeSeriesPanel.tsx +++ b/public/app/plugins/panel/timeseries/TimeSeriesPanel.tsx @@ -1,18 +1,20 @@ import React, { useMemo } from 'react'; + import { Field, PanelProps } from '@grafana/data'; +import { PanelDataErrorView } from '@grafana/runtime'; import { TooltipDisplayMode } from '@grafana/schema'; import { usePanelContext, TimeSeries, TooltipPlugin, ZoomPlugin, KeyboardPlugin } from '@grafana/ui'; +import { config } from 'app/core/config'; import { getFieldLinksForExplore } from 'app/features/explore/utils/links'; + +import { AnnotationEditorPlugin } from './plugins/AnnotationEditorPlugin'; import { AnnotationsPlugin } from './plugins/AnnotationsPlugin'; import { ContextMenuPlugin } from './plugins/ContextMenuPlugin'; import { ExemplarsPlugin } from './plugins/ExemplarsPlugin'; +import { OutsideRangePlugin } from './plugins/OutsideRangePlugin'; +import { ThresholdControlsPlugin } from './plugins/ThresholdControlsPlugin'; import { TimeSeriesOptions } from './types'; import { prepareGraphableFields } from './utils'; -import { AnnotationEditorPlugin } from './plugins/AnnotationEditorPlugin'; -import { ThresholdControlsPlugin } from './plugins/ThresholdControlsPlugin'; -import { config } from 'app/core/config'; -import { PanelDataErrorView } from '@grafana/runtime'; -import { OutsideRangePlugin } from './plugins/OutsideRangePlugin'; interface TimeSeriesPanelProps extends PanelProps {} diff --git a/public/app/plugins/panel/timeseries/config.ts b/public/app/plugins/panel/timeseries/config.ts index dae74c592a2..b75ad5e5b68 100644 --- a/public/app/plugins/panel/timeseries/config.ts +++ b/public/app/plugins/panel/timeseries/config.ts @@ -18,11 +18,10 @@ import { GraphTresholdsStyleMode, GraphTransform, } from '@grafana/schema'; - import { graphFieldOptions, commonOptionsBuilder } from '@grafana/ui'; -import { LineStyleEditor } from './LineStyleEditor'; import { FillBellowToEditor } from './FillBelowToEditor'; +import { LineStyleEditor } from './LineStyleEditor'; import { SpanNullsEditor } from './SpanNullsEditor'; import { ThresholdsStyleEditor } from './ThresholdsStyleEditor'; diff --git a/public/app/plugins/panel/timeseries/migrations.test.ts b/public/app/plugins/panel/timeseries/migrations.test.ts index da9cf0275d4..767c528464a 100644 --- a/public/app/plugins/panel/timeseries/migrations.test.ts +++ b/public/app/plugins/panel/timeseries/migrations.test.ts @@ -1,8 +1,10 @@ -import { PanelModel, FieldConfigSource } from '@grafana/data'; -import { graphPanelChangedHandler } from './migrations'; import { cloneDeep } from 'lodash'; + +import { PanelModel, FieldConfigSource } from '@grafana/data'; import { TooltipDisplayMode, SortOrder } from '@grafana/schema'; +import { graphPanelChangedHandler } from './migrations'; + describe('Graph Migrations', () => { let prevFieldConfig: FieldConfigSource; diff --git a/public/app/plugins/panel/timeseries/migrations.ts b/public/app/plugins/panel/timeseries/migrations.ts index 8b336f8d3c1..56beb024450 100644 --- a/public/app/plugins/panel/timeseries/migrations.ts +++ b/public/app/plugins/panel/timeseries/migrations.ts @@ -1,3 +1,5 @@ +import { omitBy, pickBy, isNil, isNumber, isString } from 'lodash'; + import { ConfigOverrideRule, DynamicConfigValue, @@ -29,9 +31,9 @@ import { SortOrder, GraphTransform, } from '@grafana/schema'; -import { TimeSeriesOptions } from './types'; -import { omitBy, pickBy, isNil, isNumber, isString } from 'lodash'; + import { defaultGraphConfig } from './config'; +import { TimeSeriesOptions } from './types'; /** * This is called when the panel changes from another panel diff --git a/public/app/plugins/panel/timeseries/module.tsx b/public/app/plugins/panel/timeseries/module.tsx index 230a985cae6..c1f4b742ff9 100644 --- a/public/app/plugins/panel/timeseries/module.tsx +++ b/public/app/plugins/panel/timeseries/module.tsx @@ -1,11 +1,12 @@ -import { GraphFieldConfig } from '@grafana/schema'; import { PanelPlugin } from '@grafana/data'; +import { GraphFieldConfig } from '@grafana/schema'; import { commonOptionsBuilder } from '@grafana/ui'; + import { TimeSeriesPanel } from './TimeSeriesPanel'; -import { graphPanelChangedHandler } from './migrations'; -import { TimeSeriesOptions } from './types'; import { defaultGraphConfig, getGraphFieldConfig } from './config'; +import { graphPanelChangedHandler } from './migrations'; import { TimeSeriesSuggestionsSupplier } from './suggestions'; +import { TimeSeriesOptions } from './types'; export const plugin = new PanelPlugin(TimeSeriesPanel) .setPanelChangeHandler(graphPanelChangedHandler) diff --git a/public/app/plugins/panel/timeseries/overrides/colorSeriesConfigFactory.test.ts b/public/app/plugins/panel/timeseries/overrides/colorSeriesConfigFactory.test.ts index c66d04ffeb3..08a8600bd29 100644 --- a/public/app/plugins/panel/timeseries/overrides/colorSeriesConfigFactory.test.ts +++ b/public/app/plugins/panel/timeseries/overrides/colorSeriesConfigFactory.test.ts @@ -1,4 +1,5 @@ import { FieldColorModeId, FieldConfigSource, FieldMatcherID } from '@grafana/data'; + import { changeSeriesColorConfigFactory } from './colorSeriesConfigFactory'; describe('changeSeriesColorConfigFactory', () => { diff --git a/public/app/plugins/panel/timeseries/overrides/hideSeriesConfigFactory.test.ts b/public/app/plugins/panel/timeseries/overrides/hideSeriesConfigFactory.test.ts index 369dc0f4a18..059e65db4a8 100644 --- a/public/app/plugins/panel/timeseries/overrides/hideSeriesConfigFactory.test.ts +++ b/public/app/plugins/panel/timeseries/overrides/hideSeriesConfigFactory.test.ts @@ -7,6 +7,7 @@ import { toDataFrame, } from '@grafana/data'; import { GraphNGLegendEvent, SeriesVisibilityChangeMode } from '@grafana/ui'; + import { hideSeriesConfigFactory } from './hideSeriesConfigFactory'; describe('hideSeriesConfigFactory', () => { diff --git a/public/app/plugins/panel/timeseries/plugins/AnnotationEditorPlugin.tsx b/public/app/plugins/panel/timeseries/plugins/AnnotationEditorPlugin.tsx index 43d0e6e8bc0..c66e91972f9 100644 --- a/public/app/plugins/panel/timeseries/plugins/AnnotationEditorPlugin.tsx +++ b/public/app/plugins/panel/timeseries/plugins/AnnotationEditorPlugin.tsx @@ -1,10 +1,12 @@ -import { CartesianCoords2D, DataFrame, TimeZone } from '@grafana/data'; -import { PlotSelection, UPlotConfigBuilder } from '@grafana/ui'; import React, { useCallback, useLayoutEffect, useRef, useState } from 'react'; import { useMountedState } from 'react-use'; -import { AnnotationEditor } from './annotations/AnnotationEditor'; import uPlot from 'uplot'; +import { CartesianCoords2D, DataFrame, TimeZone } from '@grafana/data'; +import { PlotSelection, UPlotConfigBuilder } from '@grafana/ui'; + +import { AnnotationEditor } from './annotations/AnnotationEditor'; + type StartAnnotatingFn = (props: { // pixel coordinates of the clicked point on the uPlot canvas coords: { viewport: CartesianCoords2D; plotCanvas: CartesianCoords2D } | null; diff --git a/public/app/plugins/panel/timeseries/plugins/AnnotationsPlugin.tsx b/public/app/plugins/panel/timeseries/plugins/AnnotationsPlugin.tsx index ad6a58b8ac8..8073bb61d38 100644 --- a/public/app/plugins/panel/timeseries/plugins/AnnotationsPlugin.tsx +++ b/public/app/plugins/panel/timeseries/plugins/AnnotationsPlugin.tsx @@ -1,8 +1,10 @@ +import React, { useCallback, useEffect, useLayoutEffect, useRef } from 'react'; +import uPlot from 'uplot'; + import { colorManipulator, DataFrame, DataFrameFieldIndex, DataFrameView, TimeZone } from '@grafana/data'; import { EventsCanvas, UPlotConfigBuilder, useTheme2 } from '@grafana/ui'; -import React, { useCallback, useEffect, useLayoutEffect, useRef } from 'react'; + import { AnnotationMarker } from './annotations/AnnotationMarker'; -import uPlot from 'uplot'; interface AnnotationsPluginProps { config: UPlotConfigBuilder; diff --git a/public/app/plugins/panel/timeseries/plugins/ContextMenuPlugin.tsx b/public/app/plugins/panel/timeseries/plugins/ContextMenuPlugin.tsx index d5fbcd2e92b..b27a9f9880a 100644 --- a/public/app/plugins/panel/timeseries/plugins/ContextMenuPlugin.tsx +++ b/public/app/plugins/panel/timeseries/plugins/ContextMenuPlugin.tsx @@ -1,5 +1,8 @@ -import React, { useCallback, useLayoutEffect, useMemo, useRef, useState } from 'react'; import { css as cssCore, Global } from '@emotion/react'; +import React, { useCallback, useLayoutEffect, useMemo, useRef, useState } from 'react'; +import { useClickAway } from 'react-use'; + +import { CartesianCoords2D, DataFrame, getFieldDisplayName, InterpolateFunction, TimeZone } from '@grafana/data'; import { ContextMenu, GraphContextMenuHeader, @@ -10,8 +13,6 @@ import { MenuItem, UPlotConfigBuilder, } from '@grafana/ui'; -import { CartesianCoords2D, DataFrame, getFieldDisplayName, InterpolateFunction, TimeZone } from '@grafana/data'; -import { useClickAway } from 'react-use'; import { pluginLog } from '@grafana/ui/src/components/uPlot/utils'; type ContextMenuSelectionCoords = { viewport: CartesianCoords2D; plotCanvas: CartesianCoords2D }; diff --git a/public/app/plugins/panel/timeseries/plugins/ExemplarMarker.tsx b/public/app/plugins/panel/timeseries/plugins/ExemplarMarker.tsx index b99bcfd5121..1a0112ef62c 100644 --- a/public/app/plugins/panel/timeseries/plugins/ExemplarMarker.tsx +++ b/public/app/plugins/panel/timeseries/plugins/ExemplarMarker.tsx @@ -1,4 +1,7 @@ import { css, cx } from '@emotion/css'; +import React, { useCallback, useRef, useState } from 'react'; +import { usePopper } from 'react-popper'; + import { DataFrame, DataFrameFieldIndex, @@ -12,8 +15,6 @@ import { } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; import { FieldLinkList, Portal, UPlotConfigBuilder, useStyles } from '@grafana/ui'; -import React, { useCallback, useRef, useState } from 'react'; -import { usePopper } from 'react-popper'; interface ExemplarMarkerProps { timeZone: TimeZone; diff --git a/public/app/plugins/panel/timeseries/plugins/ExemplarsPlugin.tsx b/public/app/plugins/panel/timeseries/plugins/ExemplarsPlugin.tsx index ea22594b674..6e8e663f940 100644 --- a/public/app/plugins/panel/timeseries/plugins/ExemplarsPlugin.tsx +++ b/public/app/plugins/panel/timeseries/plugins/ExemplarsPlugin.tsx @@ -1,3 +1,6 @@ +import React, { useCallback, useLayoutEffect, useRef } from 'react'; +import uPlot from 'uplot'; + import { DataFrame, DataFrameFieldIndex, @@ -8,9 +11,8 @@ import { TIME_SERIES_VALUE_FIELD_NAME, } from '@grafana/data'; import { EventsCanvas, FIXED_UNIT, UPlotConfigBuilder } from '@grafana/ui'; -import React, { useCallback, useLayoutEffect, useRef } from 'react'; + import { ExemplarMarker } from './ExemplarMarker'; -import uPlot from 'uplot'; interface ExemplarsPluginProps { config: UPlotConfigBuilder; diff --git a/public/app/plugins/panel/timeseries/plugins/OutsideRangePlugin.tsx b/public/app/plugins/panel/timeseries/plugins/OutsideRangePlugin.tsx index c8f37bf5aa5..6cf3cd30532 100644 --- a/public/app/plugins/panel/timeseries/plugins/OutsideRangePlugin.tsx +++ b/public/app/plugins/panel/timeseries/plugins/OutsideRangePlugin.tsx @@ -1,7 +1,8 @@ import React, { useLayoutEffect, useRef } from 'react'; +import uPlot from 'uplot'; + import { TimeRange, AbsoluteTimeRange } from '@grafana/data'; import { UPlotConfigBuilder, Button } from '@grafana/ui'; -import uPlot from 'uplot'; interface ThresholdControlsPluginProps { config: UPlotConfigBuilder; diff --git a/public/app/plugins/panel/timeseries/plugins/ThresholdControlsPlugin.tsx b/public/app/plugins/panel/timeseries/plugins/ThresholdControlsPlugin.tsx index 34cb44742a1..84c766b3032 100644 --- a/public/app/plugins/panel/timeseries/plugins/ThresholdControlsPlugin.tsx +++ b/public/app/plugins/panel/timeseries/plugins/ThresholdControlsPlugin.tsx @@ -1,8 +1,10 @@ import React, { useState, useLayoutEffect, useMemo, useRef } from 'react'; +import uPlot from 'uplot'; + import { FieldConfigSource, ThresholdsConfig, getValueFormat } from '@grafana/data'; import { UPlotConfigBuilder, buildScaleKey } from '@grafana/ui'; + import { ThresholdDragHandle } from './ThresholdDragHandle'; -import uPlot from 'uplot'; const GUTTER_SIZE = 60; diff --git a/public/app/plugins/panel/timeseries/plugins/ThresholdDragHandle.tsx b/public/app/plugins/panel/timeseries/plugins/ThresholdDragHandle.tsx index 33430101ad8..605887c8d05 100644 --- a/public/app/plugins/panel/timeseries/plugins/ThresholdDragHandle.tsx +++ b/public/app/plugins/panel/timeseries/plugins/ThresholdDragHandle.tsx @@ -1,8 +1,9 @@ -import React, { useMemo, useState } from 'react'; import { css } from '@emotion/css'; +import React, { useMemo, useState } from 'react'; +import Draggable, { DraggableBounds } from 'react-draggable'; + import { Threshold, GrafanaTheme2 } from '@grafana/data'; import { useStyles2, useTheme2 } from '@grafana/ui'; -import Draggable, { DraggableBounds } from 'react-draggable'; type OutOfBounds = 'top' | 'bottom' | 'none'; diff --git a/public/app/plugins/panel/timeseries/plugins/annotations/AnnotationEditor.tsx b/public/app/plugins/panel/timeseries/plugins/annotations/AnnotationEditor.tsx index 6186365b1f8..b140d9e80ec 100644 --- a/public/app/plugins/panel/timeseries/plugins/annotations/AnnotationEditor.tsx +++ b/public/app/plugins/panel/timeseries/plugins/annotations/AnnotationEditor.tsx @@ -1,9 +1,12 @@ +import { css, cx } from '@emotion/css'; import React, { HTMLAttributes, useState } from 'react'; import { usePopper } from 'react-popper'; -import { css, cx } from '@emotion/css'; -import { PlotSelection, useStyles2, useTheme2, Portal, DEFAULT_ANNOTATION_COLOR } from '@grafana/ui'; + import { colorManipulator, DataFrame, getDisplayProcessor, GrafanaTheme2, TimeZone } from '@grafana/data'; +import { PlotSelection, useStyles2, useTheme2, Portal, DEFAULT_ANNOTATION_COLOR } from '@grafana/ui'; + import { getCommonAnnotationStyles } from '../styles'; + import { AnnotationEditorForm } from './AnnotationEditorForm'; interface AnnotationEditorProps extends HTMLAttributes { diff --git a/public/app/plugins/panel/timeseries/plugins/annotations/AnnotationEditorForm.tsx b/public/app/plugins/panel/timeseries/plugins/annotations/AnnotationEditorForm.tsx index fb26a82951a..edc4cfd149e 100644 --- a/public/app/plugins/panel/timeseries/plugins/annotations/AnnotationEditorForm.tsx +++ b/public/app/plugins/panel/timeseries/plugins/annotations/AnnotationEditorForm.tsx @@ -1,9 +1,10 @@ -import React, { HTMLAttributes, useRef } from 'react'; import { css, cx } from '@emotion/css'; -import { Button, Field, Form, HorizontalGroup, InputControl, TextArea, usePanelContext, useStyles2 } from '@grafana/ui'; -import { AnnotationEventUIModel, GrafanaTheme2 } from '@grafana/data'; -import useClickAway from 'react-use/lib/useClickAway'; +import React, { HTMLAttributes, useRef } from 'react'; import useAsyncFn from 'react-use/lib/useAsyncFn'; +import useClickAway from 'react-use/lib/useClickAway'; + +import { AnnotationEventUIModel, GrafanaTheme2 } from '@grafana/data'; +import { Button, Field, Form, HorizontalGroup, InputControl, TextArea, usePanelContext, useStyles2 } from '@grafana/ui'; import { TagFilter } from 'app/core/components/TagFilter/TagFilter'; import { getAnnotationTags } from 'app/features/annotations/api'; diff --git a/public/app/plugins/panel/timeseries/plugins/annotations/AnnotationMarker.tsx b/public/app/plugins/panel/timeseries/plugins/annotations/AnnotationMarker.tsx index c7c8cc19a01..dd354bf4df4 100644 --- a/public/app/plugins/panel/timeseries/plugins/annotations/AnnotationMarker.tsx +++ b/public/app/plugins/panel/timeseries/plugins/annotations/AnnotationMarker.tsx @@ -1,11 +1,14 @@ +import { css } from '@emotion/css'; import React, { HTMLAttributes, useCallback, useRef, useState } from 'react'; +import { usePopper } from 'react-popper'; + import { GrafanaTheme2, dateTimeFormat, systemDateFormats, TimeZone } from '@grafana/data'; import { Portal, useStyles2, usePanelContext } from '@grafana/ui'; -import { css } from '@emotion/css'; -import { AnnotationEditorForm } from './AnnotationEditorForm'; -import { getCommonAnnotationStyles } from '../styles'; -import { usePopper } from 'react-popper'; import { getTooltipContainerStyles } from '@grafana/ui/src/themes/mixins'; + +import { getCommonAnnotationStyles } from '../styles'; + +import { AnnotationEditorForm } from './AnnotationEditorForm'; import { AnnotationTooltip } from './AnnotationTooltip'; interface Props extends HTMLAttributes { diff --git a/public/app/plugins/panel/timeseries/plugins/annotations/AnnotationTooltip.tsx b/public/app/plugins/panel/timeseries/plugins/annotations/AnnotationTooltip.tsx index ce5ff0ba437..0a6da533d90 100644 --- a/public/app/plugins/panel/timeseries/plugins/annotations/AnnotationTooltip.tsx +++ b/public/app/plugins/panel/timeseries/plugins/annotations/AnnotationTooltip.tsx @@ -1,11 +1,11 @@ -import React from 'react'; import { css } from '@emotion/css'; -import { HorizontalGroup, IconButton, Tag, useStyles2 } from '@grafana/ui'; -import { GrafanaTheme2, textUtil } from '@grafana/data'; +import React from 'react'; +import { GrafanaTheme2, textUtil } from '@grafana/data'; +import { HorizontalGroup, IconButton, Tag, useStyles2 } from '@grafana/ui'; +import config from 'app/core/config'; import alertDef from 'app/features/alerting/state/alertDef'; import { CommentManager } from 'app/features/comments/CommentManager'; -import config from 'app/core/config'; interface AnnotationTooltipProps { annotation: AnnotationsDataFrameViewDTO; diff --git a/public/app/plugins/panel/timeseries/plugins/styles.ts b/public/app/plugins/panel/timeseries/plugins/styles.ts index 31dc2fc6aae..9bb7054dfae 100644 --- a/public/app/plugins/panel/timeseries/plugins/styles.ts +++ b/public/app/plugins/panel/timeseries/plugins/styles.ts @@ -1,5 +1,6 @@ -import { GrafanaTheme2 } from '@grafana/data'; import { css } from '@emotion/css'; + +import { GrafanaTheme2 } from '@grafana/data'; import { DEFAULT_ANNOTATION_COLOR } from '@grafana/ui'; export const getCommonAnnotationStyles = (theme: GrafanaTheme2) => { diff --git a/public/app/plugins/panel/timeseries/suggestions.ts b/public/app/plugins/panel/timeseries/suggestions.ts index 72d1c020c11..e1e3906a912 100644 --- a/public/app/plugins/panel/timeseries/suggestions.ts +++ b/public/app/plugins/panel/timeseries/suggestions.ts @@ -8,6 +8,7 @@ import { StackingMode, } from '@grafana/schema'; import { SuggestionName } from 'app/types/suggestions'; + import { TimeSeriesOptions } from './types'; export class TimeSeriesSuggestionsSupplier { diff --git a/public/app/plugins/panel/timeseries/utils.test.ts b/public/app/plugins/panel/timeseries/utils.test.ts index 0d2065a8bff..3064163f1b2 100644 --- a/public/app/plugins/panel/timeseries/utils.test.ts +++ b/public/app/plugins/panel/timeseries/utils.test.ts @@ -1,4 +1,5 @@ import { createTheme, FieldType, MutableDataFrame, toDataFrame } from '@grafana/data'; + import { prepareGraphableFields } from './utils'; describe('prepare timeseries graph', () => { diff --git a/public/app/plugins/panel/welcome/Welcome.tsx b/public/app/plugins/panel/welcome/Welcome.tsx index d2194971b8e..fa623ef0e8e 100644 --- a/public/app/plugins/panel/welcome/Welcome.tsx +++ b/public/app/plugins/panel/welcome/Welcome.tsx @@ -1,5 +1,6 @@ -import React, { FC } from 'react'; import { css } from '@emotion/css'; +import React, { FC } from 'react'; + import { GrafanaTheme } from '@grafana/data'; import { stylesFactory, useTheme } from '@grafana/ui'; diff --git a/public/app/plugins/panel/welcome/module.ts b/public/app/plugins/panel/welcome/module.ts index d7b86178a29..4a654deafb1 100644 --- a/public/app/plugins/panel/welcome/module.ts +++ b/public/app/plugins/panel/welcome/module.ts @@ -1,4 +1,5 @@ import { PanelPlugin } from '@grafana/data'; + import { WelcomeBanner } from './Welcome'; export const plugin = new PanelPlugin(WelcomeBanner).setNoPadding(); diff --git a/public/app/plugins/panel/xychart/ExplicitEditor.tsx b/public/app/plugins/panel/xychart/ExplicitEditor.tsx index a5af738005f..d2ddac4d6da 100644 --- a/public/app/plugins/panel/xychart/ExplicitEditor.tsx +++ b/public/app/plugins/panel/xychart/ExplicitEditor.tsx @@ -1,4 +1,5 @@ import React, { FC } from 'react'; + import { StandardEditorProps } from '@grafana/data'; import { XYChartOptions, ScatterFieldConfig } from './models.gen'; diff --git a/public/app/plugins/panel/xychart/TooltipView.tsx b/public/app/plugins/panel/xychart/TooltipView.tsx index db62263a678..d5fa55c0084 100644 --- a/public/app/plugins/panel/xychart/TooltipView.tsx +++ b/public/app/plugins/panel/xychart/TooltipView.tsx @@ -1,8 +1,10 @@ -import React, { PureComponent } from 'react'; -import { stylesFactory } from '@grafana/ui'; -import { DataFrame, Field, formattedValueToString, getFieldDisplayName, GrafanaTheme2 } from '@grafana/data'; import { css } from '@emotion/css'; +import React, { PureComponent } from 'react'; + +import { DataFrame, Field, formattedValueToString, getFieldDisplayName, GrafanaTheme2 } from '@grafana/data'; +import { stylesFactory } from '@grafana/ui'; import { config } from 'app/core/config'; + import { ScatterSeries } from './types'; export interface Props { diff --git a/public/app/plugins/panel/xychart/XYChartPanel2.tsx b/public/app/plugins/panel/xychart/XYChartPanel2.tsx index dd1051fa648..262c9aa74a0 100644 --- a/public/app/plugins/panel/xychart/XYChartPanel2.tsx +++ b/public/app/plugins/panel/xychart/XYChartPanel2.tsx @@ -1,7 +1,7 @@ import React, { PureComponent } from 'react'; + import { PanelProps } from '@grafana/data'; -import { XYChartOptions } from './models.gen'; -import { ScatterHoverEvent, ScatterSeries } from './types'; +import { config } from '@grafana/runtime'; import { LegendDisplayMode, Portal, @@ -13,9 +13,11 @@ import { VizTooltipContainer, } from '@grafana/ui'; import { FacetedData } from '@grafana/ui/src/components/uPlot/types'; -import { prepData, prepScatter } from './scatter'; -import { config } from '@grafana/runtime'; + import { TooltipView } from './TooltipView'; +import { XYChartOptions } from './models.gen'; +import { prepData, prepScatter } from './scatter'; +import { ScatterHoverEvent, ScatterSeries } from './types'; type Props = PanelProps; type State = { diff --git a/public/app/plugins/panel/xychart/XYDimsEditor.tsx b/public/app/plugins/panel/xychart/XYDimsEditor.tsx index 50019f6354e..040a0dbb0a5 100644 --- a/public/app/plugins/panel/xychart/XYDimsEditor.tsx +++ b/public/app/plugins/panel/xychart/XYDimsEditor.tsx @@ -1,6 +1,6 @@ -import React, { FC, useMemo } from 'react'; import { css } from '@emotion/css'; -import { IconButton, Label, Select, stylesFactory, useTheme } from '@grafana/ui'; +import React, { FC, useMemo } from 'react'; + import { SelectableValue, getFrameDisplayName, @@ -8,9 +8,10 @@ import { StandardEditorProps, getFieldDisplayName, } from '@grafana/data'; +import { IconButton, Label, Select, stylesFactory, useTheme } from '@grafana/ui'; -import { XYDimensionConfig, XYChartOptions } from './models.gen'; import { getXYDimensions, isGraphable } from './dims'; +import { XYDimensionConfig, XYChartOptions } from './models.gen'; interface XYInfo { numberFields: Array>; diff --git a/public/app/plugins/panel/xychart/config.ts b/public/app/plugins/panel/xychart/config.ts index 5d5347a2344..ac05945f02f 100644 --- a/public/app/plugins/panel/xychart/config.ts +++ b/public/app/plugins/panel/xychart/config.ts @@ -6,9 +6,10 @@ import { SetFieldConfigOptionsArgs, } from '@grafana/data'; import { LineStyle, VisibilityMode } from '@grafana/schema'; - import { commonOptionsBuilder, graphFieldOptions } from '@grafana/ui'; + import { LineStyleEditor } from '../timeseries/LineStyleEditor'; + import { ScatterFieldConfig, ScatterLineMode } from './models.gen'; const categoryStyles = undefined; // ['Scatter styles']; diff --git a/public/app/plugins/panel/xychart/dims.ts b/public/app/plugins/panel/xychart/dims.ts index 7f11ee1757d..b2228c63823 100644 --- a/public/app/plugins/panel/xychart/dims.ts +++ b/public/app/plugins/panel/xychart/dims.ts @@ -1,8 +1,9 @@ import { DataFrame, Field, FieldMatcher, FieldType, getFieldDisplayName } from '@grafana/data'; +import { XYFieldMatchers } from '@grafana/ui/src/components/GraphNG/types'; + import { XYDimensionConfig } from './models.gen'; // TODO: fix import -import { XYFieldMatchers } from '@grafana/ui/src/components/GraphNG/types'; export enum DimensionError { NoData, diff --git a/public/app/plugins/panel/xychart/module.tsx b/public/app/plugins/panel/xychart/module.tsx index 32e917025ba..d9a46da727f 100644 --- a/public/app/plugins/panel/xychart/module.tsx +++ b/public/app/plugins/panel/xychart/module.tsx @@ -1,11 +1,12 @@ import { PanelPlugin } from '@grafana/data'; import { commonOptionsBuilder } from '@grafana/ui'; -import { defaultScatterConfig, XYChartOptions, ScatterFieldConfig } from './models.gen'; -import { getScatterFieldConfig } from './config'; -import { XYDimsEditor } from './XYDimsEditor'; -import { XYChartPanel2 } from './XYChartPanel2'; import { ColorDimensionEditor, ScaleDimensionEditor } from 'app/features/dimensions/editors'; +import { XYChartPanel2 } from './XYChartPanel2'; +import { XYDimsEditor } from './XYDimsEditor'; +import { getScatterFieldConfig } from './config'; +import { defaultScatterConfig, XYChartOptions, ScatterFieldConfig } from './models.gen'; + export const plugin = new PanelPlugin(XYChartPanel2) .useFieldConfig(getScatterFieldConfig(defaultScatterConfig)) .setPanelOptions((builder) => { diff --git a/public/app/plugins/panel/xychart/scatter.ts b/public/app/plugins/panel/xychart/scatter.ts index 5830c75b414..022e9db6707 100644 --- a/public/app/plugins/panel/xychart/scatter.ts +++ b/public/app/plugins/panel/xychart/scatter.ts @@ -1,3 +1,5 @@ +import uPlot from 'uplot'; + import { DataFrame, FieldColorModeId, @@ -8,6 +10,8 @@ import { getFieldSeriesColor, GrafanaTheme2, } from '@grafana/data'; +import { alpha } from '@grafana/data/src/themes/colorManipulator'; +import { config } from '@grafana/runtime'; import { AxisPlacement, ScaleDirection, ScaleOrientation, VisibilityMode } from '@grafana/schema'; import { UPlotConfigBuilder } from '@grafana/ui'; import { FacetedData, FacetSeries } from '@grafana/ui/src/components/uPlot/types'; @@ -17,13 +21,12 @@ import { ScaleDimensionConfig, ScaleDimensionMode, } from 'app/features/dimensions'; -import { config } from '@grafana/runtime'; -import { defaultScatterConfig, ScatterFieldConfig, ScatterLineMode, XYChartOptions } from './models.gen'; + import { pointWithin, Quadtree, Rect } from '../barchart/quadtree'; -import { alpha } from '@grafana/data/src/themes/colorManipulator'; -import uPlot from 'uplot'; -import { DimensionValues, ScatterHoverCallback, ScatterSeries } from './types'; + import { isGraphable } from './dims'; +import { defaultScatterConfig, ScatterFieldConfig, ScatterLineMode, XYChartOptions } from './models.gen'; +import { DimensionValues, ScatterHoverCallback, ScatterSeries } from './types'; export interface ScatterPanelInfo { error?: string; diff --git a/public/app/plugins/panel/xychart/types.ts b/public/app/plugins/panel/xychart/types.ts index 10e6e64171a..0ef28147778 100644 --- a/public/app/plugins/panel/xychart/types.ts +++ b/public/app/plugins/panel/xychart/types.ts @@ -2,6 +2,7 @@ import { DataFrame, Field, FieldColorMode } from '@grafana/data'; import { LineStyle, VisibilityMode } from '@grafana/schema'; import { VizLegendItem } from '@grafana/ui'; import { ScaleDimensionConfig } from 'app/features/dimensions'; + import { ScatterLineMode } from './models.gen'; /** diff --git a/public/app/plugins/sdk.ts b/public/app/plugins/sdk.ts index 58fd3f2b02f..c70ba4638ad 100644 --- a/public/app/plugins/sdk.ts +++ b/public/app/plugins/sdk.ts @@ -1,7 +1,7 @@ import { makeClassES5Compatible } from '@grafana/data'; import { loadPluginCss } from '@grafana/runtime'; -import { PanelCtrl as PanelCtrlES6 } from 'app/angular/panel/panel_ctrl'; import { MetricsPanelCtrl as MetricsPanelCtrlES6 } from 'app/angular/panel/metrics_panel_ctrl'; +import { PanelCtrl as PanelCtrlES6 } from 'app/angular/panel/panel_ctrl'; import { QueryCtrl as QueryCtrlES6 } from 'app/angular/panel/query_ctrl'; const PanelCtrl = makeClassES5Compatible(PanelCtrlES6); diff --git a/public/app/routes/routes.tsx b/public/app/routes/routes.tsx index 9186b51d2d6..ecefa48d15f 100644 --- a/public/app/routes/routes.tsx +++ b/public/app/routes/routes.tsx @@ -1,19 +1,21 @@ import React from 'react'; -import LdapPage from 'app/features/admin/ldap/LdapPage'; -import UserAdminPage from 'app/features/admin/UserAdminPage'; +import { Redirect } from 'react-router-dom'; + +import ErrorPage from 'app/core/components/ErrorPage/ErrorPage'; import { LoginPage } from 'app/core/components/Login/LoginPage'; import config from 'app/core/config'; -import { AccessControlAction, DashboardRoutes } from 'app/types'; -import { SafeDynamicImport } from '../core/components/DynamicImports/SafeDynamicImport'; -import { RouteDescriptor } from '../core/navigation/types'; -import { Redirect } from 'react-router-dom'; -import ErrorPage from 'app/core/components/ErrorPage/ErrorPage'; -import { getRoutes as getPluginCatalogRoutes } from 'app/features/plugins/admin/routes'; import { contextSrv } from 'app/core/services/context_srv'; -import { getLiveRoutes } from 'app/features/live/pages/routes'; +import UserAdminPage from 'app/features/admin/UserAdminPage'; +import LdapPage from 'app/features/admin/ldap/LdapPage'; import { getAlertingRoutes } from 'app/features/alerting/routes'; +import { getLiveRoutes } from 'app/features/live/pages/routes'; +import { getRoutes as getPluginCatalogRoutes } from 'app/features/plugins/admin/routes'; import { getProfileRoutes } from 'app/features/profile/routes'; import { ServiceAccountPage } from 'app/features/serviceaccounts/ServiceAccountPage'; +import { AccessControlAction, DashboardRoutes } from 'app/types'; + +import { SafeDynamicImport } from '../core/components/DynamicImports/SafeDynamicImport'; +import { RouteDescriptor } from '../core/navigation/types'; export const extraRoutes: RouteDescriptor[] = []; diff --git a/public/app/store/configureStore.ts b/public/app/store/configureStore.ts index 03275629e9b..c28a2c0a6bb 100644 --- a/public/app/store/configureStore.ts +++ b/public/app/store/configureStore.ts @@ -1,11 +1,14 @@ import { configureStore as reduxConfigureStore, MiddlewareArray } from '@reduxjs/toolkit'; -import { setStore } from './store'; -import { StoreState } from 'app/types/store'; -import { addReducer, createRootReducer } from '../core/reducers/root'; -import { buildInitialState } from '../core/reducers/navModel'; import { AnyAction } from 'redux'; import { ThunkMiddleware } from 'redux-thunk'; +import { StoreState } from 'app/types/store'; + +import { buildInitialState } from '../core/reducers/navModel'; +import { addReducer, createRootReducer } from '../core/reducers/root'; + +import { setStore } from './store'; + export function addRootReducer(reducers: any) { // this is ok now because we add reducers before configureStore is called // in the future if we want to add reducers during runtime diff --git a/public/app/types/appEvent.ts b/public/app/types/appEvent.ts index 940c2000ed8..b5ee46d553d 100644 --- a/public/app/types/appEvent.ts +++ b/public/app/types/appEvent.ts @@ -1,4 +1,5 @@ import { IAngularEvent } from 'angular'; + import { AppEvent } from '@grafana/data'; export interface AppEventEmitter { diff --git a/public/app/types/dashboard.ts b/public/app/types/dashboard.ts index 614c6061663..68ace717636 100644 --- a/public/app/types/dashboard.ts +++ b/public/app/types/dashboard.ts @@ -1,8 +1,9 @@ -import { DashboardAcl } from './acl'; import { DataQuery } from '@grafana/data'; import { DashboardModel } from 'app/features/dashboard/state/DashboardModel'; import { VariableModel } from 'app/features/variables/types'; +import { DashboardAcl } from './acl'; + export interface DashboardDTO { redirectUri?: string; dashboard: DashboardDataDTO; diff --git a/public/app/types/datasources.ts b/public/app/types/datasources.ts index 03eb07a1652..10bd4f0471a 100644 --- a/public/app/types/datasources.ts +++ b/public/app/types/datasources.ts @@ -1,6 +1,6 @@ import { DataSourcePluginMeta, DataSourceSettings, LayoutMode } from '@grafana/data'; -import { GenericDataSourcePlugin } from 'app/features/datasources/settings/PluginSettings'; import { HealthCheckResultDetails } from '@grafana/runtime/src/utils/DataSourceWithBackend'; +import { GenericDataSourcePlugin } from 'app/features/datasources/settings/PluginSettings'; export interface DataSourcesState { dataSources: DataSourceSettings[]; diff --git a/public/app/types/explore.ts b/public/app/types/explore.ts index ca313a28f06..5f836805e72 100644 --- a/public/app/types/explore.ts +++ b/public/app/types/explore.ts @@ -1,4 +1,5 @@ import { Observable, SubscriptionLike, Unsubscribable } from 'rxjs'; + import { AbsoluteTimeRange, DataFrame, diff --git a/public/app/types/serviceaccount.ts b/public/app/types/serviceaccount.ts index 40c4b533676..3448e99b546 100644 --- a/public/app/types/serviceaccount.ts +++ b/public/app/types/serviceaccount.ts @@ -1,4 +1,5 @@ import { SelectableValue, WithAccessControlMetadata } from '@grafana/data'; + import { ApiKey, OrgRole, Role } from '.'; export interface OrgServiceAccount extends WithAccessControlMetadata { diff --git a/public/app/types/store.ts b/public/app/types/store.ts index 7b03dc2b890..0cb1961c674 100644 --- a/public/app/types/store.ts +++ b/public/app/types/store.ts @@ -1,9 +1,3 @@ -import { ThunkAction, ThunkDispatch as GenericThunkDispatch } from 'redux-thunk'; -import { - useSelector as useSelectorUntyped, - TypedUseSelectorHook, - useDispatch as useDispatchUntyped, -} from 'react-redux'; import { Action, AsyncThunk, @@ -12,6 +6,13 @@ import { createAsyncThunk as createAsyncThunkUntyped, PayloadAction, } from '@reduxjs/toolkit'; +import { + useSelector as useSelectorUntyped, + TypedUseSelectorHook, + useDispatch as useDispatchUntyped, +} from 'react-redux'; +import { ThunkAction, ThunkDispatch as GenericThunkDispatch } from 'redux-thunk'; + import type { createRootReducer } from 'app/core/reducers/root'; import { configureStore } from 'app/store/configureStore'; diff --git a/public/app/types/teams.ts b/public/app/types/teams.ts index 92c83b436a9..99739affb95 100644 --- a/public/app/types/teams.ts +++ b/public/app/types/teams.ts @@ -1,4 +1,5 @@ import { WithAccessControlMetadata } from '@grafana/data'; + import { TeamPermissionLevel } from './acl'; export interface Team extends WithAccessControlMetadata { diff --git a/public/app/types/unified-alerting.ts b/public/app/types/unified-alerting.ts index 52b2e903e54..5c98037378e 100644 --- a/public/app/types/unified-alerting.ts +++ b/public/app/types/unified-alerting.ts @@ -1,6 +1,7 @@ /* Prometheus internal models */ import { AlertState, DataSourceInstanceSettings } from '@grafana/data'; + import { PromAlertingRuleState, PromRuleType, diff --git a/public/app/types/user.ts b/public/app/types/user.ts index 157bc143c0b..7d6eeab849d 100644 --- a/public/app/types/user.ts +++ b/public/app/types/user.ts @@ -1,5 +1,6 @@ -import { OrgRole } from '.'; import { SelectableValue, WithAccessControlMetadata } from '@grafana/data'; + +import { OrgRole } from '.'; export interface OrgUser extends WithAccessControlMetadata { avatarUrl: string; email: string; diff --git a/public/test/core/redux/reducerTester.test.ts b/public/test/core/redux/reducerTester.test.ts index f5cb8890897..fb4c71922e3 100644 --- a/public/test/core/redux/reducerTester.test.ts +++ b/public/test/core/redux/reducerTester.test.ts @@ -1,5 +1,5 @@ -import { AnyAction } from 'redux'; import { createAction } from '@reduxjs/toolkit'; +import { AnyAction } from 'redux'; import { reducerTester } from './reducerTester'; diff --git a/public/test/core/redux/reducerTester.ts b/public/test/core/redux/reducerTester.ts index 728a4aa9869..49c7dad1854 100644 --- a/public/test/core/redux/reducerTester.ts +++ b/public/test/core/redux/reducerTester.ts @@ -1,6 +1,6 @@ -import { Action } from 'redux'; import { AnyAction } from '@reduxjs/toolkit'; import { cloneDeep } from 'lodash'; +import { Action } from 'redux'; type GrafanaReducer = (state: S, action: A) => S; diff --git a/public/test/core/redux/reduxTester.ts b/public/test/core/redux/reduxTester.ts index c730b6f96a6..d3decce2c8e 100644 --- a/public/test/core/redux/reduxTester.ts +++ b/public/test/core/redux/reduxTester.ts @@ -1,5 +1,3 @@ -import { Dispatch, Middleware, MiddlewareAPI } from 'redux'; -import thunk, { ThunkMiddleware } from 'redux-thunk'; import { AnyAction, configureStore, @@ -9,10 +7,12 @@ import { CombinedState, PreloadedState, } from '@reduxjs/toolkit'; - -import { StoreState } from '../../../app/types'; -import { setStore } from '../../../app/store/store'; import { NoInfer } from '@reduxjs/toolkit/dist/tsHelpers'; +import { Dispatch, Middleware, MiddlewareAPI } from 'redux'; +import thunk, { ThunkMiddleware } from 'redux-thunk'; + +import { setStore } from '../../../app/store/store'; +import { StoreState } from '../../../app/types'; export interface ReduxTesterGiven { givenRootReducer: (rootReducer: Reducer) => ReduxTesterWhen; diff --git a/public/test/core/thunk/thunkTester.ts b/public/test/core/thunk/thunkTester.ts index 944d44fd129..8afedcb53bf 100644 --- a/public/test/core/thunk/thunkTester.ts +++ b/public/test/core/thunk/thunkTester.ts @@ -1,7 +1,7 @@ // @ts-ignore +import { PayloadAction } from '@reduxjs/toolkit'; import configureMockStore from 'redux-mock-store'; import thunk from 'redux-thunk'; -import { PayloadAction } from '@reduxjs/toolkit'; const mockStore = configureMockStore([thunk]); diff --git a/public/test/global-jquery-shim.ts b/public/test/global-jquery-shim.ts new file mode 100644 index 00000000000..645b39e9c63 --- /dev/null +++ b/public/test/global-jquery-shim.ts @@ -0,0 +1,4 @@ +import $ from 'jquery'; + +const global = window as any; +global.$ = global.jQuery = $; diff --git a/public/test/helpers/TestProvider.tsx b/public/test/helpers/TestProvider.tsx index cc93f37db33..ba71a620dfa 100644 --- a/public/test/helpers/TestProvider.tsx +++ b/public/test/helpers/TestProvider.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { I18nProvider } from '../../app/core/localisation'; const TestProvider: React.FC = ({ children }) => { diff --git a/public/test/helpers/convertToStoreState.ts b/public/test/helpers/convertToStoreState.ts index 40bbe568e91..8a93487ae02 100644 --- a/public/test/helpers/convertToStoreState.ts +++ b/public/test/helpers/convertToStoreState.ts @@ -1,5 +1,5 @@ -import { StoreState } from '../../app/types'; import { getPreloadedState } from '../../app/features/variables/state/helpers'; +import { StoreState } from '../../app/types'; export const convertToStoreState = (key: string, models: any[]): StoreState => { const variables = models.reduce((byName, variable) => { diff --git a/public/test/helpers/getTemplateSrvDependencies.ts b/public/test/helpers/getTemplateSrvDependencies.ts index 6c52f78c9e4..c1da0c4d247 100644 --- a/public/test/helpers/getTemplateSrvDependencies.ts +++ b/public/test/helpers/getTemplateSrvDependencies.ts @@ -1,6 +1,7 @@ +import { TemplateSrvDependencies } from 'app/features/templating/template_srv'; + import { getFilteredVariables, getVariables, getVariableWithName } from '../../app/features/variables/state/selectors'; import { StoreState } from '../../app/types'; -import { TemplateSrvDependencies } from 'app/features/templating/template_srv'; export const getTemplateSrvDependencies = (state: StoreState): TemplateSrvDependencies => ({ getFilteredVariables: (filter) => getFilteredVariables(filter, state), diff --git a/public/test/helpers/initTemplateSrv.ts b/public/test/helpers/initTemplateSrv.ts index a19688f282c..acf5b026a7d 100644 --- a/public/test/helpers/initTemplateSrv.ts +++ b/public/test/helpers/initTemplateSrv.ts @@ -1,6 +1,8 @@ import { TimeRange } from '@grafana/data'; -import { convertToStoreState } from './convertToStoreState'; + import { TemplateSrv } from '../../app/features/templating/template_srv'; + +import { convertToStoreState } from './convertToStoreState'; import { getTemplateSrvDependencies } from './getTemplateSrvDependencies'; export function initTemplateSrv(key: string, variables: any[], timeRange?: TimeRange) { diff --git a/public/test/jest-setup.ts b/public/test/jest-setup.ts index 40a7a0ceffa..de839539c09 100644 --- a/public/test/jest-setup.ts +++ b/public/test/jest-setup.ts @@ -1,10 +1,18 @@ -import { configure } from 'enzyme'; -import { EventBusSrv } from '@grafana/data'; +// This import has side effects, and must be at the top so jQuery is made global before +// angular is imported. +import './global-jquery-shim'; + import Adapter from '@wojtekmaj/enzyme-adapter-react-17'; -import $ from 'jquery'; +import angular from 'angular'; +import { configure } from 'enzyme'; + +import { EventBusSrv } from '@grafana/data'; import 'mutationobserver-shim'; import './mocks/workers'; +import '../vendor/flot/jquery.flot'; +import '../vendor/flot/jquery.flot.time'; + const testAppEvents = new EventBusSrv(); const global = window as any; global.$ = global.jQuery = $; @@ -24,10 +32,6 @@ Object.defineProperty(global, 'matchMedia', { })), }); -import '../vendor/flot/jquery.flot'; -import '../vendor/flot/jquery.flot.time'; -import angular from 'angular'; - angular.module('grafana', ['ngRoute']); angular.module('grafana.services', ['ngRoute', '$strap.directives']); angular.module('grafana.panels', []); diff --git a/public/test/matchers/index.ts b/public/test/matchers/index.ts index 3b955e37493..b6f8a091aaa 100644 --- a/public/test/matchers/index.ts +++ b/public/test/matchers/index.ts @@ -1,7 +1,8 @@ -import { ObservableMatchers } from './types'; +import { Observable } from 'rxjs'; + import { toEmitValues } from './toEmitValues'; import { toEmitValuesWith } from './toEmitValuesWith'; -import { Observable } from 'rxjs'; +import { ObservableMatchers } from './types'; export const matchers: ObservableMatchers> = { toEmitValues, diff --git a/public/test/matchers/toEmitValues.test.ts b/public/test/matchers/toEmitValues.test.ts index a6411a1fa96..71edff27e8d 100644 --- a/public/test/matchers/toEmitValues.test.ts +++ b/public/test/matchers/toEmitValues.test.ts @@ -1,5 +1,6 @@ import { interval, Observable, of, throwError } from 'rxjs'; import { map, mergeMap, take } from 'rxjs/operators'; + import { OBSERVABLE_TEST_TIMEOUT_IN_MS } from './types'; describe('toEmitValues matcher', () => { diff --git a/public/test/matchers/toEmitValues.ts b/public/test/matchers/toEmitValues.ts index 1ecf554646e..e8bf9e80470 100644 --- a/public/test/matchers/toEmitValues.ts +++ b/public/test/matchers/toEmitValues.ts @@ -1,7 +1,8 @@ -import { Observable, Subscription } from 'rxjs'; import { matcherHint, printExpected, printReceived } from 'jest-matcher-utils'; -import { expectObservable, forceObservableCompletion } from './utils'; import { isEqual } from 'lodash'; +import { Observable, Subscription } from 'rxjs'; + +import { expectObservable, forceObservableCompletion } from './utils'; function passMessage(received: any[], expected: any[]) { return `${matcherHint('.not.toEmitValues')} diff --git a/public/test/matchers/toEmitValuesWith.ts b/public/test/matchers/toEmitValuesWith.ts index cc464302337..0764e674b65 100644 --- a/public/test/matchers/toEmitValuesWith.ts +++ b/public/test/matchers/toEmitValuesWith.ts @@ -1,6 +1,7 @@ -import { Observable, Subscription } from 'rxjs'; -import { expectObservable, forceObservableCompletion } from './utils'; import { matcherHint, printReceived } from 'jest-matcher-utils'; +import { Observable, Subscription } from 'rxjs'; + +import { expectObservable, forceObservableCompletion } from './utils'; function tryExpectations(received: any[], expectations: (received: any[]) => void): jest.CustomMatcherResult { try { diff --git a/public/test/matchers/utils.ts b/public/test/matchers/utils.ts index b8b677cb752..ddba865e453 100644 --- a/public/test/matchers/utils.ts +++ b/public/test/matchers/utils.ts @@ -1,7 +1,8 @@ import { matcherHint, printExpected, printReceived } from 'jest-matcher-utils'; -import { OBSERVABLE_TEST_TIMEOUT_IN_MS } from './types'; import { asapScheduler, Subscription, timer, isObservable } from 'rxjs'; +import { OBSERVABLE_TEST_TIMEOUT_IN_MS } from './types'; + export function forceObservableCompletion(subscription: Subscription, resolve: (args: any) => void) { const timeoutObservable = timer(OBSERVABLE_TEST_TIMEOUT_IN_MS, asapScheduler); diff --git a/public/test/mocks/datasource_srv.ts b/public/test/mocks/datasource_srv.ts index 3b6eeb45b30..e6caeda6d0c 100644 --- a/public/test/mocks/datasource_srv.ts +++ b/public/test/mocks/datasource_srv.ts @@ -1,3 +1,5 @@ +import { Observable } from 'rxjs'; + import { DataQueryRequest, DataQueryResponse, @@ -7,7 +9,6 @@ import { DataSourceRef, getDataSourceUID, } from '@grafana/data'; -import { Observable } from 'rxjs'; export class DatasourceSrvMock { constructor(private defaultDS: DataSourceApi, private datasources: { [name: string]: DataSourceApi }) { diff --git a/public/test/mocks/linguiMacro.tsx b/public/test/mocks/linguiMacro.tsx index f3f5c344fed..955298f6b8c 100644 --- a/public/test/mocks/linguiMacro.tsx +++ b/public/test/mocks/linguiMacro.tsx @@ -1,6 +1,6 @@ -import React from 'react'; import { MessageDescriptor } from '@lingui/core'; import { Trans as OriginalTrans } from '@lingui/macro'; +import React from 'react'; export const Trans: typeof OriginalTrans = ({ id, children }) => { return <>{children ?? id}; diff --git a/public/test/redux-rtl.tsx b/public/test/redux-rtl.tsx index 0c8b33148ef..279df6a49a6 100644 --- a/public/test/redux-rtl.tsx +++ b/public/test/redux-rtl.tsx @@ -1,10 +1,12 @@ -import React from 'react'; -import { render as rtlRender } from '@testing-library/react'; import { AnyAction, configureStore } from '@reduxjs/toolkit'; import { ThunkMiddlewareFor } from '@reduxjs/toolkit/dist/getDefaultMiddleware'; +import { render as rtlRender } from '@testing-library/react'; +import React from 'react'; import { Provider } from 'react-redux'; + import { createRootReducer } from 'app/core/reducers/root'; import { StoreState } from 'app/types'; + import { mockNavModel } from './mocks/navModel'; function render( diff --git a/public/test/setupTests.ts b/public/test/setupTests.ts index 2d4eeaae51f..4c88026270a 100644 --- a/public/test/setupTests.ts +++ b/public/test/setupTests.ts @@ -1,5 +1,6 @@ import '@testing-library/jest-dom'; import failOnConsole from 'jest-fail-on-console'; + import { matchers } from './matchers'; failOnConsole({ diff --git a/public/test/specs/helpers.ts b/public/test/specs/helpers.ts index 1bb8a295729..0bddf53b9cd 100644 --- a/public/test/specs/helpers.ts +++ b/public/test/specs/helpers.ts @@ -1,10 +1,11 @@ import { each, template } from 'lodash'; -import config from 'app/core/config'; -import { angularMocks, sinon } from '../lib/common'; -import { PanelModel } from 'app/features/dashboard/state/PanelModel'; import { RawTimeRange, PanelPluginMeta, dateMath } from '@grafana/data'; import { GrafanaRootScope } from 'app/angular/GrafanaCtrl'; +import config from 'app/core/config'; +import { PanelModel } from 'app/features/dashboard/state/PanelModel'; + +import { angularMocks, sinon } from '../lib/common'; export function ControllerTestContext(this: any) { const self = this; diff --git a/scripts/cli/generateSassVariableFiles.ts b/scripts/cli/generateSassVariableFiles.ts index dad9c610e05..4e7cb99d5b7 100644 --- a/scripts/cli/generateSassVariableFiles.ts +++ b/scripts/cli/generateSassVariableFiles.ts @@ -1,8 +1,9 @@ import * as fs from 'fs'; + +import { createTheme } from '@grafana/data'; import { darkThemeVarsTemplate } from '@grafana/ui/src/themes/_variables.dark.scss.tmpl'; import { lightThemeVarsTemplate } from '@grafana/ui/src/themes/_variables.light.scss.tmpl'; import { commonThemeVarsTemplate } from '@grafana/ui/src/themes/_variables.scss.tmpl'; -import { createTheme } from '@grafana/data'; const darkThemeVariablesPath = __dirname + '/../../public/sass/_variables.dark.generated.scss'; const lightThemeVariablesPath = __dirname + '/../../public/sass/_variables.light.generated.scss'; diff --git a/scripts/webpack/dependencies.js b/scripts/webpack/dependencies.js index 8b253145e28..2aecd51d4e3 100644 --- a/scripts/webpack/dependencies.js +++ b/scripts/webpack/dependencies.js @@ -1,8 +1,9 @@ 'use strict'; -const pkg = require('../../package.json'); const { pull } = require('lodash'); +const pkg = require('../../package.json'); + let dependencies = Object.keys(pkg.dependencies); // remove jquery so we can add it first // remove rxjs so we can only depend on parts of it in code diff --git a/scripts/webpack/loaders/compile.js b/scripts/webpack/loaders/compile.js index 4c88ab473da..29f9ffe81fc 100644 --- a/scripts/webpack/loaders/compile.js +++ b/scripts/webpack/loaders/compile.js @@ -1,10 +1,9 @@ const loaderUtils = require('loader-utils'); - -const WebWorkerTemplatePlugin = require('webpack/lib/webworker/WebWorkerTemplatePlugin'); const ExternalsPlugin = require('webpack/lib/ExternalsPlugin'); -const NodeTargetPlugin = require('webpack/lib/node/NodeTargetPlugin'); const LoaderTargetPlugin = require('webpack/lib/LoaderTargetPlugin'); const SingleEntryPlugin = require('webpack/lib/SingleEntryPlugin'); +const NodeTargetPlugin = require('webpack/lib/node/NodeTargetPlugin'); +const WebWorkerTemplatePlugin = require('webpack/lib/webworker/WebWorkerTemplatePlugin'); const COMPILATION_METADATA = Symbol('COMPILATION_METADATA'); diff --git a/scripts/webpack/sass.rule.js b/scripts/webpack/sass.rule.js index d68d6b35c56..36290bb3adc 100644 --- a/scripts/webpack/sass.rule.js +++ b/scripts/webpack/sass.rule.js @@ -1,7 +1,7 @@ 'use strict'; -const path = require('path'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); +const path = require('path'); module.exports = function (options) { return { diff --git a/scripts/webpack/webpack.common.js b/scripts/webpack/webpack.common.js index a8ac713dd8a..d8d00d6cc52 100644 --- a/scripts/webpack/webpack.common.js +++ b/scripts/webpack/webpack.common.js @@ -1,8 +1,9 @@ +const CopyWebpackPlugin = require('copy-webpack-plugin'); const fs = require('fs-extra'); const path = require('path'); const webpack = require('webpack'); + const CorsWorkerPlugin = require('./plugins/CorsWorkerPlugin'); -const CopyWebpackPlugin = require('copy-webpack-plugin'); class CopyUniconsPlugin { apply(compiler) { diff --git a/scripts/webpack/webpack.dev.js b/scripts/webpack/webpack.dev.js index acdb133bc7d..dddb04ae409 100644 --- a/scripts/webpack/webpack.dev.js +++ b/scripts/webpack/webpack.dev.js @@ -1,13 +1,14 @@ 'use strict'; -const { merge } = require('webpack-merge'); -const common = require('./webpack.common.js'); -const path = require('path'); -const { DefinePlugin } = require('webpack'); -const HtmlWebpackPlugin = require('html-webpack-plugin'); const ESLintPlugin = require('eslint-webpack-plugin'); const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); +const HtmlWebpackPlugin = require('html-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); +const path = require('path'); +const { DefinePlugin } = require('webpack'); +const { merge } = require('webpack-merge'); + +const common = require('./webpack.common.js'); // const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; module.exports = (env = {}) => diff --git a/scripts/webpack/webpack.hot.js b/scripts/webpack/webpack.hot.js index 2abb19043ec..41933f42758 100644 --- a/scripts/webpack/webpack.hot.js +++ b/scripts/webpack/webpack.hot.js @@ -1,12 +1,13 @@ 'use strict'; -const { merge } = require('webpack-merge'); -const common = require('./webpack.common.js'); -const path = require('path'); -const { DefinePlugin } = require('webpack'); const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); +const path = require('path'); +const { DefinePlugin } = require('webpack'); +const { merge } = require('webpack-merge'); + +const common = require('./webpack.common.js'); module.exports = merge(common, { devtool: 'inline-source-map', diff --git a/scripts/webpack/webpack.prod.js b/scripts/webpack/webpack.prod.js index 3595d2d34a8..ec9c1ac5759 100644 --- a/scripts/webpack/webpack.prod.js +++ b/scripts/webpack/webpack.prod.js @@ -1,12 +1,13 @@ 'use strict'; -const { merge } = require('webpack-merge'); -const TerserPlugin = require('terser-webpack-plugin'); -const common = require('./webpack.common.js'); -const path = require('path'); +const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); -const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); +const path = require('path'); +const TerserPlugin = require('terser-webpack-plugin'); +const { merge } = require('webpack-merge'); + +const common = require('./webpack.common.js'); module.exports = (env = {}) => merge(common, { diff --git a/yarn.lock b/yarn.lock index dae71d7cb2a..89c0142448e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10130,6 +10130,13 @@ __metadata: languageName: node linkType: hard +"@types/json5@npm:^0.0.29": + version: 0.0.29 + resolution: "@types/json5@npm:0.0.29" + checksum: e60b153664572116dfea673c5bda7778dbff150498f44f998e34b5886d8afc47f16799280e4b6e241c0472aef1bc36add771c569c68fc5125fc2ae519a3eb9ac + languageName: node + linkType: hard + "@types/jsurl@npm:^1.2.28": version: 1.2.30 resolution: "@types/jsurl@npm:1.2.30" @@ -12914,6 +12921,18 @@ __metadata: languageName: node linkType: hard +"array.prototype.flat@npm:^1.2.5": + version: 1.3.0 + resolution: "array.prototype.flat@npm:1.3.0" + dependencies: + call-bind: ^1.0.2 + define-properties: ^1.1.3 + es-abstract: ^1.19.2 + es-shim-unscopables: ^1.0.0 + checksum: 2a652b3e8dc0bebb6117e42a5ab5738af0203a14c27341d7bb2431467bdb4b348e2c5dc555dfcda8af0a5e4075c400b85311ded73861c87290a71a17c3e0a257 + languageName: node + linkType: hard + "array.prototype.flatmap@npm:^1.2.1, array.prototype.flatmap@npm:^1.2.5": version: 1.2.5 resolution: "array.prototype.flatmap@npm:1.2.5" @@ -16916,7 +16935,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:2.6.9, debug@npm:^2.2.0, debug@npm:^2.3.3, debug@npm:^2.6.0": +"debug@npm:2.6.9, debug@npm:^2.2.0, debug@npm:^2.3.3, debug@npm:^2.6.0, debug@npm:^2.6.9": version: 2.6.9 resolution: "debug@npm:2.6.9" dependencies: @@ -18040,6 +18059,34 @@ __metadata: languageName: node linkType: hard +"es-abstract@npm:^1.19.2": + version: 1.19.5 + resolution: "es-abstract@npm:1.19.5" + dependencies: + call-bind: ^1.0.2 + es-to-primitive: ^1.2.1 + function-bind: ^1.1.1 + get-intrinsic: ^1.1.1 + get-symbol-description: ^1.0.0 + has: ^1.0.3 + has-symbols: ^1.0.3 + internal-slot: ^1.0.3 + is-callable: ^1.2.4 + is-negative-zero: ^2.0.2 + is-regex: ^1.1.4 + is-shared-array-buffer: ^1.0.2 + is-string: ^1.0.7 + is-weakref: ^1.0.2 + object-inspect: ^1.12.0 + object-keys: ^1.1.1 + object.assign: ^4.1.2 + string.prototype.trimend: ^1.0.4 + string.prototype.trimstart: ^1.0.4 + unbox-primitive: ^1.0.1 + checksum: 55199b0f179a12b3b0ec9c9f2e3a27a7561686e4f88d46f9ef32c836448a336e367c14d8f792612fc83a64113896e478259e4dffbbcffb3efdd06650f6360324 + languageName: node + linkType: hard + "es-array-method-boxes-properly@npm:^1.0.0": version: 1.0.0 resolution: "es-array-method-boxes-properly@npm:1.0.0" @@ -18070,6 +18117,15 @@ __metadata: languageName: node linkType: hard +"es-shim-unscopables@npm:^1.0.0": + version: 1.0.0 + resolution: "es-shim-unscopables@npm:1.0.0" + dependencies: + has: ^1.0.3 + checksum: 83e95cadbb6ee44d3644dfad60dcad7929edbc42c85e66c3e99aefd68a3a5c5665f2686885cddb47dfeabfd77bd5ea5a7060f2092a955a729bbd8834f0d86fa1 + languageName: node + linkType: hard + "es-to-primitive@npm:^1.2.1": version: 1.2.1 resolution: "es-to-primitive@npm:1.2.1" @@ -18246,6 +18302,49 @@ __metadata: languageName: node linkType: hard +"eslint-import-resolver-node@npm:^0.3.6": + version: 0.3.6 + resolution: "eslint-import-resolver-node@npm:0.3.6" + dependencies: + debug: ^3.2.7 + resolve: ^1.20.0 + checksum: 6266733af1e112970e855a5bcc2d2058fb5ae16ad2a6d400705a86b29552b36131ffc5581b744c23d550de844206fb55e9193691619ee4dbf225c4bde526b1c8 + languageName: node + linkType: hard + +"eslint-module-utils@npm:^2.7.3": + version: 2.7.3 + resolution: "eslint-module-utils@npm:2.7.3" + dependencies: + debug: ^3.2.7 + find-up: ^2.1.0 + checksum: 77048263f309167a1e6a1e1b896bfb5ddd1d3859b2e2abbd9c32c432aee13d610d46e6820b1ca81b37fba437cf423a404bc6649be64ace9148a3062d1886a678 + languageName: node + linkType: hard + +"eslint-plugin-import@npm:^2.26.0": + version: 2.26.0 + resolution: "eslint-plugin-import@npm:2.26.0" + dependencies: + array-includes: ^3.1.4 + array.prototype.flat: ^1.2.5 + debug: ^2.6.9 + doctrine: ^2.1.0 + eslint-import-resolver-node: ^0.3.6 + eslint-module-utils: ^2.7.3 + has: ^1.0.3 + is-core-module: ^2.8.1 + is-glob: ^4.0.3 + minimatch: ^3.1.2 + object.values: ^1.1.5 + resolve: ^1.22.0 + tsconfig-paths: ^3.14.1 + peerDependencies: + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + checksum: 0bf77ad80339554481eafa2b1967449e1f816b94c7a6f9614ce33fb4083c4e6c050f10d241dd50b4975d47922880a34de1e42ea9d8e6fd663ebb768baa67e655 + languageName: node + linkType: hard + "eslint-plugin-jest@npm:26.1.2": version: 26.1.2 resolution: "eslint-plugin-jest@npm:26.1.2" @@ -19331,7 +19430,7 @@ __metadata: languageName: node linkType: hard -"find-up@npm:^2.0.0": +"find-up@npm:^2.0.0, find-up@npm:^2.1.0": version: 2.1.0 resolution: "find-up@npm:2.1.0" dependencies: @@ -20575,6 +20674,7 @@ __metadata: enzyme-to-json: 3.6.2 eslint: 8.11.0 eslint-config-prettier: 8.5.0 + eslint-plugin-import: ^2.26.0 eslint-plugin-jest: 26.1.2 eslint-plugin-jsdoc: 38.0.6 eslint-plugin-lodash: 7.4.0 @@ -20835,6 +20935,13 @@ __metadata: languageName: node linkType: hard +"has-symbols@npm:^1.0.3": + version: 1.0.3 + resolution: "has-symbols@npm:1.0.3" + checksum: a054c40c631c0d5741a8285010a0777ea0c068f99ed43e5d6eb12972da223f8af553a455132fdb0801bdcfa0e0f443c0c03a68d8555aa529b3144b446c3f2410 + languageName: node + linkType: hard + "has-tostringtag@npm:^1.0.0": version: 1.0.0 resolution: "has-tostringtag@npm:1.0.0" @@ -22415,6 +22522,13 @@ __metadata: languageName: node linkType: hard +"is-negative-zero@npm:^2.0.2": + version: 2.0.2 + resolution: "is-negative-zero@npm:2.0.2" + checksum: f3232194c47a549da60c3d509c9a09be442507616b69454716692e37ae9f37c4dea264fb208ad0c9f3efd15a796a46b79df07c7e53c6227c32170608b809149a + languageName: node + linkType: hard + "is-npm@npm:^5.0.0": version: 5.0.0 resolution: "is-npm@npm:5.0.0" @@ -22580,6 +22694,15 @@ __metadata: languageName: node linkType: hard +"is-shared-array-buffer@npm:^1.0.2": + version: 1.0.2 + resolution: "is-shared-array-buffer@npm:1.0.2" + dependencies: + call-bind: ^1.0.2 + checksum: 9508929cf14fdc1afc9d61d723c6e8d34f5e117f0bffda4d97e7a5d88c3a8681f633a74f8e3ad1fe92d5113f9b921dc5ca44356492079612f9a247efbce7032a + languageName: node + linkType: hard + "is-ssh@npm:^1.3.0": version: 1.3.3 resolution: "is-ssh@npm:1.3.3" @@ -22673,6 +22796,15 @@ __metadata: languageName: node linkType: hard +"is-weakref@npm:^1.0.2": + version: 1.0.2 + resolution: "is-weakref@npm:1.0.2" + dependencies: + call-bind: ^1.0.2 + checksum: 95bd9a57cdcb58c63b1c401c60a474b0f45b94719c30f548c891860f051bc2231575c290a6b420c6bc6e7ed99459d424c652bd5bf9a1d5259505dc35b4bf83de + languageName: node + linkType: hard + "is-what@npm:^3.12.0": version: 3.14.1 resolution: "is-what@npm:3.14.1" @@ -26050,7 +26182,7 @@ __metadata: languageName: node linkType: hard -"minimist@npm:^1.1.1, minimist@npm:^1.2.0, minimist@npm:^1.2.5": +"minimist@npm:^1.1.1, minimist@npm:^1.2.0, minimist@npm:^1.2.5, minimist@npm:^1.2.6": version: 1.2.6 resolution: "minimist@npm:1.2.6" checksum: d15428cd1e11eb14e1233bcfb88ae07ed7a147de251441d61158619dfb32c4d7e9061d09cab4825fdee18ecd6fce323228c8c47b5ba7cd20af378ca4048fb3fb @@ -32191,7 +32323,7 @@ __metadata: languageName: node linkType: hard -"resolve@npm:^1.3.2": +"resolve@npm:^1.22.0, resolve@npm:^1.3.2": version: 1.22.0 resolution: "resolve@npm:1.22.0" dependencies: @@ -32243,7 +32375,7 @@ __metadata: languageName: node linkType: hard -"resolve@patch:resolve@^1.3.2#~builtin": +"resolve@patch:resolve@^1.22.0#~builtin, resolve@patch:resolve@^1.3.2#~builtin": version: 1.22.0 resolution: "resolve@patch:resolve@npm%3A1.22.0#~builtin::version=1.22.0&hash=07638b" dependencies: @@ -35502,6 +35634,18 @@ __metadata: languageName: node linkType: hard +"tsconfig-paths@npm:^3.14.1": + version: 3.14.1 + resolution: "tsconfig-paths@npm:3.14.1" + dependencies: + "@types/json5": ^0.0.29 + json5: ^1.0.1 + minimist: ^1.2.6 + strip-bom: ^3.0.0 + checksum: 8afa01c673ebb4782ba53d3a12df97fa837ce524f8ad38ee4e2b2fd57f5ac79abc21c574e9e9eb014d93efe7fe8214001b96233b5c6ea75bd1ea82afe17a4c6d + languageName: node + linkType: hard + "tslib@npm:2.3.1, tslib@npm:^2, tslib@npm:^2.0.0, tslib@npm:^2.0.1, tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.2.0, tslib@npm:^2.3.0, tslib@npm:^2.3.1": version: 2.3.1 resolution: "tslib@npm:2.3.1" From 1566fa2ede57510eea3c2c049e9aedfb69fff397 Mon Sep 17 00:00:00 2001 From: Ezequiel Victorero Date: Fri, 22 Apr 2022 10:40:27 -0300 Subject: [PATCH 097/120] Chore: bump github.com/microcosm-cc/bluemonday to 1.0.18 CVE-2021-29272 (#48011) --- go.mod | 2 ++ go.sum | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 521db1c19a0..876f131db0c 100644 --- a/go.mod +++ b/go.mod @@ -304,3 +304,5 @@ replace github.com/tidwall/match => github.com/tidwall/match v1.1.1 // Upgrading affects backend plugins: https://github.com/grafana/grafana/pull/47653#discussion_r850508593 // No harm to Thema because it's only a dependency in its main package. replace github.com/hashicorp/go-hclog => github.com/hashicorp/go-hclog v0.16.1 + +replace github.com/microcosm-cc/bluemonday => github.com/microcosm-cc/bluemonday v1.0.18 diff --git a/go.sum b/go.sum index 071e5682a5b..867b2836997 100644 --- a/go.sum +++ b/go.sum @@ -432,6 +432,7 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.16.3/go.mod h1:bfBj0iVmsUyUg4weDB4Nx github.com/aws/smithy-go v1.5.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= github.com/aws/smithy-go v1.11.2 h1:eG/N+CcUMAvsdffgMvjMKwfyDzIkjM6pfxMJ8Mzc6mE= github.com/aws/smithy-go v1.11.2/go.mod h1:3xHYmszWVx2c0kIwQeEVf9uSm4fYZt67FBJnwub1bgM= +github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc= github.com/beevik/etree v1.1.0 h1:T0xke/WvNtMoCqgzPhkX2r4rjY3GDZFi+FjpRZY2Jbs= @@ -1354,6 +1355,7 @@ github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORR github.com/gopherjs/gopherjs v0.0.0-20191106031601-ce3c9ade29de h1:F7WD09S8QB4LrkEpka0dFPLSotH11HRpCsLIbIcJ7sU= github.com/gopherjs/gopherjs v0.0.0-20191106031601-ce3c9ade29de/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= @@ -1909,7 +1911,7 @@ github.com/mdlayher/netlink v1.1.0/go.mod h1:H4WCitaheIsdF9yOYu8CFmCgQthAPIWZmcK github.com/mdlayher/wifi v0.0.0-20190303161829-b1436901ddee/go.mod h1:Evt/EIne46u9PtQbeTx2NTcqURpr5K4SvKtGmBuDPN8= github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= -github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= +github.com/microcosm-cc/bluemonday v1.0.18/go.mod h1:Z0r70sCuXHig8YpBzCc5eGHAap2K7e/u082ZUpDRRqM= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.15/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.22/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= From 94fd03f44fee3f32a3ba9a88c59a441011ab81ea Mon Sep 17 00:00:00 2001 From: Gabriel MABILLE Date: Fri, 22 Apr 2022 15:45:54 +0200 Subject: [PATCH 098/120] LDAP: Fix debug view to display the actual computed mapping in ldap.go (#48103) * LDAP debug fix with Org role inheritance Co-authored-by: Jguer * ldap debug coherent with ldap.go Co-authored-by: Jguer Co-authored-by: Jguer --- pkg/api/ldap_debug.go | 54 ++++++++++---------------- pkg/services/ldap/helpers.go | 2 +- pkg/services/ldap/ldap.go | 2 +- pkg/services/ldap/ldap_helpers_test.go | 2 +- 4 files changed, 23 insertions(+), 37 deletions(-) diff --git a/pkg/api/ldap_debug.go b/pkg/api/ldap_debug.go index c7a978e0234..f62daaa0407 100644 --- a/pkg/api/ldap_debug.go +++ b/pkg/api/ldap_debug.go @@ -241,7 +241,7 @@ func (hs *HTTPServer) GetUserFromLDAP(c *models.ReqContext) response.Response { return response.Error(http.StatusBadRequest, "Failed to obtain the LDAP configuration", err) } - ldap := newLDAP(ldapConfig.Servers) + multiLDAP := newLDAP(ldapConfig.Servers) username := web.Params(c.Req)[":username"] @@ -249,9 +249,8 @@ func (hs *HTTPServer) GetUserFromLDAP(c *models.ReqContext) response.Response { return response.Error(http.StatusBadRequest, "Validation error. You must specify an username", nil) } - user, serverConfig, err := ldap.User(username) - - if user == nil { + user, serverConfig, err := multiLDAP.User(username) + if user == nil || err != nil { return response.Error(http.StatusNotFound, "No user was found in the LDAP server(s) with that username", err) } @@ -268,45 +267,32 @@ func (hs *HTTPServer) GetUserFromLDAP(c *models.ReqContext) response.Response { IsDisabled: user.IsDisabled, } - orgRoles := []LDAPRoleDTO{} - - // Need to iterate based on the config groups as only the first match for an org is used - // We are showing all matches as that should help in understanding why one match wins out - // over another. - for _, configGroup := range serverConfig.Groups { - for _, userGroup := range user.Groups { - if strings.EqualFold(configGroup.GroupDN, userGroup) { - r := &LDAPRoleDTO{GroupDN: configGroup.GroupDN, OrgId: configGroup.OrgId, OrgRole: configGroup.OrgRole} - orgRoles = append(orgRoles, *r) - break - } - } - //} - } - - // Then, we find what we did not match by inspecting the list of groups returned from - // LDAP against what we have already matched above. + unmappedUserGroups := map[string]struct{}{} for _, userGroup := range user.Groups { - var matched bool + unmappedUserGroups[strings.ToLower(userGroup)] = struct{}{} + } - for _, orgRole := range orgRoles { - if strings.EqualFold(orgRole.GroupDN, userGroup) { // we already matched it - matched = true - break - } + orgRolesMap := map[int64]models.RoleType{} + for _, group := range serverConfig.Groups { + // only use the first match for each org + if orgRolesMap[group.OrgId] != "" { + continue } - if !matched { - r := &LDAPRoleDTO{GroupDN: userGroup} - orgRoles = append(orgRoles, *r) + if ldap.IsMemberOf(user.Groups, group.GroupDN) { + orgRolesMap[group.OrgId] = group.OrgRole + u.OrgRoles = append(u.OrgRoles, LDAPRoleDTO{GroupDN: group.GroupDN, + OrgId: group.OrgId, OrgRole: group.OrgRole}) + delete(unmappedUserGroups, strings.ToLower(group.GroupDN)) } } - u.OrgRoles = orgRoles + for userGroup := range unmappedUserGroups { + u.OrgRoles = append(u.OrgRoles, LDAPRoleDTO{GroupDN: userGroup}) + } ldapLogger.Debug("mapping org roles", "orgsRoles", u.OrgRoles) - err = u.FetchOrgs(c.Req.Context(), hs.SQLStore) - if err != nil { + if err := u.FetchOrgs(c.Req.Context(), hs.SQLStore); err != nil { return response.Error(http.StatusBadRequest, "An organization was not found - Please verify your LDAP configuration", err) } diff --git a/pkg/services/ldap/helpers.go b/pkg/services/ldap/helpers.go index 12438f23f6c..851725f2d19 100644 --- a/pkg/services/ldap/helpers.go +++ b/pkg/services/ldap/helpers.go @@ -6,7 +6,7 @@ import ( "gopkg.in/ldap.v3" ) -func isMemberOf(memberOf []string, group string) bool { +func IsMemberOf(memberOf []string, group string) bool { if group == "*" { return true } diff --git a/pkg/services/ldap/ldap.go b/pkg/services/ldap/ldap.go index 1ad3fa15905..02f9e2b2f13 100644 --- a/pkg/services/ldap/ldap.go +++ b/pkg/services/ldap/ldap.go @@ -422,7 +422,7 @@ func (server *Server) buildGrafanaUser(user *ldap.Entry) (*models.ExternalUserIn continue } - if isMemberOf(memberOf, group.GroupDN) { + if IsMemberOf(memberOf, group.GroupDN) { extUser.OrgRoles[group.OrgId] = group.OrgRole if extUser.IsGrafanaAdmin == nil || !*extUser.IsGrafanaAdmin { extUser.IsGrafanaAdmin = group.IsGrafanaAdmin diff --git a/pkg/services/ldap/ldap_helpers_test.go b/pkg/services/ldap/ldap_helpers_test.go index e276917c973..887a2a0a5df 100644 --- a/pkg/services/ldap/ldap_helpers_test.go +++ b/pkg/services/ldap/ldap_helpers_test.go @@ -21,7 +21,7 @@ func TestIsMemberOf(t *testing.T) { for _, tc := range tests { t.Run(fmt.Sprintf("isMemberOf(%v, \"%s\") = %v", tc.memberOf, tc.group, tc.expected), func(t *testing.T) { - assert.Equal(t, tc.expected, isMemberOf(tc.memberOf, tc.group)) + assert.Equal(t, tc.expected, IsMemberOf(tc.memberOf, tc.group)) }) } } From e9ad2207befb58b99df5cf90864c58aa52957718 Mon Sep 17 00:00:00 2001 From: Ezequiel Victorero Date: Fri, 22 Apr 2022 11:59:10 -0300 Subject: [PATCH 099/120] Chore: bump github.com/containerd/containerd to 1.6.2 (#48003) --- go.mod | 23 +++++---- go.sum | 149 ++++++++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 146 insertions(+), 26 deletions(-) diff --git a/go.mod b/go.mod index 876f131db0c..dd8a6d450ad 100644 --- a/go.mod +++ b/go.mod @@ -100,11 +100,11 @@ require ( go.opentelemetry.io/collector/model v0.31.0 go.opentelemetry.io/otel v1.6.3 go.opentelemetry.io/otel/exporters/jaeger v1.0.0 - go.opentelemetry.io/otel/sdk v1.0.0 + go.opentelemetry.io/otel/sdk v1.3.0 go.opentelemetry.io/otel/trace v1.6.3 golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29 golang.org/x/exp v0.0.0-20210220032938-85be41e4509f - golang.org/x/net v0.0.0-20220401154927-543a649e0bdd // indirect + golang.org/x/net v0.0.0-20220421235706-1d1ef9303861 // indirect golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a golang.org/x/sync v0.0.0-20210220032951-036812b2e83c golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 @@ -144,7 +144,7 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/buger/jsonparser v1.1.1 // indirect github.com/c2h5oh/datasize v0.0.0-20200112174442-28bbd4740fee // indirect - github.com/cenkalti/backoff/v4 v4.1.1 // indirect + github.com/cenkalti/backoff/v4 v4.1.2 // indirect github.com/centrifugal/protocol v0.7.6 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/cheekybits/genny v1.0.0 // indirect @@ -183,9 +183,9 @@ require ( github.com/gorilla/mux v1.8.0 // indirect github.com/grafana/grafana-google-sdk-go v0.0.0-20211104130251-b190293eaf58 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340 // indirect - github.com/hashicorp/errwrap v1.0.0 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-msgpack v0.5.5 // indirect - github.com/hashicorp/go-multierror v1.1.0 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-sockaddr v1.0.2 // indirect github.com/hashicorp/golang-lru v0.5.4 github.com/hashicorp/yamux v0.0.0-20210826001029-26ff87cf9493 // indirect @@ -232,12 +232,12 @@ require ( go.mongodb.org/mongo-driver v1.7.0 // indirect go.opencensus.io v0.23.0 // indirect go.uber.org/atomic v1.9.0 - go.uber.org/goleak v1.1.11 // indirect - golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f // indirect + go.uber.org/goleak v1.1.12 // indirect + golang.org/x/sys v0.0.0-20220422013727-9388b58f7150 // indirect golang.org/x/text v0.3.7 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20220401170504-314d38edb7de + google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3 gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d // indirect ) @@ -270,8 +270,9 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/azcore v0.22.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/keyvault/internal v0.2.1 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v0.4.0 // indirect + github.com/Microsoft/go-winio v0.5.2 // indirect github.com/chromedp/cdproto v0.0.0-20220208224320-6efb837e6bc2 // indirect - github.com/containerd/containerd v1.5.9 // indirect + github.com/containerd/containerd v1.6.2 // indirect github.com/elazarl/goproxy v0.0.0-20220115173737-adb46da277ac // indirect github.com/getkin/kin-openapi v0.94.0 // indirect github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 // indirect @@ -285,6 +286,10 @@ require ( github.com/pierrec/lz4/v4 v4.1.8 // indirect github.com/segmentio/asm v1.1.1 // indirect github.com/yudai/pp v2.0.1+incompatible // indirect + k8s.io/api v0.22.5 // indirect + k8s.io/apimachinery v0.22.5 // indirect + k8s.io/klog/v2 v2.30.0 // indirect + k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b // indirect ) // Use fork of crewjam/saml with fixes for some issues until changes get merged into upstream diff --git a/go.sum b/go.sum index 867b2836997..b6a9645888a 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,5 @@ bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= +bazil.org/fuse v0.0.0-20200407214033-5883e5a4b512/go.mod h1:FbcW6z/2VytnFDhZfumh8Ss8zxHE6qpMP5sHTRe0EaM= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw= @@ -94,6 +95,7 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7 dmitri.shuralyov.com/gpu/mtl v0.0.0-20201218220906-28db891af037/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8= git.sr.ht/~sbinet/gg v0.3.1/go.mod h1:KGYtlADtqsqANL9ueOFkWymvzUvLMQllU5Ixo+8v3pc= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20210715213245-6c3934b029d8/go.mod h1:CzsSbkDixRphAF5hS6wbMKq0eI6ccJRb7/A0M6JBnwg= github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/Azure/azure-amqp-common-go/v3 v3.0.0/go.mod h1:SY08giD/XbhTz07tJdpw1SoxQXHPN30+DI3Z04SYqyg= github.com/Azure/azure-amqp-common-go/v3 v3.2.1/go.mod h1:O6X1iYHP7s2x7NjUKsXVhkwWrQhxrd+d8/3rRadj4CI= @@ -149,6 +151,8 @@ github.com/Azure/go-amqp v0.12.6/go.mod h1:qApuH6OFTSKZFmCOxccvAv5rLizBQf4v8pRmG github.com/Azure/go-amqp v0.16.0/go.mod h1:9YJ3RhxRT1gquYnzpZO1vcYMMpAdJT+QEg6fwmw9Zlg= github.com/Azure/go-amqp v0.16.4/go.mod h1:9YJ3RhxRT1gquYnzpZO1vcYMMpAdJT+QEg6fwmw9Zlg= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= +github.com/Azure/go-ansiterm v0.0.0-20210608223527-2377c96fe795/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest v11.2.8+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= @@ -257,8 +261,10 @@ github.com/Microsoft/go-winio v0.4.16-0.20201130162521-d1ffc52c7331/go.mod h1:XB github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.4.17-0.20210324224401-5516f17a5958/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= -github.com/Microsoft/go-winio v0.4.17 h1:iT12IBVClFevaf8PuVyi3UmZOVh4OqnaLxDTW2O6j3w= github.com/Microsoft/go-winio v0.4.17/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA= +github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= github.com/Microsoft/hcsshim v0.8.7-0.20190325164909-8abdbb8205e4/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ= @@ -267,7 +273,10 @@ github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2 github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00= github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+VxGOoXdC600= github.com/Microsoft/hcsshim v0.8.18/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4= +github.com/Microsoft/hcsshim v0.8.20/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4= +github.com/Microsoft/hcsshim v0.8.21/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4= github.com/Microsoft/hcsshim v0.8.23/go.mod h1:4zegtUJth7lAvFyc6cH2gGQ5B3OFQim01nnU2M8jKDg= +github.com/Microsoft/hcsshim v0.9.2/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc= github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU= github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= @@ -316,6 +325,7 @@ github.com/alecthomas/units v0.0.0-20210208195552-ff826a37aa15/go.mod h1:OMCwj8V github.com/alecthomas/units v0.0.0-20210912230133-d1bdfacee922 h1:8ypNbf5sd3Sm3cKJ9waOGoQv6dKAFiFty9L6NP1AqJ4= github.com/alecthomas/units v0.0.0-20210912230133-d1bdfacee922/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0= +github.com/alexflint/go-filemutex v1.1.0/go.mod h1:7P4iRhttt/nUvUOrYIhcpMzv2G6CY9UnI16Z+UJqRyk= github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= github.com/alicebob/miniredis v2.5.0+incompatible/go.mod h1:8HZjEj4yU0dwhYHky+DxYx+6BMjkBbe5ONFIF1MXffk= github.com/alicebob/miniredis/v2 v2.14.3/go.mod h1:gquAfGbzn92jvtrSC69+6zZnwSODVXVpYDRaGhWaL6I= @@ -490,8 +500,9 @@ github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEe github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff/v4 v4.0.2/go.mod h1:eEew/i+1Q6OrCDZh3WiXYv3+nJwBASZ8Bog/87DQnVg= github.com/cenkalti/backoff/v4 v4.1.0/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= -github.com/cenkalti/backoff/v4 v4.1.1 h1:G2HAfAmvm/GcKan2oOQpBXOd2tT2G57ZnZGWa1PxPBQ= github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/cenkalti/backoff/v4 v4.1.2 h1:6Yo7N8UP2K6LWZnW94DLVSSrbobcWdVzAYOisuDPIFo= +github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/centrifugal/centrifuge v0.19.0 h1:YHws0dRpgsBiI73tRl1wwaB13gzuaI1AM4IFcQQQqcw= @@ -499,6 +510,7 @@ github.com/centrifugal/centrifuge v0.19.0/go.mod h1:O2elf8q3Qkie3z97wkqVqxB52pnO github.com/centrifugal/protocol v0.7.6 h1:AfMwTZfwnFwZslIzQL4QtRnWSVO32RPSuk4iNS/V9tg= github.com/centrifugal/protocol v0.7.6/go.mod h1:cJo0/BuXglhPfg0fgSgTXvBZ7y+9rdg4+nPbIDOVmlA= github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= +github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= github.com/cespare/xxhash v0.0.0-20181017004759-096ff4a8a059/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= @@ -508,6 +520,7 @@ github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cb github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw= github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M= +github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE= github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= github.com/chromedp/cdproto v0.0.0-20200116234248-4da64dd111ac/go.mod h1:PfAWWKJqjlGFYJEidUM6aVIWPr0EpobeyVWEEmplX7g= @@ -524,6 +537,7 @@ github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLI github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= +github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/cisco-ie/nx-telemetry-proto v0.0.0-20190531143454-82441e232cf6/go.mod h1:ugEfq4B8T8ciw/h5mCkgdiDRFS4CkqqhH2dymDB4knc= @@ -568,11 +582,13 @@ github.com/containerd/cgroups v0.0.0-20200710171044-318312a37340/go.mod h1:s5q4S github.com/containerd/cgroups v0.0.0-20200824123100-0b889c03f102/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo= github.com/containerd/cgroups v0.0.0-20210114181951-8a68de567b68/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= github.com/containerd/cgroups v1.0.1/go.mod h1:0SJrPIenamHDcZhEcJMNBB85rHcUsw4f25ZfBiPYRkU= +github.com/containerd/cgroups v1.0.3/go.mod h1:/ofk34relqNjSGyqPrmEULrO4Sc8LJhvJmWbUCUKqj8= github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= github.com/containerd/console v0.0.0-20191206165004-02ecf6a7291e/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE= github.com/containerd/console v1.0.1/go.mod h1:XUsP6YE/mKtz6bxc+I8UiKKTP04qjQL4qcS3XoQ5xkw= github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ= +github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= github.com/containerd/containerd v1.2.7/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/containerd v1.2.10/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= @@ -590,8 +606,10 @@ github.com/containerd/containerd v1.5.0-beta.4/go.mod h1:GmdgZd2zA2GYIBZ0w09Zvgq github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoTJseu1FGOKuoA4nNb2s= github.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g= github.com/containerd/containerd v1.5.4/go.mod h1:sx18RgvW6ABJ4iYUw7Q5x7bgFOAB9B6G7+yO0XBc4zw= -github.com/containerd/containerd v1.5.9 h1:rs6Xg1gtIxaeyG+Smsb/0xaSDu1VgFhOCKBXxMxbsF4= -github.com/containerd/containerd v1.5.9/go.mod h1:fvQqCfadDGga5HZyn3j4+dx56qj2I9YwBrlSdalvJYQ= +github.com/containerd/containerd v1.5.7/go.mod h1:gyvv6+ugqY25TiXxcZC3L5yOeYgEw0QMhscqVp1AR9c= +github.com/containerd/containerd v1.5.8/go.mod h1:YdFSv5bTFLpG2HIYmfqDpSYYTDX+mc5qtSuYx1YUb/s= +github.com/containerd/containerd v1.6.2 h1:pcaPUGbYW8kBw6OgIZwIVIeEhdWVrBzsoCfVJ5BjrLU= +github.com/containerd/containerd v1.6.2/go.mod h1:sidY30/InSE1j2vdD1ihtKoJz+lWdaXMdiAeIupaf+s= github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= @@ -599,6 +617,7 @@ github.com/containerd/continuity v0.0.0-20200710164510-efbc4488d8fe/go.mod h1:cE github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7/go.mod h1:kR3BEg7bDFaEddKm54WSmrol1fKWDU1nKYkgrcgZT7Y= github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e/go.mod h1:EXlVlkqNba9rJe3j7w3Xa924itAMLgZH4UD/Q4PExuQ= github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM= +github.com/containerd/continuity v0.2.2/go.mod h1:pWygW9u7LtS1o4N/Tn0FoCFDIXZ7rxcMX7HX1Dmibvk= github.com/containerd/fifo v0.0.0-20180307165137-3d5202aec260/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= github.com/containerd/fifo v0.0.0-20200410184934-f15a3290365b/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0= @@ -607,6 +626,8 @@ github.com/containerd/fifo v0.0.0-20210316144830-115abcc95a1d/go.mod h1:ocF/ME1S github.com/containerd/fifo v1.0.0/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4= github.com/containerd/go-cni v1.0.1/go.mod h1:+vUpYxKvAF72G9i1WoDOiPGRtQpqsNW/ZHtSlv++smU= github.com/containerd/go-cni v1.0.2/go.mod h1:nrNABBHzu0ZwCug9Ije8hL2xBCYh/pjfMb1aZGrrohk= +github.com/containerd/go-cni v1.1.0/go.mod h1:Rflh2EJ/++BA2/vY5ao3K6WJRR/bZKsX123aPk+kUtA= +github.com/containerd/go-cni v1.1.3/go.mod h1:Rflh2EJ/++BA2/vY5ao3K6WJRR/bZKsX123aPk+kUtA= github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= github.com/containerd/go-runc v0.0.0-20190911050354-e029b79d8cda/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= github.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328/go.mod h1:PpyHrqVs8FTi9vpyHwPwiNEGaACDxT/N/pLcvMSRA9g= @@ -616,9 +637,11 @@ github.com/containerd/imgcrypt v1.0.1/go.mod h1:mdd8cEPW7TPgNG4FpuP3sGBiQ7Yi/zak github.com/containerd/imgcrypt v1.0.4-0.20210301171431-0ae5c75f59ba/go.mod h1:6TNsg0ctmizkrOgXRNQjAPFWpMYRWuiB6dSF4Pfa5SA= github.com/containerd/imgcrypt v1.1.1-0.20210312161619-7ed62a527887/go.mod h1:5AZJNI6sLHJljKuI9IHnw1pWqo/F0nGDOuR9zgTs7ow= github.com/containerd/imgcrypt v1.1.1/go.mod h1:xpLnwiQmEUJPvQoAapeb2SNCxz7Xr6PJrXQb0Dpc4ms= +github.com/containerd/imgcrypt v1.1.3/go.mod h1:/TPA1GIDXMzbj01yd8pIbQiLdQxed5ue1wb8bP7PQu4= github.com/containerd/nri v0.0.0-20201007170849-eb1350a75164/go.mod h1:+2wGSDGFYfE5+So4M5syatU0N0f0LbWpuqyMi4/BE8c= github.com/containerd/nri v0.0.0-20210316161719-dbaa18c31c14/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY= github.com/containerd/nri v0.1.0/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY= +github.com/containerd/stargz-snapshotter/estargz v0.4.1/go.mod h1:x7Q9dg9QYb4+ELgxmo4gBUeJB0tl5dqH1Sdz0nJU1QM= github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= github.com/containerd/ttrpc v0.0.0-20190828172938-92c8520ef9f8/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= github.com/containerd/ttrpc v0.0.0-20191028202541-4f1b8fe65a5c/go.mod h1:LPm1u0xBw8r8NOKoOdNMeVHSawSsltak+Ihv+etqsE8= @@ -637,11 +660,14 @@ github.com/containerd/zfs v1.0.0/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNR github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= github.com/containernetworking/cni v0.8.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= +github.com/containernetworking/cni v1.0.1/go.mod h1:AKuhXbN5EzmD4yTNtfSsX3tPcmtrBI6QcRV0NiNt15Y= github.com/containernetworking/plugins v0.8.6/go.mod h1:qnw5mN19D8fIwkqW7oHHYDHVlzhJpcY6TQxn/fUyDDM= github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRDjeJr6FLK6vuiUwoH7P8= +github.com/containernetworking/plugins v1.0.1/go.mod h1:QHCfGpaTwYTbbH+nZXKVTxNBDZcxSOplJT5ico8/FLE= github.com/containers/ocicrypt v1.0.1/go.mod h1:MeJDzk1RJHv89LjsH0Sp5KTY3ZYkjXO/C+bKAeWFIrc= github.com/containers/ocicrypt v1.1.0/go.mod h1:b8AOe0YR67uU8OqfVNcznfFpAzu3rdgUV4GP9qXPfu4= github.com/containers/ocicrypt v1.1.1/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B0oB3dj3jFxY= +github.com/containers/ocicrypt v1.1.2/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B0oB3dj3jFxY= github.com/coredns/coredns v1.1.2/go.mod h1:zASH/MVDgR6XZTbxvOnsZfffS+31vg6Ackf/wo1+AM0= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= @@ -650,6 +676,7 @@ github.com/coreos/etcd v3.3.25+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= github.com/coreos/go-iptables v0.5.0/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= +github.com/coreos/go-iptables v0.6.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= github.com/coreos/go-oidc v2.2.1+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= @@ -694,6 +721,7 @@ github.com/crossdock/crossdock-go v0.0.0-20160816171116-049aabb0122b/go.mod h1:v github.com/cucumber/godog v0.8.1/go.mod h1:vSh3r/lM+psC1BPXvdkSEuNjmXfpVqrMGYAElF6hxnA= github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= +github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/cznic/b v0.0.0-20180115125044-35e9bbe41f07/go.mod h1:URriBxXwVq5ijiJ12C7iIZqlA69nTlI+LgI6/pwftG8= github.com/cznic/fileutil v0.0.0-20180108211300-6a051e75936f/go.mod h1:8S58EK26zhXSxzv7NQFpnliaOQsmDUxvoQO3rt154Vg= github.com/cznic/golex v0.0.0-20170803123110-4ab7c5e190e4/go.mod h1:+bmmJDNmKlhWNG+gwWCkaBoTy39Fs+bzRxVBzoTQbIc= @@ -760,6 +788,7 @@ github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwu github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= github.com/dnaeon/go-vcr v1.1.0 h1:ReYa/UBrRyQdant9B4fNHGoCNKw6qh6P0fsdGmZpR7c= github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= +github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY= github.com/docker/distribution v2.6.0-rc.1.0.20170726174610-edc3ab29cdff+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.7.0+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= @@ -768,6 +797,7 @@ github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BU github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v0.7.3-0.20190103212154-2b7e084dc98b/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v0.7.3-0.20190817195342-4760db040282/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v17.12.0-ce-rc1.0.20200706150819-a40b877fbb9e+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v17.12.0-ce-rc1.0.20200916142827-bd33bbf0497b+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v20.10.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= @@ -776,6 +806,7 @@ github.com/docker/docker v20.10.6+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05b github.com/docker/docker v20.10.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v20.10.8+incompatible h1:RVqD337BgQicVCzYrrlhLDWhq6OAD2PJDUg2LsEUvKM= github.com/docker/docker v20.10.8+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y= github.com/docker/go-connections v0.3.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= @@ -940,9 +971,12 @@ github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KE github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= +github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.1/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/stdr v1.2.0/go.mod h1:YkVgnZu1ZjjL7xTxrfm/LLZBfkhTqSR1ydtm6jTKKwI= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= @@ -1144,6 +1178,7 @@ github.com/godbus/dbus v0.0.0-20190402143921-271e53dc4968/go.mod h1:/YcGZj5zSblf github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.7.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gofrs/uuid v2.1.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= @@ -1258,6 +1293,7 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-containerregistry v0.5.1/go.mod h1:Ct15B4yir3PLOP5jsy0GNeYVaIZs/MK/Jz5any1wFW0= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-github/v32 v32.1.0/go.mod h1:rIEpZD9CTDQwDK9GDrtMTycQNA4JU3qBsCizh3q2WCI= github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= @@ -1379,8 +1415,6 @@ github.com/grafana/dskit v0.0.0-20211011144203-3a88ec0b675f h1:FvvSVEbnGeM2bUivG github.com/grafana/dskit v0.0.0-20211011144203-3a88ec0b675f/go.mod h1:uPG2nyK4CtgNDmWv7qyzYcdI+S90kHHRWvHnBtEMBXM= github.com/grafana/go-mssqldb v0.0.0-20210326084033-d0ce3c521036 h1:GplhUk6Xes5JIhUUrggPcPBhOn+eT8+WsHiebvq7GgA= github.com/grafana/go-mssqldb v0.0.0-20210326084033-d0ce3c521036/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= -github.com/grafana/grafana-aws-sdk v0.10.1 h1:Ksguhjx6EuGLN/5Oc7oZoxuDReJ5RxIH99yqSMpLGUs= -github.com/grafana/grafana-aws-sdk v0.10.1/go.mod h1:vFIOHEnY1u5nY0/tge1IHQjPuG6DRKr2ISf/HikUdjE= github.com/grafana/grafana-aws-sdk v0.10.3 h1:nqjK8NfrUyUcAtSjGxnt17ZKjeOMCi62MNKFNagjG6g= github.com/grafana/grafana-aws-sdk v0.10.3/go.mod h1:vFIOHEnY1u5nY0/tge1IHQjPuG6DRKr2ISf/HikUdjE= github.com/grafana/grafana-azure-sdk-go v1.1.0 h1:Gh0fjs7jr4Lp5y+4cjn48U+MQaJeV8i9m1ds/1xszto= @@ -1449,8 +1483,9 @@ github.com/hashicorp/consul/sdk v0.6.0/go.mod h1:fY08Y9z5SvJqevyZNy6WWPXiG3KwBPA github.com/hashicorp/consul/sdk v0.7.0/go.mod h1:fY08Y9z5SvJqevyZNy6WWPXiG3KwBPAvlcdx16zZ0fM= github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-bexpr v0.1.2/go.mod h1:ANbpTX1oAql27TZkKVeW8p1w8NTdnyzPe/0qqPCKohU= github.com/hashicorp/go-checkpoint v0.5.0/go.mod h1:7nfLNL10NsxqO4iWuW6tWW0HjZuDrwkBuEQsVcpCOgg= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= @@ -1474,8 +1509,9 @@ github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9 github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI= github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-plugin v1.0.1/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY= github.com/hashicorp/go-plugin v1.2.2/go.mod h1:F9eH4LrE/ZsRdbwhfjs9k9HoDUwAHnYtXdgmf1AVNs0= github.com/hashicorp/go-plugin v1.4.2/go.mod h1:5fGEH17QVwTTcR0zV7yhDPLLmFX9YSZ38b18Udy6vYQ= @@ -1618,12 +1654,14 @@ github.com/influxdata/telegraf v1.16.3/go.mod h1:fX/6k7qpIqzVPWyeIamb0wN5hbwc0AN github.com/influxdata/toml v0.0.0-20190415235208-270119a8ce65/go.mod h1:zApaNFpP/bTpQItGZNNUMISDMDAnTXu9UqJ4yT3ocz8= github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1:Wbbw6tYNvwa5dlB6304Sd+82Z3f7PmVZHVKU637d4po= github.com/influxdata/wlog v0.0.0-20160411224016-7c63b0a71ef8/go.mod h1:/2NMgWB1DHM1ti/gqhOlg+LJeBVk6FqR5aVGYY0hlwI= +github.com/intel/goresctrl v0.2.0/go.mod h1:+CZdzouYFn5EsxgqAQTEzMfwKwuc0fVdMrT9FCCAVRQ= github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA= +github.com/j-keck/arping v1.0.2/go.mod h1:aJbELhR92bSk7tp79AWM/ftfc90EfEi2bQJrbBFOsPw= github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= @@ -1688,6 +1726,7 @@ github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9Y github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8= github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901/go.mod h1:Z86h9688Y0wesXCyonoVr47MasHilkuLMqGhRZ4Hpak= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= @@ -1820,6 +1859,7 @@ github.com/linode/linodego v0.7.1/go.mod h1:ga11n3ivecUrPCHN0rANxKmfWBJVkOXfLMZi github.com/linode/linodego v0.28.5/go.mod h1:BR0gVkCJffEdIGJSl6bHR80Ty+Uvg/2jkjmrWaFectM= github.com/linode/linodego v0.32.0 h1:IK04cx2b/IwAAd6XLruf1Dl/n3dRXj87Uw/5qo6afVU= github.com/linode/linodego v0.32.0/go.mod h1:BR0gVkCJffEdIGJSl6bHR80Ty+Uvg/2jkjmrWaFectM= +github.com/linuxkit/virtsock v0.0.0-20201010232012-f8cee7dfc7a3/go.mod h1:3r6x7q95whyfWQpmGZTu3gk3v2YkMi05HEzl7Tf7YEo= github.com/lovoo/gcloud-opentracing v0.3.0/go.mod h1:ZFqk2y38kMDDikZPAK7ynTTGuyt17nSPdS3K5e+ZTBY= github.com/lucasb-eyer/go-colorful v1.0.2/go.mod h1:0MS4r+7BZKSJ5mw4/S5MPN+qHFF1fYclkSPilDOKW0s= github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= @@ -1891,6 +1931,8 @@ github.com/mattn/go-runewidth v0.0.8/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= +github.com/mattn/go-shellwords v1.0.6/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= +github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.14.7 h1:fxWBnXkxfM6sRiuH3bqJ4CfzZojMOLVc0UTsTglEghA= @@ -1902,6 +1944,7 @@ github.com/matttproud/golang_protobuf_extensions v1.0.0/go.mod h1:D8He9yQNgCq6Z5 github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY= github.com/mdlayher/apcupsd v0.0.0-20200608131503-2bf01da7bf1b/go.mod h1:WYK/Z/aXq9cbMFIL5ihcA4sX/r/3/WCas/Qvs/2fXcA= github.com/mdlayher/genetlink v1.0.0/go.mod h1:0rJ0h4itni50A86M2kHcgS85ttZazNt7a8H2a2cw0Gc= github.com/mdlayher/netlink v0.0.0-20190409211403-11939a169225/go.mod h1:eQB3mZE4aiYnlUsyGGCOpPETfdQq4Jhsgf1fk3cwQaA= @@ -1974,9 +2017,13 @@ github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQ github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= +github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= +github.com/moby/sys/signal v0.6.0/go.mod h1:GQ6ObYZfqacOwTtlXvcmh9A26dVRul/hbOZn88Kg8Tg= github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ= +github.com/moby/sys/symlink v0.2.0/go.mod h1:7uZVF2dqJjG/NsClqul95CqKOBRQyYSNnJ6BMgR/gFs= github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc= +github.com/moby/term v0.0.0-20210610120745-9d4ed1856297/go.mod h1:vgPCkQMyxTZ7IDy8SXRufE172gr8+K/JE/7hHFxHW3A= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -2058,6 +2105,7 @@ github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+ github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= @@ -2073,6 +2121,7 @@ github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoT github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= +github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0= github.com/onsi/gomega v1.16.0 h1:6gjqkI8iiRHMvdccRJM8rVKjCWk6ZIm6FTm3ddIe4/c= github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= @@ -2085,6 +2134,7 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8 github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.0.0/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/opencontainers/image-spec v1.0.2-0.20211117181255-693428a734f5/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM= github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= @@ -2093,6 +2143,7 @@ github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0= github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0= +github.com/opencontainers/runc v1.1.0/go.mod h1:Tj1hFw6eFWp/o33uxGf5yF2BX5yz2Z6iptFpuvbbKqc= github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.2-0.20190207185410-29686dbc5559/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= @@ -2103,6 +2154,7 @@ github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mo github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE= github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo= github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8= +github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= github.com/opentracing-contrib/go-grpc v0.0.0-20180928155321-4b5a12d3ff02/go.mod h1:JNdpVEzCpXBgIiv4ds+TzhN1hrtxq6ClLrTlT9OQRSc= github.com/opentracing-contrib/go-grpc v0.0.0-20191001143057-db30781987df/go.mod h1:DYR5Eij8rJl8h7gblRrOZ8g0kW1umSpKqYIBTgeDtLo= github.com/opentracing-contrib/go-grpc v0.0.0-20210225150812-73cb765af46e h1:4cPxUYdgaGzZIT5/j0IfqOrrXmq6bG8AwvwisMXpdrg= @@ -2354,6 +2406,7 @@ github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFo github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= github.com/safchain/ethtool v0.0.0-20200218184317-f459e2d13664/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= +github.com/safchain/ethtool v0.0.0-20210803160452-9aa261dae9b1/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig= github.com/samuel/go-zookeeper v0.0.0-20180130194729-c4fab1ac1bec/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/samuel/go-zookeeper v0.0.0-20190810000440-0ceca61e4d75/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= @@ -2368,11 +2421,14 @@ github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b/go.mod h1:dA0hQrY github.com/scaleway/scaleway-sdk-go v1.0.0-beta.7.0.20210223165440-c65ae3540d44 h1:3egqo0Vut6daANFm7tOXdNAa8v5/uLU+sgCJrc88Meo= github.com/scaleway/scaleway-sdk-go v1.0.0-beta.7.0.20210223165440-c65ae3540d44/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8= github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= +github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= +github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U= github.com/sean-/conswriter v0.0.0-20180208195008-f5ae3917a627/go.mod h1:7zjs06qF79/FKAJpBvFx3P8Ww4UTIMAe+lpNXDHziac= github.com/sean-/pager v0.0.0-20180208200047-666be9bf53b5/go.mod h1:BeybITEsBEg6qbIiqJ6/Bqeq25bCLbL7YFmpaFfJDuM= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= +github.com/seccomp/libseccomp-golang v0.9.2-0.20210429002308-3879420cc921/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= github.com/securego/gosec v0.0.0-20200203094520-d13bb6d2420c/go.mod h1:gp0gaHj0WlmPh9BdsTmo1aq6C27yIPWdxCKGFGdVKBE= github.com/segmentio/asm v1.1.0/go.mod h1:4EUJGaKsB8ImLUwOGORVsNd9vTRDeh44JGsY4aKp5I4= github.com/segmentio/asm v1.1.1 h1:WzUpP9BRnRgoP+v8qywthpSe9U5KLq1uDGdJBEcSeQo= @@ -2449,6 +2505,7 @@ github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tL github.com/spf13/cobra v0.0.7/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= +github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= github.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi9V4= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= @@ -2528,9 +2585,11 @@ github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZF github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20200427203606-3cfed13b9966/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tonistiigi/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:Q5IRRDY+cjIaiOjTAnXN5LKQV5MPqVx5ofQn85Jy5Yw= github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= +github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/ua-parser/uap-go v0.0.0-20211112212520-00c877edfe0f h1:A+MmlgpvrHLeUP8dkBVn4Pnf5Bp5Yk2OALm7SEJLLE8= github.com/ua-parser/uap-go v0.0.0-20211112212520-00c877edfe0f/go.mod h1:OBcG9bn7sHtXgarhUEb3OfCnNsgtGnkVf41ilSZ3K3E= github.com/uber-go/tally v3.3.15+incompatible/go.mod h1:YDTIBxdXyOU/sCWilKB4bgyufu1cEi0jdVnRdxvjnmU= @@ -2578,9 +2637,11 @@ github.com/vishvananda/netlink v0.0.0-20171020171820-b2de5d10e38e/go.mod h1:+SR5 github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho= +github.com/vishvananda/netlink v1.1.1-0.20210330154013-f5de75959ad5/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho= github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI= github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= +github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= github.com/vjeantet/grok v1.0.0/go.mod h1:/FWYEVYekkm+2VjcFmO9PufDU5FgXHUz9oy2EGqmQBo= github.com/vmware/govmomi v0.18.0/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= github.com/vmware/govmomi v0.19.0/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= @@ -2676,8 +2737,11 @@ go.etcd.io/etcd/client/v3 v3.5.0-alpha.0/go.mod h1:wKt7jgDgf/OfKiYmCq5WFGxOFAkVM go.etcd.io/etcd/client/v3 v3.5.0-alpha.0.0.20210225194612-fa82d11a958a/go.mod h1:wKt7jgDgf/OfKiYmCq5WFGxOFAkVMLxiiXgLDFhECr8= go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0= go.etcd.io/etcd/pkg/v3 v3.5.0-alpha.0/go.mod h1:tV31atvwzcybuqejDoY3oaNRTtlD2l/Ot78Pc9w7DMY= +go.etcd.io/etcd/pkg/v3 v3.5.0/go.mod h1:UzJGatBQ1lXChBkQF0AuAtkRQMYnHubxAEYIrC3MSsE= go.etcd.io/etcd/raft/v3 v3.5.0-alpha.0/go.mod h1:FAwse6Zlm5v4tEWZaTjmNhe17Int4Oxbu7+2r0DiD3w= +go.etcd.io/etcd/raft/v3 v3.5.0/go.mod h1:UFOHSIvO/nKwd4lhkwabrTD3cqW5yVyYYf/KlD00Szc= go.etcd.io/etcd/server/v3 v3.5.0-alpha.0.0.20210225194612-fa82d11a958a/go.mod h1:tsKetYpt980ZTpzl/gb+UOJj9RkIyCb1u4wjzMg90BQ= +go.etcd.io/etcd/server/v3 v3.5.0/go.mod h1:3Ah5ruV+M+7RZr0+Y/5mNLwC+eQlni+mQmOVdCRJoS4= go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.0.4/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= @@ -2709,28 +2773,48 @@ go.opentelemetry.io/collector v0.31.0 h1:Lxrsl/fhYQTcsrAOwklQpKi8T+ghxLEmmUjFqey go.opentelemetry.io/collector v0.31.0/go.mod h1:A9vKmEa2MI/vJXNUoRinq9w25ZMmxWJLYXYELHkBEw0= go.opentelemetry.io/collector/model v0.31.0 h1:IgMOkSBd/n/gV4EQQ1nJ+/ylddOlqTfMGjku91yC0d8= go.opentelemetry.io/collector/model v0.31.0/go.mod h1:PcHNnM+RUl0uD8VkSn93PO78N7kQYhfqpI/eki57pl4= +go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc= go.opentelemetry.io/contrib v0.21.0/go.mod h1:EH4yDYeNoaTqn/8yCWQmfNB78VHfGX2Jt2bvnvzBlGM= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0/go.mod h1:oVGt1LRbBOBq1A5BQLlUg9UaU/54aiHw8cgjV3aWZ/E= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.21.0/go.mod h1:Vm5u/mtkj1OMhtao0v+BGo2LUoLCgHYXvRmj0jWITlE= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.28.0/go.mod h1:vEhqr0m4eTc+DWxfsXoXue2GBgV2uUwVznkGIHW/e5w= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0/go.mod h1:2AboqHi0CiIZU0qwhtUfCYD1GeUzvvIXWNkhDt7ZMG4= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.21.0/go.mod h1:JQAtechjxLEL81EjmbRwxBq/XEzGaHcsPuDHAx54hg4= go.opentelemetry.io/contrib/zpages v0.0.0-20210722161726-7668016acb73/go.mod h1:NAkejuYm41lpyL43Fu1XdnCOYxN5NVV80/MJ03JQ/X8= go.opentelemetry.io/otel v0.11.0/go.mod h1:G8UCk+KooF2HLkgo8RHX9epABH/aRGYET7gQOqBVdB0= +go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= go.opentelemetry.io/otel v1.0.0-RC1/go.mod h1:x9tRa9HK4hSSq7jf2TKbqFbtt58/TGk0f9XiEYISI1I= go.opentelemetry.io/otel v1.0.0/go.mod h1:AjRVh9A5/5DE7S+mZtTR6t8vpKKryam+0lREnfmS4cg= +go.opentelemetry.io/otel v1.3.0/go.mod h1:PWIKzi6JCp7sM0k9yZ43VX+T345uNbAkDKwHVjb2PTs= go.opentelemetry.io/otel v1.6.3 h1:FLOfo8f9JzFVFVyU+MSRJc2HdEAXQgm7pIv2uFKRSZE= go.opentelemetry.io/otel v1.6.3/go.mod h1:7BgNga5fNlF/iZjG06hM3yofffp0ofKCDwSXx1GC4dI= go.opentelemetry.io/otel/exporters/jaeger v1.0.0 h1:cLhx8llHw02h5JTqGqaRbYn+QVKHmrzD9vEbKnSPk5U= go.opentelemetry.io/otel/exporters/jaeger v1.0.0/go.mod h1:q10N1AolE1JjqKrFJK2tYw0iZpmX+HBaXBtuCzRnBGQ= +go.opentelemetry.io/otel/exporters/otlp v0.20.0/go.mod h1:YIieizyaN77rtLJra0buKiNBOm9XQfkPEKBeuhoMwAM= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.3.0/go.mod h1:VpP4/RMn8bv8gNo9uK7/IMY4mtWLELsS+JIP0inH0h4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.3.0/go.mod h1:hO1KLR7jcKaDDKDkvI9dP/FIhpmna5lkqPUQdEjFAM8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.3.0/go.mod h1:keUU7UfnwWTWpJ+FWnyqmogPa82nuU5VUANFq49hlMY= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.3.0/go.mod h1:QNX1aly8ehqqX1LEa6YniTU7VY9I6R3X/oPxhGdTceE= go.opentelemetry.io/otel/internal/metric v0.21.0/go.mod h1:iOfAaY2YycsXfYD4kaRSbLx2LKmfpKObWBEv9QK5zFo= +go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU= go.opentelemetry.io/otel/metric v0.21.0/go.mod h1:JWCt1bjivC4iCrz/aCrM1GSw+ZcvY44KCbaeeRhzHnc= +go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw= go.opentelemetry.io/otel/oteltest v1.0.0-RC1/go.mod h1:+eoIG0gdEOaPNftuy1YScLr1Gb4mL/9lpDkZ0JjMRq4= +go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc= go.opentelemetry.io/otel/sdk v1.0.0-RC1/go.mod h1:kj6yPn7Pgt5ByRuwesbaWcRLA+V7BSDg3Hf8xRvsvf8= -go.opentelemetry.io/otel/sdk v1.0.0 h1:BNPMYUONPNbLneMttKSjQhOTlFLOD9U22HNG1KrIN2Y= go.opentelemetry.io/otel/sdk v1.0.0/go.mod h1:PCrDHlSy5x1kjezSdL37PhbFUMjrsLRshJ2zCzeXwbM= +go.opentelemetry.io/otel/sdk v1.3.0 h1:3278edCoH89MEJ0Ky8WQXVmDQv3FX4ZJ3Pp+9fJreAI= +go.opentelemetry.io/otel/sdk v1.3.0/go.mod h1:rIo4suHNhQwBIPg9axF8V9CA72Wz2mKF1teNrup8yzs= +go.opentelemetry.io/otel/sdk/export/metric v0.20.0/go.mod h1:h7RBNMsDJ5pmI1zExLi+bJK+Dr8NQCh0qGhm1KDnNlE= +go.opentelemetry.io/otel/sdk/metric v0.20.0/go.mod h1:knxiS8Xd4E/N+ZqKmUPf3gTTZ4/0TjTXukfxjzSTpHE= +go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= go.opentelemetry.io/otel/trace v1.0.0-RC1/go.mod h1:86UHmyHWFEtWjfWPSbu0+d0Pf9Q6e1U+3ViBOc+NXAg= go.opentelemetry.io/otel/trace v1.0.0/go.mod h1:PXTWqayeFUlJV1YDNhsJYB184+IvAH814St6o6ajzIs= +go.opentelemetry.io/otel/trace v1.3.0/go.mod h1:c/VDhno8888bvQYmbYLqe41/Ldmr/KKunbvWM4/fEjk= go.opentelemetry.io/otel/trace v1.6.3 h1:IqN4L+5b0mPNjdXIiZ90Ni4Bl5BRkDQywePLWemd9bc= go.opentelemetry.io/otel/trace v1.6.3/go.mod h1:GNJQusJlUgZl9/TQBPKU/Y/ty+0iVB5fjhKeJGZPGFs= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.opentelemetry.io/proto/otlp v0.11.0/go.mod h1:QpEjXPrNQzrFDZgoTo49dgHR9RYRSrg3NAKnUGl9YpQ= go.starlark.net v0.0.0-20200901195727-6e684ef5eeee/go.mod h1:f0znQkUKRrkk36XxWbGjMqQM8wGv/xHBVE2qc3B5oFU= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -2745,8 +2829,9 @@ go.uber.org/automaxprocs v1.2.0/go.mod h1:YfO3fm683kQpzETxlTGZhGIVmXAhaw3gxeBADb go.uber.org/automaxprocs v1.4.0/go.mod h1:/mTEdr7LvHhs0v7mjdxDreTz1OG5zdZGqgOnhWiR/+Q= go.uber.org/goleak v1.0.0/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= -go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= +go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= @@ -2969,17 +3054,21 @@ golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210903162142-ad29c8ab022f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211020060615-d418f374d309/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220107192237-5cfca573fb4d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220401154927-543a649e0bdd h1:zYlwaUHTmxuf6H7hwO2dgwqozQmH7zf4x+/qql4oVWc= golang.org/x/net v0.0.0-20220401154927-543a649e0bdd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220421235706-1d1ef9303861 h1:yssD99+7tqHWO5Gwh81phT+67hg+KttniBr6UnEXOY8= +golang.org/x/net v0.0.0-20220421235706-1d1ef9303861/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -3169,14 +3258,18 @@ golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210903071746-97244b99971b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211110154304-99a53858aa08/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -3190,11 +3283,13 @@ golang.org/x/sys v0.0.0-20220204135822-1c1b9b1eba6a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f h1:rlezHXNlxYWvBCzNses9Dlc7nGFaNMJeqLolcmQSSZY= golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150 h1:xHms4gcpe1YE7A3yIllJXP16CMAGuqwO2lX1mTyyRRc= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -3257,6 +3352,7 @@ golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190706070813-72ffa07ba3db/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= golang.org/x/tools v0.0.0-20190813034749-528a2984e271/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -3299,6 +3395,7 @@ golang.org/x/tools v0.0.0-20200317043434-63da46f3035e/go.mod h1:Sl4aGygMT6LrqrWc golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200422205258-72e4a01eba43/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200509030707-2212a7e161a5/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200513201620-d5fe73897c97/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= @@ -3306,6 +3403,7 @@ golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200522201501-cb1345f3a375/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200603131246-cc40288be839/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200612220849-54c614fe050c/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200616133436-c1934b75d054/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200710042808-f1c4188a97a1/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= @@ -3316,6 +3414,7 @@ golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200822203824-307de81be3f4/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20200916195026-c9a70fc28ce3/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/tools v0.0.0-20201014170642-d1624618ad65/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/tools v0.0.0-20201020161133-226fd2f889ca/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= @@ -3460,6 +3559,7 @@ google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200527145253-8367513e4ece/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200603110839-e855014d5736/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200710124503-20a17af7bd0e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= @@ -3526,8 +3626,9 @@ google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2 google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= -google.golang.org/genproto v0.0.0-20220401170504-314d38edb7de h1:9Ti5SG2U4cAcluryUo/sFay3TQKoxiFMfaT0pbizU7k= google.golang.org/genproto v0.0.0-20220401170504-314d38edb7de/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3 h1:SeX3QUcBj3fciwnfPT9kt5gBhFy/FCZtYZ+I/RB8agc= +google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= @@ -3570,6 +3671,7 @@ google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9K google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k= google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= @@ -3700,8 +3802,9 @@ k8s.io/api v0.20.5/go.mod h1:FQjAceXnVaWDeov2YUWhOb6Yt+5UjErkp6UO3nczO1Y= k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8= k8s.io/api v0.21.0/go.mod h1:+YbrhBBGgsxbF6o6Kj4KJPJnBmAKuXDeS3E18bgHNVU= k8s.io/api v0.21.1/go.mod h1:FstGROTmsSHBarKc8bylzXih8BLNYTiS3TZcsoEDg2s= -k8s.io/api v0.22.1 h1:ISu3tD/jRhYfSW8jI/Q1e+lRxkR7w9UwQEZ7FgslrwY= k8s.io/api v0.22.1/go.mod h1:bh13rkTp3F1XEaLGykbyRD2QaTTzPm0e/BMd8ptFONY= +k8s.io/api v0.22.5 h1:xk7C+rMjF/EGELiD560jdmwzrB788mfcHiNbMQLIVI8= +k8s.io/api v0.22.5/go.mod h1:mEhXyLaSD1qTOf40rRiKXkc+2iCem09rWLlFwhCEiAs= k8s.io/apimachinery v0.0.0-20190809020650-423f5d784010/go.mod h1:Waf/xTS2FGRrgXCkO5FP3XxTOWh0qLf2QhL1qFZZ/R8= k8s.io/apimachinery v0.0.0-20191115015347-3c7067801da2/go.mod h1:dXFS2zaQR8fyzuvRdJDHw2Aerij/yVGJSre0bZQSVJA= k8s.io/apimachinery v0.16.9/go.mod h1:Xk2vD2TRRpuWYLQNM6lT9R7DSFZUYG03SarNkbGrnKE= @@ -3720,22 +3823,29 @@ k8s.io/apimachinery v0.20.5/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRp k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc= k8s.io/apimachinery v0.21.0/go.mod h1:jbreFvJo3ov9rj7eWT7+sYiRx+qZuCYXwWT1bcDswPY= k8s.io/apimachinery v0.21.1/go.mod h1:jbreFvJo3ov9rj7eWT7+sYiRx+qZuCYXwWT1bcDswPY= -k8s.io/apimachinery v0.22.1 h1:DTARnyzmdHMz7bFWFDDm22AM4pLWTQECMpRTFu2d2OM= k8s.io/apimachinery v0.22.1/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0= +k8s.io/apimachinery v0.22.5 h1:cIPwldOYm1Slq9VLBRPtEYpyhjIm1C6aAMAoENuvN9s= +k8s.io/apimachinery v0.22.5/go.mod h1:xziclGKwuuJ2RM5/rSFQSYAj0zdbci3DH8kj+WvyN0U= k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU= k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM= k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q= +k8s.io/apiserver v0.22.5/go.mod h1:s2WbtgZAkTKt679sYtSudEQrTGWUSQAPe6MupLnlmaQ= k8s.io/client-go v0.22.1 h1:jW0ZSHi8wW260FvcXHkIa0NLxFBQszTlhiAVsU5mopw= k8s.io/client-go v0.22.1/go.mod h1:BquC5A4UOo4qVDUtoc04/+Nxp1MeHcVc1HJm1KmG8kk= +k8s.io/code-generator v0.19.7/go.mod h1:lwEq3YnLYb/7uVXLorOJfxg+cUu2oihFhHZ0n9NIla0= k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk= k8s.io/component-base v0.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI= k8s.io/component-base v0.20.6/go.mod h1:6f1MPBAeI+mvuts3sIdtpjljHWBQ2cIy38oBIWMYnrM= +k8s.io/component-base v0.22.5/go.mod h1:VK3I+TjuF9eaa+Ln67dKxhGar5ynVbwnGrUiNF4MqCI= k8s.io/cri-api v0.17.3/go.mod h1:X1sbHmuXhwaHs9xxYffLqJogVsnI+f6cPRcgPel7ywM= k8s.io/cri-api v0.20.1/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= k8s.io/cri-api v0.20.4/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= k8s.io/cri-api v0.20.6/go.mod h1:ew44AjNXwyn1s0U4xCKGodU7J1HzBeZ1MpGrpa5r8Yc= +k8s.io/cri-api v0.23.1/go.mod h1:REJE3PSU0h/LOV1APBrupxrEJqnoxZC8KWzkBUHwrK4= k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20200428234225-8167cfdcfc14/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.1/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= @@ -3749,8 +3859,9 @@ k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.5.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= -k8s.io/klog/v2 v2.10.0 h1:R2HDMDJsHVTHA2n4RjwbeYXdOcBymXdX/JRb1v0VGhE= k8s.io/klog/v2 v2.10.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= +k8s.io/klog/v2 v2.30.0 h1:bUO6drIvCIsvZ/XFgfxoGFQU/a4Qkh0iAlvUR7vlHJw= +k8s.io/klog/v2 v2.30.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/kube-openapi v0.0.0-20190709113604-33be087ad058/go.mod h1:nfDlWeOsu3pUf4yWGL+ERqohP4YsZcBJXWMK+gkzOA4= k8s.io/kube-openapi v0.0.0-20190722073852-5e22f3d471e6/go.mod h1:RZvgC8MSN6DjiMV6oIfEE9pDL9CYXokkfaCKZeHm3nc= k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= @@ -3761,13 +3872,16 @@ k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE= k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= +k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= k8s.io/utils v0.0.0-20190809000727-6c36bc71fc4a/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= k8s.io/utils v0.0.0-20191114200735-6ca3b61696b6/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= k8s.io/utils v0.0.0-20200414100711-2df71ebbae66/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20210707171843-4b05e18ac7d9 h1:imL9YgXQ9p7xmPzHFm/vVd/cF78jad+n4wK1ABwYtMM= k8s.io/utils v0.0.0-20210707171843-4b05e18ac7d9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b h1:wxEMGetGMur3J1xuGLQY7GEQYg9bZxKn3tKo5k/eYcs= +k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM= modernc.org/httpfs v1.0.0/go.mod h1:BSkfoMUcahSijQD5J/Vu4UMOxzmEf5SNRwyXC4PJBEw= modernc.org/libc v1.3.1/go.mod h1:f8sp9GAfEyGYh3lsRIKtBh/XwACdFvGznxm6GJmQvXk= @@ -3782,6 +3896,7 @@ rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.22/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e h1:4Z09Hglb792X0kfOBBJUPFEyvVfQWrYT/l8h5EKA6JQ= sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= sigs.k8s.io/structured-merge-diff/v2 v2.0.1/go.mod h1:Wb7vfKAodbKgf6tn1Kl0VvGj7mRH6DGaRcixXEJXTsE= From 277a83215c1e20ff8c93768f93edf92d60deee5f Mon Sep 17 00:00:00 2001 From: Ashley Harrison Date: Fri, 22 Apr 2022 16:00:37 +0100 Subject: [PATCH 100/120] Use jest.fakeTimers instead of mocking Date.now (#48121) --- .../inspect/VariablesUnknownTable.test.tsx | 38 ++++++++++++++----- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/public/app/features/variables/inspect/VariablesUnknownTable.test.tsx b/public/app/features/variables/inspect/VariablesUnknownTable.test.tsx index 161f12f03bd..e6dd04e8ba6 100644 --- a/public/app/features/variables/inspect/VariablesUnknownTable.test.tsx +++ b/public/app/features/variables/inspect/VariablesUnknownTable.test.tsx @@ -1,12 +1,17 @@ import { render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import { UserEvent } from '@testing-library/user-event/dist/types/setup'; import React from 'react'; import * as runtime from '@grafana/runtime'; import { customBuilder } from '../shared/testing/builders'; -import { VariablesUnknownTable, VariablesUnknownTableProps } from './VariablesUnknownTable'; +import { + SLOW_VARIABLES_EXPANSION_THRESHOLD, + VariablesUnknownTable, + VariablesUnknownTableProps, +} from './VariablesUnknownTable'; import * as utils from './utils'; import { UsagesToNetwork } from './utils'; @@ -100,25 +105,40 @@ describe('VariablesUnknownTable', () => { }); describe('but when the unknown processing takes a while', () => { - const origDateNow = Date.now; + let user: UserEvent; + + beforeEach(() => { + jest.useFakeTimers(); + // Need to use delay: null here to work with fakeTimers + // see https://github.com/testing-library/user-event/issues/833 + user = userEvent.setup({ delay: null }); + }); afterEach(() => { - Date.now = origDateNow; + jest.useRealTimers(); }); it('then it should report slow expansion', async () => { const variable = customBuilder().withId('Renamed Variable').withName('Renamed Variable').build(); const usages = [{ variable, nodes: [], edges: [], showGraph: false }]; - const { reportInteractionSpy } = await getTestContext({}, usages); - const dateNowStart = 1000; - const dateNowStop = 2000; - Date.now = jest.fn().mockReturnValueOnce(dateNowStart).mockReturnValue(dateNowStop); + const { getUnknownsNetworkSpy, reportInteractionSpy } = await getTestContext({}, usages); + getUnknownsNetworkSpy.mockImplementation(() => { + return new Promise((resolve) => { + setTimeout(() => { + resolve(usages); + }, SLOW_VARIABLES_EXPANSION_THRESHOLD); + }); + }); - await userEvent.click(screen.getByRole('heading', { name: /renamed or missing variables/i })); + await user.click(screen.getByRole('heading', { name: /renamed or missing variables/i })); + + jest.advanceTimersByTime(SLOW_VARIABLES_EXPANSION_THRESHOLD); // make sure we report the interaction for slow expansion await waitFor(() => - expect(reportInteractionSpy).toHaveBeenCalledWith('Slow unknown variables expansion', { elapsed: 1000 }) + expect(reportInteractionSpy).toHaveBeenCalledWith('Slow unknown variables expansion', { + elapsed: expect.any(Number), + }) ); }); }); From 7dc28d4083df97430257c10cca32ab9c0adcde3a Mon Sep 17 00:00:00 2001 From: owensmallwood Date: Fri, 22 Apr 2022 09:32:00 -0600 Subject: [PATCH 101/120] Adds replace directive for tidwall/gjson (#48083) * Adds replace directive for tidwall/gjson * uses more recent version of gjson --- go.mod | 2 ++ 1 file changed, 2 insertions(+) diff --git a/go.mod b/go.mod index dd8a6d450ad..55c4cabade7 100644 --- a/go.mod +++ b/go.mod @@ -301,6 +301,8 @@ replace github.com/hashicorp/consul => github.com/hashicorp/consul v1.10.2 replace github.com/gin-gonic/gin => github.com/gin-gonic/gin v1.7.7 +replace github.com/tidwall/gjson => github.com/tidwall/gjson v1.14.1 + // Upgraded to fix CVE-2020-26066. This can be removed when go.opentelemetry.io/collector and github.com/influxdata/telegraf are upgraded // github.com/tidwall/match v1.0.1 should not be used. replace github.com/tidwall/match => github.com/tidwall/match v1.1.1 From a7f02094b1c99238639bbdbc485cdf0287b82c38 Mon Sep 17 00:00:00 2001 From: Ashley Harrison Date: Fri, 22 Apr 2022 17:21:52 +0100 Subject: [PATCH 102/120] Navigation: Add scroll indicators (#48115) * Attach nav item menus to a portal that's a sibling of the chevron to prevent incorrect stacking * add scrollbar to navbar * Make clickable area of grafana logo full size * hide vertical track as well * initial attempt at a scroll overlay * fix indentation * Extract into a separate component * Add arrows * fix unit tests * Fix imports in new component * add comment --- .../NavBar/Next/NavBarNext.test.tsx | 11 ++ .../components/NavBar/Next/NavBarNext.tsx | 7 +- .../NavBar/Next/NavBarScrollContainer.tsx | 130 ++++++++++++++++++ 3 files changed, 145 insertions(+), 3 deletions(-) create mode 100644 public/app/core/components/NavBar/Next/NavBarScrollContainer.tsx diff --git a/public/app/core/components/NavBar/Next/NavBarNext.test.tsx b/public/app/core/components/NavBar/Next/NavBarNext.test.tsx index 5d0788750b9..9c3c96f4de1 100644 --- a/public/app/core/components/NavBar/Next/NavBarNext.test.tsx +++ b/public/app/core/components/NavBar/Next/NavBarNext.test.tsx @@ -36,6 +36,17 @@ const setup = () => { }; describe('Render', () => { + beforeEach(() => { + // IntersectionObserver isn't available in test environment + const mockIntersectionObserver = jest.fn(); + mockIntersectionObserver.mockReturnValue({ + observe: () => null, + unobserve: () => null, + disconnect: () => null, + }); + window.IntersectionObserver = mockIntersectionObserver; + }); + it('should render component', async () => { setup(); const sidemenu = await screen.findByTestId('sidemenu'); diff --git a/public/app/core/components/NavBar/Next/NavBarNext.tsx b/public/app/core/components/NavBar/Next/NavBarNext.tsx index 4e9992e98d7..1b97427d1a4 100644 --- a/public/app/core/components/NavBar/Next/NavBarNext.tsx +++ b/public/app/core/components/NavBar/Next/NavBarNext.tsx @@ -7,7 +7,7 @@ import { useLocation } from 'react-router-dom'; import { GrafanaTheme2, NavModelItem, NavSection } from '@grafana/data'; import { config, locationService } from '@grafana/runtime'; -import { CustomScrollbar, Icon, IconName, useTheme2 } from '@grafana/ui'; +import { Icon, IconName, useTheme2 } from '@grafana/ui'; import { Branding } from 'app/core/components/Branding/Branding'; import { getKioskMode } from 'app/core/navigation/kiosk'; import { KioskMode, StoreState } from 'app/types'; @@ -20,6 +20,7 @@ import NavBarItem from './NavBarItem'; import { NavBarItemWithoutMenu } from './NavBarItemWithoutMenu'; import { NavBarMenu } from './NavBarMenu'; import { NavBarMenuPortalContainer } from './NavBarMenuPortalContainer'; +import { NavBarScrollContainer } from './NavBarScrollContainer'; import { NavBarToggle } from './NavBarToggle'; const onOpenSearch = () => { @@ -103,7 +104,7 @@ export const NavBarNext = React.memo(() => { - + @@ -130,7 +131,7 @@ export const NavBarNext = React.memo(() => { {link.img && {`${link.text}} ))} - + {configItems.map((link, index) => ( { + const [showScrollTopIndicator, setShowTopScrollIndicator] = useState(false); + const [showScrollBottomIndicator, setShowBottomScrollIndicator] = useState(false); + const scrollTopMarker = useRef(null); + const scrollBottomMarker = useRef(null); + const theme = useTheme2(); + const styles = getStyles(theme); + + // Here we observe the top and bottom markers to determine if we should show the scroll indicators + useEffect(() => { + const intersectionObserver = new IntersectionObserver((entries) => { + entries.forEach((entry) => { + if (entry.target === scrollTopMarker.current) { + setShowTopScrollIndicator(!entry.isIntersecting); + } else if (entry.target === scrollBottomMarker.current) { + setShowBottomScrollIndicator(!entry.isIntersecting); + } + }); + }); + [scrollTopMarker, scrollBottomMarker].forEach((ref) => { + if (ref.current) { + intersectionObserver.observe(ref.current); + } + }); + return () => intersectionObserver.disconnect(); + }, []); + + return ( + +
      + +
      +
      +
      + {children} +
      +
      +
      + +
      +
      + ); +}; + +NavBarScrollContainer.displayName = 'NavBarScrollContainer'; + +const getStyles = (theme: GrafanaTheme2) => ({ + 'scrollTopMarker, scrollBottomMarker': css({ + height: theme.spacing(1), + left: 0, + position: 'absolute', + pointerEvents: 'none', + right: 0, + }), + scrollTopMarker: css({ + top: 0, + }), + scrollBottomMarker: css({ + bottom: 0, + }), + scrollContent: css({ + position: 'relative', + }), + // override the scroll container position so that the scroll indicators + // are positioned at the top and bottom correctly. + // react-custom-scrollbars doesn't provide any way for us to hook in nicely, + // so we have to override with !important. feelsbad. + scrollContainer: css` + .scrollbar-view { + position: static !important; + } + `, + scrollTopIndicator: css({ + background: `linear-gradient(0deg, transparent, ${theme.colors.background.canvas})`, + height: theme.spacing(6), + left: 0, + opacity: 0, + pointerEvents: 'none', + position: 'absolute', + right: 0, + top: 0, + transition: theme.transitions.create('opacity'), + zIndex: theme.zIndex.sidemenu, + }), + scrollBottomIndicator: css({ + background: `linear-gradient(0deg, ${theme.colors.background.canvas}, transparent)`, + bottom: 0, + height: theme.spacing(6), + left: 0, + opacity: 0, + pointerEvents: 'none', + position: 'absolute', + right: 0, + transition: theme.transitions.create('opacity'), + zIndex: theme.zIndex.sidemenu, + }), + scrollIndicatorVisible: css({ + opacity: 1, + }), + scrollTopIcon: css({ + left: '50%', + position: 'absolute', + top: 0, + transform: 'translateX(-50%)', + }), + scrollBottomIcon: css({ + bottom: 0, + left: '50%', + position: 'absolute', + transform: 'translateX(-50%)', + }), +}); From f915767fdc0dfa4f7d86e593315e28166ba088fa Mon Sep 17 00:00:00 2001 From: achatterjee-grafana <70489351+achatterjee-grafana@users.noreply.github.com> Date: Fri, 22 Apr 2022 12:44:11 -0400 Subject: [PATCH 103/120] Update what's new with correct image link (#48133) --- docs/sources/whatsnew/whats-new-in-v8-5.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/sources/whatsnew/whats-new-in-v8-5.md b/docs/sources/whatsnew/whats-new-in-v8-5.md index 997091d850e..0e783ec44ff 100644 --- a/docs/sources/whatsnew/whats-new-in-v8-5.md +++ b/docs/sources/whatsnew/whats-new-in-v8-5.md @@ -52,7 +52,7 @@ The Bar gauge panel now supports scrolling to support displaying large datasets {{< figure src="/static/img/docs/bar-gauge-panel/vertical-view-8-5.png" max-width="400px" caption="Vertical view" >}} -{{< figure src="/static/img/docs/bar-gauge-panel/horizontal-view-8-5.png" max-width="400px" caption="Horizontal view" >}} +{{< figure src="/static/img/docs/bar-gauge-panel/horizontal-8-5.png" max-width="400px" caption="Horizontal view" >}} ## Transformations @@ -111,10 +111,14 @@ This feature is behind the `explore2Dashboard` feature toggle and is enabled by Check the Grafana Enterprise / Security section below for more details, including how to enable this beta feature; we’ve implemented [fine-grained access control](https://grafana.com/docs/grafana/latest/enterprise/access-control/) for alerting rules, notification policies, and contact points in [Grafana Enterprise](https://grafana.com/docs/grafana/latest/enterprise/). You can turn on fine-grained access control using the `accesscontrol` [feature toggle](https://grafana.com/docs/grafana/latest/enterprise/access-control/#enable-fine-grained-access-control), or by [reaching out to our support team](https://grafana.com/orgs/raintank/tickets#) for early access if you use Grafana Cloud. For more information on fine-grained access control, visit our [docs](https://grafana.com/docs/grafana/latest/enterprise/access-control/). +{{< figure src="/static/img/docs/enterprise/fine-grained-access-control-8-5.png" max-width="400px" caption="Fine grained access control" >}} + ### Control access to dashboards, folders, and annotations (beta) You can now use fine-grained access control to manage which specific users, teams, and roles can create, read, update, or delete dashboards, folders, or annotations. These are the latest services to incorporate fine-grained access control, which helps you dial in the specific access your users should have in Grafana. Fine-grained access control is currently in beta, but general availability is just around the corner, planned for our 9.0 release. You can turn on fine-grained access control using the `accesscontrol` [feature toggle](https://grafana.com/docs/grafana/latest/enterprise/access-control/#enable-fine-grained-access-control), or by [reaching out to our support team](https://grafana.com/orgs/raintank/tickets#) for early access if you use Grafana Cloud. For more information on fine-grained access control, visit our [docs](https://grafana.com/docs/grafana/latest/enterprise/access-control/). +{{< figure src="/static/img/docs/enterprise/configure-role-access-8-5.png" max-width="400px" caption="Configure role access" >}} + ### Configure Azure Key Vault using Managed Identities You can already keep secrets in Grafana’s database (like data source credentials) safer by retrieving your database encryption key from a Key Management Service, like AWS KMS or Azure Key Vault. In Grafana v8.5, you can use an Azure Managed Identity to integrate with Azure Key Vault. This simplifies the Key Vault integration and keeps it consistent with Grafana data sources, like Azure Data Explorer. From 8310789ef1da3c1784434ba69b4ec66333d4c67f Mon Sep 17 00:00:00 2001 From: Alexander Weaver Date: Fri, 22 Apr 2022 11:57:56 -0500 Subject: [PATCH 104/120] Indicate whether routes are provisioned when GETting Alertmanager configuration (#47857) * Test composition simplification from last PR * Policies use proper API model everywhere * Expose policy provenance in API, miss some dep injection * Complete injection * fix args * Tests for provenance value * Extract test helpers so tests are very readable * Single source adapter struct that was copied in 3 places * Drop redundant test * Resolve merge conflicts on changelog --- pkg/services/ngalert/CHANGELOG.md | 1 + .../ngalert/api/api_alertmanager_test.go | 77 ++++++++++++++++--- pkg/services/ngalert/api/api_provisioning.go | 3 +- .../ngalert/api/api_provisioning_test.go | 16 ++-- .../definitions/provisioning_contactpoints.go | 2 +- pkg/services/ngalert/ngalert.go | 2 +- .../ngalert/notifier/alertmanager_config.go | 24 ++++++ .../ngalert/notifier/multiorg_alertmanager.go | 11 ++- .../notifier/multiorg_alertmanager_test.go | 10 ++- .../ngalert/provisioning/contactpoints.go | 24 +++--- .../provisioning/contactpoints_test.go | 2 +- .../provisioning/notification_policies.go | 51 ++++-------- .../notification_policies_test.go | 2 +- pkg/services/ngalert/provisioning/persist.go | 17 ++++ pkg/services/ngalert/provisioning/testing.go | 2 +- .../ngalert/schedule/schedule_unit_test.go | 3 +- 16 files changed, 163 insertions(+), 84 deletions(-) diff --git a/pkg/services/ngalert/CHANGELOG.md b/pkg/services/ngalert/CHANGELOG.md index a3f76d0e097..bc1d909f3e7 100644 --- a/pkg/services/ngalert/CHANGELOG.md +++ b/pkg/services/ngalert/CHANGELOG.md @@ -50,3 +50,4 @@ Scopes must have an order to ensure consistency and ease of search, this helps u - [BUGFIX] Scheduler: Fix state manager to support OK option of `AlertRule.ExecErrState` #47670 - [ENHANCEMENT] Templates: Enable the use of classic condition values in templates #46971 - [CHANGE] Notification URL points to alert view page instead of alert edit page. #47752 +- [FEATURE] Indicate whether routes are provisioned when GETting Alertmanager configuration #47857 diff --git a/pkg/services/ngalert/api/api_alertmanager_test.go b/pkg/services/ngalert/api/api_alertmanager_test.go index eeb41fa7c52..45c886cd1e4 100644 --- a/pkg/services/ngalert/api/api_alertmanager_test.go +++ b/pkg/services/ngalert/api/api_alertmanager_test.go @@ -2,6 +2,7 @@ package api import ( "context" + "encoding/json" "math/rand" "net/http" "testing" @@ -12,14 +13,17 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/stretchr/testify/require" + "github.com/grafana/grafana/pkg/api/response" "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/accesscontrol" acMock "github.com/grafana/grafana/pkg/services/accesscontrol/mock" + "github.com/grafana/grafana/pkg/services/featuremgmt" apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions" "github.com/grafana/grafana/pkg/services/ngalert/metrics" ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models" "github.com/grafana/grafana/pkg/services/ngalert/notifier" + "github.com/grafana/grafana/pkg/services/ngalert/provisioning" "github.com/grafana/grafana/pkg/services/secrets/fakes" secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager" "github.com/grafana/grafana/pkg/setting" @@ -208,6 +212,31 @@ func TestAlertmanagerConfig(t *testing.T) { require.Equal(t, 202, response.Status()) }) + + t.Run("when objects are not provisioned", func(t *testing.T) { + t.Run("route from GET config has no provenance", func(t *testing.T) { + sut := createSut(t, nil) + rc := createRequestCtxInOrg(1) + + response := sut.RouteGetAlertingConfig(rc) + + body := asGettableUserConfig(t, response) + require.Equal(t, ngmodels.ProvenanceNone, body.AlertmanagerConfig.Route.Provenance) + }) + }) + + t.Run("when objects are provisioned", func(t *testing.T) { + t.Run("route from GET config has expected provenance", func(t *testing.T) { + sut := createSut(t, nil) + rc := createRequestCtxInOrg(1) + setRouteProvenance(t, 1, sut.mam.ProvStore) + + response := sut.RouteGetAlertingConfig(rc) + + body := asGettableUserConfig(t, response) + require.Equal(t, ngmodels.ProvenanceAPI, body.AlertmanagerConfig.Route.Provenance) + }) + }) } func TestRouteCreateSilence(t *testing.T) { @@ -346,19 +375,16 @@ func createSut(t *testing.T, accessControl accesscontrol.AccessControl) Alertman t.Helper() mam := createMultiOrgAlertmanager(t) - configs := map[int64]*ngmodels.AlertConfiguration{ - 1: {AlertmanagerConfiguration: validConfig, OrgID: 1}, - 2: {AlertmanagerConfiguration: validConfig, OrgID: 2}, - 3: {AlertmanagerConfiguration: brokenConfig, OrgID: 3}, - } - configStore := notifier.NewFakeConfigStore(t, configs) - secrets := fakes.NewFakeSecretsService() if accessControl == nil { accessControl = acMock.New().WithDisabled() } log := log.NewNopLogger() - crypto := notifier.NewCrypto(secrets, &configStore, log) - return AlertmanagerSrv{mam: mam, crypto: crypto, ac: accessControl, log: log} + return AlertmanagerSrv{ + mam: mam, + crypto: mam.Crypto, + ac: accessControl, + log: log, + } } func createAmConfigRequest(t *testing.T) apimodels.PostableUserConfig { @@ -381,6 +407,7 @@ func createMultiOrgAlertmanager(t *testing.T) *notifier.MultiOrgAlertmanager { } configStore := notifier.NewFakeConfigStore(t, configs) orgStore := notifier.NewFakeOrgStore(t, []int64{1, 2, 3}) + provStore := provisioning.NewFakeProvisioningStore() tmpDir := t.TempDir() kvStore := notifier.NewFakeKVStore(t) secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore()) @@ -394,9 +421,12 @@ func createMultiOrgAlertmanager(t *testing.T) *notifier.MultiOrgAlertmanager { DefaultConfiguration: setting.GetAlertmanagerDefaultConfiguration(), DisabledOrgs: map[int64]struct{}{5: {}}, }, // do not poll in tests. + IsFeatureToggleEnabled: func(key string) bool { + return key == featuremgmt.FlagAlertProvisioning + }, } - mam, err := notifier.NewMultiOrgAlertmanager(cfg, &configStore, &orgStore, kvStore, decryptFn, m.GetMultiOrgAlertmanagerMetrics(), nil, log.New("testlogger"), secretsService) + mam, err := notifier.NewMultiOrgAlertmanager(cfg, &configStore, &orgStore, kvStore, provStore, decryptFn, m.GetMultiOrgAlertmanagerMetrics(), nil, log.New("testlogger"), secretsService) require.NoError(t, err) err = mam.LoadAndSyncAlertmanagersForOrgs(context.Background()) require.NoError(t, err) @@ -460,3 +490,30 @@ func silenceGen(mutatorFuncs ...func(*apimodels.PostableSilence)) func() apimode func withEmptyID(silence *apimodels.PostableSilence) { silence.ID = "" } + +func createRequestCtxInOrg(org int64) *models.ReqContext { + return &models.ReqContext{ + Context: &web.Context{ + Req: &http.Request{}, + }, + SignedInUser: &models.SignedInUser{ + OrgId: org, + }, + } +} + +// setRouteProvenance marks an org's routing tree as provisioned. +func setRouteProvenance(t *testing.T, org int64, ps provisioning.ProvisioningStore) { + t.Helper() + adp := provisioning.ProvenanceOrgAdapter{Inner: &apimodels.Route{}, OrgID: org} + err := ps.SetProvenance(context.Background(), adp, ngmodels.ProvenanceAPI) + require.NoError(t, err) +} + +func asGettableUserConfig(t *testing.T, r response.Response) *apimodels.GettableUserConfig { + t.Helper() + body := &apimodels.GettableUserConfig{} + err := json.Unmarshal(r.Body(), body) + require.NoError(t, err) + return body +} diff --git a/pkg/services/ngalert/api/api_provisioning.go b/pkg/services/ngalert/api/api_provisioning.go index 2b6e632c58e..c8113be9abb 100644 --- a/pkg/services/ngalert/api/api_provisioning.go +++ b/pkg/services/ngalert/api/api_provisioning.go @@ -10,7 +10,6 @@ import ( "github.com/grafana/grafana/pkg/models" apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions" alerting_models "github.com/grafana/grafana/pkg/services/ngalert/models" - "github.com/grafana/grafana/pkg/services/ngalert/provisioning" "github.com/grafana/grafana/pkg/services/ngalert/store" "github.com/grafana/grafana/pkg/util" "github.com/grafana/grafana/pkg/web" @@ -30,7 +29,7 @@ type ContactPointService interface { } type NotificationPolicyService interface { - GetPolicyTree(ctx context.Context, orgID int64) (provisioning.EmbeddedRoutingTree, error) + GetPolicyTree(ctx context.Context, orgID int64) (apimodels.Route, error) UpdatePolicyTree(ctx context.Context, orgID int64, tree apimodels.Route, p alerting_models.Provenance) error } diff --git a/pkg/services/ngalert/api/api_provisioning_test.go b/pkg/services/ngalert/api/api_provisioning_test.go index 5cac3a26a1b..e618f4091d2 100644 --- a/pkg/services/ngalert/api/api_provisioning_test.go +++ b/pkg/services/ngalert/api/api_provisioning_test.go @@ -10,7 +10,6 @@ import ( "github.com/grafana/grafana/pkg/models" apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions" domain "github.com/grafana/grafana/pkg/services/ngalert/models" - "github.com/grafana/grafana/pkg/services/ngalert/provisioning" "github.com/grafana/grafana/pkg/services/ngalert/store" "github.com/grafana/grafana/pkg/web" "github.com/stretchr/testify/require" @@ -120,14 +119,13 @@ func newFakeNotificationPolicyService() *fakeNotificationPolicyService { } } -func (f *fakeNotificationPolicyService) GetPolicyTree(ctx context.Context, orgID int64) (provisioning.EmbeddedRoutingTree, error) { +func (f *fakeNotificationPolicyService) GetPolicyTree(ctx context.Context, orgID int64) (apimodels.Route, error) { if orgID != 1 { - return provisioning.EmbeddedRoutingTree{}, store.ErrNoAlertmanagerConfiguration + return apimodels.Route{}, store.ErrNoAlertmanagerConfiguration } - return provisioning.EmbeddedRoutingTree{ - Route: f.tree, - Provenance: f.prov, - }, nil + result := f.tree + result.Provenance = f.prov + return result, nil } func (f *fakeNotificationPolicyService) UpdatePolicyTree(ctx context.Context, orgID int64, tree apimodels.Route, p domain.Provenance) error { @@ -141,8 +139,8 @@ func (f *fakeNotificationPolicyService) UpdatePolicyTree(ctx context.Context, or type fakeFailingNotificationPolicyService struct{} -func (f *fakeFailingNotificationPolicyService) GetPolicyTree(ctx context.Context, orgID int64) (provisioning.EmbeddedRoutingTree, error) { - return provisioning.EmbeddedRoutingTree{}, fmt.Errorf("something went wrong") +func (f *fakeFailingNotificationPolicyService) GetPolicyTree(ctx context.Context, orgID int64) (apimodels.Route, error) { + return apimodels.Route{}, fmt.Errorf("something went wrong") } func (f *fakeFailingNotificationPolicyService) UpdatePolicyTree(ctx context.Context, orgID int64, tree apimodels.Route, p domain.Provenance) error { diff --git a/pkg/services/ngalert/api/tooling/definitions/provisioning_contactpoints.go b/pkg/services/ngalert/api/tooling/definitions/provisioning_contactpoints.go index 3d86af76928..ddbcc007f2c 100644 --- a/pkg/services/ngalert/api/tooling/definitions/provisioning_contactpoints.go +++ b/pkg/services/ngalert/api/tooling/definitions/provisioning_contactpoints.go @@ -66,7 +66,7 @@ type EmbeddedContactPoint struct { Type string `json:"type" binding:"required"` Settings *simplejson.Json `json:"settings" binding:"required"` DisableResolveMessage bool `json:"disableResolveMessage"` - Provenance string `json:"provanance"` + Provenance string `json:"provenance"` } const RedactedValue = "[REDACTED]" diff --git a/pkg/services/ngalert/ngalert.go b/pkg/services/ngalert/ngalert.go index 49158bc52b5..b47cc404a33 100644 --- a/pkg/services/ngalert/ngalert.go +++ b/pkg/services/ngalert/ngalert.go @@ -99,7 +99,7 @@ func (ng *AlertNG) init() error { decryptFn := ng.SecretsService.GetDecryptedValue multiOrgMetrics := ng.Metrics.GetMultiOrgAlertmanagerMetrics() - ng.MultiOrgAlertmanager, err = notifier.NewMultiOrgAlertmanager(ng.Cfg, store, store, ng.KVStore, decryptFn, multiOrgMetrics, ng.NotificationService, log.New("ngalert.multiorg.alertmanager"), ng.SecretsService) + ng.MultiOrgAlertmanager, err = notifier.NewMultiOrgAlertmanager(ng.Cfg, store, store, ng.KVStore, store, decryptFn, multiOrgMetrics, ng.NotificationService, log.New("ngalert.multiorg.alertmanager"), ng.SecretsService) if err != nil { return err } diff --git a/pkg/services/ngalert/notifier/alertmanager_config.go b/pkg/services/ngalert/notifier/alertmanager_config.go index 7efd6561589..f3d873a9c98 100644 --- a/pkg/services/ngalert/notifier/alertmanager_config.go +++ b/pkg/services/ngalert/notifier/alertmanager_config.go @@ -5,8 +5,10 @@ import ( "errors" "fmt" + "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions" "github.com/grafana/grafana/pkg/services/ngalert/models" + "github.com/grafana/grafana/pkg/services/ngalert/provisioning" "github.com/grafana/grafana/pkg/services/ngalert/store" ) @@ -81,6 +83,13 @@ func (moa *MultiOrgAlertmanager) GetAlertmanagerConfiguration(ctx context.Contex result.AlertmanagerConfig.Receivers = append(result.AlertmanagerConfig.Receivers, &gettableApiReceiver) } + if moa.settings.IsFeatureToggleEnabled(featuremgmt.FlagAlertProvisioning) { + result.AlertmanagerConfig, err = moa.mergeProvenance(ctx, result.AlertmanagerConfig, org) + if err != nil { + return definitions.GettableUserConfig{}, err + } + } + return result, nil } @@ -117,3 +126,18 @@ func (moa *MultiOrgAlertmanager) ApplyAlertmanagerConfiguration(ctx context.Cont return nil } + +func (moa *MultiOrgAlertmanager) mergeProvenance(ctx context.Context, config definitions.GettableApiAlertingConfig, org int64) (definitions.GettableApiAlertingConfig, error) { + if config.Route != nil { + adp := provisioning.ProvenanceOrgAdapter{ + Inner: config.Route, + OrgID: org, + } + provenance, err := moa.ProvStore.GetProvenance(ctx, adp) + if err != nil { + return definitions.GettableApiAlertingConfig{}, err + } + config.Route.Provenance = provenance + } + return config, nil +} diff --git a/pkg/services/ngalert/notifier/multiorg_alertmanager.go b/pkg/services/ngalert/notifier/multiorg_alertmanager.go index d34677c3e44..6764619121d 100644 --- a/pkg/services/ngalert/notifier/multiorg_alertmanager.go +++ b/pkg/services/ngalert/notifier/multiorg_alertmanager.go @@ -10,6 +10,7 @@ import ( "time" "github.com/grafana/grafana/pkg/services/ngalert/notifier/channels" + "github.com/grafana/grafana/pkg/services/ngalert/provisioning" "github.com/grafana/grafana/pkg/services/notifications" "github.com/grafana/grafana/pkg/services/secrets" @@ -30,7 +31,8 @@ var ( ) type MultiOrgAlertmanager struct { - Crypto Crypto + Crypto Crypto + ProvStore provisioning.ProvisioningStore alertmanagersMtx sync.RWMutex alertmanagers map[int64]*Alertmanager @@ -53,11 +55,12 @@ type MultiOrgAlertmanager struct { } func NewMultiOrgAlertmanager(cfg *setting.Cfg, configStore store.AlertingStore, orgStore store.OrgStore, - kvStore kvstore.KVStore, decryptFn channels.GetDecryptedValueFn, m *metrics.MultiOrgAlertmanager, - ns notifications.Service, l log.Logger, s secrets.Service, + kvStore kvstore.KVStore, provStore provisioning.ProvisioningStore, decryptFn channels.GetDecryptedValueFn, + m *metrics.MultiOrgAlertmanager, ns notifications.Service, l log.Logger, s secrets.Service, ) (*MultiOrgAlertmanager, error) { moa := &MultiOrgAlertmanager{ - Crypto: NewCrypto(s, configStore, l), + Crypto: NewCrypto(s, configStore, l), + ProvStore: provStore, logger: l, settings: cfg, diff --git a/pkg/services/ngalert/notifier/multiorg_alertmanager_test.go b/pkg/services/ngalert/notifier/multiorg_alertmanager_test.go index 56899182532..d0f819775ff 100644 --- a/pkg/services/ngalert/notifier/multiorg_alertmanager_test.go +++ b/pkg/services/ngalert/notifier/multiorg_alertmanager_test.go @@ -13,6 +13,7 @@ import ( "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/services/ngalert/metrics" "github.com/grafana/grafana/pkg/services/ngalert/models" + "github.com/grafana/grafana/pkg/services/ngalert/provisioning" "github.com/grafana/grafana/pkg/services/secrets/fakes" secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager" "github.com/grafana/grafana/pkg/setting" @@ -32,6 +33,7 @@ func TestMultiOrgAlertmanager_SyncAlertmanagersForOrgs(t *testing.T) { tmpDir := t.TempDir() kvStore := NewFakeKVStore(t) + provStore := provisioning.NewFakeProvisioningStore() secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore()) decryptFn := secretsService.GetDecryptedValue reg := prometheus.NewPedanticRegistry() @@ -44,7 +46,7 @@ func TestMultiOrgAlertmanager_SyncAlertmanagersForOrgs(t *testing.T) { DisabledOrgs: map[int64]struct{}{5: {}}, }, // do not poll in tests. } - mam, err := NewMultiOrgAlertmanager(cfg, configStore, orgStore, kvStore, decryptFn, m.GetMultiOrgAlertmanagerMetrics(), nil, log.New("testlogger"), secretsService) + mam, err := NewMultiOrgAlertmanager(cfg, configStore, orgStore, kvStore, provStore, decryptFn, m.GetMultiOrgAlertmanagerMetrics(), nil, log.New("testlogger"), secretsService) require.NoError(t, err) ctx := context.Background() @@ -157,6 +159,7 @@ func TestMultiOrgAlertmanager_SyncAlertmanagersForOrgsWithFailures(t *testing.T) tmpDir := t.TempDir() kvStore := NewFakeKVStore(t) + provStore := provisioning.NewFakeProvisioningStore() secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore()) decryptFn := secretsService.GetDecryptedValue reg := prometheus.NewPedanticRegistry() @@ -168,7 +171,7 @@ func TestMultiOrgAlertmanager_SyncAlertmanagersForOrgsWithFailures(t *testing.T) DefaultConfiguration: setting.GetAlertmanagerDefaultConfiguration(), }, // do not poll in tests. } - mam, err := NewMultiOrgAlertmanager(cfg, configStore, orgStore, kvStore, decryptFn, m.GetMultiOrgAlertmanagerMetrics(), nil, log.New("testlogger"), secretsService) + mam, err := NewMultiOrgAlertmanager(cfg, configStore, orgStore, kvStore, provStore, decryptFn, m.GetMultiOrgAlertmanagerMetrics(), nil, log.New("testlogger"), secretsService) require.NoError(t, err) ctx := context.Background() @@ -214,11 +217,12 @@ func TestMultiOrgAlertmanager_AlertmanagerFor(t *testing.T) { UnifiedAlerting: setting.UnifiedAlertingSettings{AlertmanagerConfigPollInterval: 3 * time.Minute, DefaultConfiguration: setting.GetAlertmanagerDefaultConfiguration()}, // do not poll in tests. } kvStore := NewFakeKVStore(t) + provStore := provisioning.NewFakeProvisioningStore() secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore()) decryptFn := secretsService.GetDecryptedValue reg := prometheus.NewPedanticRegistry() m := metrics.NewNGAlert(reg) - mam, err := NewMultiOrgAlertmanager(cfg, configStore, orgStore, kvStore, decryptFn, m.GetMultiOrgAlertmanagerMetrics(), nil, log.New("testlogger"), secretsService) + mam, err := NewMultiOrgAlertmanager(cfg, configStore, orgStore, kvStore, provStore, decryptFn, m.GetMultiOrgAlertmanagerMetrics(), nil, log.New("testlogger"), secretsService) require.NoError(t, err) ctx := context.Background() diff --git a/pkg/services/ngalert/provisioning/contactpoints.go b/pkg/services/ngalert/provisioning/contactpoints.go index 00b1b60aba7..83922021f0c 100644 --- a/pkg/services/ngalert/provisioning/contactpoints.go +++ b/pkg/services/ngalert/provisioning/contactpoints.go @@ -177,9 +177,9 @@ func (ecp *ContactPointService) CreateContactPoint(ctx context.Context, orgID in if err != nil { return err } - adapter := provenanceOrgAdapter{ - inner: &contactPoint, - orgID: orgID, + adapter := ProvenanceOrgAdapter{ + Inner: &contactPoint, + OrgID: orgID, } err = ecp.provenanceStore.SetProvenance(ctx, adapter, provenance) if err != nil { @@ -218,9 +218,9 @@ func (ecp *ContactPointService) UpdateContactPoint(ctx context.Context, orgID in return err } // check that provenance is not changed in a invalid way - storedProvenance, err := ecp.provenanceStore.GetProvenance(ctx, provenanceOrgAdapter{ - inner: &contactPoint, - orgID: orgID, + storedProvenance, err := ecp.provenanceStore.GetProvenance(ctx, ProvenanceOrgAdapter{ + Inner: &contactPoint, + OrgID: orgID, }) if err != nil { return err @@ -283,9 +283,9 @@ func (ecp *ContactPointService) UpdateContactPoint(ctx context.Context, orgID in if err != nil { return err } - adapter := provenanceOrgAdapter{ - inner: &contactPoint, - orgID: orgID, + adapter := ProvenanceOrgAdapter{ + Inner: &contactPoint, + OrgID: orgID, } err = ecp.provenanceStore.SetProvenance(ctx, adapter, provenance) if err != nil { @@ -330,11 +330,11 @@ func (ecp *ContactPointService) DeleteContactPoint(ctx context.Context, orgID in return err } return ecp.xact.InTransaction(ctx, func(ctx context.Context) error { - err := ecp.provenanceStore.DeleteProvenance(ctx, provenanceOrgAdapter{ - inner: &apimodels.EmbeddedContactPoint{ + err := ecp.provenanceStore.DeleteProvenance(ctx, ProvenanceOrgAdapter{ + Inner: &apimodels.EmbeddedContactPoint{ UID: uid, }, - orgID: orgID, + OrgID: orgID, }) if err != nil { return err diff --git a/pkg/services/ngalert/provisioning/contactpoints_test.go b/pkg/services/ngalert/provisioning/contactpoints_test.go index cb70fe05baa..d9c358aca33 100644 --- a/pkg/services/ngalert/provisioning/contactpoints_test.go +++ b/pkg/services/ngalert/provisioning/contactpoints_test.go @@ -178,7 +178,7 @@ func TestContactPointInUse(t *testing.T) { func createContactPointServiceSut(secretService secrets.Service) *ContactPointService { return &ContactPointService{ amStore: newFakeAMConfigStore(), - provenanceStore: newFakeProvisioningStore(), + provenanceStore: NewFakeProvisioningStore(), xact: newNopTransactionManager(), encryptionService: secretService, log: log.NewNopLogger(), diff --git a/pkg/services/ngalert/provisioning/notification_policies.go b/pkg/services/ngalert/provisioning/notification_policies.go index e77b5f11aea..87582b012f8 100644 --- a/pkg/services/ngalert/provisioning/notification_policies.go +++ b/pkg/services/ngalert/provisioning/notification_policies.go @@ -25,47 +25,39 @@ func NewNotificationPolicyService(am AMConfigStore, prov ProvisioningStore, xact } } -// TODO: move to Swagger codegen -type EmbeddedRoutingTree struct { - definitions.Route - Provenance models.Provenance -} - func (nps *NotificationPolicyService) GetAMConfigStore() AMConfigStore { return nps.amStore } -func (nps *NotificationPolicyService) GetPolicyTree(ctx context.Context, orgID int64) (EmbeddedRoutingTree, error) { +func (nps *NotificationPolicyService) GetPolicyTree(ctx context.Context, orgID int64) (definitions.Route, error) { q := models.GetLatestAlertmanagerConfigurationQuery{ OrgID: orgID, } err := nps.amStore.GetLatestAlertmanagerConfiguration(ctx, &q) if err != nil { - return EmbeddedRoutingTree{}, err + return definitions.Route{}, err } cfg, err := DeserializeAlertmanagerConfig([]byte(q.Result.AlertmanagerConfiguration)) if err != nil { - return EmbeddedRoutingTree{}, err + return definitions.Route{}, err } if cfg.AlertmanagerConfig.Config.Route == nil { - return EmbeddedRoutingTree{}, fmt.Errorf("no route present in current alertmanager config") + return definitions.Route{}, fmt.Errorf("no route present in current alertmanager config") } - adapter := provenanceOrgAdapter{ - inner: cfg.AlertmanagerConfig.Route, - orgID: orgID, + adapter := ProvenanceOrgAdapter{ + Inner: cfg.AlertmanagerConfig.Route, + OrgID: orgID, } provenance, err := nps.provenanceStore.GetProvenance(ctx, adapter) if err != nil { - return EmbeddedRoutingTree{}, err + return definitions.Route{}, err } - result := EmbeddedRoutingTree{ - Route: *cfg.AlertmanagerConfig.Route, - Provenance: provenance, - } + result := *cfg.AlertmanagerConfig.Route + result.Provenance = provenance return result, nil } @@ -103,9 +95,9 @@ func (nps *NotificationPolicyService) UpdatePolicyTree(ctx context.Context, orgI if err != nil { return err } - adapter := provenanceOrgAdapter{ - inner: &tree, - orgID: orgID, + adapter := ProvenanceOrgAdapter{ + Inner: &tree, + OrgID: orgID, } err = nps.provenanceStore.SetProvenance(ctx, adapter, p) if err != nil { @@ -119,20 +111,3 @@ func (nps *NotificationPolicyService) UpdatePolicyTree(ctx context.Context, orgI return nil } - -type provenanceOrgAdapter struct { - inner models.ProvisionableInOrg - orgID int64 -} - -func (a provenanceOrgAdapter) ResourceType() string { - return a.inner.ResourceType() -} - -func (a provenanceOrgAdapter) ResourceID() string { - return a.inner.ResourceID() -} - -func (a provenanceOrgAdapter) ResourceOrgID() int64 { - return a.orgID -} diff --git a/pkg/services/ngalert/provisioning/notification_policies_test.go b/pkg/services/ngalert/provisioning/notification_policies_test.go index 2a27b6b3554..2b4d4327bab 100644 --- a/pkg/services/ngalert/provisioning/notification_policies_test.go +++ b/pkg/services/ngalert/provisioning/notification_policies_test.go @@ -75,7 +75,7 @@ func TestNotificationPolicyService(t *testing.T) { func createNotificationPolicyServiceSut() *NotificationPolicyService { return &NotificationPolicyService{ amStore: newFakeAMConfigStore(), - provenanceStore: newFakeProvisioningStore(), + provenanceStore: NewFakeProvisioningStore(), xact: newNopTransactionManager(), log: log.NewNopLogger(), } diff --git a/pkg/services/ngalert/provisioning/persist.go b/pkg/services/ngalert/provisioning/persist.go index eb428055a86..0be6e093dd3 100644 --- a/pkg/services/ngalert/provisioning/persist.go +++ b/pkg/services/ngalert/provisioning/persist.go @@ -24,3 +24,20 @@ type ProvisioningStore interface { type TransactionManager interface { InTransaction(ctx context.Context, work func(ctx context.Context) error) error } + +type ProvenanceOrgAdapter struct { + Inner models.ProvisionableInOrg + OrgID int64 +} + +func (a ProvenanceOrgAdapter) ResourceType() string { + return a.Inner.ResourceType() +} + +func (a ProvenanceOrgAdapter) ResourceID() string { + return a.Inner.ResourceID() +} + +func (a ProvenanceOrgAdapter) ResourceOrgID() int64 { + return a.OrgID +} diff --git a/pkg/services/ngalert/provisioning/testing.go b/pkg/services/ngalert/provisioning/testing.go index aba31dfd513..4693460c1c8 100644 --- a/pkg/services/ngalert/provisioning/testing.go +++ b/pkg/services/ngalert/provisioning/testing.go @@ -92,7 +92,7 @@ type fakeProvisioningStore struct { records map[int64]map[string]models.Provenance } -func newFakeProvisioningStore() *fakeProvisioningStore { +func NewFakeProvisioningStore() *fakeProvisioningStore { return &fakeProvisioningStore{ records: map[int64]map[string]models.Provenance{}, } diff --git a/pkg/services/ngalert/schedule/schedule_unit_test.go b/pkg/services/ngalert/schedule/schedule_unit_test.go index 7f5f8da4cac..5882a49dc12 100644 --- a/pkg/services/ngalert/schedule/schedule_unit_test.go +++ b/pkg/services/ngalert/schedule/schedule_unit_test.go @@ -26,6 +26,7 @@ import ( "github.com/grafana/grafana/pkg/services/ngalert/metrics" "github.com/grafana/grafana/pkg/services/ngalert/models" "github.com/grafana/grafana/pkg/services/ngalert/notifier" + "github.com/grafana/grafana/pkg/services/ngalert/provisioning" "github.com/grafana/grafana/pkg/services/ngalert/sender" "github.com/grafana/grafana/pkg/services/ngalert/state" "github.com/grafana/grafana/pkg/services/ngalert/store" @@ -1015,7 +1016,7 @@ func setupScheduler(t *testing.T, rs store.RuleStore, is store.InstanceStore, ac m := metrics.NewNGAlert(registry) secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore()) decryptFn := secretsService.GetDecryptedValue - moa, err := notifier.NewMultiOrgAlertmanager(&setting.Cfg{}, ¬ifier.FakeConfigStore{}, ¬ifier.FakeOrgStore{}, ¬ifier.FakeKVStore{}, decryptFn, m.GetMultiOrgAlertmanagerMetrics(), nil, log.New("testlogger"), secretsService) + moa, err := notifier.NewMultiOrgAlertmanager(&setting.Cfg{}, ¬ifier.FakeConfigStore{}, ¬ifier.FakeOrgStore{}, ¬ifier.FakeKVStore{}, provisioning.NewFakeProvisioningStore(), decryptFn, m.GetMultiOrgAlertmanagerMetrics(), nil, log.New("testlogger"), secretsService) require.NoError(t, err) schedCfg := SchedulerCfg{ From 75ba4e98c60f0a9297582b7631a3300c82a78532 Mon Sep 17 00:00:00 2001 From: Yuriy Tseretyan Date: Fri, 22 Apr 2022 15:09:47 -0400 Subject: [PATCH 105/120] Alerting: Remove unused features from ticker + metric + tests (#47828) * remove not used code: - remove offset in ticket because it is not used - remove unused ticker and scheduler methods * use duration for interval * add metrics grafana_alerting_ticker_last_consumed_tick_timestamp_seconds, grafana_alerting_ticker_next_tick_timestamp_seconds, grafana_alerting_ticker_interval_seconds --- pkg/services/alerting/engine.go | 4 +- pkg/services/alerting/metrics/metrics.go | 35 +++++++++++ pkg/services/alerting/ticker.go | 75 +++++++++-------------- pkg/services/alerting/ticker_test.go | 57 +++++++++++++---- pkg/services/ngalert/CHANGELOG.md | 1 + pkg/services/ngalert/metrics/ngalert.go | 16 +++-- pkg/services/ngalert/schedule/schedule.go | 24 +------- pkg/tests/testinfra/testinfra.go | 7 ++- 8 files changed, 128 insertions(+), 91 deletions(-) create mode 100644 pkg/services/alerting/metrics/metrics.go diff --git a/pkg/services/alerting/engine.go b/pkg/services/alerting/engine.go index 7fda9c47e85..59add0c5eb2 100644 --- a/pkg/services/alerting/engine.go +++ b/pkg/services/alerting/engine.go @@ -7,6 +7,7 @@ import ( "time" "github.com/benbjohnson/clock" + "github.com/prometheus/client_golang/prometheus" "go.opentelemetry.io/otel/attribute" "golang.org/x/sync/errgroup" @@ -14,6 +15,7 @@ import ( "github.com/grafana/grafana/pkg/infra/tracing" "github.com/grafana/grafana/pkg/infra/usagestats" "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/alerting/metrics" "github.com/grafana/grafana/pkg/services/encryption" "github.com/grafana/grafana/pkg/services/notifications" "github.com/grafana/grafana/pkg/services/rendering" @@ -77,7 +79,6 @@ func ProvideAlertEngine(renderer rendering.Service, requestValidator models.Plug sqlStore: sqlStore, dashAlertExtractor: dashAlertExtractor, } - e.ticker = NewTicker(time.Now(), time.Second*0, clock.New(), 1) e.execQueue = make(chan *Job, 1000) e.scheduler = newScheduler() e.evalHandler = NewEvalHandler(e.DataService) @@ -92,6 +93,7 @@ func ProvideAlertEngine(renderer rendering.Service, requestValidator models.Plug // Run starts the alerting service background process. func (e *AlertEngine) Run(ctx context.Context) error { + e.ticker = NewTicker(clock.New(), 1*time.Second, metrics.NewTickerMetrics(prometheus.DefaultRegisterer)) alertGroup, ctx := errgroup.WithContext(ctx) alertGroup.Go(func() error { return e.alertingTicker(ctx) }) alertGroup.Go(func() error { return e.runJobDispatcher(ctx) }) diff --git a/pkg/services/alerting/metrics/metrics.go b/pkg/services/alerting/metrics/metrics.go new file mode 100644 index 00000000000..e93087aa8dd --- /dev/null +++ b/pkg/services/alerting/metrics/metrics.go @@ -0,0 +1,35 @@ +package metrics + +import ( + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" +) + +type Ticker struct { + LastTickTime prometheus.Gauge + NextTickTime prometheus.Gauge + IntervalSeconds prometheus.Gauge +} + +func NewTickerMetrics(reg prometheus.Registerer) *Ticker { + return &Ticker{ + LastTickTime: promauto.With(reg).NewGauge(prometheus.GaugeOpts{ + Namespace: "grafana", + Subsystem: "alerting", + Name: "ticker_last_consumed_tick_timestamp_seconds", + Help: "Timestamp of the last consumed tick in seconds.", + }), + NextTickTime: promauto.With(reg).NewGauge(prometheus.GaugeOpts{ + Namespace: "grafana", + Subsystem: "alerting", + Name: "ticker_next_tick_timestamp_seconds", + Help: "Timestamp of the next tick in seconds before it is consumed.", + }), + IntervalSeconds: promauto.With(reg).NewGauge(prometheus.GaugeOpts{ + Namespace: "grafana", + Subsystem: "alerting", + Name: "ticker_interval_seconds", + Help: "Interval at which the ticker is meant to tick.", + }), + } +} diff --git a/pkg/services/alerting/ticker.go b/pkg/services/alerting/ticker.go index 48df4c227d5..16ea19ea5a3 100644 --- a/pkg/services/alerting/ticker.go +++ b/pkg/services/alerting/ticker.go @@ -1,76 +1,57 @@ package alerting import ( + "fmt" "time" "github.com/benbjohnson/clock" + + "github.com/grafana/grafana/pkg/services/alerting/metrics" ) // Ticker is a ticker to power the alerting scheduler. it's like a time.Ticker, except: // * it doesn't drop ticks for slow receivers, rather, it queues up. so that callers are in control to instrument what's going on. -// * it automatically ticks every second, which is the right thing in our current design -// * it ticks on intervalSec marks or very shortly after. this provides a predictable load pattern +// * it ticks on interval marks or very shortly after. this provides a predictable load pattern // (this shouldn't cause too much load contention issues because the next steps in the pipeline just process at their own pace) // * the timestamps are used to mark "last datapoint to query for" and as such, are a configurable amount of seconds in the past -// * because we want to allow: -// - a clean "resume where we left off" and "don't yield ticks we already did" -// - adjusting offset over time to compensate for storage backing up or getting fast and providing lower latency -// you specify a lastProcessed timestamp as well as an offset at creation, or runtime type Ticker struct { - C chan time.Time - clock clock.Clock - last time.Time - offset time.Duration - newOffset chan time.Duration - intervalSec int64 - paused bool + C chan time.Time + clock clock.Clock + last time.Time + interval time.Duration + metrics *metrics.Ticker } -// NewTicker returns a ticker that ticks on intervalSec marks or very shortly after, and never drops ticks -func NewTicker(last time.Time, initialOffset time.Duration, c clock.Clock, intervalSec int64) *Ticker { - t := &Ticker{ - C: make(chan time.Time), - clock: c, - last: last, - offset: initialOffset, - newOffset: make(chan time.Duration), - intervalSec: intervalSec, +// NewTicker returns a Ticker that ticks on interval marks (or very shortly after) starting at c.Now(), and never drops ticks. interval should not be negative or zero. +func NewTicker(c clock.Clock, interval time.Duration, metric *metrics.Ticker) *Ticker { + if interval <= 0 { + panic(fmt.Errorf("non-positive interval [%v] is not allowed", interval)) } + t := &Ticker{ + C: make(chan time.Time), + clock: c, + last: c.Now(), + interval: interval, + metrics: metric, + } + metric.IntervalSeconds.Set(t.interval.Seconds()) // Seconds report fractional part as well, so it matches the format of the timestamp we report below go t.run() return t } func (t *Ticker) run() { for { - next := t.last.Add(time.Duration(t.intervalSec) * time.Second) - diff := t.clock.Now().Add(-t.offset).Sub(next) + next := t.last.Add(t.interval) // calculate the time of the next tick + t.metrics.NextTickTime.Set(float64(next.UnixNano()) / 1e9) + diff := t.clock.Now().Sub(next) // calculate the difference between the current time and the next tick + // if difference is not negative, then it should tick if diff >= 0 { - if !t.paused { - t.C <- next - } + t.C <- next t.last = next + t.metrics.LastTickTime.Set(float64(next.UnixNano()) / 1e9) continue } // tick is too young. try again when ... - select { - case <-t.clock.After(-diff): // ...it'll definitely be old enough - case offset := <-t.newOffset: // ...it might be old enough - t.offset = offset - } + <-t.clock.After(-diff) // ...it'll definitely be old enough } } - -// ResetOffset resets the offset. -func (t *Ticker) ResetOffset(duration time.Duration) { - t.newOffset <- duration -} - -// Pause unpauses the ticker and no ticks will be sent. -func (t *Ticker) Pause() { - t.paused = true -} - -// Unpause unpauses the ticker and ticks will be sent. -func (t *Ticker) Unpause() { - t.paused = false -} diff --git a/pkg/services/alerting/ticker_test.go b/pkg/services/alerting/ticker_test.go index 0db3c6b777f..8eb4061e14d 100644 --- a/pkg/services/alerting/ticker_test.go +++ b/pkg/services/alerting/ticker_test.go @@ -1,6 +1,7 @@ package alerting import ( + "bytes" "context" "fmt" "math/rand" @@ -9,7 +10,11 @@ import ( "time" "github.com/benbjohnson/clock" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/testutil" "github.com/stretchr/testify/require" + + "github.com/grafana/grafana/pkg/services/alerting/metrics" ) func TestTicker(t *testing.T) { @@ -27,10 +32,8 @@ func TestTicker(t *testing.T) { } t.Run("should not drop ticks", func(t *testing.T) { clk := clock.NewMock() - intervalSec := rand.Int63n(100) + 10 - interval := time.Duration(intervalSec) * time.Second - last := clk.Now() - ticker := NewTicker(last, 0, clk, intervalSec) + interval := time.Duration(rand.Int63n(100)+10) * time.Second + ticker := NewTicker(clk, interval, metrics.NewTickerMetrics(prometheus.NewRegistry())) ticks := rand.Intn(9) + 1 jitter := rand.Int63n(int64(interval) - 1) @@ -63,10 +66,8 @@ func TestTicker(t *testing.T) { t.Run("should not put anything to channel until it's time", func(t *testing.T) { clk := clock.NewMock() - intervalSec := rand.Int63n(9) + 1 - interval := time.Duration(intervalSec) * time.Second - last := clk.Now() - ticker := NewTicker(last, 0, clk, intervalSec) + interval := time.Duration(rand.Int63n(9)+1) * time.Second + ticker := NewTicker(clk, interval, metrics.NewTickerMetrics(prometheus.NewRegistry())) expectedTick := clk.Now().Add(interval) for { require.Empty(t, ticker.C) @@ -85,10 +86,8 @@ func TestTicker(t *testing.T) { t.Run("should put the tick in the channel immediately if it is behind", func(t *testing.T) { clk := clock.NewMock() - intervalSec := rand.Int63n(9) + 1 - interval := time.Duration(intervalSec) * time.Second - last := clk.Now() - ticker := NewTicker(last, 0, clk, intervalSec) + interval := time.Duration(rand.Int63n(9)+1) * time.Second + ticker := NewTicker(clk, interval, metrics.NewTickerMetrics(prometheus.NewRegistry())) // We can expect the first tick to be at a consistent interval. Take a snapshot of the clock now, before we advance it. expectedTick := clk.Now().Add(interval) @@ -116,4 +115,38 @@ func TestTicker(t *testing.T) { // Similarly, the second tick should be last tick + interval irregardless of wall time. require.Equal(t, expectedTick.Add(interval), actual2) }) + + t.Run("should report metrics", func(t *testing.T) { + clk := clock.NewMock() + clk.Set(time.Now()) + interval := time.Duration(rand.Int63n(9)+1) * time.Second + registry := prometheus.NewPedanticRegistry() + ticker := NewTicker(clk, interval, metrics.NewTickerMetrics(registry)) + expectedTick := clk.Now().Add(interval) + + expectedMetricFmt := `# HELP grafana_alerting_ticker_interval_seconds Interval at which the ticker is meant to tick. + # TYPE grafana_alerting_ticker_interval_seconds gauge + grafana_alerting_ticker_interval_seconds %v + # HELP grafana_alerting_ticker_last_consumed_tick_timestamp_seconds Timestamp of the last consumed tick in seconds. + # TYPE grafana_alerting_ticker_last_consumed_tick_timestamp_seconds gauge + grafana_alerting_ticker_last_consumed_tick_timestamp_seconds %v + # HELP grafana_alerting_ticker_next_tick_timestamp_seconds Timestamp of the next tick in seconds before it is consumed. + # TYPE grafana_alerting_ticker_next_tick_timestamp_seconds gauge + grafana_alerting_ticker_next_tick_timestamp_seconds %v + ` + + expectedMetric := fmt.Sprintf(expectedMetricFmt, interval.Seconds(), 0, float64(expectedTick.UnixNano())/1e9) + + require.NoError(t, testutil.GatherAndCompare(registry, bytes.NewBufferString(expectedMetric), "grafana_alerting_ticker_last_consumed_tick_timestamp_seconds", "grafana_alerting_ticker_next_tick_timestamp_seconds", "grafana_alerting_ticker_interval_seconds")) + + clk.Add(interval) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + t.Cleanup(func() { + cancel() + }) + actual := readChanOrFail(t, ctx, ticker.C) + + expectedMetric = fmt.Sprintf(expectedMetricFmt, interval.Seconds(), float64(actual.UnixNano())/1e9, float64(expectedTick.Add(interval).UnixNano())/1e9) + require.NoError(t, testutil.GatherAndCompare(registry, bytes.NewBufferString(expectedMetric), "grafana_alerting_ticker_last_consumed_tick_timestamp_seconds", "grafana_alerting_ticker_next_tick_timestamp_seconds", "grafana_alerting_ticker_interval_seconds")) + }) } diff --git a/pkg/services/ngalert/CHANGELOG.md b/pkg/services/ngalert/CHANGELOG.md index bc1d909f3e7..6738445a117 100644 --- a/pkg/services/ngalert/CHANGELOG.md +++ b/pkg/services/ngalert/CHANGELOG.md @@ -49,5 +49,6 @@ Scopes must have an order to ensure consistency and ease of search, this helps u - [BUGFIX] (Legacy) Templates: Parse notification templates using all the matches of the alert rule when going from `Alerting` to `OK` in legacy alerting #47355 - [BUGFIX] Scheduler: Fix state manager to support OK option of `AlertRule.ExecErrState` #47670 - [ENHANCEMENT] Templates: Enable the use of classic condition values in templates #46971 +- [ENHANCEMENT] Scheduler: ticker expose new metrics `grafana_alerting_ticker_last_consumed_tick_timestamp_seconds`, `grafana_alerting_ticker_next_tick_timestamp_seconds`, `grafana_alerting_ticker_interval_seconds` #47828 - [CHANGE] Notification URL points to alert view page instead of alert edit page. #47752 - [FEATURE] Indicate whether routes are provisioned when GETting Alertmanager configuration #47857 diff --git a/pkg/services/ngalert/metrics/ngalert.go b/pkg/services/ngalert/metrics/ngalert.go index 86f04857d55..6bbf6a601b9 100644 --- a/pkg/services/ngalert/metrics/ngalert.go +++ b/pkg/services/ngalert/metrics/ngalert.go @@ -7,15 +7,17 @@ import ( "sync" "time" - "github.com/grafana/grafana/pkg/api/response" - "github.com/grafana/grafana/pkg/api/routing" - "github.com/grafana/grafana/pkg/models" - apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions" - - "github.com/grafana/grafana/pkg/web" "github.com/prometheus/alertmanager/api/metrics" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" + + "github.com/grafana/grafana/pkg/api/response" + "github.com/grafana/grafana/pkg/api/routing" + "github.com/grafana/grafana/pkg/models" + legacyMetrics "github.com/grafana/grafana/pkg/services/alerting/metrics" + apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions" + + "github.com/grafana/grafana/pkg/web" ) const ( @@ -52,6 +54,7 @@ type Scheduler struct { EvalDuration *prometheus.SummaryVec GetAlertRulesDuration prometheus.Histogram SchedulePeriodicDuration prometheus.Histogram + Ticker *legacyMetrics.Ticker } type MultiOrgAlertmanager struct { @@ -179,6 +182,7 @@ func newSchedulerMetrics(r prometheus.Registerer) *Scheduler { Buckets: []float64{0.1, 0.25, 0.5, 1, 2, 5, 10}, }, ), + Ticker: legacyMetrics.NewTickerMetrics(r), } } diff --git a/pkg/services/ngalert/schedule/schedule.go b/pkg/services/ngalert/schedule/schedule.go index a15438d5f8d..04ab92e7aff 100644 --- a/pkg/services/ngalert/schedule/schedule.go +++ b/pkg/services/ngalert/schedule/schedule.go @@ -31,8 +31,6 @@ type ScheduleService interface { // Run the scheduler until the context is canceled or the scheduler returns // an error. The scheduler is terminated when this function returns. Run(context.Context) error - Pause() error - Unpause() error // AlertmanagersFor returns all the discovered Alertmanager URLs for the // organization. @@ -123,7 +121,7 @@ type SchedulerCfg struct { // NewScheduler returns a new schedule. func NewScheduler(cfg SchedulerCfg, expressionService *expr.Service, appURL *url.URL, stateManager *state.Manager) *schedule { - ticker := alerting.NewTicker(cfg.C.Now(), time.Second*0, cfg.C, int64(cfg.BaseInterval.Seconds())) + ticker := alerting.NewTicker(cfg.C, cfg.BaseInterval, cfg.Metrics.Ticker) sch := schedule{ registry: alertRuleRegistry{alertRuleInfo: make(map[models.AlertRuleKey]*alertRuleInfo)}, @@ -154,24 +152,6 @@ func NewScheduler(cfg SchedulerCfg, expressionService *expr.Service, appURL *url return &sch } -func (sch *schedule) Pause() error { - if sch == nil { - return fmt.Errorf("scheduler is not initialised") - } - sch.ticker.Pause() - sch.log.Info("alert rule scheduler paused", "now", sch.clock.Now()) - return nil -} - -func (sch *schedule) Unpause() error { - if sch == nil { - return fmt.Errorf("scheduler is not initialised") - } - sch.ticker.Unpause() - sch.log.Info("alert rule scheduler unpaused", "now", sch.clock.Now()) - return nil -} - func (sch *schedule) Run(ctx context.Context) error { var wg sync.WaitGroup wg.Add(2) @@ -789,7 +769,7 @@ type evaluation struct { func (sch *schedule) overrideCfg(cfg SchedulerCfg) { sch.clock = cfg.C sch.baseInterval = cfg.BaseInterval - sch.ticker = alerting.NewTicker(cfg.C.Now(), time.Second*0, cfg.C, int64(cfg.BaseInterval.Seconds())) + sch.ticker = alerting.NewTicker(cfg.C, cfg.BaseInterval, cfg.Metrics.Ticker) sch.evalAppliedFunc = cfg.EvalAppliedFunc sch.stopAppliedFunc = cfg.StopAppliedFunc } diff --git a/pkg/tests/testinfra/testinfra.go b/pkg/tests/testinfra/testinfra.go index ad7d5f3029a..251a62ca3d5 100644 --- a/pkg/tests/testinfra/testinfra.go +++ b/pkg/tests/testinfra/testinfra.go @@ -12,15 +12,16 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "gopkg.in/ini.v1" + "github.com/grafana/grafana/pkg/api" "github.com/grafana/grafana/pkg/infra/fs" "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/server" "github.com/grafana/grafana/pkg/services/sqlstore" "github.com/grafana/grafana/pkg/setting" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "gopkg.in/ini.v1" ) // StartGrafana starts a Grafana server. From 2b2f275a08847151da70d1277683697451b4722d Mon Sep 17 00:00:00 2001 From: Nathan Marrs Date: Fri, 22 Apr 2022 14:02:36 -0700 Subject: [PATCH 106/120] Canvas: Support scale + center constraints (#48085) --- .../app/features/canvas/runtime/element.tsx | 181 +++++++++++------- public/app/features/canvas/runtime/scene.tsx | 5 +- .../panel/canvas/editor/PlacementEditor.tsx | 17 +- 3 files changed, 123 insertions(+), 80 deletions(-) diff --git a/public/app/features/canvas/runtime/element.tsx b/public/app/features/canvas/runtime/element.tsx index 17f0225a019..37000ed02bd 100644 --- a/public/app/features/canvas/runtime/element.tsx +++ b/public/app/features/canvas/runtime/element.tsx @@ -42,12 +42,6 @@ export class ElementState implements LayerElement { horizontal: HorizontalConstraint.Left, }; options.placement = options.placement ?? { width: 100, height: 100, top: 0, left: 0 }; - this.validatePlacement(); - this.sizeStyle = { - ...options.placement, - position: 'absolute', - }; - const scene = this.getScene(); if (!options.name) { const newName = scene?.getNextElementName(); @@ -61,7 +55,6 @@ export class ElementState implements LayerElement { while (trav) { if (trav.isRoot()) { return trav.scene; - break; } trav = trav.parent; } @@ -73,48 +66,108 @@ export class ElementState implements LayerElement { return this.options.name; } - validatePlacement() { - const { constraint, placement } = this.options; + /** Use the configured options to update CSS style properties directly on the wrapper div **/ + applyLayoutStylesToDiv() { + const { constraint } = this.options; const { vertical, horizontal } = constraint ?? {}; - const updatedPlacement = placement ?? ({} as Placement); + const placement = this.options.placement ?? ({} as Placement); + + const style: React.CSSProperties = { + position: 'absolute', + }; + + const translate = ['0px', '0px']; switch (vertical) { case VerticalConstraint.Top: - updatedPlacement.top = updatedPlacement.top ?? 0; - updatedPlacement.height = updatedPlacement.height ?? 100; - delete updatedPlacement.bottom; + placement.top = placement.top ?? 0; + placement.height = placement.height ?? 100; + style.top = `${placement.top}px`; + style.height = `${placement.height}px`; + delete placement.bottom; break; case VerticalConstraint.Bottom: - updatedPlacement.bottom = updatedPlacement.bottom ?? 0; - updatedPlacement.height = updatedPlacement.height ?? 100; - delete updatedPlacement.top; + placement.bottom = placement.bottom ?? 0; + placement.height = placement.height ?? 100; + style.bottom = `${placement.bottom}px`; + style.height = `${placement.height}px`; + delete placement.top; break; case VerticalConstraint.TopBottom: - updatedPlacement.top = updatedPlacement.top ?? 0; - updatedPlacement.bottom = updatedPlacement.bottom ?? 0; - delete updatedPlacement.height; + placement.top = placement.top ?? 0; + placement.bottom = placement.bottom ?? 0; + style.top = `${placement.top}px`; + style.bottom = `${placement.bottom}px`; + delete placement.height; + break; + case VerticalConstraint.Center: + placement.top = placement.top ?? 0; + placement.height = placement.height ?? 100; + translate[1] = '-50%'; + style.top = `calc(50% - ${placement.top}px)`; + style.height = `${placement.height}px`; + delete placement.bottom; + break; + case VerticalConstraint.Scale: + placement.top = placement.top ?? 0; + placement.bottom = placement.bottom ?? 0; + style.top = `${placement.top}%`; + style.bottom = `${placement.bottom}%`; + delete placement.height; break; } switch (horizontal) { case HorizontalConstraint.Left: - updatedPlacement.left = updatedPlacement.left ?? 0; - updatedPlacement.width = updatedPlacement.width ?? 100; - delete updatedPlacement.right; + placement.left = placement.left ?? 0; + placement.width = placement.width ?? 100; + style.left = `${placement.left}px`; + style.width = `${placement.width}px`; + delete placement.right; break; case HorizontalConstraint.Right: - updatedPlacement.right = updatedPlacement.right ?? 0; - updatedPlacement.width = updatedPlacement.width ?? 100; - delete updatedPlacement.left; + placement.right = placement.right ?? 0; + placement.width = placement.width ?? 100; + style.right = `${placement.right}px`; + style.width = `${placement.width}px`; + delete placement.left; break; case HorizontalConstraint.LeftRight: - updatedPlacement.left = updatedPlacement.left ?? 0; - updatedPlacement.right = updatedPlacement.right ?? 0; - delete updatedPlacement.width; + placement.left = placement.left ?? 0; + placement.right = placement.right ?? 0; + style.left = `${placement.left}px`; + style.right = `${placement.right}px`; + delete placement.width; + break; + case HorizontalConstraint.Center: + placement.left = placement.left ?? 0; + placement.width = placement.width ?? 100; + translate[0] = '-50%'; + style.left = `calc(50% - ${placement.left}px)`; + style.width = `${placement.width}px`; + delete placement.right; + break; + case HorizontalConstraint.Scale: + placement.left = placement.left ?? 0; + placement.right = placement.right ?? 0; + style.left = `${placement.left}%`; + style.right = `${placement.right}%`; + delete placement.width; break; } - this.options.placement = updatedPlacement; + style.transform = `translate(${translate[0]}, ${translate[1]})`; + this.options.placement = placement; + this.sizeStyle = style; + if (this.div) { + for (const key in this.sizeStyle) { + this.div.style[key as any] = (this.sizeStyle as any)[key]; + } + + for (const key in this.dataStyle) { + this.div.style[key as any] = (this.dataStyle as any)[key]; + } + } } setPlacementFromConstraint() { @@ -151,6 +204,17 @@ export class ElementState implements LayerElement { placement.top = relativeTop; placement.bottom = relativeBottom; break; + case VerticalConstraint.Center: + const elementCenter = elementContainer ? relativeTop + height / 2 : 0; + const parentCenter = parentContainer ? parentContainer.height / 2 : 0; + const distanceFromCenter = parentCenter - elementCenter; + placement.top = distanceFromCenter; + placement.height = height; + break; + case VerticalConstraint.Scale: + placement.top = (relativeTop / (parentContainer?.height ?? height)) * 100; + placement.bottom = (relativeBottom / (parentContainer?.height ?? height)) * 100; + break; } switch (horizontal) { @@ -166,13 +230,22 @@ export class ElementState implements LayerElement { placement.left = relativeLeft; placement.right = relativeRight; break; + case HorizontalConstraint.Center: + const elementCenter = elementContainer ? relativeLeft + width / 2 : 0; + const parentCenter = parentContainer ? parentContainer.width / 2 : 0; + const distanceFromCenter = parentCenter - elementCenter; + placement.left = distanceFromCenter; + placement.width = width; + break; + case HorizontalConstraint.Scale: + placement.left = (relativeLeft / (parentContainer?.width ?? width)) * 100; + placement.right = (relativeRight / (parentContainer?.width ?? width)) * 100; + break; } this.options.placement = placement; - this.sizeStyle = { - ...this.options.placement, - position: 'absolute', - }; + + this.applyLayoutStylesToDiv(); this.revId++; } @@ -273,45 +346,11 @@ export class ElementState implements LayerElement { initElement = (target: HTMLDivElement) => { this.div = target; + this.applyLayoutStylesToDiv(); }; applyDrag = (event: OnDrag) => { - const { options } = this; - const { placement, constraint } = options; - const { vertical, horizontal } = constraint ?? {}; - - const deltaX = event.delta[0]; - const deltaY = event.delta[1]; - - const style = event.target.style; - - const isConstrainedTop = vertical === VerticalConstraint.Top || vertical === VerticalConstraint.TopBottom; - const isConstrainedBottom = vertical === VerticalConstraint.Bottom || vertical === VerticalConstraint.TopBottom; - const isConstrainedLeft = horizontal === HorizontalConstraint.Left || horizontal === HorizontalConstraint.LeftRight; - const isConstrainedRight = - horizontal === HorizontalConstraint.Right || horizontal === HorizontalConstraint.LeftRight; - - if (isConstrainedTop) { - placement!.top! += deltaY; - style.top = `${placement!.top}px`; - } - - if (isConstrainedBottom) { - placement!.bottom! -= deltaY; - style.bottom = `${placement!.bottom}px`; - } - - if (isConstrainedLeft) { - placement!.left! += deltaX; - style.left = `${placement!.left}px`; - } - - if (isConstrainedRight) { - placement!.right! -= deltaX; - style.right = `${placement!.right}px`; - } - - // TODO: Center + Scale + event.target.style.transform = event.transform; }; // kinda like: @@ -380,14 +419,12 @@ export class ElementState implements LayerElement { style.height = `${placement!.height}px`; } } - - // TODO: Center + Scale }; render() { const { item } = this; return ( -
      +
      ); diff --git a/public/app/features/canvas/runtime/scene.tsx b/public/app/features/canvas/runtime/scene.tsx index a0e1b934693..0db06d31aff 100644 --- a/public/app/features/canvas/runtime/scene.tsx +++ b/public/app/features/canvas/runtime/scene.tsx @@ -255,21 +255,20 @@ export class Scene { .on('drag', (event) => { const targetedElement = this.findElementByTarget(event.target); targetedElement!.applyDrag(event); - this.moved.next(Date.now()); // TODO only on end }) .on('dragGroup', (e) => { e.events.forEach((event) => { const targetedElement = this.findElementByTarget(event.target); targetedElement!.applyDrag(event); }); - this.moved.next(Date.now()); // TODO only on end }) .on('dragEnd', (event) => { const targetedElement = this.findElementByTarget(event.target); - if (targetedElement) { targetedElement?.setPlacementFromConstraint(); } + + this.moved.next(Date.now()); }) .on('resize', (event) => { const targetedElement = this.findElementByTarget(event.target); diff --git a/public/app/plugins/panel/canvas/editor/PlacementEditor.tsx b/public/app/plugins/panel/canvas/editor/PlacementEditor.tsx index a670332b936..b64564f6dc4 100644 --- a/public/app/plugins/panel/canvas/editor/PlacementEditor.tsx +++ b/public/app/plugins/panel/canvas/editor/PlacementEditor.tsx @@ -17,18 +17,19 @@ const horizontalOptions: Array> = [ { label: 'Left', value: HorizontalConstraint.Left }, { label: 'Right', value: HorizontalConstraint.Right }, { label: 'Left and right', value: HorizontalConstraint.LeftRight }, + { label: 'Center', value: HorizontalConstraint.Center }, + { label: 'Scale', value: HorizontalConstraint.Scale }, ]; const verticalOptions: Array> = [ { label: 'Top', value: VerticalConstraint.Top }, { label: 'Bottom', value: VerticalConstraint.Bottom }, { label: 'Top and bottom', value: VerticalConstraint.TopBottom }, + { label: 'Center', value: VerticalConstraint.Center }, + { label: 'Scale', value: VerticalConstraint.Scale }, ]; -export const PlacementEditor: FC> = ({ - item, - onChange, -}) => { +export const PlacementEditor: FC> = ({ item }) => { const settings = item.settings; // Will force a rerender whenever the subject changes @@ -59,6 +60,12 @@ export const PlacementEditor: FC { + element.options.placement![placement] = value ?? element.options.placement![placement]; + element.applyLayoutStylesToDiv(); + settings.scene.clearCurrentSelection(); + }; + return (
      @@ -81,7 +88,7 @@ export const PlacementEditor: FC - console.log('TODO, edit!!!', p, v)} /> + onPositionChange(v, p)} /> ); From 1c977281c8a17a63aada8dc2adbbf49fa06059e7 Mon Sep 17 00:00:00 2001 From: Leon Sorokin Date: Fri, 22 Apr 2022 19:33:25 -0500 Subject: [PATCH 107/120] TimeSeries: sync minimum bar width across all bar series (#48030) --- .../src/components/GraphNG/utils.test.ts | 299 ++++++++++++++++++ .../src/components/GraphNG/utils.ts | 86 +++-- 2 files changed, 367 insertions(+), 18 deletions(-) diff --git a/packages/grafana-ui/src/components/GraphNG/utils.test.ts b/packages/grafana-ui/src/components/GraphNG/utils.test.ts index 7395c859226..31a4bb00209 100644 --- a/packages/grafana-ui/src/components/GraphNG/utils.test.ts +++ b/packages/grafana-ui/src/components/GraphNG/utils.test.ts @@ -1,6 +1,8 @@ import { + ArrayVector, createTheme, DashboardCursorSync, + DataFrame, DefaultTimeZone, EventBusSrv, FieldConfig, @@ -204,4 +206,301 @@ describe('GraphNG utils', () => { }).getConfig(); expect(result).toMatchSnapshot(); }); + + test('preparePlotFrame appends min bar spaced nulls when > 1 bar series', () => { + const df1: DataFrame = { + name: 'A', + length: 5, + fields: [ + { + name: 'time', + type: FieldType.time, + config: {}, + values: new ArrayVector([1, 2, 4, 6, 100]), // should find smallest delta === 1 from here + }, + { + name: 'value', + type: FieldType.number, + config: { + custom: { + drawStyle: GraphDrawStyle.Bars, + }, + }, + values: new ArrayVector([1, 1, 1, 1, 1]), + }, + ], + }; + + const df2: DataFrame = { + name: 'B', + length: 5, + fields: [ + { + name: 'time', + type: FieldType.time, + config: {}, + values: new ArrayVector([30, 40, 50, 90, 100]), // should be appended with two smallest-delta increments + }, + { + name: 'value', + type: FieldType.number, + config: { + custom: { + drawStyle: GraphDrawStyle.Bars, + }, + }, + values: new ArrayVector([2, 2, 2, 2, 2]), // bar series should be appended with nulls + }, + { + name: 'value', + type: FieldType.number, + config: { + custom: { + drawStyle: GraphDrawStyle.Line, + }, + }, + values: new ArrayVector([3, 3, 3, 3, 3]), // line series should be appended with undefineds + }, + ], + }; + + const df3: DataFrame = { + name: 'C', + length: 2, + fields: [ + { + name: 'time', + type: FieldType.time, + config: {}, + values: new ArrayVector([1, 1.1]), // should not trip up on smaller deltas of non-bars + }, + { + name: 'value', + type: FieldType.number, + config: { + custom: { + drawStyle: GraphDrawStyle.Line, + }, + }, + values: new ArrayVector([4, 4]), + }, + { + name: 'value', + type: FieldType.number, + config: { + custom: { + drawStyle: GraphDrawStyle.Bars, + hideFrom: { + viz: true, // should ignore hidden bar series + }, + }, + }, + values: new ArrayVector([4, 4]), + }, + ], + }; + + let aligndFrame = preparePlotFrame([df1, df2, df3], { + x: fieldMatchers.get(FieldMatcherID.firstTimeField).get({}), + y: fieldMatchers.get(FieldMatcherID.numeric).get({}), + }); + + expect(aligndFrame).toMatchInlineSnapshot(` + Object { + "fields": Array [ + Object { + "config": Object {}, + "name": "time", + "state": Object { + "origin": Object { + "fieldIndex": 0, + "frameIndex": 0, + }, + }, + "type": "time", + "values": Array [ + 1, + 1.1, + 2, + 4, + 6, + 30, + 40, + 50, + 90, + 100, + 101, + 102, + ], + }, + Object { + "config": Object { + "custom": Object { + "drawStyle": "bars", + "spanNulls": -1, + }, + }, + "labels": Object { + "name": "A", + }, + "name": "value", + "state": Object { + "origin": Object { + "fieldIndex": 1, + "frameIndex": 0, + }, + }, + "type": "number", + "values": Array [ + 1, + undefined, + 1, + 1, + 1, + undefined, + undefined, + undefined, + undefined, + 1, + null, + null, + ], + }, + Object { + "config": Object { + "custom": Object { + "drawStyle": "bars", + "spanNulls": -1, + }, + }, + "labels": Object { + "name": "B", + }, + "name": "value", + "state": Object { + "origin": Object { + "fieldIndex": 1, + "frameIndex": 1, + }, + }, + "type": "number", + "values": Array [ + undefined, + undefined, + undefined, + undefined, + undefined, + 2, + 2, + 2, + 2, + 2, + null, + null, + ], + }, + Object { + "config": Object { + "custom": Object { + "drawStyle": "line", + }, + }, + "labels": Object { + "name": "B", + }, + "name": "value", + "state": Object { + "origin": Object { + "fieldIndex": 2, + "frameIndex": 1, + }, + }, + "type": "number", + "values": Array [ + undefined, + undefined, + undefined, + undefined, + undefined, + 3, + 3, + 3, + 3, + 3, + undefined, + undefined, + ], + }, + Object { + "config": Object { + "custom": Object { + "drawStyle": "line", + }, + }, + "labels": Object { + "name": "C", + }, + "name": "value", + "state": Object { + "origin": Object { + "fieldIndex": 1, + "frameIndex": 2, + }, + }, + "type": "number", + "values": Array [ + 4, + 4, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ], + }, + Object { + "config": Object { + "custom": Object { + "drawStyle": "bars", + "hideFrom": Object { + "viz": true, + }, + }, + }, + "labels": Object { + "name": "C", + }, + "name": "value", + "state": Object { + "origin": Object { + "fieldIndex": 2, + "frameIndex": 2, + }, + }, + "type": "number", + "values": Array [ + 4, + 4, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ], + }, + ], + "length": 10, + } + `); + }); }); diff --git a/packages/grafana-ui/src/components/GraphNG/utils.ts b/packages/grafana-ui/src/components/GraphNG/utils.ts index 41558d9bd3c..3abea36bb97 100644 --- a/packages/grafana-ui/src/components/GraphNG/utils.ts +++ b/packages/grafana-ui/src/components/GraphNG/utils.ts @@ -1,4 +1,4 @@ -import { ArrayVector, DataFrame, FieldConfig, FieldType, outerJoinDataFrames, TimeRange } from '@grafana/data'; +import { ArrayVector, DataFrame, Field, FieldConfig, FieldType, outerJoinDataFrames, TimeRange } from '@grafana/data'; import { AxisPlacement, GraphDrawStyle, @@ -12,6 +12,10 @@ import { applyNullInsertThreshold } from './nullInsertThreshold'; import { nullToUndefThreshold } from './nullToUndefThreshold'; import { XYFieldMatchers } from './types'; +function isVisibleBarField(f: Field) { + return f.config.custom?.drawStyle === GraphDrawStyle.Bars && !f.config.custom?.hideFrom?.viz; +} + // will mutate the DataFrame's fields' values function applySpanNullsThresholds(frame: DataFrame) { let refField = frame.fields.find((field) => field.type === FieldType.time); // this doesnt need to be time, just any numeric/asc join field @@ -20,7 +24,7 @@ function applySpanNullsThresholds(frame: DataFrame) { for (let i = 0; i < frame.fields.length; i++) { let field = frame.fields[i]; - if (field === refField) { + if (field === refField || isVisibleBarField(field)) { continue; } @@ -37,30 +41,76 @@ function applySpanNullsThresholds(frame: DataFrame) { } export function preparePlotFrame(frames: DataFrame[], dimFields: XYFieldMatchers, timeRange?: TimeRange | null) { - let alignedFrame = outerJoinDataFrames({ - frames: frames.map((frame) => { - let fr = applyNullInsertThreshold(frame, null, timeRange?.to.valueOf()); + // apply null insertions at interval + frames = frames.map((frame) => applyNullInsertThreshold(frame, null, timeRange?.to.valueOf())); - // prevent minesweeper-expansion of nulls (gaps) when joining bars - // since bar width is determined from the minimum distance between non-undefined values - // (this strategy will still retain any original pre-join nulls, though) - fr.fields.forEach((f) => { - if (f.type === FieldType.number && f.config.custom?.drawStyle === GraphDrawStyle.Bars) { - f.config.custom = { - ...f.config.custom, - spanNulls: -1, - }; + let numBarSeries = 0; + + frames.forEach((frame) => { + frame.fields.forEach((f) => { + if (isVisibleBarField(f)) { + // prevent minesweeper-expansion of nulls (gaps) when joining bars + // since bar width is determined from the minimum distance between non-undefined values + // (this strategy will still retain any original pre-join nulls, though) + f.config.custom = { + ...f.config.custom, + spanNulls: -1, + }; + + numBarSeries++; + } + }); + }); + + // to make bar widths of all series uniform (equal to narrowest bar series), find smallest distance between x points + let minXDelta = Infinity; + + if (numBarSeries > 1) { + frames.forEach((frame) => { + if (!frame.fields.some(isVisibleBarField)) { + return; + } + + const xVals = frame.fields[0].values.toArray(); + + for (let i = 0; i < xVals.length; i++) { + if (i > 0) { + minXDelta = Math.min(minXDelta, xVals[i] - xVals[i - 1]); } - }); + } + }); + } - return fr; - }), + let alignedFrame = outerJoinDataFrames({ + frames, joinBy: dimFields.x, keep: dimFields.y, keepOriginIndices: true, }); - return alignedFrame && applySpanNullsThresholds(alignedFrame); + if (alignedFrame) { + alignedFrame = applySpanNullsThresholds(alignedFrame); + + // append 2 null vals at minXDelta to bar series + if (minXDelta !== Infinity) { + alignedFrame.fields.forEach((f, fi) => { + let vals = f.values.toArray(); + + if (fi === 0) { + let lastVal = vals[vals.length - 1]; + vals.push(lastVal + minXDelta, lastVal + 2 * minXDelta); + } else if (isVisibleBarField(f)) { + vals.push(null, null); + } else { + vals.push(undefined, undefined); + } + }); + } + + return alignedFrame; + } + + return null; } export function buildScaleKey(config: FieldConfig) { From ea52663dd924609d85b0ea324fa919ca5f0eaa84 Mon Sep 17 00:00:00 2001 From: Christopher Moyer <35463610+chri2547@users.noreply.github.com> Date: Sat, 23 Apr 2022 08:29:16 -0500 Subject: [PATCH 108/120] Docs: Combines thresholds docs into a single topic (#47985) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * start updates * combines content into single topic * completes draft update * Update docs/sources/panels/configure-thresholds/_index.md Co-authored-by: Torkel Ödegaard * incorporates feedback * Update docs/sources/panels/configure-thresholds/_index.md Co-authored-by: Torkel Ödegaard * Update docs/sources/panels/configure-thresholds/_index.md Co-authored-by: Torkel Ödegaard * Update docs/sources/panels/configure-thresholds/_index.md Co-authored-by: Torkel Ödegaard * incorporates final feedback Co-authored-by: Torkel Ödegaard --- .../dashboard-management-maturity-levels.md | 2 +- docs/sources/dashboards/_index.md | 4 +- .../panels/configure-thresholds/_index.md | 90 +++++++++++++++++++ .../panels/specify-thresholds/_index.md | 11 --- .../specify-thresholds/about-thresholds.md | 26 ------ .../specify-thresholds/add-a-threshold.md | 29 ------ .../add-threshold-to-graph.md | 32 ------- .../specify-thresholds/delete-a-threshold.md | 20 ----- .../panels/working-with-panels/add-panel.md | 2 +- docs/sources/visualizations/graph-panel.md | 2 +- 10 files changed, 95 insertions(+), 123 deletions(-) create mode 100644 docs/sources/panels/configure-thresholds/_index.md delete mode 100644 docs/sources/panels/specify-thresholds/_index.md delete mode 100644 docs/sources/panels/specify-thresholds/about-thresholds.md delete mode 100644 docs/sources/panels/specify-thresholds/add-a-threshold.md delete mode 100644 docs/sources/panels/specify-thresholds/add-threshold-to-graph.md delete mode 100644 docs/sources/panels/specify-thresholds/delete-a-threshold.md diff --git a/docs/sources/best-practices/dashboard-management-maturity-levels.md b/docs/sources/best-practices/dashboard-management-maturity-levels.md index 268cd83d7dd..17ca84905e6 100644 --- a/docs/sources/best-practices/dashboard-management-maturity-levels.md +++ b/docs/sources/best-practices/dashboard-management-maturity-levels.md @@ -46,7 +46,7 @@ How can you tell you are here? - Compare like to like: split service dashboards when the magnitude differs. Make sure aggregated metrics don't drown out important information. - Expressive charts with meaningful use of color and normalizing axes where you can. - - Example of meaningful color: Blue means it's good, red means it's bad. [Thresholds]({{< relref "../panels/specify-thresholds/about-thresholds.md" >}}) can help with that. + - Example of meaningful color: Blue means it's good, red means it's bad. [Thresholds]({{< relref "../panels/configure-thresholds" >}}) can help with that. - Example of normalizing axes: When comparing CPU usage, measure by percentage rather than raw number, because machines can have a different number of cores. Normalizing CPU usage by the number of cores reduces cognitive load because the viewer can trust that at 100% all cores are being used, without having to know the number of CPUs. - Directed browsing cuts down on "guessing." - Template variables make it harder to “just browse” randomly or aimlessly. diff --git a/docs/sources/dashboards/_index.md b/docs/sources/dashboards/_index.md index 672c34883df..0c73e1a8696 100644 --- a/docs/sources/dashboards/_index.md +++ b/docs/sources/dashboards/_index.md @@ -13,7 +13,7 @@ Dashboard snapshots are static . Queries and expressions cannot be re-executed f Before you begin, ensure that you have configured a data source. See also: - [Working with Grafana dashboard UI]({{< relref "./dashboard-ui/_index.md" >}}) -- [Dashboard folders]({{< relref "./dashboard-folders.md" >}}) +- [Dashboard folders]({{< relref "./dashboard_folders.md" >}}) - [Create dashboard]({{< relref "./dashboard-create" >}}) - [Manage dashboards]({{< relref "./dashboard-manage.md" >}}) - [Annotations]({{< relref "./annotations.md" >}}) @@ -22,7 +22,7 @@ Before you begin, ensure that you have configured a data source. See also: - [Keyboard shortcuts]({{< relref "./shortcuts.md" >}}) - [Reporting]({{< relref "./reporting.md" >}}) - [Time range controls]({{< relref "./time-range-controls.md" >}}) -- [Dashboard version history]({{< relref "./dashboard-history.md" >}}) +- [Dashboard version history]({{< relref "./dashboard_history.md" >}}) - [Dashboard export and import]({{< relref "./export-import.md" >}}) - [Dashboard JSON model]({{< relref "./json-model.md" >}}) - [Scripted dashboards]({{< relref "./scripted-dashboards.md" >}}) diff --git a/docs/sources/panels/configure-thresholds/_index.md b/docs/sources/panels/configure-thresholds/_index.md new file mode 100644 index 00000000000..65ff85242f0 --- /dev/null +++ b/docs/sources/panels/configure-thresholds/_index.md @@ -0,0 +1,90 @@ +--- +title: 'Configure visualization thresholds' +menuTitle: 'Configure visualization thresholds' +description: 'This section includes information about using thresholds in your visualizations.' +weight: 300 +aliases: + [ + docs/grafana/latest/panels/thresholds/, + docs/grafana/latest/panels/, + docs/grafana/latest/panels/specify-thresholds/about-thresholds/, + docs/grafana/latest/panels/specify-thresholds/add-a-threshold/, + docs/grafana/latest/panels/specify-thresholds/add-threshold-to-graph/, + docs/grafana/latest/panels/specify-thresholds/delete-a-threshold/, + ] +--- + +# Configure visualization thresholds + +This section includes information about using thresholds in your visualizations. You'll learn about thresholds and their defaults, how to add or delete a threshold, and adding a threshold to a legacy panel. + +## About thresholds + +A threshold is a value that you specify for a metric that is visually reflected in a dashboard when the threshold value is met or exceeded. + +Thresholds provide one method for you to conditionally style and color your visualizations based on query results. You can apply thresholds to most, but not all, visualizations. For more information about visualizations, refer to [Visualization panels]({{< relref "../../visualizations" >}}). + +You can use thresholds to: + +- Color grid lines or grid ares areas in the [Time-series visualization]({{< relref "../../visualizations/time-series" >}}) +- Color lines in the [Time-series visualization]({{< relref "../../visualizations/time-series/graph-color-scheme/#from-thresholds" >}}) +- Color the background or value text in the [Stat visualization]({{< relref "../../visualizations/stat-panel" >}}) +- Color the gauge and threshold markers in the [Gauge visualization]({{< relref "../../visualizations/gauge-panel" >}}) +- Color markers in the [Geomap visualization]({{< relref "../../visualizations/geomap" >}}) +- Color cell text or background in the [Table visualization]({{< relref "../../visualizations/table" >}}) +- Define regions and region colors in the [State timeline visualization]({{< relref "../../visualizations/state-timeline" >}}) + +There are two types of thresholds: + +- **Absolute** thresholds are defined by a number. For example, 80 on a scale of 1 to 150. +- **Percentage** thresholds are defined relative to minimum or maximum. For example, 80 percent. + +### Default thresholds + +On visualizations that support it, Grafana sets default threshold values of: + +- 80 = red +- Base = green +- Mode = Absolute + +The **Base** value represents minus infinity. It is generally the “good” color. + +## Add or delete a threshold + +You can add as many thresholds to a panel as you want. Grafana automatically sorts thresholds values from highest to lowest. + +Delete a threshold when it is no longer relevant to your business operations. When you delete a threshold, the system removes the threshold from all visualizations that include the threshold. + +1. To add a threshold: + + a. Edit the panel to which you want to add a threshold. + + b. In the options side pane, locate the **Thresholds** section and click **+ Add threshold**. + + c. Select a threshold color, number, and mode. + Threshold mode applies to all thresholds on this panel. + + d. For a time-series panel, select a **Show thresholds** option. + +1. To delete a threshold, navigate to the panel that contains the threshold and click the trash icon next to the threshold you want to remove. + +## Add a threshold to a legacy graph panel + +In the Graph panel visualization, thresholds enable you to add lines or sections to a graph to make it easier to recognize when the graph crosses a threshold. + +1. Navigate to the graph panel to which you want to add a threshold. +1. On the **Panel** tab, click **Thresholds**. +1. Click **Add threshold**. +1. Complete the following fields: + - **T1 -** Both values are required to display a threshold. + - **lt** or **gt** - Select **lt** for less than or **gt** for greater than to indicate what the threshold applies to. + - **Value -** Enter a threshold value. Grafana draws a threshold line along the Y-axis at that value. + - **Color -** Choose a condition that corresponds to a color, or define your own color. + - **custom -** You define the fill color and line color. + - **critical -** Fill and line color are red. + - **warning -** Fill and line color are yellow. + - **ok -** Fill and line color are green. + - **Fill -** Controls whether the threshold fill is displayed. + - **Line -** Controls whether the threshold line is displayed. + - **Y-Axis -** Choose **left** or **right**. +1. Click **Save** to save the changes in the dashboard. diff --git a/docs/sources/panels/specify-thresholds/_index.md b/docs/sources/panels/specify-thresholds/_index.md deleted file mode 100644 index 7c879fc2116..00000000000 --- a/docs/sources/panels/specify-thresholds/_index.md +++ /dev/null @@ -1,11 +0,0 @@ -+++ -title = "Modify visualization text and background colors" -aliases = ["/docs/grafana/next/panels/thresholds/", "/docs/sources/panels/specify-thresholds/"] -weight = 300 -+++ - -# Modify visualization text and background colors - -Use thresholds to set the color of a visualization text and background. - -{{< section >}} diff --git a/docs/sources/panels/specify-thresholds/about-thresholds.md b/docs/sources/panels/specify-thresholds/about-thresholds.md deleted file mode 100644 index c99ae25c479..00000000000 --- a/docs/sources/panels/specify-thresholds/about-thresholds.md +++ /dev/null @@ -1,26 +0,0 @@ -+++ -title = "About thresholds" -weight = 10 -aliases = ["/docs/sources/panels/specify-thresholds/about-thresholds/"] -+++ - -# About thresholds - -Thresholds set the color of either the value text or the background based on conditions that you define. - -There are two types of thresholds: - -- **Absolute** thresholds are defined based on a number. For example, 80 on a scale of 1 to 150. -- **Percentage** thresholds are defined relative to minimum or maximum. For example, 80 percent. - -You can apply thresholds to most, but not all, visualizations. - -## Default thresholds - -On visualizations that support it, Grafana sets default threshold values of: - -- 80 = red -- Base = green -- Mode = Absolute - -The **Base** value represents minus infinity. It is generally the “good” color. diff --git a/docs/sources/panels/specify-thresholds/add-a-threshold.md b/docs/sources/panels/specify-thresholds/add-a-threshold.md deleted file mode 100644 index 27ce198f93a..00000000000 --- a/docs/sources/panels/specify-thresholds/add-a-threshold.md +++ /dev/null @@ -1,29 +0,0 @@ -+++ -title = "Add a threshold" -weight = 20 -aliases = ["/docs/sources/panels/specify-thresholds/add-a-threshold/"] -+++ - -# Add a threshold - -You can add as many thresholds to a panel as you want. Grafana automatically sorts thresholds from highest value to lowest. - -## Before you begin - -- [Add a panel to a dashboard]({{< relref "../working-with-panels/add-panel.md" >}}). - -**To add a threshold**: - -1. Edit the panel to which you want to add a threshold. -1. On the panel display options, locate the **Thresholds** section. -1. Click **+ Add threshold**. - - Grafana adds a threshold value and color. - -1. Accept the recommendations or edit the threshold. - - **Edit color:** To select a color, click the color dot. - - **Edit number:** To change the threshold value, click in the field and enter a number. -1. Select a **Threshold mode**. - Threshold mode applies to all thresholds on this panel. -1. In the **Show thresholds** drop-down, select a threshold display option. -1. Click **Save**. diff --git a/docs/sources/panels/specify-thresholds/add-threshold-to-graph.md b/docs/sources/panels/specify-thresholds/add-threshold-to-graph.md deleted file mode 100644 index edc6f2044a0..00000000000 --- a/docs/sources/panels/specify-thresholds/add-threshold-to-graph.md +++ /dev/null @@ -1,32 +0,0 @@ -+++ -title = "Add a threshold to a legacy graph panel" -weight = 40 -aliases = ["/docs/sources/panels/specify-thresholds/add-threshold-to-graph/"] -+++ - -# Add a threshold to a legacy graph panel - -In the Graph panel visualization, thresholds enable you to add lines or sections to a graph to make it easier to recognize when the graph crosses a threshold. - -## Before you begin - -- [Add a panel to a dashboard]({{< relref "../working-with-panels/add-panel.md" >}}). - -**To add a threshold to a graph panel**: - -1. Navigate to the graph panel to which you want to add a threshold. -1. On the **Panel** tab, click **Thresholds**. -1. Click **Add threshold**. -1. Complete the following fields: - - **T1 -** Both values are required to display a threshold. - - **lt** or **gt** - Select **lt** for less than or **gt** for greater than to indicate what the threshold applies to. - - **Value -** Enter a threshold value. Grafana draws a threshold line along the Y-axis at that value. - - **Color -** Choose a condition that corresponds to a color, or define your own color. - - **custom -** You define the fill color and line color. - - **critical -** Fill and line color are red. - - **warning -** Fill and line color are yellow. - - **ok -** Fill and line color are green. - - **Fill -** Controls whether the threshold fill is displayed. - - **Line -** Controls whether the threshold line is displayed. - - **Y-Axis -** Choose **left** or **right**. -1. Click **Save** to save the changes in the dashboard. diff --git a/docs/sources/panels/specify-thresholds/delete-a-threshold.md b/docs/sources/panels/specify-thresholds/delete-a-threshold.md deleted file mode 100644 index c673e211fc6..00000000000 --- a/docs/sources/panels/specify-thresholds/delete-a-threshold.md +++ /dev/null @@ -1,20 +0,0 @@ -+++ -title = "Delete a threshold" -weight = 30 -aliases = ["/docs/sources/panels/specify-thresholds/delete-a-threshold/"] -+++ - -# Delete a threshold - -Delete a threshold when it is no longer relevant to your business operations. When you delete a threshold, the system removes the threshold from all visualizations that include the threshold. - -## Before you begin - -- [Add a threshold]({{< relref "./add-a-threshold.md" >}}). - -**To delete a threshold**: - -1. Navigate to the panel to which you want to add a threshold. -1. Click the **Field** tab. (Or **Panel** tab for a graph panel.) -1. Click the trash can icon next to the threshold you want to remove. -1. Click **Save** to save the changes in the dashboard. diff --git a/docs/sources/panels/working-with-panels/add-panel.md b/docs/sources/panels/working-with-panels/add-panel.md index b35c960887c..7a09be1b9eb 100644 --- a/docs/sources/panels/working-with-panels/add-panel.md +++ b/docs/sources/panels/working-with-panels/add-panel.md @@ -47,7 +47,7 @@ Panels allow you to show your data in visual form. Each panel needs at least one - [Format data using value mapping]({{< relref "../format-data/about-value-mapping.md" >}}) - [Visualization-specific options]({{< relref "../../visualizations/_index.md" >}}) - [Override field values]({{< relref "../override-field-values/about-field-overrides.md" >}}) - - [Specify thresholds to set the color of visualization text and background]({{< relref "../specify-thresholds/about-thresholds.md" >}}) + - [Configure thresholds]({{< relref "../configure-thresholds/" >}}) - [Apply color to series and fields]({{< relref "./apply-color-to-series.md" >}}) 1. Add a note to describe the visualization (or describe your changes) and then click **Save** in the upper-right corner of the page. diff --git a/docs/sources/visualizations/graph-panel.md b/docs/sources/visualizations/graph-panel.md index 61e869246cb..6832bca406e 100644 --- a/docs/sources/visualizations/graph-panel.md +++ b/docs/sources/visualizations/graph-panel.md @@ -18,7 +18,7 @@ Graph visualizations allow you to apply: - [Alerts]({{< relref "../alerting/_index.md" >}}) - This is the only type of visualization that allows you to set alerts. - [Transform data]({{< relref "../panels/transform-data/add-transformation-to-data.md" >}}) - [Add a field override]({{< relref "../panels/override-field-values/add-a-field-override.md" >}}) -- [Add a threshold]({{< relref "../panels/specify-thresholds/add-a-threshold.md" >}}) +- [Configure thresholds]({{< relref "../panels/configure-thresholds/" >}}) ## Display options From 70a7b7383929868c570e1860fc5d9f36b258fab2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Sun, 24 Apr 2022 17:50:10 +0200 Subject: [PATCH 109/120] Preferences: Fixes broken preferences after recent merge (#48157) * Preferences: Fixes broken preferences after recent merge * Added check * Shorter syntax * Fixed test * Remove error, and remove duplicate call --- pkg/api/index.go | 17 ++++++----------- pkg/services/preference/prefimpl/pref.go | 1 + pkg/services/preference/prefimpl/pref_test.go | 2 +- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/pkg/api/index.go b/pkg/api/index.go index bc3b400037e..6528c5c8906 100644 --- a/pkg/api/index.go +++ b/pkg/api/index.go @@ -168,12 +168,12 @@ func (hs *HTTPServer) ReqCanAdminTeams(c *models.ReqContext) bool { return c.OrgRole == models.ROLE_ADMIN || (hs.Cfg.EditorsCanAdmin && c.OrgRole == models.ROLE_EDITOR) } -func (hs *HTTPServer) getNavTree(c *models.ReqContext, hasEditPerm bool) ([]*dtos.NavLink, error) { +func (hs *HTTPServer) getNavTree(c *models.ReqContext, hasEditPerm bool, prefs *pref.Preference) ([]*dtos.NavLink, error) { hasAccess := ac.HasAccess(hs.AccessControl, c) navTree := []*dtos.NavLink{} if hs.Features.IsEnabled(featuremgmt.FlagNewNavigation) { - savedItemsLinks, err := hs.buildSavedItemsNavLinks(c) + savedItemsLinks, err := hs.buildSavedItemsNavLinks(c, prefs) if err != nil { return nil, err } @@ -411,16 +411,11 @@ func (hs *HTTPServer) addHelpLinks(navTree []*dtos.NavLink, c *models.ReqContext return navTree } -func (hs *HTTPServer) buildSavedItemsNavLinks(c *models.ReqContext) ([]*dtos.NavLink, error) { +func (hs *HTTPServer) buildSavedItemsNavLinks(c *models.ReqContext, prefs *pref.Preference) ([]*dtos.NavLink, error) { savedItemsChildNavs := []*dtos.NavLink{} // query preferences table for any saved items - prefsQuery := pref.GetPreferenceWithDefaultsQuery{UserID: c.SignedInUser.UserId} - preference, err := hs.preferenceService.GetWithDefaults(c.Req.Context(), &prefsQuery) - if err != nil { - return nil, err - } - savedItems := preference.JSONData.Navbar.SavedItems + savedItems := prefs.JSONData.Navbar.SavedItems if len(savedItems) > 0 { for _, savedItem := range savedItems { @@ -665,7 +660,7 @@ func (hs *HTTPServer) setIndexViewData(c *models.ReqContext) (*dtos.IndexViewDat settings["dateFormats"] = hs.Cfg.DateFormats - prefsQuery := pref.GetPreferenceWithDefaultsQuery{UserID: c.SignedInUser.UserId} + prefsQuery := pref.GetPreferenceWithDefaultsQuery{UserID: c.UserId, OrgID: c.OrgId, Teams: c.Teams} prefs, err := hs.preferenceService.GetWithDefaults(c.Req.Context(), &prefsQuery) if err != nil { return nil, err @@ -690,7 +685,7 @@ func (hs *HTTPServer) setIndexViewData(c *models.ReqContext) (*dtos.IndexViewDat settings["appSubUrl"] = "" } - navTree, err := hs.getNavTree(c, hasEditPerm) + navTree, err := hs.getNavTree(c, hasEditPerm, prefs) if err != nil { return nil, err } diff --git a/pkg/services/preference/prefimpl/pref.go b/pkg/services/preference/prefimpl/pref.go index bf78d8d34a4..0acc2904c11 100644 --- a/pkg/services/preference/prefimpl/pref.go +++ b/pkg/services/preference/prefimpl/pref.go @@ -30,6 +30,7 @@ func (s *Service) GetWithDefaults(ctx context.Context, query *pref.GetPreference OrgID: query.OrgID, UserID: query.UserID, } + prefs, err := s.store.List(ctx, listQuery) if err != nil { return nil, err diff --git a/pkg/services/preference/prefimpl/pref_test.go b/pkg/services/preference/prefimpl/pref_test.go index 3c083c1cb68..2e6158ae56b 100644 --- a/pkg/services/preference/prefimpl/pref_test.go +++ b/pkg/services/preference/prefimpl/pref_test.go @@ -107,7 +107,7 @@ func TestPreferencesService(t *testing.T) { Theme: "light", Timezone: "UTC", } - query := &pref.GetPreferenceWithDefaultsQuery{} + query := &pref.GetPreferenceWithDefaultsQuery{OrgID: 1} preference, err := prefService.GetWithDefaults(context.Background(), query) require.NoError(t, err) expected := &pref.Preference{ From 2e599643f6a8c50c52b3667f4a1ce974a8cf6f36 Mon Sep 17 00:00:00 2001 From: Artur Wierzbicki Date: Mon, 25 Apr 2022 01:55:10 +0400 Subject: [PATCH 110/120] Previews: refactor (#47728) * #44449: return standard thumb service even if auth setup fails * #44449: remove dashboardPreviewsScheduler feature flag * #44449: externalize dashboardPreviews config * #44449: disable previews by default * #44449: rename logger * #44449: dashboardPreviewsAdmin feature requires dev mode * #44449: retrigger CII --- conf/defaults.ini | 19 ++++++++++++ .../src/types/featureToggles.gen.ts | 1 - pkg/services/featuremgmt/registry.go | 12 +++---- pkg/services/featuremgmt/toggles_gen.go | 4 --- pkg/services/thumbs/crawler.go | 27 ++++++++++------ pkg/services/thumbs/service.go | 26 +++++++++++----- pkg/setting/setting.go | 4 +++ pkg/setting/setting_dashboard_previews.go | 31 +++++++++++++++++++ .../search/hooks/useShowDashboardPreviews.ts | 2 +- 9 files changed, 94 insertions(+), 32 deletions(-) create mode 100644 pkg/setting/setting_dashboard_previews.go diff --git a/conf/defaults.ini b/conf/defaults.ini index 4bb5376c233..024a7066a1c 100644 --- a/conf/defaults.ini +++ b/conf/defaults.ini @@ -1176,3 +1176,22 @@ default_baselayer_config = # Enable or disable loading other base map layers enable_custom_baselayers = true + +#################################### Dashboard previews ##################################### + +[dashboard_previews.crawler] +# Number of dashboards rendered in parallel. Default is 6. +thread_count = + +# Timeout passed down to the Image Renderer plugin. It is used in two separate places within a single rendering request: +# First during the initial navigation to the dashboard and then when waiting for all the panels to load. Default is 20s. +# This setting should be expressed as a duration. Examples: 10s (seconds), 1m (minutes). +rendering_timeout = + +# Maximum duration of a single crawl. Default is 1h. +# This setting should be expressed as a duration. Examples: 10s (seconds), 1m (minutes). +max_crawl_duration = + +# Minimum interval between two subsequent scheduler runs. Default is 12h. +# This setting should be expressed as a duration. Examples: 10s (seconds), 1m (minutes). +scheduler_interval = diff --git a/packages/grafana-data/src/types/featureToggles.gen.ts b/packages/grafana-data/src/types/featureToggles.gen.ts index e5b4cb3e532..080394dd1a9 100644 --- a/packages/grafana-data/src/types/featureToggles.gen.ts +++ b/packages/grafana-data/src/types/featureToggles.gen.ts @@ -22,7 +22,6 @@ export interface FeatureToggles { serviceAccounts?: boolean; database_metrics?: boolean; dashboardPreviews?: boolean; - dashboardPreviewsScheduler?: boolean; dashboardPreviewsAdmin?: boolean; ['live-config']?: boolean; ['live-pipeline']?: boolean; diff --git a/pkg/services/featuremgmt/registry.go b/pkg/services/featuremgmt/registry.go index 6c18fb2a947..a96c4249061 100644 --- a/pkg/services/featuremgmt/registry.go +++ b/pkg/services/featuremgmt/registry.go @@ -39,14 +39,10 @@ var ( State: FeatureStateAlpha, }, { - Name: "dashboardPreviewsScheduler", - Description: "Schedule automatic updates to dashboard previews", - State: FeatureStateAlpha, - }, - { - Name: "dashboardPreviewsAdmin", - Description: "Manage the dashboard previews crawler process from the UI", - State: FeatureStateAlpha, + Name: "dashboardPreviewsAdmin", + Description: "Manage the dashboard previews crawler process from the UI", + State: FeatureStateAlpha, + RequiresDevMode: true, }, { Name: "live-config", diff --git a/pkg/services/featuremgmt/toggles_gen.go b/pkg/services/featuremgmt/toggles_gen.go index 0d762f26555..31978faca12 100644 --- a/pkg/services/featuremgmt/toggles_gen.go +++ b/pkg/services/featuremgmt/toggles_gen.go @@ -31,10 +31,6 @@ const ( // Create and show thumbnails for dashboard search results FlagDashboardPreviews = "dashboardPreviews" - // FlagDashboardPreviewsScheduler - // Schedule automatic updates to dashboard previews - FlagDashboardPreviewsScheduler = "dashboardPreviewsScheduler" - // FlagDashboardPreviewsAdmin // Manage the dashboard previews crawler process from the UI FlagDashboardPreviewsAdmin = "dashboardPreviewsAdmin" diff --git a/pkg/services/thumbs/crawler.go b/pkg/services/thumbs/crawler.go index c641455728c..7e65a3590cf 100644 --- a/pkg/services/thumbs/crawler.go +++ b/pkg/services/thumbs/crawler.go @@ -10,6 +10,7 @@ import ( "sync" "time" + "github.com/grafana/grafana/pkg/setting" "golang.org/x/sync/errgroup" "github.com/grafana/grafana/pkg/infra/log" @@ -19,8 +20,10 @@ import ( ) type simpleCrawler struct { - renderService rendering.Service - threadCount int + renderService rendering.Service + threadCount int + concurrentLimit int + renderingTimeout time.Duration glive *live.GrafanaLive thumbnailRepo thumbnailRepo @@ -36,13 +39,17 @@ type simpleCrawler struct { renderingSessionByOrgId map[int64]rendering.Session } -func newSimpleCrawler(renderService rendering.Service, gl *live.GrafanaLive, repo thumbnailRepo) dashRenderer { +func newSimpleCrawler(renderService rendering.Service, gl *live.GrafanaLive, repo thumbnailRepo, cfg *setting.Cfg, settings setting.DashboardPreviewsSettings) dashRenderer { + threadCount := int(settings.CrawlThreadCount) c := &simpleCrawler{ - renderService: renderService, - threadCount: 6, - glive: gl, - thumbnailRepo: repo, - log: log.New("thumbnails_crawler"), + // temporarily increases the concurrentLimit from the 'cfg.RendererConcurrentRequestLimit' to 'cfg.RendererConcurrentRequestLimit + crawlerThreadCount' + concurrentLimit: cfg.RendererConcurrentRequestLimit + threadCount, + renderingTimeout: settings.RenderingTimeout, + renderService: renderService, + threadCount: threadCount, + glive: gl, + thumbnailRepo: repo, + log: log.New("thumbnails_crawler"), status: crawlStatus{ State: initializing, Complete: 0, @@ -154,11 +161,11 @@ func (r *simpleCrawler) Run(ctx context.Context, auth CrawlerAuth, mode CrawlerM r.auth = auth r.opts = rendering.Opts{ TimeoutOpts: rendering.TimeoutOpts{ - Timeout: 20 * time.Second, + Timeout: r.renderingTimeout, RequestTimeoutMultiplier: 3, }, Theme: theme, - ConcurrentLimit: 10, + ConcurrentLimit: r.concurrentLimit, } r.renderingSessionByOrgId = make(map[int64]rendering.Session) diff --git a/pkg/services/thumbs/service.go b/pkg/services/thumbs/service.go index 45cba2828aa..72e0ccb450f 100644 --- a/pkg/services/thumbs/service.go +++ b/pkg/services/thumbs/service.go @@ -51,6 +51,8 @@ type thumbService struct { crawlLockServiceActionName string log log.Logger usageStatsService usagestats.Service + canRunCrawler bool + settings setting.DashboardPreviewsSettings } type crawlerScheduleOptions struct { @@ -67,30 +69,34 @@ func ProvideService(cfg *setting.Cfg, features featuremgmt.FeatureToggles, lockS if !features.IsEnabled(featuremgmt.FlagDashboardPreviews) { return &dummyService{} } - logger := log.New("thumbnails_service") + logger := log.New("previews_service") + logger.Info("initialized thumb", "settings", cfg.DashboardPreviews) thumbnailRepo := newThumbnailRepo(store) + canRunCrawler := true crawlerAuth, err := authSetupService.Setup(context.Background()) if err != nil { - logger.Error("Failed to setup auth for the dashboard previews crawler", "err", err) - return &dummyService{} + logger.Error("failed to setup auth for the dashboard previews crawler", "err", err) + canRunCrawler = false } t := &thumbService{ usageStatsService: usageStatsService, renderingService: renderService, - renderer: newSimpleCrawler(renderService, gl, thumbnailRepo), + renderer: newSimpleCrawler(renderService, gl, thumbnailRepo, cfg, cfg.DashboardPreviews), thumbnailRepo: thumbnailRepo, store: store, features: features, lockService: lockService, crawlLockServiceActionName: "dashboard-crawler", log: logger, + canRunCrawler: canRunCrawler, + settings: cfg.DashboardPreviews, scheduleOptions: crawlerScheduleOptions{ - tickerInterval: time.Hour, - crawlInterval: time.Hour * 12, - maxCrawlDuration: time.Hour, + tickerInterval: 5 * time.Minute, + crawlInterval: cfg.DashboardPreviews.SchedulerInterval, + maxCrawlDuration: cfg.DashboardPreviews.MaxCrawlDuration, crawlerMode: CrawlerModeThumbs, thumbnailKind: models.ThumbnailKindDefault, themes: []models.Theme{models.ThemeDark, models.ThemeLight}, @@ -401,6 +407,10 @@ func (hs *thumbService) getDashboardId(c *models.ReqContext, uid string) (int64, } func (hs *thumbService) runOnDemandCrawl(parentCtx context.Context, theme models.Theme, mode CrawlerMode, kind models.ThumbnailKind, authOpts rendering.AuthOpts) { + if !hs.canRunCrawler { + return + } + crawlerCtx, cancel := context.WithTimeout(parentCtx, hs.scheduleOptions.maxCrawlDuration) defer cancel() @@ -435,7 +445,7 @@ func (hs *thumbService) runScheduledCrawl(parentCtx context.Context) { } func (hs *thumbService) Run(ctx context.Context) error { - if !hs.features.IsEnabled(featuremgmt.FlagDashboardPreviewsScheduler) { + if !hs.canRunCrawler { return nil } diff --git a/pkg/setting/setting.go b/pkg/setting/setting.go index 58d695f41fc..43974b76986 100644 --- a/pkg/setting/setting.go +++ b/pkg/setting/setting.go @@ -439,6 +439,8 @@ type Cfg struct { // Query history QueryHistoryEnabled bool + + DashboardPreviews DashboardPreviewsSettings } type CommandLineArgs struct { @@ -1001,6 +1003,8 @@ func (cfg *Cfg) Load(args CommandLineArgs) error { cfg.readDataSourcesSettings() + cfg.DashboardPreviews = readDashboardPreviewsSettings(iniFile) + if VerifyEmailEnabled && !cfg.Smtp.Enabled { cfg.Logger.Warn("require_email_validation is enabled but smtp is disabled") } diff --git a/pkg/setting/setting_dashboard_previews.go b/pkg/setting/setting_dashboard_previews.go new file mode 100644 index 00000000000..f73e046e99f --- /dev/null +++ b/pkg/setting/setting_dashboard_previews.go @@ -0,0 +1,31 @@ +package setting + +import ( + "time" + + "gopkg.in/ini.v1" +) + +type DashboardPreviewsSettings struct { + SchedulerInterval time.Duration + MaxCrawlDuration time.Duration + RenderingTimeout time.Duration + CrawlThreadCount uint32 +} + +func readDashboardPreviewsSettings(iniFile *ini.File) DashboardPreviewsSettings { + maxThreadCount := uint32(20) + + s := DashboardPreviewsSettings{} + + previewsCrawlerSection := iniFile.Section("dashboard_previews.crawler") + s.CrawlThreadCount = uint32(previewsCrawlerSection.Key("thread_count").MustUint(6)) + if s.CrawlThreadCount > maxThreadCount { + s.CrawlThreadCount = maxThreadCount + } + + s.SchedulerInterval = previewsCrawlerSection.Key("scheduler_interval").MustDuration(12 * time.Hour) + s.MaxCrawlDuration = previewsCrawlerSection.Key("max_crawl_duration").MustDuration(1 * time.Hour) + s.RenderingTimeout = previewsCrawlerSection.Key("rendering_timeout").MustDuration(20 * time.Second) + return s +} diff --git a/public/app/features/search/hooks/useShowDashboardPreviews.ts b/public/app/features/search/hooks/useShowDashboardPreviews.ts index ebddd8b607b..80e50f37e7b 100644 --- a/public/app/features/search/hooks/useShowDashboardPreviews.ts +++ b/public/app/features/search/hooks/useShowDashboardPreviews.ts @@ -6,7 +6,7 @@ import { PREVIEWS_LOCAL_STORAGE_KEY } from '../constants'; export const useShowDashboardPreviews = () => { const previewFeatureEnabled = Boolean(config.featureToggles.dashboardPreviews); - const [showPreviews, setShowPreviews] = useLocalStorage(PREVIEWS_LOCAL_STORAGE_KEY, previewFeatureEnabled); + const [showPreviews, setShowPreviews] = useLocalStorage(PREVIEWS_LOCAL_STORAGE_KEY, false); return { showPreviews: Boolean(showPreviews && previewFeatureEnabled), previewFeatureEnabled, setShowPreviews }; }; From 68ca5b2e0561d33fd7910ae605b608225fbe3d87 Mon Sep 17 00:00:00 2001 From: Ieva Date: Mon, 25 Apr 2022 10:42:09 +0200 Subject: [PATCH 111/120] Access control: refactor RBAC checks (#48107) * refactor RBAC checks * fix a test * another test fix * and another --- pkg/api/annotations.go | 9 ++++----- pkg/api/dashboard_permission.go | 3 +-- pkg/api/dashboard_permission_test.go | 1 + pkg/api/folder_permission.go | 3 +-- pkg/api/folder_permission_test.go | 1 + pkg/api/index.go | 2 +- pkg/api/org.go | 3 +-- pkg/api/team.go | 15 +++++++-------- pkg/api/team_members.go | 9 ++++----- pkg/services/comments/commentmodel/permissions.go | 2 +- .../datasources/service/datasource_service.go | 4 +++- .../service/datasource_service_test.go | 2 +- pkg/services/guardian/provider.go | 2 +- 13 files changed, 27 insertions(+), 29 deletions(-) diff --git a/pkg/api/annotations.go b/pkg/api/annotations.go index fee82d3fbb8..7aa1a2a3a2e 100644 --- a/pkg/api/annotations.go +++ b/pkg/api/annotations.go @@ -12,7 +12,6 @@ import ( "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/annotations" - "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/guardian" "github.com/grafana/grafana/pkg/util" "github.com/grafana/grafana/pkg/web" @@ -275,7 +274,7 @@ func (hs *HTTPServer) MassDeleteAnnotations(c *models.ReqContext) response.Respo // validations only for RBAC. A user can mass delete all annotations in a (dashboard + panel) or a specific annotation // if has access to that dashboard. - if hs.Features.IsEnabled(featuremgmt.FlagAccesscontrol) { + if !hs.AccessControl.IsDisabled() { var dashboardId int64 if cmd.AnnotationId != 0 { @@ -351,7 +350,7 @@ func (hs *HTTPServer) canSaveAnnotation(c *models.ReqContext, annotation *annota if annotation.GetType() == annotations.Dashboard { return canEditDashboard(c, annotation.DashboardId) } else { - if !hs.Features.IsEnabled(featuremgmt.FlagAccesscontrol) { + if hs.AccessControl.IsDisabled() { return c.SignedInUser.HasRole(models.ROLE_EDITOR), nil } return true, nil @@ -446,7 +445,7 @@ func AnnotationTypeScopeResolver() (string, accesscontrol.AttributeScopeResolveF func (hs *HTTPServer) canCreateAnnotation(c *models.ReqContext, dashboardId int64) (bool, error) { if dashboardId != 0 { - if hs.Features.IsEnabled(featuremgmt.FlagAccesscontrol) { + if !hs.AccessControl.IsDisabled() { evaluator := accesscontrol.EvalPermission(accesscontrol.ActionAnnotationsCreate, accesscontrol.ScopeAnnotationsTypeDashboard) if canSave, err := hs.AccessControl.Evaluate(c.Req.Context(), c.SignedInUser, evaluator); err != nil || !canSave { return canSave, err @@ -454,7 +453,7 @@ func (hs *HTTPServer) canCreateAnnotation(c *models.ReqContext, dashboardId int6 } return canEditDashboard(c, dashboardId) } else { // organization annotations - if hs.Features.IsEnabled(featuremgmt.FlagAccesscontrol) { + if !hs.AccessControl.IsDisabled() { evaluator := accesscontrol.EvalPermission(accesscontrol.ActionAnnotationsCreate, accesscontrol.ScopeAnnotationsTypeOrganization) return hs.AccessControl.Evaluate(c.Req.Context(), c.SignedInUser, evaluator) } else { diff --git a/pkg/api/dashboard_permission.go b/pkg/api/dashboard_permission.go index 45d105c9e4d..184c7c53c58 100644 --- a/pkg/api/dashboard_permission.go +++ b/pkg/api/dashboard_permission.go @@ -11,7 +11,6 @@ import ( "github.com/grafana/grafana/pkg/api/response" "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/accesscontrol" - "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/guardian" "github.com/grafana/grafana/pkg/web" ) @@ -133,7 +132,7 @@ func (hs *HTTPServer) UpdateDashboardPermissions(c *models.ReqContext) response. return response.Error(403, "Cannot remove own admin permission for a folder", nil) } - if hs.Features.IsEnabled(featuremgmt.FlagAccesscontrol) { + if !hs.AccessControl.IsDisabled() { old, err := g.GetAcl() if err != nil { return response.Error(500, "Error while checking dashboard permissions", err) diff --git a/pkg/api/dashboard_permission_test.go b/pkg/api/dashboard_permission_test.go index 18c9a90e0ca..136bb08e8a8 100644 --- a/pkg/api/dashboard_permission_test.go +++ b/pkg/api/dashboard_permission_test.go @@ -38,6 +38,7 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) { dashboardService: dashboardservice.ProvideDashboardService( settings, dashboardStore, nil, features, accesscontrolmock.NewPermissionsServicesMock(), ), + AccessControl: accesscontrolmock.New().WithDisabled(), } t.Run("Given user has no admin permissions", func(t *testing.T) { diff --git a/pkg/api/folder_permission.go b/pkg/api/folder_permission.go index 830c71b7afd..edaff924528 100644 --- a/pkg/api/folder_permission.go +++ b/pkg/api/folder_permission.go @@ -9,7 +9,6 @@ import ( "github.com/grafana/grafana/pkg/api/dtos" "github.com/grafana/grafana/pkg/api/response" "github.com/grafana/grafana/pkg/models" - "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/guardian" "github.com/grafana/grafana/pkg/util" "github.com/grafana/grafana/pkg/web" @@ -115,7 +114,7 @@ func (hs *HTTPServer) UpdateFolderPermissions(c *models.ReqContext) response.Res return response.Error(403, "Cannot remove own admin permission for a folder", nil) } - if hs.Features.IsEnabled(featuremgmt.FlagAccesscontrol) { + if !hs.AccessControl.IsDisabled() { old, err := g.GetAcl() if err != nil { return response.Error(500, "Error while checking dashboard permissions", err) diff --git a/pkg/api/folder_permission_test.go b/pkg/api/folder_permission_test.go index 9198f15e55b..24556b120d7 100644 --- a/pkg/api/folder_permission_test.go +++ b/pkg/api/folder_permission_test.go @@ -44,6 +44,7 @@ func TestFolderPermissionAPIEndpoint(t *testing.T) { dashboardService: service.ProvideDashboardService( settings, dashboardStore, nil, features, permissionsServices, ), + AccessControl: accesscontrolmock.New().WithDisabled(), } t.Run("Given folder not exists", func(t *testing.T) { diff --git a/pkg/api/index.go b/pkg/api/index.go index 6528c5c8906..42c0c18948c 100644 --- a/pkg/api/index.go +++ b/pkg/api/index.go @@ -733,7 +733,7 @@ func (hs *HTTPServer) setIndexViewData(c *models.ReqContext) (*dtos.IndexViewDat LoadingLogo: "public/img/grafana_icon.svg", } - if hs.Features.IsEnabled(featuremgmt.FlagAccesscontrol) { + if !hs.AccessControl.IsDisabled() { userPermissions, err := hs.AccessControl.GetUserPermissions(c.Req.Context(), c.SignedInUser, ac.Options{ReloadCache: false}) if err != nil { return nil, err diff --git a/pkg/api/org.go b/pkg/api/org.go index d6cd5b3799b..797cf7de76b 100644 --- a/pkg/api/org.go +++ b/pkg/api/org.go @@ -10,7 +10,6 @@ import ( "github.com/grafana/grafana/pkg/api/response" "github.com/grafana/grafana/pkg/infra/metrics" "github.com/grafana/grafana/pkg/models" - "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/sqlstore" "github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/util" @@ -90,7 +89,7 @@ func (hs *HTTPServer) CreateOrg(c *models.ReqContext) response.Response { if err := web.Bind(c.Req, &cmd); err != nil { return response.Error(http.StatusBadRequest, "bad request data", err) } - acEnabled := hs.Features.IsEnabled(featuremgmt.FlagAccesscontrol) + acEnabled := !hs.AccessControl.IsDisabled() if !acEnabled && !(setting.AllowUserOrgCreate || c.IsGrafanaAdmin) { return response.Error(403, "Access denied", nil) } diff --git a/pkg/api/team.go b/pkg/api/team.go index 79c0eac9982..cfd44400e06 100644 --- a/pkg/api/team.go +++ b/pkg/api/team.go @@ -8,7 +8,6 @@ import ( "github.com/grafana/grafana/pkg/api/dtos" "github.com/grafana/grafana/pkg/api/response" "github.com/grafana/grafana/pkg/models" - "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/util" "github.com/grafana/grafana/pkg/web" ) @@ -19,7 +18,7 @@ func (hs *HTTPServer) CreateTeam(c *models.ReqContext) response.Response { if err := web.Bind(c.Req, &cmd); err != nil { return response.Error(http.StatusBadRequest, "bad request data", err) } - accessControlEnabled := hs.Features.IsEnabled(featuremgmt.FlagAccesscontrol) + accessControlEnabled := !hs.AccessControl.IsDisabled() if !accessControlEnabled && c.OrgRole == models.ROLE_VIEWER { return response.Error(403, "Not allowed to create team.", nil) } @@ -63,7 +62,7 @@ func (hs *HTTPServer) UpdateTeam(c *models.ReqContext) response.Response { return response.Error(http.StatusBadRequest, "teamId is invalid", err) } - if !hs.Features.IsEnabled(featuremgmt.FlagAccesscontrol) { + if hs.AccessControl.IsDisabled() { if err := hs.teamGuardian.CanAdmin(c.Req.Context(), cmd.OrgId, cmd.Id, c.SignedInUser); err != nil { return response.Error(403, "Not allowed to update team", err) } @@ -88,7 +87,7 @@ func (hs *HTTPServer) DeleteTeamByID(c *models.ReqContext) response.Response { } user := c.SignedInUser - if !hs.Features.IsEnabled(featuremgmt.FlagAccesscontrol) { + if hs.AccessControl.IsDisabled() { if err := hs.teamGuardian.CanAdmin(c.Req.Context(), orgId, teamId, user); err != nil { return response.Error(403, "Not allowed to delete team", err) } @@ -116,7 +115,7 @@ func (hs *HTTPServer) SearchTeams(c *models.ReqContext) response.Response { // Using accesscontrol the filtering is done based on user permissions userIdFilter := models.FilterIgnoreUser - if !hs.Features.IsEnabled(featuremgmt.FlagAccesscontrol) { + if hs.AccessControl.IsDisabled() { userIdFilter = userFilter(c) } @@ -174,7 +173,7 @@ func (hs *HTTPServer) GetTeamByID(c *models.ReqContext) response.Response { // Using accesscontrol the filtering has already been performed at middleware layer userIdFilter := models.FilterIgnoreUser - if !hs.Features.IsEnabled(featuremgmt.FlagAccesscontrol) { + if hs.AccessControl.IsDisabled() { userIdFilter = userFilter(c) } @@ -210,7 +209,7 @@ func (hs *HTTPServer) GetTeamPreferences(c *models.ReqContext) response.Response orgId := c.OrgId - if !hs.Features.IsEnabled(featuremgmt.FlagAccesscontrol) { + if hs.AccessControl.IsDisabled() { if err := hs.teamGuardian.CanAdmin(c.Req.Context(), orgId, teamId, c.SignedInUser); err != nil { return response.Error(403, "Not allowed to view team preferences.", err) } @@ -233,7 +232,7 @@ func (hs *HTTPServer) UpdateTeamPreferences(c *models.ReqContext) response.Respo orgId := c.OrgId - if !hs.Features.IsEnabled(featuremgmt.FlagAccesscontrol) { + if hs.AccessControl.IsDisabled() { if err := hs.teamGuardian.CanAdmin(c.Req.Context(), orgId, teamId, c.SignedInUser); err != nil { return response.Error(403, "Not allowed to update team preferences.", err) } diff --git a/pkg/api/team_members.go b/pkg/api/team_members.go index a8c44cde66a..f0a7576da64 100644 --- a/pkg/api/team_members.go +++ b/pkg/api/team_members.go @@ -11,7 +11,6 @@ import ( "github.com/grafana/grafana/pkg/api/response" "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/accesscontrol" - "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/util" "github.com/grafana/grafana/pkg/web" ) @@ -27,7 +26,7 @@ func (hs *HTTPServer) GetTeamMembers(c *models.ReqContext) response.Response { // With accesscontrol the permission check has been done at middleware layer // and the membership filtering will be done at DB layer based on user permissions - if !hs.Features.IsEnabled(featuremgmt.FlagAccesscontrol) { + if hs.AccessControl.IsDisabled() { if err := hs.teamGuardian.CanAdmin(c.Req.Context(), query.OrgId, query.TeamId, c.SignedInUser); err != nil { return response.Error(403, "Not allowed to list team members", err) } @@ -70,7 +69,7 @@ func (hs *HTTPServer) AddTeamMember(c *models.ReqContext) response.Response { return response.Error(http.StatusBadRequest, "teamId is invalid", err) } - if !hs.Features.IsEnabled(featuremgmt.FlagAccesscontrol) { + if hs.AccessControl.IsDisabled() { if err := hs.teamGuardian.CanAdmin(c.Req.Context(), cmd.OrgId, cmd.TeamId, c.SignedInUser); err != nil { return response.Error(403, "Not allowed to add team member", err) } @@ -110,7 +109,7 @@ func (hs *HTTPServer) UpdateTeamMember(c *models.ReqContext) response.Response { } orgId := c.OrgId - if !hs.Features.IsEnabled(featuremgmt.FlagAccesscontrol) { + if hs.AccessControl.IsDisabled() { if err := hs.teamGuardian.CanAdmin(c.Req.Context(), orgId, teamId, c.SignedInUser); err != nil { return response.Error(403, "Not allowed to update team member", err) } @@ -153,7 +152,7 @@ func (hs *HTTPServer) RemoveTeamMember(c *models.ReqContext) response.Response { return response.Error(http.StatusBadRequest, "userId is invalid", err) } - if !hs.Features.IsEnabled(featuremgmt.FlagAccesscontrol) { + if hs.AccessControl.IsDisabled() { if err := hs.teamGuardian.CanAdmin(c.Req.Context(), orgId, teamId, c.SignedInUser); err != nil { return response.Error(403, "Not allowed to remove team member", err) } diff --git a/pkg/services/comments/commentmodel/permissions.go b/pkg/services/comments/commentmodel/permissions.go index b1bcbee82d1..33c17b3eca4 100644 --- a/pkg/services/comments/commentmodel/permissions.go +++ b/pkg/services/comments/commentmodel/permissions.go @@ -105,7 +105,7 @@ func (c *PermissionChecker) CheckWritePermissions(ctx context.Context, orgId int if !c.features.IsEnabled(featuremgmt.FlagAnnotationComments) { return false, nil } - if c.features.IsEnabled(featuremgmt.FlagAccesscontrol) { + if !c.accessControl.IsDisabled() { evaluator := accesscontrol.EvalPermission(accesscontrol.ActionAnnotationsWrite, accesscontrol.ScopeAnnotationsTypeDashboard) if canEdit, err := c.accessControl.Evaluate(ctx, signedInUser, evaluator); err != nil || !canEdit { return canEdit, err diff --git a/pkg/services/datasources/service/datasource_service.go b/pkg/services/datasources/service/datasource_service.go index 914f5ed0b26..dbc22e6e261 100644 --- a/pkg/services/datasources/service/datasource_service.go +++ b/pkg/services/datasources/service/datasource_service.go @@ -33,6 +33,7 @@ type Service struct { cfg *setting.Cfg features featuremgmt.FeatureToggles permissionsService accesscontrol.PermissionsService + ac accesscontrol.AccessControl ptc proxyTransportCache dsDecryptionCache secureJSONDecryptionCache @@ -74,6 +75,7 @@ func ProvideService( cfg: cfg, features: features, permissionsService: permissionsServices.GetDataSourceService(), + ac: ac, } ac.RegisterAttributeScopeResolver(NewNameScopeResolver(store)) @@ -162,7 +164,7 @@ func (s *Service) AddDataSource(ctx context.Context, cmd *models.AddDataSourceCo return err } - if s.features.IsEnabled(featuremgmt.FlagAccesscontrol) { + if !s.ac.IsDisabled() { // This belongs in Data source permissions, and we probably want // to do this with a hook in the store and rollback on fail. // We can't use events, because there's no way to communicate diff --git a/pkg/services/datasources/service/datasource_service_test.go b/pkg/services/datasources/service/datasource_service_test.go index 511b0f8c9b2..2df5cb86f50 100644 --- a/pkg/services/datasources/service/datasource_service_test.go +++ b/pkg/services/datasources/service/datasource_service_test.go @@ -38,7 +38,7 @@ func TestService(t *testing.T) { }) secretsService := secretsManager.SetupTestService(t, database.ProvideSecretsStore(sqlStore)) - s := ProvideService(sqlStore, secretsService, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewPermissionsServicesMock()) + s := ProvideService(sqlStore, secretsService, cfg, featuremgmt.WithFeatures(), acmock.New().WithDisabled(), acmock.NewPermissionsServicesMock()) var ds *models.DataSource diff --git a/pkg/services/guardian/provider.go b/pkg/services/guardian/provider.go index 5acccdf7774..3318fb45abb 100644 --- a/pkg/services/guardian/provider.go +++ b/pkg/services/guardian/provider.go @@ -12,7 +12,7 @@ import ( type Provider struct{} func ProvideService(store *sqlstore.SQLStore, ac accesscontrol.AccessControl, permissionsServices accesscontrol.PermissionsServices, features featuremgmt.FeatureToggles) *Provider { - if features.IsEnabled(featuremgmt.FlagAccesscontrol) { + if !ac.IsDisabled() { // TODO: Fix this hack, see https://github.com/grafana/grafana-enterprise/issues/2935 InitAcessControlGuardian(store, ac, permissionsServices) } else { From cb2c6fe6bc61571f83538590e808ffd41d791be8 Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Mon, 25 Apr 2022 12:30:33 +0200 Subject: [PATCH 112/120] AzureMonitor: Remove unused angular code (#48110) * remove unsued code * fix import --- public/app/angular/angular_wrappers.ts | 14 +-- .../partials/annotations.editor.html | 91 ------------------- 2 files changed, 1 insertion(+), 104 deletions(-) delete mode 100644 public/app/plugins/datasource/grafana-azure-monitor-datasource/partials/annotations.editor.html diff --git a/public/app/angular/angular_wrappers.ts b/public/app/angular/angular_wrappers.ts index 6827c913d8d..11d77c90a1d 100644 --- a/public/app/angular/angular_wrappers.ts +++ b/public/app/angular/angular_wrappers.ts @@ -15,8 +15,6 @@ import { FolderPicker } from 'app/core/components/Select/FolderPicker'; import { TimePickerSettings } from 'app/features/dashboard/components/DashboardSettings/TimePickerSettings'; import { AnnotationQueryEditor as CloudMonitoringAnnotationQueryEditor } from 'app/plugins/datasource/cloud-monitoring/components/AnnotationQueryEditor'; import { QueryEditor as CloudMonitoringQueryEditor } from 'app/plugins/datasource/cloud-monitoring/components/QueryEditor'; -import { AnnotationQueryEditor as CloudWatchAnnotationQueryEditor } from 'app/plugins/datasource/cloudwatch/components/AnnotationQueryEditor'; -import QueryEditor from 'app/plugins/datasource/grafana-azure-monitor-datasource/components/QueryEditor/QueryEditor'; import EmptyListCTA from '../core/components/EmptyListCTA/EmptyListCTA'; import { Footer } from '../core/components/Footer/Footer'; @@ -125,11 +123,7 @@ export function registerAngularDirectives() { ['datasource', { watchDepth: 'reference' }], ['templateSrv', { watchDepth: 'reference' }], ]); - react2AngularDirective('cloudwatchAnnotationQueryEditor', CloudWatchAnnotationQueryEditor, [ - 'query', - 'onChange', - ['datasource', { watchDepth: 'reference' }], - ]); + react2AngularDirective('secretFormField', SecretFormField, [ 'value', 'isConfigured', @@ -198,12 +192,6 @@ export function registerAngularDirectives() { ['onHideTimePickerChange', { watchDepth: 'reference', wrapApply: true }], ]); - react2AngularDirective('azureMonitorQueryEditor', QueryEditor, [ - 'query', - ['datasource', { watchDepth: 'reference' }], - 'onChange', - ]); - react2AngularDirective('clipboardButton', ClipboardButton, [ ['getText', { watchDepth: 'reference', wrapApply: true }], ]); diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/partials/annotations.editor.html b/public/app/plugins/datasource/grafana-azure-monitor-datasource/partials/annotations.editor.html deleted file mode 100644 index 206e2789159..00000000000 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/partials/annotations.editor.html +++ /dev/null @@ -1,91 +0,0 @@ -
      -
      - -
      - -
      -
      -
      - -
      - -
      -
      -
      -
      -
      - -
      - -
      -
      -
      -
      -
      -
      - -
      -
      - -
      -
      - -
      - -
      -
      - -
      -
      - -
      -
      - -
      -
      - -
      -
      Annotation Query Format
      -An annotation is an event that is overlaid on top of graphs. The query can have up to three columns per row, the datetime column is mandatory. Annotation rendering is expensive so it is important to limit the number of rows returned. - -- column with the datetime type. -- column with alias: Text or text for the annotation text -- column with alias: Tags or tags for annotation tags. This is should return a comma separated string of tags e.g. 'tag1,tag2' - -Macros: - - $__timeFilter() -> TimeGenerated ≥ datetime(2018-06-05T18:09:58.907Z) and TimeGenerated ≤ datetime(2018-06-05T20:09:58.907Z) - - $__timeFilter(datetimeColumn) -> datetimeColumn ≥ datetime(2018-06-05T18:09:58.907Z) and datetimeColumn ≤ datetime(2018-06-05T20:09:58.907Z) - - Or build your own conditionals using these built-in variables which just return the values: - - $__timeFrom -> datetime(2018-06-05T18:09:58.907Z) - - $__timeTo -> datetime(2018-06-05T20:09:58.907Z) - - $__interval -> 5m -
      -
      -
      From 7cfab776504a42ff3bf929e55fc0af43b9b5b0c9 Mon Sep 17 00:00:00 2001 From: Andres Martinez Gotor Date: Mon, 25 Apr 2022 03:34:12 -0700 Subject: [PATCH 113/120] AzureMonitor: Remove workaround in Logs editor (#48104) --- .../azure_log_analytics_datasource.test.ts | 5 +---- .../azure_log_analytics/response_parser.ts | 13 ++----------- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_log_analytics/azure_log_analytics_datasource.test.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_log_analytics/azure_log_analytics_datasource.test.ts index 5da7a4ab09f..6acfffb8630 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_log_analytics/azure_log_analytics_datasource.test.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_log_analytics/azure_log_analytics_datasource.test.ts @@ -138,10 +138,7 @@ describe('AzureLogAnalyticsDatasource', () => { it('should include template variables as global parameters', async () => { const result = await ctx.ds.azureLogAnalyticsDatasource.getKustoSchema('myWorkspace'); - expect(result.globalParameters.map((f: { name: string }) => f.name)).toEqual([ - `$${singleVariable.name}`, - '$__timeFilter', - ]); + expect(result.globalParameters.map((f: { name: string }) => f.name)).toEqual([`$${singleVariable.name}`]); }); }); diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_log_analytics/response_parser.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_log_analytics/response_parser.ts index 8d70eeea6de..da97cbe4a45 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_log_analytics/response_parser.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_log_analytics/response_parser.ts @@ -236,8 +236,8 @@ export function transformMetadataToKustoSchema( { name: 'timeColumn', type: 'System.String', - defaultValue: 'TimeGenerated', - cslDefaultValue: 'TimeGenerated', + defaultValue: '""', + cslDefaultValue: '""', }, ], }, @@ -291,15 +291,6 @@ export function transformMetadataToKustoSchema( }; }); - // It's not possible to define optional paramaters in Kusto - // and it's not possible to define the same function twice so - // we are defining $__timeFilter also as a parameter when used - // with no arguments as a workaround - globalParameters.push({ - name: `$__timeFilter`, - type: 'boolean', - }); - return { clusterType: 'Engine', cluster: { From c5547123bcda22b87de2baba5babc13da220d958 Mon Sep 17 00:00:00 2001 From: George Robinson Date: Mon, 25 Apr 2022 11:42:42 +0100 Subject: [PATCH 114/120] Remove redundant queries in GetAlertRules and GetOrgAlertRules and replace with ListAlertRules (#48108) --- pkg/services/ngalert/api/api_prometheus.go | 2 +- pkg/services/ngalert/api/api_ruler.go | 44 ++++++------- pkg/services/ngalert/api/api_ruler_test.go | 2 +- pkg/services/ngalert/models/alert_rule.go | 16 +---- pkg/services/ngalert/state/manager.go | 2 +- pkg/services/ngalert/store/alert_rule.go | 67 +++++++------------ pkg/services/ngalert/store/testing.go | 77 ++++++++++++++-------- pkg/services/ngalert/tests/util.go | 10 +-- 8 files changed, 103 insertions(+), 117 deletions(-) diff --git a/pkg/services/ngalert/api/api_prometheus.go b/pkg/services/ngalert/api/api_prometheus.go index c7ee7b93b97..15759737c14 100644 --- a/pkg/services/ngalert/api/api_prometheus.go +++ b/pkg/services/ngalert/api/api_prometheus.go @@ -147,7 +147,7 @@ func (srv PrometheusSrv) RouteGetRuleStatuses(c *models.ReqContext) response.Res DashboardUID: dashboardUID, PanelID: panelID, } - if err := srv.store.GetOrgAlertRules(c.Req.Context(), &alertRuleQuery); err != nil { + if err := srv.store.ListAlertRules(c.Req.Context(), &alertRuleQuery); err != nil { ruleResponse.DiscoveryBase.Status = "error" ruleResponse.DiscoveryBase.Error = fmt.Sprintf("failure getting rules: %s", err.Error()) ruleResponse.DiscoveryBase.ErrorType = apiv1.ErrServer diff --git a/pkg/services/ngalert/api/api_ruler.go b/pkg/services/ngalert/api/api_ruler.go index 963597e7e9c..f8f9a43a10f 100644 --- a/pkg/services/ngalert/api/api_ruler.go +++ b/pkg/services/ngalert/api/api_ruler.go @@ -55,9 +55,9 @@ func (srv RulerSrv) RouteDeleteAlertRules(c *models.ReqContext) response.Respons "namespace", namespace.Title, } - var ruleGroup *string + var ruleGroup string if group, ok := web.Params(c.Req)[":Groupname"]; ok { - ruleGroup = &group + ruleGroup = group loggerCtx = append(loggerCtx, "group", group) } logger := srv.log.New(loggerCtx...) @@ -68,12 +68,12 @@ func (srv RulerSrv) RouteDeleteAlertRules(c *models.ReqContext) response.Respons var canDelete, cannotDelete []string err = srv.xactManager.InTransaction(c.Req.Context(), func(ctx context.Context) error { - q := ngmodels.GetAlertRulesQuery{ - OrgID: c.SignedInUser.OrgId, - NamespaceUID: namespace.Uid, - RuleGroup: ruleGroup, + q := ngmodels.ListAlertRulesQuery{ + OrgID: c.SignedInUser.OrgId, + NamespaceUIDs: []string{namespace.Uid}, + RuleGroup: ruleGroup, } - if err = srv.store.GetAlertRules(ctx, &q); err != nil { + if err = srv.store.ListAlertRules(ctx, &q); err != nil { return err } @@ -128,11 +128,11 @@ func (srv RulerSrv) RouteGetNamespaceRulesConfig(c *models.ReqContext) response. return toNamespaceErrorResponse(err) } - q := ngmodels.GetAlertRulesQuery{ - OrgID: c.SignedInUser.OrgId, - NamespaceUID: namespace.Uid, + q := ngmodels.ListAlertRulesQuery{ + OrgID: c.SignedInUser.OrgId, + NamespaceUIDs: []string{namespace.Uid}, } - if err := srv.store.GetAlertRules(c.Req.Context(), &q); err != nil { + if err := srv.store.ListAlertRules(c.Req.Context(), &q); err != nil { return ErrResp(http.StatusInternalServerError, err, "failed to update rule group") } @@ -178,12 +178,12 @@ func (srv RulerSrv) RouteGetRulegGroupConfig(c *models.ReqContext) response.Resp } ruleGroup := web.Params(c.Req)[":Groupname"] - q := ngmodels.GetAlertRulesQuery{ - OrgID: c.SignedInUser.OrgId, - NamespaceUID: namespace.Uid, - RuleGroup: &ruleGroup, + q := ngmodels.ListAlertRulesQuery{ + OrgID: c.SignedInUser.OrgId, + NamespaceUIDs: []string{namespace.Uid}, + RuleGroup: ruleGroup, } - if err := srv.store.GetAlertRules(c.Req.Context(), &q); err != nil { + if err := srv.store.ListAlertRules(c.Req.Context(), &q); err != nil { return ErrResp(http.StatusInternalServerError, err, "failed to get group alert rules") } @@ -245,7 +245,7 @@ func (srv RulerSrv) RouteGetRulesConfig(c *models.ReqContext) response.Response PanelID: panelID, } - if err := srv.store.GetOrgAlertRules(c.Req.Context(), &q); err != nil { + if err := srv.store.ListAlertRules(c.Req.Context(), &q); err != nil { return ErrResp(http.StatusInternalServerError, err, "failed to get alert rules") } @@ -493,12 +493,12 @@ func (c *changes) isEmpty() bool { // calculateChanges calculates the difference between rules in the group in the database and the submitted rules. If a submitted rule has UID it tries to find it in the database (in other groups). // returns a list of rules that need to be added, updated and deleted. Deleted considered rules in the database that belong to the group but do not exist in the list of submitted rules. func calculateChanges(ctx context.Context, ruleStore store.RuleStore, orgId int64, namespace *models.Folder, ruleGroupName string, submittedRules []*ngmodels.AlertRule) (*changes, error) { - q := &ngmodels.GetAlertRulesQuery{ - OrgID: orgId, - NamespaceUID: namespace.Uid, - RuleGroup: &ruleGroupName, + q := &ngmodels.ListAlertRulesQuery{ + OrgID: orgId, + NamespaceUIDs: []string{namespace.Uid}, + RuleGroup: ruleGroupName, } - if err := ruleStore.GetAlertRules(ctx, q); err != nil { + if err := ruleStore.ListAlertRules(ctx, q); err != nil { return nil, fmt.Errorf("failed to query database for rules in the group %s: %w", ruleGroupName, err) } existingGroupRules := q.Result diff --git a/pkg/services/ngalert/api/api_ruler_test.go b/pkg/services/ngalert/api/api_ruler_test.go index 9a40a93dfbd..1d10b29c80d 100644 --- a/pkg/services/ngalert/api/api_ruler_test.go +++ b/pkg/services/ngalert/api/api_ruler_test.go @@ -232,7 +232,7 @@ func TestCalculateChanges(t *testing.T) { expectedErr := errors.New("TEST ERROR") fakeStore.Hook = func(cmd interface{}) error { switch cmd.(type) { - case models.GetAlertRulesQuery: + case models.ListAlertRulesQuery: return expectedErr } return nil diff --git a/pkg/services/ngalert/models/alert_rule.go b/pkg/services/ngalert/models/alert_rule.go index e395f1f220f..6bf3c088421 100644 --- a/pkg/services/ngalert/models/alert_rule.go +++ b/pkg/services/ngalert/models/alert_rule.go @@ -232,6 +232,7 @@ type ListAlertRulesQuery struct { OrgID int64 NamespaceUIDs []string ExcludeOrgs []int64 + RuleGroup string // DashboardUID and PanelID are optional and allow filtering rules // to return just those for a dashboard and panel. @@ -250,21 +251,6 @@ type ListNamespaceAlertRulesQuery struct { Result []*AlertRule } -// GetAlertRulesQuery is the query for listing rule group alert rules -type GetAlertRulesQuery struct { - OrgID int64 - // Namespace is the folder slug - NamespaceUID string - RuleGroup *string - - // DashboardUID and PanelID are optional and allow filtering rules - // to return just those for a dashboard and panel. - DashboardUID string - PanelID int64 - - Result []*AlertRule -} - // ListRuleGroupsQuery is the query for listing unique rule groups // across all organizations type ListRuleGroupsQuery struct { diff --git a/pkg/services/ngalert/state/manager.go b/pkg/services/ngalert/state/manager.go index a40f8fc0c82..5deb39d2555 100644 --- a/pkg/services/ngalert/state/manager.go +++ b/pkg/services/ngalert/state/manager.go @@ -76,7 +76,7 @@ func (st *Manager) Warm(ctx context.Context) { ruleCmd := ngModels.ListAlertRulesQuery{ OrgID: orgId, } - if err := st.ruleStore.GetOrgAlertRules(ctx, &ruleCmd); err != nil { + if err := st.ruleStore.ListAlertRules(ctx, &ruleCmd); err != nil { st.log.Error("unable to fetch previous state", "msg", err.Error()) } diff --git a/pkg/services/ngalert/store/alert_rule.go b/pkg/services/ngalert/store/alert_rule.go index 3d4822128a6..bc6a0f97c00 100644 --- a/pkg/services/ngalert/store/alert_rule.go +++ b/pkg/services/ngalert/store/alert_rule.go @@ -38,10 +38,9 @@ type RuleStore interface { DeleteAlertInstancesByRuleUID(ctx context.Context, orgID int64, ruleUID string) error GetAlertRuleByUID(ctx context.Context, query *ngmodels.GetAlertRuleByUIDQuery) error GetAlertRulesForScheduling(ctx context.Context, query *ngmodels.ListAlertRulesQuery) error - GetOrgAlertRules(ctx context.Context, query *ngmodels.ListAlertRulesQuery) error + ListAlertRules(ctx context.Context, query *ngmodels.ListAlertRulesQuery) error // GetRuleGroups returns the unique rule groups across all organizations. GetRuleGroups(ctx context.Context, query *ngmodels.ListRuleGroupsQuery) error - GetAlertRules(ctx context.Context, query *ngmodels.GetAlertRulesQuery) error GetUserVisibleNamespaces(context.Context, int64, *models.SignedInUser) (map[string]*models.Folder, error) GetNamespaceByTitle(context.Context, string, int64, *models.SignedInUser, bool) (*models.Folder, error) InsertAlertRules(ctx context.Context, rule []ngmodels.AlertRule) error @@ -228,33 +227,39 @@ func (st DBstore) UpdateAlertRules(ctx context.Context, rules []UpdateRule) erro } // GetOrgAlertRules is a handler for retrieving alert rules of specific organisation. -func (st DBstore) GetOrgAlertRules(ctx context.Context, query *ngmodels.ListAlertRulesQuery) error { +func (st DBstore) ListAlertRules(ctx context.Context, query *ngmodels.ListAlertRulesQuery) error { return st.SQLStore.WithDbSession(ctx, func(sess *sqlstore.DBSession) error { - alertRules := make([]*ngmodels.AlertRule, 0) - q := "SELECT * FROM alert_rule WHERE org_id = ?" - params := []interface{}{query.OrgID} + q := sess.Table("alert_rule") - if len(query.NamespaceUIDs) > 0 { - placeholders := make([]string, 0, len(query.NamespaceUIDs)) - for _, folderUID := range query.NamespaceUIDs { - params = append(params, folderUID) - placeholders = append(placeholders, "?") - } - q = fmt.Sprintf("%s AND namespace_uid IN (%s)", q, strings.Join(placeholders, ",")) + if query.OrgID >= 0 { + q = q.Where("org_id = ?", query.OrgID) } if query.DashboardUID != "" { - params = append(params, query.DashboardUID) - q = fmt.Sprintf("%s AND dashboard_uid = ?", q) + q = q.Where("dashboard_uid = ?", query.DashboardUID) if query.PanelID != 0 { - params = append(params, query.PanelID) - q = fmt.Sprintf("%s AND panel_id = ?", q) + q = q.Where("panel_id = ?", query.PanelID) } } - q = fmt.Sprintf("%s ORDER BY id ASC", q) + if len(query.NamespaceUIDs) > 0 { + args := make([]interface{}, 0, len(query.NamespaceUIDs)) + in := make([]string, 0, len(query.NamespaceUIDs)) + for _, namespaceUID := range query.NamespaceUIDs { + args = append(args, namespaceUID) + in = append(in, "?") + } + q = q.Where(fmt.Sprintf("namespace_uid IN (%s)", strings.Join(in, ",")), args...) + } - if err := sess.SQL(q, params...).Find(&alertRules); err != nil { + if query.RuleGroup != "" { + q = q.Where("rule_group = ?", query.RuleGroup) + } + + q = q.OrderBy("id ASC") + + alertRules := make([]*ngmodels.AlertRule, 0) + if err := q.Find(&alertRules); err != nil { return err } @@ -274,30 +279,6 @@ func (st DBstore) GetRuleGroups(ctx context.Context, query *ngmodels.ListRuleGro }) } -// GetAlertRules is a handler for retrieving rule group alert rules of specific organisation. -func (st DBstore) GetAlertRules(ctx context.Context, query *ngmodels.GetAlertRulesQuery) error { - return st.SQLStore.WithDbSession(ctx, func(sess *sqlstore.DBSession) error { - q := sess.Table("alert_rule").Where("org_id = ? AND namespace_uid = ?", query.OrgID, query.NamespaceUID) - if query.RuleGroup != nil { - q = q.Where("rule_group = ?", *query.RuleGroup) - } - if query.DashboardUID != "" { - q = q.Where("dashboard_uid = ?", query.DashboardUID) - if query.PanelID != 0 { - q = q.Where("panel_id = ?", query.PanelID) - } - } - - alertRules := make([]*ngmodels.AlertRule, 0) - if err := q.Find(&alertRules); err != nil { - return err - } - - query.Result = alertRules - return nil - }) -} - // GetNamespaces returns the folders that are visible to the user and have at least one alert in it func (st DBstore) GetUserVisibleNamespaces(ctx context.Context, orgID int64, user *models.SignedInUser) (map[string]*models.Folder, error) { namespaceMap := make(map[string]*models.Folder) diff --git a/pkg/services/ngalert/store/testing.go b/pkg/services/ngalert/store/testing.go index 4a340037ced..1a3af60bc30 100644 --- a/pkg/services/ngalert/store/testing.go +++ b/pkg/services/ngalert/store/testing.go @@ -166,16 +166,58 @@ func (f *FakeRuleStore) GetAlertRulesForScheduling(_ context.Context, q *models. return nil } -func (f *FakeRuleStore) GetOrgAlertRules(_ context.Context, q *models.ListAlertRulesQuery) error { +func (f *FakeRuleStore) ListAlertRules(_ context.Context, q *models.ListAlertRulesQuery) error { f.mtx.Lock() defer f.mtx.Unlock() f.RecordedOps = append(f.RecordedOps, *q) - rules, ok := f.Rules[q.OrgID] - if !ok { - return nil + if err := f.Hook(*q); err != nil { + return err } - q.Result = rules + + hasDashboard := func(r *models.AlertRule, dashboardUID string, panelID int64) bool { + if dashboardUID != "" { + if r.DashboardUID == nil || *r.DashboardUID != dashboardUID { + return false + } + if panelID > 0 { + if r.PanelID == nil || *r.PanelID != panelID { + return false + } + } + } + return true + } + + hasNamespace := func(r *models.AlertRule, namespaceUIDs []string) bool { + if len(namespaceUIDs) > 0 { + var ok bool + for _, uid := range q.NamespaceUIDs { + if uid == r.NamespaceUID { + ok = true + break + } + } + if !ok { + return false + } + } + return true + } + + for _, r := range f.Rules[q.OrgID] { + if !hasDashboard(r, q.DashboardUID, q.PanelID) { + continue + } + if !hasNamespace(r, q.NamespaceUIDs) { + continue + } + if q.RuleGroup != "" && r.RuleGroup != q.RuleGroup { + continue + } + q.Result = append(q.Result, r) + } + return nil } @@ -198,30 +240,6 @@ func (f *FakeRuleStore) GetRuleGroups(_ context.Context, q *models.ListRuleGroup return nil } -func (f *FakeRuleStore) GetAlertRules(_ context.Context, q *models.GetAlertRulesQuery) error { - f.mtx.Lock() - defer f.mtx.Unlock() - f.RecordedOps = append(f.RecordedOps, *q) - if err := f.Hook(*q); err != nil { - return err - } - rules, ok := f.Rules[q.OrgID] - if !ok { - return nil - } - var result []*models.AlertRule - for _, rule := range rules { - if q.NamespaceUID != rule.NamespaceUID { - continue - } - if q.RuleGroup != nil && *q.RuleGroup != rule.RuleGroup { - continue - } - result = append(result, rule) - } - q.Result = result - return nil -} func (f *FakeRuleStore) GetUserVisibleNamespaces(_ context.Context, orgID int64, _ *models2.SignedInUser) (map[string]*models2.Folder, error) { f.mtx.Lock() defer f.mtx.Unlock() @@ -238,6 +256,7 @@ func (f *FakeRuleStore) GetUserVisibleNamespaces(_ context.Context, orgID int64, } return namespacesMap, nil } + func (f *FakeRuleStore) GetNamespaceByTitle(_ context.Context, title string, orgID int64, _ *models2.SignedInUser, _ bool) (*models2.Folder, error) { folders := f.Folders[orgID] for _, folder := range folders { diff --git a/pkg/services/ngalert/tests/util.go b/pkg/services/ngalert/tests/util.go index 19de8f046a2..69f79d427ae 100644 --- a/pkg/services/ngalert/tests/util.go +++ b/pkg/services/ngalert/tests/util.go @@ -113,12 +113,12 @@ func CreateTestAlertRuleWithLabels(t *testing.T, ctx context.Context, dbstore *s }) require.NoError(t, err) - q := models.GetAlertRulesQuery{ - OrgID: orgID, - NamespaceUID: "namespace", - RuleGroup: &ruleGroup, + q := models.ListAlertRulesQuery{ + OrgID: orgID, + NamespaceUIDs: []string{"namespace"}, + RuleGroup: ruleGroup, } - err = dbstore.GetAlertRules(ctx, &q) + err = dbstore.ListAlertRules(ctx, &q) require.NoError(t, err) require.NotEmpty(t, q.Result) From d8a754c4a02cd54a69939317cde56aa5339a3ae9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Farkas?= Date: Mon, 25 Apr 2022 13:16:14 +0200 Subject: [PATCH 115/120] loki: send metadata requests through backend (#48063) --- pkg/tsdb/loki/api.go | 44 +++++++++++++++++-- pkg/tsdb/loki/loki.go | 42 ++++++++++++++++-- .../app/plugins/datasource/loki/datasource.ts | 9 +++- 3 files changed, 87 insertions(+), 8 deletions(-) diff --git a/pkg/tsdb/loki/api.go b/pkg/tsdb/loki/api.go index 87e340dfc8c..d1d1eb6f813 100644 --- a/pkg/tsdb/loki/api.go +++ b/pkg/tsdb/loki/api.go @@ -25,7 +25,7 @@ func newLokiAPI(client *http.Client, url string, log log.Logger) *LokiAPI { return &LokiAPI{client: client, url: url, log: log} } -func makeRequest(ctx context.Context, lokiDsUrl string, query lokiQuery) (*http.Request, error) { +func makeDataRequest(ctx context.Context, lokiDsUrl string, query lokiQuery) (*http.Request, error) { qs := url.Values{} qs.Set("query", query.Expr) @@ -135,8 +135,8 @@ func makeLokiError(body io.ReadCloser) error { return fmt.Errorf("%v", errorMessage) } -func (api *LokiAPI) Query(ctx context.Context, query lokiQuery) (*loghttp.QueryResponse, error) { - req, err := makeRequest(ctx, api.url, query) +func (api *LokiAPI) DataQuery(ctx context.Context, query lokiQuery) (*loghttp.QueryResponse, error) { + req, err := makeDataRequest(ctx, api.url, query) if err != nil { return nil, err } @@ -164,3 +164,41 @@ func (api *LokiAPI) Query(ctx context.Context, query lokiQuery) (*loghttp.QueryR return &response, nil } + +func makeRawRequest(ctx context.Context, lokiDsUrl string, resourceURL string) (*http.Request, error) { + lokiUrl, err := url.Parse(lokiDsUrl) + if err != nil { + return nil, err + } + + url, err := lokiUrl.Parse(resourceURL) + if err != nil { + return nil, err + } + + return http.NewRequestWithContext(ctx, "GET", url.String(), nil) +} + +func (api *LokiAPI) RawQuery(ctx context.Context, resourceURL string) ([]byte, error) { + req, err := makeRawRequest(ctx, api.url, resourceURL) + if err != nil { + return nil, err + } + + resp, err := api.client.Do(req) + if err != nil { + return nil, err + } + + defer func() { + if err := resp.Body.Close(); err != nil { + api.log.Warn("Failed to close response body", "err", err) + } + }() + + if resp.StatusCode/100 != 2 { + return nil, makeLokiError(resp.Body) + } + + return io.ReadAll(resp.Body) +} diff --git a/pkg/tsdb/loki/loki.go b/pkg/tsdb/loki/loki.go index e2112d33623..976c1db464d 100644 --- a/pkg/tsdb/loki/loki.go +++ b/pkg/tsdb/loki/loki.go @@ -6,6 +6,7 @@ import ( "fmt" "net/http" "regexp" + "strings" "sync" "github.com/grafana/grafana-plugin-sdk-go/backend" @@ -25,8 +26,9 @@ type Service struct { } var ( - _ backend.QueryDataHandler = (*Service)(nil) - _ backend.StreamHandler = (*Service)(nil) + _ backend.QueryDataHandler = (*Service)(nil) + _ backend.StreamHandler = (*Service)(nil) + _ backend.CallResourceHandler = (*Service)(nil) ) func ProvideService(httpClientProvider httpclient.Provider, tracer tracing.Tracer) *Service { @@ -89,6 +91,40 @@ func newInstanceSettings(httpClientProvider httpclient.Provider) datasource.Inst } } +func (s *Service) CallResource(ctx context.Context, req *backend.CallResourceRequest, sender backend.CallResourceResponseSender) error { + url := req.URL + + // a very basic is-this-url-valid check + if req.Method != "GET" { + return fmt.Errorf("invalid resource method: %s", req.Method) + } + if (!strings.HasPrefix(url, "/loki/api/v1/label?")) && + (!strings.HasPrefix(url, "/loki/api/v1/label/")) && // the `/label/$label_name/values` form + (!strings.HasPrefix(url, "/loki/api/v1/series?")) { + return fmt.Errorf("invalid resource URL: %s", url) + } + + dsInfo, err := s.getDSInfo(req.PluginContext) + if err != nil { + return err + } + + api := newLokiAPI(dsInfo.HTTPClient, dsInfo.URL, s.plog) + bytes, err := api.RawQuery(ctx, url) + + if err != nil { + return err + } + + return sender.Send(&backend.CallResourceResponse{ + Status: http.StatusOK, + Headers: map[string][]string{ + "content-type": {"application/json"}, + }, + Body: bytes, + }) +} + func (s *Service) QueryData(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) { result := backend.NewQueryDataResponse() @@ -129,7 +165,7 @@ func (s *Service) QueryData(ctx context.Context, req *backend.QueryDataRequest) // we extracted this part of the functionality to make it easy to unit-test it func runQuery(ctx context.Context, api *LokiAPI, query *lokiQuery) (data.Frames, error) { - value, err := api.Query(ctx, *query) + value, err := api.DataQuery(ctx, *query) if err != nil { return data.Frames{}, err } diff --git a/public/app/plugins/datasource/loki/datasource.ts b/public/app/plugins/datasource/loki/datasource.ts index 9897ae2cc15..79b808543aa 100644 --- a/public/app/plugins/datasource/loki/datasource.ts +++ b/public/app/plugins/datasource/loki/datasource.ts @@ -439,8 +439,13 @@ export class LokiDatasource } async metadataRequest(url: string, params?: Record) { - const res = await lastValueFrom(this._request(url, params, { hideFromInspector: true })); - return res.data.data || res.data.values || []; + if (config.featureToggles.lokiBackendMode) { + const res = await this.getResource(url, params); + return res.data || res.values || []; + } else { + const res = await lastValueFrom(this._request(url, params, { hideFromInspector: true })); + return res.data.data || res.data.values || []; + } } async metricFindQuery(query: string) { From c1c94f478a8d23a042c2614912a5e7ef9239e5ec Mon Sep 17 00:00:00 2001 From: Andres Martinez Gotor Date: Mon, 25 Apr 2022 04:27:22 -0700 Subject: [PATCH 116/120] Chore: Fix e2e selector (#48168) --- packages/grafana-e2e/src/flows/configurePanel.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/grafana-e2e/src/flows/configurePanel.ts b/packages/grafana-e2e/src/flows/configurePanel.ts index 275561809d1..384bef3200c 100644 --- a/packages/grafana-e2e/src/flows/configurePanel.ts +++ b/packages/grafana-e2e/src/flows/configurePanel.ts @@ -1,4 +1,4 @@ -import { e2e } from '../index'; +import { e2e } from '..'; import { getScenarioContext } from '../support/scenarioContext'; import { selectOption } from './selectOption'; @@ -148,7 +148,7 @@ export const configurePanel = (config: PartialAddPanelConfig | PartialEditPanelC //e2e().wait('@chartData'); // Avoid annotations flakiness - e2e.components.RefreshPicker.runButton().should('be.visible').click(); + e2e.components.RefreshPicker.runButtonV2().first().should('be.visible').click({ force: true }); e2e().wait('@chartData'); From 98291958296ee1eefb8476f31a07066ea22b31e8 Mon Sep 17 00:00:00 2001 From: Kevin Yu Date: Mon, 25 Apr 2022 05:39:34 -0700 Subject: [PATCH 117/120] AzureMonitor: fix the encoding of the metrics query deep link to Azure Portal (#48139) --- pkg/tsdb/azuremonitor/metrics/azuremonitor-datasource.go | 4 ++++ pkg/tsdb/azuremonitor/metrics/azuremonitor-datasource_test.go | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/pkg/tsdb/azuremonitor/metrics/azuremonitor-datasource.go b/pkg/tsdb/azuremonitor/metrics/azuremonitor-datasource.go index 84279f4de67..9f256972543 100644 --- a/pkg/tsdb/azuremonitor/metrics/azuremonitor-datasource.go +++ b/pkg/tsdb/azuremonitor/metrics/azuremonitor-datasource.go @@ -368,6 +368,10 @@ func getQueryUrl(query *types.AzureMonitorQuery, azurePortalUrl string) (string, return "", err } escapedChart := url.QueryEscape(string(chartDef)) + // Azure Portal will timeout if the chart definition includes a space character encoded as '+'. + // url.QueryEscape encodes spaces as '+'. + // Note: this will not encode '+' literals as those are already encoded as '%2B' by url.QueryEscape + escapedChart = strings.ReplaceAll(escapedChart, "+", "%20") return fmt.Sprintf("%s/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%s/ChartDefinition/%s", azurePortalUrl, escapedTime, escapedChart), nil } diff --git a/pkg/tsdb/azuremonitor/metrics/azuremonitor-datasource_test.go b/pkg/tsdb/azuremonitor/metrics/azuremonitor-datasource_test.go index 89faac286c0..abc44521375 100644 --- a/pkg/tsdb/azuremonitor/metrics/azuremonitor-datasource_test.go +++ b/pkg/tsdb/azuremonitor/metrics/azuremonitor-datasource_test.go @@ -188,7 +188,7 @@ func TestAzureMonitorBuildQueries(t *testing.T) { expected := `http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/` + `TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%222018-03-15T13%3A00%3A00Z%22%2C%22endTime%22%3A%222018-03-15T13%3A34%3A00Z%22%7D%7D/` + `ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C` + - `%22name%22%3A%22Percentage+CPU%22%2C%22aggregationType%22%3A4%2C%22namespace%22%3A%22Microsoft.Compute-virtualMachines%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22Percentage+CPU%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D` + `%22name%22%3A%22Percentage%20CPU%22%2C%22aggregationType%22%3A4%2C%22namespace%22%3A%22Microsoft.Compute-virtualMachines%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22Percentage%20CPU%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D` actual, err := getQueryUrl(queries[0], "http://ds") require.NoError(t, err) require.Equal(t, expected, actual) From b30d9f2732e3c93ee8f1c83ab66e71bcdb7d285d Mon Sep 17 00:00:00 2001 From: Kristina Date: Mon, 25 Apr 2022 07:48:55 -0500 Subject: [PATCH 118/120] Explore: Fix height on horizontal drawer and query inspector (#47832) * Move tab height and horizontal drawer height to themable variables so they can be referred to. Add a default height to tabbed container so it can set an explicit height. Add overflow: scroll to inspector content * Use height variable that changes on resize * Use css to set height --- packages/grafana-data/src/themes/createComponents.ts | 12 ++++++++++++ .../components/TabbedContainer/TabbedContainer.tsx | 2 +- packages/grafana-ui/src/components/Tabs/TabsBar.tsx | 2 +- public/app/features/explore/ExploreDrawer.tsx | 8 ++++---- .../app/features/explore/ExploreQueryInspector.tsx | 2 +- .../explore/RichHistory/RichHistoryContainer.tsx | 4 +++- public/app/features/inspector/styles.ts | 1 + 7 files changed, 23 insertions(+), 8 deletions(-) diff --git a/packages/grafana-data/src/themes/createComponents.ts b/packages/grafana-data/src/themes/createComponents.ts index fefd3dbf101..51603f036c7 100644 --- a/packages/grafana-data/src/themes/createComponents.ts +++ b/packages/grafana-data/src/themes/createComponents.ts @@ -39,6 +39,12 @@ export interface ThemeComponents { sidemenu: { width: number; }; + menuTabs: { + height: number; + }; + horizontalDrawer: { + defaultHeight: number; + }; } export function createComponents(colors: ThemeColors, shadows: ThemeShadows): ThemeComponents { @@ -82,5 +88,11 @@ export function createComponents(colors: ThemeColors, shadows: ThemeShadows): Th sidemenu: { width: 48, }, + menuTabs: { + height: 41, + }, + horizontalDrawer: { + defaultHeight: 400, + }, }; } diff --git a/packages/grafana-ui/src/components/TabbedContainer/TabbedContainer.tsx b/packages/grafana-ui/src/components/TabbedContainer/TabbedContainer.tsx index 0baad2778c7..f4a14cfe11e 100644 --- a/packages/grafana-ui/src/components/TabbedContainer/TabbedContainer.tsx +++ b/packages/grafana-ui/src/components/TabbedContainer/TabbedContainer.tsx @@ -28,7 +28,7 @@ const getStyles = stylesFactory((theme: GrafanaTheme2) => { tabContent: css` padding: ${theme.spacing(2)}; background-color: ${theme.colors.background.primary}; - height: 100%; + height: calc(100% - ${theme.components.menuTabs.height}px); `, close: css` position: absolute; diff --git a/packages/grafana-ui/src/components/Tabs/TabsBar.tsx b/packages/grafana-ui/src/components/Tabs/TabsBar.tsx index 73acd2a67bc..6cfb03409be 100644 --- a/packages/grafana-ui/src/components/Tabs/TabsBar.tsx +++ b/packages/grafana-ui/src/components/Tabs/TabsBar.tsx @@ -23,7 +23,7 @@ const getTabsBarStyles = stylesFactory((theme: GrafanaTheme2, hideBorder = false tabs: css` position: relative; display: flex; - height: 41px; + height: ${theme.components.menuTabs.height}px; `, }; }); diff --git a/public/app/features/explore/ExploreDrawer.tsx b/public/app/features/explore/ExploreDrawer.tsx index 8220dc748d9..10fa3489d5e 100644 --- a/public/app/features/explore/ExploreDrawer.tsx +++ b/public/app/features/explore/ExploreDrawer.tsx @@ -9,9 +9,9 @@ import { stylesFactory, useTheme2 } from '@grafana/ui'; // Types -const drawerSlide = keyframes` +const drawerSlide = (theme: GrafanaTheme2) => keyframes` 0% { - transform: translateY(400px); + transform: translateY(${theme.components.horizontalDrawer.defaultHeight}px); } 100% { @@ -32,7 +32,7 @@ const getStyles = stylesFactory((theme: GrafanaTheme2) => { `, drawerActive: css` opacity: 1; - animation: 0.5s ease-out ${drawerSlide}; + animation: 0.5s ease-out ${drawerSlide(theme)}; `, rzHandle: css` background: ${theme.colors.secondary.main}; @@ -66,7 +66,7 @@ export function ExploreDrawer(props: Props) { return ( {}}> + ); diff --git a/public/app/features/explore/RichHistory/RichHistoryContainer.tsx b/public/app/features/explore/RichHistory/RichHistoryContainer.tsx index 0824dae0aac..8f47865710d 100644 --- a/public/app/features/explore/RichHistory/RichHistoryContainer.tsx +++ b/public/app/features/explore/RichHistory/RichHistoryContainer.tsx @@ -1,6 +1,7 @@ // Libraries import React, { useEffect, useState } from 'react'; import { connect, ConnectedProps } from 'react-redux'; +import { useTheme2 } from '@grafana/ui'; // Types import { ExploreItemState, StoreState } from 'app/types'; @@ -54,7 +55,8 @@ interface OwnProps { export type Props = ConnectedProps & OwnProps; export function RichHistoryContainer(props: Props) { - const [height, setHeight] = useState(400); + const theme = useTheme2(); + const [height, setHeight] = useState(theme.components.horizontalDrawer.defaultHeight); const { richHistory, diff --git a/public/app/features/inspector/styles.ts b/public/app/features/inspector/styles.ts index 66aef0e653d..123ccb131a7 100644 --- a/public/app/features/inspector/styles.ts +++ b/public/app/features/inspector/styles.ts @@ -26,6 +26,7 @@ export const getPanelInspectorStyles = stylesFactory(() => { content: css` flex-grow: 1; height: 100%; + overflow: scroll; `, editor: css` font-family: monospace; From ea25f7e1ca8dd6485fa74db487d56185ccaee360 Mon Sep 17 00:00:00 2001 From: Ieva Date: Mon, 25 Apr 2022 15:26:46 +0200 Subject: [PATCH 119/120] fix argument ordering (#48124) --- pkg/api/folder.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/api/folder.go b/pkg/api/folder.go index 3a14be06d33..9efde7251f9 100644 --- a/pkg/api/folder.go +++ b/pkg/api/folder.go @@ -52,7 +52,7 @@ func (hs *HTTPServer) GetFolderByID(c *models.ReqContext) response.Response { if err != nil { return response.Error(http.StatusBadRequest, "id is invalid", err) } - folder, err := hs.folderService.GetFolderByID(c.Req.Context(), c.SignedInUser, c.OrgId, id) + folder, err := hs.folderService.GetFolderByID(c.Req.Context(), c.SignedInUser, id, c.OrgId) if err != nil { return apierrors.ToFolderErrorResponse(err) } From 801a2a240aeb068dbff3d2626bd6efe990ee989c Mon Sep 17 00:00:00 2001 From: Isabella Siu Date: Mon, 25 Apr 2022 10:33:49 -0400 Subject: [PATCH 120/120] Cloudwatch: fix template variables in variable queries (#48140) --- .../__mocks__/CloudWatchDataSource.ts | 18 +++++++++++++++++- .../datasource/cloudwatch/datasource.ts | 2 +- .../datasource/cloudwatch/variables.test.ts | 14 +++++++------- .../plugins/datasource/cloudwatch/variables.ts | 9 ++++++--- 4 files changed, 31 insertions(+), 12 deletions(-) diff --git a/public/app/plugins/datasource/cloudwatch/__mocks__/CloudWatchDataSource.ts b/public/app/plugins/datasource/cloudwatch/__mocks__/CloudWatchDataSource.ts index f846d4e254c..7cc2ab389e1 100644 --- a/public/app/plugins/datasource/cloudwatch/__mocks__/CloudWatchDataSource.ts +++ b/public/app/plugins/datasource/cloudwatch/__mocks__/CloudWatchDataSource.ts @@ -47,7 +47,7 @@ export function setupMockedDataSource({ data = [], variables }: { data?: any; va const fetchMock = jest.fn().mockReturnValue(of({ data })); setBackendSrv({ fetch: fetchMock } as any); - return { datasource, fetchMock }; + return { datasource, fetchMock, templateService }; } export const metricVariable: CustomVariableModel = { @@ -125,3 +125,19 @@ export const aggregationvariable: CustomVariableModel = { ], multi: false, }; + +export const dimensionVariable: CustomVariableModel = { + ...initialCustomVariableModelState, + id: 'dimension', + name: 'dimension', + current: { + value: 'env', + text: 'env', + selected: true, + }, + options: [ + { value: 'env', text: 'env', selected: false }, + { value: 'tag', text: 'tag', selected: false }, + ], + multi: false, +}; diff --git a/public/app/plugins/datasource/cloudwatch/datasource.ts b/public/app/plugins/datasource/cloudwatch/datasource.ts index 6d7cdebe903..379ea6e4d45 100644 --- a/public/app/plugins/datasource/cloudwatch/datasource.ts +++ b/public/app/plugins/datasource/cloudwatch/datasource.ts @@ -125,7 +125,7 @@ export class CloudWatchDatasource this.logsTimeout = instanceSettings.jsonData.logsTimeout || '15m'; this.sqlCompletionItemProvider = new SQLCompletionItemProvider(this, this.templateSrv); this.metricMathCompletionItemProvider = new MetricMathCompletionItemProvider(this, this.templateSrv); - this.variables = new CloudWatchVariableSupport(this); + this.variables = new CloudWatchVariableSupport(this, this.templateSrv); } query(options: DataQueryRequest): Observable { diff --git a/public/app/plugins/datasource/cloudwatch/variables.test.ts b/public/app/plugins/datasource/cloudwatch/variables.test.ts index 592506cba98..a6e48356153 100644 --- a/public/app/plugins/datasource/cloudwatch/variables.test.ts +++ b/public/app/plugins/datasource/cloudwatch/variables.test.ts @@ -1,4 +1,4 @@ -import { setupMockedDataSource } from './__mocks__/CloudWatchDataSource'; +import { dimensionVariable, labelsVariable, setupMockedDataSource } from './__mocks__/CloudWatchDataSource'; import { VariableQuery, VariableQueryType } from './types'; import { CloudWatchVariableSupport } from './variables'; @@ -16,7 +16,7 @@ const defaultQuery: VariableQuery = { refId: '', }; -const ds = setupMockedDataSource(); +const ds = setupMockedDataSource({ variables: [labelsVariable, dimensionVariable] }); ds.datasource.getRegions = jest.fn().mockResolvedValue([{ label: 'a', value: 'a' }]); ds.datasource.getNamespaces = jest.fn().mockResolvedValue([{ label: 'b', value: 'b' }]); ds.datasource.getMetrics = jest.fn().mockResolvedValue([{ label: 'c', value: 'c' }]); @@ -26,7 +26,7 @@ const getEbsVolumeIds = jest.fn().mockResolvedValue([{ label: 'f', value: 'f' }] const getEc2InstanceAttribute = jest.fn().mockResolvedValue([{ label: 'g', value: 'g' }]); const getResourceARNs = jest.fn().mockResolvedValue([{ label: 'h', value: 'h' }]); -const variables = new CloudWatchVariableSupport(ds.datasource); +const variables = new CloudWatchVariableSupport(ds.datasource, ds.templateService); describe('variables', () => { it('should run regions', async () => { @@ -114,7 +114,7 @@ describe('variables', () => { ...defaultQuery, queryType: VariableQueryType.EC2InstanceAttributes, attributeName: 'abc', - ec2Filters: '{"a":["b"]}', + ec2Filters: '{"$dimension":["b"]}', }; beforeEach(() => { ds.datasource.getEc2InstanceAttribute = getEc2InstanceAttribute; @@ -129,7 +129,7 @@ describe('variables', () => { it('should run if instance id set', async () => { const result = await variables.execute(query); - expect(getEc2InstanceAttribute).toBeCalledWith(query.region, query.attributeName, { a: ['b'] }); + expect(getEc2InstanceAttribute).toBeCalledWith(query.region, query.attributeName, { env: ['b'] }); expect(result).toEqual([{ text: 'g', value: 'g', expandable: true }]); }); }); @@ -139,7 +139,7 @@ describe('variables', () => { ...defaultQuery, queryType: VariableQueryType.ResourceArns, resourceType: 'abc', - tags: '{"a":["b"]}', + tags: '{"a":${labels:json}}', }; beforeEach(() => { ds.datasource.getResourceARNs = getResourceARNs; @@ -154,7 +154,7 @@ describe('variables', () => { it('should run if instance id set', async () => { const result = await variables.execute(query); - expect(getResourceARNs).toBeCalledWith(query.region, query.resourceType, { a: ['b'] }); + expect(getResourceARNs).toBeCalledWith(query.region, query.resourceType, { a: ['InstanceId', 'InstanceType'] }); expect(result).toEqual([{ text: 'h', value: 'h', expandable: true }]); }); }); diff --git a/public/app/plugins/datasource/cloudwatch/variables.ts b/public/app/plugins/datasource/cloudwatch/variables.ts index 3a6932b3ca7..a4eb2ea5397 100644 --- a/public/app/plugins/datasource/cloudwatch/variables.ts +++ b/public/app/plugins/datasource/cloudwatch/variables.ts @@ -2,6 +2,7 @@ import { from, Observable } from 'rxjs'; import { map } from 'rxjs/operators'; import { CustomVariableSupport, DataQueryRequest, DataQueryResponse } from '@grafana/data'; +import { getTemplateSrv, TemplateSrv } from '@grafana/runtime'; import { VariableQueryEditor } from './components/VariableQueryEditor/VariableQueryEditor'; import { CloudWatchDatasource } from './datasource'; @@ -10,10 +11,12 @@ import { VariableQuery, VariableQueryType } from './types'; export class CloudWatchVariableSupport extends CustomVariableSupport { private readonly datasource: CloudWatchDatasource; + private readonly templateSrv: TemplateSrv; - constructor(datasource: CloudWatchDatasource) { + constructor(datasource: CloudWatchDatasource, templateSrv: TemplateSrv = getTemplateSrv()) { super(); this.datasource = datasource; + this.templateSrv = templateSrv; this.query = this.query.bind(this); } @@ -124,7 +127,7 @@ export class CloudWatchVariableSupport extends CustomVariableSupport ({ @@ -140,7 +143,7 @@ export class CloudWatchVariableSupport extends CustomVariableSupport ({