feat: flows index (#19448)
* feat(flows): empty state for index page * feat(wip): link to flows from index page * feat(wip): rename flows * feat: name flows * fix: set feature flags * test: skip flagged testpull/19455/head
parent
684b1149f3
commit
6151c389f0
|
@ -0,0 +1,26 @@
|
||||||
|
describe('Flows', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.flush()
|
||||||
|
cy.signin().then(({body}) => {
|
||||||
|
const {
|
||||||
|
org: {id},
|
||||||
|
bucket,
|
||||||
|
} = body
|
||||||
|
cy.wrap(body.org).as('org')
|
||||||
|
cy.wrap(bucket).as('bucket')
|
||||||
|
cy.fixture('routes').then(({orgs, flows}) => {
|
||||||
|
cy.visit(`${orgs}/${id}${flows}`)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// TODO: unskip when no longer blocked by feature flag
|
||||||
|
it.skip('CRUD a flow from the index page', () => {
|
||||||
|
cy.getByTestID('create-flow--button')
|
||||||
|
.first()
|
||||||
|
.click()
|
||||||
|
|
||||||
|
cy.getByTestID('page-title').click()
|
||||||
|
cy.getByTestID('renamable-page-title--input').type('My Flow {enter}')
|
||||||
|
})
|
||||||
|
})
|
|
@ -7,5 +7,6 @@
|
||||||
"endpoints": "/endpoints",
|
"endpoints": "/endpoints",
|
||||||
"rules": "/rules",
|
"rules": "/rules",
|
||||||
"buckets": "/load-data/buckets",
|
"buckets": "/load-data/buckets",
|
||||||
"telegrafs": "/load-data/telegrafs"
|
"telegrafs": "/load-data/telegrafs",
|
||||||
|
"flows": "/flows"
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
import React, {FC} from 'react'
|
||||||
|
import {useParams, useHistory} from 'react-router-dom'
|
||||||
|
|
||||||
|
// Components
|
||||||
|
import {ResourceCard} from '@influxdata/clockface'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const FlowCard: FC<Props> = ({id, name}) => {
|
||||||
|
const {orgID} = useParams()
|
||||||
|
const history = useHistory()
|
||||||
|
|
||||||
|
const handleClick = () => {
|
||||||
|
history.push(`/orgs/${orgID}/notebooks/${id}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ResourceCard key={`flow-card--${id}`}>
|
||||||
|
<ResourceCard.Name
|
||||||
|
name={name || 'Name this flow'}
|
||||||
|
onClick={handleClick}
|
||||||
|
/>
|
||||||
|
</ResourceCard>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default FlowCard
|
|
@ -0,0 +1,32 @@
|
||||||
|
import React, {useContext} from 'react'
|
||||||
|
|
||||||
|
import {ResourceList, Grid, Columns} from '@influxdata/clockface'
|
||||||
|
import {NotebookListContext} from 'src/notebooks/context/notebook.list'
|
||||||
|
import FlowsIndexEmpty from 'src/notebooks/components/FlowsIndexEmpty'
|
||||||
|
|
||||||
|
import FlowCard from 'src/notebooks/components/FlowCard'
|
||||||
|
|
||||||
|
const FlowCards = () => {
|
||||||
|
const {notebooks} = useContext(NotebookListContext)
|
||||||
|
return (
|
||||||
|
<Grid>
|
||||||
|
<Grid.Row>
|
||||||
|
<Grid.Column
|
||||||
|
widthXS={Columns.Twelve}
|
||||||
|
widthSM={Columns.Eight}
|
||||||
|
widthMD={Columns.Ten}
|
||||||
|
>
|
||||||
|
<ResourceList>
|
||||||
|
<ResourceList.Body emptyState={<FlowsIndexEmpty />}>
|
||||||
|
{Object.entries(notebooks).map(([id, {name}]) => {
|
||||||
|
return <FlowCard key={id} id={id} name={name} />
|
||||||
|
})}
|
||||||
|
</ResourceList.Body>
|
||||||
|
</ResourceList>
|
||||||
|
</Grid.Column>
|
||||||
|
</Grid.Row>
|
||||||
|
</Grid>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default FlowCards
|
|
@ -0,0 +1,31 @@
|
||||||
|
// Libraries
|
||||||
|
import React, {useContext} from 'react'
|
||||||
|
import {useHistory, useParams} from 'react-router-dom'
|
||||||
|
|
||||||
|
// Components
|
||||||
|
import {Button, IconFont, ComponentColor} from '@influxdata/clockface'
|
||||||
|
import {NotebookListContext} from 'src/notebooks/context/notebook.list'
|
||||||
|
|
||||||
|
const FlowCreateButton = () => {
|
||||||
|
const history = useHistory()
|
||||||
|
const {orgID} = useParams()
|
||||||
|
const {add} = useContext(NotebookListContext)
|
||||||
|
|
||||||
|
const handleCreate = async () => {
|
||||||
|
const id = await add()
|
||||||
|
history.push(`/orgs/${orgID}/notebooks/${id}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
icon={IconFont.Plus}
|
||||||
|
color={ComponentColor.Primary}
|
||||||
|
text="Create Flow"
|
||||||
|
titleText="Click to create a Flow"
|
||||||
|
onClick={handleCreate}
|
||||||
|
testID="create-flow--button"
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default FlowCreateButton
|
|
@ -0,0 +1,27 @@
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
// Components
|
||||||
|
import {Page} from '@influxdata/clockface'
|
||||||
|
import FlowHeader from 'src/notebooks/components/header'
|
||||||
|
import PipeList from 'src/notebooks/components/PipeList'
|
||||||
|
import MiniMap from 'src/notebooks/components/minimap/MiniMap'
|
||||||
|
|
||||||
|
const FlowPage = () => {
|
||||||
|
return (
|
||||||
|
<Page titleTag="Flows">
|
||||||
|
<FlowHeader />
|
||||||
|
<Page.Contents
|
||||||
|
fullWidth={true}
|
||||||
|
scrollable={false}
|
||||||
|
className="notebook-page"
|
||||||
|
>
|
||||||
|
<div className="notebook">
|
||||||
|
<MiniMap />
|
||||||
|
<PipeList />
|
||||||
|
</div>
|
||||||
|
</Page.Contents>
|
||||||
|
</Page>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default FlowPage
|
|
@ -0,0 +1,32 @@
|
||||||
|
// Libraries
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
// Components
|
||||||
|
import {Page, PageHeader} from '@influxdata/clockface'
|
||||||
|
import FlowCreateButton from 'src/notebooks/components/FlowCreateButton'
|
||||||
|
import NotebookListProvider from 'src/notebooks/context/notebook.list'
|
||||||
|
import FlowCards from 'src/notebooks/components/FlowCards'
|
||||||
|
|
||||||
|
// Utils
|
||||||
|
import {pageTitleSuffixer} from 'src/shared/utils/pageTitles'
|
||||||
|
|
||||||
|
const FlowsIndex = () => {
|
||||||
|
return (
|
||||||
|
<NotebookListProvider>
|
||||||
|
<Page titleTag={pageTitleSuffixer(['Flows'])} testID="flows-index">
|
||||||
|
<PageHeader fullWidth={false}>
|
||||||
|
<Page.Title title="Flows" />
|
||||||
|
</PageHeader>
|
||||||
|
<Page.ControlBar fullWidth={false}>
|
||||||
|
<Page.ControlBarLeft></Page.ControlBarLeft>
|
||||||
|
<Page.ControlBarRight>
|
||||||
|
<FlowCreateButton />
|
||||||
|
</Page.ControlBarRight>
|
||||||
|
</Page.ControlBar>
|
||||||
|
<FlowCards />
|
||||||
|
</Page>
|
||||||
|
</NotebookListProvider>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default FlowsIndex
|
|
@ -0,0 +1,16 @@
|
||||||
|
import React from 'react'
|
||||||
|
import {ComponentSize, EmptyState} from '@influxdata/clockface'
|
||||||
|
import FlowCreateButton from './FlowCreateButton'
|
||||||
|
|
||||||
|
const FlowsIndexEmpty = () => {
|
||||||
|
return (
|
||||||
|
<EmptyState size={ComponentSize.Large}>
|
||||||
|
<EmptyState.Text>
|
||||||
|
Looks like there aren't any <b>Flows</b>, why not create one?
|
||||||
|
</EmptyState.Text>
|
||||||
|
<FlowCreateButton />
|
||||||
|
</EmptyState>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default FlowsIndexEmpty
|
|
@ -1,18 +1,26 @@
|
||||||
// Libraries
|
// Libraries
|
||||||
import React, {FC} from 'react'
|
import React, {FC, useContext, useEffect} from 'react'
|
||||||
|
import {useParams} from 'react-router-dom'
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
import {Page} from '@influxdata/clockface'
|
|
||||||
import NotebookHeader from 'src/notebooks/components/header'
|
|
||||||
import PipeList from 'src/notebooks/components/PipeList'
|
|
||||||
import MiniMap from 'src/notebooks/components/minimap/MiniMap'
|
|
||||||
|
|
||||||
// Contexts
|
|
||||||
import {ResultsProvider} from 'src/notebooks/context/results'
|
import {ResultsProvider} from 'src/notebooks/context/results'
|
||||||
import {RefProvider} from 'src/notebooks/context/refs'
|
import {RefProvider} from 'src/notebooks/context/refs'
|
||||||
import CurrentNotebook from 'src/notebooks/context/notebook.current'
|
import CurrentNotebookProvider, {
|
||||||
|
NotebookContext,
|
||||||
|
} from 'src/notebooks/context/notebook.current'
|
||||||
import {ScrollProvider} from 'src/notebooks/context/scroll'
|
import {ScrollProvider} from 'src/notebooks/context/scroll'
|
||||||
|
import FlowPage from 'src/notebooks/components/FlowPage'
|
||||||
|
|
||||||
|
const NotebookFromRoute = () => {
|
||||||
|
const {id} = useParams()
|
||||||
|
const {change} = useContext(NotebookContext)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
change(id)
|
||||||
|
}, [id, change])
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
// NOTE: uncommon, but using this to scope the project
|
// NOTE: uncommon, but using this to scope the project
|
||||||
// within the page and not bleed it's dependancies outside
|
// within the page and not bleed it's dependancies outside
|
||||||
// of the feature flag
|
// of the feature flag
|
||||||
|
@ -20,27 +28,16 @@ import 'src/notebooks/style.scss'
|
||||||
|
|
||||||
const NotebookPage: FC = () => {
|
const NotebookPage: FC = () => {
|
||||||
return (
|
return (
|
||||||
<CurrentNotebook>
|
<CurrentNotebookProvider>
|
||||||
|
<NotebookFromRoute />
|
||||||
<ResultsProvider>
|
<ResultsProvider>
|
||||||
<RefProvider>
|
<RefProvider>
|
||||||
<ScrollProvider>
|
<ScrollProvider>
|
||||||
<Page titleTag="Flows">
|
<FlowPage />
|
||||||
<NotebookHeader />
|
|
||||||
<Page.Contents
|
|
||||||
fullWidth={true}
|
|
||||||
scrollable={false}
|
|
||||||
className="notebook-page"
|
|
||||||
>
|
|
||||||
<div className="notebook">
|
|
||||||
<MiniMap />
|
|
||||||
<PipeList />
|
|
||||||
</div>
|
|
||||||
</Page.Contents>
|
|
||||||
</Page>
|
|
||||||
</ScrollProvider>
|
</ScrollProvider>
|
||||||
</RefProvider>
|
</RefProvider>
|
||||||
</ResultsProvider>
|
</ResultsProvider>
|
||||||
</CurrentNotebook>
|
</CurrentNotebookProvider>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
import React, {FC, useContext, useCallback} from 'react'
|
import React, {FC, useContext, useCallback} from 'react'
|
||||||
|
|
||||||
// Contexts
|
// Contexts
|
||||||
import {NotebookContext} from 'src/notebooks/context/notebook'
|
import {NotebookContext} from 'src/notebooks/context/notebook.current'
|
||||||
import {TimeProvider, TimeContext, TimeBlock} from 'src/notebooks/context/time'
|
import {TimeProvider, TimeContext, TimeBlock} from 'src/notebooks/context/time'
|
||||||
import AppSettingProvider from 'src/notebooks/context/app'
|
import AppSettingProvider from 'src/notebooks/context/app'
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ import TimeRangeDropdown from 'src/notebooks/components/header/TimeRangeDropdown
|
||||||
import AutoRefreshDropdown from 'src/notebooks/components/header/AutoRefreshDropdown'
|
import AutoRefreshDropdown from 'src/notebooks/components/header/AutoRefreshDropdown'
|
||||||
import Submit from 'src/notebooks/components/header/Submit'
|
import Submit from 'src/notebooks/components/header/Submit'
|
||||||
import PresentationMode from 'src/notebooks/components/header/PresentationMode'
|
import PresentationMode from 'src/notebooks/components/header/PresentationMode'
|
||||||
|
import RenamablePageTitle from 'src/pageLayout/components/RenamablePageTitle'
|
||||||
|
|
||||||
const FULL_WIDTH = true
|
const FULL_WIDTH = true
|
||||||
|
|
||||||
|
@ -22,12 +23,12 @@ export interface TimeContextProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
const NotebookHeader: FC = () => {
|
const NotebookHeader: FC = () => {
|
||||||
const {id} = useContext(NotebookContext)
|
const {id, update, notebook} = useContext(NotebookContext)
|
||||||
const {timeContext, addTimeContext, updateTimeContext} = useContext(
|
const {timeContext, addTimeContext, updateTimeContext} = useContext(
|
||||||
TimeContext
|
TimeContext
|
||||||
)
|
)
|
||||||
|
|
||||||
const update = useCallback(
|
const updateTime = useCallback(
|
||||||
(data: TimeBlock) => {
|
(data: TimeBlock) => {
|
||||||
updateTimeContext(id, data)
|
updateTimeContext(id, data)
|
||||||
},
|
},
|
||||||
|
@ -39,10 +40,19 @@ const NotebookHeader: FC = () => {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleRename = (name: string) => {
|
||||||
|
update({...notebook, name})
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Page.Header fullWidth={FULL_WIDTH}>
|
<Page.Header fullWidth={FULL_WIDTH}>
|
||||||
<Page.Title title="Flows" />
|
<RenamablePageTitle
|
||||||
|
onRename={handleRename}
|
||||||
|
name={notebook.name}
|
||||||
|
placeholder="Name this Flow"
|
||||||
|
maxLength={50}
|
||||||
|
/>
|
||||||
</Page.Header>
|
</Page.Header>
|
||||||
<Page.ControlBar fullWidth={FULL_WIDTH}>
|
<Page.ControlBar fullWidth={FULL_WIDTH}>
|
||||||
<Page.ControlBarLeft>
|
<Page.ControlBarLeft>
|
||||||
|
@ -51,8 +61,8 @@ const NotebookHeader: FC = () => {
|
||||||
<Page.ControlBarRight>
|
<Page.ControlBarRight>
|
||||||
<PresentationMode />
|
<PresentationMode />
|
||||||
<TimeZoneDropdown />
|
<TimeZoneDropdown />
|
||||||
<TimeRangeDropdown context={timeContext[id]} update={update} />
|
<TimeRangeDropdown context={timeContext[id]} update={updateTime} />
|
||||||
<AutoRefreshDropdown context={timeContext[id]} update={update} />
|
<AutoRefreshDropdown context={timeContext[id]} update={updateTime} />
|
||||||
</Page.ControlBarRight>
|
</Page.ControlBarRight>
|
||||||
</Page.ControlBar>
|
</Page.ControlBar>
|
||||||
</>
|
</>
|
||||||
|
|
|
@ -12,6 +12,7 @@ const useNotebookCurrentState = createPersistedState('current-notebook')
|
||||||
|
|
||||||
export interface NotebookContextType {
|
export interface NotebookContextType {
|
||||||
id: string | null
|
id: string | null
|
||||||
|
name: string
|
||||||
notebook: Notebook | null
|
notebook: Notebook | null
|
||||||
change: (id: string) => void
|
change: (id: string) => void
|
||||||
add: (data: Partial<PipeData>, index?: number) => string
|
add: (data: Partial<PipeData>, index?: number) => string
|
||||||
|
@ -21,6 +22,7 @@ export interface NotebookContextType {
|
||||||
|
|
||||||
export const DEFAULT_CONTEXT: NotebookContextType = {
|
export const DEFAULT_CONTEXT: NotebookContextType = {
|
||||||
id: null,
|
id: null,
|
||||||
|
name: 'Name this Flow',
|
||||||
notebook: null,
|
notebook: null,
|
||||||
add: () => '',
|
add: () => '',
|
||||||
change: () => {},
|
change: () => {},
|
||||||
|
@ -114,6 +116,7 @@ export const NotebookProvider: FC = ({children}) => {
|
||||||
<NotebookContext.Provider
|
<NotebookContext.Provider
|
||||||
value={{
|
value={{
|
||||||
id: currentID,
|
id: currentID,
|
||||||
|
name,
|
||||||
notebook: notebooks[currentID],
|
notebook: notebooks[currentID],
|
||||||
add: addPipe,
|
add: addPipe,
|
||||||
update: updateCurrent,
|
update: updateCurrent,
|
||||||
|
|
|
@ -20,6 +20,7 @@ export interface NotebookListContextType extends NotebookList {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const EMPTY_NOTEBOOK: NotebookState = {
|
export const EMPTY_NOTEBOOK: NotebookState = {
|
||||||
|
name: 'Name this Flow',
|
||||||
data: {
|
data: {
|
||||||
byID: {},
|
byID: {},
|
||||||
allIDs: [],
|
allIDs: [],
|
||||||
|
@ -57,6 +58,7 @@ export const NotebookListProvider: FC = ({children}) => {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_notebook = {
|
_notebook = {
|
||||||
|
name: notebook.name,
|
||||||
data: notebook.data.serialize(),
|
data: notebook.data.serialize(),
|
||||||
meta: notebook.meta.serialize(),
|
meta: notebook.meta.serialize(),
|
||||||
readOnly: notebook.readOnly,
|
readOnly: notebook.readOnly,
|
||||||
|
@ -79,6 +81,7 @@ export const NotebookListProvider: FC = ({children}) => {
|
||||||
setNotebooks({
|
setNotebooks({
|
||||||
...notebooks,
|
...notebooks,
|
||||||
[id]: {
|
[id]: {
|
||||||
|
name: notebook.name,
|
||||||
data: notebook.data.serialize(),
|
data: notebook.data.serialize(),
|
||||||
meta: notebook.meta.serialize(),
|
meta: notebook.meta.serialize(),
|
||||||
readOnly: notebook.readOnly,
|
readOnly: notebook.readOnly,
|
||||||
|
@ -111,6 +114,7 @@ export const NotebookListProvider: FC = ({children}) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
acc[curr] = {
|
acc[curr] = {
|
||||||
|
name: notebooks[curr].name,
|
||||||
data: _asResource(notebooks[curr].data, data => {
|
data: _asResource(notebooks[curr].data, data => {
|
||||||
stateUpdater('data', data)
|
stateUpdater('data', data)
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -14,6 +14,7 @@ export interface PipeMeta {
|
||||||
// TODO: this is screaming for normalization. figure out frontend uuids for cells
|
// TODO: this is screaming for normalization. figure out frontend uuids for cells
|
||||||
export interface NotebookContextType {
|
export interface NotebookContextType {
|
||||||
id: string
|
id: string
|
||||||
|
name: string
|
||||||
pipes: PipeData[]
|
pipes: PipeData[]
|
||||||
meta: PipeMeta[] // data only used for the view layer for Notebooks
|
meta: PipeMeta[] // data only used for the view layer for Notebooks
|
||||||
results: FluxResult[]
|
results: FluxResult[]
|
||||||
|
@ -21,16 +22,19 @@ export interface NotebookContextType {
|
||||||
updatePipe: (idx: number, pipe: Partial<PipeData>) => void
|
updatePipe: (idx: number, pipe: Partial<PipeData>) => void
|
||||||
updateMeta: (idx: number, pipe: Partial<PipeMeta>) => void
|
updateMeta: (idx: number, pipe: Partial<PipeMeta>) => void
|
||||||
updateResult: (idx: number, result: Partial<FluxResult>) => void
|
updateResult: (idx: number, result: Partial<FluxResult>) => void
|
||||||
|
updateName: (name: string) => void
|
||||||
movePipe: (currentIdx: number, newIdx: number) => void
|
movePipe: (currentIdx: number, newIdx: number) => void
|
||||||
removePipe: (idx: number) => void
|
removePipe: (idx: number) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DEFAULT_CONTEXT: NotebookContextType = {
|
export const DEFAULT_CONTEXT: NotebookContextType = {
|
||||||
id: 'new',
|
id: 'new',
|
||||||
|
name: 'Name this Flow',
|
||||||
pipes: [],
|
pipes: [],
|
||||||
meta: [],
|
meta: [],
|
||||||
results: [],
|
results: [],
|
||||||
addPipe: () => {},
|
addPipe: () => {},
|
||||||
|
updateName: () => {},
|
||||||
updatePipe: () => {},
|
updatePipe: () => {},
|
||||||
updateMeta: () => {},
|
updateMeta: () => {},
|
||||||
updateResult: () => {},
|
updateResult: () => {},
|
||||||
|
@ -78,11 +82,14 @@ export const NotebookProvider: FC = ({children}) => {
|
||||||
const [pipes, setPipes] = useState(DEFAULT_CONTEXT.pipes)
|
const [pipes, setPipes] = useState(DEFAULT_CONTEXT.pipes)
|
||||||
const [meta, setMeta] = useState(DEFAULT_CONTEXT.meta)
|
const [meta, setMeta] = useState(DEFAULT_CONTEXT.meta)
|
||||||
const [results, setResults] = useState(DEFAULT_CONTEXT.results)
|
const [results, setResults] = useState(DEFAULT_CONTEXT.results)
|
||||||
|
const [name, setName] = useState(DEFAULT_CONTEXT.name)
|
||||||
|
|
||||||
const _setPipes = useCallback(setPipes, [id, setPipes])
|
const _setPipes = useCallback(setPipes, [id, setPipes])
|
||||||
const _setMeta = useCallback(setMeta, [id, setMeta])
|
const _setMeta = useCallback(setMeta, [id, setMeta])
|
||||||
const _setResults = useCallback(setResults, [id, setResults])
|
const _setResults = useCallback(setResults, [id, setResults])
|
||||||
|
|
||||||
|
const updateName = (newName: string) => setName(newName)
|
||||||
|
|
||||||
const addPipe = useCallback(
|
const addPipe = useCallback(
|
||||||
(pipe: PipeData, insertAtIndex?: number) => {
|
(pipe: PipeData, insertAtIndex?: number) => {
|
||||||
let add = data => {
|
let add = data => {
|
||||||
|
@ -221,9 +228,11 @@ export const NotebookProvider: FC = ({children}) => {
|
||||||
<NotebookContext.Provider
|
<NotebookContext.Provider
|
||||||
value={{
|
value={{
|
||||||
id,
|
id,
|
||||||
|
name,
|
||||||
pipes,
|
pipes,
|
||||||
meta,
|
meta,
|
||||||
results,
|
results,
|
||||||
|
updateName,
|
||||||
updatePipe,
|
updatePipe,
|
||||||
updateMeta,
|
updateMeta,
|
||||||
updateResult,
|
updateResult,
|
||||||
|
|
|
@ -56,12 +56,14 @@ export interface ResourceManipulator<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface NotebookState {
|
export interface NotebookState {
|
||||||
|
name: string
|
||||||
data: Resource<PipeData>
|
data: Resource<PipeData>
|
||||||
meta: Resource<PipeMeta>
|
meta: Resource<PipeMeta>
|
||||||
readOnly?: boolean
|
readOnly?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Notebook {
|
export interface Notebook {
|
||||||
|
name: string
|
||||||
data: ResourceManipulator<PipeData>
|
data: ResourceManipulator<PipeData>
|
||||||
meta: ResourceManipulator<PipeMeta>
|
meta: ResourceManipulator<PipeMeta>
|
||||||
results: FluxResult
|
results: FluxResult
|
||||||
|
|
|
@ -108,17 +108,17 @@ export const generateNavItems = (orgID: string): NavItem[] => {
|
||||||
activeKeywords: ['data-explorer'],
|
activeKeywords: ['data-explorer'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'notebooks',
|
id: 'flows',
|
||||||
testID: 'nav-item-notebooks',
|
testID: 'nav-item-flows',
|
||||||
icon: IconFont.Erlenmeyer,
|
icon: IconFont.Erlenmeyer,
|
||||||
label: 'Flows',
|
label: 'Flows',
|
||||||
featureFlag: 'notebooks',
|
featureFlag: 'notebooks',
|
||||||
shortLabel: 'Flows',
|
shortLabel: 'Flows',
|
||||||
link: {
|
link: {
|
||||||
type: 'link',
|
type: 'link',
|
||||||
location: `${orgPrefix}/notebooks`,
|
location: `${orgPrefix}/flows`,
|
||||||
},
|
},
|
||||||
activeKeywords: ['notebooks'],
|
activeKeywords: ['flows'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'dashboards',
|
id: 'dashboards',
|
||||||
|
|
|
@ -29,6 +29,7 @@ import MembersIndex from 'src/members/containers/MembersIndex'
|
||||||
import RouteToDashboardList from 'src/dashboards/components/RouteToDashboardList'
|
import RouteToDashboardList from 'src/dashboards/components/RouteToDashboardList'
|
||||||
import ClientLibrariesPage from 'src/writeData/containers/ClientLibrariesPage'
|
import ClientLibrariesPage from 'src/writeData/containers/ClientLibrariesPage'
|
||||||
import TelegrafPluginsPage from 'src/writeData/containers/TelegrafPluginsPage'
|
import TelegrafPluginsPage from 'src/writeData/containers/TelegrafPluginsPage'
|
||||||
|
import FlowsIndex from 'src/notebooks/components/FlowsIndex'
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import {AppState, Organization, ResourceType} from 'src/types'
|
import {AppState, Organization, ResourceType} from 'src/types'
|
||||||
|
@ -134,9 +135,13 @@ const SetOrg: FC<Props> = ({
|
||||||
component={RouteToDashboardList}
|
component={RouteToDashboardList}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* Flows */}
|
{/* Flows */}
|
||||||
{isFlagEnabled('notebooks') && (
|
{isFlagEnabled('notebooks') && (
|
||||||
<Route path={`${orgPath}/notebooks`} component={NotebookPage} />
|
<Route path={`${orgPath}/notebooks/:id`} component={NotebookPage} />
|
||||||
|
)}
|
||||||
|
|
||||||
|
{isFlagEnabled('notebooks') && (
|
||||||
|
<Route path={`${orgPath}/flows`} component={FlowsIndex} />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Write Data */}
|
{/* Write Data */}
|
||||||
|
|
Loading…
Reference in New Issue