Transformations: Add includeByName to organize fields transformation (#77797)

* add includeByName inclusion list to transform, update ui to work with either filtering method
This commit is contained in:
Galen Kistler
2023-11-13 08:59:37 -06:00
committed by GitHub
parent 55d61c93d2
commit 7617a7a3fc
3 changed files with 52 additions and 3 deletions

View File

@@ -70,6 +70,33 @@ describe('OrganizeFields Transformer', () => {
]); ]);
}); });
}); });
it('should order and filter (inclusion) according to config', async () => {
const cfg: DataTransformerConfig<OrganizeFieldsTransformerOptions> = {
id: DataTransformerID.organize,
options: {
excludeByName: {},
indexByName: {},
includeByName: {
time: true,
},
renameByName: {},
},
};
await expect(transformDataFrame([cfg], [data])).toEmitValuesWith((received) => {
const data = received[0];
const organized = data[0];
expect(organized.fields).toEqual([
{
config: {},
name: 'time',
type: FieldType.time,
values: [3000, 4000, 5000, 6000],
},
]);
});
});
}); });
describe('when inconsistent data is received', () => { describe('when inconsistent data is received', () => {

View File

@@ -9,6 +9,7 @@ export interface OrganizeFieldsTransformerOptions
extends OrderFieldsTransformerOptions, extends OrderFieldsTransformerOptions,
RenameFieldsTransformerOptions { RenameFieldsTransformerOptions {
excludeByName: Record<string, boolean>; excludeByName: Record<string, boolean>;
includeByName?: Record<string, boolean>;
} }
export const organizeFieldsTransformer: DataTransformerInfo<OrganizeFieldsTransformerOptions> = { export const organizeFieldsTransformer: DataTransformerInfo<OrganizeFieldsTransformerOptions> = {
@@ -19,6 +20,7 @@ export const organizeFieldsTransformer: DataTransformerInfo<OrganizeFieldsTransf
excludeByName: {}, excludeByName: {},
indexByName: {}, indexByName: {},
renameByName: {}, renameByName: {},
includeByName: {},
}, },
isApplicable: (data: DataFrame[]) => { isApplicable: (data: DataFrame[]) => {
return data.length > 1 return data.length > 1
@@ -33,6 +35,7 @@ export const organizeFieldsTransformer: DataTransformerInfo<OrganizeFieldsTransf
source.pipe( source.pipe(
filterFieldsByNameTransformer.operator( filterFieldsByNameTransformer.operator(
{ {
include: options.includeByName ? { names: mapToExcludeArray(options.includeByName) } : undefined,
exclude: { names: mapToExcludeArray(options.excludeByName) }, exclude: { names: mapToExcludeArray(options.excludeByName) },
}, },
ctx ctx

View File

@@ -20,10 +20,11 @@ import { useAllFieldNamesFromDataFrames } from '../utils';
interface OrganizeFieldsTransformerEditorProps extends TransformerUIProps<OrganizeFieldsTransformerOptions> {} interface OrganizeFieldsTransformerEditorProps extends TransformerUIProps<OrganizeFieldsTransformerOptions> {}
const OrganizeFieldsTransformerEditor = ({ options, input, onChange }: OrganizeFieldsTransformerEditorProps) => { const OrganizeFieldsTransformerEditor = ({ options, input, onChange }: OrganizeFieldsTransformerEditorProps) => {
const { indexByName, excludeByName, renameByName } = options; const { indexByName, excludeByName, renameByName, includeByName } = options;
const fieldNames = useAllFieldNamesFromDataFrames(input); const fieldNames = useAllFieldNamesFromDataFrames(input);
const orderedFieldNames = useMemo(() => orderFieldNamesByIndex(fieldNames, indexByName), [fieldNames, indexByName]); const orderedFieldNames = useMemo(() => orderFieldNamesByIndex(fieldNames, indexByName), [fieldNames, indexByName]);
const filterType = includeByName && Object.keys(includeByName).length > 0 ? 'include' : 'exclude';
const onToggleVisibility = useCallback( const onToggleVisibility = useCallback(
(field: string, shouldExclude: boolean) => { (field: string, shouldExclude: boolean) => {
@@ -38,6 +39,20 @@ const OrganizeFieldsTransformerEditor = ({ options, input, onChange }: OrganizeF
[onChange, options, excludeByName] [onChange, options, excludeByName]
); );
const onToggleVisibilityInclude = useCallback(
(field: string, shouldInclude: boolean) => {
const pendingState = {
...options,
includeByName: {
...includeByName,
[field]: !shouldInclude,
},
};
onChange(pendingState);
},
[onChange, options, includeByName]
);
const onDragEnd = useCallback( const onDragEnd = useCallback(
(result: DropResult) => { (result: DropResult) => {
if (!result || !result.destination) { if (!result || !result.destination) {
@@ -88,14 +103,18 @@ const OrganizeFieldsTransformerEditor = ({ options, input, onChange }: OrganizeF
{(provided) => ( {(provided) => (
<div ref={provided.innerRef} {...provided.droppableProps}> <div ref={provided.innerRef} {...provided.droppableProps}>
{orderedFieldNames.map((fieldName, index) => { {orderedFieldNames.map((fieldName, index) => {
const isIncludeFilter = includeByName && fieldName in includeByName ? includeByName[fieldName] : false;
const isVisible = filterType === 'include' ? isIncludeFilter : !excludeByName[fieldName];
const onToggleFunction = filterType === 'include' ? onToggleVisibilityInclude : onToggleVisibility;
return ( return (
<DraggableFieldName <DraggableFieldName
fieldName={fieldName} fieldName={fieldName}
renamedFieldName={renameByName[fieldName]} renamedFieldName={renameByName[fieldName]}
index={index} index={index}
onToggleVisibility={onToggleVisibility} onToggleVisibility={onToggleFunction}
onRenameField={onRenameField} onRenameField={onRenameField}
visible={!excludeByName[fieldName]} visible={isVisible}
key={fieldName} key={fieldName}
/> />
); );