1
Fork 0

The following components are migrated to apollo hooks instead of deprecated <Query> and <Mutation> components:

- AddUserRow.js
- AlbumGallery.js
- UserRow.js

LazyPhoto is migrated to functional component
This commit is contained in:
stz184 2020-11-15 01:25:21 +02:00
parent d5e21f6a5e
commit a0f7b4b135
4 changed files with 259 additions and 275 deletions

View File

@ -1,7 +1,6 @@
import { gql } from '@apollo/client'
import { gql, useMutation } from '@apollo/client'
import PropTypes from 'prop-types'
import React, { useState } from 'react'
import { Mutation } from '@apollo/client'
import { Button, Checkbox, Input, Table } from 'semantic-ui-react'
const createUserMutation = gql`
@ -28,6 +27,12 @@ const initialState = {
const AddUserRow = ({ setShow, show, onUserAdded }) => {
const [state, setState] = useState(initialState)
const [createUser, { loading }] = useMutation(createUserMutation, {
onCompleted: () => {
onUserAdded()
},
})
function updateInput(event, key) {
setState({
...state,
@ -40,68 +45,59 @@ const AddUserRow = ({ setShow, show, onUserAdded }) => {
}
return (
<Mutation
mutation={createUserMutation}
onCompleted={() => {
onUserAdded()
}}
>
{(createUser, { loading }) => (
<Table.Row>
<Table.Cell>
<Input
placeholder="Username"
value={state.username}
onChange={e => updateInput(e, 'username')}
/>
</Table.Cell>
<Table.Cell>
<Input
placeholder="/path/to/photos"
value={state.rootPath}
onChange={e => updateInput(e, 'rootPath')}
/>
</Table.Cell>
<Table.Cell>
<Checkbox
toggle
checked={state.admin}
onChange={(e, data) => {
setState({
...state,
admin: data.checked,
})
}}
/>
</Table.Cell>
<Table.Cell>
<Button.Group>
<Button negative onClick={() => setShow(false)}>
Cancel
</Button>
<Button
type="submit"
loading={loading}
disabled={loading}
positive
onClick={() => {
createUser({
variables: {
username: state.username,
rootPath: state.rootPath,
admin: state.admin,
},
})
setState(initialState)
}}
>
Add User
</Button>
</Button.Group>
</Table.Cell>
</Table.Row>
)}
</Mutation>
<Table.Row>
<Table.Cell>
<Input
placeholder="Username"
value={state.username}
onChange={e => updateInput(e, 'username')}
/>
</Table.Cell>
<Table.Cell>
<Input
placeholder="/path/to/photos"
value={state.rootPath}
onChange={e => updateInput(e, 'rootPath')}
/>
</Table.Cell>
<Table.Cell>
<Checkbox
toggle
checked={state.admin}
onChange={(e, data) => {
setState({
...state,
admin: data.checked,
})
}}
/>
</Table.Cell>
<Table.Cell>
<Button.Group>
<Button negative onClick={() => setShow(false)}>
Cancel
</Button>
<Button
type="submit"
loading={loading}
disabled={loading}
positive
onClick={() => {
createUser({
variables: {
username: state.username,
rootPath: state.rootPath,
admin: state.admin,
},
})
setState(initialState)
}}
>
Add User
</Button>
</Button.Group>
</Table.Cell>
</Table.Row>
)
}

View File

@ -1,7 +1,6 @@
import PropTypes from 'prop-types'
import React, { useState } from 'react'
import { Mutation } from '@apollo/client/react/components'
import { gql } from '@apollo/client'
import { gql, useMutation } from '@apollo/client'
import {
Button,
Checkbox,
@ -61,50 +60,47 @@ const scanUserMutation = gql`
const ChangePasswordModal = ({ onClose, user, ...props }) => {
const [passwordInput, setPasswordInput] = useState('')
const [changePassword] = useMutation(changeUserPasswordMutation, {
onCompleted: () => {
onClose && onClose()
},
})
return (
<Mutation
mutation={changeUserPasswordMutation}
onCompleted={() => {
onClose && onClose()
}}
>
{changePassword => (
<Modal {...props}>
<Modal.Header>Change password</Modal.Header>
<Modal.Content>
<p>
Change password for <b>{user.username}</b>
</p>
<Form>
<Form.Field>
<label>New password</label>
<Input
placeholder="password"
onChange={e => setPasswordInput(e.target.value)}
type="password"
/>
</Form.Field>
</Form>
</Modal.Content>
<Modal.Actions>
<Button onClick={() => onClose && onClose()}>Cancel</Button>
<Button
positive
onClick={() => {
changePassword({
variables: {
userId: user.id,
password: passwordInput,
},
})
}}
>
Change password
</Button>
</Modal.Actions>
</Modal>
)}
</Mutation>
<Modal {...props}>
<Modal.Header>Change password</Modal.Header>
<Modal.Content>
<p>
Change password for <b>{user.username}</b>
</p>
<Form>
<Form.Field>
<label>New password</label>
<Input
placeholder="password"
onChange={e => setPasswordInput(e.target.value)}
type="password"
/>
</Form.Field>
</Form>
</Modal.Content>
<Modal.Actions>
<Button onClick={() => onClose && onClose()}>Cancel</Button>
<Button
positive
onClick={() => {
changePassword({
variables: {
userId: user.id,
password: passwordInput,
},
})
}}
>
Change password
</Button>
</Modal.Actions>
</Modal>
)
}
@ -119,7 +115,7 @@ const UserRow = ({ user, refetchUsers }) => {
editing: false,
})
const [showComfirmDelete, setConfirmDelete] = useState(false)
const [showConfirmDelete, setConfirmDelete] = useState(false)
const [showChangePassword, setChangePassword] = useState(false)
function updateInput(event, key) {
@ -129,171 +125,168 @@ const UserRow = ({ user, refetchUsers }) => {
})
}
const [updateUser, { loading: updateUserLoading }] = useMutation(
updateUserMutation,
{
onCompleted: data => {
setState({
...data.updateUser,
editing: false,
})
refetchUsers()
},
}
)
const [deleteUser] = useMutation(deleteUserMutation, {
onCompleted: () => {
refetchUsers()
},
})
const [scanUser, { called: scanUserCalled }] = useMutation(scanUserMutation, {
onCompleted: () => {
refetchUsers()
},
})
if (state.editing) {
return (
<Mutation
mutation={updateUserMutation}
onCompleted={data => {
setState({
...data.updateUser,
editing: false,
})
refetchUsers()
}}
>
{(updateUser, { loading }) => (
<Table.Row>
<Table.Cell>
<Input
style={{ width: '100%' }}
placeholder={user.username}
value={state.username}
onChange={e => updateInput(e, 'username')}
/>
</Table.Cell>
<Table.Cell>
<Input
style={{ width: '100%' }}
placeholder={user.rootPath}
value={state.rootPath}
onChange={e => updateInput(e, 'rootPath')}
/>
</Table.Cell>
<Table.Cell>
<Checkbox
toggle
checked={state.admin}
onChange={(_, data) => {
setState({
...state,
admin: data.checked,
})
}}
/>
</Table.Cell>
<Table.Cell>
<Button.Group>
<Button
negative
onClick={() =>
setState({
...state.oldState,
})
}
>
Cancel
</Button>
<Button
loading={loading}
disabled={loading}
positive
onClick={() =>
updateUser({
variables: {
id: user.id,
username: state.username,
rootPath: state.rootPath,
admin: state.admin,
},
})
}
>
Save
</Button>
</Button.Group>
</Table.Cell>
</Table.Row>
)}
</Mutation>
<Table.Row>
<Table.Cell>
<Input
style={{ width: '100%' }}
placeholder={user.username}
value={state.username}
onChange={e => updateInput(e, 'username')}
/>
</Table.Cell>
<Table.Cell>
<Input
style={{ width: '100%' }}
placeholder={user.rootPath}
value={state.rootPath}
onChange={e => updateInput(e, 'rootPath')}
/>
</Table.Cell>
<Table.Cell>
<Checkbox
toggle
checked={state.admin}
onChange={(_, data) => {
setState({
...state,
admin: data.checked,
})
}}
/>
</Table.Cell>
<Table.Cell>
<Button.Group>
<Button
negative
onClick={() =>
setState({
...state.oldState,
})
}
>
Cancel
</Button>
<Button
loading={updateUserLoading}
disabled={updateUserLoading}
positive
onClick={() =>
updateUser({
variables: {
id: user.id,
username: state.username,
rootPath: state.rootPath,
admin: state.admin,
},
})
}
>
Save
</Button>
</Button.Group>
</Table.Cell>
</Table.Row>
)
}
return (
<Mutation
mutation={deleteUserMutation}
onCompleted={() => {
refetchUsers()
}}
>
{deleteUser => (
<Table.Row>
<Table.Cell>{user.username}</Table.Cell>
<Table.Cell>{user.rootPath}</Table.Cell>
<Table.Cell>
{user.admin ? <Icon name="checkmark" size="large" /> : null}
</Table.Cell>
<Table.Cell>
<Button.Group>
<Button
onClick={() => {
setState({ ...state, editing: true, oldState: state })
}}
>
<Icon name="edit" />
Edit
</Button>
<Mutation mutation={scanUserMutation}>
{(scanUser, { called }) => (
<Button
disabled={called}
onClick={() => scanUser({ variables: { userId: user.id } })}
>
<Icon name="sync" />
Scan
</Button>
)}
</Mutation>
<Button onClick={() => setChangePassword(true)}>
<Icon name="key" />
Change password
</Button>
<ChangePasswordModal
user={user}
open={showChangePassword}
onClose={() => setChangePassword(false)}
/>
<Table.Row>
<Table.Cell>{user.username}</Table.Cell>
<Table.Cell>{user.rootPath}</Table.Cell>
<Table.Cell>
{user.admin ? <Icon name="checkmark" size="large" /> : null}
</Table.Cell>
<Table.Cell>
<Button.Group>
<Button
onClick={() => {
setState({ ...state, editing: true, oldState: state })
}}
>
<Icon name="edit" />
Edit
</Button>
<Button
disabled={scanUserCalled}
onClick={() => scanUser({ variables: { userId: user.id } })}
>
<Icon name="sync" />
Scan
</Button>
<Button onClick={() => setChangePassword(true)}>
<Icon name="key" />
Change password
</Button>
<ChangePasswordModal
user={user}
open={showChangePassword}
onClose={() => setChangePassword(false)}
/>
<Button
negative
onClick={() => {
setConfirmDelete(true)
}}
>
<Icon name="delete" />
Delete
</Button>
<Modal open={showConfirmDelete}>
<Modal.Header>Delete user</Modal.Header>
<Modal.Content>
<p>
{`Are you sure, you want to delete `}
<b>{user.username}</b>?
</p>
<p>{`This action cannot be undone`}</p>
</Modal.Content>
<Modal.Actions>
<Button onClick={() => setConfirmDelete(false)}>Cancel</Button>
<Button
negative
onClick={() => {
setConfirmDelete(true)
setConfirmDelete(false)
deleteUser({
variables: {
id: user.id,
},
})
}}
>
<Icon name="delete" />
Delete
Delete {user.username}
</Button>
<Modal open={showComfirmDelete}>
<Modal.Header>Delete user</Modal.Header>
<Modal.Content>
<p>
{`Are you sure, you want to delete `}
<b>{user.username}</b>?
</p>
<p>{`This action cannot be undone`}</p>
</Modal.Content>
<Modal.Actions>
<Button onClick={() => setConfirmDelete(false)}>
Cancel
</Button>
<Button
negative
onClick={() => {
setConfirmDelete(false)
deleteUser({
variables: {
id: user.id,
},
})
}}
>
Delete {user.username}
</Button>
</Modal.Actions>
</Modal>
</Button.Group>
</Table.Cell>
</Table.Row>
)}
</Mutation>
</Modal.Actions>
</Modal>
</Button.Group>
</Table.Cell>
</Table.Row>
)
}

View File

@ -56,9 +56,7 @@ const AlbumGallery = ({
useEffect(() => {
const updateImageState = event => {
if (event.state.imageState) {
setImageState(event.state.imageState)
}
setImageState(event.state.imageState)
}
window.addEventListener('popstate', updateImageState)

View File

@ -49,19 +49,16 @@ const PhotoImg = photoProps => {
)
}
class LazyPhoto extends React.Component {
shouldComponentUpdate(nextProps) {
return nextProps.src != this.props.src
}
render() {
const LazyPhoto = React.memo(
props => {
return (
<LazyLoad scrollContainer="#layout-content">
<PhotoImg {...this.props} />
<PhotoImg {...props} />
</LazyLoad>
)
}
}
},
(prevProps, nextProps) => prevProps.src === nextProps.src
)
LazyPhoto.propTypes = {
src: PropTypes.string,