-
Notifications
You must be signed in to change notification settings - Fork 917
Commit
Signed-off-by: SuZhou-Joe <suzhou@amazon.com>
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"id": "contentManagement", | ||
"version": "opensearchDashboards", | ||
"server": false, | ||
"ui": true, | ||
"requiredPlugins": ["embeddable"], | ||
"optionalPlugins": [], | ||
"requiredBundles": ["embeddable"] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
import React from 'react'; | ||
import ReactDOM from 'react-dom'; | ||
import { Route, Router, Switch } from 'react-router-dom'; | ||
import { I18nProvider } from '@osd/i18n/react'; | ||
|
||
import { | ||
AppMountParameters, | ||
CoreStart, | ||
SavedObjectsClientContract, | ||
} from 'opensearch-dashboards/public'; | ||
import { PageRender } from './components/page_render'; | ||
import { Page } from './services'; | ||
import { ContentManagementPluginStartDependencies } from './types'; | ||
import { EmbeddableStart } from '../../embeddable/public'; | ||
|
||
interface Props { | ||
params: AppMountParameters; | ||
pages: Page[]; | ||
coreStart: CoreStart; | ||
depsStart: ContentManagementPluginStartDependencies; | ||
} | ||
|
||
export const renderPage = ({ | ||
page, | ||
embeddable, | ||
savedObjectsClient, | ||
}: { | ||
page: Page; | ||
embeddable: EmbeddableStart; | ||
savedObjectsClient: SavedObjectsClientContract; | ||
}) => { | ||
return <PageRender page={page} embeddable={embeddable} savedObjectsClient={savedObjectsClient} />; | ||
}; | ||
|
||
export const renderApp = ( | ||
{ params, pages, coreStart, depsStart }: Props, | ||
element: AppMountParameters['element'] | ||
) => { | ||
ReactDOM.render( | ||
<I18nProvider> | ||
<Router history={params.history}> | ||
<Switch> | ||
{pages.map((page) => ( | ||
<Route path={[`/${page.config.id}`]}> | ||
{renderPage({ | ||
page, | ||
embeddable: depsStart.embeddable, | ||
savedObjectsClient: coreStart.savedObjects.client, | ||
})} | ||
</Route> | ||
))} | ||
</Switch> | ||
</Router> | ||
</I18nProvider>, | ||
element | ||
); | ||
|
||
return () => ReactDOM.unmountComponentAtNode(element); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
import React from 'react'; | ||
import ReactDOM from 'react-dom'; | ||
import { Container, ContainerInput, EmbeddableStart } from '../../../../embeddable/public'; | ||
import { CardList } from './card_list'; | ||
|
||
export const CARD_CONTAINER = 'CARD_CONTAINER'; | ||
|
||
export type CardContainerInput = ContainerInput<{ description: string; onClick?: () => void }>; | ||
|
||
export class CardContainer extends Container<{}, ContainerInput> { | ||
public readonly type = CARD_CONTAINER; | ||
private node?: HTMLElement; | ||
|
||
constructor(input: ContainerInput, private embeddableServices: EmbeddableStart) { | ||
super(input, { embeddableLoaded: {} }, embeddableServices.getEmbeddableFactory); | ||
} | ||
|
||
getInheritedInput() { | ||
return { | ||
viewMode: this.input.viewMode, | ||
}; | ||
} | ||
|
||
public render(node: HTMLElement) { | ||
if (this.node) { | ||
ReactDOM.unmountComponentAtNode(this.node); | ||
} | ||
this.node = node; | ||
ReactDOM.render( | ||
Check warning on line 34 in src/plugins/content_management/public/components/card_container/card_container.tsx Codecov / codecov/patchsrc/plugins/content_management/public/components/card_container/card_container.tsx#L33-L34
|
||
<CardList embeddable={this} embeddableServices={this.embeddableServices} />, | ||
node | ||
); | ||
} | ||
|
||
public destroy() { | ||
super.destroy(); | ||
if (this.node) { | ||
ReactDOM.unmountComponentAtNode(this.node); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
import { i18n } from '@osd/i18n'; | ||
|
||
import { | ||
EmbeddableFactoryDefinition, | ||
ContainerInput, | ||
EmbeddableStart, | ||
EmbeddableFactory, | ||
ContainerOutput, | ||
} from '../../../../embeddable/public'; | ||
import { CARD_CONTAINER, CardContainer } from './card_container'; | ||
|
||
interface StartServices { | ||
embeddableServices: EmbeddableStart; | ||
} | ||
|
||
export type CardContainerFactory = EmbeddableFactory<ContainerInput, ContainerOutput>; | ||
export class CardContainerFactoryDefinition | ||
implements EmbeddableFactoryDefinition<ContainerInput, ContainerOutput> { | ||
public readonly type = CARD_CONTAINER; | ||
public readonly isContainerType = true; | ||
Check warning on line 25 in src/plugins/content_management/public/components/card_container/card_container_factory.ts Codecov / codecov/patchsrc/plugins/content_management/public/components/card_container/card_container_factory.ts#L24-L25
|
||
|
||
constructor(private getStartServices: () => Promise<StartServices>) {} | ||
|
||
public async isEditable() { | ||
return true; | ||
Check warning on line 30 in src/plugins/content_management/public/components/card_container/card_container_factory.ts Codecov / codecov/patchsrc/plugins/content_management/public/components/card_container/card_container_factory.ts#L30
|
||
} | ||
|
||
public create = async (initialInput: ContainerInput) => { | ||
const { embeddableServices } = await this.getStartServices(); | ||
return new CardContainer(initialInput, embeddableServices); | ||
Check warning on line 35 in src/plugins/content_management/public/components/card_container/card_container_factory.ts Codecov / codecov/patchsrc/plugins/content_management/public/components/card_container/card_container_factory.ts#L33-L35
|
||
}; | ||
|
||
public getDisplayName() { | ||
return i18n.translate('contentManagement.cardContainer.displayName', { | ||
Check warning on line 39 in src/plugins/content_management/public/components/card_container/card_container_factory.ts Codecov / codecov/patchsrc/plugins/content_management/public/components/card_container/card_container_factory.ts#L39
|
||
defaultMessage: 'Card container', | ||
}); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
import React from 'react'; | ||
import ReactDOM from 'react-dom'; | ||
import { Embeddable, EmbeddableInput, IContainer } from '../../../../embeddable/public'; | ||
import { EuiCard } from '@elastic/eui'; | ||
|
||
export const CARD_EMBEDDABLE = 'card_embeddable'; | ||
export type CardEmbeddableInput = EmbeddableInput & { description: string; onClick?: () => void }; | ||
|
||
export class CardEmbeddable extends Embeddable<CardEmbeddableInput> { | ||
public readonly type = CARD_EMBEDDABLE; | ||
private node: HTMLElement | null = null; | ||
Check warning on line 16 in src/plugins/content_management/public/components/card_container/card_embeddable.tsx Codecov / codecov/patchsrc/plugins/content_management/public/components/card_container/card_embeddable.tsx#L15-L16
|
||
|
||
constructor(initialInput: CardEmbeddableInput, parent?: IContainer) { | ||
super(initialInput, {}, parent); | ||
} | ||
|
||
public render(node: HTMLElement) { | ||
if (this.node) { | ||
ReactDOM.unmountComponentAtNode(this.node); | ||
} | ||
this.node = node; | ||
ReactDOM.render( | ||
Check warning on line 27 in src/plugins/content_management/public/components/card_container/card_embeddable.tsx Codecov / codecov/patchsrc/plugins/content_management/public/components/card_container/card_embeddable.tsx#L26-L27
|
||
<EuiCard | ||
title={this.input.title ?? ''} | ||
description={this.input.description} | ||
display="plain" | ||
onClick={this.input.onClick} | ||
/>, | ||
node | ||
); | ||
} | ||
|
||
public destroy() { | ||
super.destroy(); | ||
if (this.node) { | ||
ReactDOM.unmountComponentAtNode(this.node); | ||
} | ||
} | ||
|
||
public reload() {} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
import { i18n } from '@osd/i18n'; | ||
import { EmbeddableFactoryDefinition, IContainer } from '../../../../embeddable/public'; | ||
import { CARD_EMBEDDABLE, CardEmbeddable, CardEmbeddableInput } from './card_embeddable'; | ||
|
||
export class CardEmbeddableFactoryDefinition implements EmbeddableFactoryDefinition { | ||
public readonly type = CARD_EMBEDDABLE; | ||
Check warning on line 11 in src/plugins/content_management/public/components/card_container/card_embeddable_factory.ts Codecov / codecov/patchsrc/plugins/content_management/public/components/card_container/card_embeddable_factory.ts#L11
|
||
|
||
public async isEditable() { | ||
return false; | ||
Check warning on line 14 in src/plugins/content_management/public/components/card_container/card_embeddable_factory.ts Codecov / codecov/patchsrc/plugins/content_management/public/components/card_container/card_embeddable_factory.ts#L14
|
||
} | ||
|
||
public async create(initialInput: CardEmbeddableInput, parent?: IContainer) { | ||
return new CardEmbeddable(initialInput, parent); | ||
Check warning on line 18 in src/plugins/content_management/public/components/card_container/card_embeddable_factory.ts Codecov / codecov/patchsrc/plugins/content_management/public/components/card_container/card_embeddable_factory.ts#L18
|
||
} | ||
|
||
public getDisplayName() { | ||
return i18n.translate('contentManagement.embeddable.card', { | ||
Check warning on line 22 in src/plugins/content_management/public/components/card_container/card_embeddable_factory.ts Codecov / codecov/patchsrc/plugins/content_management/public/components/card_container/card_embeddable_factory.ts#L22
|
||
defaultMessage: 'Card', | ||
}); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
import React from 'react'; | ||
import { EuiFlexGrid, EuiFlexItem } from '@elastic/eui'; | ||
|
||
import { | ||
IContainer, | ||
withEmbeddableSubscription, | ||
ContainerInput, | ||
ContainerOutput, | ||
EmbeddableStart, | ||
} from '../../../../embeddable/public'; | ||
|
||
interface Props { | ||
embeddable: IContainer; | ||
input: ContainerInput; | ||
embeddableServices: EmbeddableStart; | ||
} | ||
|
||
const CardListInner = ({ embeddable, input, embeddableServices }: Props) => { | ||
const cards = Object.values(input.panels).map((panel) => { | ||
const child = embeddable.getChild(panel.explicitInput.id); | ||
return ( | ||
<EuiFlexItem key={panel.explicitInput.id}> | ||
<embeddableServices.EmbeddablePanel embeddable={child} /> | ||
</EuiFlexItem> | ||
); | ||
}); | ||
return ( | ||
<EuiFlexGrid gutterSize="s" columns={4}> | ||
{cards} | ||
</EuiFlexGrid> | ||
); | ||
}; | ||
|
||
export const CardList = withEmbeddableSubscription< | ||
ContainerInput, | ||
ContainerOutput, | ||
IContainer, | ||
{ embeddableServices: EmbeddableStart } | ||
>(CardListInner); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
import React from 'react'; | ||
import ReactDOM from 'react-dom'; | ||
|
||
import { Embeddable, EmbeddableInput, IContainer } from '../../../embeddable/public'; | ||
|
||
export const CUSTOM_CONTENT_EMBEDDABLE = 'custom_content_embeddable'; | ||
export type CustomContentEmbeddableInput = EmbeddableInput & { render: () => React.ReactElement }; | ||
|
||
export class CustomContentEmbeddable extends Embeddable<CustomContentEmbeddableInput> { | ||
public readonly type = CUSTOM_CONTENT_EMBEDDABLE; | ||
private node: HTMLElement | null = null; | ||
Check warning on line 16 in src/plugins/content_management/public/components/custom_content_embeddable.tsx Codecov / codecov/patchsrc/plugins/content_management/public/components/custom_content_embeddable.tsx#L15-L16
|
||
|
||
constructor(initialInput: CustomContentEmbeddableInput, parent?: IContainer) { | ||
super(initialInput, {}, parent); | ||
} | ||
|
||
public render(node: HTMLElement) { | ||
if (this.node) { | ||
ReactDOM.unmountComponentAtNode(this.node); | ||
} | ||
this.node = node; | ||
ReactDOM.render(this.input.render(), node); | ||
Check warning on line 27 in src/plugins/content_management/public/components/custom_content_embeddable.tsx Codecov / codecov/patchsrc/plugins/content_management/public/components/custom_content_embeddable.tsx#L26-L27
|
||
} | ||
|
||
public destroy() { | ||
super.destroy(); | ||
if (this.node) { | ||
ReactDOM.unmountComponentAtNode(this.node); | ||
} | ||
} | ||
|
||
public reload() {} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
import { i18n } from '@osd/i18n'; | ||
|
||
import { EmbeddableFactoryDefinition, IContainer } from '../../../embeddable/public'; | ||
import { | ||
CUSTOM_CONTENT_EMBEDDABLE, | ||
CustomContentEmbeddable, | ||
CustomContentEmbeddableInput, | ||
} from './custom_content_embeddable'; | ||
|
||
export class CustomContentEmbeddableFactoryDefinition implements EmbeddableFactoryDefinition { | ||
public readonly type = CUSTOM_CONTENT_EMBEDDABLE; | ||
Check warning on line 16 in src/plugins/content_management/public/components/custom_content_embeddable_factory.ts Codecov / codecov/patchsrc/plugins/content_management/public/components/custom_content_embeddable_factory.ts#L16
|
||
|
||
public async isEditable() { | ||
return false; | ||
Check warning on line 19 in src/plugins/content_management/public/components/custom_content_embeddable_factory.ts Codecov / codecov/patchsrc/plugins/content_management/public/components/custom_content_embeddable_factory.ts#L19
|
||
} | ||
|
||
public async create(initialInput: CustomContentEmbeddableInput, parent?: IContainer) { | ||
return new CustomContentEmbeddable(initialInput, parent); | ||
Check warning on line 23 in src/plugins/content_management/public/components/custom_content_embeddable_factory.ts Codecov / codecov/patchsrc/plugins/content_management/public/components/custom_content_embeddable_factory.ts#L23
|
||
} | ||
|
||
public getDisplayName() { | ||
return i18n.translate('contentManagement.embeddable.customContent', { | ||
Check warning on line 27 in src/plugins/content_management/public/components/custom_content_embeddable_factory.ts Codecov / codecov/patchsrc/plugins/content_management/public/components/custom_content_embeddable_factory.ts#L27
|
||
defaultMessage: 'Content', | ||
}); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
export * from './page_render'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
import React from 'react'; | ||
import { useObservable } from 'react-use'; | ||
|
||
import { Page } from '../services'; | ||
import { SectionRender } from './section_render'; | ||
import { EmbeddableStart } from '../../../embeddable/public'; | ||
import { SavedObjectsClientContract } from 'opensearch-dashboards/public'; | ||
|
||
export interface Props { | ||
page: Page; | ||
embeddable: EmbeddableStart; | ||
savedObjectsClient: SavedObjectsClientContract; | ||
} | ||
|
||
export const PageRender = ({ page, embeddable, savedObjectsClient }: Props) => { | ||
const sections = useObservable(page.getSections$()) || []; | ||
|
||
return ( | ||
<div className="contentManagement-page" style={{ margin: '10px 20px' }}> | ||
{sections.map((section) => ( | ||
<SectionRender | ||
embeddable={embeddable} | ||
section={section} | ||
savedObjectsClient={savedObjectsClient} | ||
contents$={page.getContents$(section.id)} | ||
/> | ||
))} | ||
</div> | ||
); | ||
}; |