Skip to content

Commit d229d65

Browse files
feat: add ability to download notebook in full presentation as PDF/PNG (#3658)
* feat: download Notebooks pipes only * feat: add basic menu button in notebook header * feat: add logo and title to pdf file * feat: add dropdown menu button * feat: add icons to menu items * feat: add functionality to download PNG * fix: remove console.log * fix: recalculate the Y coordinate for pipe list screenshot * chore: replace Dropdown.Menu with List and remove repeated delete and clone buttons * fix: remove PopoverInteraction.Click * test: add cypress test for menu button * test: add cypress test for menu button in e2e * feat: add PopoverInteraction on Popover component * chore: move delete option to bottom * feat: add hidden header in pipe list for download pdf/png canvas * style: move inline style to scss file * feat: add time zone flag to time range label * feat: add time range label to the hidden header in pipe list * chore: generalize html2canvas option to select hidden element by class name instead of by id * chore: replace currentID with flow.id * chore: change canvasOption back to object instead of a function * chore: replace currentID with flow.id * chore: move timezone to be a property of the flow for pdf/png download rather than a property of TimeRangeLabel * fix: resolve lint and lint-cloud test * chore: change data-download-hide from class to attribute * feat: add feature flag downloadNotebookPDF * chore: remove comment * fix(test): add multiple to click test * fix(test): only click on the first element of page-title * fix: run prettier on pinned.test.ts * test: click the first page-title element
1 parent d7096ea commit d229d65

File tree

6 files changed

+282
-32
lines changed

6 files changed

+282
-32
lines changed

cypress/e2e/cloud/pinned.test.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,9 @@ from(bucket: "${name}"{rightarrow}
228228
.click()
229229

230230
cy.getByTestID('time-machine-submit-button').should('be.visible')
231-
cy.getByTestID('page-title').click()
231+
cy.getByTestID('page-title')
232+
.first()
233+
.click()
232234
cy.getByTestID('renamable-page-title--input')
233235
.clear()
234236
.type('Flow')

cypress/e2e/shared/flows.test.ts

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ describe('Flows', () => {
3333

3434
cy.getByTestID('time-machine-submit-button').should('be.visible')
3535

36-
cy.getByTestID('page-title').click()
36+
cy.getByTestID('page-title')
37+
.first()
38+
.click()
3739
cy.getByTestID('renamable-page-title--input').type('My Flow {enter}')
3840

3941
cy.getByTestID('sidebar-button')
@@ -65,7 +67,9 @@ describe('Flows', () => {
6567
.click()
6668

6769
cy.getByTestID('time-machine-submit-button').should('be.visible')
68-
cy.getByTestID('page-title').click()
70+
cy.getByTestID('page-title')
71+
.first()
72+
.click()
6973
cy.getByTestID('renamable-page-title--input').type('My Flow {enter}')
7074

7175
cy.getByTestID('sidebar-button')
@@ -114,7 +118,9 @@ describe('Flows', () => {
114118
.click()
115119
cy.getByTestID('time-machine-submit-button').should('be.visible')
116120

117-
cy.getByTestID('page-title').click()
121+
cy.getByTestID('page-title')
122+
.first()
123+
.click()
118124
cy.getByTestID('renamable-page-title--input').type('My Flow {enter}')
119125

120126
// select our bucket
@@ -196,7 +202,9 @@ describe('Flows', () => {
196202
cy.getByTestID('time-machine-submit-button').should('be.visible')
197203
cy.intercept('PATCH', '**/notebooks/*').as('updateNotebook')
198204

199-
cy.getByTestID('page-title').click()
205+
cy.getByTestID('page-title')
206+
.first()
207+
.click()
200208
cy.getByTestID('renamable-page-title--input').type(`${flowName}`)
201209

202210
// select our bucket
@@ -276,6 +284,25 @@ describe('Flows', () => {
276284

277285
cy.get('.cf-resource-card').should('have.length', 1)
278286
cy.getByTestID('resource-editable-name').contains(`${flowName}`)
287+
288+
// Clone a flow again
289+
cy.getByTestID(`flow-card--${flowName}`).within(() => {
290+
cy.getByTestID(`context-menu-flow`).click()
291+
})
292+
cy.getByTestID(`context-clone-flow`).click()
293+
294+
// Should redirect the user to the newly cloned flow
295+
// Test menu button works
296+
cy.getByTestID('flow-menu-button').click()
297+
298+
// Make sure the delete button is visible
299+
cy.getByTestID('flow-menu-button-delete').should('be.visible')
300+
301+
// Delete the cloned flow inside the notebook
302+
cy.getByTestID('flow-menu-button-delete').click()
303+
304+
cy.get('.cf-resource-card').should('have.length', 1)
305+
cy.getByTestID('resource-editable-name').contains(`${flowName}`)
279306
})
280307

281308
it('should not run Preview when presentation mode is off', () => {
@@ -301,7 +328,9 @@ describe('Flows', () => {
301328
.click()
302329
cy.getByTestID('time-machine-submit-button').should('be.visible')
303330

304-
cy.getByTestID('page-title').click()
331+
cy.getByTestID('page-title')
332+
.first()
333+
.click()
305334
cy.getByTestID('renamable-page-title--input').type(`${flowName}`)
306335

307336
// select our bucket
@@ -379,7 +408,9 @@ describe('Flows', () => {
379408
.click()
380409
cy.getByTestID('time-machine-submit-button').should('be.visible')
381410

382-
cy.getByTestID('page-title').click()
411+
cy.getByTestID('page-title')
412+
.first()
413+
.click()
383414
cy.getByTestID('renamable-page-title--input').type(`${flowName}`)
384415

385416
// select our bucket

cypress/e2e/shared/flowsAlerts.test.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ describe('flows alert panel', () => {
4545
.click()
4646
cy.getByTestID('time-machine-submit-button').should('be.visible')
4747

48-
cy.getByTestID('page-title').click()
48+
cy.getByTestID('page-title')
49+
.first()
50+
.click()
4951
cy.getByTestID('renamable-page-title--input').type(`${flowName}`)
5052

5153
// select our bucket, measurement, field and tag
@@ -141,7 +143,9 @@ describe('flows alert panel', () => {
141143
.click()
142144
cy.getByTestID('time-machine-submit-button').should('be.visible')
143145

144-
cy.getByTestID('page-title').click()
146+
cy.getByTestID('page-title')
147+
.first()
148+
.click()
145149
cy.getByTestID('renamable-page-title--input').type(`${flowName}`)
146150

147151
// select our bucket, measurement, field and tag

src/flows/components/PipeList.tsx

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,48 @@
11
// Libraries
22
import React, {FC, useContext} from 'react'
3+
import {useSelector} from 'react-redux'
34
import ReactGridLayout, {WidthProvider, Layout} from 'react-grid-layout'
45

56
// Contexts
67
import {FlowContext} from 'src/flows/context/flow.current'
8+
import {getTimeZone} from 'src/dashboards/selectors'
79

810
// Components
911
import FlowPipe from 'src/flows/components/FlowPipe'
1012
import PresentationPipe from 'src/flows/components/PresentationPipe'
1113
import EmptyPipeList from 'src/flows/components/EmptyPipeList'
1214
import InsertCellButton from 'src/flows/components/panel/InsertCellButton'
15+
import {InfluxColors, InfluxDataLogo, Page} from '@influxdata/clockface'
16+
import TimeRangeLabel from 'src/flows/components/header/TimeRangeLabel'
1317

1418
import {LAYOUT_MARGIN, DASHBOARD_LAYOUT_ROW_HEIGHT} from 'src/shared/constants'
1519

1620
const Grid = WidthProvider(ReactGridLayout)
1721

22+
// This component only shows up in downloaded PNG/PDF files
23+
const HiddenHeader: FC = () => {
24+
const {flow} = useContext(FlowContext)
25+
const timeZone = useSelector(getTimeZone)
26+
return (
27+
<div data-download-hide="true">
28+
<div className="hidden-header-logo">
29+
<InfluxDataLogo fill={InfluxColors.White} />
30+
</div>
31+
<div className="hidden-header-title">
32+
<Page.Title title={flow.name} />
33+
<span>
34+
<TimeRangeLabel />
35+
<h4>
36+
{timeZone === 'Local'
37+
? Intl.DateTimeFormat().resolvedOptions().timeZone // e.g. America/Chicago
38+
: timeZone}
39+
</h4>
40+
</span>
41+
</div>
42+
</div>
43+
)
44+
}
45+
1846
const PipeList: FC = () => {
1947
const {flow, updateMeta} = useContext(FlowContext)
2048

@@ -71,7 +99,8 @@ const PipeList: FC = () => {
7199
}
72100

73101
return (
74-
<div className="flow">
102+
<div className="flow" id={flow?.id}>
103+
<HiddenHeader />
75104
<Grid
76105
cols={12}
77106
layout={layout}
@@ -109,7 +138,8 @@ const PipeList: FC = () => {
109138
})
110139

111140
return (
112-
<div className="flow">
141+
<div className="flow" id={flow?.id}>
142+
<HiddenHeader />
113143
<InsertCellButton />
114144
{_pipes}
115145
</div>

0 commit comments

Comments
 (0)