/* * Copyright OpenSearch Contributors * SPDX-License-Identifier: Apache-2.0 */ import React, { useCallback, useContext, useEffect, useMemo, useState } from 'react'; import { EuiComboBox, EuiComboBoxOptionOption, EuiIcon, EuiTabbedContent, EuiTabbedContentTab, } from '@elastic/eui'; import hjson from 'hjson'; import { find } from 'lodash'; import { ENABLED_VIS_TYPES } from '../../../../../../common/constants/shared'; import { getVisTypeData } from '../../../../visualizations/charts/helpers/viz_types'; import { TabContext } from '../../../hooks'; import { reset as resetVisualizationConfig } from '../../../redux/slices/viualization_config_slice'; import { getDefaultSpec } from '../visualization_specs/default_spec'; const HJSON_STRINGIFY_OPTIONS = { keepWsc: true, condense: 0, bracesSameLine: true, }; interface PanelTabType { id: string; name: string; mapTo: string; editor: any; section?: any; content?: any; } export const ConfigPanel = ({ visualizations, setCurVisId, callback }: any) => { const { tabId, curVisId, dispatch, changeVisualizationConfig, setToast } = useContext( TabContext ); const { data, vis } = visualizations; const { userConfigs } = data; const isAppAnalyticsConfigPanel = data.appData?.fromApp; const [vizConfigs, setVizConfigs] = useState({ dataConfig: {}, layoutConfig: userConfigs?.layoutConfig ? hjson.stringify({ ...userConfigs.layoutConfig }, HJSON_STRINGIFY_OPTIONS) : getDefaultSpec(), availabilityConfig: {}, }); useEffect(() => { setVizConfigs({ ...userConfigs, layoutConfig: userConfigs?.layoutConfig ? hjson.stringify({ ...userConfigs.layoutConfig }, HJSON_STRINGIFY_OPTIONS) : getDefaultSpec(), }); if (callback) { callback(() => switchToAvailability()); } }, [userConfigs, curVisId]); const handleConfigUpdate = useCallback( (updatedConfigs) => { try { dispatch( changeVisualizationConfig({ tabId, vizId: curVisId, data: { ...{ ...updatedConfigs, layoutConfig: hjson.parse(updatedConfigs.layoutConfig), }, }, }) ); } catch (e: any) { setToast(`Invalid visualization configurations. error: ${e.message}`, 'danger'); } }, [tabId, changeVisualizationConfig, dispatch, setToast, curVisId] ); const handleConfigChange = (configSchema: string) => { return (configChanges: any) => { const updatedVizConfigs = { ...vizConfigs, [configSchema]: configChanges }; setVizConfigs((staleState) => { return { ...staleState, [configSchema]: configChanges, }; }); handleConfigUpdate(updatedVizConfigs); }; }; const params = useMemo(() => { return { dataConfig: { visualizations, curVisId, onConfigChange: handleConfigChange('dataConfig'), vizState: vizConfigs.dataConfig, }, layoutConfig: { onConfigEditorChange: handleConfigChange('layoutConfig'), spec: vizConfigs.layoutConfig, setToast, }, ...(isAppAnalyticsConfigPanel && { availabilityConfig: { visualizations, curVisId, onConfigChange: handleConfigChange('availabilityConfig'), vizState: vizConfigs.availabilityConfig, }, }), }; }, [visualizations, vizConfigs, setToast, curVisId]); const tabs: EuiTabbedContentTab[] = useMemo(() => { // hide availability for event analytics, only show availability in App Analytics let tabsToRender: EuiTabbedContentTab[] = vis.editorconfig.panelTabs; if (!isAppAnalyticsConfigPanel) { tabsToRender = vis.editorconfig.panelTabs.filter( (pnltb: PanelTabType) => pnltb.id !== 'availability-panel' ); } return tabsToRender.map((tab: PanelTabType) => { const Editor = tab.editor; return { id: tab.id, name: tab.name, content: , }; }); }, [vis.editorconfig.panelTabs, params]); const [currTabId, setCurrTabId] = useState(tabs[0].id); const switchToAvailability = () => { setCurrTabId('availability-panel'); }; const onTabClick = (selectedTab: EuiTabbedContentTab) => { setCurrTabId(selectedTab.id); }; const handleDiscardConfig = () => { dispatch( resetVisualizationConfig({ tabId, }) ); }; const memorizedVisualizationTypes = useMemo( () => ENABLED_VIS_TYPES.map((vs: string) => getVisTypeData(vs)), [] ); const vizSelectableItemRenderer = (option: EuiComboBoxOptionOption) => { const { icontype = 'empty', label = '' } = option; return (
   {label}
); }; const getSelectedVisDById = useCallback( (visId) => { const selectedOption = find(memorizedVisualizationTypes, (v) => { return v.id === visId; }); selectedOption.iconType = selectedOption.icontype; return selectedOption; }, [memorizedVisualizationTypes] ); return (
{ handleDiscardConfig(); // currently reset all viz configurations setCurVisId(visType[0].id); }} fullWidth renderOption={vizSelectableItemRenderer} isClearable={false} />
tab.id === currTabId) || tabs[0]} onTabClick={onTabClick} />
); };