Skip to content

Commit

Permalink
setup workspace plugin project skeleton
Browse files Browse the repository at this point in the history
Signed-off-by: Yulong Ruan <ruanyl@amazon.com>
  • Loading branch information
ruanyl committed Jun 7, 2023
1 parent cb27336 commit 11a5ad4
Show file tree
Hide file tree
Showing 8 changed files with 171 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/plugins/workspace/common/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const WORKSPACE_APP_ID = 'workspace';
export const WORKSPACE_APP_NAME = 'Workspace';
10 changes: 10 additions & 0 deletions src/plugins/workspace/opensearch_dashboards.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"id": "workspace",
"version": "opensearchDashboards",
"server": false,
"ui": true,
"requiredPlugins": ["savedObjects"],
"requiredBundles": [
"opensearchDashboardsReact"
]
}
32 changes: 32 additions & 0 deletions src/plugins/workspace/public/application.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import React from 'react';
import ReactDOM from 'react-dom';
import { Router } from 'react-router-dom';

import { AppMountParameters, CoreStart } from '../../../core/public';
import { OpenSearchDashboardsContextProvider } from '../../../plugins/opensearch_dashboards_react/public';
import { WorkspaceApp } from './components/workspace_app';

interface Service extends CoreStart {}

export const renderApp = (
{ element, history, appBasePath }: AppMountParameters,
services: Service
) => {
ReactDOM.render(
<Router history={history}>
<OpenSearchDashboardsContextProvider services={services}>
<WorkspaceApp appBasePath={appBasePath} />
</OpenSearchDashboardsContextProvider>
</Router>,
element
);

return () => {
ReactDOM.unmountComponentAtNode(element);
};
};
20 changes: 20 additions & 0 deletions src/plugins/workspace/public/components/routes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { WorkspaceCreator } from './workspace_creator';

export const paths = {
create: '/create',
};

interface RouteConfig {
path: string;
Component: React.ComponentType<any>;
label: string;
exact?: boolean;
}

export const ROUTES: RouteConfig[] = [
{
path: paths.create,
Component: WorkspaceCreator,
label: 'Create',
},
];
59 changes: 59 additions & 0 deletions src/plugins/workspace/public/components/workspace_app.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import React, { useEffect } from 'react';
import { EuiPage, EuiPageBody } from '@elastic/eui';
import { I18nProvider } from '@osd/i18n/react';
import { matchPath, Route, Switch, useLocation } from 'react-router-dom';

import { ROUTES } from './routes';
import { useOpenSearchDashboards } from '../../../opensearch_dashboards_react/public';
import { ChromeBreadcrumb } from '../../../../core/public';
import { WORKSPACE_APP_NAME } from '../../common/constants';

export const WorkspaceApp = ({ appBasePath }: { appBasePath: string }) => {
const {
services: { chrome },
} = useOpenSearchDashboards();
const location = useLocation();

/**
* map the current pathname to breadcrumbs
*/
useEffect(() => {
let pathname = location.pathname;
const breadcrumbs: ChromeBreadcrumb[] = [];

while (pathname !== '/') {
const matchedRoute = ROUTES.find((route) =>
matchPath(pathname, { path: route.path, exact: true })
);
if (matchedRoute) {
if (breadcrumbs.length === 0) {
breadcrumbs.unshift({ text: matchedRoute.label });
} else {
breadcrumbs.unshift({
text: matchedRoute.label,
href: `${appBasePath}${matchedRoute.path}`,
});
}
}
const pathArr = pathname.split('/');
pathArr.pop();
pathname = pathArr.join('/') ? pathArr.join('/') : '/';
}
breadcrumbs.unshift({ text: WORKSPACE_APP_NAME, href: appBasePath });
chrome?.setBreadcrumbs(breadcrumbs);
}, [appBasePath, location.pathname, chrome?.setBreadcrumbs]);

return (
<I18nProvider>
<EuiPage>
<EuiPageBody component="main">
<Switch>
{ROUTES.map(({ path, Component, exact }) => (
<Route key={path} path={path} render={() => <Component />} exact={exact ?? false} />
))}
</Switch>
</EuiPageBody>
</EuiPage>
</I18nProvider>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import React from 'react';

export const WorkspaceCreator = () => {
return <div>TODO</div>;
};
5 changes: 5 additions & 0 deletions src/plugins/workspace/public/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { WorkspacesPlugin } from './plugin';

export function plugin() {
return new WorkspacesPlugin();
}
38 changes: 38 additions & 0 deletions src/plugins/workspace/public/plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { i18n } from '@osd/i18n';
import {
CoreSetup,
CoreStart,
Plugin,
AppMountParameters,
AppNavLinkStatus,
} from '../../../core/public';
import { WORKSPACE_APP_ID } from '../common/constants';

export class WorkspacesPlugin implements Plugin<{}, {}> {
public setup(core: CoreSetup) {
core.application.register({
id: WORKSPACE_APP_ID,
title: i18n.translate('workspace.settings.title', {
defaultMessage: 'Workspace',
}),
// order: 6010,
navLinkStatus: AppNavLinkStatus.hidden,
// updater$: this.appUpdater,
async mount(params: AppMountParameters) {
const { renderApp } = await import('./application');
const [coreStart] = await core.getStartServices();
const services = {
...coreStart,
};

return renderApp(params, services);
},
});

return {};
}

public start(core: CoreStart) {
return {};
}
}

0 comments on commit 11a5ad4

Please sign in to comment.