Skip to content

Commit

Permalink
[Data Explorer] Adds toggle between legacy and new discover (opensear…
Browse files Browse the repository at this point in the history
…ch-project#4563)

* Adds toggle between legacy and new discover

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

* Fixes header offset

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

---------

Signed-off-by: Ashwin P Chandran <ashwinpc@amazon.com>
  • Loading branch information
ashwin-pc committed Jul 18, 2023
1 parent d4ce533 commit 6e0a855
Show file tree
Hide file tree
Showing 20 changed files with 234 additions and 43 deletions.
2 changes: 1 addition & 1 deletion src/plugins/data_explorer/opensearch_dashboards.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"opensearchDashboardsVersion": "opensearchDashboards",
"server": true,
"ui": true,
"requiredPlugins": ["navigation"],
"requiredPlugins": ["data", "navigation"],
"optionalPlugins": [],
"requiredBundles": ["opensearchDashboardsReact"]
}
10 changes: 3 additions & 7 deletions src/plugins/data_explorer/public/application.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,16 @@ import { DataExplorerApp } from './components/app';
export const renderApp = (
{ notifications, http }: CoreStart,
services: DataExplorerServices,
{ appBasePath, element, history }: AppMountParameters
params: AppMountParameters
) => {
const { history, element } = params;
ReactDOM.render(
<Router history={history}>
<OpenSearchDashboardsContextProvider services={services}>
<services.i18n.Context>
<Switch>
<Route path={[`/:appId`, '/']} exact={false}>
<DataExplorerApp
basename={appBasePath}
notifications={notifications}
http={http}
history={history}
/>
<DataExplorerApp params={params} />
</Route>
</Switch>
</services.i18n.Context>
Expand Down
13 changes: 3 additions & 10 deletions src/plugins/data_explorer/public/components/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,12 @@
*/

import React from 'react';
import { CoreStart, ScopedHistory } from '../../../../core/public';
import { AppMountParameters } from '../../../../core/public';
import { useView } from '../utils/use';
import { AppContainer } from './app_container';

interface DataExplorerAppDeps {
basename: string;
notifications: CoreStart['notifications'];
http: CoreStart['http'];
history: ScopedHistory;
}

export const DataExplorerApp = (deps: DataExplorerAppDeps) => {
export const DataExplorerApp = ({ params }: { params: AppMountParameters }) => {
const { view } = useView();

return <AppContainer view={view} />;
return <AppContainer view={view} params={params} />;
};
10 changes: 6 additions & 4 deletions src/plugins/data_explorer/public/components/app_container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@

import React, { useLayoutEffect, useRef, useState } from 'react';
import { EuiPageTemplate } from '@elastic/eui';

import { AppMountParameters } from '../../../../core/public';
import { Sidebar } from './sidebar';
import { NoView } from './no_view';
import { View } from '../services/view_service/view';

export const AppContainer = ({ view }: { view?: View }) => {
export const AppContainer = ({ view, params }: { view?: View; params: AppMountParameters }) => {
const [showSpinner, setShowSpinner] = useState(false);
const canvasRef = useRef<HTMLDivElement>(null);
const panelRef = useRef<HTMLDivElement>(null);
Expand All @@ -24,7 +24,8 @@ export const AppContainer = ({ view }: { view?: View }) => {
}
};

if (!view) {
// Do nothing if the view is not defined or if the view is the same as the previous view
if (!view || (unmountRef.current && unmountRef.current.viewId === view.id)) {
return;
}

Expand All @@ -38,6 +39,7 @@ export const AppContainer = ({ view }: { view?: View }) => {
(await view.mount({
canvasElement: canvasRef.current!,
panelElement: panelRef.current!,
appParams: params,
})) || null;
} catch (e) {
// TODO: add error UI
Expand All @@ -54,7 +56,7 @@ export const AppContainer = ({ view }: { view?: View }) => {
mount();

return unmount;
}, [view]);
}, [params, view]);

// TODO: Make this more robust.
if (!view) {
Expand Down
4 changes: 4 additions & 0 deletions src/plugins/data_explorer/public/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,7 @@ $osdHeaderOffset: $euiHeaderHeightCompensation;
.dePageTemplate {
height: calc(100vh - #{$osdHeaderOffset});
}

.headerIsExpanded .dePageTemplate {
height: calc(100vh - #{$osdHeaderOffset * 2});
}
25 changes: 21 additions & 4 deletions src/plugins/data_explorer/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,40 @@ import {
Plugin,
AppNavLinkStatus,
} from '../../../core/public';
import { DataExplorerPluginSetup, DataExplorerPluginStart, DataExplorerServices } from './types';
import {
DataExplorerPluginSetup,
DataExplorerPluginSetupDependencies,
DataExplorerPluginStart,
DataExplorerPluginStartDependencies,
DataExplorerServices,
} from './types';
import { PLUGIN_ID, PLUGIN_NAME } from '../common';
import { ViewService } from './services/view_service';

export class DataExplorerPlugin
implements Plugin<DataExplorerPluginSetup, DataExplorerPluginStart> {
implements
Plugin<
DataExplorerPluginSetup,
DataExplorerPluginStart,
DataExplorerPluginSetupDependencies,
DataExplorerPluginStartDependencies
> {
private viewService = new ViewService();

public setup(core: CoreSetup): DataExplorerPluginSetup {
public setup(
core: CoreSetup<DataExplorerPluginStartDependencies, DataExplorerPluginStart>
): DataExplorerPluginSetup {
const viewService = this.viewService;
// Register an application into the side navigation menu
core.application.register({
id: PLUGIN_ID,
title: PLUGIN_NAME,
navLinkStatus: AppNavLinkStatus.hidden,
async mount(params: AppMountParameters) {
const [coreStart, depsStart] = await core.getStartServices();
const [coreStart, pluginsStart] = await core.getStartServices();

// make sure the index pattern list is up to date
pluginsStart.data.indexPatterns.clearCache();

const services: DataExplorerServices = {
...coreStart,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
* SPDX-License-Identifier: Apache-2.0
*/

// TODO: Correctly type this file.
import { AppMountParameters } from '../../../../../core/public';

// TODO: State management props

interface ViewListItem {
id: string;
Expand All @@ -13,6 +15,7 @@ interface ViewListItem {
export interface ViewMountParameters {
canvasElement: HTMLDivElement;
panelElement: HTMLDivElement;
appParams: AppMountParameters;
}

export interface ViewDefinition<T = any> {
Expand Down
7 changes: 7 additions & 0 deletions src/plugins/data_explorer/public/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,20 @@

import { CoreStart } from 'opensearch-dashboards/public';
import { ViewService } from './services/view_service';
import { DataPublicPluginStart } from '../../data/public';

export interface DataExplorerPluginSetup {
registerView: ViewService['registerView'];
}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface DataExplorerPluginStart {}

// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface DataExplorerPluginSetupDependencies {}
export interface DataExplorerPluginStartDependencies {
data: DataPublicPluginStart;
}

export interface ViewRedirectParams {
view: string;
path?: string;
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/discover/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/

export const PLUGIN_ID = 'discover';
export const DISCOVER_LEGACY_TOGGLE = 'discover:legacyToggle';
export const NEW_DISCOVER_APP = 'discover:v2';
export const DEFAULT_COLUMNS_SETTING = 'defaultColumns';
export const SAMPLE_SIZE_SETTING = 'discover:sampleSize';
export const AGGS_TERMS_SIZE_SETTING = 'discover:aggs:terms:size';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import React from 'react';
import { AppMountParameters } from '../../../../../../core/public';
import { useOpenSearchDashboards } from '../../../../../opensearch_dashboards_react/public';
import { DiscoverServices } from '../../../build_services';
import { TopNav } from './top_nav';

interface CanvasProps {
opts: {
setHeaderActionMenu: AppMountParameters['setHeaderActionMenu'];
};
}

export const Canvas = ({ opts }: CanvasProps) => {
const { services } = useOpenSearchDashboards<DiscoverServices>();

return (
<div>
<TopNav opts={opts} />
Canvas
</div>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,21 @@ import ReactDOM from 'react-dom';
import { ViewMountParameters } from '../../../../../data_explorer/public';
import { OpenSearchDashboardsContextProvider } from '../../../../../opensearch_dashboards_react/public';
import { DiscoverServices } from '../../../build_services';
import { Canvas } from './canvas';

export const renderCanvas = (
{ canvasElement }: ViewMountParameters,
{ canvasElement, appParams }: ViewMountParameters,
services: DiscoverServices
) => {
const { setHeaderActionMenu } = appParams;

ReactDOM.render(
<OpenSearchDashboardsContextProvider services={services}>
{/* This is dummy code, inline styles will not be added in production */}
<div style={{ whiteSpace: 'pre-wrap' }}>
{JSON.stringify(services.capabilities.navLinks, null, 2)}
</div>
<Canvas
opts={{
setHeaderActionMenu,
}}
/>
</OpenSearchDashboardsContextProvider>,
canvasElement
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import React, { useEffect, useState } from 'react';
import { i18n } from '@osd/i18n';
import { AppMountParameters } from '../../../../../../core/public';
import { NEW_DISCOVER_APP, PLUGIN_ID } from '../../../../common';
import { useOpenSearchDashboards } from '../../../../../opensearch_dashboards_react/public';
import { DiscoverServices } from '../../../build_services';
import { IndexPattern } from '../../../opensearch_dashboards_services';

export interface TopNavProps {
opts: {
setHeaderActionMenu: AppMountParameters['setHeaderActionMenu'];
};
}

export const TopNav = ({ opts }: TopNavProps) => {
const {
services: {
uiSettings,
navigation: {
ui: { TopNavMenu },
},
core: {
application: { navigateToApp },
},
data,
},
} = useOpenSearchDashboards<DiscoverServices>();
const [indexPatterns, setIndexPatterns] = useState<IndexPattern[] | undefined>(undefined);

useEffect(() => {
if (uiSettings.get(NEW_DISCOVER_APP) === false) {
const path = window.location.hash;
navigateToApp('discoverLegacy', {
replace: true,
path,
});
}

return () => {};
}, [navigateToApp, uiSettings]);

useEffect(() => {
const getDefaultIndexPattern = async () => {
await data.indexPatterns.ensureDefaultIndexPattern();
const indexPattern = await data.indexPatterns.getDefault();

setIndexPatterns(indexPattern ? [indexPattern] : undefined);
};

getDefaultIndexPattern();
}, [data.indexPatterns]);

return (
<TopNavMenu
appName={PLUGIN_ID}
config={[
{
label: i18n.translate('discover.localMenu.legacyDiscoverTitle', {
defaultMessage: 'Legacy Discover',
}),
run: async () => {
await uiSettings.set(NEW_DISCOVER_APP, false);
window.location.reload();
},
emphasize: true,
},
]}
showSearchBar
useDefaultBehaviors
setMenuMountPoint={opts.setHeaderActionMenu}
indexPatterns={indexPatterns}
/>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ import ReactDOM from 'react-dom';
import { ViewMountParameters } from '../../../../../data_explorer/public';
import { OpenSearchDashboardsContextProvider } from '../../../../../opensearch_dashboards_react/public';
import { DiscoverServices } from '../../../build_services';
import { Panel } from './panel';

export const renderPanel = ({ panelElement }: ViewMountParameters, services: DiscoverServices) => {
ReactDOM.render(
<OpenSearchDashboardsContextProvider services={services}>
<div>Side panel</div>
<Panel />
</OpenSearchDashboardsContextProvider>,
panelElement
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import React from 'react';

export const Panel = () => {
return <div>Side Panel</div>;
};
1 change: 1 addition & 0 deletions src/plugins/discover/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,4 @@ export { SavedSearch, SavedSearchLoader, createSavedSearchesLoader } from './sav
// TODO: Fix embeddable after removing Angular
// export { ISearchEmbeddable, SEARCH_EMBEDDABLE_TYPE, SearchInput } from './application/embeddable';
export { DISCOVER_APP_URL_GENERATOR, DiscoverUrlGeneratorState } from './url_generator';
export { NEW_DISCOVER_APP } from '../common';
7 changes: 4 additions & 3 deletions src/plugins/discover/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ import {
DiscoverUrlGenerator,
} from './url_generator';
// import { SearchEmbeddableFactory } from './application/embeddable';
import { DISCOVER_LEGACY_TOGGLE, PLUGIN_ID } from '../common';
import { NEW_DISCOVER_APP, PLUGIN_ID } from '../common';
import { DataExplorerPluginSetup, ViewRedirectParams } from '../../data_explorer/public';
import { registerFeature } from './register_feature';

Expand Down Expand Up @@ -319,9 +319,10 @@ export class DiscoverPlugin
},
} = await this.initializeServices();

// This is for instances where the user navigates to the app from the application nav menu
const path = window.location.hash;
const enableLegacyMode = await core.uiSettings.get<boolean>(DISCOVER_LEGACY_TOGGLE);
if (enableLegacyMode) {
const v2Enabled = await core.uiSettings.get<boolean>(NEW_DISCOVER_APP);
if (!v2Enabled) {
navigateToApp('discoverLegacy', {
replace: true,
path,
Expand Down
Loading

0 comments on commit 6e0a855

Please sign in to comment.