Skip to content

Commit

Permalink
Merge pull request #772 from oskarhane/grass-regressions
Browse files Browse the repository at this point in the history
Fix :style / GraSS regressions
  • Loading branch information
pe4cey authored May 29, 2018
2 parents 644aefb + 2d81dfa commit 14728fa
Show file tree
Hide file tree
Showing 15 changed files with 522 additions and 109 deletions.
57 changes: 57 additions & 0 deletions e2e_tests/integration/style.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Copyright (c) 2002-2018 "Neo4j, Inc"
* Network Engine for Objects in Lund AB [http://neotechnology.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

/* global Cypress, cy, test, expect */

describe(':style', () => {
it('can connect', () => {
const password = Cypress.env('BROWSER_NEW_PASSWORD') || 'newpassword'
cy.connect('neo4j', password)
})
it('print the current style', () => {
cy.executeCommand(':clear')
cy.executeCommand('CREATE (n:Style) RETURN n') // To generate any style
const query = ':style'
cy.executeCommand(query)
cy
.get('[data-test-id="frameCommand"]', { timeout: 10000 })
.first()
.should('contain', query)
cy
.get('[data-test-id="frameContents"]', { timeout: 10000 })
.first()
.should('contain', 'node {')
.should('contain', 'relationship {')
.should('contain', '"<type>"')
})
it('can reset style with button', () => {
cy.executeCommand(':clear')
cy.executeCommand(':style')
cy.get('[data-test-id="exportGrassButton"]', { timeout: 10000 })
cy
.get('[data-test-id="styleResetButton"]', { timeout: 10000 })
.first()
.click()
cy
.get('[data-test-id="frameContents"]', { timeout: 10000 })
.first()
.should('contain', 'No style generated or set yet')
})
})
4 changes: 4 additions & 0 deletions src/browser/components/icons/Icons.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -294,3 +294,7 @@ export const Spinner = () => (
export const ExclamationTriangleIcon = () => (
<IconContainer suppressIconStyles className='fa fa-exclamation-triangle' />
)

export const FireExtinguisherIcon = ({ title = 'Reset' }) => (
<IconContainer className='fa fa-fire-extinguisher' title={title} />
)
2 changes: 1 addition & 1 deletion src/browser/modules/Sidebar/FileDrop.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { connect } from 'preact-redux'
import Dropzone from 'react-dropzone'

import { addFavorite } from 'shared/modules/favorites/favoritesDuck'
import { parseGrass } from 'shared/modules/commands/helpers/grass'
import { parseGrass } from 'shared/services/grassUtils'
import { updateGraphStyleData } from 'shared/modules/grass/grassDuck'
import { showErrorMessage } from 'shared/modules/commands/commandsDuck'

Expand Down
37 changes: 27 additions & 10 deletions src/browser/modules/Stream/FrameTitlebar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,24 @@ class FrameTitlebar extends Component {
const { svgElement, graphElement, type } = this.props.visElement
downloadPNGFromSVG(svgElement, graphElement, type)
}

exportSVG () {
const { svgElement, graphElement, type } = this.props.visElement
downloadSVG(svgElement, graphElement, type)
}

exportGrass (data) {
var blob = new Blob([data], {
type: 'text/plain;charset=utf-8'
})
saveAs(blob, 'style.grass')
}
canExport = () => {
let props = this.props
const { frame = {} } = props
return (
(frame.type === 'cypher' && (this.hasData() || props.visElement)) ||
(frame.type === 'style' && this.hasData())
)
}
render () {
let props = this.props
const { frame = {} } = props
Expand All @@ -104,9 +116,7 @@ class FrameTitlebar extends Component {
</DottedLineHover>
</StyledFrameCommand>
<FrameTitlebarButtonSection>
<Render
if={frame.type === 'cypher' && (this.hasData() || props.visElement)}
>
<Render if={this.canExport()}>
<DropdownButton>
<DownloadIcon />
<DropdownList>
Expand All @@ -121,13 +131,21 @@ class FrameTitlebar extends Component {
</DropdownItem>
</span>
</Render>
<Render if={this.hasData()}>
<Render if={this.hasData() && frame.type === 'cypher'}>
<DropdownItem
onClick={() => this.exportCSV(props.getRecords())}
>
Export CSV
</DropdownItem>
</Render>
<Render if={this.hasData() && frame.type === 'style'}>
<DropdownItem
data-test-id='exportGrassButton'
onClick={() => this.exportGrass(props.getRecords())}
>
Export GraSS
</DropdownItem>
</Render>
</DropdownContent>
</DropdownList>
</DropdownButton>
Expand All @@ -142,9 +160,7 @@ class FrameTitlebar extends Component {
>
<PinIcon />
</FrameButton>
<Render
if={['cypher', 'play', 'play-remote'].indexOf(frame.type) > -1}
>
<Render if={['cypher', 'play', 'play-remote'].includes(frame.type)}>
<FrameButton
title={props.fullscreen ? 'Close fullscreen' : 'Fullscreen'}
onClick={() => props.fullscreenToggle()}
Expand All @@ -158,8 +174,9 @@ class FrameTitlebar extends Component {
>
{expandCollapseIcon}
</FrameButton>
<Render if={frame.type === 'cypher'}>
<Render if={['cypher', 'style'].includes(frame.type)}>
<FrameButton
data-test-id='rerunFrameButton'
title='Rerun'
onClick={() =>
props.onReRunClick(frame.cmd, frame.id, frame.requestId)}
Expand Down
50 changes: 50 additions & 0 deletions src/browser/modules/Stream/InfoView.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright (c) 2002-2018 "Neo4j, Inc"
* Network Engine for Objects in Lund AB [http://neotechnology.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { Component } from 'preact'
import {
StyledInfoMessage,
StyledHelpContent,
StyledH4,
StyledHelpDescription,
StyledDiv,
StyledHelpFrame
} from './styled'

export class InfoView extends Component {
shouldComponentUpdate (props, state) {
return false
}
render () {
const { title, description } = this.props
return (
<StyledHelpFrame>
<StyledHelpContent>
<StyledHelpDescription>
<StyledInfoMessage>INFO</StyledInfoMessage>
<StyledH4>{title}</StyledH4>
</StyledHelpDescription>
<StyledDiv>
<StyledHelpDescription>{description}</StyledHelpDescription>
</StyledDiv>
</StyledHelpContent>
</StyledHelpFrame>
)
}
}
2 changes: 2 additions & 0 deletions src/browser/modules/Stream/Stream.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import ParamsFrame from './ParamsFrame'
import ErrorFrame from './ErrorFrame'
import HelpFrame from './HelpFrame'
import SchemaFrame from './SchemaFrame'
import StyleFrame from './StyleFrame'
import SysInfoFrame from './SysInfoFrame'
import ConnectionFrame from './Auth/ConnectionFrame'
import DisconnectFrame from './Auth/DisconnectFrame'
Expand Down Expand Up @@ -67,6 +68,7 @@ const getFrame = type => {
status: ServerStatusFrame,
'switch-success': ServerSwitchFrame,
'switch-fail': ServerSwitchFrame,
style: StyleFrame,
default: Frame
}
return trans[type] || trans['default']
Expand Down
101 changes: 101 additions & 0 deletions src/browser/modules/Stream/StyleFrame.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
* Copyright (c) 2002-2018 "Neo4j, Inc"
* Network Engine for Objects in Lund AB [http://neotechnology.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { connect } from 'preact-redux'
import FrameTemplate from './FrameTemplate'
import {
PaddedDiv,
StyledOneRowStatsBar,
StyledRightPartial,
FrameTitlebarButtonSection
} from './styled'
import { FrameButton } from 'browser-components/buttons'
import { objToCss } from 'services/grassUtils'
import {
executeSystemCommand,
executeCommand
} from 'shared/modules/commands/commandsDuck'
import { getCmdChar } from 'shared/modules/settings/settingsDuck'
import { FireExtinguisherIcon } from 'browser-components/icons/Icons'
import { InfoView } from './InfoView'

const StyleFrame = ({ frame }) => {
let grass = ''
let contents = (
<InfoView
title='No styles yet'
description='No style generated or set yet. Run a query and return a few nodes and
relationships to generate some styling.'
/>
)
if (frame.result) {
grass = objToCss(frame.result)
contents = (
<PaddedDiv>
<pre>
{grass ||
'Something went wrong when parsing the GraSS. Please reset and try again.'}
</pre>
</PaddedDiv>
)
}
return (
<FrameTemplate
header={frame}
numRecords={1}
getRecords={() => grass}
contents={contents}
statusbar={<Statusbar frame={frame} />}
/>
)
}

const StyleStatusbar = ({ resetStyleAction, rerunAction, onResetClick }) => {
return (
<StyledOneRowStatsBar>
<StyledRightPartial>
<FrameTitlebarButtonSection>
<FrameButton
data-test-id='styleResetButton'
onClick={() => onResetClick(resetStyleAction, rerunAction)}
>
<FireExtinguisherIcon title='Reset style' />
</FrameButton>
</FrameTitlebarButtonSection>
</StyledRightPartial>
</StyledOneRowStatsBar>
)
}

const mapStateToProps = (state, ownProps) => {
return {
resetStyleAction: executeSystemCommand(`${getCmdChar(state)}style reset`),
rerunAction: executeCommand(ownProps.frame.cmd, ownProps.frame.id)
}
}
const mapDispatchToProps = dispatch => ({
onResetClick: (resetStyleAction, rerunAction) => {
dispatch(resetStyleAction)
dispatch(rerunAction)
}
})

const Statusbar = connect(mapStateToProps, mapDispatchToProps)(StyleStatusbar)

export default StyleFrame
8 changes: 6 additions & 2 deletions src/browser/modules/Stream/styled.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -203,12 +203,16 @@ export const StyledCypherMessage = styled.div`
float: left;
`
export const StyledCypherWarningMessage = styled(StyledCypherMessage)`
background-color: #ffa500;
background-color: ${props => props.theme.warning};
color: #ffffff;
`

export const StyledCypherErrorMessage = styled(StyledCypherMessage)`
background-color: #e74c3c;
background-color: ${props => props.theme.error};
color: #ffffff;
`
export const StyledInfoMessage = styled(StyledCypherMessage)`
background-color: ${props => props.theme.info};
color: #ffffff;
`

Expand Down
1 change: 1 addition & 0 deletions src/browser/styles/themes.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export const base = {
error: '#E74C3C',
warning: '#FD952C',
auth: '#428BCA',
info: '#428BCA',

// Buttons
primaryButtonText: '#fff',
Expand Down
4 changes: 2 additions & 2 deletions src/shared/modules/commands/commandsDuck.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -355,8 +355,8 @@ describe('commandsDuck', () => {
{ type: commands.KNOWN_COMMAND },
frames.add({
...action,
type: 'pre',
result: JSON.stringify({ node: { color: '#000' } }, null, 2)
type: 'style',
result: { node: { color: '#000' } }
}),
{ type: 'NOOP' }
])
Expand Down
Loading

0 comments on commit 14728fa

Please sign in to comment.