Skip to content

Commit

Permalink
Merge branch '2.x' into 2.x-backport-6911
Browse files Browse the repository at this point in the history
  • Loading branch information
BionIT committed Jun 7, 2024
2 parents 341e7dd + 4b9dd67 commit 878934f
Show file tree
Hide file tree
Showing 8 changed files with 174 additions and 172 deletions.
2 changes: 2 additions & 0 deletions changelogs/fragments/6948.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fix:
- Fix web log sample visualization & vis-builder not rendering with data source issue ([#6948](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6948))
24 changes: 1 addition & 23 deletions src/plugins/data_explorer/public/components/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,12 @@
* SPDX-License-Identifier: Apache-2.0
*/

import React, { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
import React from 'react';
import { AppMountParameters } from '../../../../core/public';
import { useView } from '../utils/use';
import { AppContainer } from './app_container';
import { useOpenSearchDashboards } from '../../../opensearch_dashboards_react/public';
import { DataExplorerServices } from '../types';
import { syncQueryStateWithUrl } from '../../../data/public';

export const DataExplorerApp = ({ params }: { params: AppMountParameters }) => {
const { view } = useView();
const {
services: {
data: { query },
osdUrlStateStorage,
},
} = useOpenSearchDashboards<DataExplorerServices>();
const { pathname } = useLocation();

useEffect(() => {
// syncs `_g` portion of url with query services
const { stop } = syncQueryStateWithUrl(query, osdUrlStateStorage);

return () => stop();

// this effect should re-run when pathname is changed to preserve querystring part,
// so the global state is always preserved
}, [query, osdUrlStateStorage, pathname]);

return <AppContainer view={view} params={params} />;
};
93 changes: 51 additions & 42 deletions src/plugins/data_explorer/public/components/app_container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,51 +10,60 @@ import { AppMountParameters } from '../../../../core/public';
import { Sidebar } from './sidebar';
import { NoView } from './no_view';
import { View } from '../services/view_service/view';
import { shallowEqual } from '../utils/use/shallow_equal';
import './app_container.scss';

export const AppContainer = ({ view, params }: { view?: View; params: AppMountParameters }) => {
const isMobile = useIsWithinBreakpoints(['xs', 's', 'm']);
// TODO: Make this more robust.
if (!view) {
return <NoView />;
}
export const AppContainer = React.memo(
({ view, params }: { view?: View; params: AppMountParameters }) => {
const isMobile = useIsWithinBreakpoints(['xs', 's', 'm']);
// TODO: Make this more robust.
if (!view) {
return <NoView />;
}

const { Canvas, Panel, Context } = view;
const { Canvas, Panel, Context } = view;

const MemoizedPanel = memo(Panel);
const MemoizedCanvas = memo(Canvas);
const MemoizedPanel = memo(Panel);
const MemoizedCanvas = memo(Canvas);

// Render the application DOM.
return (
<EuiPage className="deLayout" paddingSize="none">
{/* TODO: improve fallback state */}
<Suspense fallback={<div>Loading...</div>}>
<Context {...params}>
<EuiResizableContainer direction={isMobile ? 'vertical' : 'horizontal'}>
{(EuiResizablePanel, EuiResizableButton) => (
<>
<EuiResizablePanel
initialSize={20}
minSize="260px"
mode={['collapsible', { position: 'top' }]}
paddingSize="none"
>
<Sidebar>
<MemoizedPanel {...params} />
</Sidebar>
</EuiResizablePanel>
<EuiResizableButton />
// Render the application DOM.
return (
<EuiPage className="deLayout" paddingSize="none">
{/* TODO: improve fallback state */}
<Suspense fallback={<div>Loading...</div>}>
<Context {...params}>
<EuiResizableContainer direction={isMobile ? 'vertical' : 'horizontal'}>
{(EuiResizablePanel, EuiResizableButton) => (
<>
<EuiResizablePanel
initialSize={20}
minSize="260px"
mode={['collapsible', { position: 'top' }]}
paddingSize="none"
>
<Sidebar>
<MemoizedPanel {...params} />
</Sidebar>
</EuiResizablePanel>
<EuiResizableButton />

<EuiResizablePanel initialSize={80} minSize="65%" mode="main" paddingSize="none">
<EuiPageBody className="deLayout__canvas">
<MemoizedCanvas {...params} />
</EuiPageBody>
</EuiResizablePanel>
</>
)}
</EuiResizableContainer>
</Context>
</Suspense>
</EuiPage>
);
};
<EuiResizablePanel initialSize={80} minSize="65%" mode="main" paddingSize="none">
<EuiPageBody className="deLayout__canvas">
<MemoizedCanvas {...params} />
</EuiPageBody>
</EuiResizablePanel>
</>
)}
</EuiResizableContainer>
</Context>
</Suspense>
</EuiPage>
);
},
(prevProps, nextProps) => {
return (
prevProps.view === nextProps.view &&
shallowEqual(prevProps.params, nextProps.params, ['history'])
);
}
);
48 changes: 48 additions & 0 deletions src/plugins/data_explorer/public/utils/use/shallow_equal.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import { shallowEqual } from './shallow_equal';

describe('shallowEqual', () => {
it('should return true for equal objects without ignored keys', () => {
const obj1 = { a: 1, b: 2, c: 3 };
const obj2 = { a: 1, b: 2, c: 3 };
const ignoreKeys = [];

expect(shallowEqual(obj1, obj2, ignoreKeys)).toBe(true);
});

it('should return false for objects with different values', () => {
const obj1 = { a: 1, b: 2, c: 3 };
const obj2 = { a: 1, b: 2, c: 4 };
const ignoreKeys = [];

expect(shallowEqual(obj1, obj2, ignoreKeys)).toBe(false);
});

it('should return false for objects with different keys', () => {
const obj1 = { a: 1, b: 2 };
const obj2 = { a: 1, b: 2, c: 3 };
const ignoreKeys = [];

expect(shallowEqual(obj1, obj2, ignoreKeys)).toBe(false);
});

it('should return true for objects with different values but ignored', () => {
const obj1 = { a: 1, b: 2, c: 3 };
const obj2 = { a: 1, b: 2, c: 4 };
const ignoreKeys = ['c'];

expect(shallowEqual(obj1, obj2, ignoreKeys)).toBe(true);
});

it('should return true for objects with different keys but ignored', () => {
const obj1 = { a: 1, b: 2 };
const obj2 = { a: 1, b: 2, c: 4 };
const ignoreKeys = ['c'];

expect(shallowEqual(obj1, obj2, ignoreKeys)).toBe(true);
});
});
22 changes: 22 additions & 0 deletions src/plugins/data_explorer/public/utils/use/shallow_equal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

// A simple shallow equal function that can ignore specified keys
export function shallowEqual(object1: any, object2: any, ignoreKeys: any) {
const keys1 = Object.keys(object1).filter((key) => !ignoreKeys.includes(key));
const keys2 = Object.keys(object2).filter((key) => !ignoreKeys.includes(key));

if (keys1.length !== keys2.length) {
return false;
}

for (const key of keys1) {
if (object1[key] !== object2[key]) {
return false;
}
}

return true;
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { debounceTime } from 'rxjs/operators';
import { i18n } from '@osd/i18n';
import { useEffect } from 'react';
import { cloneDeep } from 'lodash';
import { useLocation } from 'react-router-dom';
import { RequestAdapter } from '../../../../../inspector/public';
import { DiscoverViewServices } from '../../../build_services';
import { search } from '../../../../../data/public';
Expand All @@ -31,6 +32,7 @@ import {
getResponseInspectorStats,
} from '../../../opensearch_dashboards_services';
import { SEARCH_ON_PAGE_LOAD_SETTING } from '../../../../common';
import { syncQueryStateWithUrl } from '../../../../../data/public';

export enum ResultStatus {
UNINITIALIZED = 'uninitialized',
Expand Down Expand Up @@ -68,11 +70,19 @@ export type RefetchSubject = Subject<SearchRefetch>;
* }, [data$]);
*/
export const useSearch = (services: DiscoverViewServices) => {
const { pathname } = useLocation();
const initalSearchComplete = useRef(false);
const [savedSearch, setSavedSearch] = useState<SavedSearch | undefined>(undefined);
const { savedSearch: savedSearchId, sort, interval } = useSelector((state) => state.discover);
const { data, filterManager, getSavedSearchById, core, toastNotifications, chrome } = services;
const indexPattern = useIndexPattern(services);
const {
data,
filterManager,
getSavedSearchById,
core,
toastNotifications,
osdUrlStateStorage,
} = services;
const timefilter = data.query.timefilter.timefilter;
const fetchStateRef = useRef<{
abortController: AbortController | undefined;
Expand Down Expand Up @@ -309,6 +319,16 @@ export const useSearch = (services: DiscoverViewServices) => {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [getSavedSearchById, savedSearchId]);

useEffect(() => {
// syncs `_g` portion of url with query services
const { stop } = syncQueryStateWithUrl(data.query, osdUrlStateStorage);

return () => stop();

// this effect should re-run when pathname is changed to preserve querystring part,
// so the global state is always preserved
}, [data.query, osdUrlStateStorage, pathname]);

return {
data$,
refetch$,
Expand Down
Loading

0 comments on commit 878934f

Please sign in to comment.