SU-SWS/react_paragraphs

View on GitHub
js/src/Components/Widgets/ViewFieldWidget.js

Summary

Maintainability
A
0 mins
Test Coverage
import React, {Component} from 'react';
import InputLabel from '@mui/material/InputLabel';
import FormGroup from '@mui/material/FormGroup';
import FormHelperText from '@mui/material/FormHelperText';
import Select from '@mui/material/Select';
import MenuItem from "@mui/material/MenuItem";
import TextField from "@mui/material/TextField";

export class ViewFieldWidget extends Component {

  constructor(props) {
    super(props);
    this.state = {
      target_id: this.getDefaultValue('target_id') ? this.getDefaultValue('target_id') : '_none',
      display_id: this.getDefaultValue('display_id') ? this.getDefaultValue('display_id') : '_none',
      arguments: this.getDefaultValue('arguments'),
      items_to_display: this.getDefaultValue('items_to_display'),
      advancedOpen: false
    };
  }

  getDefaultValue(column) {
    return this.props.defaultValue && this.props.defaultValue[0] ? this.props.defaultValue[0][column] : '';
  }

  valueChanged(column, newValue) {
    const newState = {...this.state};
    newState[column] = newValue;

    if (column === 'target_id' && newValue === '_none') {
      newState['target_id'] = '_none';
      newState['display_id'] = '_none';
      newState['arguments'] = '';
      newState['items_to_display'] = '';
    }

    this.setState(newState);

    // Don't change the field value if the view or the display are not selected.
    if (newState.target_id !== '_none' && newState.display_id !== '_none') {
      this.props.onFieldChange([newState]);
    }
    else {
      this.props.onFieldChange([]);
    }
  }

  getDisplayOptions(viewId) {
    if (viewId !== '_none') {
      if (typeof this.props.settings.displays[viewId] === 'object') {
        return Object.keys(this.props.settings.displays[viewId]).map(key => this.props.settings.displays[viewId][key])
      }
      return this.props.settings.displays[viewId];
    }
    return [];
  }

  render() {
    return (
      <FormGroup>
        <InputLabel htmlFor={this.props.fieldId + '-target-id'}>
          {this.props.settings.label}
        </InputLabel>

        <FormHelperText dangerouslySetInnerHTML={{__html: this.props.settings.help}}/>

        <Select
          id={this.props.fieldId + '-target-id'}
          value={this.state.target_id}
          multiple={this.props.settings.cardinality !== 1}
          onChange={e => this.valueChanged('target_id', e.target.value)}
          variant="outlined"
          required={this.props.settings.required}
          classes={{select: 'max-w-md mt-2.5'}}
        >
          {this.props.settings.required === false && this.props.settings.cardinality === 1 &&
          <MenuItem value="_none">
            -- Choose a view --
          </MenuItem>
          }

          {this.props.settings.views.map(view =>
            <MenuItem value={view.value} key={'view-' + view.value}>
              {view.label}
            </MenuItem>
          )}
        </Select>

        <div className={`p-5 mt-2.5 border border-solid border-[#ccc] ${this.state.target_id !== '_none' ?'block':'hidden'}`}>

          <InputLabel htmlFor={this.props.fieldId + '-display-id'}>
            Display
          </InputLabel>

          <Select
            id={this.props.fieldId + '-display-id'}
            value={this.state.display_id}
            multiple={this.props.settings.cardinality !== 1}
            onChange={e => this.valueChanged('display_id', e.target.value)}
            variant="outlined"
            required={this.props.settings.required}
            classes={{select: 'max-w-md mt-2.5'}}
          >
            {this.props.settings.required === false && this.props.settings.cardinality === 1 &&
            <MenuItem value="_none">
              -- Choose a display --
            </MenuItem>
            }

            {this.getDisplayOptions(this.state.target_id).map(display =>
              <MenuItem value={display.value} key={'display-' + display.value}>
                {display.label}
              </MenuItem>
            )}
          </Select>


          <div className="border-solid border border-[#ccc] p-5 mt-5">
            <a href="#"
               onClick={(e) => {
                 e.preventDefault();
                 this.setState({advancedOpen: !this.state.advancedOpen})
               }}
            >
              Advanced Options
            </a>
            <div className={this.state.advancedOpen ? 'block' : 'hidden'}>
              <div className="mt-2.5">
                <TextField
                  id={this.props.fieldId + '-arguments'}
                  label="Arguments"
                  helperText={`Separate contextual filters with a "/". Each filter may use "+" or "," for multi-value arguments. This field supports tokens.`}
                  variant="outlined"
                  defaultValue={this.state['arguments']}
                  onChange={e => this.valueChanged('arguments', e.target.value)}
                  inputProps={{maxLength: 254}}
                  fullWidth
                />
              </div>
              <div className="mt-2.5">
                <TextField
                  id={this.props.fieldId + '-num-items'}
                  label="Number of items"
                  helperText="Override the number of items to display. This also disables the pager if one is configured. Leave empty for default limit."
                  inputProps={{
                    min: 0,
                    step: 1
                  }}
                  defaultValue={this.state.items_to_display}
                  onChange={e => this.valueChanged('items_to_display', e.target.value)}
                  type='number'
                />
              </div>
            </div>
          </div>
        </div>
      </FormGroup>
    )
  }

}