MetaPhase-Consulting/State-TalentMAP

View on GitHub
src/Components/AdministratorPage/ManageEntryLevel/ManageEntryLevel.jsx

Summary

Maintainability
A
2 hrs
Test Coverage
F
3%
import { useEffect, useState } from 'react';
import Picky from 'react-picky';
import FA from 'react-fontawesome';
import { useDispatch, useSelector } from 'react-redux';
import PropTypes from 'prop-types';
import { onEditModeSearch, renderSelectionList } from 'utilities';
import { entryLevelFetchData, entryLevelFiltersFetchData, saveEntryLevelSelections } from 'actions/entryLevel';
import Alert from 'Components/Alert';
import Spinner from 'Components/Spinner';
import ProfileSectionTitle from 'Components/ProfileSectionTitle/ProfileSectionTitle';
import EntryLevelCard from './EntryLevelCard';
import CheckBox from '../../CheckBox/CheckBox';

const ManageEntryLevel = () => {
  const dispatch = useDispatch();

  const userSelections = useSelector(state => state.entryLevelSelections);

  const elPositionsList = useSelector(state => state.entryLevelPositions);
  const elPositionsIsLoading = useSelector(state => state.entryLevelFetchDataLoading);
  const elPositionsHasErrored = useSelector(state => state.entryLevelFetchDataErrored);
  const elFiltersIsLoading = useSelector(state => state.entryLevelFiltersFetchDataLoading);

  const [cardsInEditMode, setCardsInEditMode] = useState([]);

  const [selectedTps, setSelectedTps] = useState(userSelections?.selectedTps || []);
  const [selectedBureaus, setSelectedBureaus] = useState(userSelections?.selectedBureaus || []);
  const [selectedOrgs, setSelectedOrgs] = useState(userSelections?.selectedOrgs || []);
  const [selectedGrades, setSelectedGrades] = useState(userSelections?.selectedGrade || []);
  const [selectedSkills, setSelectedSkills] = useState(userSelections?.selectedSkills || []);
  const [selectedJobs, setSelectedJobs] = useState(userSelections?.selectedJobs || []);
  const [selectedLanguages, setSelectedLanguages] =
    useState(userSelections?.selectedLanguage || []);
  const [overseas, setOverseas] = useState(userSelections?.overseas || false);
  const [domestic, setDomestic] = useState(userSelections?.domestic || false);
  const [clearFilters, setClearFilters] = useState(false);
  const [hasSelectedFilter, setHasSelectedFilter] = useState(false);

  const elFiltersList = useSelector(state => state.entryLevelFilters);
  const tpFilters = elFiltersList?.tpFilters;
  const bureauFilters = elFiltersList?.bureauFilters;
  const orgFilters = elFiltersList?.orgFilters;
  const gradeFilters = elFiltersList?.gradeFilters;
  const skillsFilters = elFiltersList?.skillsFilters;
  const jcFilters = elFiltersList?.jcFilters;
  const languageFilters = elFiltersList?.languageFilters;

  const isLoading = elPositionsIsLoading || elFiltersIsLoading;
  const disableSearch = cardsInEditMode.length > 0;
  const disableInput = isLoading || disableSearch;

  const getQuery = () => ({
    'el-tps': selectedTps.map(tpObject => (tpObject?.code)),
    'el-bureaus': selectedBureaus.map(bureauObject => (bureauObject?.code)),
    'el-orgs': selectedOrgs.map(orgObject => (orgObject?.code)),
    'el-grades': selectedGrades.map(gradeObject => (gradeObject?.code)),
    'el-skills': selectedSkills.map(skillObject => (skillObject?.code)),
    'el-jobs': selectedJobs.map(jobObject => (jobObject?.code)),
    'el-language': selectedLanguages.map(langObject => (langObject?.code)),
    'el-overseas': overseas,
    'el-domestic': domestic,
  });

  const resetFilters = () => {
    setSelectedTps([]);
    setSelectedBureaus([]);
    setSelectedOrgs([]);
    setSelectedGrades([]);
    setSelectedSkills([]);
    setSelectedJobs([]);
    setSelectedLanguages([]);
    setOverseas(false);
    setDomestic(false);
    setClearFilters(false);
  };

  const getCurrentInputs = () => ({
    selectedTps,
    selectedBureaus,
    selectedOrgs,
    selectedGrade: selectedGrades,
    selectedSkills,
    selectedJobs,
    selectedLanguage: selectedLanguages,
    overseas,
    domestic,
  });

  useEffect(() => {
    dispatch(entryLevelFiltersFetchData());
    dispatch(saveEntryLevelSelections(getCurrentInputs()));
  }, []);

  const fetchAndSet = () => {
    const filters = [
      selectedTps,
      selectedBureaus,
      selectedOrgs,
      selectedGrades,
      selectedSkills,
      selectedJobs,
      selectedLanguages,
      overseas,
      domestic,
    ];
    if (filters.flat().length === 2 && !filters.flat().includes(true)) {
      setClearFilters(false);
      setHasSelectedFilter(false);
    } else {
      setClearFilters(true);
      setHasSelectedFilter(true);
      dispatch(entryLevelFetchData(getQuery()));
    }
    dispatch(saveEntryLevelSelections(getCurrentInputs()));
  };

  useEffect(() => {
    fetchAndSet();
  }, [
    selectedTps,
    selectedBureaus,
    selectedOrgs,
    selectedGrades,
    selectedSkills,
    selectedJobs,
    selectedLanguages,
    overseas,
    domestic,
  ]);

  const pickyProps = {
    numberDisplayed: 2,
    multiple: true,
    includeFilter: true,
    dropdownHeight: 255,
    renderList: renderSelectionList,
    includeSelectAll: true,
  };

  const noResults = elPositionsList?.length === 0;
  const getOverlay = () => {
    let overlay;
    if (!hasSelectedFilter) {
      overlay = <Alert type="info" title="Select Filters" messages={[{ body: 'Please select at least 1 filter to search.' }]} />;
    } else if (elPositionsHasErrored) {
      overlay = <Alert type="error" title="Error loading results" messages={[{ body: 'Please try again.' }]} />;
    } else if (noResults) {
      overlay = <Alert type="info" title="No results found" messages={[{ body: 'Please broaden your search criteria and try again.' }]} />;
    } else {
      return false;
    }
    return overlay;
  };

  return (
    <div className="position-search">
      <div className="usa-grid-full position-search--header">
        <ProfileSectionTitle title="Manage Entry Level" icon="keyboard-o" className="xl-icon" />
        {elFiltersIsLoading ?
          <Spinner type="manage-el-filters" size="small" /> :
          <div className="results-search-bar pt-20">
            <div className="filterby-container">
              <div className="filterby-label">Filter by:</div>
              <div className="filterby-clear">
                {clearFilters &&
                  <button
                    className="unstyled-button"
                    onClick={resetFilters}
                    disabled={disableSearch}
                  >
                    <FA name="times" />
                    Clear Filters
                  </button>
                }
              </div>
            </div>
            <div className="usa-width-one-whole position-search--filters--el results-dropdown">
              <div className="filter-div">
                <div className="label">TP:</div>
                <Picky
                  {...pickyProps}
                  placeholder="Select TP(s)"
                  value={selectedTps}
                  options={tpFilters}
                  onChange={setSelectedTps}
                  valueKey="code"
                  labelKey="description"
                  disabled={disableInput}
                />
              </div>
              <div className="filter-div">
                <div className="label">Bureau:</div>
                <Picky
                  {...pickyProps}
                  placeholder="Select Bureau(s)"
                  value={selectedBureaus}
                  options={bureauFilters}
                  onChange={setSelectedBureaus}
                  valueKey="code"
                  labelKey="description"
                  disabled={disableInput}
                />
              </div>
              <div className="filter-div">
                <div className="label">Organization:</div>
                <Picky
                  {...pickyProps}
                  placeholder="Select Organization(s)"
                  value={selectedOrgs}
                  options={orgFilters}
                  onChange={setSelectedOrgs}
                  valueKey="code"
                  labelKey="description"
                  disabled={disableInput}
                />
              </div>
              <div className="filter-div">
                <div className="label">Grade:</div>
                <Picky
                  {...pickyProps}
                  placeholder="Select Grade(s)"
                  value={selectedGrades}
                  options={gradeFilters}
                  onChange={setSelectedGrades}
                  valueKey="code"
                  labelKey="description"
                  disabled={disableInput}
                />
              </div>
              <div className="filter-div">
                <div className="label">Skill Code:</div>
                <Picky
                  {...pickyProps}
                  placeholder="Select Skill(s)"
                  value={selectedSkills}
                  options={skillsFilters}
                  onChange={setSelectedSkills}
                  valueKey="code"
                  labelKey="custom_description"
                  disabled={disableInput}
                />
              </div>
              <div className="filter-div">
                <div className="label">Job Categories:</div>
                <Picky
                  {...pickyProps}
                  placeholder="Select Job Categories(s)"
                  value={selectedJobs}
                  options={jcFilters}
                  onChange={setSelectedJobs}
                  valueKey="code"
                  labelKey="description"
                  disabled={disableInput}
                />
              </div>
              <div className="filter-div">
                <div className="label">Languages:</div>
                <Picky
                  {...pickyProps}
                  placeholder="Select Language(s)"
                  value={selectedLanguages}
                  options={languageFilters}
                  onChange={setSelectedLanguages}
                  valueKey="code"
                  labelKey="description"
                  disabled={disableInput}
                />
              </div>
              <div className="filter-div">
                <CheckBox
                  id="overseas"
                  label="Overseas Only"
                  value={overseas}
                  onCheckBoxClick={e => setOverseas(e)}
                  disabled={disableInput || domestic}
                />
              </div>
              <div className="filter-div">
                <CheckBox
                  id="domestic"
                  label="Domestic Only"
                  value={domestic}
                  onCheckBoxClick={e => setDomestic(e)}
                  disabled={disableInput || overseas}
                />
              </div>
            </div>
          </div>
        }
      </div>
      {disableSearch &&
        <Alert
          type="warning"
          title={'Edit Mode (Search Disabled)'}
          customClassName="mb-10"
          messages={[{
            body: 'Discard or save your edits before searching. ' +
              'Filters and Pagination are disabled if any cards are in Edit Mode.',
          }]}
        />
      }
      {elPositionsIsLoading ?
        <Spinner type="manage-el-positions" size="small" /> :
        <div className="usa-width-one-whole position-search--results">
          {getOverlay() ||
          <div className="usa-grid-full position-list">
            {
              elPositionsList?.map((pos, i) => (
                <EntryLevelCard
                  id={i}
                  result={pos}
                  appendAdditionalFieldsToBodyPrimary={false}
                  onEditModeSearch={(editMode, id) =>
                    onEditModeSearch(editMode, id, setCardsInEditMode, cardsInEditMode)
                  }
                />
              ))}
          </div>
          }
        </div>
      }
      {disableSearch &&
        <div className="disable-react-paginate-overlay" />
      }
    </div>
  );
};


ManageEntryLevel.propTypes = {
  bureauFiltersIsLoading: PropTypes.bool,
};

ManageEntryLevel.defaultProps = {
  bureauFilters: { filters: [] },
  bureauPositions: { results: [] },
  bureauFiltersIsLoading: false,
  bureauPositionsIsLoading: false,
};

export default ManageEntryLevel;