Skip to content

Commit 718d3e3

Browse files
authored
feat: separate the flow list from the current flow (#4205)
1 parent c9025c7 commit 718d3e3

File tree

8 files changed

+260
-198
lines changed

8 files changed

+260
-198
lines changed

cypress/e2e/cloud/pinned.test.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,14 +227,31 @@ from(bucket: "${name}"{rightarrow}
227227
.first()
228228
.click()
229229

230-
cy.getByTestID('time-machine-submit-button').should('be.visible')
231230
cy.getByTestID('page-title')
232231
.first()
233232
.click()
233+
cy.intercept('PATCH', '**/notebooks/*').as('updateNotebook')
234234
cy.getByTestID('renamable-page-title--input')
235235
.clear()
236236
.type('Flow')
237237
.type('{enter}')
238+
239+
cy.wait('@updateNotebook')
240+
cy.getByTestID('time-machine-submit-button')
241+
.should('be.visible')
242+
.and('be.disabled')
243+
cy.getByTestID('enable-auto-refresh-button').should('be.disabled')
244+
cy.getByTestID('dropdown-menu--contents').should('not.exist')
245+
cy.getByTestID('timezone-dropdown').click()
246+
cy.getByTestID('dropdown-menu--contents')
247+
.should('be.visible')
248+
.within(() => {
249+
cy.getByTestID('dropdown-item').should('have.length.gte', 2)
250+
cy.getByTestID('dropdown-item')
251+
.last()
252+
.click()
253+
})
254+
cy.wait('@updateNotebook')
238255
cy.visit(`/orgs/${orgID}/notebooks`)
239256
})
240257

@@ -256,6 +273,7 @@ from(bucket: "${name}"{rightarrow}
256273
cy.getByTestID('context-menu-flow').click()
257274
})
258275
cy.getByTestID('context-pin-flow').click()
276+
cy.getByTestID('notification-success--children').should('exist')
259277

260278
cy.getByTestID('resource-editable-name')
261279
.first()
@@ -271,6 +289,8 @@ from(bucket: "${name}"{rightarrow}
271289
.focus()
272290
.type('Bucks In Six')
273291
.type('{enter}')
292+
cy.getByTestID('notification-success--children').should('exist')
293+
cy.wait('@updateNotebook')
274294
cy.wait('@updatePinned')
275295
cy.visit('/')
276296
cy.getByTestID('tree-nav')

src/flows/components/FlowPage.tsx

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
// Libraries
22
import React, {FC, useContext, useEffect} from 'react'
3-
import {useParams} from 'react-router-dom'
43
import {Page} from '@influxdata/clockface'
54
import {DapperScrollbars} from '@influxdata/clockface'
65

76
// Contexts
87
import CurrentFlowProvider, {FlowContext} from 'src/flows/context/flow.current'
98
import QueryProvider from 'src/shared/contexts/query'
109
import {FlowQueryProvider, FlowQueryContext} from 'src/flows/context/flow.query'
11-
import {FlowListContext} from 'src/flows/context/flow.list'
1210
import {PopupDrawer, PopupProvider} from 'src/flows/context/popup'
1311
import {ResultsProvider} from 'src/flows/context/results'
1412
import {SidebarProvider} from 'src/flows/context/sidebar'
@@ -19,37 +17,8 @@ import {SubSideBar} from 'src/flows/components/Sidebar'
1917
import FlowHeader from 'src/flows/components/header'
2018
import FlowKeyboardPreview from 'src/flows/components/FlowKeyboardPreview'
2119

22-
// Constants
23-
import {PROJECT_NAME_PLURAL} from 'src/flows'
24-
2520
import 'src/flows/style.scss'
2621

27-
// Utils
28-
import {pageTitleSuffixer} from 'src/shared/utils/pageTitles'
29-
import {event} from 'src/cloud/utils/reporting'
30-
31-
const FlowFromRoute = () => {
32-
const {id} = useParams<{id: string}>()
33-
const {change, flows, currentID} = useContext(FlowListContext)
34-
35-
useEffect(() => {
36-
change(id)
37-
}, [id, change])
38-
39-
useEffect(() => {
40-
if (currentID !== null) {
41-
event('Notebook Accessed', {notebookID: currentID})
42-
}
43-
}, [currentID])
44-
45-
document.title = pageTitleSuffixer([
46-
flows[currentID]?.name,
47-
PROJECT_NAME_PLURAL,
48-
])
49-
50-
return null
51-
}
52-
5322
const RunOnMount = () => {
5423
const {queryAll} = useContext(FlowQueryContext)
5524
const {flow} = useContext(FlowContext)
@@ -97,7 +66,6 @@ export const FlowPage: FC = () => (
9766
export default () => (
9867
<QueryProvider>
9968
<CurrentFlowProvider>
100-
<FlowFromRoute />
10169
<FlowPage />
10270
</CurrentFlowProvider>
10371
</QueryProvider>

src/flows/components/header/MenuButton.tsx

Lines changed: 81 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, {FC, createRef, RefObject, useContext} from 'react'
1+
import React, {FC, createRef, RefObject, useContext, useState} from 'react'
22
import {
33
IconFont,
44
Icon,
@@ -7,12 +7,14 @@ import {
77
PopoverInteraction,
88
SquareButton,
99
InfluxColors,
10+
RemoteDataState,
11+
SpinnerContainer,
12+
TechnoSpinner,
1013
} from '@influxdata/clockface'
1114
import {useSelector} from 'react-redux'
1215

1316
// Contexts
1417
import {FlowContext} from 'src/flows/context/flow.current'
15-
import {FlowListContext} from 'src/flows/context/flow.list'
1618
import {VersionPublishContext} from 'src/flows/context/version.publish'
1719
import {useHistory} from 'react-router-dom'
1820

@@ -33,32 +35,44 @@ type Props = {
3335
}
3436

3537
const MenuButton: FC<Props> = ({handleResetShare}) => {
36-
const {remove, clone} = useContext(FlowListContext)
37-
const {flow} = useContext(FlowContext)
38+
const {flow, cloneNotebook, deleteNotebook} = useContext(FlowContext)
3839
const {handlePublish, versions} = useContext(VersionPublishContext)
3940
const {id: orgID} = useSelector(getOrg)
41+
const [loading, setLoading] = useState(RemoteDataState.Done)
4042

4143
const triggerRef: RefObject<HTMLButtonElement> = createRef()
4244
const history = useHistory()
4345

4446
const handleClone = async () => {
45-
event('clone_notebook', {
46-
context: 'notebook',
47-
})
48-
const clonedId = await clone(flow.id)
49-
handleResetShare()
50-
history.push(
51-
`/orgs/${orgID}/${PROJECT_NAME_PLURAL.toLowerCase()}/${clonedId}`
52-
)
47+
try {
48+
setLoading(RemoteDataState.Loading)
49+
event('clone_notebook', {
50+
context: 'notebook',
51+
})
52+
const clonedId = await cloneNotebook()
53+
handleResetShare()
54+
setLoading(RemoteDataState.Done)
55+
history.push(
56+
`/orgs/${orgID}/${PROJECT_NAME_PLURAL.toLowerCase()}/${clonedId}`
57+
)
58+
} catch {
59+
setLoading(RemoteDataState.Done)
60+
}
5361
}
5462

55-
const handleDelete = () => {
56-
event('delete_notebook', {
57-
context: 'notebook',
58-
})
59-
deletePinnedItemByParam(flow.id)
60-
remove(flow.id)
61-
history.push(`/orgs/${orgID}/${PROJECT_NAME_PLURAL.toLowerCase()}`)
63+
const handleDelete = async () => {
64+
try {
65+
setLoading(RemoteDataState.Loading)
66+
event('delete_notebook', {
67+
context: 'notebook',
68+
})
69+
deletePinnedItemByParam(flow.id)
70+
await deleteNotebook()
71+
setLoading(RemoteDataState.Done)
72+
history.push(`/orgs/${orgID}/${PROJECT_NAME_PLURAL.toLowerCase()}`)
73+
} catch {
74+
setLoading(RemoteDataState.Error)
75+
}
6276
}
6377

6478
const canvasOptions = {
@@ -216,51 +230,57 @@ const MenuButton: FC<Props> = ({handleResetShare}) => {
216230
}
217231

218232
return (
219-
<>
220-
<SquareButton
221-
ref={triggerRef}
222-
icon={IconFont.More}
223-
testID="flow-menu-button"
224-
/>
225-
<Popover
226-
triggerRef={triggerRef}
227-
enableDefaultStyles={false}
228-
style={{minWidth: 209}}
229-
onShow={() => {
230-
event('Notebook main menu opened')
231-
}}
232-
showEvent={PopoverInteraction.Click}
233-
hideEvent={PopoverInteraction.Click}
234-
contents={onHide => (
235-
<List>
236-
{menuItems.map(item => {
237-
if (item.type === 'divider') {
233+
<SpinnerContainer
234+
loading={loading}
235+
spinnerComponent={<TechnoSpinner style={{width: 20, height: 20}} />}
236+
style={{width: 20, height: 20}}
237+
>
238+
<>
239+
<SquareButton
240+
ref={triggerRef}
241+
icon={IconFont.More}
242+
testID="flow-menu-button"
243+
/>
244+
<Popover
245+
triggerRef={triggerRef}
246+
enableDefaultStyles={false}
247+
style={{minWidth: 209}}
248+
onShow={() => {
249+
event('Notebook main menu opened')
250+
}}
251+
showEvent={PopoverInteraction.Click}
252+
hideEvent={PopoverInteraction.Click}
253+
contents={onHide => (
254+
<List>
255+
{menuItems.map(item => {
256+
if (item.type === 'divider') {
257+
return (
258+
<List.Divider
259+
key={item.title}
260+
style={{backgroundColor: InfluxColors.Grey35}}
261+
/>
262+
)
263+
}
238264
return (
239-
<List.Divider
265+
<List.Item
240266
key={item.title}
241-
style={{backgroundColor: InfluxColors.Grey35}}
242-
/>
267+
disabled={item?.disabled ? item.disabled() : false}
268+
onClick={() => {
269+
item?.onClick()
270+
onHide()
271+
}}
272+
testID={item?.testID || ''}
273+
>
274+
<Icon glyph={item?.icon} />
275+
<span style={{paddingLeft: '10px'}}>{item.title}</span>
276+
</List.Item>
243277
)
244-
}
245-
return (
246-
<List.Item
247-
key={item.title}
248-
disabled={item?.disabled ? item.disabled() : false}
249-
onClick={() => {
250-
item?.onClick()
251-
onHide()
252-
}}
253-
testID={item?.testID || ''}
254-
>
255-
<Icon glyph={item?.icon} />
256-
<span style={{paddingLeft: '10px'}}>{item.title}</span>
257-
</List.Item>
258-
)
259-
})}
260-
</List>
261-
)}
262-
/>
263-
</>
278+
})}
279+
</List>
280+
)}
281+
/>
282+
</>
283+
</SpinnerContainer>
264284
)
265285
}
266286

0 commit comments

Comments
 (0)