Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce saved object plugin into maps plugin #67

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions maps_dashboards/common/map_saved_object_attributes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import { SavedObjectAttributes } from 'opensearch-dashboards/server';

export interface MapSavedObjectAttributes extends SavedObjectAttributes {
/** Title of the map */
title: string;
/** Description of the map */
description?: string;
/** State of the map, which could include current zoom level, lat, lng etc. */
mapState?: string;
/** Maps-dashboards layers of the map */
layerList?: string;
/** UI state of the map */
uiState?: string;
/** Version is used to track version differences in saved object mapping */
version: number;
/** SearchSourceFields is used to reference other saved objects */
searchSourceFields?: {
index?: string;
};
}
2 changes: 1 addition & 1 deletion maps_dashboards/opensearch_dashboards.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
"opensearchDashboardsVersion": "3.0.0",
"server": true,
"ui": true,
"requiredPlugins": ["navigation", "opensearchDashboardsReact"],
"requiredPlugins": ["navigation", "opensearchDashboardsReact", "savedObjects"],
"optionalPlugins": []
}
20 changes: 7 additions & 13 deletions maps_dashboards/public/application.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,16 @@

import React from 'react';
import ReactDOM from 'react-dom';
import { AppMountParameters, CoreStart } from '../../../src/core/public';
import { AppPluginStartDependencies } from './types';
import { AppMountParameters } from '../../../src/core/public';
import { MapServices } from './types';
import { MapsDashboardsApp } from './components/app';
import { OpenSearchDashboardsContextProvider } from '../../../src/plugins/opensearch_dashboards_react/public';

export const renderApp = (
{ notifications, http }: CoreStart,
{ navigation }: AppPluginStartDependencies,
{ appBasePath, element }: AppMountParameters
) => {
export const renderApp = ({ element }: AppMountParameters, services: MapServices) => {
ReactDOM.render(
<MapsDashboardsApp
basename={appBasePath}
notifications={notifications}
http={http}
navigation={navigation}
/>,
<OpenSearchDashboardsContextProvider services={services}>
<MapsDashboardsApp />
</OpenSearchDashboardsContextProvider>,
element
);

Expand Down
32 changes: 12 additions & 20 deletions maps_dashboards/public/components/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,26 @@
*/

import React from 'react';
import { HashRouter as Router, Route, Switch } from 'react-router-dom';
import { Router, Route, Switch } from 'react-router-dom';
import { I18nProvider } from '@osd/i18n/react';
import { MapsList } from './maps_list';
import { MapContainer } from './map_container';
import { CoreStart } from '../../../../src/core/public';
import { NavigationPublicPluginStart } from '../../../../src/plugins/navigation/public';
import { APP_PATH } from '../../common/index';
import { MapPage } from './map_page';
import { APP_PATH } from '../../common';
import { useOpenSearchDashboards } from '../../../../src/plugins/opensearch_dashboards_react/public';
import { MapServices } from '../types';

interface MapsDashboardsAppDeps {
basename: string;
notifications: CoreStart['notifications'];
http: CoreStart['http'];
navigation: NavigationPublicPluginStart;
}

export const MapsDashboardsApp = ({ basename, notifications, http }: MapsDashboardsAppDeps) => {
export const MapsDashboardsApp = () => {
const {
services: { appBasePath },
} = useOpenSearchDashboards<MapServices>();
// Render the application DOM.
return (
<Router basename={basename}>
<Router history={appBasePath}>
<I18nProvider>
<div>
<Switch>
<Route path={APP_PATH.CREATE_MAP} render={(props) => <MapContainer />} />
<Route
exact
path="/"
render={() => <MapsList http={http} notifications={notifications} />}
/>
<Route path={APP_PATH.CREATE_MAP} render={() => <MapPage />} />
<Route exact path="/" render={() => <MapsList />} />
</Switch>
</div>
</I18nProvider>
Expand Down
6 changes: 6 additions & 0 deletions maps_dashboards/public/components/map_page/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

export { MapPage } from './map_page';
17 changes: 17 additions & 0 deletions maps_dashboards/public/components/map_page/map_page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import React from 'react';
import { MapContainer } from '../map_container';
import { MapTopNavMenu } from '../map_top_nav';

export const MapPage = () => {
return (
<div>
<MapTopNavMenu />
<MapContainer />
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import React from 'react';
import { i18n } from '@osd/i18n';
import { TopNavMenuData } from '../../../../../src/plugins/navigation/public';
import {
OnSaveProps,
SavedObjectSaveModalOrigin,
showSaveModal,
} from '../../../../../src/plugins/saved_objects/public';
import { MapServices } from '../../types';

export const getTopNavConfig = (services: MapServices) => {
const {
notifications: { toasts },
i18n: { Context: I18nContext },
savedObjects: { client: savedObjectsClient },
} = services;
junqiu-lei marked this conversation as resolved.
Show resolved Hide resolved

const topNavConfig: TopNavMenuData[] = [
{
iconType: 'save',
emphasize: true,
id: 'save',
label: i18n.translate('maps.topNav.saveMapButtonLabel', {
defaultMessage: `Save`,
junqiu-lei marked this conversation as resolved.
Show resolved Hide resolved
}),
run: (_anchorElement) => {
const onModalSave = async (onSaveProps: OnSaveProps) => {
const savedMap = await savedObjectsClient.create('map', {
junqiu-lei marked this conversation as resolved.
Show resolved Hide resolved
title: onSaveProps.newTitle,
description: onSaveProps.newDescription,
// TODO: Integrate other attributes to saved object
});
const id = savedMap.id;
if (id) {
toasts.addSuccess({
title: i18n.translate('map.topNavMenu.saveMap.successNotificationText', {
defaultMessage: `Saved ${onSaveProps.newTitle}`,
values: {
visTitle: savedMap.attributes.title,
},
}),
});
}
return { id };
};

const documentInfo = {
title: '',
description: '',
};
const saveModal = (
<SavedObjectSaveModalOrigin
documentInfo={documentInfo}
onSave={onModalSave}
objectType={'map'}
onClose={() => {}}
/>
);
showSaveModal(saveModal, I18nContext);
},
},
];
return topNavConfig;
};
6 changes: 6 additions & 0 deletions maps_dashboards/public/components/map_top_nav/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

export { MapTopNavMenu } from './top_nav_menu';
27 changes: 27 additions & 0 deletions maps_dashboards/public/components/map_top_nav/top_nav_menu.tsx
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 { PLUGIN_ID } from '../../../common';
import { getTopNavConfig } from './get_top_nav_config';
import { useOpenSearchDashboards } from '../../../../../src/plugins/opensearch_dashboards_react/public';
import { MapServices } from '../../types';

export const MapTopNavMenu = () => {
const { services } = useOpenSearchDashboards<MapServices>();
const {
setHeaderActionMenu,
navigation: {
ui: { TopNavMenu },
},
} = services;
return (
<TopNavMenu
appName={PLUGIN_ID}
config={getTopNavConfig(services)}
setMenuMountPoint={setHeaderActionMenu}
/>
);
};
79 changes: 51 additions & 28 deletions maps_dashboards/public/components/maps_list/maps_list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,48 +7,71 @@ import { i18n } from '@osd/i18n';
import React, { useCallback } from 'react';
import { I18nProvider } from '@osd/i18n/react';
import { EuiPage, EuiPageBody, EuiPageContentBody } from '@elastic/eui';
import { CoreStart } from 'opensearch-dashboards/public';
import { TableListView } from '../../../../../src/plugins/opensearch_dashboards_react/public';

export const MapsList = (props: {
notifications: CoreStart['notifications'];
http: CoreStart['http'];
}) => {
const { http } = props;
const find = async (num: number) => {
const res = await http.post('/api/maps-dashboards/example');
return {
total: num,
hits: res.hits,
};
};
import {
TableListView,
useOpenSearchDashboards,
} from '../../../../../src/plugins/opensearch_dashboards_react/public';
import { MapSavedObjectAttributes } from '../../../common/map_saved_object_attributes';
import { MapServices } from '../../types';

export const MapsList = () => {
const {
services: {
notifications: { toasts },
http: { basePath },
savedObjects: { client: savedObjectsClient },
application: { navigateToUrl },
},
} = useOpenSearchDashboards<MapServices>();
const tableColumns = [
{
field: 'title',
field: 'attributes.title',
name: i18n.translate('maps.listing.table.titleColumnName', {
defaultMessage: 'Title',
}),
sortable: true,
},
{
field: 'description',
field: 'attributes.description',
name: i18n.translate('maps.listing.table.descriptionColumnName', {
defaultMessage: 'Description',
}),
sortable: true,
},
];

const createItem = useCallback(() => {
window.location.href = http.basePath.prepend('/app/maps-dashboards/#/create-map');
}, [http.basePath]);
const createMap = () => {
navigateToUrl(basePath.prepend('/app/maps-dashboards/create-map'));
junqiu-lei marked this conversation as resolved.
Show resolved Hide resolved
};

const findItem = find.bind(null, 3);
const fetchMaps = useCallback(async (): Promise<{
total: number;
hits: object[];
}> => {
const res = await savedObjectsClient.find<MapSavedObjectAttributes>({
type: 'map',
fields: ['description', 'title'],
});
return {
total: res.total,
hits: res.savedObjects,
};
}, [savedObjectsClient]);

const deleteItems = async () => {
await Promise.all([]);
};
const deleteMaps = useCallback(
async (selectedItems: object[]) => {
await Promise.all(
selectedItems.map((item: any) => savedObjectsClient.delete(item.type, item.id))
).catch((error) => {
toasts.addError(error, {
title: i18n.translate('map.mapListingDeleteErrorTitle', {
defaultMessage: 'Error deleting map',
}),
});
});
},
[savedObjectsClient, toasts]
);

const editItem = useCallback(() => {}, []);

Expand All @@ -61,9 +84,9 @@ export const MapsList = (props: {
<EuiPageContentBody>
<TableListView
headingId="mapsListingHeading"
createItem={createItem}
findItems={findItem}
deleteItems={deleteItems}
createItem={createMap}
findItems={fetchMaps}
deleteItems={deleteMaps}
editItem={editItem}
tableColumns={tableColumns}
listingLimit={10}
Expand All @@ -79,7 +102,7 @@ export const MapsList = (props: {
tableListTitle={i18n.translate('maps.listing.table.listTitle', {
defaultMessage: 'Maps',
})}
toastNotifications={props.notifications.toasts}
toastNotifications={toasts}
/>
</EuiPageContentBody>
</EuiPageBody>
Expand Down
12 changes: 11 additions & 1 deletion maps_dashboards/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
MapsDashboardsPluginSetup,
MapsDashboardsPluginStart,
AppPluginStartDependencies,
MapServices,
} from './types';
import { PLUGIN_NAME, PLUGIN_ID } from '../common';

Expand All @@ -31,8 +32,17 @@ export class MapsDashboardsPlugin
const { renderApp } = await import('./application');
// Get start services as specified in opensearch_dashboards.json
const [coreStart, depsStart] = await core.getStartServices();
const { navigation } = depsStart as AppPluginStartDependencies;
const services: MapServices = {
...coreStart,
setHeaderActionMenu: params.setHeaderActionMenu,
appBasePath: params.history,
element: params.element,
navigation,
toastNotifications: coreStart.notifications.toasts,
};
// Render the application
return renderApp(coreStart, depsStart as AppPluginStartDependencies, params);
return renderApp(params, services);
},
});

Expand Down
Loading