-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(asset): add feature flag support (#79)
Co-authored-by: NI\akerezsi <[email protected]>
- Loading branch information
1 parent
ad5d9e0
commit de4ee90
Showing
23 changed files
with
290 additions
and
88 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
/** | ||
* AssetConfigEditor is a React component that implements the UI for editing the asset | ||
* datasource configuration options. | ||
*/ | ||
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'; | ||
|
||
interface Props extends DataSourcePluginOptionsEditorProps<AssetDataSourceOptions> { } | ||
|
||
export const AssetConfigEditor: React.FC<Props> = ({ options, onOptionsChange }) => { | ||
const handleFeatureChange = useCallback((featureKey: string) => (event: ChangeEvent<HTMLInputElement>) => { | ||
const jsonData = { | ||
...options.jsonData, | ||
...{ featureToggles: { ...options.jsonData.featureToggles, [featureKey]: event.target.checked } } | ||
}; | ||
onOptionsChange({ ...options, jsonData }); | ||
}, [options, onOptionsChange]); | ||
|
||
return ( | ||
<> | ||
<DataSourceHttpSettings | ||
defaultUrl="" | ||
dataSourceConfig={options} | ||
showAccessOptions={false} | ||
onChange={onOptionsChange} | ||
/> | ||
<> | ||
<div style={{ paddingBottom: "10px" }}> | ||
<Text element="h6"> | ||
Features | ||
</Text> | ||
</div> | ||
<InlineSegmentGroup> | ||
<InlineField label="Asset list" labelWidth={25}> | ||
<InlineSwitch | ||
value={options.jsonData?.featureToggles?.assetList ?? AssetFeatureTogglesDefaults.assetList} | ||
onChange={handleFeatureChange('assetList')} /> | ||
</InlineField> | ||
<Tag name='Beta' colorIndex={5} /> | ||
</InlineSegmentGroup> | ||
<InlineSegmentGroup> | ||
<InlineField label="Calibration forecast" labelWidth={25}> | ||
<InlineSwitch | ||
value={options.jsonData?.featureToggles?.calibrationForecast ?? AssetFeatureTogglesDefaults.calibrationForecast} | ||
onChange={handleFeatureChange('calibrationForecast')} /> | ||
</InlineField> | ||
<Tag name='Beta' colorIndex={5} /> | ||
</InlineSegmentGroup> | ||
<InlineSegmentGroup> | ||
<InlineField label="Asset summary" labelWidth={25}> | ||
<InlineSwitch | ||
value={options.jsonData?.featureToggles?.assetSummary ?? AssetFeatureTogglesDefaults.assetSummary} | ||
onChange={handleFeatureChange('assetSummary')} /> | ||
</InlineField> | ||
<Tag name='Beta' colorIndex={5} /> | ||
</InlineSegmentGroup> | ||
</> | ||
</> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
import { screen, waitForElementToBeRemoved } from '@testing-library/react'; | ||
import { SystemMetadata } from '../../system/types'; | ||
import { AssetDataSource } from '../AssetDataSource'; | ||
import { setupRenderer } from '../../../test/fixtures'; | ||
import { ListAssetsDataSource } from './editors/list-assets/ListAssetsDataSource'; | ||
import { AssetSummaryDataSource } from './editors/asset-summary/AssetSummaryDataSource'; | ||
import { CalibrationForecastDataSource } from './editors/calibration-forecast/CalibrationForecastDataSource'; | ||
import { AssetQueryEditor } from './AssetQueryEditor'; | ||
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 } from '../types/types'; | ||
|
||
const fakeSystems: SystemMetadata[] = [ | ||
{ | ||
id: '1', | ||
state: 'CONNECTED', | ||
workspace: '1', | ||
}, | ||
{ | ||
id: '2', | ||
state: 'CONNECTED', | ||
workspace: '2', | ||
}, | ||
]; | ||
|
||
let assetDatasourceOptions = { | ||
featureToggles: { ...AssetFeatureTogglesDefaults } | ||
} | ||
|
||
class FakeAssetsSource extends ListAssetsDataSource { | ||
querySystems(filter?: string, projection?: string[]): Promise<SystemMetadata[]> { | ||
return Promise.resolve(fakeSystems); | ||
} | ||
} | ||
|
||
class FakeAssetDataSource extends AssetDataSource { | ||
getCalibrationForecastSource(): CalibrationForecastDataSource { | ||
return new CalibrationForecastDataSource(this.instanceSettings, this.backendSrv, this.templateSrv); | ||
} | ||
getAssetSummarySource(): AssetSummaryDataSource { | ||
return new AssetSummaryDataSource(this.instanceSettings, this.backendSrv, this.templateSrv); | ||
} | ||
getListAssetsSource(): ListAssetsDataSource { | ||
return new FakeAssetsSource(this.instanceSettings, this.backendSrv, this.templateSrv); | ||
} | ||
} | ||
|
||
const workspacesLoaded = () => waitForElementToBeRemoved(screen.getByTestId('Spinner')); | ||
const render = setupRenderer(AssetQueryEditor, FakeAssetDataSource, () => assetDatasourceOptions); | ||
|
||
beforeEach(() => { | ||
assetDatasourceOptions = { | ||
featureToggles: { ...AssetFeatureTogglesDefaults } | ||
}; | ||
}); | ||
|
||
it('renders Asset list when feature is enabled', async () => { | ||
assetDatasourceOptions.featureToggles.assetList = true; | ||
render({} as ListAssetsQuery); | ||
await workspacesLoaded(); | ||
|
||
expect(screen.getAllByRole('combobox').length).toBe(3); | ||
expect(screen.getAllByRole('combobox')[1]).toHaveAccessibleDescription('Any workspace'); | ||
expect(screen.getAllByRole('combobox')[2]).toHaveAccessibleDescription('Select systems'); | ||
}); | ||
|
||
it('does not render when Asset list feature is not enabled', async () => { | ||
assetDatasourceOptions.featureToggles.assetList = false; | ||
render({} as ListAssetsQuery); | ||
|
||
expect(screen.getAllByRole('combobox').length).toBe(1); | ||
}); | ||
|
||
it('does not render when Asset calibration forecast feature is not enabled', async () => { | ||
assetDatasourceOptions.featureToggles.calibrationForecast = true; | ||
render({} as CalibrationForecastQuery); | ||
const queryType = screen.getAllByRole('combobox')[0]; | ||
await select(queryType, "Calibration Forecast", { container: document.body }); | ||
expect(screen.getAllByText("Calibration Forecast").length).toBe(2) | ||
}); | ||
|
||
it('does not render when Asset summary feature is not enabled', async () => { | ||
assetDatasourceOptions.featureToggles.assetSummary = true; | ||
render({} as AssetSummaryQuery); | ||
const queryType = screen.getAllByRole('combobox')[0]; | ||
await select(queryType, "Asset Summary", { container: document.body }); | ||
expect(screen.getAllByText("Asset Summary").length).toBe(2) | ||
}); |
Oops, something went wrong.