diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a208b4f1f40..38c648238852 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) - [Vis Builder] Add field summary popovers ([#2682](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/2682)) - [I18n] Register ru, ru-RU locale ([#2817](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/2817)) - Add yarn opensearch arg to setup plugin dependencies ([#2544](https://github.com/opensearch-project/OpenSearch-Dashboards/issues/2544)) +- [Point in TIme] Add management plugin shell and empty state ([#2813](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/2813)) ### 🐛 Bug Fixes diff --git a/src/dev/build/tasks/os_packages/docker_generator/resources/bin/opensearch-dashboards-docker b/src/dev/build/tasks/os_packages/docker_generator/resources/bin/opensearch-dashboards-docker index a5cefbc2397c..76b79e8fca9c 100755 --- a/src/dev/build/tasks/os_packages/docker_generator/resources/bin/opensearch-dashboards-docker +++ b/src/dev/build/tasks/os_packages/docker_generator/resources/bin/opensearch-dashboards-docker @@ -160,6 +160,7 @@ opensearch_dashboards_vars=( data_source.audit.appender.layout.kind data_source.audit.appender.layout.highlight data_source.audit.appender.layout.pattern + pit.enabled ) longopts='' diff --git a/src/plugins/point_in_time_management/opensearch_dashboards.json b/src/plugins/point_in_time_management/opensearch_dashboards.json new file mode 100644 index 000000000000..1757278f19a6 --- /dev/null +++ b/src/plugins/point_in_time_management/opensearch_dashboards.json @@ -0,0 +1,10 @@ +{ + "id": "pit", + "version": "1.0.0", + "opensearchDashboardsVersion": "opensearchDashboards", + "server": true, + "ui": true, + "requiredPlugins": ["navigation", "management"], + "optionalPlugins": [], + "requiredBundles": ["opensearchDashboardsReact"] +} diff --git a/src/plugins/point_in_time_management/public/components/empty_state/__snapshots__/empty_state.test.tsx.snap b/src/plugins/point_in_time_management/public/components/empty_state/__snapshots__/empty_state.test.tsx.snap new file mode 100644 index 000000000000..cc1ee347208f --- /dev/null +++ b/src/plugins/point_in_time_management/public/components/empty_state/__snapshots__/empty_state.test.tsx.snap @@ -0,0 +1,84 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`EmptyState should render normally 1`] = ` + + + + + +

+ +

+
+
+ + + +
+ +

+ +

+
+ + + + + No point in time objects have been created yet. + + + + + + + +
+
+`; diff --git a/src/plugins/point_in_time_management/public/components/empty_state/empty_state.test.tsx b/src/plugins/point_in_time_management/public/components/empty_state/empty_state.test.tsx new file mode 100644 index 000000000000..82393e830152 --- /dev/null +++ b/src/plugins/point_in_time_management/public/components/empty_state/empty_state.test.tsx @@ -0,0 +1,16 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import React from 'react'; +import { EmptyState } from './empty_state'; +import { shallow } from 'enzyme'; + +describe('EmptyState', () => { + it('should render normally', () => { + const component = shallow(); + + expect(component).toMatchSnapshot(); + }); +}); diff --git a/src/plugins/point_in_time_management/public/components/empty_state/empty_state.tsx b/src/plugins/point_in_time_management/public/components/empty_state/empty_state.tsx new file mode 100644 index 000000000000..650c742c6744 --- /dev/null +++ b/src/plugins/point_in_time_management/public/components/empty_state/empty_state.tsx @@ -0,0 +1,78 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import React from 'react'; +import { FormattedMessage } from '@osd/i18n/react'; +import { + EuiPageContentHeader, + EuiPageContentHeaderSection, + EuiTitle, + EuiPageContent, + EuiSpacer, + EuiText, + EuiPageContentBody, + EuiFlexItem, + EuiFlexGroup, + EuiButton, +} from '@elastic/eui'; + +export const EmptyState = () => { + return ( + <> + + + + +

+ +

+
+
+ + + +
+ +

+ +

+
+ + + + No point in time objects have been created yet. + + + + + + +
+ + ); +}; diff --git a/src/plugins/point_in_time_management/public/components/empty_state/index.ts b/src/plugins/point_in_time_management/public/components/empty_state/index.ts new file mode 100644 index 000000000000..c903066cdbb0 --- /dev/null +++ b/src/plugins/point_in_time_management/public/components/empty_state/index.ts @@ -0,0 +1,6 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +export { EmptyState } from './empty_state'; diff --git a/src/plugins/point_in_time_management/public/components/index.ts b/src/plugins/point_in_time_management/public/components/index.ts new file mode 100644 index 000000000000..c903066cdbb0 --- /dev/null +++ b/src/plugins/point_in_time_management/public/components/index.ts @@ -0,0 +1,6 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +export { EmptyState } from './empty_state'; diff --git a/src/plugins/point_in_time_management/public/index.ts b/src/plugins/point_in_time_management/public/index.ts new file mode 100644 index 000000000000..2c2ecadca2e3 --- /dev/null +++ b/src/plugins/point_in_time_management/public/index.ts @@ -0,0 +1,12 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { PointInTimeManagementPlugin } from './plugin'; + +export function plugin() { + return new PointInTimeManagementPlugin(); +} + +export { PointInTimeManagementPluginSetup, PointInTimeManagementPluginStart } from './types'; diff --git a/src/plugins/point_in_time_management/public/management_app/index.ts b/src/plugins/point_in_time_management/public/management_app/index.ts new file mode 100644 index 000000000000..414bc60e89cc --- /dev/null +++ b/src/plugins/point_in_time_management/public/management_app/index.ts @@ -0,0 +1,6 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +export { mountManagementSection } from './mount_management_section'; diff --git a/src/plugins/point_in_time_management/public/management_app/mount_management_section.tsx b/src/plugins/point_in_time_management/public/management_app/mount_management_section.tsx new file mode 100644 index 000000000000..96c87fc73538 --- /dev/null +++ b/src/plugins/point_in_time_management/public/management_app/mount_management_section.tsx @@ -0,0 +1,38 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import React from 'react'; +import ReactDOM from 'react-dom'; +import { I18nProvider } from '@osd/i18n/react'; +import { ManagementAppMountParams } from '../../../management/public'; +import { PointInTimeManagementStartDependencies } from '../plugin'; +import { StartServicesAccessor } from '../../../../core/public'; +import { PointInTimeManagementContext } from '../types'; +import { OpenSearchDashboardsContextProvider } from '../../../opensearch_dashboards_react/public'; +import { EmptyState } from '../components'; + +export async function mountManagementSection( + getStartServices: StartServicesAccessor, + params: ManagementAppMountParams +) { + const [{ chrome, application }] = await getStartServices(); + const deps: PointInTimeManagementContext = { + chrome, + application, + }; + ReactDOM.render( + + + + + , + params.element + ); + + return () => { + chrome.docTitle.reset(); + ReactDOM.unmountComponentAtNode(params.element); + }; +} diff --git a/src/plugins/point_in_time_management/public/plugin.ts b/src/plugins/point_in_time_management/public/plugin.ts new file mode 100644 index 000000000000..53a1421926e4 --- /dev/null +++ b/src/plugins/point_in_time_management/public/plugin.ts @@ -0,0 +1,60 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { i18n } from '@osd/i18n'; +import { CoreSetup, CoreStart, Plugin } from '../../../core/public'; +import { PointInTimeManagementPluginSetup, PointInTimeManagementPluginStart } from './types'; +import { ManagementSetup } from '../../management/public'; + +export interface PointInTimeManagementSetupDependencies { + management: ManagementSetup; +} + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface PointInTimeManagementStartDependencies {} + +const sectionsHeader = i18n.translate('pointInTimeManagement.pointInTime.sectionsHeader', { + defaultMessage: 'Point In Time', +}); + +const PITM_APP_ID = 'pointInTime'; + +export class PointInTimeManagementPlugin + implements + Plugin< + PointInTimeManagementPluginSetup, + PointInTimeManagementPluginStart, + PointInTimeManagementSetupDependencies, + PointInTimeManagementStartDependencies + > { + public setup( + core: CoreSetup, + { management }: PointInTimeManagementSetupDependencies + ): PointInTimeManagementPluginSetup { + const opensearchDashboardsSection = management.sections.section.opensearchDashboards; + + if (!opensearchDashboardsSection) { + throw new Error('`opensearchDashboards` management section not found.'); + } + + opensearchDashboardsSection.registerApp({ + id: PITM_APP_ID, + title: sectionsHeader, + order: 1, + mount: async (mountParams) => { + const { mountManagementSection } = await import('./management_app'); + return mountManagementSection(core.getStartServices, mountParams); + }, + }); + + return {}; + } + + public start(core: CoreStart): PointInTimeManagementPluginStart { + return {}; + } + + public stop() {} +} diff --git a/src/plugins/point_in_time_management/public/types.ts b/src/plugins/point_in_time_management/public/types.ts new file mode 100644 index 000000000000..fc0c5b7038c8 --- /dev/null +++ b/src/plugins/point_in_time_management/public/types.ts @@ -0,0 +1,27 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { ApplicationStart, ChromeStart } from 'opensearch-dashboards/public'; +import { NavigationPublicPluginStart } from '../../navigation/public'; +import { ManagementSetup } from '../../management/public'; + +export interface PointInTimeManagementContext { + chrome: ChromeStart; + application: ApplicationStart; +} + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface PointInTimeManagementPluginSetup {} + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface PointInTimeManagementPluginStart {} + +export interface AppPluginStartDependencies { + navigation: NavigationPublicPluginStart; +} + +export interface SetupDependencies { + management: ManagementSetup; +} diff --git a/src/plugins/point_in_time_management/server/index.ts b/src/plugins/point_in_time_management/server/index.ts new file mode 100644 index 000000000000..bcc35da781c8 --- /dev/null +++ b/src/plugins/point_in_time_management/server/index.ts @@ -0,0 +1,21 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { schema } from '@osd/config-schema'; +import { PluginInitializerContext } from '../../../core/server'; +import { PointInTimeManagementPlugin } from './plugin'; + +export const config = { + schema: schema.object({ enabled: schema.boolean({ defaultValue: false }) }), +}; + +// This exports static code and TypeScript types, +// as well as the OpenSearch Dashboards Platform `plugin()` initializer. + +export function plugin(initializerContext: PluginInitializerContext) { + return new PointInTimeManagementPlugin(initializerContext); +} + +export { PointInTimeManagementPluginSetup, PointInTimeManagementPluginStart } from './types'; diff --git a/src/plugins/point_in_time_management/server/plugin.ts b/src/plugins/point_in_time_management/server/plugin.ts new file mode 100644 index 000000000000..876e4271d432 --- /dev/null +++ b/src/plugins/point_in_time_management/server/plugin.ts @@ -0,0 +1,40 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { + PluginInitializerContext, + CoreSetup, + CoreStart, + Plugin, + Logger, +} from '../../../core/server'; + +import { PointInTimeManagementPluginSetup, PointInTimeManagementPluginStart } from './types'; +import { defineRoutes } from './routes'; + +export class PointInTimeManagementPlugin + implements Plugin { + private readonly logger: Logger; + + constructor(initializerContext: PluginInitializerContext) { + this.logger = initializerContext.logger.get(); + } + + public setup(core: CoreSetup) { + this.logger.debug('pointInTimeManagement: Setup'); + const router = core.http.createRouter(); + + defineRoutes(router); + + return {}; + } + + public start(core: CoreStart) { + this.logger.debug('pointInTimeManagement: Started'); + return {}; + } + + public stop() {} +} diff --git a/src/plugins/point_in_time_management/server/routes/index.ts b/src/plugins/point_in_time_management/server/routes/index.ts new file mode 100644 index 000000000000..b56d1871d7dd --- /dev/null +++ b/src/plugins/point_in_time_management/server/routes/index.ts @@ -0,0 +1,22 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { IRouter } from '../../../../core/server'; + +export function defineRoutes(router: IRouter) { + router.get( + { + path: '/api/point_in_time_management/test', + validate: false, + }, + async (context, request, response) => { + return response.ok({ + body: { + time: new Date().toISOString(), + }, + }); + } + ); +} diff --git a/src/plugins/point_in_time_management/server/types.ts b/src/plugins/point_in_time_management/server/types.ts new file mode 100644 index 000000000000..d9c957b4edc3 --- /dev/null +++ b/src/plugins/point_in_time_management/server/types.ts @@ -0,0 +1,9 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface PointInTimeManagementPluginSetup {} +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface PointInTimeManagementPluginStart {}