/usr/share/grafana/public/app/plugins/datasource/cloudwatch
import { useEffect, useState } from 'react'; import { useAsyncFn, useDeepCompareEffect } from 'react-use'; import { SelectableValue, toOption } from '@grafana/data'; import { config } from '@grafana/runtime'; import { CloudWatchDatasource } from './datasource'; import { ResourcesAPI } from './resources/ResourcesAPI'; import { GetMetricsRequest, GetDimensionKeysRequest } from './resources/types'; import { appendTemplateVariables } from './utils/utils'; export const useRegions = (datasource: CloudWatchDatasource): [Array<SelectableValue<string>>, boolean] => { const [regionsIsLoading, setRegionsIsLoading] = useState<boolean>(false); const [regions, setRegions] = useState<Array<SelectableValue<string>>>([{ label: 'default', value: 'default' }]); useEffect(() => { setRegionsIsLoading(true); const variableOptionGroup = { label: 'Template Variables', options: datasource.getVariables().map(toOption), }; datasource.resources .getRegions() .then((regions: Array<SelectableValue<string>>) => setRegions([...regions, variableOptionGroup])) .finally(() => setRegionsIsLoading(false)); }, [datasource]); return [regions, regionsIsLoading]; }; export const useNamespaces = (datasource: CloudWatchDatasource) => { const [namespaces, setNamespaces] = useState<Array<SelectableValue<string>>>([]); useEffect(() => { datasource.resources.getNamespaces().then((namespaces) => { setNamespaces(appendTemplateVariables(datasource, namespaces)); }); }, [datasource]); return namespaces; }; export const useMetrics = (datasource: CloudWatchDatasource, { region, namespace, accountId }: GetMetricsRequest) => { const [metrics, setMetrics] = useState<Array<SelectableValue<string>>>([]); // need to ensure dependency array below recieves the interpolated value so that the effect is triggered when a variable is changed if (region) { region = datasource.templateSrv.replace(region, {}); } if (namespace) { namespace = datasource.templateSrv.replace(namespace, {}); } if (accountId) { accountId = datasource.templateSrv.replace(accountId, {}); } useEffect(() => { datasource.resources.getMetrics({ namespace, region, accountId }).then((result: Array<SelectableValue<string>>) => { setMetrics(appendTemplateVariables(datasource, result)); }); }, [datasource, region, namespace, accountId]); return metrics; }; export const useDimensionKeys = ( datasource: CloudWatchDatasource, { region, namespace, metricName, dimensionFilters, accountId }: GetDimensionKeysRequest ) => { const [dimensionKeys, setDimensionKeys] = useState<Array<SelectableValue<string>>>([]); // need to ensure dependency array below revieves the interpolated value so that the effect is triggered when a variable is changed if (region) { region = datasource.templateSrv.replace(region, {}); } if (namespace) { namespace = datasource.templateSrv.replace(namespace, {}); } if (metricName) { metricName = datasource.templateSrv.replace(metricName, {}); } if (accountId) { accountId = datasource.templateSrv.replace(accountId, {}); } if (dimensionFilters) { dimensionFilters = datasource.resources.convertDimensionFormat(dimensionFilters, {}, false); } // doing deep comparison to avoid making new api calls to list metrics unless dimension filter object props changes useDeepCompareEffect(() => { datasource.resources .getDimensionKeys({ namespace, region, metricName, accountId, dimensionFilters }, false) .then((result: Array<SelectableValue<string>>) => { setDimensionKeys(appendTemplateVariables(datasource, result)); }); }, [datasource, namespace, region, metricName, accountId, dimensionFilters]); return dimensionKeys; }; export const useEnsureVariableHasSingleSelection = (datasource: CloudWatchDatasource, target?: string) => { const [error, setError] = useState(''); // interpolate the target to ensure the check in useEffect runs when the variable selection is changed const interpolatedTarget = datasource.templateSrv.replace(target); useEffect(() => { if (datasource.resources.isVariableWithMultipleOptionsSelected(target)) { const newErrorMessage = `Template variables with multiple selected options are not supported for ${target}`; if (error !== newErrorMessage) { setError(newErrorMessage); } return; } if (error) { setError(''); } }, [datasource.resources, target, interpolatedTarget, error]); return error; }; export const useIsMonitoringAccount = (resources: ResourcesAPI, region: string) => { const [isMonitoringAccount, setIsMonitoringAccount] = useState(false); // we call this before the use effect to ensure dependency array below // receives the interpolated value so that the effect is triggered when a variable is changed if (region) { region = resources.templateSrv.replace(region, {}); } useEffect(() => { if (config.featureToggles.cloudWatchCrossAccountQuerying) { resources.isMonitoringAccount(region).then((result) => setIsMonitoringAccount(result)); } }, [region, resources]); return isMonitoringAccount; }; export const useAccountOptions = ( resources: Pick<ResourcesAPI, 'getAccounts' | 'templateSrv' | 'getVariables'> | undefined, region: string ) => { // we call this before the use effect to ensure dependency array below // receives the interpolated value so that the effect is triggered when a variable is changed if (region) { region = resources?.templateSrv.replace(region, {}) ?? ''; } const fetchAccountOptions = async () => { if (!config.featureToggles.cloudWatchCrossAccountQuerying) { return Promise.resolve([]); } const accounts = (await resources?.getAccounts({ region })) ?? []; if (accounts.length === 0) { return []; } const options: Array<SelectableValue<string>> = accounts.map((a) => ({ label: a.label, value: a.id, description: a.id, })); const variableOptions = resources?.getVariables().map(toOption) || []; const variableOptionGroup: SelectableValue<string> = { label: 'Template Variables', options: variableOptions, }; return [...options, variableOptionGroup]; }; const [state, doFetch] = useAsyncFn(fetchAccountOptions, [resources, region]); useEffect(() => { doFetch(); }, [resources, region, doFetch]); return state; };
.
Edit
..
Edit
README.md
Edit
annotationSupport.test.ts
Edit
annotationSupport.ts
Edit
aws_url.test.ts
Edit
aws_url.ts
Edit
components
Edit
dashboards
Edit
dataquery.cue
Edit
dataquery.gen.ts
Edit
datasource.test.ts
Edit
datasource.ts
Edit
defaultQueries.ts
Edit
expressions.ts
Edit
guards.ts
Edit
hooks.test.ts
Edit
hooks.ts
Edit
img
Edit
language
Edit
memoizedDebounce.ts
Edit
migrations
Edit
mocks
Edit
module.tsx
Edit
plugin.json
Edit
query-runner
Edit
resources
Edit
standardStatistics.ts
Edit
tracking.test.ts
Edit
tracking.ts
Edit
types.ts
Edit
utils
Edit
variables.test.ts
Edit
variables.ts
Edit