grafana/public/app/features/geo/editor/GazetteerPathEditor.tsx
Ashley Harrison 06d3c27bc1
Select: Portal menu by default (#48176)
* Remove menuShouldPortal from all <Select /> components

* fix unit tests

* leave menuShouldPortal as an escape hatch

* Fix import order
2022-05-04 15:12:59 +01:00

103 lines
2.6 KiB
TypeScript

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';
const defaultPaths: Array<SelectableValue<string>> = [
{
label: 'Countries',
description: 'Lookup countries by name, two letter code, or three letter code',
value: COUNTRIES_GAZETTEER_PATH,
},
{
label: 'USA States',
description: 'Lookup states by name or 2 ',
value: 'public/gazetteer/usa-states.json',
},
{
label: 'Airports',
description: 'Lookup airports by id or code',
value: 'public/gazetteer/airports.geojson',
},
];
export interface GazetteerPathEditorConfigSettings {
options?: Array<SelectableValue<string>>;
}
export const GazetteerPathEditor: FC<StandardEditorProps<string, any, any, GazetteerPathEditorConfigSettings>> = ({
value,
onChange,
context,
item,
}) => {
const styles = getStyles(useTheme2());
const [gaz, setGaz] = useState<Gazetteer>();
const settings = item.settings as any;
useEffect(() => {
async function fetchData() {
const p = await getGazetteer(value);
setGaz(p);
}
fetchData();
}, [value, setGaz]);
const { current, options } = useMemo(() => {
let options = settings?.options ? [...settings.options] : [...defaultPaths];
let current = options?.find((f) => f.value === gaz?.path);
if (!current && gaz) {
current = {
label: gaz.path,
value: gaz.path,
};
options.push(current);
}
return { options, current };
}, [gaz, settings?.options]);
return (
<>
<Select
value={current}
options={options}
onChange={(v) => onChange(v.value)}
allowCustomValue={true}
formatCreateLabel={(txt) => `Load from URL: ${txt}`}
/>
{gaz && (
<>
{gaz.error && <Alert title={gaz.error} severity={'warning'} />}
{gaz.count && (
<div className={styles.keys}>
<b>({gaz.count})</b>
{gaz.examples(10).map((k) => (
<span key={k}>{k},</span>
))}
{gaz.count > 10 && ' ...'}
</div>
)}
</>
)}
</>
);
};
const getStyles = stylesFactory((theme: GrafanaTheme2) => {
return {
keys: css`
margin-top: 4px;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
> span {
margin-left: 4px;
}
`,
};
});