-
Notifications
You must be signed in to change notification settings - Fork 894
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New core plugin for dynamic content rendering(#7201)
Signed-off-by: SuZhou-Joe <[email protected]>
- Loading branch information
1 parent
0ca967c
commit d73444b
Showing
27 changed files
with
1,229 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
}; |
46 changes: 46 additions & 0 deletions
46
src/plugins/content_management/public/components/card_container/card_container.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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( | ||
<CardList embeddable={this} embeddableServices={this.embeddableServices} />, | ||
node | ||
); | ||
} | ||
|
||
public destroy() { | ||
super.destroy(); | ||
if (this.node) { | ||
ReactDOM.unmountComponentAtNode(this.node); | ||
} | ||
} | ||
} |
43 changes: 43 additions & 0 deletions
43
src/plugins/content_management/public/components/card_container/card_container_factory.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
|
||
constructor(private getStartServices: () => Promise<StartServices>) {} | ||
|
||
public async isEditable() { | ||
return true; | ||
} | ||
|
||
public create = async (initialInput: ContainerInput) => { | ||
const { embeddableServices } = await this.getStartServices(); | ||
return new CardContainer(initialInput, embeddableServices); | ||
}; | ||
|
||
public getDisplayName() { | ||
return i18n.translate('contentManagement.cardContainer.displayName', { | ||
defaultMessage: 'Card container', | ||
}); | ||
} | ||
} |
46 changes: 46 additions & 0 deletions
46
src/plugins/content_management/public/components/card_container/card_embeddable.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
|
||
constructor(initialInput: CardEmbeddableInput, parent?: IContainer) { | ||
super(initialInput, {}, parent); | ||
} | ||
|
||
public render(node: HTMLElement) { | ||
if (this.node) { | ||
ReactDOM.unmountComponentAtNode(this.node); | ||
} | ||
this.node = node; | ||
ReactDOM.render( | ||
<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() {} | ||
} |
26 changes: 26 additions & 0 deletions
26
src/plugins/content_management/public/components/card_container/card_embeddable_factory.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
|
||
public async isEditable() { | ||
return false; | ||
} | ||
|
||
public async create(initialInput: CardEmbeddableInput, parent?: IContainer) { | ||
return new CardEmbeddable(initialInput, parent); | ||
} | ||
|
||
public getDisplayName() { | ||
return i18n.translate('contentManagement.embeddable.card', { | ||
defaultMessage: 'Card', | ||
}); | ||
} | ||
} |
44 changes: 44 additions & 0 deletions
44
src/plugins/content_management/public/components/card_container/card_list.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); |
38 changes: 38 additions & 0 deletions
38
src/plugins/content_management/public/components/custom_content_embeddable.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
|
||
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); | ||
} | ||
|
||
public destroy() { | ||
super.destroy(); | ||
if (this.node) { | ||
ReactDOM.unmountComponentAtNode(this.node); | ||
} | ||
} | ||
|
||
public reload() {} | ||
} |
31 changes: 31 additions & 0 deletions
31
src/plugins/content_management/public/components/custom_content_embeddable_factory.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
|
||
public async isEditable() { | ||
return false; | ||
} | ||
|
||
public async create(initialInput: CustomContentEmbeddableInput, parent?: IContainer) { | ||
return new CustomContentEmbeddable(initialInput, parent); | ||
} | ||
|
||
public getDisplayName() { | ||
return i18n.translate('contentManagement.embeddable.customContent', { | ||
defaultMessage: 'Content', | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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'; |
35 changes: 35 additions & 0 deletions
35
src/plugins/content_management/public/components/page_render.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | ||
); | ||
}; |
Oops, something went wrong.