in dashboards-observability/public/components/notebooks/components/notebook.tsx [697:1112]
render() {
const createdText = (
<div>
<p>
Created <br /> {moment(this.state.dateCreated).format(UI_DATE_FORMAT)}
</p>
</div>
);
const viewOptions: EuiButtonGroupOption[] = [
{
id: 'view_both',
label: 'View both',
},
{
id: 'input_only',
label: 'Input only',
},
{
id: 'output_only',
label: 'Output only',
},
];
const addParaPanels: EuiContextMenuPanelDescriptor[] = [
{
id: 0,
title: 'Type',
items: [
{
name: 'Code block',
onClick: () => {
this.setState({ isAddParaPopoverOpen: false });
this.addPara(this.state.paragraphs.length, '', 'CODE');
},
},
{
name: 'Visualization',
onClick: () => {
this.setState({ isAddParaPopoverOpen: false });
this.addPara(this.state.paragraphs.length, '', 'VISUALIZATION');
},
},
],
},
];
const paraActionsPanels: EuiContextMenuPanelDescriptor[] = [
{
id: 0,
title: 'Actions',
items: [
{
name: 'Add paragraph to top',
panel: 1,
},
{
name: 'Add paragraph to bottom',
panel: 2,
},
{
name: 'Run all paragraphs',
disabled: this.state.parsedPara.length === 0,
onClick: () => {
this.setState({ isParaActionsPopoverOpen: false });
this.runForAllParagraphs((para: ParaType, index: number) => {
return para.paraRef.current?.runParagraph();
});
if (this.state.selectedViewId === 'input_only') {
this.updateView('view_both');
}
},
},
{
name: 'Clear all outputs',
disabled: this.state.parsedPara.length === 0,
onClick: () => {
this.setState({ isParaActionsPopoverOpen: false });
this.showClearOutputsModal();
},
},
{
name: 'Delete all paragraphs',
disabled: this.state.parsedPara.length === 0,
onClick: () => {
this.setState({ isParaActionsPopoverOpen: false });
this.showDeleteAllParaModal();
},
},
],
},
{
id: 1,
title: 'Add to top',
items: [
{
name: 'Code block',
onClick: () => {
this.setState({ isParaActionsPopoverOpen: false });
this.addPara(0, '', 'CODE');
},
},
{
name: 'Visualization',
onClick: () => {
this.setState({ isParaActionsPopoverOpen: false });
this.addPara(0, '', 'VISUALIZATION');
},
},
],
},
{
id: 2,
title: 'Add to bottom',
items: [
{
name: 'Code block',
onClick: () => {
this.setState({ isParaActionsPopoverOpen: false });
this.addPara(this.state.paragraphs.length, '', 'CODE');
},
},
{
name: 'Visualization',
onClick: () => {
this.setState({ isParaActionsPopoverOpen: false });
this.addPara(this.state.paragraphs.length, '', 'VISUALIZATION');
},
},
],
},
];
const noteActionsPanels: EuiContextMenuPanelDescriptor[] = [
{
id: 0,
title: 'Notebook actions',
items: [
{
name: 'Rename notebook',
onClick: () => {
this.setState({ isNoteActionsPopoverOpen: false });
this.showRenameModal();
},
},
{
name: 'Duplicate notebook',
onClick: () => {
this.setState({ isNoteActionsPopoverOpen: false });
this.showCloneModal();
},
},
{
name: 'Delete notebook',
onClick: () => {
this.setState({ isNoteActionsPopoverOpen: false });
this.showDeleteNotebookModal();
},
},
],
},
];
const reportingActionPanels: EuiContextMenuPanelDescriptor[] = [
{
id: 0,
title: 'Reporting',
items: [
{
name: 'Download PDF',
icon: <EuiIcon type="download" />,
onClick: () => {
this.setState({ isReportingActionsPopoverOpen: false });
generateInContextReport('pdf', this.props, this.toggleReportingLoadingModal);
},
},
{
name: 'Download PNG',
icon: <EuiIcon type="download" />,
onClick: () => {
this.setState({ isReportingActionsPopoverOpen: false });
generateInContextReport('png', this.props, this.toggleReportingLoadingModal);
},
},
{
name: 'Create report definition',
icon: <EuiIcon type="calendar" />,
onClick: () => {
this.setState({ isReportingActionsPopoverOpen: false });
contextMenuCreateReportDefinition(window.location.href);
},
},
{
name: 'View reports',
icon: <EuiIcon type="document" />,
onClick: () => {
this.setState({ isReportingActionsPopoverOpen: false });
contextMenuViewReports();
},
},
],
},
];
const showReportingContextMenu = this.state.isReportingPluginInstalled ? (
<div>
<EuiPopover
panelPaddingSize="none"
withTitle
button={
<EuiButton
id="reportingActionsButton"
iconType="arrowDown"
iconSide="right"
onClick={() => this.setState({ isReportingActionsPopoverOpen: true })}
>
Reporting actions
</EuiButton>
}
isOpen={this.state.isReportingActionsPopoverOpen}
closePopover={() => this.setState({ isReportingActionsPopoverOpen: false })}
>
<EuiContextMenu initialPanelId={0} panels={reportingActionPanels} />
</EuiPopover>
</div>
) : null;
const showLoadingModal = this.state.isReportingLoadingModalOpen ? (
<GenerateReportLoadingModal setShowLoading={this.toggleReportingLoadingModal} />
) : null;
return (
<div style={pageStyles}>
<EuiPage>
<EuiPageBody component="div">
<EuiFlexGroup gutterSize="s" justifyContent="flexEnd">
<EuiFlexItem />
{this.state.parsedPara.length > 0 && (
<EuiFlexItem grow={false}>
<EuiButtonGroup
buttonSize="m"
options={viewOptions}
idSelected={this.state.selectedViewId}
onChange={(id) => {
this.updateView(id);
}}
/>
</EuiFlexItem>
)}
<EuiFlexItem grow={false} />
<EuiFlexItem grow={false} />
<EuiFlexItem grow={false}>
<EuiPopover
panelPaddingSize="none"
withTitle
button={
<EuiButton
data-test-subj="notebook-paragraph-actions-button"
iconType="arrowDown"
iconSide="right"
onClick={() => this.setState({ isParaActionsPopoverOpen: true })}
>
Paragraph actions
</EuiButton>
}
isOpen={this.state.isParaActionsPopoverOpen}
closePopover={() => this.setState({ isParaActionsPopoverOpen: false })}
>
<EuiContextMenu initialPanelId={0} panels={paraActionsPanels} />
</EuiPopover>
</EuiFlexItem>
<EuiFlexItem grow={false}>{showReportingContextMenu}</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiPopover
panelPaddingSize="none"
withTitle
button={
<EuiButton
data-test-subj="notebook-notebook-actions-button"
iconType="arrowDown"
iconSide="right"
onClick={() => this.setState({ isNoteActionsPopoverOpen: true })}
>
Notebook actions
</EuiButton>
}
isOpen={this.state.isNoteActionsPopoverOpen}
closePopover={() => this.setState({ isNoteActionsPopoverOpen: false })}
>
<EuiContextMenu initialPanelId={0} panels={noteActionsPanels} />
</EuiPopover>
</EuiFlexItem>
</EuiFlexGroup>
<EuiSpacer size="s" />
<EuiTitle size="l">
<h1>{this.state.path}</h1>
</EuiTitle>
<EuiSpacer size="m" />
<EuiFlexGroup alignItems={'flexStart'} gutterSize={'l'}>
<EuiFlexItem grow={false}>
<EuiText>{createdText}</EuiText>
</EuiFlexItem>
</EuiFlexGroup>
{this.state.parsedPara.length > 0 ? (
<>
{this.state.parsedPara.map((para: ParaType, index: number) => (
<div
ref={this.state.parsedPara[index].paraDivRef}
key={`para_div_${para.uniqueId}`}
style={panelStyles}
>
<Paragraphs
ref={this.state.parsedPara[index].paraRef}
pplService={this.props.pplService}
para={para}
setPara={(para: ParaType) => this.setPara(para, index)}
dateModified={this.state.paragraphs[index]?.dateModified}
index={index}
paraCount={this.state.parsedPara.length}
paragraphSelector={this.paragraphSelector}
textValueEditor={this.textValueEditor}
handleKeyPress={this.handleKeyPress}
addPara={this.addPara}
DashboardContainerByValueRenderer={
this.props.DashboardContainerByValueRenderer
}
deleteVizualization={this.deleteVizualization}
http={this.props.http}
selectedViewId={this.state.selectedViewId}
setSelectedViewId={this.updateView}
deletePara={this.showDeleteParaModal}
runPara={this.updateRunParagraph}
clonePara={this.cloneParaButton}
movePara={this.movePara}
showQueryParagraphError={this.state.showQueryParagraphError}
queryParagraphErrorMessage={this.state.queryParagraphErrorMessage}
/>
</div>
))}
{this.state.selectedViewId !== 'output_only' && (
<>
<EuiSpacer />
<EuiPopover
panelPaddingSize="none"
withTitle
button={
<EuiButton
iconType="arrowDown"
iconSide="right"
onClick={() => this.setState({ isAddParaPopoverOpen: true })}
>
Add paragraph
</EuiButton>
}
isOpen={this.state.isAddParaPopoverOpen}
closePopover={() => this.setState({ isAddParaPopoverOpen: false })}
>
<EuiContextMenu initialPanelId={0} panels={addParaPanels} />
</EuiPopover>
</>
)}
</>
) : (
// show default paragraph if no paragraphs in this notebook
<div style={panelStyles}>
<EuiPanel>
<EuiSpacer size="xxl" />
<EuiText textAlign="center">
<h2>No paragraphs</h2>
<EuiText>
Add a paragraph to compose your document or story. Notebooks now support two
types of input:
</EuiText>
</EuiText>
<EuiSpacer size="xl" />
<EuiFlexGroup justifyContent="spaceEvenly">
<EuiFlexItem grow={2} />
<EuiFlexItem grow={3}>
<EuiCard
icon={<EuiIcon size="xxl" type="editorCodeBlock" />}
title="Code block"
description="Write contents directly using markdown, SQL or PPL."
footer={
<EuiButton
onClick={() => this.addPara(0, '', 'CODE')}
style={{ marginBottom: 17 }}
>
Add code block
</EuiButton>
}
/>
</EuiFlexItem>
<EuiFlexItem grow={3}>
<EuiCard
icon={<EuiIcon size="xxl" type="visArea" />}
title="Visualization"
description="Import OpenSearch Dashboards or Observability visualizations to the notes."
footer={
<EuiButton
onClick={() => this.addPara(0, '', 'VISUALIZATION')}
style={{ marginBottom: 17 }}
>
Add visualization
</EuiButton>
}
/>
</EuiFlexItem>
<EuiFlexItem grow={2} />
</EuiFlexGroup>
<EuiSpacer size="xxl" />
</EuiPanel>
</div>
)}
{showLoadingModal}
</EuiPageBody>
</EuiPage>
{this.state.isModalVisible && this.state.modalLayout}
</div>
);
}