From 79cf934ae0e1dda7545674a4e2919e7ef0fb5853 Mon Sep 17 00:00:00 2001 From: Ashwin P Chandran Date: Thu, 30 Jun 2022 17:08:43 -0700 Subject: [PATCH] [D&D] Adds drop validation (#1833) * edit and add agg works Signed-off-by: Ashwin Pc * edit agg using draft state Signed-off-by: Ashwin Pc * Adds other metric style props Signed-off-by: Ashwin Pc * feat: Adds agg type validation and defaults on drop Signed-off-by: Ashwin Pc * chore: refactor filter Signed-off-by: Ashwin Pc --- .../public/components/agg_params_helper.ts | 2 +- .../data_tab/items/use/use_dropbox.tsx | 54 ++++++++++++++----- .../application/utils/drag_drop/types.ts | 2 +- .../visualizations/metric/metric_viz_type.ts | 4 +- 4 files changed, 44 insertions(+), 18 deletions(-) diff --git a/src/plugins/vis_default_editor/public/components/agg_params_helper.ts b/src/plugins/vis_default_editor/public/components/agg_params_helper.ts index 8255c2945411..a16071f51c08 100644 --- a/src/plugins/vis_default_editor/public/components/agg_params_helper.ts +++ b/src/plugins/vis_default_editor/public/components/agg_params_helper.ts @@ -51,7 +51,7 @@ interface ParamInstanceBase { agg: IAggConfig; editorConfig: EditorConfig; metricAggs: IAggConfig[]; - state: EditorVisState; + state: Partial; schemas: Schema[]; hideCustomLabel?: boolean; } diff --git a/src/plugins/wizard/public/application/contributions/containers/data_tab/items/use/use_dropbox.tsx b/src/plugins/wizard/public/application/contributions/containers/data_tab/items/use/use_dropbox.tsx index c966767b4852..ebabb90eccbf 100644 --- a/src/plugins/wizard/public/application/contributions/containers/data_tab/items/use/use_dropbox.tsx +++ b/src/plugins/wizard/public/application/contributions/containers/data_tab/items/use/use_dropbox.tsx @@ -3,9 +3,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { useCallback, useMemo } from 'react'; +import { useState, useEffect, useCallback, useMemo } from 'react'; import { cloneDeep } from 'lodash'; -import { IndexPatternField } from 'src/plugins/data/common'; +import { BucketAggType, IndexPatternField, propFilter } from '../../../../../../../../data/common'; import { Schema } from '../../../../../../../../vis_default_editor/public'; import { FieldDragDataType } from '../../../../../utils/drag_drop/types'; import { useTypedDispatch, useTypedSelector } from '../../../../../utils/state_management'; @@ -21,6 +21,9 @@ import { useIndexPattern } from '../../../../../../application/utils/use/use_ind import { useOpenSearchDashboards } from '../../../../../../../../opensearch_dashboards_react/public'; import { WizardServices } from '../../../../../../types'; +const filterByName = propFilter('name'); +const filterByType = propFilter('type'); + export const INITIAL_STATE: DropboxState = { instances: [], }; @@ -31,6 +34,7 @@ export interface UseDropboxProps extends Pick { export const useDropbox = (props: UseDropboxProps): DropboxProps => { const { id: dropboxId, label, schema } = props; + const [validAggTypes, setValidAggTypes] = useState([]); const dispatch = useTypedDispatch(); const indexPattern = useIndexPattern(); const { @@ -118,12 +122,16 @@ export const useDropbox = (props: UseDropboxProps): DropboxProps => { const onDropField = useCallback( (data: FieldDragDataType['value']) => { - if (!data) return; + if (!data || !validAggTypes.length) return; const { name: fieldName } = data; + const schemaAggTypes = (schema.defaults as any).aggTypes; + const allowedAggTypes = schemaAggTypes + ? schemaAggTypes.filter((type) => validAggTypes.includes(type)) + : []; aggConfigs?.createAggConfig({ - type: (schema.defaults as any).aggType, + type: allowedAggTypes[0] || validAggTypes[0], schema: schema.name, params: { field: fieldName, @@ -134,7 +142,7 @@ export const useDropbox = (props: UseDropboxProps): DropboxProps => { dispatch(updateAggConfigParams(aggConfigs.aggs.map((agg) => agg.serialize()))); } }, - [aggConfigs, dispatch, schema.defaults, schema.name] + [aggConfigs, dispatch, schema.defaults, schema.name, validAggTypes] ); const onReorderField = useCallback( @@ -154,17 +162,35 @@ export const useDropbox = (props: UseDropboxProps): DropboxProps => { onDropField ); - const isValidDropField = useMemo(() => { - if (!dragData) return false; + useEffect(() => { + const getValidAggTypes = () => { + if (!dragData || schema.group === 'none') return []; + + const indexField = getIndexPatternField(dragData.name, indexPattern?.fields ?? []); + + if (!indexField) return []; - const indexField = getIndexPatternField(dragData.name, indexPattern?.fields ?? []); + // Get all aggTypes allowed by the schema and get a list of all the aggTypes that the dragged index field can use + const aggTypes = aggService.types.getAll(); + const allowedAggTypes = filterByName(aggTypes[schema.group], schema.aggFilter); + + return ( + allowedAggTypes + .filter((aggType) => { + const allowedFieldTypes = aggType.paramByName('field')?.filterFieldTypes; + return filterByType([indexField], allowedFieldTypes).length !== 0; + }) + // `types` can be either a Bucket or Metric aggType, but both types have the name property. + .map((agg) => (agg as BucketAggType).name) + ); + }; - if (!indexField) return false; + setValidAggTypes(getValidAggTypes()); - return isValidDropTarget; - // TODO: Validate if the field is droppable from schema ref : src/plugins/vis_default_editor/public/components/agg_params.tsx - // return isValidDropTarget && (isDroppable?.(indexField) ?? true); - }, [dragData, indexPattern?.fields, isValidDropTarget]); + return () => { + setValidAggTypes([]); + }; + }, [aggService.types, dragData, indexPattern?.fields, schema.aggFilter, schema.group]); return { id: dropboxId, @@ -177,7 +203,7 @@ export const useDropbox = (props: UseDropboxProps): DropboxProps => { onReorderField, ...dropState, dragData, - isValidDropTarget: isValidDropField, + isValidDropTarget: validAggTypes.length > 0, dropProps, }; }; diff --git a/src/plugins/wizard/public/application/utils/drag_drop/types.ts b/src/plugins/wizard/public/application/utils/drag_drop/types.ts index 0258a2315ec6..8ac8deb73e44 100644 --- a/src/plugins/wizard/public/application/utils/drag_drop/types.ts +++ b/src/plugins/wizard/public/application/utils/drag_drop/types.ts @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { IndexPatternField } from 'src/plugins/data/common'; +import { IndexPatternField } from '../../../../../data/common'; export interface EmptyDragDataType { namespace: null; diff --git a/src/plugins/wizard/public/visualizations/metric/metric_viz_type.ts b/src/plugins/wizard/public/visualizations/metric/metric_viz_type.ts index 406984f87ece..ce85db45c51b 100644 --- a/src/plugins/wizard/public/visualizations/metric/metric_viz_type.ts +++ b/src/plugins/wizard/public/visualizations/metric/metric_viz_type.ts @@ -67,7 +67,7 @@ export const createMetricConfig = (): VisualizationTypeOptions