Skip to content

Commit d1078c2

Browse files
opensearch-trigger-bot[bot]github-actions[bot]ashwin-pc
authored
[BUG][Dashboard listing] push to history if dashboard otherwise nav (#3922) (#3941)
History push will just to the current route. However, dashboardsProvider was implemented with the expectation that it was a different app. So when a plugin registered it was attempting to navigate to `app/dashboard#/app/{url}` Add tests and extra data test subject. (cherry picked from commit 0e34c3c) Signed-off-by: Kawika Avilla <kavilla414@gmail.com> Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Ashwin P Chandran <ashwinpc@amazon.com>
1 parent 7416cb7 commit d1078c2

File tree

11 files changed

+239
-6
lines changed

11 files changed

+239
-6
lines changed

src/plugins/dashboard/public/application/legacy_app.js

+12-4
Original file line numberDiff line numberDiff line change
@@ -163,11 +163,19 @@ export function initDashboardApp(app, deps) {
163163
};
164164
};
165165

166-
$scope.editItem = ({ editUrl }) => {
167-
history.push(editUrl);
166+
$scope.editItem = ({ appId, editUrl }) => {
167+
if (appId === 'dashboard') {
168+
history.push(editUrl);
169+
} else {
170+
deps.core.application.navigateToUrl(editUrl);
171+
}
168172
};
169-
$scope.viewItem = ({ viewUrl }) => {
170-
history.push(deps.addBasePath(viewUrl));
173+
$scope.viewItem = ({ appId, viewUrl }) => {
174+
if (appId === 'dashboard') {
175+
history.push(viewUrl);
176+
} else {
177+
deps.core.application.navigateToUrl(viewUrl);
178+
}
171179
};
172180
$scope.delete = (dashboards) => {
173181
const ids = dashboards.map((d) => ({ id: d.id, appId: d.appId }));

src/plugins/dashboard/public/application/listing/create_button.test.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ describe('create button with props', () => {
5757
expect(createButtons.length).toBe(0);
5858
const createDropdown = findTestSubject(component, 'createMenuDropdown');
5959
createDropdown.simulate('click');
60-
const contextMenus = findTestSubject(component, 'contextMenuItem');
60+
const contextMenus = findTestSubject(component, 'contextMenuItem-test');
6161
expect(contextMenus.length).toBe(2);
6262
expect(contextMenus.at(0).prop('href')).toBe('test1');
6363
});

src/plugins/dashboard/public/application/listing/create_button.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ const CreateButton = (props: CreateButtonProps) => {
3838
<EuiContextMenuItem
3939
key={provider.savedObjectsType}
4040
href={provider.createUrl}
41-
data-test-subj="contextMenuItem"
41+
data-test-subj={`contextMenuItem-${provider.appId}`}
4242
>
4343
{provider.createLinkText}
4444
</EuiContextMenuItem>

test/plugin_functional/config.ts

+1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) {
5252
require.resolve('./test_suites/doc_views_links'),
5353
require.resolve('./test_suites/application_links'),
5454
require.resolve('./test_suites/data_plugin'),
55+
require.resolve('./test_suites/dashboard_listing_plugin'),
5556
],
5657
services: {
5758
...functionalConfig.get('services'),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"id": "dashboard_listing_test_plugin",
3+
"version": "0.0.1",
4+
"opensearchDashboardsVersion": "opensearchDashboards",
5+
"configPath": ["dashboard_listing_test_plugin"],
6+
"server": false,
7+
"ui": true,
8+
"requiredPlugins": ["dashboard"]
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"name": "dashboard_listing_test_plugin",
3+
"version": "1.0.0",
4+
"main": "target/test/plugin_functional/plugins/dashboard_listing_test_plugin",
5+
"opensearchDashboards": {
6+
"version": "opensearchDashboards",
7+
"templateVersion": "1.0.0"
8+
},
9+
"license": "Apache-2.0",
10+
"scripts": {
11+
"osd": "../../../../scripts/use_node ../../../../scripts/osd.js",
12+
"build": "../../../../scripts/use_node ../../../../scripts/remove.js './target' && tsc"
13+
},
14+
"devDependencies": {
15+
"typescript": "4.0.2"
16+
}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
*
4+
* The OpenSearch Contributors require contributions made to
5+
* this file be licensed under the Apache-2.0 license or a
6+
* compatible open source license.
7+
*
8+
* Any modifications Copyright OpenSearch Contributors. See
9+
* GitHub history for details.
10+
*/
11+
12+
import { PluginInitializer } from 'opensearch-dashboards/public';
13+
import {
14+
DashboardListingTestPlugin,
15+
DashboardListingTestPluginSetup,
16+
DashboardListingTestPluginStart,
17+
} from './plugin';
18+
19+
export const plugin: PluginInitializer<
20+
DashboardListingTestPluginSetup,
21+
DashboardListingTestPluginStart
22+
> = () => new DashboardListingTestPlugin();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
*
4+
* The OpenSearch Contributors require contributions made to
5+
* this file be licensed under the Apache-2.0 license or a
6+
* compatible open source license.
7+
*
8+
* Any modifications Copyright OpenSearch Contributors. See
9+
* GitHub history for details.
10+
*/
11+
12+
import * as React from 'react';
13+
import { render, unmountComponentAtNode } from 'react-dom';
14+
import { Router, Switch, Route, Link } from 'react-router-dom';
15+
import { CoreSetup, Plugin } from 'opensearch-dashboards/public';
16+
17+
export class DashboardListingTestPlugin
18+
implements Plugin<DashboardListingTestPluginSetup, DashboardListingTestPluginStart> {
19+
public setup(core: CoreSetup, setupDeps: SetupDependencies) {
20+
const ID = 'dashboard_listing_test_plugin';
21+
const BASE_URL = core.http.basePath.prepend(`/app/${ID}#`);
22+
setupDeps.dashboard.registerDashboardProvider({
23+
appId: ID,
24+
savedObjectsType: 'dashboardTest',
25+
savedObjectsName: 'Dashboard Test',
26+
editUrlPathFn: (obj: SavedObject) => `${BASE_URL}/${obj.id}/edit`,
27+
viewUrlPathFn: (obj: SavedObject) => `${BASE_URL}/${obj.id}`,
28+
createLinkText: 'Test Dashboard',
29+
createSortText: 'Test Dashboard',
30+
createUrl: `${BASE_URL}/create`,
31+
});
32+
33+
core.application.register({
34+
id: ID,
35+
title: 'Dashboard Listing Test Plugin',
36+
appRoute: `app/${ID}`,
37+
async mount(context, { element }) {
38+
render(
39+
<h1 data-test-subj="dashboardListingTestHeader">Dashboard Listing Test Header</h1>,
40+
element
41+
);
42+
43+
return () => unmountComponentAtNode(element);
44+
},
45+
});
46+
}
47+
48+
public start() {}
49+
public stop() {}
50+
}
51+
52+
export type DashboardListingTestPluginSetup = ReturnType<DashboardListingTestPlugin['setup']>;
53+
export type DashboardListingTestPluginStart = ReturnType<DashboardListingTestPlugin['start']>;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"extends": "../../../../tsconfig.base.json",
3+
"compilerOptions": {
4+
"outDir": "./target",
5+
"skipLibCheck": true
6+
},
7+
"include": [
8+
"index.ts",
9+
"public/**/*.ts",
10+
"public/**/*.tsx",
11+
"../../../../typings/**/*",
12+
],
13+
"exclude": [],
14+
"references": [
15+
{ "path": "../../../../src/core/tsconfig.json" }
16+
]
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
*
4+
* The OpenSearch Contributors require contributions made to
5+
* this file be licensed under the Apache-2.0 license or a
6+
* compatible open source license.
7+
*
8+
* Any modifications Copyright OpenSearch Contributors. See
9+
* GitHub history for details.
10+
*/
11+
12+
import url from 'url';
13+
import expect from '@osd/expect';
14+
15+
const getPathWithHash = (absoluteUrl: string) => {
16+
const parsed = url.parse(absoluteUrl);
17+
return `${parsed.path}${parsed.hash ?? ''}`;
18+
};
19+
20+
export default function ({ getService, getPageObjects }) {
21+
const testSubjects = getService('testSubjects');
22+
const PageObjects = getPageObjects(['common', 'dashboard', 'header']);
23+
const browser = getService('browser');
24+
const listingTable = getService('listingTable');
25+
const find = getService('find');
26+
27+
describe('dashboard listing plugin', function describeIndexTests() {
28+
const dashboardName = 'Dashboard Test';
29+
30+
before(async () => {
31+
await PageObjects.dashboard.initTests({
32+
opensearchDashboardsIndex: '../functional/fixtures/opensearch_archiver/dashboard/legacy',
33+
});
34+
await PageObjects.dashboard.clickCreateDashboardPrompt();
35+
await PageObjects.dashboard.saveDashboard('default');
36+
await PageObjects.dashboard.gotoDashboardLandingPage();
37+
});
38+
39+
it('should be able to navigate to create a dashboard', async () => {
40+
await testSubjects.click('createMenuDropdown');
41+
await testSubjects.click('contextMenuItem-dashboard');
42+
await PageObjects.dashboard.saveDashboard(dashboardName);
43+
44+
await PageObjects.dashboard.gotoDashboardLandingPage();
45+
await listingTable.searchAndExpectItemsCount('dashboard', dashboardName, 1);
46+
});
47+
48+
it('should be able to navigate to view dashboard', async () => {
49+
await listingTable.clickItemLink('dashboard', dashboardName);
50+
await PageObjects.header.awaitGlobalLoadingIndicatorHidden();
51+
await PageObjects.dashboard.getIsInViewMode();
52+
await PageObjects.dashboard.gotoDashboardLandingPage();
53+
});
54+
55+
it('should be able to navigate to edit dashboard', async () => {
56+
await listingTable.searchForItemWithName(dashboardName);
57+
const editBttn = await find.allByCssSelector('.euiToolTipAnchor');
58+
await editBttn[0].click();
59+
await PageObjects.dashboard.clickCancelOutOfEditMode();
60+
await PageObjects.dashboard.gotoDashboardLandingPage();
61+
});
62+
63+
it('should be able to navigate to create a test dashboard', async () => {
64+
await testSubjects.click('createMenuDropdown');
65+
await testSubjects.click('contextMenuItem-dashboard_listing_test_plugin');
66+
expect(getPathWithHash(await browser.getCurrentUrl())).to.eql(
67+
'/app/dashboard_listing_test_plugin#/create'
68+
);
69+
});
70+
});
71+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
*
4+
* The OpenSearch Contributors require contributions made to
5+
* this file be licensed under the Apache-2.0 license or a
6+
* compatible open source license.
7+
*
8+
* Any modifications Copyright OpenSearch Contributors. See
9+
* GitHub history for details.
10+
*/
11+
12+
export default function ({ getService, loadTestFile }) {
13+
const browser = getService('browser');
14+
const opensearchArchiver = getService('opensearchArchiver');
15+
16+
async function loadLogstash() {
17+
await browser.setWindowSize(1200, 900);
18+
await opensearchArchiver.loadIfNeeded(
19+
'../functional/fixtures/opensearch_archiver/logstash_functional'
20+
);
21+
}
22+
23+
async function unloadLogstash() {
24+
await opensearchArchiver.unload(
25+
'../functional/fixtures/opensearch_archiver/logstash_functional'
26+
);
27+
}
28+
29+
describe('dashboard listing plugin', () => {
30+
before(loadLogstash);
31+
after(unloadLogstash);
32+
33+
loadTestFile(require.resolve('./dashboard_listing_plugin'));
34+
});
35+
}

0 commit comments

Comments
 (0)