Skip to content

Commit

Permalink
[Log Explorer] Remove top level tabs (opensearch-project#970)
Browse files Browse the repository at this point in the history
* remove unused files

Signed-off-by: Eric Wei <[email protected]>

* missing snapshots

Signed-off-by: Eric Wei <[email protected]>

* minimal changes to remove log explorer tab

Signed-off-by: Eric <[email protected]>

* skip tab related tests

Signed-off-by: Eric <[email protected]>

* update snapshots

Signed-off-by: Eric <[email protected]>

* remove missed logging

Signed-off-by: Eric <[email protected]>

* add path to constant

Signed-off-by: Eric <[email protected]>

---------

Signed-off-by: Eric Wei <[email protected]>
Signed-off-by: Eric <[email protected]>
  • Loading branch information
mengweieric authored Sep 7, 2023
1 parent 2544618 commit dd50d8b
Show file tree
Hide file tree
Showing 11 changed files with 53 additions and 261 deletions.
11 changes: 6 additions & 5 deletions .cypress/integration/1_event_analytics.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@ describe('Open flyout for a data row to see details', () => {
});
});

describe('Add/delete/switch explorer top level tabs', () => {
// skip for now due to tab removals
describe.skip('Add/delete/switch explorer top level tabs', () => {
beforeEach(() => {
landOnEventExplorer();
});
Expand Down Expand Up @@ -406,15 +407,15 @@ describe('Live tail stop automatically', () => {
landOnEventExplorer();
});

it('Moving to other tab should stop live tail automatically', () => {
it.skip('Moving to other tab should stop live tail automatically', () => {
clearQuerySearchBoxText('searchAutocompleteTextArea');
cy.get('[data-test-subj="searchAutocompleteTextArea"]').type(TEST_QUERIES[1].query);
cy.get('[data-test-subj=eventLiveTail]').click();
cy.get('[data-test-subj=eventLiveTail__delay10s]').click();
cy.get('.euiToastHeader__title').contains('On').should('exist');
});

it('Add a new tab', () => {
it.skip('Add a new tab', () => {
cy.get('[data-test-subj="eventExplorer__topLevelTabbing"]')
.find('button.euiTab')
.then((lists) => {
Expand All @@ -426,7 +427,7 @@ describe('Live tail stop automatically', () => {
});
});

it('Click to switch to another tab', () => {
it.skip('Click to switch to another tab', () => {
cy.get('[data-test-subj="eventExplorer__addNewTab"]', {
timeout: COMMAND_TIMEOUT_LONG,
}).click();
Expand All @@ -441,7 +442,7 @@ describe('Live tail stop automatically', () => {
.should('have.class', 'euiTab-isSelected');
});

it('Close current selected tab', () => {
it.skip('Close current selected tab', () => {
cy.get('[data-test-subj="eventExplorer__addNewTab"]', {
timeout: COMMAND_TIMEOUT_LONG,
}).click();
Expand Down
3 changes: 3 additions & 0 deletions common/constants/explorer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@ import { htmlIdGenerator } from '@elastic/eui';
import { ThresholdUnitType } from '../../public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/config_thresholds';
import { VIS_CHART_TYPES } from './shared';

// URLs
export const EVENT_ANALYTICS_DOCUMENTATION_URL =
'https://opensearch.org/docs/latest/observability-plugin/event-analytics/';
export const OPEN_TELEMETRY_LOG_CORRELATION_LINK =
'https://opentelemetry.io/docs/reference/specification/logs/overview/#log-correlation';
export const LOG_EXPLORER_BASE_PATH = 'observability-logs#/explorer/';

export const RAW_QUERY = 'rawQuery';
export const FINAL_QUERY = 'finalQuery';
export const SELECTED_DATE_RANGE = 'selectedDateRange';
Expand Down
4 changes: 1 addition & 3 deletions common/types/explorer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,7 @@ export interface IExplorerFields {
}

export interface EmptyTabParams {
tabIds: string[] | undefined;
queries: any | undefined;
explorerData: any | undefined;
tabIds: string[];
}

export interface ILogExplorerProps {
Expand Down
1 change: 0 additions & 1 deletion public/components/common/search/search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import {
EuiBadge,
EuiContextMenuPanel,
EuiToolTip,
EuiCallOut,
} from '@elastic/eui';
import { DatePicker } from './date_picker';
import '@algolia/autocomplete-theme-classic';
Expand Down
21 changes: 3 additions & 18 deletions public/components/event_analytics/explorer/explorer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ import {
DATE_PICKER_FORMAT,
DEFAULT_AVAILABILITY_QUERY,
EVENT_ANALYTICS_DOCUMENTATION_URL,
NEW_TAB,
PATTERNS_EXTRACTOR_REGEX,
PATTERNS_REGEX,
RAW_QUERY,
Expand All @@ -52,7 +51,6 @@ import {
SELECTED_TIMESTAMP,
TAB_CHART_ID,
TAB_CHART_TITLE,
TAB_CREATED_TYPE,
TAB_EVENT_ID,
TAB_EVENT_TITLE,
TIME_INTERVAL_OPTIONS,
Expand Down Expand Up @@ -347,17 +345,6 @@ export const Explorer = ({
}, [appBasedRef.current]);

useEffect(() => {
let objectId;
if (queryRef.current![TAB_CREATED_TYPE] === NEW_TAB || appLogEvents) {
objectId = queryRef.current!.savedObjectId || '';
} else {
objectId = queryRef.current!.savedObjectId || savedObjectId;
}
if (objectId) {
updateTabData(objectId);
} else {
fetchData(startTime, endTime);
}
if (
routerContext &&
routerContext.searchParams.get(CREATE_TAB_PARAM_KEY) === CREATE_TAB_PARAM[TAB_CHART_ID]
Expand All @@ -367,10 +354,8 @@ export const Explorer = ({
}, []);

useEffect(() => {
if (appLogEvents) {
if (savedObjectId) {
updateTabData(savedObjectId);
}
if (savedObjectId) {
updateTabData(savedObjectId);
}
}, [savedObjectId]);

Expand Down Expand Up @@ -642,7 +627,7 @@ export const Explorer = ({
isOverridingTimestamp,
query,
isLiveTailOnRef.current,
isOverridingPattern
isOverridingPattern,
]);

const visualizations: IVisualizationContainerProps = useMemo(() => {
Expand Down
170 changes: 21 additions & 149 deletions public/components/event_analytics/explorer/log_explorer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,21 @@
* SPDX-License-Identifier: Apache-2.0
*/
/* eslint-disable react-hooks/exhaustive-deps */

import {
EuiIcon,
EuiTabbedContent,
EuiTabbedContentTab,
EuiText,
htmlIdGenerator,
} from '@elastic/eui';
import $ from 'jquery';
import { isEmpty, map } from 'lodash';
import React, { useContext, useEffect, useMemo, useRef, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { isEmpty } from 'lodash';
import React, { useContext, useEffect, useRef, useState } from 'react';
import { useSelector } from 'react-redux';
import { useHistory } from 'react-router-dom';
import { LogExplorerRouterContext } from '..';
import {
APP_ANALYTICS_TAB_ID_REGEX,
CREATE_TAB_PARAM_KEY,
NEW_TAB,
REDIRECT_TAB,
SAVED_OBJECT_ID,
TAB_CHART_ID,
TAB_EVENT_ID,
TAB_ID_TXT_PFX,
TAB_TITLE,
} from '../../../../common/constants/explorer';
import { ILogExplorerProps } from '../../../../common/types/explorer';
import { initializeTabData, removeTabData } from '../../application_analytics/helpers/utils';
import { selectQueryResult } from '../redux/slices/query_result_slice';
import { selectQueries } from '../redux/slices/query_slice';
import { selectQueryTabs, setSelectedQueryTab } from '../redux/slices/query_tab_slice';
import { selectQueryTabs } from '../redux/slices/query_tab_slice';
import { Explorer } from './explorer';

const searchBarConfigs = {
Expand Down Expand Up @@ -60,11 +45,9 @@ export const LogExplorer = ({
}: ILogExplorerProps) => {
const history = useHistory();
const routerContext = useContext(LogExplorerRouterContext);
const dispatch = useDispatch();
const tabIds = useSelector(selectQueryTabs).queryTabIds.filter(
(tabid: string) => !tabid.match(APP_ANALYTICS_TAB_ID_REGEX)
);
const tabNames = useSelector(selectQueryTabs).tabNames;
const queries = useSelector(selectQueries);
const curSelectedTabId = useSelector(selectQueryTabs).selectedQueryTab;
const explorerData = useSelector(selectQueryResult);
Expand All @@ -79,68 +62,12 @@ export const LogExplorer = ({

const [tabCreatedTypes, setTabCreatedTypes] = useState({});

// Append add-new-tab link to the end of the tab list, and remove it once tabs state changes
useEffect(() => {
const newLink = $(
'<a class="linkNewTag" data-test-subj="eventExplorer__addNewTab">+ Add new</a>'
).on('click', () => {
addNewTab(NEW_TAB);
});
$('.queryTabs > .euiTabs').append(newLink);
return () => {
$('.queryTabs > .euiTabs .linkNewTag').remove();
};
}, [tabIds]);

const handleTabClick = (selectedTab: EuiTabbedContentTab) => {
history.replace(`/explorer/${queryRef.current![selectedTab.id][SAVED_OBJECT_ID] || ''}`);
dispatch(setSelectedQueryTab({ tabId: selectedTab.id }));
};

const handleTabClose = (TabIdToBeClosed: string) => {
if (tabIds.length === 1) {
setToast('Cannot close last tab.', 'danger');
return;
}

const index: number = tabIds.indexOf(TabIdToBeClosed);
const curSelectedTab = curSelectedTabIdRef.current;
let newIdToFocus = '';
if (TabIdToBeClosed === curSelectedTab) {
if (index === 0) {
newIdToFocus = tabIds[index + 1];
} else if (index > 0) {
newIdToFocus = tabIds[index - 1];
}
}
removeTabData(dispatch, TabIdToBeClosed, newIdToFocus);
};

const addNewTab = async (where: string) => {
// get a new tabId
const tabId = htmlIdGenerator(TAB_ID_TXT_PFX)();

// create a new tab
await initializeTabData(dispatch, tabId, where);

setTabCreatedTypes((staleState) => {
return {
...staleState,
[tabId]: where,
};
});

return tabId;
};

const dispatchSavedObjectId = async () => {
const emptyTabId = getExistingEmptyTab({
return getExistingEmptyTab({
tabIds: tabIdsRef.current,
queries: queryRef.current,
explorerData: explorerDataRef.current,
});
const newTabId = emptyTabId ? emptyTabId : await addNewTab(REDIRECT_TAB);
return newTabId;
};

useEffect(() => {
Expand All @@ -150,7 +77,6 @@ export const LogExplorer = ({
if (routerContext && routerContext.searchParams.has(CREATE_TAB_PARAM_KEY)) {
// need to wait for current redux event loop to finish
setImmediate(() => {
addNewTab(NEW_TAB);
routerContext.searchParams.delete(CREATE_TAB_PARAM_KEY);
routerContext.routerProps.history.replace({
search: routerContext.searchParams.toString(),
Expand All @@ -159,78 +85,24 @@ export const LogExplorer = ({
}
}, []);

function getQueryTab({
tabTitle,
tabId,
handlesTabClose,
}: {
tabTitle: string;
tabId: string;
handlesTabClose: (TabIdToBeClosed: string) => void;
}) {
return {
id: tabId,
name: (
<>
<EuiText size="s" textAlign="left" color="default">
<span className="tab-title">{tabTitle}</span>
<EuiIcon
type="cross"
onClick={(e) => {
e.stopPropagation();
handlesTabClose(tabId);
}}
data-test-subj="eventExplorer__tabClose"
/>
</EuiText>
</>
),
content: (
<>
<Explorer
key={`explorer_${tabId}`}
pplService={pplService}
dslService={dslService}
tabId={tabId}
savedObjects={savedObjects}
timestampUtils={timestampUtils}
setToast={setToast}
history={history}
notifications={notifications}
savedObjectId={savedObjectId}
tabCreatedTypes={tabCreatedTypes}
curSelectedTabId={curSelectedTabIdRef}
http={http}
searchBarConfigs={searchBarConfigs}
queryManager={queryManager}
/>
</>
),
};
}

const memorizedTabs = useMemo(() => {
const res = map(tabIds, (tabId) => {
return getQueryTab({
tabTitle: tabNames[tabId] || TAB_TITLE,
tabId,
handlesTabClose: handleTabClose,
});
});

return res;
}, [tabIds, tabNames, tabCreatedTypes]);

return (
<>
<EuiTabbedContent
id="queryTabs"
className="queryTabs"
tabs={memorizedTabs}
selectedTab={memorizedTabs.find((tab) => tab.id === curSelectedTabId)}
onTabClick={(selectedTab: EuiTabbedContentTab) => handleTabClick(selectedTab)}
data-test-subj="eventExplorer__topLevelTabbing"
size="s"
<Explorer
key={`explorer_${tabIds[0]}`}
pplService={pplService}
dslService={dslService}
tabId={tabIds[0]}
savedObjects={savedObjects}
timestampUtils={timestampUtils}
setToast={setToast}
history={history}
notifications={notifications}
savedObjectId={savedObjectId}
tabCreatedTypes={tabCreatedTypes}
curSelectedTabId={curSelectedTabIdRef}
http={http}
searchBarConfigs={searchBarConfigs}
queryManager={queryManager}
/>
</>
);
Expand Down
Loading

0 comments on commit dd50d8b

Please sign in to comment.