parent
020d938537
commit
1dc54f403e
|
@ -11,25 +11,37 @@ import {PIPE_DEFINITIONS} from 'src/notebooks'
|
|||
const AddButtons: FC = () => {
|
||||
const {addPipe} = useContext(NotebookContext)
|
||||
|
||||
const pipes = Object.entries(PIPE_DEFINITIONS).map(([type, def]) => {
|
||||
return (
|
||||
<Button
|
||||
key={def.type}
|
||||
text={def.button}
|
||||
onClick={() => {
|
||||
let data = def.initial
|
||||
if (typeof data === 'function') {
|
||||
data = data()
|
||||
}
|
||||
addPipe({
|
||||
...data,
|
||||
type,
|
||||
})
|
||||
}}
|
||||
color={ComponentColor.Secondary}
|
||||
/>
|
||||
)
|
||||
})
|
||||
const pipes = Object.entries(PIPE_DEFINITIONS)
|
||||
.filter(([_, def]) => !def.disabled)
|
||||
.sort((a, b) => {
|
||||
const aPriority = a[1].priority || 0
|
||||
const bPriority = b[1].priority || 0
|
||||
|
||||
if (aPriority === bPriority) {
|
||||
return a[1].button.localeCompare(b[1].button)
|
||||
}
|
||||
|
||||
return bPriority - aPriority
|
||||
})
|
||||
.map(([type, def]) => {
|
||||
return (
|
||||
<Button
|
||||
key={def.type}
|
||||
text={def.button}
|
||||
onClick={() => {
|
||||
let data = def.initial
|
||||
if (typeof data === 'function') {
|
||||
data = data()
|
||||
}
|
||||
addPipe({
|
||||
...data,
|
||||
type,
|
||||
})
|
||||
}}
|
||||
color={ComponentColor.Secondary}
|
||||
/>
|
||||
)
|
||||
})
|
||||
|
||||
return <>{pipes}</>
|
||||
}
|
||||
|
|
|
@ -26,6 +26,8 @@ export interface PipeProp {
|
|||
// on the page.
|
||||
export interface TypeRegistration {
|
||||
type: string // a unique string that identifies a pipe
|
||||
priority?: number // 0 is lowest priority, equal priorities revert to string comparison
|
||||
disabled?: boolean // if you should show it or not
|
||||
component: FunctionComponent<PipeProp> | ComponentClass<PipeProp> // the view component for rendering the interface
|
||||
button: string // a human readable string for appending the type
|
||||
initial: any // the default state for an add
|
||||
|
|
|
@ -4,6 +4,7 @@ import './style.scss'
|
|||
|
||||
register({
|
||||
type: 'query',
|
||||
priority: 1,
|
||||
component: View,
|
||||
button: 'Custom Script',
|
||||
initial: {
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
import React, {FC} from 'react'
|
||||
import {Input} from '@influxdata/clockface'
|
||||
|
||||
import {PipeData} from 'src/notebooks'
|
||||
|
||||
interface Props {
|
||||
data: PipeData
|
||||
onUpdate: (data: PipeData) => void
|
||||
visible: boolean
|
||||
}
|
||||
|
||||
const Editor: FC<Props> = ({data, onUpdate, visible}) => {
|
||||
const update = evt => {
|
||||
onUpdate(evt.target.value)
|
||||
}
|
||||
|
||||
if (!visible) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="notebook-spotify--editor">
|
||||
<label>Spotify URI</label>
|
||||
<Input value={data.uri} onChange={update} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Editor
|
|
@ -0,0 +1,29 @@
|
|||
import React, {FC, useMemo} from 'react'
|
||||
|
||||
interface Props {
|
||||
uri: string
|
||||
visible: boolean
|
||||
}
|
||||
|
||||
const Embedded: FC<Props> = ({uri, visible}) => {
|
||||
const parts = uri.split(':')
|
||||
|
||||
if (!visible) {
|
||||
return null
|
||||
}
|
||||
|
||||
return useMemo(
|
||||
() => (
|
||||
<iframe
|
||||
src={`https://open.spotify.com/embed/${parts[1]}/${parts[2]}`}
|
||||
width="600"
|
||||
height="80"
|
||||
frameBorder="0"
|
||||
allow="encrypted-media"
|
||||
/>
|
||||
),
|
||||
[uri]
|
||||
)
|
||||
}
|
||||
|
||||
export default Embedded
|
|
@ -0,0 +1,15 @@
|
|||
import {register} from 'src/notebooks'
|
||||
|
||||
import View from './view'
|
||||
import './style.scss'
|
||||
|
||||
register({
|
||||
type: 'spotify',
|
||||
priority: -1,
|
||||
disabled: true,
|
||||
button: 'Music',
|
||||
component: View,
|
||||
initial: {
|
||||
uri: 'spotify:track:55A8N3HXzIecctUSvru3Ch',
|
||||
},
|
||||
})
|
|
@ -0,0 +1,10 @@
|
|||
.notebook-spotify {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.notebook-spotify--editor {
|
||||
width: 600px;
|
||||
margin: 0 auto;
|
||||
|
||||
text-align: right;
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
// Libraries
|
||||
import React, {FC, useState} from 'react'
|
||||
|
||||
// Components
|
||||
import Embedded from './embedded'
|
||||
import Editor from './editor'
|
||||
import {SquareButton, IconFont} from '@influxdata/clockface'
|
||||
|
||||
// Types
|
||||
import {PipeProp} from 'src/notebooks'
|
||||
|
||||
const Spotify: FC<PipeProp> = ({Context, data, onUpdate}) => {
|
||||
const [isEditing, setIsEditing] = useState<boolean>(false)
|
||||
const toggleEdit = () => {
|
||||
setIsEditing(!isEditing)
|
||||
}
|
||||
|
||||
const controls = (
|
||||
<SquareButton
|
||||
icon={IconFont.CogThick}
|
||||
titleText="Edit Spotify URI"
|
||||
onClick={toggleEdit}
|
||||
/>
|
||||
)
|
||||
|
||||
const showEditing = isEditing || !data.uri
|
||||
|
||||
return (
|
||||
<Context controls={controls}>
|
||||
<div className="notebook-spotify">
|
||||
<Editor data={data} onUpdate={onUpdate} visible={showEditing} />
|
||||
<Embedded uri={data.uri} visible={!showEditing} />
|
||||
</div>
|
||||
</Context>
|
||||
)
|
||||
}
|
||||
|
||||
export default Spotify
|
Loading…
Reference in New Issue