Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import { useQuery } from '@apollo/react-hooks';
- import {
- Button,
- Checkbox,
- Dialog,
- DialogActions,
- DialogContent,
- DialogTitle,
- FormControl,
- Grid,
- InputLabel,
- ListItemText,
- makeStyles,
- MenuItem,
- Select,
- } from '@material-ui/core';
- import Tooltip from '@material-ui/core/Tooltip';
- import ActiveIcon from '@material-ui/icons/Brightness1';
- import gql from 'graphql-tag';
- import { get } from 'lodash';
- import MuiDataTable from 'mui-datatables';
- import { func, shape, string } from 'prop-types';
- import { useEffect, useMemo, useState } from 'react';
- import { FormattedMessage, useIntl } from 'react-intl';
- import { useParams } from 'react-router-dom';
- import PropTypes from '../../helpers/propTypes';
- import { useDisclosure } from '../../utils/hooks';
- import { sortSiteSelection } from '../../utils/sites';
- import AutocompletePlaces from '../AutocompletePlacesAPI';
- import ConfirmDialog from '../Dialogs/ConfirmDialog';
- import calculateNearestSites from '../../utils/sitesUtil';
- const useStyle = makeStyles(theme => ({
- dialogTitle: {
- marginTop: theme.spacing(2),
- },
- flag: {
- height: 12,
- marginRight: theme.spacing(1),
- },
- button: {
- marginRight: theme.spacing(4),
- height: 40,
- },
- active: {
- color: '#4caf50',
- fontSize: 15,
- },
- notActive: {
- color: '#ff1259',
- fontSize: 15,
- },
- }));
- const getStudySiteChoicesQuery = gql`
- query getStudySiteChoices($studyId: ID!) {
- sites(studyId: $studyId, statuses: [ACTIVE, INACTIVE]) {
- siteId
- name
- city
- state
- address
- status
- countryCode
- country {
- code
- englishName
- flagIconUrl
- }
- coordinates {
- latitude
- longitude
- }
- }
- }
- `;
- const useStudySiteChoices = () => {
- const { studyId } = useParams();
- const { data, ...rest } = useQuery(getStudySiteChoicesQuery, {
- variables: { studyId },
- fetchPolicy: 'network-only',
- });
- return { sites: data?.sites ?? [], ...rest };
- };
- const CustomCheckbox = props => {
- const newProps = { ...props };
- newProps.color =
- newProps['data-description'] === 'row-select' ? 'secondary' : 'primary';
- const i = newProps['data-index'] === null ? 0 : newProps['data-index'];
- if (newProps.sites[i][0] === newProps.defaultsite.siteId)
- newProps.checked = true;
- return <Checkbox {...newProps} color="primary" />;
- };
- const Flag = siteCountry => {
- return (
- <Tooltip title={get(siteCountry, 'siteCountry.englishName')}>
- <img
- className={useStyle().flag}
- src={get(siteCountry, 'siteCountry.flagIconUrl')}
- alt={get(siteCountry, 'siteCountry.englishName')}
- />
- </Tooltip>
- );
- };
- const Sites = ({
- isOpen,
- onClose,
- site,
- onChange: onChangeSelectedSite = () => {},
- }) => {
- const intl = useIntl();
- const classes = useStyle();
- const { sites } = useStudySiteChoices();
- const [selectedSiteId, selectSite] = useState('');
- const { isOpen: isConfirmOpen, onToggle: onConfirmToggle } = useDisclosure();
- const [usingLocation, setLocation] = useState(null);
- const nearestSites = calculateNearestSites(usingLocation, sites);
- const selectedSite = sites.find(s => s.siteId === selectedSiteId);
- const preparedSites = useMemo(
- () =>
- sites.sort(sortSiteSelection(site)).map(elm => {
- const arr = [
- elm.siteId,
- elm.city,
- elm.state,
- elm.country,
- elm.address,
- elm.status,
- ];
- if (nearestSites.length)
- arr.push(
- nearestSites.find(s => s.closestSiteId === elm.siteId).distance,
- );
- return arr;
- }),
- [sites, nearestSites],
- );
- const onFieldChangeConfirm = () => {
- onChangeSelectedSite('siteId', selectedSiteId);
- onClose();
- };
- console.log('LOCATION', usingLocation);
- const isLocation = usingLocation !== null;
- const isDisplay = () => {
- if (usingLocation !== null) return true;
- else return false;
- };
- console.log(isDisplay());
- const DISTANCE_MEASURE = 'Km';
- const columns = useMemo(
- () => [
- 'Id',
- {
- name: intl.formatMessage({
- id: 'SitesColumn.city',
- defaultMessage: 'City',
- }),
- },
- {
- name: intl.formatMessage({
- id: 'SitesColumn.state',
- defaultMessage: 'State',
- }),
- },
- {
- name: intl.formatMessage({
- id: 'SitesColumn.country',
- defaultMessage: 'Country',
- }),
- options: {
- filter: true,
- filterList: [site.countryCode],
- filterType: 'custom',
- filterOptions: {
- logic(country, filters) {
- if (filters.length) return filters[0] !== country.code;
- return false;
- },
- display: (filterList, onChange, index, column) => (
- <MuiTableForm
- preparedSites={preparedSites}
- filterList={filterList}
- onChange={onChange}
- index={index}
- column={column}
- />
- ),
- },
- customBodyRender: value => <Flag siteCountry={value} />,
- },
- },
- {
- name: intl.formatMessage({
- id: 'SitesColumn.address',
- defaultMessage: 'Address',
- }),
- },
- {
- name: intl.formatMessage({
- id: 'SitesColumn.status',
- defaultMessage: 'Status',
- }),
- options: {
- customBodyRender: value => {
- if (value === 'ACTIVE')
- return (
- <Tooltip
- title={intl.formatMessage({
- id: 'SitesColumn.active',
- defaultMessage: 'ACTIVE',
- })}
- >
- <ActiveIcon className={classes.active} />
- </Tooltip>
- );
- else
- return (
- <Tooltip
- title={intl.formatMessage({
- id: 'SitesColumn.inactive',
- defaultMessage: 'INACTIVE',
- })}
- >
- <ActiveIcon className={classes.notActive} />
- </Tooltip>
- );
- },
- filter: true,
- filterList: ['ACTIVE'],
- },
- },
- {
- name: 'Distance',
- options: {
- display: isDisplay(),
- filter: false,
- customBodyRender: value => {
- return !value ? 'N/A' : `${value} ${DISTANCE_MEASURE}`;
- },
- },
- },
- ],
- [sites, site],
- );
- const options = useMemo(
- () => ({
- filter: true,
- filterType: 'dropdown',
- responsive: 'standard',
- tableBodyHeight: '90%',
- tableBodyWith: '100%',
- tableBodyMaxHeight: '100%',
- selectableRowsOnClick: true,
- selectableRows: 'single',
- search: false,
- viewColumns: false,
- download: false,
- print: false,
- sortOrder: {
- name: 'Distance',
- direction: 'asc',
- },
- customToolbarSelect: () => {},
- isRowSelectable: dataIndex => {
- if (
- preparedSites[dataIndex][5] === 'INACTIVE' ||
- preparedSites[dataIndex][0] === site.siteId
- ) {
- return false;
- }
- return true;
- },
- setRowProps: (row, dataIndex) => {
- if (preparedSites[dataIndex][0] === site.siteId)
- return {
- style: { backgroundColor: 'rgba(0, 168, 238, .1)' },
- };
- else if (preparedSites[dataIndex][5] === 'INACTIVE')
- return {
- style: {
- opacity: '.5',
- },
- };
- return '';
- },
- setFilterChipProps: () => {
- return {
- color: 'primary',
- variant: 'outlined',
- };
- },
- onRowSelectionChange: rowsSelectedData => {
- const id = preparedSites[rowsSelectedData[0].dataIndex][0];
- const status = preparedSites[rowsSelectedData[0].dataIndex][5];
- if (status === 'ACTIVE') selectSite(id);
- },
- }),
- [sites, site],
- );
- return (
- <>
- <Dialog open={isOpen} fullWidth maxWidth="md">
- <DialogTitle className={classes.dialogTitle}>
- <FormattedMessage
- id="Candidate.selectClinicTitle"
- defaultMessage="Select a clinic"
- />
- <br />
- <FormattedMessage
- id="Candidate.currentSite"
- defaultMessage="Current site: "
- />
- {site.name} {site.city}
- </DialogTitle>
- <DialogContent>
- <AutocompletePlaces onSelect={setLocation} />
- <MuiDataTable
- data={preparedSites}
- columns={columns}
- options={options}
- components={{
- Checkbox: props => (
- <CustomCheckbox
- {...{ ...props, defaultsite: site, sites: preparedSites }}
- />
- ),
- }}
- />
- </DialogContent>
- <DialogActions>
- <Grid
- container
- direction="row"
- justify="flex-end"
- alignItems="center"
- >
- {' '}
- <Grid item>
- <Button
- color="primary"
- variant="outlined"
- onClick={onClose}
- className={classes.button}
- >
- <FormattedMessage id="Candidate.close" defaultMessage="Close" />
- </Button>
- </Grid>
- <Grid item>
- <Button
- color="primary"
- variant="contained"
- disabled={!selectedSite}
- onClick={onConfirmToggle}
- className={classes.button}
- >
- <FormattedMessage
- id="Candidate.saveClinic"
- defaultMessage="Save clinic selection"
- />
- </Button>
- </Grid>
- </Grid>
- </DialogActions>
- </Dialog>
- <ConfirmDialog
- open={isConfirmOpen}
- title={intl.formatMessage({
- id: 'Candidate.confirmChangeTitle',
- defaultMessage: 'Confirm the change',
- })}
- content={intl.formatMessage(
- {
- id: 'Candidate.confirmChangeMessage',
- defaultMessage: 'Change from {oldValue} to {newValue}?',
- },
- {
- oldValue: `${site.name} ${site.city} ${site.state}`,
- newValue: `${selectedSite?.name} ${selectedSite?.city} ${selectedSite?.state}`,
- },
- )}
- close={onConfirmToggle}
- confirm={onFieldChangeConfirm}
- />
- </>
- );
- };
- const MuiTableForm = ({
- preparedSites,
- filterList,
- onChange,
- index,
- column,
- }) => {
- // Eslint saying .reduce has a missing proptypes seems a bug
- // eslint-disable-next-line react/prop-types
- const optionValues = preparedSites.reduce((acc, val) => {
- const exists = acc.find(country => country.code === val[3].code);
- if (!exists) acc.push(val[3]);
- return acc;
- }, []);
- return (
- <FormControl>
- <InputLabel htmlFor="select-multiple-chip">Country</InputLabel>
- <Select
- value={filterList[index]}
- renderValue={selected => selected.join(' ')}
- onChange={event => {
- onChange([event.target.value], index, column);
- }}
- >
- {optionValues.map(item => (
- <MenuItem key={item.code} value={item.code}>
- <Flag siteCountry={item} />
- <ListItemText primary={item.code} />
- </MenuItem>
- ))}
- </Select>
- </FormControl>
- );
- };
- Sites.propTypes = {
- isOpen: PropTypes.bool,
- onClose: func,
- site: shape({ id: string, name: string, siteId: string }).isRequired,
- onChange: func,
- };
- MuiTableForm.propTypes = {
- onChange: func,
- preparedSites: PropTypes.shape({}).isRequired,
- filterList: PropTypes.arrayOf(),
- index: PropTypes.number,
- column: PropTypes.shape(),
- };
- export default Sites;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement