mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
88 lines
2.3 KiB
TypeScript
88 lines
2.3 KiB
TypeScript
import React, { FC, useCallback, useMemo, useState } from 'react';
|
|
|
|
import {
|
|
FrameMatcherID,
|
|
getFieldDisplayName,
|
|
MatcherConfig,
|
|
SelectableValue,
|
|
StandardEditorProps,
|
|
} from '@grafana/data';
|
|
import { Select } from '@grafana/ui';
|
|
|
|
const recoverRefIdMissing = (
|
|
newRefIds: SelectableValue[],
|
|
oldRefIds: SelectableValue[],
|
|
previousValue: string | undefined
|
|
): SelectableValue | undefined => {
|
|
if (!previousValue) {
|
|
return;
|
|
}
|
|
// Previously selected value is missing from the new list.
|
|
// Find the value that is in the new list but isn't in the old list
|
|
let changedTo = newRefIds.find((refId) => {
|
|
return !oldRefIds.some((refId2) => {
|
|
return refId === refId2;
|
|
});
|
|
});
|
|
if (changedTo) {
|
|
// Found the new value, we assume the old value changed to this one, so we'll use it
|
|
return changedTo;
|
|
}
|
|
return;
|
|
};
|
|
|
|
export const FrameSelectionEditor: FC<StandardEditorProps<MatcherConfig>> = ({ value, context, onChange, item }) => {
|
|
const listOfRefId = useMemo(() => {
|
|
return context.data.map((f) => ({
|
|
value: f.refId,
|
|
label: `Query: ${f.refId} (size: ${f.length})`,
|
|
description: f.fields.map((f) => getFieldDisplayName(f)).join(', '),
|
|
}));
|
|
}, [context.data]);
|
|
|
|
const [priorSelectionState, updatePriorSelectionState] = useState<{
|
|
refIds: SelectableValue[];
|
|
value: string | undefined;
|
|
}>({
|
|
refIds: [],
|
|
value: undefined,
|
|
});
|
|
|
|
const currentValue = useMemo(() => {
|
|
return (
|
|
listOfRefId.find((refId) => refId.value === value?.options) ??
|
|
recoverRefIdMissing(listOfRefId, priorSelectionState.refIds, priorSelectionState.value)
|
|
);
|
|
}, [value, listOfRefId, priorSelectionState]);
|
|
|
|
const onFilterChange = useCallback(
|
|
(v: SelectableValue<string>) => {
|
|
onChange(
|
|
v?.value
|
|
? {
|
|
id: FrameMatcherID.byRefId,
|
|
options: v.value,
|
|
}
|
|
: undefined
|
|
);
|
|
},
|
|
[onChange]
|
|
);
|
|
|
|
if (listOfRefId !== priorSelectionState.refIds || currentValue?.value !== priorSelectionState.value) {
|
|
updatePriorSelectionState({
|
|
refIds: listOfRefId,
|
|
value: currentValue?.value,
|
|
});
|
|
}
|
|
return (
|
|
<Select
|
|
options={listOfRefId}
|
|
onChange={onFilterChange}
|
|
isClearable={true}
|
|
placeholder="Change filter"
|
|
value={currentValue}
|
|
/>
|
|
);
|
|
};
|