Skip to content

Instantly share code, notes, and snippets.

@saaage
Created November 18, 2019 21:10
Show Gist options
  • Save saaage/25c9170b9faebfb85a4dd732ac0c7c5a to your computer and use it in GitHub Desktop.
Save saaage/25c9170b9faebfb85a4dd732ac0c7c5a to your computer and use it in GitHub Desktop.
import React, { useState, useEffect, useRef } from 'react'
import get from 'lodash.get'
import { array, bool, func } from 'prop-types'
import Autocomplete from '@material-ui/lab/Autocomplete'
import Button from '@material-ui/core/Button'
import FormGroup from '@material-ui/core/FormGroup'
import FormLabel from '@material-ui/core/FormLabel'
import FormHelperText from '@material-ui/core/FormHelperText'
import TextField from '@material-ui/core/TextField'
import { contains, compareUsingKey, isEmpty } from 'utils'
import { Space } from 'shared/components'
import { useQuery } from 'react-apollo'
import { Container } from 'shared/components'
import CircularProgress from '@material-ui/core/CircularProgress'
import { useConceptLocations } from 'shared/hooks'
import GET_CATEGORY from 'pages/menu/graphql/queries/getCategory'
const AddSelections = ({
setSelections,
categoryId,
owner,
ignore,
batchUpdate
}) => {
const {
loading: categoryLoading,
error: categoryError,
data: categoryData
} = useQuery(GET_CATEGORY, {
variables: {
categoryId: categoryId,
conceptLocationsFilter: useConceptLocations().filter,
recursiveChildCategories: true,
recursiveElements: true
}
})
const [values, setValues] = useState([])
const clearValues = () => setValues([])
const ignoreRef = useRef(null)
useEffect(() => {
if (ignoreRef.current !== ignore) {
ignoreRef.current = ignore
clearValues()
}
})
if (categoryError) throw new Error(categoryError)
if (categoryLoading || !categoryData)
return (
<Container display="flex" justifyContent="center">
<CircularProgress />
</Container>
)
const category = get(categoryData, 'category', null)
const options = get(category, 'elements', [])
// re-render form whenever we get a new `ignore` prop
return (
<FormGroup key={ignore}>
<FormLabel>Selections</FormLabel>
<FormHelperText>
The valid selections from {category.displayName} when ordering within
the context of {owner.displayName}.
</FormHelperText>
<Space value="one-and-half" />
<Container display="flex" alignItems="center">
<Container flex="1">
<Autocomplete
disableCloseOnSelect
getOptionLabel={s => s.displayName}
multiple
onChange={(_, v) => {
batchUpdate ? setValues(v) : setSelections(v)
}}
options={options
.filter(
o =>
!contains(ignore, o.elementId, i =>
get(i, 'element.elementId')
)
)
.sort((a, b) => compareUsingKey(a, b, 'displayName'))}
renderInput={params => (
<TextField
{...params}
fullWidth
variant="outlined"
label="add selections"
/>
)}
/>
</Container>
{batchUpdate && (
<Container display="flex" alignItems="center">
<Space value="one" direction="x" />
<Button
disabled={isEmpty(values)}
onClick={() => { setSelections(values) }}
>
add
</Button>
</Container>
)}
</Container>
</FormGroup>
)
}
AddSelections.propTypes = {
// An array of selections to ignore
ignore: array,
// Function to call with current values
setSelections: func.isRequired,
// Should we add a confirm Button which calls `setSelections`?
batchUpdate: bool
}
AddSelections.defaultProps = {
ignore: []
}
export default AddSelections
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment