Commit ad0325ee authored by Markus Scheidgen's avatar Markus Scheidgen
Browse files

Fixed eslinting for ci.

parent 361e2af1
......@@ -55,6 +55,14 @@ linting:
- $CI_COMMIT_REF_NAME =~ /^dev-.*$/
- $CI_COMMIT_MESSAGE =~ /\[skip[ _-]tests?\]/i
gui_linting:
stage: test
image: node
script:
- cd gui
- yarn
- yarn run eslint 'src/**/*.js'
tests:
stage: test
image: $TEST_IMAGE
......
......@@ -8,10 +8,16 @@ module.exports = {
}
},
"globals": {
"fetch": false
"fetch": false,
"browser": true
},
"rules": {
"space-before-function-paren": ["error", "never"],
"camelcase": [0]
},
"settings": {
"react": {
"version": "detect"
}
}
}
\ No newline at end of file
......@@ -56,7 +56,7 @@ function ReloadSnack() {
>
<SnackbarContent
style={{backgroundColor: amber[700]}}
message={<span>There is a new NOMAD version. Please press your browser's reload (or even shift+reload) button.</span>}
message={<span>There is a new NOMAD version. Please press your browser&apos;s reload (or even shift+reload) button.</span>}
/>
</Snackbar>
}
......
......@@ -39,7 +39,7 @@ class DownloadButton extends React.Component {
handleClick(event) {
event.stopPropagation()
this.setState({ anchorEl: event.currentTarget });
this.setState({ anchorEl: event.currentTarget })
}
async handleSelect(choice) {
......
......@@ -30,7 +30,7 @@ class FAQ extends React.Component {
### How can I be sure that my data will be cited properly?
Sharing means a change of culture. Making data open access is comparable to a
Sharing means a change of culture. Making data open access is comparable to a
publication where references to other work are common practice ever since.
Likewise, using someone's data requires proper citation. We recommend the uploader
to provide references to their data (publications, websites) and the users to
......@@ -43,7 +43,7 @@ class FAQ extends React.Component {
associated with your data might not change right away, but it will be updated
eventually.
### I'd like to install NOMAD on my local computers to be only used by my group
### I'd like to install NOMAD on my local computers to be only used by my group
Local NOMAD deployments are not actively supported at the moment. However, all
[NOMAD software](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-FAIR) is
......
export default function ReloadSnack() {
return <Snackbar
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left',
}}
open
message={<span id="message-id">There is a new version. Please press your browsers Reload (or even Shift+Reload) button.</span>}
/>
}
\ No newline at end of file
......@@ -322,6 +322,8 @@ class Api {
}))
.catch(handleApiError)
.then(response => {
/* global Blob */
/* eslint no-undef: "error" */
if (response.data instanceof Blob) {
if (response.data.type.endsWith('empty')) {
return {
......@@ -397,7 +399,9 @@ class Api {
// this helps to keep consistent values, e.g. in the metadata search view
if (response.statistics) {
const empty = {}
Object.keys(response.statistics.total.all).forEach(metric => empty[metric] = 0)
Object.keys(response.statistics.total.all).forEach(metric => {
empty[metric] = 0
})
Object.keys(response.statistics)
.filter(key => !['total', 'authors', 'atoms'].includes(key))
.forEach(key => {
......
......@@ -5,7 +5,6 @@ import { Quantity } from '../search/QuantityHistogram'
import SearchContext from '../search/SearchContext'
import { withApi } from '../api'
class DFTSearchAggregations extends React.Component {
static propTypes = {
info: PropTypes.object
......
......@@ -7,6 +7,8 @@ import EMSEntryOverview from './ems/EMSEntryOverview'
import EMSEntryCards from './ems/EMSEntryCards'
import DFTSearchByPropertyAggregations from './dft/DFTSearchByPropertyAggregations'
/* eslint-disable react/display-name */
export const domains = ({
dft: {
name: 'DFT',
......
......@@ -22,7 +22,6 @@ learn more about NOMAD's archive format [here](/metainfo).
`
class MetainfoDialogUnstyled extends React.PureComponent {
static propTypes = {
classes: PropTypes.object.isRequired,
history: PropTypes.object.isRequired,
......
......@@ -209,8 +209,8 @@ class RawFiles extends React.Component {
downloadUrl = `raw/calc/${uploadId}/${calcId}/*?strip=true`
} else if (selectedFiles.length > 0) {
// use a prefix to shorten the url
const prefix = selectedFiles[0].substring(0, selectedFiles[0].lastIndexOf("/"))
const files = selectedFiles.map(path => path.substring(path.lastIndexOf("/") + 1)).join(',')
const prefix = selectedFiles[0].substring(0, selectedFiles[0].lastIndexOf('/'))
const files = selectedFiles.map(path => path.substring(path.lastIndexOf('/') + 1)).join(',')
downloadUrl = `raw/${uploadId}?files=${encodeURIComponent(files)}&prefix=${prefix}&strip=true`
}
......
......@@ -51,7 +51,7 @@ function getSuggestionValue(suggestion) {
const styles = theme => ({
container: {
position: 'relative',
position: 'relative'
},
suggestionsContainerOpen: {
position: 'absolute',
......
......@@ -161,7 +161,8 @@ export class EntryListUnstyled extends React.Component {
}
}
componentWillUpdate(prevProps) {
// TODO was this really intentional
UNSAFE_componentWillUpdate(prevProps) {
if (prevProps.data !== this.props.data) {
this.setState({selected: []})
}
......
......@@ -35,7 +35,7 @@ const _mapping = {
'oscillator_strengths': 'Oscillator strengths',
'transition_dipole_moments': 'Transition dipole moments'}
function map_key (name) {
function mapKey(name) {
if (name in _mapping) {
return _mapping[name]
}
......@@ -102,7 +102,7 @@ class QuantityHistogramUnstyled extends React.Component {
const data = Object.keys(this.props.data)
.map(key => ({
name: map_key(key),
name: mapKey(key),
value: this.props.data[key][this.props.metric]
}))
......@@ -247,7 +247,6 @@ class QuantityHistogramUnstyled extends React.Component {
export const QuantityHistogram = withStyles(QuantityHistogramUnstyled.styles)(QuantityHistogramUnstyled)
class QuantityUnstyled extends React.Component {
static propTypes = {
classes: PropTypes.object.isRequired,
......
import React from 'react'
import PropTypes from 'prop-types'
import { withStyles } from '@material-ui/core/styles'
/* eslint-disable-next-line */
import { domains } from '../domains' // TODO this causes a weird import bug
import ChipInput from 'material-ui-chip-input'
import Autosuggest from 'react-autosuggest'
......
......@@ -98,7 +98,7 @@ class UploadsHistogramUnstyled extends React.Component {
}
]
timeInterval = Object.assign({}, ...this.intervals.map(e => ( {[e.value]: e.number})))
timeInterval = Object.assign({}, ...this.intervals.map(e => ({[e.value]: e.number})))
componentDidMount() {
const from_time = new Date(this.startDate).getTime()
......@@ -120,9 +120,7 @@ class UploadsHistogramUnstyled extends React.Component {
handleIntervalChange(newInterval) {
// TODO: add a refresh button so directly updating interval is not necessary
this.state.interval = newInterval
//this.setState({interval: newInterval})
this.handleQueryChange()
this.setState({interval: newInterval}, () => this.handleQueryChange())
}
handleTimeChange(newTime, key, target) {
......@@ -136,7 +134,7 @@ class UploadsHistogramUnstyled extends React.Component {
key === 'from_time' ? this.setState({from_time: date.getTime()}) : this.setState({until_time: date.getTime()})
}
if (target === 'picker' || target === 'all') {
document.getElementById(key).value = date.toISOString().substring(0,10)
document.getElementById(key).value = date.toISOString().substring(0, 10)
}
}
......@@ -152,14 +150,14 @@ class UploadsHistogramUnstyled extends React.Component {
}
}
resolveDate (name) {
resolveDate(name) {
const date = new Date(parseInt(name, 10))
const year = date.toLocaleDateString(undefined, {year: 'numeric'})
const month = date.toLocaleDateString(undefined, {month: 'short'})
const day = date.toLocaleDateString(undefined, {day: 'numeric'})
const hour = date.toLocaleTimeString(undefined, {hour: 'numeric'})
const min = date.toLocaleTimeString(undefined, {minute: 'numeric'})
const sec= date.toLocaleTimeString(undefined, {second: 'numeric'})
const sec = date.toLocaleTimeString(undefined, {second: 'numeric'})
const intervals = {
'1y': year,
......@@ -173,7 +171,7 @@ class UploadsHistogramUnstyled extends React.Component {
return intervals[this.state.interval]
}
hover (svg, bar) {
hover(svg, bar) {
const textOffset = 25
const tooltip = svg.append('g')
......@@ -191,36 +189,36 @@ class UploadsHistogramUnstyled extends React.Component {
.attr('dy', '1.2em')
.style('text-anchor', 'start')
.attr('font-size', '12px')
//.attr('font-weight', 'bold')
// .attr('font-weight', 'bold')
bar
.on('mouseover', () => {
tooltip.style('display', null)
let { width } = text.node().getBBox()
hoverBox.attr('width', `${ width + textOffset }px`)
hoverBox.attr('width', `${width + textOffset}px`)
})
.on('mouseout', () => tooltip.style('display', 'none'))
.on('mousemove', function(d) {
let xPosition = d3.mouse(this)[0] - 15
let yPosition = d3.mouse(this)[1] - 25
tooltip.attr('transform', `translate( ${ xPosition }, ${ yPosition })`)
tooltip.attr('transform', `translate( ${xPosition}, ${yPosition})`)
tooltip.attr('data-html', 'true')
tooltip.select('text').text( new Date(d.time).toISOString() + ': ' + d.value )
tooltip.select('text').text(new Date(d.time).toISOString() + ': ' + d.value)
})
}
updateChart () {
updateChart() {
let data = []
if (! this.props.data) {
if (!this.props.data) {
return
} else {
data = Object.keys(this.props.data).map(key => ({
time: parseInt(key, 10),
name: this.resolveDate(key),
value: this.props.data[key][this.props.metric]
}))}
}))
}
data.sort((a, b) => d3.ascending(a.time, b.time))
if (data.length > 0) {
......@@ -231,10 +229,10 @@ class UploadsHistogramUnstyled extends React.Component {
const scalePower = this.state.scalePower
const width = this.container.current.offsetWidth
const height = this.props.height
const margin = Math.round(0.1*height)
const margin = Math.round(0.1 * height)
const x = scaleBand().rangeRound([margin, width]).padding(0.1)
const y = scalePow().range([height-margin, margin]).exponent(scalePower)
const y = scalePow().range([height - margin, margin]).exponent(scalePower)
const max = d3.max(data, d => d.value) || 0
x.domain(data.map(d => d.name))
......@@ -247,16 +245,16 @@ class UploadsHistogramUnstyled extends React.Component {
const xAxis = d3.axisBottom(x)
svg.select('.xaxis').remove()
svg.append('g')
.attr('transform', `translate(0,${height-margin})`)
.attr('transform', `translate(0,${height - margin})`)
.attr('class', 'xaxis')
.call(xAxis)
svg.select('.xlabel').remove()
svg.append('text')
.attr('class', 'xlabel')
.attr("x", width)
.attr("y", height-4)
.attr('dy', ".35em")
.attr('x', width)
.attr('y', height - 4)
.attr('dy', '.35em')
.attr('font-size', '12px')
.style('text-anchor', 'end')
......@@ -270,13 +268,13 @@ class UploadsHistogramUnstyled extends React.Component {
const {label, shortLabel} = this.props.metricsDefinitions[this.props.metric]
svg.select('.ylabel').remove()
svg.append('text')
.attr('class','ylabel')
.attr('class', 'ylabel')
.attr('x', 0)
.attr('y', 0)
.attr('dy', "1em")
.attr('dy', '1em')
.attr('text-anchor', 'start')
.attr('font-size', '12px')
.text(`${shortLabel ? shortLabel : label}`)
.text(`${shortLabel || label}`)
let withData = svg
.selectAll('.bar').remove().exit()
......@@ -300,9 +298,9 @@ class UploadsHistogramUnstyled extends React.Component {
svg.select('.tooltip').remove()
svg.call(this.hover, item)
}
}
render () {
render() {
return (
<div>
<Grid container justify='space-around' spacing={24}>
......@@ -327,7 +325,7 @@ class UploadsHistogramUnstyled extends React.Component {
type="date"
onChange={(event) => this.handleTimeChange(event.target.value, 'from_time', 'state')}
InputLabelProps={{
shrink: true,
shrink: true
}}
/>
</Grid>
......@@ -350,7 +348,7 @@ class UploadsHistogramUnstyled extends React.Component {
type="date"
onChange={(event) => this.handleTimeChange(event.target.value, 'until_time', 'state')}
InputLabelProps={{
shrink: true,
shrink: true
}}
/>
</Grid>
......@@ -366,7 +364,6 @@ class UploadsHistogramUnstyled extends React.Component {
export const UploadsHistogram = withStyles(UploadsHistogramUnstyled.styles)(UploadsHistogramUnstyled)
class UploadersListUnstyled extends React.Component {
static propTypes = {
classes: PropTypes.object.isRequired
}
......@@ -379,7 +376,7 @@ class UploadersListUnstyled extends React.Component {
static contextType = SearchContext.type
render () {
render() {
const {state: {usedMetric}} = this.context
return (
......@@ -407,7 +404,7 @@ class UploadsChart extends React.Component {
render() {
const {classes, metricsDefinitions, ...props} = this.props
const {state: {response, usedMetric, query, }, setQuery} = this.context
const {state: {response, usedMetric, query}, setQuery} = this.context
return (
<Grid container spacing={24}>
......
......@@ -18,7 +18,7 @@ class ConfirmDialog extends React.Component {
}
render() {
const { onConfirm, onClose, open, title, content,confirmLabel } = this.props
const { onConfirm, onClose, open, title, content, confirmLabel } = this.props
return (
<div>
<Dialog
......
......@@ -107,7 +107,8 @@ class Upload extends React.Component {
upload: PropTypes.object.isRequired,
onDoesNotExist: PropTypes.func,
open: PropTypes.bool,
history: PropTypes.object.isRequired
history: PropTypes.object.isRequired,
domain: PropTypes.object
}
static styles = theme => ({
......
......@@ -193,7 +193,7 @@ class UploadPage extends React.Component {
}
update(newPage) {
const { data: { pagination: { page, per_page }}} = this.state
const {data: {pagination: {page, per_page}}} = this.state
this.props.api.getUploads('all', newPage || page, per_page)
.then(uploads => {
this.setState({
......@@ -226,8 +226,8 @@ class UploadPage extends React.Component {
}
renderUploads(openUpload) {
const { classes } = this.props
const { data: { results, pagination: { total, per_page, page }}, uploading } = this.state
const {classes} = this.props
const {data: {results, pagination: {total, per_page, page}}, uploading} = this.state
const renderUpload = upload => <Upload
open={openUpload === upload.upload_id}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment