Skip to content

Commit

Permalink
handle refresh, adjust naming, unit test
Browse files Browse the repository at this point in the history
Signed-off-by: Adam Tackett <[email protected]>
  • Loading branch information
Adam Tackett committed Nov 11, 2024
1 parent 3126f99 commit 42b6c6b
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 30 deletions.
2 changes: 1 addition & 1 deletion common/constants/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export const JOBS_ENDPOINT_BASE = '/_plugins/_async_query';
export const JOB_RESULT_ENDPOINT = '/result';

export const tutorialSampleDataPluginId = 'import_sample_data';
export const dataSourcesId = 'dataSources';
export const dataSourceManagementPluginId = 'dataSources';

export const observabilityID = 'observability-logs';
export const observabilityTitle = 'Observability';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Dashboard controls should render 1`] = `
exports[`Dashboard controls - checkDataSource useEffect simplified should render 1`] = `
<DashboardControls>
<AddDashboardCallout>
<EuiPanel
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,21 @@ import { configure, mount } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import React from 'react';
import { DashboardControls } from '../dashboard_controls';
import { coreRefs } from '../../../../framework/core_refs';
import { setObservabilityDashboardsId } from '../utils';
import { getWorkspaceIdFromUrl } from '../../../../../../../src/core/public/utils';
import { act } from 'react-dom/test-utils';

configure({ adapter: new Adapter() });

const mountDashboardControls = () => {
return mount(<DashboardControls />);
};

jest.mock('../../../getting_started/components/utils', () => ({
redirectToDashboards: jest.fn(),
}));

jest.mock('../../../../framework/core_refs', () => ({
coreRefs: {
contentManagement: {
updatePageSection: jest.fn(),
savedObjectsClient: {
find: jest.fn(),
},
http: {
basePath: {
Expand All @@ -31,13 +31,68 @@ jest.mock('../../../../framework/core_refs', () => ({
},
}));

describe('Dashboard controls', () => {
jest.mock('../utils', () => ({
setObservabilityDashboardsId: jest.fn(),
}));

jest.mock('../../../../../common/utils', () => ({
getOverviewPage: jest.fn(() => ({
removeSection: jest.fn(),
})),
}));

jest.mock('../../../../../../../src/core/public/utils', () => ({
getWorkspaceIdFromUrl: jest.fn(),
}));

describe('Dashboard controls - checkDataSource useEffect simplified', () => {
beforeEach(() => {
jest.clearAllMocks();
});

it('should render', () => {
const wrapper = mountDashboardControls();
const wrapper = mount(<DashboardControls />);
expect(wrapper).toMatchSnapshot();
});

it('should handle no data sources in a workspace', async () => {
getWorkspaceIdFromUrl.mockReturnValue('workspace123');
coreRefs.savedObjectsClient.find.mockResolvedValue({ savedObjects: [] });

const mockSetObservabilityDashboardsId = setObservabilityDashboardsId;

await act(async () => {
mount(<DashboardControls />);
await new Promise((resolve) => setImmediate(resolve));
});

expect(mockSetObservabilityDashboardsId).toHaveBeenCalledWith(null);
});

it('should handle existing data sources in a workspace', async () => {
getWorkspaceIdFromUrl.mockReturnValue('workspace123');
coreRefs.savedObjectsClient.find.mockResolvedValue({ savedObjects: [{ id: 'ds1' }] });

const mockSetObservabilityDashboardsId = setObservabilityDashboardsId;

await act(async () => {
mount(<DashboardControls />);
await new Promise((resolve) => setImmediate(resolve));
});

expect(mockSetObservabilityDashboardsId).not.toHaveBeenCalled();
});

it('should handle non-workspace scenario', async () => {
getWorkspaceIdFromUrl.mockReturnValue(null);

const mockSetObservabilityDashboardsId = setObservabilityDashboardsId;

await act(async () => {
mount(<DashboardControls />);
await new Promise((resolve) => setImmediate(resolve));
});

expect(mockSetObservabilityDashboardsId).not.toHaveBeenCalled();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import SampleDataLightPNG from './assets/SampleDataLight.png';

export function AddDashboardCallout() {
const showFlyout = useObservable(ObsDashboardStateManager.showFlyout$);
const isDarkMode = uiSettingsService.get('theme:darkMode');
const isDarkMode = uiSettingsService?.get('theme:darkMode') ?? false;

return (
<EuiPanel paddingSize="m" hasShadow={true}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
EuiButton,
} from '@elastic/eui';
import { coreRefs } from '../../../framework/core_refs';
import { dataSourcesId } from '../../../../common/constants/shared';
import { dataSourceManagementPluginId } from '../../../../common/constants/shared';

export function AddDataSourceCallout() {
return (
Expand All @@ -40,7 +40,9 @@ export function AddDataSourceCallout() {
<EuiButton
fill
color="primary"
onClick={() => coreRefs.application?.navigateToApp(dataSourcesId, { path: '#/' })}
onClick={() =>
coreRefs.application?.navigateToApp(dataSourceManagementPluginId, { path: '#/' })
}
>
Manage data sources
</EuiButton>
Expand Down
4 changes: 3 additions & 1 deletion public/components/overview/components/dashboard_controls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,15 @@ import { OnTimeChangeProps } from '@opensearch-project/oui/src/eui_components/da
import { useObservable } from 'react-use';
import { FormattedMessage } from '@osd/i18n/react';
import { coreRefs } from '../../../framework/core_refs';
import { HOME_CONTENT_AREAS } from '../../../plugin_helpers/plugin_overview';
import { HOME_CONTENT_AREAS, SECTIONS } from '../../../plugin_helpers/plugin_overview';
import { redirectToDashboards } from '../../getting_started/components/utils';
import { AddDashboardCallout } from './add_dashboard_callout';
import { AddDataSourceCallout } from './add_datasource_callout';
import { ObsDashboardStateManager } from './obs_dashboard_state_manager';
import { SavedObjectsClientCommonFindArgs } from '../../../../../../src/plugins/data/common';
import { getWorkspaceIdFromUrl } from '../../../../../../src/core/public/utils';
import { setObservabilityDashboardsId } from './utils';
import { getOverviewPage } from '../../../../common/utils';

const getDatasourceAttributes = async () => {
const findOptions: SavedObjectsClientCommonFindArgs = {
Expand Down Expand Up @@ -55,6 +56,7 @@ export function DashboardControls() {
// Set to null if there are no data sources associated [Handle if dashboard was set, then datasource deleted]
if (savedObjectsArray.length === 0) {
await setObservabilityDashboardsId(null);
getOverviewPage().removeSection(SECTIONS.DASHBOARD); // Clear the present dashboard
}
} else {
setIsInWorkspace(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import { ObsDashboardStateManager } from './obs_dashboard_state_manager';
import { getObservabilityDashboardsId, setObservabilityDashboardsId } from './utils';
import { coreRefs } from '../../../framework/core_refs';
import { tutorialSampleDataPluginId } from '../../../../common/constants/shared';
import { getOverviewPage } from '../../../../common/utils';
import { DASHBOARD_SECTION } from '../../../../public/plugin_helpers/plugin_overview';

export interface Props {
closeFlyout: () => void;
Expand Down Expand Up @@ -61,6 +63,7 @@ export function SelectDashboardFlyout({ closeFlyout, dashboardsSavedObjects, rel
const onClickAdd = async () => {
const selectedOption = options.find((option) => option.checked === 'on');
if (selectedOption && selectedOption.key) {
getOverviewPage().createSection(DASHBOARD_SECTION);
setIsLoading(true);
ObsDashboardStateManager.isDashboardSelected$.next(true);
await setObservabilityDashboardsId(selectedOption.key);
Expand Down
25 changes: 23 additions & 2 deletions public/components/overview/home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import {
EuiIcon,
EuiButtonEmpty,
EuiToolTip,
EuiFlexGroup,
EuiFlexItem,
EuiLoadingSpinner,
} from '@elastic/eui';
import React, { ReactNode, useEffect, useMemo, useState } from 'react';
import { HashRouter, Route, Switch } from 'react-router-dom';
Expand Down Expand Up @@ -51,6 +54,7 @@ export const Home = () => {
const [isFlyoutVisible, setIsFlyoutVisible] = useState(false);
const [isPopoverOpen, setIsPopoverOpen] = useState(false);
const [showGetStarted, setShowGetStarted] = useState<boolean | null>(null); // Initial null state
const [isDashboardLoaded, setIsDashboardLoaded] = useState(false);

const canUpdateUiSetting = useMemo(() => {
const capabilities = coreRefs.application?.capabilities;
Expand All @@ -74,6 +78,7 @@ export const Home = () => {
const closePopover = () => setIsPopoverOpen(false);

const loadDashboardState = () => {
setIsDashboardLoaded(false);
coreRefs.savedObjectsClient
?.find({
type: 'dashboard',
Expand All @@ -92,6 +97,7 @@ export const Home = () => {
startDate: dashboardAttributes.timeFrom,
endDate: dashboardAttributes.timeTo,
};
setIsDashboardLoaded(true);
return acc;
}, {} as DashboardSavedObjectsType);

Expand Down Expand Up @@ -121,6 +127,7 @@ export const Home = () => {
})
.catch((error) => {
console.error('Error fetching dashboards:', error);
setIsDashboardLoaded(true);
});
};

Expand Down Expand Up @@ -382,8 +389,22 @@ export const Home = () => {
<Switch>
<Route exact path="/">
<div>
{homePage}
{flyout}
{isDashboardLoaded ? (
<>
{homePage}
{flyout}
</>
) : (
<EuiFlexGroup
justifyContent="center"
alignItems="center"
style={{ height: '100vh' }}
>
<EuiFlexItem grow={false}>
<EuiLoadingSpinner size="xl" />
</EuiFlexItem>
</EuiFlexGroup>
)}
</div>
</Route>
</Switch>
Expand Down
29 changes: 15 additions & 14 deletions public/plugin_helpers/plugin_overview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,23 +32,24 @@ export const GET_STARTED_SECTION: Section = {
columns: 5,
};

export const SELECTOR_SECTION: Section = {
id: SECTIONS.SELECTOR,
order: 2000,
title: 'Dashboards controls',
kind: 'custom',
render: (contents) => <div key={contents[0].id}>{contents[0].render()}</div>,
};

export const DASHBOARD_SECTION: Section = {
id: SECTIONS.DASHBOARD,
order: 3000,
kind: 'dashboard',
};

export const setupOverviewPage = (contentManagement: ContentManagementPluginSetup) => {
return contentManagement.registerPage({
id: HOME_PAGE_ID,
title: 'Home',
sections: [
{
id: SECTIONS.SELECTOR,
order: 2000,
title: 'Dashboards controls',
kind: 'custom',
render: (contents) => <div key={contents[0].id}>{contents[0].render()}</div>,
},
{
id: SECTIONS.DASHBOARD,
order: 3000,
kind: 'dashboard',
},
],
sections: [SELECTOR_SECTION, DASHBOARD_SECTION],
});
};

0 comments on commit 42b6c6b

Please sign in to comment.