Skip to content

Commit

Permalink
[VisBuilder] fixes filters for table visualisation (#3210) (#3233)
Browse files Browse the repository at this point in the history
* fixes table vis for filter aggregation types

Signed-off-by: Ashwin P Chandran <ashwinpc@amazon.com>

* Fixes filter and add error boundry

Signed-off-by: Ashwin P Chandran <ashwinpc@amazon.com>

* Adds changelog

Signed-off-by: Ashwin P Chandran <ashwinpc@amazon.com>

Signed-off-by: Ashwin P Chandran <ashwinpc@amazon.com>
(cherry picked from commit fba380b)
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

# Conflicts:
#	CHANGELOG.md

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
  • Loading branch information
1 parent 28751d4 commit 0c02514
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,24 @@
* SPDX-License-Identifier: Apache-2.0
*/

import React, { useCallback, useMemo, useState } from 'react';
import React, { Component, useCallback, useMemo, useState } from 'react';
import { cloneDeep, get } from 'lodash';
import { useDebounce } from 'react-use';
import { i18n } from '@osd/i18n';
import { EuiCallOut } from '@elastic/eui';
import { useTypedDispatch, useTypedSelector } from '../../utils/state_management';
import { DefaultEditorAggParams } from '../../../../../vis_default_editor/public';
import { Title } from './title';
import { useIndexPatterns, useVisualizationType } from '../../utils/use';
import { useOpenSearchDashboards } from '../../../../../opensearch_dashboards_react/public';
import {
OpenSearchDashboardsContextProvider,
useOpenSearchDashboards,
} from '../../../../../opensearch_dashboards_react/public';
import { VisBuilderServices } from '../../../types';
import { AggParam, IAggType, IFieldParamType } from '../../../../../data/public';
import { saveDraftAgg, editDraftAgg } from '../../utils/state_management/visualization_slice';
import { setValidity } from '../../utils/state_management/metadata_slice';
import { Storage } from '../../../../../opensearch_dashboards_utils/public';

const EDITOR_KEY = 'CONFIG_PANEL';

Expand All @@ -27,13 +33,12 @@ export function SecondaryPanel() {
const dispatch = useTypedDispatch();
const vizType = useVisualizationType();
const indexPattern = useIndexPatterns().selected;
const { services } = useOpenSearchDashboards<VisBuilderServices>();
const {
services: {
data: {
search: { aggs: aggService },
},
data: {
search: { aggs: aggService },
},
} = useOpenSearchDashboards<VisBuilderServices>();
} = services;
const schemas = vizType.ui.containerConfig.data.schemas.all;

const aggConfigs = useMemo(() => {
Expand Down Expand Up @@ -98,49 +103,98 @@ export function SecondaryPanel() {
<div className="vbConfig__section vbConfig--secondary">
<Title title={selectedSchema?.title ?? 'Edit'} isSecondary closeMenu={closeMenu} />
{showAggParamEditor && (
<DefaultEditorAggParams
className="vbConfig__aggEditor"
agg={aggConfig!}
indexPattern={indexPattern!}
setValidity={handleSetValid}
setTouched={setTouched}
schemas={schemas}
formIsTouched={touched}
groupName={selectedSchema?.group ?? 'none'}
metricAggs={metricAggs}
state={{
data: {},
description: '',
title: '',
<OpenSearchDashboardsContextProvider
services={{
...services,
storage: new Storage(window.localStorage), // This is necessary for filters
}}
setAggParamValue={function <T extends string | number | symbol>(
aggId: string,
paramName: T,
value: any
): void {
aggConfig.params[paramName] = value;
dispatch(editDraftAgg(aggConfig.serialize()));
}}
onAggTypeChange={function (aggId: string, aggType: IAggType): void {
aggConfig.type = aggType;

// Persist field if the new agg type supports the existing field
const fieldParam = (aggType.params as AggParam[]).find(({ type }) => type === 'field');
if (fieldParam) {
const availableFields = (fieldParam as IFieldParamType).getAvailableFields(aggConfig);
const indexField = availableFields.find(
({ name }) => name === get(draftAgg, 'params.field')
);

if (indexField) {
aggConfig.params.field = indexField;
}
}

dispatch(editDraftAgg(aggConfig.serialize()));
}}
/>
>
<EditorErrorBoundary>
<DefaultEditorAggParams
className="vbConfig__aggEditor"
agg={aggConfig!}
indexPattern={indexPattern!}
setValidity={handleSetValid}
setTouched={setTouched}
schemas={schemas}
formIsTouched={touched}
groupName={selectedSchema?.group ?? 'none'}
metricAggs={metricAggs}
state={{
data: {},
description: '',
title: '',
}}
setAggParamValue={function <T extends string | number | symbol>(
aggId: string,
paramName: T,
value: any
): void {
aggConfig.params[paramName] = value;
dispatch(editDraftAgg(aggConfig.serialize()));
}}
onAggTypeChange={function (aggId: string, aggType: IAggType): void {
aggConfig.type = aggType;

// Persist field if the new agg type supports the existing field
const fieldParam = (aggType.params as AggParam[]).find(
({ type }) => type === 'field'
);
if (fieldParam) {
const availableFields = (fieldParam as IFieldParamType).getAvailableFields(
aggConfig
);
const indexField = availableFields.find(
({ name }) => name === get(draftAgg, 'params.field')
);

if (indexField) {
aggConfig.params.field = indexField;
}
}

dispatch(editDraftAgg(aggConfig.serialize()));
}}
/>
</EditorErrorBoundary>
</OpenSearchDashboardsContextProvider>
)}
</div>
);
}

class EditorErrorBoundary extends Component<{}, { error?: any }> {
state = {
error: undefined,
};

static getDerivedStateFromError(error: any) {
return { error };
}

componentDidCatch(error) {
// eslint-disable-next-line no-console
console.error(error);
}

render() {
if (this.state.error) {
return (
<EuiCallOut
title={i18n.translate('visBuilder.aggParamsEditor.errorTitle', {
defaultMessage: 'Error',
})}
color="danger"
iconType="alert"
>
<p>
{i18n.translate('visBuilder.aggParamsEditor.errorMsg', {
defaultMessage: 'Something went wrong while editing the aggregation',
})}
</p>
</EuiCallOut>
);
}
return this.props.children;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import React, { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
import { useUnmount } from 'react-use';
import { PLUGIN_ID } from '../../../common';
import { useOpenSearchDashboards } from '../../../../opensearch_dashboards_react/public';
import { getTopNavConfig } from '../utils/get_top_nav_config';
import { VisBuilderServices } from '../../types';
Expand All @@ -29,6 +28,7 @@ export const TopNav = () => {
navigation: {
ui: { TopNavMenu },
},
appName,
} = services;
const rootState = useTypedSelector((state) => state);
const dispatch = useTypedDispatch();
Expand Down Expand Up @@ -81,7 +81,7 @@ export const TopNav = () => {
return (
<div className="vbTopNav">
<TopNavMenu
appName={PLUGIN_ID}
appName={appName}
config={config}
setMenuMountPoint={setHeaderActionMenu}
indexPatterns={indexPattern ? [indexPattern] : []}
Expand Down
1 change: 1 addition & 0 deletions src/plugins/vis_builder/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ export class VisBuilderPlugin

const services: VisBuilderServices = {
...coreStart,
appName: PLUGIN_ID,
scopedHistory: this.currentHistory,
history: this.currentHistory,
osdUrlStateStorage: createOsdUrlStateStorage({
Expand Down
1 change: 1 addition & 0 deletions src/plugins/vis_builder/public/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export interface VisBuilderPluginStartDependencies {
}

export interface VisBuilderServices extends CoreStart {
appName: string;
setHeaderActionMenu: AppMountParameters['setHeaderActionMenu'];
savedVisBuilderLoader: VisBuilderStart['savedVisBuilderLoader'];
toastNotifications: ToastsStart;
Expand Down
3 changes: 3 additions & 0 deletions src/plugins/vis_type_table/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@ import { TableVisPlugin as Plugin } from './plugin';
export function plugin(initializerContext: PluginInitializerContext) {
return new Plugin(initializerContext);
}

/* Public Types */
export { TableVisExpressionFunctionDefinition } from './table_vis_fn';

0 comments on commit 0c02514

Please sign in to comment.