diff --git a/README.md b/README.md index fceb00440..38ad23339 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # SystemLink Grafana Plugins + [![Push to main](https://github.com/ni/systemlink-grafana-plugins/actions/workflows/push.yml/badge.svg)](https://github.com/ni/systemlink-grafana-plugins/actions/workflows/push.yml) @@ -80,6 +81,92 @@ You should now be able to use the data source when building a dashboard or in the Explore mode. Navigating to Explore is the easiest way to begin testing the plugin. +### Feature Toggle implementation + +The SystemLink Grafana plugins now support a feature flag infrastructure to enable or disable specific features dynamically. This implementation is inspired by the feature flag system used in SLE Angular Apps and is designed to work seamlessly in both development and production environments. Features can be toggled on or off without requiring a redeployment. + +#### Steps to Add a New Feature Toggle + +**Define the Feature Toggle** + +1. Add new entry to the `FeatureToggleNames` enum present in [feature-toggle.ts](/src/core/feature-toggle.ts). + +```ts +export enum FeatureToggleNames { + locations = 'locations', + newFeature = 'newFeature', // Add your new feature toggle here +} +``` + +2. Add the default configuration for the new feature toggle in the `FeatureTogglesDefaults` object. + +```ts +export const FeatureTogglesDefaults: Record = { + [FeatureToggleNames.locations]: { + name: 'locations', + enabledByDefault: false, + description: 'Enables location support in Asset queries.', + }, + // Add your new feature toggle configuration + [FeatureToggleNames.newFeature]: { + name: 'newFeature', + enabledByDefault: false, + description: 'Description of the new feature.', + }, +}; +``` + +**Use the Feature Flag in Code** + +1. Use the getFeatureFlagValue function to check if the feature is enabled before executing the related logic. + +```ts +const isNewFeatureEnabled = getFeatureFlagValue(this.instanceSettings.jsonData, FeatureToggleNames.newFeature); + +if (isNewFeatureEnabled) { + // Execute logic for the new feature +} else { + // Fallback logic +} +``` + +**Update the Data Source Configuration UI (Optional)** + +1. This step is needed only if you want to toggle the feature flag from the data source configuration UI. +2. Open `ConfigEditor.tsx` file of your data source and add a new `InlineField` for the feature flag in the **Features** section: + +```ts + + + + + + +``` + +**Test the Feature Flag** + +1. Testing from local storage + 1. Open the inspect mode and go to the Application tab. You can update the boolean value of the feature toggle. + 2. Check whether the feature is enabled in the data source when building a dashboard. +2. Testing from data source configuration UI + 1. Navigate to the data sources configuration page (/datasources). You can get there by clicking the gear icon in the sidebar. + 2. Select the plugin in the list and click on it to enter the data source settings view. + 3. If you have created `ConfigEditor.tsx`, you can see the **Features** section in the configuration UI. + 4. Toggle a feature and click **Save & test**. + 5. Check whether the feature is enabled in the data source when building a dashboard. + +> **Note:** +> When adding a new feature flag, it is recommended to set `enabledByDefault: false` initially and use local storage for testing purposes. This ensures that the feature is only accessible to developers or testers during the development phase. +> Once the feature is released to customers and deemed stable, you should either: +> +> - Remove the feature flag from the source code entirely, or +> - Set enabledByDefault: true to make the feature permanently available. +> This approach helps maintain clean and maintainable code while ensuring a smooth feature rollout process. + ### Testing If you followed the steps above, a live reload script was injected into the @@ -121,17 +208,17 @@ optional. `` must be one of the following: -| Type | When to use | Automatic version bump | -| --- | --- | --- | -| `build` | Changes that affect the build system or external dependencies | None | -| `ci` | Changes to our CI configuration files and scripts | None | -| `docs` | Documentation only changes | None | -| `feat` | A new feature | Minor | -| `fix` | A bug fix | Maintenance | -| `perf`| A code change that improves performance | None | -| `refactor`| A code change that neither fixes a bug nor adds a feature | None | -| `test`| Adding missing tests or correcting existing tests | None | -| `chore` | Changes that don't fit into the above categories | None | +| Type | When to use | Automatic version bump | +| ---------- | ------------------------------------------------------------- | ---------------------- | +| `build` | Changes that affect the build system or external dependencies | None | +| `ci` | Changes to our CI configuration files and scripts | None | +| `docs` | Documentation only changes | None | +| `feat` | A new feature | Minor | +| `fix` | A bug fix | Maintenance | +| `perf` | A code change that improves performance | None | +| `refactor` | A code change that neither fixes a bug nor adds a feature | None | +| `test` | Adding missing tests or correcting existing tests | None | +| `chore` | Changes that don't fit into the above categories | None | For example, if you're making a bug fix to the [Data frame](src/datasources/data-frame/) plugin, your PR title (and therefore the @@ -175,4 +262,4 @@ follow the instructions. ### Helpful links - [Grafana plugin developer's -guide](https://grafana.com/docs/grafana/latest/developers/plugins/) + guide](https://grafana.com/docs/grafana/latest/developers/plugins/) diff --git a/provisioning/example.yaml b/provisioning/example.yaml index b5f62f1b9..3fa126aef 100644 --- a/provisioning/example.yaml +++ b/provisioning/example.yaml @@ -6,6 +6,7 @@ apiVersion: 1 config: &config access: proxy + editable: true url: MY_SYSTEMLINK_API_URL jsonData: httpHeaderName1: 'x-ni-api-key' diff --git a/src/core/feature-toggle.ts b/src/core/feature-toggle.ts new file mode 100644 index 000000000..272198852 --- /dev/null +++ b/src/core/feature-toggle.ts @@ -0,0 +1,62 @@ +import { DataSourceJsonData } from "@grafana/data"; + +interface FeatureToggle { + name: string; + enabledByDefault: boolean; + description?: string; +} + +export interface FeatureToggleDataSourceOptions extends DataSourceJsonData { + featureToggles: { [key: string]: boolean }; +} + +export enum FeatureToggleNames { + assetList = 'assetList', + calibrationForecast = 'calibrationForecast', + assetSummary = 'assetSummary', + locations = 'locations' +} + +export const FeatureTogglesDefaults: Record = { + [FeatureToggleNames.assetList]: { + name: 'assetList', + enabledByDefault: true, + description: 'Enables the Asset List query type.' + }, + [FeatureToggleNames.calibrationForecast]: { + name: 'calibrationForecast', + enabledByDefault: true, + description: 'Enables the Calibration Forecast query type.' + }, + [FeatureToggleNames.assetSummary]: { + name: 'assetSummary', + enabledByDefault: true, + description: 'Enables the Asset Summary query type.' + }, + [FeatureToggleNames.locations]: { + name: 'locations', + enabledByDefault: false, + description: 'Enables location support in Asset queries.' + } +}; + +export function getFeatureFlagValue(options: FeatureToggleDataSourceOptions, flagName: FeatureToggleNames): boolean { + // Check if the feature flag is set in the datasource options. + const optionValue = options?.featureToggles && options?.featureToggles[flagName]; + if (optionValue !== undefined && optionValue) { + return optionValue; + } + + // Check if the feature flag is set in local storage. + const localValue = localStorage.getItem(`${flagName}`); + if (localValue !== null) { + return localValue === 'true'; + } + + // If not set in options or local storage, use the default value and set it to local storage. + localStorage.setItem( + FeatureTogglesDefaults[flagName].name, + FeatureTogglesDefaults[flagName].enabledByDefault.toString() + ); + return FeatureTogglesDefaults[flagName].enabledByDefault; +} diff --git a/src/datasources/asset/AssetConfigEditor.tsx b/src/datasources/asset/AssetConfigEditor.tsx index 03c8105e4..02d72ae2a 100644 --- a/src/datasources/asset/AssetConfigEditor.tsx +++ b/src/datasources/asset/AssetConfigEditor.tsx @@ -5,9 +5,9 @@ import React, { ChangeEvent, useCallback } from 'react'; import { DataSourcePluginOptionsEditorProps } from '@grafana/data'; import { DataSourceHttpSettings, InlineField, InlineSegmentGroup, InlineSwitch, Tag, Text } from '@grafana/ui'; -import { AssetDataSourceOptions, AssetFeatureTogglesDefaults } from './types/types'; +import { FeatureToggleDataSourceOptions, FeatureTogglesDefaults } from 'core/feature-toggle'; -interface Props extends DataSourcePluginOptionsEditorProps { } +interface Props extends DataSourcePluginOptionsEditorProps { } export const AssetConfigEditor: React.FC = ({ options, onOptionsChange }) => { const handleFeatureChange = useCallback((featureKey: string) => (event: ChangeEvent) => { @@ -35,7 +35,7 @@ export const AssetConfigEditor: React.FC = ({ options, onOptionsChange }) @@ -43,7 +43,7 @@ export const AssetConfigEditor: React.FC = ({ options, onOptionsChange }) @@ -51,7 +51,7 @@ export const AssetConfigEditor: React.FC = ({ options, onOptionsChange }) diff --git a/src/datasources/asset/AssetDataSource.ts b/src/datasources/asset/AssetDataSource.ts index 610006640..a1f8792b3 100644 --- a/src/datasources/asset/AssetDataSource.ts +++ b/src/datasources/asset/AssetDataSource.ts @@ -9,7 +9,6 @@ import { import { BackendSrv, getBackendSrv, getTemplateSrv, TemplateSrv } from '@grafana/runtime'; import { DataSourceBase } from 'core/DataSourceBase'; import { - AssetDataSourceOptions, AssetQuery, AssetQueryType, AssetQueryReturnType @@ -25,15 +24,16 @@ import { transformComputedFieldsQuery } from 'core/query-builder.utils'; import { AssetVariableQuery } from './types/AssetVariableQuery.types'; import { defaultListAssetsVariable, defaultProjectionForListAssetsVariable } from './defaults'; import { TAKE_LIMIT } from './constants/ListAssets.constants'; +import { FeatureToggleDataSourceOptions } from 'core/feature-toggle'; -export class AssetDataSource extends DataSourceBase { +export class AssetDataSource extends DataSourceBase { private assetSummaryDataSource: AssetSummaryDataSource; private calibrationForecastDataSource: CalibrationForecastDataSource; private listAssetsDataSource: ListAssetsDataSource; private assetQueryReturnType: AssetQueryReturnType = AssetQueryReturnType.AssetTagPath; constructor( - readonly instanceSettings: DataSourceInstanceSettings, + readonly instanceSettings: DataSourceInstanceSettings, readonly backendSrv: BackendSrv = getBackendSrv(), readonly templateSrv: TemplateSrv = getTemplateSrv() ) { diff --git a/src/datasources/asset/components/AssetQueryEditor.test.ts b/src/datasources/asset/components/AssetQueryEditor.test.ts index e2c5d7ab2..63b34d1cb 100644 --- a/src/datasources/asset/components/AssetQueryEditor.test.ts +++ b/src/datasources/asset/components/AssetQueryEditor.test.ts @@ -8,10 +8,11 @@ import { ListAssetsQuery } from '../types/ListAssets.types'; import { CalibrationForecastQuery } from '../types/CalibrationForecastQuery.types'; import { select } from 'react-select-event'; import { AssetSummaryQuery } from '../types/AssetSummaryQuery.types'; -import { AssetFeatureTogglesDefaults, AssetQueryType } from '../types/types'; +import { AssetQueryType } from '../types/types'; import { ListAssetsDataSource } from '../data-sources/list-assets/ListAssetsDataSource'; import { AssetSummaryDataSource } from '../data-sources/asset-summary/AssetSummaryDataSource'; import { LocationModel } from '../types/ListLocations.types'; +import { FeatureTogglesDefaults } from 'core/feature-toggle'; const fakeSystems: SystemProperties[] = [ { @@ -38,7 +39,7 @@ const fakeLocations: LocationModel[] = [ ] let assetDatasourceOptions = { - featureToggles: { ...AssetFeatureTogglesDefaults } + featureToggles: { ...FeatureTogglesDefaults } } class FakeAssetsSource extends ListAssetsDataSource { @@ -67,12 +68,12 @@ const render = setupRenderer(AssetQueryEditor, FakeAssetDataSource, () => assetD beforeEach(() => { assetDatasourceOptions = { - featureToggles: { ...AssetFeatureTogglesDefaults } + featureToggles: { ...FeatureTogglesDefaults } }; }); it('renders Asset list when feature is enabled', async () => { - assetDatasourceOptions.featureToggles.assetList = true; + localStorage.setItem('assetList', 'true'); render({ type: AssetQueryType.ListAssets } as ListAssetsQuery); const queryType = screen.getAllByRole('combobox')[0]; await select(queryType, "List Assets", { container: document.body }); @@ -80,7 +81,7 @@ it('renders Asset list when feature is enabled', async () => { }); it('renders Asset calibration forecast when feature is enabled', async () => { - assetDatasourceOptions.featureToggles.calibrationForecast = true; + localStorage.setItem('calibrationForecast', 'true'); render({ type: AssetQueryType.CalibrationForecast } as CalibrationForecastQuery); const queryType = screen.getAllByRole('combobox')[0]; await select(queryType, "Calibration Forecast", { container: document.body }); @@ -88,7 +89,7 @@ it('renders Asset calibration forecast when feature is enabled', async () => { }); it('renders Asset summary when feature is enabled', async () => { - assetDatasourceOptions.featureToggles.assetSummary = true; + localStorage.setItem('assetSummary', 'true'); render({ type: AssetQueryType.AssetSummary } as AssetSummaryQuery); const queryType = screen.getAllByRole('combobox')[0]; await select(queryType, "Asset Summary", { container: document.body }); diff --git a/src/datasources/asset/components/AssetQueryEditor.tsx b/src/datasources/asset/components/AssetQueryEditor.tsx index 8a4d7c1e5..8de340e2b 100644 --- a/src/datasources/asset/components/AssetQueryEditor.tsx +++ b/src/datasources/asset/components/AssetQueryEditor.tsx @@ -10,17 +10,18 @@ import { ListAssetsEditor } from './editors/list-assets/ListAssetsEditor'; import { defaultAssetSummaryQuery, defaultCalibrationForecastQuery, defaultListAssetsQuery } from '../defaults'; import { ListAssetsQuery } from '../types/ListAssets.types'; import { AssetSummaryQuery } from '../types/AssetSummaryQuery.types'; -import { AssetDataSourceOptions, AssetFeatureToggles, AssetFeatureTogglesDefaults, AssetQuery, AssetQueryType } from '../types/types'; +import { AssetQuery, AssetQueryType } from '../types/types'; import { CalibrationForecastQuery } from '../types/CalibrationForecastQuery.types'; +import { FeatureToggleDataSourceOptions, FeatureToggleNames, getFeatureFlagValue } from 'core/feature-toggle'; -type Props = QueryEditorProps; +type Props = QueryEditorProps; export function AssetQueryEditor({ query, onChange, onRunQuery, datasource }: Props) { const [queryType, setQueryType] = useState(query.type); - const assetFeatures = useRef({ - assetList: datasource.instanceSettings.jsonData?.featureToggles?.assetList ?? AssetFeatureTogglesDefaults.assetList, - calibrationForecast: datasource.instanceSettings.jsonData?.featureToggles?.calibrationForecast ?? AssetFeatureTogglesDefaults.calibrationForecast, - assetSummary: datasource.instanceSettings.jsonData?.featureToggles?.assetSummary ?? AssetFeatureTogglesDefaults.assetSummary + const assetFeatures = useRef<{ [key: string]: boolean }>({ + assetList: getFeatureFlagValue(datasource.instanceSettings.jsonData, FeatureToggleNames.assetList), + calibrationForecast: getFeatureFlagValue(datasource.instanceSettings.jsonData, FeatureToggleNames.calibrationForecast), + assetSummary: getFeatureFlagValue(datasource.instanceSettings.jsonData, FeatureToggleNames.assetSummary), }); const handleQueryChange = useCallback((value: AssetQuery, runQuery = false): void => { diff --git a/src/datasources/asset/components/editors/asset-summary/AssetSummaryEditor.test.tsx b/src/datasources/asset/components/editors/asset-summary/AssetSummaryEditor.test.tsx index 5471528d2..a86c28cfa 100644 --- a/src/datasources/asset/components/editors/asset-summary/AssetSummaryEditor.test.tsx +++ b/src/datasources/asset/components/editors/asset-summary/AssetSummaryEditor.test.tsx @@ -3,13 +3,14 @@ import { BackendSrv, TemplateSrv } from '@grafana/runtime'; import { mock } from 'jest-mock-extended'; import { AssetSummaryResponse } from 'datasources/asset/types/AssetSummaryQuery.types'; -import { AssetDataSourceOptions, AssetQuery, AssetQueryType } from 'datasources/asset/types/types'; +import { AssetQuery, AssetQueryType } from 'datasources/asset/types/types'; import { AssetSummaryDataSource } from '../../../data-sources/asset-summary/AssetSummaryDataSource'; import { assetSummaryFields } from '../../../constants/AssetSummaryQuery.constants'; +import { FeatureToggleDataSourceOptions } from 'core/feature-toggle'; describe('AssetSummaryDataSource', () => { let dataSource: AssetSummaryDataSource; - const instanceSettings = mock>(); + const instanceSettings = mock>(); const backendSrv = mock(); const templateSrv = mock(); const assetSummary: AssetSummaryResponse = { diff --git a/src/datasources/asset/components/editors/list-assets/ListAssetsEditor.test.tsx b/src/datasources/asset/components/editors/list-assets/ListAssetsEditor.test.tsx index d6d2f4b42..5396bcd51 100644 --- a/src/datasources/asset/components/editors/list-assets/ListAssetsEditor.test.tsx +++ b/src/datasources/asset/components/editors/list-assets/ListAssetsEditor.test.tsx @@ -4,11 +4,12 @@ import { AssetDataSource } from '../../../AssetDataSource'; import { AssetQueryEditor } from '../../AssetQueryEditor'; import { setupRenderer } from '../../../../../test/fixtures'; import { AssetFilterProperties, AssetFilterPropertiesOption, ListAssetsQuery, OutputType } from '../../../types/ListAssets.types'; -import { AssetFeatureTogglesDefaults, AssetQueryType } from 'datasources/asset/types/types'; +import { AssetQueryType } from 'datasources/asset/types/types'; import { ListAssetsDataSource } from '../../../data-sources/list-assets/ListAssetsDataSource'; import userEvent from '@testing-library/user-event'; import { select } from 'react-select-event'; import { LocationModel } from 'datasources/asset/types/ListLocations.types'; +import { FeatureTogglesDefaults } from 'core/feature-toggle'; const fakeSystems: SystemProperties[] = [ { @@ -35,7 +36,7 @@ const fakeLocations: LocationModel[] = [ ]; let assetDatasourceOptions = { - featureToggles: { ...AssetFeatureTogglesDefaults } + featureToggles: { ...FeatureTogglesDefaults } } class FakeAssetsSource extends ListAssetsDataSource { @@ -61,18 +62,18 @@ const render = async (query: ListAssetsQuery) => { beforeEach(() => { assetDatasourceOptions = { - featureToggles: { ...AssetFeatureTogglesDefaults } + featureToggles: { ...FeatureTogglesDefaults } }; }) it('does not render when feature is not enabled', async () => { - assetDatasourceOptions.featureToggles.assetList = false; + localStorage.setItem('assetList', 'false'); await render({} as ListAssetsQuery); await waitFor(() => expect(screen.getAllByRole('combobox').length).toBe(2)); }); it('renders the query builder', async () => { - assetDatasourceOptions.featureToggles.assetList = true; + localStorage.setItem('assetList', 'true'); await render({} as ListAssetsQuery); await waitFor(() => expect(screen.getAllByText('Property').length).toBe(1)); await waitFor(() => expect(screen.getAllByText('Operator').length).toBe(1)); @@ -223,7 +224,7 @@ it('should not display error message when user changes value to number between 0 }) it('renders the query builder with properties field', async () => { - assetDatasourceOptions.featureToggles.assetList = true; + localStorage.setItem('assetList', 'true'); await render({} as ListAssetsQuery); await waitFor(() => { diff --git a/src/datasources/asset/components/variable-editor/AssetVariableQueryEditor.tsx b/src/datasources/asset/components/variable-editor/AssetVariableQueryEditor.tsx index 28cb77515..1b03a660e 100644 --- a/src/datasources/asset/components/variable-editor/AssetVariableQueryEditor.tsx +++ b/src/datasources/asset/components/variable-editor/AssetVariableQueryEditor.tsx @@ -1,6 +1,6 @@ import React, { useEffect, useRef, useState } from 'react'; import { QueryEditorProps } from "@grafana/data"; -import { AssetDataSourceOptions, AssetQuery, AssetQueryReturnType } from '../../../asset/types/types'; +import { AssetQuery, AssetQueryReturnType } from '../../../asset/types/types'; import { AssetDataSource } from '../../AssetDataSource' import { FloatingError } from '../../../../core/errors'; import { AssetQueryBuilder } from '../editors/list-assets/query-builder/AssetQueryBuilder'; @@ -12,8 +12,9 @@ import { takeErrorMessages } from 'datasources/asset/constants/constants'; import { TAKE_LIMIT, tooltips } from 'datasources/asset/constants/ListAssets.constants'; import { validateNumericInput } from 'core/utils'; import { LocationModel } from 'datasources/asset/types/ListLocations.types'; +import { FeatureToggleDataSourceOptions } from 'core/feature-toggle'; -type Props = QueryEditorProps; +type Props = QueryEditorProps; export function AssetVariableQueryEditor({ datasource, query, onChange }: Props) { query = datasource.patchListAssetQueryVariable(query); diff --git a/src/datasources/asset/data-sources/AssetDataSourceBase.ts b/src/datasources/asset/data-sources/AssetDataSourceBase.ts index 2702954f9..ab5d364aa 100644 --- a/src/datasources/asset/data-sources/AssetDataSourceBase.ts +++ b/src/datasources/asset/data-sources/AssetDataSourceBase.ts @@ -1,5 +1,5 @@ import { DataFrameDTO, DataQueryRequest, TestDataSourceResponse } from "@grafana/data"; -import { AssetDataSourceOptions, AssetQuery } from "../types/types"; +import { AssetQuery } from "../types/types"; import { DataSourceBase } from "../../../core/DataSourceBase"; import { defaultOrderBy, defaultProjection } from "../../system/constants"; import { SystemProperties } from "../../system/types"; @@ -10,8 +10,9 @@ import { QueryBuilderOperations } from "../../../core/query-builder.constants"; import { AllFieldNames, LocationFieldNames } from "../constants/constants"; import { getVariableOptions } from "core/utils"; import { ListLocationsResponse, LocationModel } from "../types/ListLocations.types"; +import { FeatureToggleDataSourceOptions } from "core/feature-toggle"; -export abstract class AssetDataSourceBase extends DataSourceBase { +export abstract class AssetDataSourceBase extends DataSourceBase { private systemsLoaded!: () => void; private locationsLoaded!: () => void; private workspacesLeaded!: () => void; diff --git a/src/datasources/asset/data-sources/asset-summary/AssetSummaryDataSource.ts b/src/datasources/asset/data-sources/asset-summary/AssetSummaryDataSource.ts index 10c29263c..16581a4a6 100644 --- a/src/datasources/asset/data-sources/asset-summary/AssetSummaryDataSource.ts +++ b/src/datasources/asset/data-sources/asset-summary/AssetSummaryDataSource.ts @@ -3,11 +3,13 @@ import { BackendSrv, getBackendSrv, getTemplateSrv, TemplateSrv } from '@grafana import { AssetSummaryResponse } from 'datasources/asset/types/AssetSummaryQuery.types'; import { AssetDataSourceBase } from '../AssetDataSourceBase'; -import { AssetDataSourceOptions, AssetQuery, AssetQueryType } from '../../types/types'; +import { AssetQuery, AssetQueryType } from '../../types/types'; import { assetSummaryFields } from '../../constants/AssetSummaryQuery.constants'; +import { FeatureToggleDataSourceOptions } from 'core/feature-toggle'; + export class AssetSummaryDataSource extends AssetDataSourceBase { constructor( - readonly instanceSettings: DataSourceInstanceSettings, + readonly instanceSettings: DataSourceInstanceSettings, readonly backendSrv: BackendSrv = getBackendSrv(), readonly templateSrv: TemplateSrv = getTemplateSrv() ) { diff --git a/src/datasources/asset/data-sources/calibration-forecast/CalibrationForecastDataSource.ts b/src/datasources/asset/data-sources/calibration-forecast/CalibrationForecastDataSource.ts index 5bd474b34..aa5501094 100644 --- a/src/datasources/asset/data-sources/calibration-forecast/CalibrationForecastDataSource.ts +++ b/src/datasources/asset/data-sources/calibration-forecast/CalibrationForecastDataSource.ts @@ -1,10 +1,11 @@ import { DataQueryRequest, DataFrameDTO, DataSourceInstanceSettings, FieldDTO, TestDataSourceResponse, DataLink } from '@grafana/data'; -import { AssetDataSourceOptions, AssetQuery, AssetQueryType, AssetType, AssetTypeOptions, BusType, BusTypeOptions } from '../../types/types'; +import { AssetQuery, AssetQueryType, AssetType, AssetTypeOptions, BusType, BusTypeOptions } from '../../types/types'; import { BackendSrv, getBackendSrv, getTemplateSrv, TemplateSrv, locationService } from '@grafana/runtime'; import { AssetDataSourceBase } from '../AssetDataSourceBase'; import { AssetCalibrationForecastKey, AssetCalibrationTimeBasedGroupByType, CalibrationForecastQuery, CalibrationForecastResponse, ColumnDescriptorType, FieldDTOWithDescriptor } from '../../types/CalibrationForecastQuery.types'; import { transformComputedFieldsQuery } from '../../../../core/query-builder.utils'; import { AssetModel, AssetsResponse } from '../../../asset-common/types'; +import { FeatureToggleDataSourceOptions } from 'core/feature-toggle'; export class CalibrationForecastDataSource extends AssetDataSourceBase { private dependenciesLoadedPromise: Promise; @@ -16,7 +17,7 @@ export class CalibrationForecastDataSource extends AssetDataSourceBase { ]); constructor( - readonly instanceSettings: DataSourceInstanceSettings, + readonly instanceSettings: DataSourceInstanceSettings, readonly backendSrv: BackendSrv = getBackendSrv(), readonly templateSrv: TemplateSrv = getTemplateSrv() ) { diff --git a/src/datasources/asset/data-sources/list-assets/ListAssetsDataSource.ts b/src/datasources/asset/data-sources/list-assets/ListAssetsDataSource.ts index a088b96a6..989b6fcdf 100644 --- a/src/datasources/asset/data-sources/list-assets/ListAssetsDataSource.ts +++ b/src/datasources/asset/data-sources/list-assets/ListAssetsDataSource.ts @@ -1,19 +1,20 @@ import { DataQueryRequest, DataFrameDTO, DataSourceInstanceSettings, FieldType } from '@grafana/data'; import { BackendSrv, getBackendSrv, getTemplateSrv, TemplateSrv } from '@grafana/runtime'; import { AssetDataSourceBase } from '../AssetDataSourceBase'; -import { AssetDataSourceOptions, AssetQuery, AssetQueryType } from '../../types/types'; +import { AssetQuery, AssetQueryType } from '../../types/types'; import { AssetFilterProperties, AssetFilterPropertiesOption, ListAssetsQuery, OutputType, QueryListAssetRequestBody } from '../../types/ListAssets.types'; import { AssetModel, AssetsResponse } from '../../../asset-common/types'; import { transformComputedFieldsQuery } from '../../../../core/query-builder.utils'; import { defaultListAssetsQuery, defaultListAssetsQueryForOldPannels } from 'datasources/asset/defaults'; import { TAKE_LIMIT } from 'datasources/asset/constants/ListAssets.constants'; import { getWorkspaceName } from 'core/utils'; +import { FeatureToggleDataSourceOptions } from 'core/feature-toggle'; export class ListAssetsDataSource extends AssetDataSourceBase { private dependenciesLoadedPromise: Promise; constructor( - readonly instanceSettings: DataSourceInstanceSettings, + readonly instanceSettings: DataSourceInstanceSettings, readonly backendSrv: BackendSrv = getBackendSrv(), readonly templateSrv: TemplateSrv = getTemplateSrv() ) { diff --git a/src/datasources/asset/module.ts b/src/datasources/asset/module.ts index c9ef3a616..c20c4a625 100644 --- a/src/datasources/asset/module.ts +++ b/src/datasources/asset/module.ts @@ -1,12 +1,12 @@ import { DataSourcePlugin } from '@grafana/data'; import { AssetDataSource } from './AssetDataSource'; import { AssetQueryEditor } from './components/AssetQueryEditor'; -import { AssetDataSourceOptions, AssetQuery } from './types/types'; +import { AssetQuery } from './types/types'; import { AssetConfigEditor } from './AssetConfigEditor'; -import { AssetVariableQueryEditor } from './components/variable-editor/AssetVariableQueryEditor' +import { AssetVariableQueryEditor } from './components/variable-editor/AssetVariableQueryEditor'; +import { FeatureToggleDataSourceOptions } from 'core/feature-toggle'; - -export const plugin = new DataSourcePlugin(AssetDataSource) +export const plugin = new DataSourcePlugin(AssetDataSource) .setConfigEditor(AssetConfigEditor) .setQueryEditor(AssetQueryEditor) .setVariableQueryEditor(AssetVariableQueryEditor); diff --git a/src/datasources/asset/types/types.ts b/src/datasources/asset/types/types.ts index d1557bf3d..6fb572d07 100644 --- a/src/datasources/asset/types/types.ts +++ b/src/datasources/asset/types/types.ts @@ -1,7 +1,5 @@ -import { DataSourceJsonData } from "@grafana/data"; import { DataQuery } from "@grafana/schema"; - export enum AssetQueryType { None = "", ListAssets = "List Assets", @@ -13,22 +11,6 @@ export interface AssetQuery extends DataQuery { type: AssetQueryType } -export interface AssetFeatureToggles { - calibrationForecast: boolean; - assetList: boolean; - assetSummary: boolean; -} - -export interface AssetDataSourceOptions extends DataSourceJsonData { - featureToggles: AssetFeatureToggles; -} - -export const AssetFeatureTogglesDefaults: AssetFeatureToggles = { - assetList: true, - calibrationForecast: true, - assetSummary: true -} - export enum AssetQueryReturnType { AssetTagPath = 'Asset Tag Path', AssetId = 'Asset Id'