1
Fork 0

Add prop types and fix eslint issues

This commit is contained in:
viktorstrate 2019-08-16 14:02:01 +02:00
parent c3ccb93380
commit 6d998a392f
24 changed files with 163 additions and 20 deletions

View File

@ -3,6 +3,7 @@
"es6": true, "es6": true,
"node": true "node": true
}, },
"extends": "eslint:recommended",
"globals": { "globals": {
"Atomics": "readonly", "Atomics": "readonly",
"SharedArrayBuffer": "readonly" "SharedArrayBuffer": "readonly"
@ -11,6 +12,8 @@
"ecmaVersion": 2018, "ecmaVersion": 2018,
"sourceType": "module" "sourceType": "module"
}, },
"rules": {}, "rules": {
"no-unused-vars": "off"
},
"parser": "babel-eslint" "parser": "babel-eslint"
} }

View File

@ -100,6 +100,7 @@ const Mutation = {
} }
} }
// eslint-disable-next-line require-atomic-updates
args.id = generateID() args.id = generateID()
return neo4jgraphql(root, args, ctx, info) return neo4jgraphql(root, args, ctx, info)

View File

@ -5,7 +5,9 @@ import config from '../config'
import { isRawImage, getImageCachePath } from '../scanner/utils' import { isRawImage, getImageCachePath } from '../scanner/utils'
import { getUserFromToken, getTokenFromBearer } from '../token' import { getUserFromToken, getTokenFromBearer } from '../token'
async function sendImage({ imagePath, photo, res }) { async function sendImage({ photo, res, id, albumId, image, scanner }) {
let imagePath = path.resolve(getImageCachePath(id, albumId), image)
if (!(await fs.exists(imagePath))) { if (!(await fs.exists(imagePath))) {
if (image == 'thumbnail.jpg') { if (image == 'thumbnail.jpg') {
console.log('Thumbnail not found, generating', photo.path) console.log('Thumbnail not found, generating', photo.path)
@ -73,9 +75,7 @@ function loadImageRoutes({ app, driver, scanner }) {
session.close() session.close()
let imagePath = path.resolve(getImageCachePath(id, albumId), image) sendImage({ photo, res, id, albumId, image, scanner })
sendImage({ imagePath, photo, res })
}) })
// app.use('/share/:token/:image', async (req, res) => { // app.use('/share/:token/:image', async (req, res) => {

View File

@ -18,7 +18,7 @@ async function addExifTags({ session, photo }) {
const rawTags = await exiftool.read(photo.path) const rawTags = await exiftool.read(photo.path)
let iso = rawTags.ISO let iso = rawTags.ISO
if (typeof iso != 'Number') { if (typeof iso != 'number') {
try { try {
iso = parseInt(iso) iso = parseInt(iso)
} catch (e) { } catch (e) {

View File

@ -6,7 +6,8 @@
"extends": ["eslint:recommended", "plugin:react/recommended"], "extends": ["eslint:recommended", "plugin:react/recommended"],
"globals": { "globals": {
"Atomics": "readonly", "Atomics": "readonly",
"SharedArrayBuffer": "readonly" "SharedArrayBuffer": "readonly",
"process": "readonly"
}, },
"parserOptions": { "parserOptions": {
"ecmaFeatures": { "ecmaFeatures": {
@ -16,6 +17,8 @@
"sourceType": "module" "sourceType": "module"
}, },
"plugins": ["react"], "plugins": ["react"],
"rules": {}, "rules": {
"no-unused-vars": "off"
},
"parser": "babel-eslint" "parser": "babel-eslint"
} }

16
ui/package-lock.json generated
View File

@ -1141,6 +1141,12 @@
"integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==",
"dev": true "dev": true
}, },
"@types/prop-types": {
"version": "15.7.1",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.1.tgz",
"integrity": "sha512-CFzn9idOEpHrgdw8JsoTkaDDyRWk1jrzIV8djzcgpq0y9tG4B4lFT+Nxh52DVpDXV+n4+NPNv7M1Dj5uMp6XFg==",
"dev": true
},
"@types/q": { "@types/q": {
"version": "1.5.2", "version": "1.5.2",
"resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.2.tgz", "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.2.tgz",
@ -7308,6 +7314,16 @@
"tiny-warning": "^1.0.0" "tiny-warning": "^1.0.0"
} }
}, },
"react-router-prop-types": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/react-router-prop-types/-/react-router-prop-types-1.0.4.tgz",
"integrity": "sha512-tXDQe0pnBTXjFivBa69hYibtgI3hz+Q/VmhMT7vIzYVPv574dd+lIuBIWOBH9dZkHeSuD6iur6zkmss3QVTeew==",
"dev": true,
"requires": {
"@types/prop-types": "^15.5.3",
"prop-types": "^15.6.1"
}
},
"react-spring": { "react-spring": {
"version": "8.0.27", "version": "8.0.27",
"resolved": "https://registry.npmjs.org/react-spring/-/react-spring-8.0.27.tgz", "resolved": "https://registry.npmjs.org/react-spring/-/react-spring-8.0.27.tgz",

View File

@ -44,7 +44,8 @@
"eslint-plugin-react": "^7.14.3", "eslint-plugin-react": "^7.14.3",
"husky": "^3.0.2", "husky": "^3.0.2",
"isarray": "^2.0.5", "isarray": "^2.0.5",
"lint-staged": "^9.2.1" "lint-staged": "^9.2.1",
"react-router-prop-types": "^1.0.4"
}, },
"husky": { "husky": {
"hooks": { "hooks": {

View File

@ -1,4 +1,5 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types'
import { Route, Redirect } from 'react-router-dom' import { Route, Redirect } from 'react-router-dom'
import gql from 'graphql-tag' import gql from 'graphql-tag'
import { Query } from 'react-apollo' import { Query } from 'react-apollo'
@ -11,7 +12,7 @@ const adminQuery = gql`
} }
` `
const AuthorizedRoute = ({ component: Component, admin, ...props }) => { const AuthorizedRoute = ({ component: Component, admin = false, ...props }) => {
const token = localStorage.getItem('token') const token = localStorage.getItem('token')
let unauthorizedRedirect = null let unauthorizedRedirect = null
@ -50,4 +51,9 @@ const AuthorizedRoute = ({ component: Component, admin, ...props }) => {
) )
} }
AuthorizedRoute.propTypes = {
component: PropTypes.element.isRequired,
admin: PropTypes.bool,
}
export default AuthorizedRoute export default AuthorizedRoute

View File

@ -1,4 +1,5 @@
import React, { Component } from 'react' import React, { Component } from 'react'
import PropTypes from 'prop-types'
import styled from 'styled-components' import styled from 'styled-components'
import { NavLink } from 'react-router-dom' import { NavLink } from 'react-router-dom'
import { Icon } from 'semantic-ui-react' import { Icon } from 'semantic-ui-react'
@ -65,6 +66,10 @@ const SideButton = props => {
) )
} }
SideButton.propTypes = {
children: PropTypes.element,
}
const SideButtonLabel = styled.div` const SideButtonLabel = styled.div`
font-size: 16px; font-size: 16px;
` `
@ -123,4 +128,8 @@ class Layout extends Component {
} }
} }
Layout.propTypes = {
children: PropTypes.element.isRequired,
}
export default Layout export default Layout

View File

@ -1,4 +1,5 @@
import React, { Component } from 'react' import React, { Component } from 'react'
import PropTypes from 'prop-types'
import styled from 'styled-components' import styled from 'styled-components'
import { Message, Progress } from 'semantic-ui-react' import { Message, Progress } from 'semantic-ui-react'
import gql from 'graphql-tag' import gql from 'graphql-tag'
@ -22,7 +23,7 @@ const Container = styled.div`
width: 500px; width: 500px;
` `
const MessageProgress = ({ header, content, percent, ...props }) => { const MessageProgress = ({ header, content, percent = 0, ...props }) => {
const StyledProgress = styled(Progress)` const StyledProgress = styled(Progress)`
position: absolute !important; position: absolute !important;
bottom: 0; bottom: 0;
@ -46,6 +47,12 @@ const MessageProgress = ({ header, content, percent, ...props }) => {
) )
} }
MessageProgress.propTypes = {
header: PropTypes.string,
content: PropTypes.element,
percent: PropTypes.number,
}
class Messages extends Component { class Messages extends Component {
constructor(props) { constructor(props) {
super(props) super(props)

View File

@ -1,14 +1,13 @@
import React, { Component } from 'react' import React, { Component } from 'react'
import ReactRouterPropTypes from 'react-router-prop-types'
import gql from 'graphql-tag' import gql from 'graphql-tag'
import { Query } from 'react-apollo' import { Query } from 'react-apollo'
import Layout from '../../Layout' import Layout from '../../Layout'
import PhotoSidebar from '../../components/sidebar/PhotoSidebar'
import PhotoGallery, { import PhotoGallery, {
presentIndexFromHash, presentIndexFromHash,
} from '../../components/photoGallery/PhotoGallery' } from '../../components/photoGallery/PhotoGallery'
import AlbumGallery from '../AllAlbumsPage/AlbumGallery' import AlbumGallery from '../AllAlbumsPage/AlbumGallery'
import AlbumTitle from '../../components/AlbumTitle' import AlbumTitle from '../../components/AlbumTitle'
import { SidebarConsumer } from '../../components/sidebar/Sidebar'
const albumQuery = gql` const albumQuery = gql`
query albumQuery($id: ID!) { query albumQuery($id: ID!) {
@ -162,4 +161,8 @@ class AlbumPage extends Component {
} }
} }
AlbumPage.propTypes = {
...ReactRouterPropTypes,
}
export default AlbumPage export default AlbumPage

View File

@ -1,8 +1,8 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types'
import styled from 'styled-components' import styled from 'styled-components'
import { Link } from 'react-router-dom' import { Link } from 'react-router-dom'
import ProtectedImage from '../../components/photoGallery/ProtectedImage' import ProtectedImage from '../../components/photoGallery/ProtectedImage'
import { Icon } from 'semantic-ui-react'
const AlbumBoxLink = styled(Link)` const AlbumBoxLink = styled(Link)`
width: 240px; width: 240px;
@ -37,6 +37,10 @@ const AlbumBoxImage = ({ src, ...props }) => {
return <Placeholder /> return <Placeholder />
} }
AlbumBoxImage.propTypes = {
src: PropTypes.string.isRequired,
}
export const AlbumBox = ({ album, ...props }) => { export const AlbumBox = ({ album, ...props }) => {
if (!album) { if (!album) {
return ( return (
@ -64,3 +68,7 @@ export const AlbumBox = ({ album, ...props }) => {
</AlbumBoxLink> </AlbumBoxLink>
) )
} }
AlbumBox.propTypes = {
album: PropTypes.object.isRequired,
}

View File

@ -1,4 +1,5 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types'
import styled from 'styled-components' import styled from 'styled-components'
import { Loader } from 'semantic-ui-react' import { Loader } from 'semantic-ui-react'
import { AlbumBox } from './AlbumBox' import { AlbumBox } from './AlbumBox'
@ -31,4 +32,10 @@ const AlbumGallery = ({ loading, error, albums }) => {
) )
} }
AlbumGallery.propTypes = {
loading: PropTypes.bool.isRequired,
error: PropTypes.object,
albums: PropTypes.array,
}
export default AlbumGallery export default AlbumGallery

View File

@ -1,4 +1,5 @@
import React, { useState } from 'react' import React, { useState } from 'react'
import PropTypes from 'prop-types'
import { Mutation } from 'react-apollo' import { Mutation } from 'react-apollo'
import { Table, Button, Input, Checkbox } from 'semantic-ui-react' import { Table, Button, Input, Checkbox } from 'semantic-ui-react'
import gql from 'graphql-tag' import gql from 'graphql-tag'
@ -101,4 +102,10 @@ const AddUserRow = ({ setShow, show, onUserAdded }) => {
) )
} }
AddUserRow.propTypes = {
setShow: PropTypes.func.isRequired,
show: PropTypes.bool.isRequired,
onUserAdded: PropTypes.func.isRequired,
}
export default AddUserRow export default AddUserRow

View File

@ -1,4 +1,5 @@
import React, { useState } from 'react' import React, { useState } from 'react'
import PropTypes from 'prop-types'
import { Mutation } from 'react-apollo' import { Mutation } from 'react-apollo'
import { import {
Table, Table,
@ -57,7 +58,7 @@ const ChangePasswordModal = ({ onClose, user, ...props }) => {
<Mutation <Mutation
mutation={changeUserPasswordMutation} mutation={changeUserPasswordMutation}
onCompleted={() => { onCompleted={() => {
onClose() onClose && onClose()
}} }}
> >
{(changePassword, { data }) => ( {(changePassword, { data }) => (
@ -79,7 +80,7 @@ const ChangePasswordModal = ({ onClose, user, ...props }) => {
</Form> </Form>
</Modal.Content> </Modal.Content>
<Modal.Actions> <Modal.Actions>
<Button onClick={() => onClose()}>Cancel</Button> <Button onClick={() => onClose && onClose()}>Cancel</Button>
<Button <Button
positive positive
onClick={() => { onClick={() => {
@ -100,6 +101,11 @@ const ChangePasswordModal = ({ onClose, user, ...props }) => {
) )
} }
ChangePasswordModal.propTypes = {
onClose: PropTypes.func,
user: PropTypes.object.isRequired,
}
const UserRow = ({ user, refetchUsers }) => { const UserRow = ({ user, refetchUsers }) => {
const [state, setState] = useState({ const [state, setState] = useState({
...user, ...user,
@ -271,4 +277,9 @@ const UserRow = ({ user, refetchUsers }) => {
) )
} }
UserRow.propTypes = {
user: PropTypes.object.isRequired,
refetchUsers: PropTypes.func.isRequired,
}
export default UserRow export default UserRow

View File

@ -1,4 +1,5 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types'
import { Link } from 'react-router-dom' import { Link } from 'react-router-dom'
import styled from 'styled-components' import styled from 'styled-components'
import { Icon } from 'semantic-ui-react' import { Icon } from 'semantic-ui-react'
@ -57,4 +58,9 @@ const AlbumTitle = ({ album, disableLink = false }) => {
) )
} }
AlbumTitle.propTypes = {
album: PropTypes.object.isRequired,
disableLink: PropTypes.bool,
}
export default AlbumTitle export default AlbumTitle

View File

@ -1,4 +1,5 @@
import React, { useState, useEffect } from 'react' import React, { useState, useEffect } from 'react'
import PropTypes from 'prop-types'
import styled from 'styled-components' import styled from 'styled-components'
import { useSpring, animated } from 'react-spring' import { useSpring, animated } from 'react-spring'
import LazyLoad from 'react-lazyload' import LazyLoad from 'react-lazyload'
@ -48,6 +49,10 @@ class LazyPhoto extends React.Component {
} }
} }
LazyPhoto.propTypes = {
src: PropTypes.string,
}
const PhotoOverlay = styled.div` const PhotoOverlay = styled.div`
width: 100%; width: 100%;
height: 100%; height: 100%;
@ -122,3 +127,12 @@ export const Photo = ({
</PhotoOverlay> </PhotoOverlay>
</PhotoContainer> </PhotoContainer>
) )
Photo.propTypes = {
photo: PropTypes.object.isRequired,
onSelectImage: PropTypes.func,
minWidth: PropTypes.number.isRequired,
index: PropTypes.number.isRequired,
active: PropTypes.bool.isRequired,
setPresenting: PropTypes.func.isRequired,
}

View File

@ -1,4 +1,5 @@
import React, { useState } from 'react' import React, { useState } from 'react'
import PropTypes from 'prop-types'
import styled, { createGlobalStyle } from 'styled-components' import styled, { createGlobalStyle } from 'styled-components'
import { Query } from 'react-apollo' import { Query } from 'react-apollo'
import gql from 'graphql-tag' import gql from 'graphql-tag'
@ -90,4 +91,11 @@ const PresentView = ({
) )
} }
PresentView.propTypes = {
image: PropTypes.string.isRequired,
presenting: PropTypes.bool,
thumbnail: PropTypes.string.isRequired,
imageLoaded: PropTypes.func.isRequired,
}
export default PresentView export default PresentView

View File

@ -1,4 +1,5 @@
import React, { useState, useEffect } from 'react' import React from 'react'
import PropTypes from 'prop-types'
let imageCache = {} let imageCache = {}
@ -58,4 +59,8 @@ class ProtectedImage extends React.Component {
} }
} }
ProtectedImage.propTypes = {
src: PropTypes.string.isRequired,
}
export default ProtectedImage export default ProtectedImage

View File

@ -1,4 +1,5 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types'
import { Query } from 'react-apollo' import { Query } from 'react-apollo'
import gql from 'graphql-tag' import gql from 'graphql-tag'
import SidebarShare from './Sharing' import SidebarShare from './Sharing'
@ -35,4 +36,8 @@ const AlbumSidebar = ({ albumId }) => {
) )
} }
AlbumSidebar.propTypes = {
albumId: PropTypes.string.isRequired,
}
export default AlbumSidebar export default AlbumSidebar

View File

@ -1,4 +1,5 @@
import React, { Component } from 'react' import React, { Component } from 'react'
import PropTypes from 'prop-types'
import styled from 'styled-components' import styled from 'styled-components'
import { Query } from 'react-apollo' import { Query } from 'react-apollo'
import gql from 'graphql-tag' import gql from 'graphql-tag'
@ -123,4 +124,8 @@ class PhotoSidebar extends Component {
} }
} }
PhotoSidebar.propTypes = {
imageId: PropTypes.string,
}
export default PhotoSidebar export default PhotoSidebar

View File

@ -1,7 +1,8 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types'
import { Query, Mutation } from 'react-apollo' import { Query, Mutation } from 'react-apollo'
import gql from 'graphql-tag' import gql from 'graphql-tag'
import { Table, Button, Icon, Dropdown } from 'semantic-ui-react' import { Table, Button, Dropdown } from 'semantic-ui-react'
const sharePhotoQuery = gql` const sharePhotoQuery = gql`
query sidbarGetPhotoShares($id: ID!) { query sidbarGetPhotoShares($id: ID!) {
@ -172,4 +173,9 @@ const SidebarShare = ({ photo, album }) => {
) )
} }
SidebarShare.propTypes = {
photo: PropTypes.object,
album: PropTypes.object,
}
export default SidebarShare export default SidebarShare

View File

@ -1,6 +1,6 @@
import React, { createContext } from 'react' import React, { createContext } from 'react'
import PropTypes from 'prop-types'
import styled from 'styled-components' import styled from 'styled-components'
import { Route } from 'react-router-dom'
const SidebarContainer = styled.div` const SidebarContainer = styled.div`
height: 100%; height: 100%;
@ -48,4 +48,8 @@ class Sidebar extends React.Component {
} }
} }
Sidebar.propTypes = {
children: PropTypes.element,
}
export default Sidebar export default Sidebar

View File

@ -1,4 +1,5 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types'
import styled from 'styled-components' import styled from 'styled-components'
const ItemName = styled.div` const ItemName = styled.div`
@ -15,9 +16,16 @@ const ItemValue = styled.div`
display: inline-block; display: inline-block;
` `
export const SidebarItem = ({ name, value }) => ( const SidebarItem = ({ name, value }) => (
<div> <div>
<ItemName>{name}</ItemName> <ItemName>{name}</ItemName>
<ItemValue>{value}</ItemValue> <ItemValue>{value}</ItemValue>
</div> </div>
) )
SidebarItem.propTypes = {
name: PropTypes.string.isRequired,
value: PropTypes.string.isRequired,
}
export default SidebarItem