Skip to content

Commit

Permalink
[公司職稱頁面] 評價分頁 (#1417)
Browse files Browse the repository at this point in the history
  • Loading branch information
peteranny authored Aug 27, 2024
1 parent 877b492 commit cc7cbee
Show file tree
Hide file tree
Showing 16 changed files with 514 additions and 60 deletions.
58 changes: 58 additions & 0 deletions src/actions/company.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,20 @@ import {
companyIndexesBoxSelectorAtPage,
companyOverviewBoxSelectorByName,
companyTimeAndSalaryBoxSelectorByName,
companyWorkExperiencesBoxSelectorByName,
} from 'selectors/companyAndJobTitle';
import {
getCompany as getCompanyApi,
queryCompanyOverview as queryCompanyOverviewApi,
getCompanyTimeAndSalary,
getCompanyWorkExperiences,
queryCompaniesApi,
} from 'apis/company';

export const SET_STATUS = '@@company/SET_STATUS';
export const SET_OVERVIEW = '@@COMPANY/SET_OVERVIEW';
export const SET_TIME_AND_SALARY = '@@COMPANY/SET_TIME_AND_SALARY';
export const SET_WORK_EXPERIENCES = '@@COMPANY/SET_WORK_EXPERIENCES';
export const SET_INDEX = '@@COMPANY/SET_INDEX';
export const SET_INDEX_COUNT = '@@COMPANY/SET_INDEX_COUNT';

Expand Down Expand Up @@ -165,6 +168,7 @@ export const queryCompanyTimeAndSalary = ({
if (
isFetching(box) ||
(isFetched(box) &&
box.name === companyName &&
box.data.jobTitle === jobTitle &&
box.data.start === start &&
box.data.limit === limit)
Expand Down Expand Up @@ -202,3 +206,57 @@ export const queryCompanyTimeAndSalary = ({
dispatch(setTimeAndSalary(companyName, getError(error)));
}
};

const setWorkExperiences = (companyName, box) => ({
type: SET_WORK_EXPERIENCES,
companyName,
box,
});

export const queryCompanyWorkExperiences = ({
companyName,
jobTitle,
start,
limit,
}) => async (dispatch, getState) => {
const box = companyWorkExperiencesBoxSelectorByName(companyName)(getState());
if (
isFetching(box) ||
(isFetched(box) &&
box.data.name === companyName &&
box.data.jobTitle === jobTitle &&
box.data.start === start &&
box.data.limit === limit)
) {
return;
}

dispatch(setWorkExperiences(companyName, toFetching()));

try {
const data = await getCompanyWorkExperiences({
companyName,
jobTitle,
start,
limit,
});

// Not found case
if (data == null) {
return dispatch(setWorkExperiences(companyName, getFetched(data)));
}

const workExperiencesData = {
name: data.name,
jobTitle,
start,
limit,
work_experiences: data.workExperiencesResult.workExperiences,
work_experiences_count: data.workExperiencesResult.count,
};

dispatch(setWorkExperiences(companyName, getFetched(workExperiencesData)));
} catch (error) {
dispatch(setWorkExperiences(companyName, getError(error)));
}
};
58 changes: 58 additions & 0 deletions src/actions/jobTitle.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,20 @@ import {
jobTitleIndexesBoxSelectorAtPage,
jobTitleOverviewBoxSelectorByName,
jobTitleTimeAndSalaryBoxSelectorByName,
jobTitleWorkExperiencesBoxSelectorByName,
} from 'selectors/companyAndJobTitle';
import {
getJobTitle as getJobTitleApi,
queryJobTitleOverview as queryJobTitleOverviewApi,
getJobTitleTimeAndSalary,
getJobTitleWorkExperiences,
queryJobTitlesApi,
} from 'apis/jobTitle';

export const SET_STATUS = '@@JOB_TITLE/SET_STATUS';
export const SET_OVERVIEW = '@@JOB_TITLE/SET_OVERVIEW';
export const SET_TIME_AND_SALARY = '@@JOB_TITLE/SET_TIME_AND_SALARY';
export const SET_WORK_EXPERIENCES = '@@JOB_TITLE/SET_WORK_EXPERIENCES';
export const SET_INDEX = '@@JOB_TITLE/SET_INDEX';
export const SET_INDEX_COUNT = '@@JOB_TITLE/SET_INDEX_COUNT';

Expand Down Expand Up @@ -163,6 +166,7 @@ export const queryJobTitleTimeAndSalary = ({
if (
isFetching(box) ||
(isFetched(box) &&
box.data.name === jobTitle &&
box.data.companyName === companyName &&
box.data.start === start &&
box.data.limit === limit)
Expand Down Expand Up @@ -200,3 +204,57 @@ export const queryJobTitleTimeAndSalary = ({
dispatch(setTimeAndSalary(jobTitle, getError(error)));
}
};

const setWorkExperiences = (jobTitle, box) => ({
type: SET_WORK_EXPERIENCES,
jobTitle,
box,
});

export const queryJobTitleWorkExperiences = ({
companyName,
jobTitle,
start,
limit,
}) => async (dispatch, getState) => {
const box = jobTitleWorkExperiencesBoxSelectorByName(jobTitle)(getState());
if (
isFetching(box) ||
(isFetched(box) &&
box.data.name === jobTitle &&
box.data.companyName === companyName &&
box.data.start === start &&
box.data.limit === limit)
) {
return;
}

dispatch(setWorkExperiences(jobTitle, toFetching()));

try {
const data = await getJobTitleWorkExperiences({
jobTitle,
companyName,
start,
limit,
});

// Not found case
if (data == null) {
return dispatch(setWorkExperiences(jobTitle, getFetched(data)));
}

const workExperiencesData = {
name: data.name,
companyName,
start,
limit,
work_experiences: data.workExperiencesResult.workExperiences,
work_experiences_count: data.workExperiencesResult.count,
};

dispatch(setWorkExperiences(jobTitle, getFetched(workExperiencesData)));
} catch (error) {
dispatch(setWorkExperiences(jobTitle, getError(error)));
}
};
12 changes: 12 additions & 0 deletions src/apis/company.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
getCompanyQuery,
queryCompanyOverviewGql,
getCompanyTimeAndSalaryQuery,
getCompanyWorkExperiencesQuery,
queryCompaniesHavingDataGql,
} from 'graphql/company';

Expand Down Expand Up @@ -41,6 +42,17 @@ export const getCompanyTimeAndSalary = ({
variables: { companyName, jobTitle, start, limit },
}).then(R.prop('company'));

export const getCompanyWorkExperiences = ({
companyName,
jobTitle,
start,
limit,
}) =>
graphqlClient({
query: getCompanyWorkExperiencesQuery,
variables: { companyName, jobTitle, start, limit },
}).then(R.prop('company'));

export const queryCompaniesApi = ({ start, limit }) =>
graphqlClient({
query: queryCompaniesHavingDataGql,
Expand Down
12 changes: 12 additions & 0 deletions src/apis/jobTitle.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
getJobTitleQuery,
queryJobTitleOverviewGql,
getJobTitleTimeAndSalaryQuery,
getJobTitleWorkExperiencesQuery,
queryJobTitlesHavingDataGql,
} from 'graphql/jobTitle';

Expand Down Expand Up @@ -41,6 +42,17 @@ export const getJobTitleTimeAndSalary = ({
variables: { jobTitle, companyName, start, limit },
}).then(R.prop('job_title'));

export const getJobTitleWorkExperiences = ({
jobTitle,
companyName,
start,
limit,
}) =>
graphqlClient({
query: getJobTitleWorkExperiencesQuery,
variables: { jobTitle, companyName, start, limit },
}).then(R.prop('job_title'));

export const queryJobTitlesApi = ({ start, limit }) =>
graphqlClient({
query: queryJobTitlesHavingDataGql,
Expand Down
27 changes: 2 additions & 25 deletions src/components/Company/CompanyPageProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,16 @@ import { useSelector, useDispatch } from 'react-redux';
import { generatePath } from 'react-router';
import { Switch, Route } from 'react-router-dom';
import InterviewExperiences from '../CompanyAndJobTitle/InterviewExperiences';
import WorkExperiences from '../CompanyAndJobTitle/WorkExperiences';
import NotFound from 'common/NotFound';
import Redirect from 'common/routing/Redirect';
import { paramsSelector } from 'common/routing/selectors';
import usePermission from 'hooks/usePermission';
import { usePage } from 'hooks/routing/page';
import { tabType, pageType as PAGE_TYPE } from 'constants/companyJobTitle';
import {
companyInterviewExperiencesPath,
companyWorkExperiencesPath,
} from 'constants/linkTo';
import { companyInterviewExperiencesPath } from 'constants/linkTo';
import { fetchCompany } from 'actions/company';
import {
interviewExperiences as interviewExperiencesSelector,
workExperiences as workExperiencesSelector,
status as statusSelector,
company as companySelector,
} from 'selectors/companyAndJobTitle';
Expand All @@ -44,14 +39,11 @@ const CompanyPageProvider = () => {
return {
status: statusSelector(company),
interviewExperiences: interviewExperiencesSelector(company),
workExperiences: workExperiencesSelector(company),
};
},
[pageName],
);
const { status, interviewExperiences, workExperiences } = useSelector(
selector,
);
const { status, interviewExperiences } = useSelector(selector);

return (
<Switch>
Expand Down Expand Up @@ -80,21 +72,6 @@ const CompanyPageProvider = () => {
/>
)}
/>
<Route
path={companyWorkExperiencesPath}
exact
render={() => (
<WorkExperiences
pageType={pageType}
pageName={pageName}
page={page}
canView={canView}
tabType={tabType.WORK_EXPERIENCE}
status={status}
workExperiences={workExperiences}
/>
)}
/>
<Route component={NotFound} />
</Switch>
);
Expand Down
110 changes: 110 additions & 0 deletions src/components/Company/CompanyWorkExperiencesProvider.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import React, { useCallback, useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import WorkExperiences from '../CompanyAndJobTitle/WorkExperiences';
import usePermission from 'hooks/usePermission';
import { usePage } from 'hooks/routing/page';
import { tabType, pageType as PAGE_TYPE } from 'constants/companyJobTitle';
import {
queryCompanyTimeAndSalary,
queryCompanyWorkExperiences,
} from 'actions/company';
import {
workExperiences as workExperiencesSelector,
workExperiencesCount as workExperiencesCountSelector,
status as statusSelector,
companyWorkExperiencesBoxSelectorByName as workExperiencesBoxSelectorByName,
} from 'selectors/companyAndJobTitle';
import { paramsSelector, querySelector } from 'common/routing/selectors';
import { usePageName, pageNameSelector } from './usePageName';
import { pageFromQuerySelector } from 'selectors/routing/page';
import {
searchTextFromQuerySelector,
useSearchTextFromQuery,
} from 'components/CompanyAndJobTitle/useSearchbar';

const useWorkExperiencesBox = pageName => {
const selector = useCallback(
state => {
const company = workExperiencesBoxSelectorByName(pageName)(state);
return {
status: statusSelector(company),
workExperiences: workExperiencesSelector(company),
workExperiencesCount: workExperiencesCountSelector(company),
};
},
[pageName],
);

return useSelector(selector);
};

const PAGE_SIZE = 10;

const CompanyWorkExperiencesProvider = () => {
const dispatch = useDispatch();
const pageType = PAGE_TYPE.COMPANY;
const pageName = usePageName();
const [jobTitle] = useSearchTextFromQuery();
const page = usePage();
const start = (page - 1) * PAGE_SIZE;
const limit = PAGE_SIZE;

useEffect(() => {
dispatch(
queryCompanyWorkExperiences({
companyName: pageName,
jobTitle: jobTitle || undefined,
start,
limit,
}),
);
}, [dispatch, pageName, jobTitle, start, limit]);

const [, fetchPermission, canView] = usePermission();
useEffect(() => {
fetchPermission();
}, [pageType, pageName, fetchPermission]);

const {
status,
workExperiences,
workExperiencesCount,
} = useWorkExperiencesBox(pageName);

return (
<WorkExperiences
pageType={pageType}
pageName={pageName}
page={page}
pageSize={PAGE_SIZE}
totalCount={workExperiencesCount}
canView={canView}
tabType={tabType.WORK_EXPERIENCE}
status={status}
workExperiences={workExperiences}
/>
);
};

CompanyWorkExperiencesProvider.fetchData = ({
store: { dispatch },
...props
}) => {
const params = paramsSelector(props);
const pageName = pageNameSelector(params);
const query = querySelector(props);
const page = pageFromQuerySelector(query);
const jobTitle = searchTextFromQuerySelector(query) || undefined;
const start = (page - 1) * PAGE_SIZE;
const limit = PAGE_SIZE;
return dispatch(
queryCompanyTimeAndSalary({
companyName: pageName,
jobTitle,
start,
limit,
}),
);
};

export default CompanyWorkExperiencesProvider;
Loading

0 comments on commit cc7cbee

Please sign in to comment.