diff --git a/src/actions/company.js b/src/actions/company.js index 2e29862ae..5acc04b7f 100644 --- a/src/actions/company.js +++ b/src/actions/company.js @@ -10,6 +10,7 @@ import { companyIndexesBoxSelectorAtPage, companyOverviewBoxSelectorByName, companyTimeAndSalaryBoxSelectorByName, + companyTimeAndSalaryStatisticsBoxSelectorByName, companyInterviewExperiencesBoxSelectorByName, companyWorkExperiencesBoxSelectorByName, } from 'selectors/companyAndJobTitle'; @@ -19,10 +20,13 @@ import { getCompanyInterviewExperiences, getCompanyWorkExperiences, queryCompaniesApi, + getCompanyTimeAndSalaryStatistics, } from 'apis/company'; export const SET_OVERVIEW = '@@COMPANY/SET_OVERVIEW'; export const SET_TIME_AND_SALARY = '@@COMPANY/SET_TIME_AND_SALARY'; +export const SET_TIME_AND_SALARY_STATISTICS = + '@@COMPANY/SET_TIME_AND_SALARY_STATISTICS'; export const SET_INTERVIEW_EXPERIENCES = '@@COMPANY/SET_INTERVIEW_EXPERIENCES'; export const SET_WORK_EXPERIENCES = '@@COMPANY/SET_WORK_EXPERIENCES'; export const SET_INDEX = '@@COMPANY/SET_INDEX'; @@ -173,7 +177,6 @@ export const queryCompanyTimeAndSalary = ({ limit, salary_work_times: data.salaryWorkTimesResult.salaryWorkTimes, salary_work_times_count: data.salaryWorkTimesResult.count, - salary_work_time_statistics: data.salary_work_time_statistics, }; dispatch(setTimeAndSalary(companyName, getFetched(timeAndSalaryData))); @@ -182,6 +185,53 @@ export const queryCompanyTimeAndSalary = ({ } }; +const setTimeAndSalaryStatistics = (companyName, box) => ({ + type: SET_TIME_AND_SALARY_STATISTICS, + companyName, + box, +}); + +export const queryCompanyTimeAndSalaryStatistics = ({ companyName }) => async ( + dispatch, + getState, +) => { + const box = companyTimeAndSalaryStatisticsBoxSelectorByName(companyName)( + getState(), + ); + if (isFetching(box) || (isFetched(box) && box.data.name === companyName)) { + return; + } + + dispatch(setTimeAndSalaryStatistics(companyName, toFetching())); + + try { + const data = await getCompanyTimeAndSalaryStatistics({ + companyName, + }); + + // Not found case + if (data == null) { + return dispatch( + setTimeAndSalaryStatistics(companyName, getFetched(data)), + ); + } + + const timeAndSalaryStatisticsData = { + name: data.name, + salary_work_time_statistics: data.salary_work_time_statistics, + }; + + dispatch( + setTimeAndSalaryStatistics( + companyName, + getFetched(timeAndSalaryStatisticsData), + ), + ); + } catch (error) { + dispatch(setTimeAndSalaryStatistics(companyName, getError(error))); + } +}; + export const queryCompanyInterviewExperiences = ({ companyName, jobTitle, diff --git a/src/actions/jobTitle.js b/src/actions/jobTitle.js index 60e6e81f2..57a2f52bc 100644 --- a/src/actions/jobTitle.js +++ b/src/actions/jobTitle.js @@ -10,12 +10,14 @@ import { jobTitleIndexesBoxSelectorAtPage, jobTitleOverviewBoxSelectorByName, jobTitleTimeAndSalaryBoxSelectorByName, + jobTitleTimeAndSalaryStatisticsBoxSelectorByName, jobTitleInterviewExperiencesBoxSelectorByName, jobTitleWorkExperiencesBoxSelectorByName, } from 'selectors/companyAndJobTitle'; import { queryJobTitleOverview as queryJobTitleOverviewApi, getJobTitleTimeAndSalary, + getJobTitleTimeAndSalaryStatistics, getJobTitleInterviewExperiences, getJobTitleWorkExperiences, queryJobTitlesApi, @@ -23,6 +25,8 @@ import { export const SET_OVERVIEW = '@@JOB_TITLE/SET_OVERVIEW'; export const SET_TIME_AND_SALARY = '@@JOB_TITLE/SET_TIME_AND_SALARY'; +export const SET_TIME_AND_SALARY_STATISTICS = + '@@JOB_TITLE/SET_TIME_AND_SALARY_STATISTICS'; export const SET_INTERVIEW_EXPERIENCES = '@@JOB_TITLE/SET_INTERVIEW_EXPERIENCES'; export const SET_WORK_EXPERIENCES = '@@JOB_TITLE/SET_WORK_EXPERIENCES'; @@ -166,7 +170,6 @@ export const queryJobTitleTimeAndSalary = ({ limit, salary_work_times: data.salaryWorkTimesResult.salaryWorkTimes, salary_work_times_count: data.salaryWorkTimesResult.count, - salary_work_time_statistics: data.salary_work_time_statistics, }; dispatch(setTimeAndSalary(jobTitle, getFetched(timeAndSalaryData))); @@ -175,6 +178,51 @@ export const queryJobTitleTimeAndSalary = ({ } }; +const setTimeAndSalaryStatistics = (jobTitle, box) => ({ + type: SET_TIME_AND_SALARY_STATISTICS, + jobTitle, + box, +}); + +export const queryJobTitleTimeAndSalaryStatistics = ({ jobTitle }) => async ( + dispatch, + getState, +) => { + const box = jobTitleTimeAndSalaryStatisticsBoxSelectorByName(jobTitle)( + getState(), + ); + if (isFetching(box) || (isFetched(box) && box.data.name === jobTitle)) { + return; + } + + dispatch(setTimeAndSalaryStatistics(jobTitle, toFetching())); + + try { + const data = await getJobTitleTimeAndSalaryStatistics({ + jobTitle, + }); + + // Not found case + if (data == null) { + return dispatch(setTimeAndSalaryStatistics(jobTitle, getFetched(data))); + } + + const timeAndSalaryStatisticsData = { + name: data.name, + salary_work_time_statistics: data.salary_work_time_statistics, + }; + + dispatch( + setTimeAndSalaryStatistics( + jobTitle, + getFetched(timeAndSalaryStatisticsData), + ), + ); + } catch (error) { + dispatch(setTimeAndSalaryStatistics(jobTitle, getError(error))); + } +}; + const setInterviewExperiences = (jobTitle, box) => ({ type: SET_INTERVIEW_EXPERIENCES, jobTitle, diff --git a/src/apis/company.js b/src/apis/company.js index 69b7c3269..754232a3f 100644 --- a/src/apis/company.js +++ b/src/apis/company.js @@ -6,6 +6,7 @@ import { getCompanyInterviewExperiencesQuery, getCompanyWorkExperiencesQuery, queryCompaniesHavingDataGql, + getCompanyTimeAndSalaryStatisticsQuery, } from 'graphql/company'; export const queryCompanyOverview = ({ @@ -35,6 +36,12 @@ export const getCompanyTimeAndSalary = ({ variables: { companyName, jobTitle, start, limit }, }).then(R.prop('company')); +export const getCompanyTimeAndSalaryStatistics = ({ companyName }) => + graphqlClient({ + query: getCompanyTimeAndSalaryStatisticsQuery, + variables: { companyName }, + }).then(R.prop('company')); + export const getCompanyInterviewExperiences = ({ companyName, jobTitle, diff --git a/src/apis/jobTitle.js b/src/apis/jobTitle.js index ebe0f5313..3113e5afb 100644 --- a/src/apis/jobTitle.js +++ b/src/apis/jobTitle.js @@ -6,6 +6,7 @@ import { getJobTitleTimeAndSalaryQuery, getJobTitleWorkExperiencesQuery, queryJobTitlesHavingDataGql, + getJobTitleTimeAndSalaryStatisticsQuery, } from 'graphql/jobTitle'; export const queryJobTitleOverview = ({ @@ -35,6 +36,12 @@ export const getJobTitleTimeAndSalary = ({ variables: { jobTitle, companyName, start, limit }, }).then(R.prop('job_title')); +export const getJobTitleTimeAndSalaryStatistics = ({ jobTitle }) => + graphqlClient({ + query: getJobTitleTimeAndSalaryStatisticsQuery, + variables: { jobTitle }, + }).then(R.prop('job_title')); + export const getJobTitleInterviewExperiences = ({ jobTitle, companyName, diff --git a/src/components/Company/CompanyInterviewExperiencesProvider.js b/src/components/Company/CompanyInterviewExperiencesProvider.js index af6d8678d..22c7ff86e 100644 --- a/src/components/Company/CompanyInterviewExperiencesProvider.js +++ b/src/components/Company/CompanyInterviewExperiencesProvider.js @@ -16,7 +16,7 @@ import { usePageName, pageNameSelector } from './usePageName'; import { searchTextFromQuerySelector, useSearchTextFromQuery, -} from 'components/CompanyAndJobTitle/useSearchbar'; +} from 'components/CompanyAndJobTitle/Searchbar'; import { pageFromQuerySelector } from 'selectors/routing/page'; const useInterviewExperiencesBox = pageName => { diff --git a/src/components/Company/CompanyTimeAndSalaryProvider.js b/src/components/Company/CompanyTimeAndSalaryProvider.js index 2e97abfb9..3d1d35d02 100644 --- a/src/components/Company/CompanyTimeAndSalaryProvider.js +++ b/src/components/Company/CompanyTimeAndSalaryProvider.js @@ -4,13 +4,17 @@ import TimeAndSalary from '../CompanyAndJobTitle/TimeAndSalary'; import usePermission from 'hooks/usePermission'; import { usePage } from 'hooks/routing/page'; import { tabType, pageType as PAGE_TYPE } from 'constants/companyJobTitle'; -import { queryCompanyTimeAndSalary } from 'actions/company'; +import { + queryCompanyTimeAndSalary, + queryCompanyTimeAndSalaryStatistics, +} from 'actions/company'; import { salaryWorkTimes as salaryWorkTimesSelector, salaryWorkTimesCount as salaryWorkTimesCountSelector, salaryWorkTimeStatistics as salaryWorkTimeStatisticsSelector, status as statusSelector, companyTimeAndSalaryBoxSelectorByName as timeAndSalaryBoxSelectorByName, + companyTimeAndSalaryStatisticsBoxSelectorByName as timeAndSalaryStatisticsBoxSelectorByName, } from 'selectors/companyAndJobTitle'; import { paramsSelector, querySelector } from 'common/routing/selectors'; import { usePageName, pageNameSelector } from './usePageName'; @@ -18,7 +22,18 @@ import { pageFromQuerySelector } from 'selectors/routing/page'; import { searchTextFromQuerySelector, useSearchTextFromQuery, -} from 'components/CompanyAndJobTitle/useSearchbar'; +} from 'components/CompanyAndJobTitle/Searchbar'; + +const useTimeAndSalaryStatisticsBox = pageName => { + const selector = useCallback( + state => { + const company = timeAndSalaryStatisticsBoxSelectorByName(pageName)(state); + return salaryWorkTimeStatisticsSelector(company); + }, + [pageName], + ); + return useSelector(selector); +}; const useTimeAndSalaryBox = pageName => { const selector = useCallback( @@ -28,7 +43,6 @@ const useTimeAndSalaryBox = pageName => { status: statusSelector(company), salaryWorkTimes: salaryWorkTimesSelector(company), salaryWorkTimesCount: salaryWorkTimesCountSelector(company), - salaryWorkTimeStatistics: salaryWorkTimeStatisticsSelector(company), }; }, [pageName], @@ -48,6 +62,14 @@ const CompanyTimeAndSalaryProvider = () => { const start = (page - 1) * PAGE_SIZE; const limit = PAGE_SIZE; + useEffect(() => { + dispatch( + queryCompanyTimeAndSalaryStatistics({ + companyName: pageName, + }), + ); + }, [dispatch, pageName]); + useEffect(() => { dispatch( queryCompanyTimeAndSalary({ @@ -64,12 +86,11 @@ const CompanyTimeAndSalaryProvider = () => { fetchPermission(); }, [pageType, pageName, fetchPermission]); - const { - status, - salaryWorkTimes, - salaryWorkTimesCount, - salaryWorkTimeStatistics, - } = useTimeAndSalaryBox(pageName); + const salaryWorkTimeStatistics = useTimeAndSalaryStatisticsBox(pageName); + + const { status, salaryWorkTimes, salaryWorkTimesCount } = useTimeAndSalaryBox( + pageName, + ); return ( { const selector = useCallback( diff --git a/src/components/CompanyAndJobTitle/InterviewExperiences/InterviewExperiences.js b/src/components/CompanyAndJobTitle/InterviewExperiences/InterviewExperiences.js index 05a96c7b5..4480250c0 100644 --- a/src/components/CompanyAndJobTitle/InterviewExperiences/InterviewExperiences.js +++ b/src/components/CompanyAndJobTitle/InterviewExperiences/InterviewExperiences.js @@ -8,7 +8,6 @@ import { Section } from 'common/base'; import EmptyView from '../EmptyView'; import ExperienceEntry from './ExperienceEntry'; -import useSearchbar from '../useSearchbar'; import { useQuery } from 'hooks/routing'; const InterviewExperiences = ({ @@ -22,22 +21,16 @@ const InterviewExperiences = ({ canView, }) => { const queryParams = useQuery(); - const { Searchbar } = useSearchbar({ - pageType, - tabType, - }); if (data.length === 0) { return (
-
); } return (
- {data.map(d => ( + + - { break; } }, - 300, + 1500, [searchText], ); @@ -105,8 +105,8 @@ Searchbar.propTypes = { placeholder: PropTypes.string, }; -const useSearchbar = ({ pageType, tabType }) => { - const [filter, setFilter] = useSearchTextFromQuery(); +const WrappedSearchbar = ({ pageType, tabType }) => { + const [, setFilter] = useSearchTextFromQuery(); const translatedPageType = pageTypeTranslation[pageType]; const translatedTabType = tabTypeTranslation[tabType]; @@ -126,45 +126,19 @@ const useSearchbar = ({ pageType, tabType }) => { const label = `搜尋${translatedSearchingPageType}:`; const placeholder = `搜該${translatedPageType}指定${translatedSearchingPageType}${translatedTabType}`; - const getSearchingValue = useCallback( - ({ company, job_title }) => { - switch (pageType) { - case pageTypes.COMPANY: - return job_title.name; - case pageTypes.JOB_TITLE: - return company.name; - default: - return null; - } - }, - [pageType], - ); - - const matchesFilter = useCallback( - data => { - const value = getSearchingValue(data); - if (!value) return false; - return value.toLowerCase().includes(filter.toLowerCase()); - }, - [filter, getSearchingValue], - ); - - const WrappedSearchbar = useCallback( - () => ( - - ), - [label, placeholder, setFilter, pageType], + return ( + ); +}; - return { - Searchbar: WrappedSearchbar, - matchesFilter, - }; +WrappedSearchbar.propTypes = { + pageType: PropTypes.string.isRequired, + tabType: PropTypes.string.isRequired, }; -export default useSearchbar; +export default WrappedSearchbar; diff --git a/src/components/CompanyAndJobTitle/TimeAndSalary/TimeAndSalary.js b/src/components/CompanyAndJobTitle/TimeAndSalary/TimeAndSalary.js index e537cdef6..11b6ac516 100644 --- a/src/components/CompanyAndJobTitle/TimeAndSalary/TimeAndSalary.js +++ b/src/components/CompanyAndJobTitle/TimeAndSalary/TimeAndSalary.js @@ -8,13 +8,10 @@ import usePermission from 'hooks/usePermission'; import EmptyView from '../EmptyView'; import WorkingHourBlock from './WorkingHourBlock'; import ViewLog from './ViewLog'; -import OvertimeSection from './OvertimeSection'; -import useSearchbar from '../useSearchbar'; import { useQuery } from 'hooks/routing'; const TimeAndSalary = ({ salaryWorkTimes, - salaryWorkTimeStatistics, pageType, pageName, tabType, @@ -27,17 +24,10 @@ const TimeAndSalary = ({ fetchPermission(); }, [fetchPermission]); - const { Searchbar } = useSearchbar({ - pageType, - tabType, - }); - const queryParams = useQuery(); return (
- - {(salaryWorkTimes.length > 0 && ( + + + - { const queryParams = useQuery(); - const { Searchbar } = useSearchbar({ - pageType, - tabType, - }); if (data.length === 0) { return (
-
); } return (
- {data.map(d => ( + + - { const selector = useCallback( diff --git a/src/components/JobTitle/JobTitleTimeAndSalaryProvider.js b/src/components/JobTitle/JobTitleTimeAndSalaryProvider.js index 1e78f0b88..947597c5d 100644 --- a/src/components/JobTitle/JobTitleTimeAndSalaryProvider.js +++ b/src/components/JobTitle/JobTitleTimeAndSalaryProvider.js @@ -4,13 +4,17 @@ import TimeAndSalary from '../CompanyAndJobTitle/TimeAndSalary'; import usePermission from 'hooks/usePermission'; import { usePage } from 'hooks/routing/page'; import { tabType, pageType as PAGE_TYPE } from 'constants/companyJobTitle'; -import { queryJobTitleTimeAndSalary } from 'actions/jobTitle'; +import { + queryJobTitleTimeAndSalary, + queryJobTitleTimeAndSalaryStatistics, +} from 'actions/jobTitle'; import { salaryWorkTimes as salaryWorkTimesSelector, salaryWorkTimesCount as salaryWorkTimesCountSelector, salaryWorkTimeStatistics as salaryWorkTimeStatisticsSelector, status as statusSelector, jobTitleTimeAndSalaryBoxSelectorByName as timeAndSalaryBoxSelectorByName, + jobTitleTimeAndSalaryStatisticsBoxSelectorByName as timeAndSalaryStatisticsBoxSelectorByName, } from 'selectors/companyAndJobTitle'; import { paramsSelector, querySelector } from 'common/routing/selectors'; import { usePageName, pageNameSelector } from './usePageName'; @@ -18,7 +22,21 @@ import { pageFromQuerySelector } from 'selectors/routing/page'; import { searchTextFromQuerySelector, useSearchTextFromQuery, -} from 'components/CompanyAndJobTitle/useSearchbar'; +} from 'components/CompanyAndJobTitle/Searchbar'; + +const useSalaryWorkTimeStatistics = pageName => { + const selector = useCallback( + state => { + const jobTitle = timeAndSalaryStatisticsBoxSelectorByName(pageName)( + state, + ); + return salaryWorkTimeStatisticsSelector(jobTitle); + }, + [pageName], + ); + + return useSelector(selector); +}; const useTimeAndSalaryBox = pageName => { const selector = useCallback( @@ -28,7 +46,6 @@ const useTimeAndSalaryBox = pageName => { status: statusSelector(jobTitle), salaryWorkTimes: salaryWorkTimesSelector(jobTitle), salaryWorkTimesCount: salaryWorkTimesCountSelector(jobTitle), - salaryWorkTimeStatistics: salaryWorkTimeStatisticsSelector(jobTitle), }; }, [pageName], @@ -48,6 +65,14 @@ const JobTitleTimeAndSalaryProvider = () => { const start = (page - 1) * PAGE_SIZE; const limit = PAGE_SIZE; + useEffect(() => { + dispatch( + queryJobTitleTimeAndSalaryStatistics({ + jobTitle: pageName, + }), + ); + }, [dispatch, pageName]); + useEffect(() => { dispatch( queryJobTitleTimeAndSalary({ @@ -64,12 +89,11 @@ const JobTitleTimeAndSalaryProvider = () => { fetchPermission(); }, [pageType, pageName, fetchPermission]); - const { - status, - salaryWorkTimes, - salaryWorkTimesCount, - salaryWorkTimeStatistics, - } = useTimeAndSalaryBox(pageName); + const { status, salaryWorkTimes, salaryWorkTimesCount } = useTimeAndSalaryBox( + pageName, + ); + + const salaryWorkTimeStatistics = useSalaryWorkTimeStatistics(pageName); return ( { const selector = useCallback( diff --git a/src/components/TimeAndSalary/common/OvertimeBlock.js b/src/components/TimeAndSalary/common/OvertimeBlock.js index 09055b9ee..67995b8cb 100644 --- a/src/components/TimeAndSalary/common/OvertimeBlock.js +++ b/src/components/TimeAndSalary/common/OvertimeBlock.js @@ -82,7 +82,24 @@ const OvertimeBlock = ({ type, heading, statistics }) => ( OvertimeBlock.propTypes = { heading: PropTypes.string.isRequired, - statistics: PropTypes.object.isRequired, + statistics: PropTypes.shape({ + count: PropTypes.number, + has_compensatory_dayoff_count: PropTypes.shape({ + no: PropTypes.number.isRequired, + unknown: PropTypes.number.isRequired, + yes: PropTypes.number.isRequired, + }), + has_overtime_salary_count: PropTypes.shape({ + no: PropTypes.number.isRequired, + unknown: PropTypes.number.isRequired, + yes: PropTypes.number.isRequired, + }), + is_overtime_salary_legal_count: PropTypes.shape({ + no: PropTypes.number.isRequired, + unknown: PropTypes.number.isRequired, + yes: PropTypes.number.isRequired, + }), + }).isRequired, type: PropTypes.oneOf(['salary', 'dayoff']).isRequired, }; diff --git a/src/graphql/company.js b/src/graphql/company.js index 7299d6ea9..c57ca43fe 100644 --- a/src/graphql/company.js +++ b/src/graphql/company.js @@ -96,8 +96,6 @@ export const queryCompanyOverviewGql = /* GraphQL */ ` } } salary_work_time_statistics { - count - average_estimated_hourly_wage average_week_work_time overtime_frequency_count { seldom @@ -105,21 +103,6 @@ export const queryCompanyOverviewGql = /* GraphQL */ ` usually almost_everyday } - is_overtime_salary_legal_count { - yes - no - unknown - } - has_compensatory_dayoff_count { - yes - no - unknown - } - has_overtime_salary_count { - yes - no - unknown - } job_average_salaries { job_title { name @@ -167,16 +150,16 @@ export const getCompanyTimeAndSalaryQuery = /* GraphQL */ ` } } } + } + } +`; + +export const getCompanyTimeAndSalaryStatisticsQuery = /* GraphQL */ ` + query($companyName: String!) { + company(name: $companyName) { + name salary_work_time_statistics { count - average_estimated_hourly_wage - average_week_work_time - overtime_frequency_count { - seldom - sometimes - usually - almost_everyday - } is_overtime_salary_legal_count { yes no @@ -192,16 +175,6 @@ export const getCompanyTimeAndSalaryQuery = /* GraphQL */ ` no unknown } - job_average_salaries { - job_title { - name - } - average_salary { - type - amount - } - data_count - } } } } diff --git a/src/graphql/jobTitle.js b/src/graphql/jobTitle.js index eafeb249d..3a181a1b3 100644 --- a/src/graphql/jobTitle.js +++ b/src/graphql/jobTitle.js @@ -105,8 +105,6 @@ export const queryJobTitleOverviewGql = /* GraphQL */ ` } } salary_work_time_statistics { - count - average_estimated_hourly_wage average_week_work_time overtime_frequency_count { seldom @@ -114,21 +112,6 @@ export const queryJobTitleOverviewGql = /* GraphQL */ ` usually almost_everyday } - is_overtime_salary_legal_count { - yes - no - unknown - } - has_compensatory_dayoff_count { - yes - no - unknown - } - has_overtime_salary_count { - yes - no - unknown - } } salary_distribution { bins { @@ -181,16 +164,16 @@ export const getJobTitleTimeAndSalaryQuery = /* GraphQL */ ` } } } + } + } +`; + +export const getJobTitleTimeAndSalaryStatisticsQuery = /* GraphQL */ ` + query($jobTitle: String!) { + job_title(name: $jobTitle) { + name salary_work_time_statistics { count - average_estimated_hourly_wage - average_week_work_time - overtime_frequency_count { - seldom - sometimes - usually - almost_everyday - } is_overtime_salary_legal_count { yes no @@ -207,16 +190,6 @@ export const getJobTitleTimeAndSalaryQuery = /* GraphQL */ ` unknown } } - salary_distribution { - bins { - data_count - range { - type - from - to - } - } - } } } `; diff --git a/src/reducers/companyIndex.js b/src/reducers/companyIndex.js index ed1d38058..1bf163b3c 100644 --- a/src/reducers/companyIndex.js +++ b/src/reducers/companyIndex.js @@ -7,6 +7,7 @@ import { SET_TIME_AND_SALARY, SET_INTERVIEW_EXPERIENCES, SET_WORK_EXPERIENCES, + SET_TIME_AND_SALARY_STATISTICS, } from 'actions/company'; const preloadedState = { @@ -16,6 +17,7 @@ const preloadedState = { // companyName --> overviewBox overviewByName: {}, timeAndSalaryByName: {}, + timeAndSalaryStatisticsByName: {}, interviewExperiencesByName: {}, workExperiencesByName: {}, }; @@ -52,6 +54,15 @@ const reducer = createReducer(preloadedState, { }, }; }, + [SET_TIME_AND_SALARY_STATISTICS]: (state, { companyName, box }) => { + return { + ...state, + timeAndSalaryStatisticsByName: { + ...state.timeAndSalaryStatisticsByName, + [companyName]: box, + }, + }; + }, [SET_INTERVIEW_EXPERIENCES]: (state, { companyName, box }) => { return { ...state, diff --git a/src/reducers/jobTitleIndex.js b/src/reducers/jobTitleIndex.js index a26eda377..68b17e051 100644 --- a/src/reducers/jobTitleIndex.js +++ b/src/reducers/jobTitleIndex.js @@ -7,6 +7,7 @@ import { SET_TIME_AND_SALARY, SET_INTERVIEW_EXPERIENCES, SET_WORK_EXPERIENCES, + SET_TIME_AND_SALARY_STATISTICS, } from 'actions/jobTitle'; const preloadedState = { @@ -16,6 +17,7 @@ const preloadedState = { // jobTitle --> overviewBox overviewByName: {}, timeAndSalaryByName: {}, + timeAndSalaryStatisticsByName: {}, interviewExperiencesByName: {}, workExperiencesByName: {}, }; @@ -52,6 +54,15 @@ const reducer = createReducer(preloadedState, { }, }; }, + [SET_TIME_AND_SALARY_STATISTICS]: (state, { jobTitle, box }) => { + return { + ...state, + timeAndSalaryStatisticsByName: { + ...state.timeAndSalaryStatisticsByName, + [jobTitle]: box, + }, + }; + }, [SET_INTERVIEW_EXPERIENCES]: (state, { jobTitle, box }) => { return { ...state, diff --git a/src/selectors/companyAndJobTitle.js b/src/selectors/companyAndJobTitle.js index aec1791de..babd72e75 100644 --- a/src/selectors/companyAndJobTitle.js +++ b/src/selectors/companyAndJobTitle.js @@ -124,6 +124,13 @@ export const companyTimeAndSalaryBoxSelectorByName = companyName => state => { return state.companyIndex.timeAndSalaryByName[companyName] || getUnfetched(); }; +export const companyTimeAndSalaryStatisticsBoxSelectorByName = companyName => state => { + return ( + state.companyIndex.timeAndSalaryStatisticsByName[companyName] || + getUnfetched() + ); +}; + export const companyInterviewExperiencesBoxSelectorByName = companyName => state => { return ( state.companyIndex.interviewExperiencesByName[companyName] || getUnfetched() @@ -153,6 +160,13 @@ export const jobTitleTimeAndSalaryBoxSelectorByName = jobTitle => state => { return state.jobTitleIndex.timeAndSalaryByName[jobTitle] || getUnfetched(); }; +export const jobTitleTimeAndSalaryStatisticsBoxSelectorByName = jobTitle => state => { + return ( + state.jobTitleIndex.timeAndSalaryStatisticsByName[jobTitle] || + getUnfetched() + ); +}; + export const jobTitleInterviewExperiencesBoxSelectorByName = jobTitle => state => { return ( state.jobTitleIndex.interviewExperiencesByName[jobTitle] || getUnfetched()