Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(notebooks): introduce markdown pipe type #18181

Merged
merged 10 commits into from
May 22, 2020
19 changes: 12 additions & 7 deletions ui/src/notebooks/components/panel/NotebookPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Libraries
import React, {FC, useContext, useCallback} from 'react'
import React, {FC, useContext, useCallback, ReactNode} from 'react'
import classnames from 'classnames'

// Components
Expand All @@ -9,22 +9,27 @@ import {
AlignItems,
JustifyContent,
} from '@influxdata/clockface'
import {PipeContextProps} from 'src/notebooks'
import {NotebookContext} from 'src/notebooks/context/notebook'
import RemovePanelButton from 'src/notebooks/components/panel/RemovePanelButton'
import PanelVisibilityToggle from 'src/notebooks/components/panel/PanelVisibilityToggle'
import MovePanelButton from 'src/notebooks/components/panel/MovePanelButton'
import NotebookPanelTitle from 'src/notebooks/components/panel/NotebookPanelTitle'

// Types
import {PipeContextProps} from 'src/notebooks'

// Contexts
import {NotebookContext} from 'src/notebooks/context/notebook'

export interface Props extends PipeContextProps {
index: number
}

export interface HeaderProps {
index: number
controls?: ReactNode
}

const NotebookPanelHeader: FC<HeaderProps> = ({index}) => {
const NotebookPanelHeader: FC<HeaderProps> = ({index, controls}) => {
const {pipes, removePipe, movePipe} = useContext(NotebookContext)
const canBeMovedUp = index > 0
const canBeMovedDown = index < pipes.length - 1
Expand Down Expand Up @@ -59,6 +64,7 @@ const NotebookPanelHeader: FC<HeaderProps> = ({index}) => {
margin={ComponentSize.Small}
justifyContent={JustifyContent.FlexEnd}
>
{controls}
<MovePanelButton direction="up" onClick={moveUp} />
<MovePanelButton direction="down" onClick={moveDown} />
<PanelVisibilityToggle index={index} />
Expand All @@ -68,8 +74,7 @@ const NotebookPanelHeader: FC<HeaderProps> = ({index}) => {
)
}

const NotebookPanel: FC<Props> = props => {
const {index, children} = props
const NotebookPanel: FC<Props> = ({index, children, controls}) => {
const {meta} = useContext(NotebookContext)

const isVisible = meta[index].visible
Expand All @@ -81,7 +86,7 @@ const NotebookPanel: FC<Props> = props => {

return (
<div className={panelClassName}>
<NotebookPanelHeader index={index} />
<NotebookPanelHeader index={index} controls={controls} />
<div className="notebook-panel--body">{children}</div>
</div>
)
Expand Down
1 change: 1 addition & 0 deletions ui/src/notebooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {FunctionComponent, ComponentClass, ReactNode} from 'react'

export interface PipeContextProps {
children?: ReactNode
controls?: ReactNode
}

export type PipeData = any
Expand Down
38 changes: 38 additions & 0 deletions ui/src/notebooks/pipes/markdown/MarkdownModeToggle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Libraries
import React, {FC} from 'react'

// Components
import {SelectGroup} from '@influxdata/clockface'

// Types
import {MarkdownMode} from './'

interface Props {
mode: MarkdownMode
onToggleMode: (mode: MarkdownMode) => void
}

const MarkdownModeToggle: FC<Props> = ({mode, onToggleMode}) => {
return (
<SelectGroup>
<SelectGroup.Option
active={mode === 'edit'}
onClick={onToggleMode}
value="edit"
id="edit"
>
Edit
</SelectGroup.Option>
<SelectGroup.Option
active={mode === 'preview'}
onClick={onToggleMode}
value="preview"
id="preview"
>
Preview
</SelectGroup.Option>
</SelectGroup>
)
}

export default MarkdownModeToggle
41 changes: 41 additions & 0 deletions ui/src/notebooks/pipes/markdown/MarkdownPanel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Libraries
import React, {FC} from 'react'

// Types
import {PipeProp} from 'src/notebooks'
import {MarkdownMode} from './'

// Components
import MarkdownModeToggle from './MarkdownModeToggle'
import MarkdownPanelEditor from './MarkdownPanelEditor'
import {MarkdownRenderer} from 'src/shared/components/views/MarkdownRenderer'

const MarkdownPanel: FC<PipeProp> = ({data, Context, onUpdate}) => {
const handleToggleMode = (mode: MarkdownMode): void => {
onUpdate({mode})
}

const controls = (
<MarkdownModeToggle mode={data.mode} onToggleMode={handleToggleMode} />
)

const handleChange = (text: string): void => {
onUpdate({text})
}

let panelContents = (
<MarkdownPanelEditor text={data.text} onChange={handleChange} />
)

if (data.mode === 'preview') {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my inner watts is saying that the wrapped renderer and the editor are two different components with a data.mode guard in each of them so that you'd add both as children, and they choose to toggle

panelContents = (
<div className="notebook-panel--markdown markdown-format">
<MarkdownRenderer text={data.text} />
</div>
)
}

return <Context controls={controls}>{panelContents}</Context>
}

export default MarkdownPanel
24 changes: 24 additions & 0 deletions ui/src/notebooks/pipes/markdown/MarkdownPanelEditor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Libraries
import React, {FC, ChangeEvent} from 'react'

interface Props {
text: string
onChange: (text: string) => void
}

const MarkdownPanelEditor: FC<Props> = ({text, onChange}) => {
const handleTextAreaChange = (e: ChangeEvent<HTMLTextAreaElement>): void => {
onChange(e.target.value)
}

return (
<textarea
className="notebook-panel--markdown-editor"
value={text}
onChange={handleTextAreaChange}
autoFocus={true}
/>
)
}

export default MarkdownPanelEditor
15 changes: 15 additions & 0 deletions ui/src/notebooks/pipes/markdown/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import {register} from 'src/notebooks'
import MarkdownPanel from './MarkdownPanel'
import './style.scss'

export type MarkdownMode = 'edit' | 'preview'

register({
type: 'markdown',
component: MarkdownPanel,
button: 'Markdown',
initial: () => ({
text: 'Content',
mode: 'edit',
}),
})
45 changes: 45 additions & 0 deletions ui/src/notebooks/pipes/markdown/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
@import "@influxdata/clockface/dist/variables.scss";

$notebook-panel--bg: mix($g1-raven, $g2-kevlar, 50%);

.notebook-panel--markdown,
.notebook-panel--markdown-editor {
font-size: 14px;
line-height: 16px;
padding: $cf-marg-b;
border-radius: $cf-radius - 1px;
border-width: $cf-border;
border-style: solid;
transition: border-color 0.25s ease;
}

.notebook-panel--markdown {
border-color: $g1-raven;

.notebook-panel:hover & {
border-color: $notebook-panel--bg;
}
}

.notebook-panel--markdown-editor {
padding: $cf-marg-b;
background-color: $g1-raven;
border-color: $cf-input-border--default;
color: $cf-input-text--default;
width: 100%;
min-width: 100%;
max-width: 100%;
transition: $cf-input--transition;
outline: none;

&:hover {
color: $cf-input-text--hover;
border-color: $cf-input-border--hover;
}

&:focus {
color: $cf-input-text--focused;
border-color: $cf-input-border--focused;
box-shadow: $cf-input--box-shadow;
}
}
50 changes: 5 additions & 45 deletions ui/src/notebooks/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ $notebook-divider-height: ($cf-marg-a * 2) + $cf-border;
font-weight: $cf-font-weight--medium;
transition: color 0.25s ease, background-color 0.25s ease;
outline: none;
width: 228px;
width: 350px;

&:hover,
&:focus {
Expand Down Expand Up @@ -141,9 +141,7 @@ $notebook-divider-height: ($cf-marg-a * 2) + $cf-border;
border-radius: 0 0 $cf-radius $cf-radius;
padding: $cf-marg-b;
padding-top: 0;
// flex: 1 0 0;
position: relative;
min-height: 200px;
}

// Special styling for query builder inside notebook panel
Expand All @@ -158,50 +156,12 @@ $notebook-divider-height: ($cf-marg-a * 2) + $cf-border;
padding-top: 0;
}

.notebook-panel--body .flux-editor {
.notebook-panel--body .flux-editor--monaco {
position: relative;
height: 320px;
width: 100%;
top: 0;
right: 0;
bottom: 0;
left: 0;
}

// Special styling for markdown panels
.notebook-panel--markdown,
.notebook-panel--markdown-edit {
font-size: 14px;
padding: $cf-marg-b;
border-radius: $cf-radius - 1px;
border-width: $cf-border;
border-style: solid;
}
min-height: 320px;

.notebook-panel--markdown {
border-color: $notebook-panel--bg;
}

.notebook-panel--markdown-edit {
padding: $cf-marg-b;
background-color: $g1-raven;
border-color: $cf-input-border--default;
color: $cf-input-text--default;
width: 100%;
min-width: 100%;
max-width: 100%;
transition: $cf-input--transition;
outline: none;

&:hover {
color: $cf-input-text--hover;
border-color: $cf-input-border--hover;
}

&:focus {
color: $cf-input-text--focused;
border-color: $cf-input-border--focused;
box-shadow: $cf-input--box-shadow;
.react-monaco-editor-container {
position: absolute;
}
}

Expand Down