From 7fe5d221bf23bdd1df112ee96e3d4a66862e303c Mon Sep 17 00:00:00 2001 From: Peteranny Date: Thu, 5 Sep 2024 22:25:45 +0800 Subject: [PATCH 01/22] show my exp --- src/apis/me.js | 6 ++++ src/components/ExperienceDetail/index.js | 44 ++++++++++++++++++++---- src/graphql/me.js | 10 ++++++ 3 files changed, 54 insertions(+), 6 deletions(-) diff --git a/src/apis/me.js b/src/apis/me.js index 0af13a029..698efff7b 100644 --- a/src/apis/me.js +++ b/src/apis/me.js @@ -2,6 +2,7 @@ import graphqlClient from 'utils/graphqlClient'; import { queryMeGql, + queryMyExperienceIdsGql, queryMyPublishesGql, queryMyPermissionGql, } from 'graphql/me'; @@ -18,5 +19,10 @@ export const queryHasSearchPermissionApi = ({ token }) => export const queryMeApi = ({ token }) => graphqlClient({ query: queryMeGql, token }).then(data => data.me); +export const queryMyExperienceIdsApi = ({ token }) => + graphqlClient({ query: queryMyExperienceIdsGql, token }).then(data => + data.me.experiences.map(({ id }) => id), + ); + export const queryMyPublishesApi = ({ token }) => graphqlClient({ query: queryMyPublishesGql, token }); diff --git a/src/components/ExperienceDetail/index.js b/src/components/ExperienceDetail/index.js index b37ca4f39..55770387f 100644 --- a/src/components/ExperienceDetail/index.js +++ b/src/components/ExperienceDetail/index.js @@ -48,6 +48,9 @@ import { generateBreadCrumbData } from '../CompanyAndJobTitle/utils'; import styles from './ExperienceDetail.module.css'; import { experienceBoxSelectorAtId } from 'selectors/experienceSelector'; import Button from 'common/button/Button'; +import { queryMyExperienceIdsApi } from 'apis/me'; +import { useToken } from 'hooks/auth'; +import { useAsyncFn } from 'react-use'; const MODAL_TYPE = { REPORT_DETAIL: 'REPORT_TYPE', @@ -79,6 +82,39 @@ const useExperienceBox = experienceId => { return useSelector(selector); }; +const useHideContent = ({ experienceId }) => { + const token = useToken(); + + const [{ value: myExperienceIds }, fetchMyExperienceIds] = useAsyncFn( + () => + queryMyExperienceIdsApi({ + token, + }), + [token], + ); + + useEffect(() => { + fetchMyExperienceIds(); + }, [fetchMyExperienceIds]); + + const isMyPublish = useMemo( + () => myExperienceIds && myExperienceIds.includes(experienceId), + [myExperienceIds, experienceId], + ); + + const [, fetchPermission, canView] = usePermission(); + + useEffect(() => { + fetchPermission(); + }, [experienceId, fetchPermission]); + + const hideContent = useMemo(() => { + return !isMyPublish && !canView; + }, [isMyPublish, canView]); + + return hideContent; +}; + const ExperienceDetail = ({ ...props }) => { const experienceId = useExperienceId(); const experienceBox = useExperienceBox(experienceId); @@ -89,11 +125,7 @@ const ExperienceDetail = ({ ...props }) => { dispatch(queryExperienceIfUnfetched(experienceId)); }, [dispatch, experienceId]); - const [, fetchPermission, canView] = usePermission(); - - useEffect(() => { - fetchPermission(); - }, [experienceId, fetchPermission]); + const hideContent = useHideContent({ experienceId }); const [{ isModalOpen, modalType, modalPayload = {} }, setModal] = useState({ isModalOpen: false, @@ -241,7 +273,7 @@ const ExperienceDetail = ({ ...props }) => { {reportZone}
diff --git a/src/graphql/me.js b/src/graphql/me.js index daa40bd61..12cfdde5f 100644 --- a/src/graphql/me.js +++ b/src/graphql/me.js @@ -19,6 +19,16 @@ export const queryMeGql = /* GraphQL */ ` } `; +export const queryMyExperienceIdsGql = /* GraphQL */ ` + query MyPublishes { + me { + experiences { + id + } + } + } +`; + export const queryMyPublishesGql = /* GraphQL */ ` query MyPublishes { me { From 87f4cd443659d6d3232b09eabae603d0e0d8f518 Mon Sep 17 00:00:00 2001 From: Peteranny Date: Thu, 5 Sep 2024 22:51:07 +0800 Subject: [PATCH 02/22] show my time and salary This reverts commit d9272e5af1fc5c252fd0c5808e9bff1a294fc122. --- src/apis/me.js | 6 ++++ .../TimeAndSalary/WorkingHourTable.js | 33 ++++++++++++++++--- .../common/injectHideContentBlock.js | 26 ++++++++++----- src/components/common/table/Table.js | 2 +- src/graphql/me.js | 10 ++++++ 5 files changed, 63 insertions(+), 14 deletions(-) diff --git a/src/apis/me.js b/src/apis/me.js index 698efff7b..f91b9beef 100644 --- a/src/apis/me.js +++ b/src/apis/me.js @@ -3,6 +3,7 @@ import graphqlClient from 'utils/graphqlClient'; import { queryMeGql, queryMyExperienceIdsGql, + queryMySalaryWorkTimesIdsGql, queryMyPublishesGql, queryMyPermissionGql, } from 'graphql/me'; @@ -24,5 +25,10 @@ export const queryMyExperienceIdsApi = ({ token }) => data.me.experiences.map(({ id }) => id), ); +export const queryMySalaryWorkTimesIdsApi = ({ token }) => + graphqlClient({ query: queryMySalaryWorkTimesIdsGql, token }).then(data => + data.me.salary_work_times.map(({ id }) => id), + ); + export const queryMyPublishesApi = ({ token }) => graphqlClient({ query: queryMyPublishesGql, token }); diff --git a/src/components/CompanyAndJobTitle/TimeAndSalary/WorkingHourTable.js b/src/components/CompanyAndJobTitle/TimeAndSalary/WorkingHourTable.js index 3e8eb6a4b..05e0236e5 100644 --- a/src/components/CompanyAndJobTitle/TimeAndSalary/WorkingHourTable.js +++ b/src/components/CompanyAndJobTitle/TimeAndSalary/WorkingHourTable.js @@ -1,4 +1,4 @@ -import React, { useState, useCallback, useMemo } from 'react'; +import React, { useState, useCallback, useMemo, useEffect } from 'react'; import PropTypes from 'prop-types'; import R from 'ramda'; import { InfoButton } from 'common/Modal'; @@ -19,6 +19,9 @@ import { formatDate, } from '../../TimeAndSalary/common/formatter'; import injectHideContentBlock from '../../TimeAndSalary/common/injectHideContentBlock'; +import { queryMySalaryWorkTimesIdsApi } from 'apis/me'; +import { useToken } from 'hooks/auth'; +import { useAsyncFn } from 'react-use'; const SalaryHeader = ({ isInfoSalaryModalOpen, toggleInfoSalaryModal }) => ( @@ -147,7 +150,7 @@ const WorkingHourTable = ({ data, hideContent, pageType }) => { [pageType], ); - const hideRange = useMemo( + const [fromCol, toCol] = useMemo( () => [ R.findIndex(R.propEq('permissionRequiredStart', true))( filteredColumnProps, @@ -157,14 +160,34 @@ const WorkingHourTable = ({ data, hideContent, pageType }) => { [filteredColumnProps], ); + const token = useToken(); + + const [{ value: mySalaryWorkTimeIds }, fetchMySalaryWorkTimeIds] = useAsyncFn( + () => + queryMySalaryWorkTimesIdsApi({ + token, + }), + [token], + ); + + useEffect(() => { + fetchMySalaryWorkTimeIds(); + }, [fetchMySalaryWorkTimeIds]); + const postProcessRows = useCallback( - rows => { + (rows, data) => { if (hideContent) { - injectHideContentBlock(hideRange)(rows); + injectHideContentBlock({ + rows, + data, + fromCol, + toCol, + mySalaryWorkTimeIds, + }); } return rows; }, - [hideContent, hideRange], + [hideContent, fromCol, toCol, mySalaryWorkTimeIds], ); return ( diff --git a/src/components/TimeAndSalary/common/injectHideContentBlock.js b/src/components/TimeAndSalary/common/injectHideContentBlock.js index 5975c5305..acc181e03 100644 --- a/src/components/TimeAndSalary/common/injectHideContentBlock.js +++ b/src/components/TimeAndSalary/common/injectHideContentBlock.js @@ -4,18 +4,22 @@ import styles from './injectHideContentBlock.module.css'; import cn from 'classnames'; import { useShareLink } from 'hooks/experiments'; -export default hideRange => rows => { - const hideIndex = hideRange[0]; - const nHides = hideRange.length; +export default ({ rows, data, fromCol, toCol, mySalaryWorkTimeIds }) => { + const nHides = toCol - fromCol + 1; const shareLink = useShareLink(); // Replace original cells with locked cells // on small screens - rows.forEach(row => { + rows.forEach((row, i) => { + const d = data[i]; + const isMySalaryWorkTime = + mySalaryWorkTimeIds && mySalaryWorkTimeIds.includes(d.id); + if (isMySalaryWorkTime) return; + row.props.children.splice( - hideIndex, + fromCol, nHides, - ...row.props.children.slice(hideIndex, hideIndex + nHides).map(col => { + ...row.props.children.slice(fromCol, fromCol + nHides).map(col => { return React.cloneElement( col, { @@ -34,8 +38,14 @@ export default hideRange => rows => { // that spans multiple columns if (rows.length > 0) { for (let i = 0; i < rows.length; i++) { - rows[i].props.children.splice( - hideIndex, + const d = data[i]; + const isMySalaryWorkTime = + mySalaryWorkTimeIds && mySalaryWorkTimeIds.includes(d.id); + if (isMySalaryWorkTime) continue; + + const row = rows[i]; + row.props.children.splice( + fromCol, 0, {record}; }); - const postRecords = postProcessRows(records); + const postRecords = postProcessRows(records, data); return ( diff --git a/src/graphql/me.js b/src/graphql/me.js index 12cfdde5f..3de459b21 100644 --- a/src/graphql/me.js +++ b/src/graphql/me.js @@ -29,6 +29,16 @@ export const queryMyExperienceIdsGql = /* GraphQL */ ` } `; +export const queryMySalaryWorkTimesIdsGql = /* GraphQL */ ` + query MyPublishes { + me { + salary_work_times { + id + } + } + } +`; + export const queryMyPublishesGql = /* GraphQL */ ` query MyPublishes { me { From 069e4bd3ec1cc131e0da54de026a7cc9b8c57c92 Mon Sep 17 00:00:00 2001 From: Peteranny Date: Fri, 6 Sep 2024 01:11:17 +0800 Subject: [PATCH 03/22] modularize --- .../TimeAndSalary/WorkingHourTable.js | 24 +++----------- .../TimeAndSalary/useIsMySalaryWorkTimeId.js | 32 +++++++++++++++++++ src/components/ExperienceDetail/index.js | 26 ++++----------- .../ExperienceDetail/useIsMyExperienceId.js | 32 +++++++++++++++++++ .../common/injectHideContentBlock.js | 8 ++--- 5 files changed, 78 insertions(+), 44 deletions(-) create mode 100644 src/components/CompanyAndJobTitle/TimeAndSalary/useIsMySalaryWorkTimeId.js create mode 100644 src/components/ExperienceDetail/useIsMyExperienceId.js diff --git a/src/components/CompanyAndJobTitle/TimeAndSalary/WorkingHourTable.js b/src/components/CompanyAndJobTitle/TimeAndSalary/WorkingHourTable.js index 05e0236e5..cd4c357a7 100644 --- a/src/components/CompanyAndJobTitle/TimeAndSalary/WorkingHourTable.js +++ b/src/components/CompanyAndJobTitle/TimeAndSalary/WorkingHourTable.js @@ -1,4 +1,4 @@ -import React, { useState, useCallback, useMemo, useEffect } from 'react'; +import React, { useState, useCallback, useMemo } from 'react'; import PropTypes from 'prop-types'; import R from 'ramda'; import { InfoButton } from 'common/Modal'; @@ -19,9 +19,7 @@ import { formatDate, } from '../../TimeAndSalary/common/formatter'; import injectHideContentBlock from '../../TimeAndSalary/common/injectHideContentBlock'; -import { queryMySalaryWorkTimesIdsApi } from 'apis/me'; -import { useToken } from 'hooks/auth'; -import { useAsyncFn } from 'react-use'; +import useIsMySalaryWorkTimeId from './useIsMySalaryWorkTimeId'; const SalaryHeader = ({ isInfoSalaryModalOpen, toggleInfoSalaryModal }) => ( @@ -160,19 +158,7 @@ const WorkingHourTable = ({ data, hideContent, pageType }) => { [filteredColumnProps], ); - const token = useToken(); - - const [{ value: mySalaryWorkTimeIds }, fetchMySalaryWorkTimeIds] = useAsyncFn( - () => - queryMySalaryWorkTimesIdsApi({ - token, - }), - [token], - ); - - useEffect(() => { - fetchMySalaryWorkTimeIds(); - }, [fetchMySalaryWorkTimeIds]); + const isMySalaryWorkTimeId = useIsMySalaryWorkTimeId(); const postProcessRows = useCallback( (rows, data) => { @@ -182,12 +168,12 @@ const WorkingHourTable = ({ data, hideContent, pageType }) => { data, fromCol, toCol, - mySalaryWorkTimeIds, + isMySalaryWorkTimeId, }); } return rows; }, - [hideContent, fromCol, toCol, mySalaryWorkTimeIds], + [hideContent, fromCol, toCol, isMySalaryWorkTimeId], ); return ( diff --git a/src/components/CompanyAndJobTitle/TimeAndSalary/useIsMySalaryWorkTimeId.js b/src/components/CompanyAndJobTitle/TimeAndSalary/useIsMySalaryWorkTimeId.js new file mode 100644 index 000000000..c6f6134af --- /dev/null +++ b/src/components/CompanyAndJobTitle/TimeAndSalary/useIsMySalaryWorkTimeId.js @@ -0,0 +1,32 @@ +import { useCallback, useEffect } from 'react'; +import { queryMySalaryWorkTimesIdsApi } from 'apis/me'; +import { useToken } from 'hooks/auth'; +import { useAsyncFn } from 'react-use'; + +const useIsMySalaryWorkTimeId = () => { + const token = useToken(); + + const [{ value: mySalaryWorkTimeIds }, fetchMySalaryWorkTimeIds] = useAsyncFn( + () => + queryMySalaryWorkTimesIdsApi({ + token, + }), + [token], + ); + + useEffect(() => { + fetchMySalaryWorkTimeIds(); + }, [fetchMySalaryWorkTimeIds]); + + const isMySalaryWorkTimeId = useCallback( + id => { + if (!mySalaryWorkTimeIds) return false; + return mySalaryWorkTimeIds.includes(id); + }, + [mySalaryWorkTimeIds], + ); + + return isMySalaryWorkTimeId; +}; + +export default useIsMySalaryWorkTimeId; diff --git a/src/components/ExperienceDetail/index.js b/src/components/ExperienceDetail/index.js index 55770387f..3c6bc7816 100644 --- a/src/components/ExperienceDetail/index.js +++ b/src/components/ExperienceDetail/index.js @@ -48,9 +48,7 @@ import { generateBreadCrumbData } from '../CompanyAndJobTitle/utils'; import styles from './ExperienceDetail.module.css'; import { experienceBoxSelectorAtId } from 'selectors/experienceSelector'; import Button from 'common/button/Button'; -import { queryMyExperienceIdsApi } from 'apis/me'; -import { useToken } from 'hooks/auth'; -import { useAsyncFn } from 'react-use'; +import useIsMyExperienceId from './useIsMyExperienceId'; const MODAL_TYPE = { REPORT_DETAIL: 'REPORT_TYPE', @@ -83,24 +81,12 @@ const useExperienceBox = experienceId => { }; const useHideContent = ({ experienceId }) => { - const token = useToken(); + const isMyExperienceId = useIsMyExperienceId(); - const [{ value: myExperienceIds }, fetchMyExperienceIds] = useAsyncFn( - () => - queryMyExperienceIdsApi({ - token, - }), - [token], - ); - - useEffect(() => { - fetchMyExperienceIds(); - }, [fetchMyExperienceIds]); - - const isMyPublish = useMemo( - () => myExperienceIds && myExperienceIds.includes(experienceId), - [myExperienceIds, experienceId], - ); + const isMyPublish = useMemo(() => isMyExperienceId(experienceId), [ + isMyExperienceId, + experienceId, + ]); const [, fetchPermission, canView] = usePermission(); diff --git a/src/components/ExperienceDetail/useIsMyExperienceId.js b/src/components/ExperienceDetail/useIsMyExperienceId.js new file mode 100644 index 000000000..c27b5f780 --- /dev/null +++ b/src/components/ExperienceDetail/useIsMyExperienceId.js @@ -0,0 +1,32 @@ +import { useCallback, useEffect } from 'react'; +import { queryMyExperienceIdsApi } from 'apis/me'; +import { useToken } from 'hooks/auth'; +import { useAsyncFn } from 'react-use'; + +const useIsMyExperienceId = () => { + const token = useToken(); + + const [{ value: myExperienceIds }, fetchMyExperienceIds] = useAsyncFn( + () => + queryMyExperienceIdsApi({ + token, + }), + [token], + ); + + useEffect(() => { + fetchMyExperienceIds(); + }, [fetchMyExperienceIds]); + + const isMyExperienceId = useCallback( + experienceId => { + if (!myExperienceIds) return false; + return myExperienceIds.includes(experienceId); + }, + [myExperienceIds], + ); + + return isMyExperienceId; +}; + +export default useIsMyExperienceId; diff --git a/src/components/TimeAndSalary/common/injectHideContentBlock.js b/src/components/TimeAndSalary/common/injectHideContentBlock.js index acc181e03..ca33c93f1 100644 --- a/src/components/TimeAndSalary/common/injectHideContentBlock.js +++ b/src/components/TimeAndSalary/common/injectHideContentBlock.js @@ -4,7 +4,7 @@ import styles from './injectHideContentBlock.module.css'; import cn from 'classnames'; import { useShareLink } from 'hooks/experiments'; -export default ({ rows, data, fromCol, toCol, mySalaryWorkTimeIds }) => { +export default ({ rows, data, fromCol, toCol, isMySalaryWorkTimeId }) => { const nHides = toCol - fromCol + 1; const shareLink = useShareLink(); @@ -12,8 +12,7 @@ export default ({ rows, data, fromCol, toCol, mySalaryWorkTimeIds }) => { // on small screens rows.forEach((row, i) => { const d = data[i]; - const isMySalaryWorkTime = - mySalaryWorkTimeIds && mySalaryWorkTimeIds.includes(d.id); + const isMySalaryWorkTime = isMySalaryWorkTimeId(d.id); if (isMySalaryWorkTime) return; row.props.children.splice( @@ -39,8 +38,7 @@ export default ({ rows, data, fromCol, toCol, mySalaryWorkTimeIds }) => { if (rows.length > 0) { for (let i = 0; i < rows.length; i++) { const d = data[i]; - const isMySalaryWorkTime = - mySalaryWorkTimeIds && mySalaryWorkTimeIds.includes(d.id); + const isMySalaryWorkTime = isMySalaryWorkTimeId(d.id); if (isMySalaryWorkTime) continue; const row = rows[i]; From 45c1cea4486bfbfe6cb21c368c1c960f3b0bf83b Mon Sep 17 00:00:00 2001 From: Peteranny Date: Wed, 18 Sep 2024 02:06:08 +0800 Subject: [PATCH 04/22] more experiences: can view when my exp --- .../ExperienceDetail/MoreExperiencesBlock/index.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/ExperienceDetail/MoreExperiencesBlock/index.js b/src/components/ExperienceDetail/MoreExperiencesBlock/index.js index 2f0d14e86..4dd43d49c 100644 --- a/src/components/ExperienceDetail/MoreExperiencesBlock/index.js +++ b/src/components/ExperienceDetail/MoreExperiencesBlock/index.js @@ -13,6 +13,7 @@ import { relatedExperiencesStateSelector } from 'selectors/experienceSelector'; import { pageType as PAGE_TYPE } from 'constants/companyJobTitle'; import Button from 'common/button/Button'; import styles from './MoreExperiencesBlock.module.css'; +import useIsMyExperienceId from '../useIsMyExperienceId'; const ExperienceEntry = props => { switch (props.data.type) { @@ -57,6 +58,8 @@ const MoreExperiencesBlock = ({ experience }) => { [dispatch], ); + const isMyExperienceId = useIsMyExperienceId(); + // we still want to show data even when Fetching if ( !relatedExperiencesState.data || @@ -83,7 +86,7 @@ const MoreExperiencesBlock = ({ experience }) => { key={e.id} pageType={pageType} data={e} - canView={canView} + canView={isMyExperienceId(e.id) || canView} /> ))} {hasMore && } From ae90684e843ee408197ae3f4ec8a56ed21a69a4e Mon Sep 17 00:00:00 2001 From: Peteranny Date: Wed, 18 Sep 2024 02:12:00 +0800 Subject: [PATCH 05/22] entries: can view when my exp --- .../InterviewExperiences/InterviewExperiences.js | 4 +++- .../CompanyAndJobTitle/WorkExperiences/WorkExperiences.js | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/CompanyAndJobTitle/InterviewExperiences/InterviewExperiences.js b/src/components/CompanyAndJobTitle/InterviewExperiences/InterviewExperiences.js index 5fe7c5a1a..793a66550 100644 --- a/src/components/CompanyAndJobTitle/InterviewExperiences/InterviewExperiences.js +++ b/src/components/CompanyAndJobTitle/InterviewExperiences/InterviewExperiences.js @@ -10,6 +10,7 @@ import EmptyView from '../EmptyView'; import ExperienceEntry from './ExperienceEntry'; import { useQuery } from 'hooks/routing'; +import useIsMyExperienceId from 'components/ExperienceDetail/useIsMyExperienceId'; const InterviewExperiences = ({ pageType, @@ -22,6 +23,7 @@ const InterviewExperiences = ({ canView, }) => { const queryParams = useQuery(); + const isMyExperienceId = useIsMyExperienceId(); if (data.length === 0) { return ( @@ -39,7 +41,7 @@ const InterviewExperiences = ({ key={d.id} pageType={pageType} data={d} - canView={canView} + canView={isMyExperienceId(d.id) || canView} /> ))} { const queryParams = useQuery(); + const isMyExperienceId = useIsMyExperienceId(); if (data.length === 0) { return ( @@ -37,7 +39,7 @@ const WorkExperiences = ({ key={d.id} pageType={pageType} data={d} - canView={canView} + canView={isMyExperienceId(d.id) || canView} /> ))} Date: Wed, 18 Sep 2024 02:13:23 +0800 Subject: [PATCH 06/22] overview: can view my my exp --- src/components/CompanyAndJobTitle/Overview/Overview.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/components/CompanyAndJobTitle/Overview/Overview.js b/src/components/CompanyAndJobTitle/Overview/Overview.js index cdf9bbbd2..7bfe6ea92 100644 --- a/src/components/CompanyAndJobTitle/Overview/Overview.js +++ b/src/components/CompanyAndJobTitle/Overview/Overview.js @@ -9,6 +9,7 @@ import WorkExperienceEntry from '../WorkExperiences/ExperienceEntry'; import InterviewExperienceEntry from '../InterviewExperiences/ExperienceEntry'; import { tabType as TAB_TYPE, generateTabURL } from 'constants/companyJobTitle'; import SummaryBlock from './SummaryBlock'; +import useIsMyExperienceId from 'components/ExperienceDetail/useIsMyExperienceId'; const Overview = ({ pageType, @@ -25,6 +26,8 @@ const Overview = ({ overtimeFrequencyCount, canView, }) => { + const isMyExperienceId = useIsMyExperienceId(); + return (
))} @@ -92,7 +95,7 @@ const Overview = ({ key={d.id} pageType={pageType} data={d} - canView={canView} + canView={isMyExperienceId(d.id) || canView} /> ))} From 6c6c238e9cef25022ef29dc3e8210ade1a268ed2 Mon Sep 17 00:00:00 2001 From: Peteranny Date: Thu, 19 Sep 2024 22:51:08 +0800 Subject: [PATCH 07/22] move to redux --- src/actions/me.js | 21 +++++++++++ src/apis/me.js | 17 ++++----- .../InterviewExperiences.js | 4 +-- .../CompanyAndJobTitle/Overview/Overview.js | 4 +-- .../TimeAndSalary/WorkingHourTable.js | 8 ++--- .../TimeAndSalary/useIsMySalaryWorkTimeId.js | 32 ----------------- .../WorkExperiences/WorkExperiences.js | 4 +-- .../MoreExperiencesBlock/index.js | 4 +-- src/components/ExperienceDetail/index.js | 4 +-- .../ExperienceDetail/useIsMyExperienceId.js | 32 ----------------- .../common/injectHideContentBlock.js | 10 +++--- src/graphql/me.js | 9 +---- src/hooks/useIsMyPublishId.js | 36 +++++++++++++++++++ src/reducers/index.js | 2 ++ src/reducers/me.js | 16 +++++++++ src/selectors/me.js | 1 + 16 files changed, 102 insertions(+), 102 deletions(-) create mode 100644 src/actions/me.js delete mode 100644 src/components/CompanyAndJobTitle/TimeAndSalary/useIsMySalaryWorkTimeId.js delete mode 100644 src/components/ExperienceDetail/useIsMyExperienceId.js create mode 100644 src/hooks/useIsMyPublishId.js create mode 100644 src/reducers/me.js create mode 100644 src/selectors/me.js diff --git a/src/actions/me.js b/src/actions/me.js new file mode 100644 index 000000000..e5d4f6406 --- /dev/null +++ b/src/actions/me.js @@ -0,0 +1,21 @@ +import { queryMyPublishIdsApi } from 'apis/me'; +import { tokenSelector } from 'selectors/authSelector'; +import { getError, getFetched, toFetching } from 'utils/fetchBox'; + +export const SET_MY_PUBLISH_IDS = '@@me/SET_MY_PUBLISH_IDS'; + +const setMyPublishIds = box => ({ + type: SET_MY_PUBLISH_IDS, + box, +}); + +export const queryMyPublishIds = () => async (dispatch, getState) => { + const token = tokenSelector(getState()); + dispatch(setMyPublishIds(toFetching())); + try { + const myPublishIds = await queryMyPublishIdsApi({ token }); + dispatch(setMyPublishIds(getFetched(myPublishIds))); + } catch (error) { + dispatch(setMyPublishIds(getError(error))); + } +}; diff --git a/src/apis/me.js b/src/apis/me.js index f91b9beef..49f466fcc 100644 --- a/src/apis/me.js +++ b/src/apis/me.js @@ -2,8 +2,7 @@ import graphqlClient from 'utils/graphqlClient'; import { queryMeGql, - queryMyExperienceIdsGql, - queryMySalaryWorkTimesIdsGql, + queryMyPublishIdsGql, queryMyPublishesGql, queryMyPermissionGql, } from 'graphql/me'; @@ -20,15 +19,11 @@ export const queryHasSearchPermissionApi = ({ token }) => export const queryMeApi = ({ token }) => graphqlClient({ query: queryMeGql, token }).then(data => data.me); -export const queryMyExperienceIdsApi = ({ token }) => - graphqlClient({ query: queryMyExperienceIdsGql, token }).then(data => - data.me.experiences.map(({ id }) => id), - ); - -export const queryMySalaryWorkTimesIdsApi = ({ token }) => - graphqlClient({ query: queryMySalaryWorkTimesIdsGql, token }).then(data => - data.me.salary_work_times.map(({ id }) => id), - ); +export const queryMyPublishIdsApi = ({ token }) => + graphqlClient({ query: queryMyPublishIdsGql, token }).then(data => [ + ...data.me.experiences.map(({ id }) => id), + ...data.me.salary_work_times.map(({ id }) => id), + ]); export const queryMyPublishesApi = ({ token }) => graphqlClient({ query: queryMyPublishesGql, token }); diff --git a/src/components/CompanyAndJobTitle/InterviewExperiences/InterviewExperiences.js b/src/components/CompanyAndJobTitle/InterviewExperiences/InterviewExperiences.js index 793a66550..a36b713ab 100644 --- a/src/components/CompanyAndJobTitle/InterviewExperiences/InterviewExperiences.js +++ b/src/components/CompanyAndJobTitle/InterviewExperiences/InterviewExperiences.js @@ -10,7 +10,7 @@ import EmptyView from '../EmptyView'; import ExperienceEntry from './ExperienceEntry'; import { useQuery } from 'hooks/routing'; -import useIsMyExperienceId from 'components/ExperienceDetail/useIsMyExperienceId'; +import useIsMyPublishId from 'hooks/useIsMyPublishId'; const InterviewExperiences = ({ pageType, @@ -23,7 +23,7 @@ const InterviewExperiences = ({ canView, }) => { const queryParams = useQuery(); - const isMyExperienceId = useIsMyExperienceId(); + const isMyExperienceId = useIsMyPublishId(); if (data.length === 0) { return ( diff --git a/src/components/CompanyAndJobTitle/Overview/Overview.js b/src/components/CompanyAndJobTitle/Overview/Overview.js index 7bfe6ea92..9d9a9978f 100644 --- a/src/components/CompanyAndJobTitle/Overview/Overview.js +++ b/src/components/CompanyAndJobTitle/Overview/Overview.js @@ -9,7 +9,7 @@ import WorkExperienceEntry from '../WorkExperiences/ExperienceEntry'; import InterviewExperienceEntry from '../InterviewExperiences/ExperienceEntry'; import { tabType as TAB_TYPE, generateTabURL } from 'constants/companyJobTitle'; import SummaryBlock from './SummaryBlock'; -import useIsMyExperienceId from 'components/ExperienceDetail/useIsMyExperienceId'; +import useIsMyPublishId from 'hooks/useIsMyPublishId'; const Overview = ({ pageType, @@ -26,7 +26,7 @@ const Overview = ({ overtimeFrequencyCount, canView, }) => { - const isMyExperienceId = useIsMyExperienceId(); + const isMyExperienceId = useIsMyPublishId(); return (
diff --git a/src/components/CompanyAndJobTitle/TimeAndSalary/WorkingHourTable.js b/src/components/CompanyAndJobTitle/TimeAndSalary/WorkingHourTable.js index cd4c357a7..5c4bebbe8 100644 --- a/src/components/CompanyAndJobTitle/TimeAndSalary/WorkingHourTable.js +++ b/src/components/CompanyAndJobTitle/TimeAndSalary/WorkingHourTable.js @@ -19,7 +19,7 @@ import { formatDate, } from '../../TimeAndSalary/common/formatter'; import injectHideContentBlock from '../../TimeAndSalary/common/injectHideContentBlock'; -import useIsMySalaryWorkTimeId from './useIsMySalaryWorkTimeId'; +import useIsMyPublishId from 'hooks/useIsMyPublishId'; const SalaryHeader = ({ isInfoSalaryModalOpen, toggleInfoSalaryModal }) => ( @@ -158,7 +158,7 @@ const WorkingHourTable = ({ data, hideContent, pageType }) => { [filteredColumnProps], ); - const isMySalaryWorkTimeId = useIsMySalaryWorkTimeId(); + const isMyPublishId = useIsMyPublishId(); const postProcessRows = useCallback( (rows, data) => { @@ -168,12 +168,12 @@ const WorkingHourTable = ({ data, hideContent, pageType }) => { data, fromCol, toCol, - isMySalaryWorkTimeId, + isMyPublishId, }); } return rows; }, - [hideContent, fromCol, toCol, isMySalaryWorkTimeId], + [hideContent, fromCol, toCol, isMyPublishId], ); return ( diff --git a/src/components/CompanyAndJobTitle/TimeAndSalary/useIsMySalaryWorkTimeId.js b/src/components/CompanyAndJobTitle/TimeAndSalary/useIsMySalaryWorkTimeId.js deleted file mode 100644 index c6f6134af..000000000 --- a/src/components/CompanyAndJobTitle/TimeAndSalary/useIsMySalaryWorkTimeId.js +++ /dev/null @@ -1,32 +0,0 @@ -import { useCallback, useEffect } from 'react'; -import { queryMySalaryWorkTimesIdsApi } from 'apis/me'; -import { useToken } from 'hooks/auth'; -import { useAsyncFn } from 'react-use'; - -const useIsMySalaryWorkTimeId = () => { - const token = useToken(); - - const [{ value: mySalaryWorkTimeIds }, fetchMySalaryWorkTimeIds] = useAsyncFn( - () => - queryMySalaryWorkTimesIdsApi({ - token, - }), - [token], - ); - - useEffect(() => { - fetchMySalaryWorkTimeIds(); - }, [fetchMySalaryWorkTimeIds]); - - const isMySalaryWorkTimeId = useCallback( - id => { - if (!mySalaryWorkTimeIds) return false; - return mySalaryWorkTimeIds.includes(id); - }, - [mySalaryWorkTimeIds], - ); - - return isMySalaryWorkTimeId; -}; - -export default useIsMySalaryWorkTimeId; diff --git a/src/components/CompanyAndJobTitle/WorkExperiences/WorkExperiences.js b/src/components/CompanyAndJobTitle/WorkExperiences/WorkExperiences.js index 2c68522bc..28425b26d 100644 --- a/src/components/CompanyAndJobTitle/WorkExperiences/WorkExperiences.js +++ b/src/components/CompanyAndJobTitle/WorkExperiences/WorkExperiences.js @@ -8,7 +8,7 @@ import { Section } from 'common/base'; import Pagination from 'common/Pagination'; import NotFoundStatus from 'common/routing/NotFound'; import { useQuery } from 'hooks/routing'; -import useIsMyExperienceId from 'components/ExperienceDetail/useIsMyExperienceId'; +import useIsMyPublishId from 'hooks/useIsMyPublishId'; const WorkExperiences = ({ pageType, @@ -21,7 +21,7 @@ const WorkExperiences = ({ canView, }) => { const queryParams = useQuery(); - const isMyExperienceId = useIsMyExperienceId(); + const isMyExperienceId = useIsMyPublishId(); if (data.length === 0) { return ( diff --git a/src/components/ExperienceDetail/MoreExperiencesBlock/index.js b/src/components/ExperienceDetail/MoreExperiencesBlock/index.js index 4dd43d49c..772d5fe80 100644 --- a/src/components/ExperienceDetail/MoreExperiencesBlock/index.js +++ b/src/components/ExperienceDetail/MoreExperiencesBlock/index.js @@ -13,7 +13,7 @@ import { relatedExperiencesStateSelector } from 'selectors/experienceSelector'; import { pageType as PAGE_TYPE } from 'constants/companyJobTitle'; import Button from 'common/button/Button'; import styles from './MoreExperiencesBlock.module.css'; -import useIsMyExperienceId from '../useIsMyExperienceId'; +import useIsMyPublishId from 'hooks/useIsMyPublishId'; const ExperienceEntry = props => { switch (props.data.type) { @@ -58,7 +58,7 @@ const MoreExperiencesBlock = ({ experience }) => { [dispatch], ); - const isMyExperienceId = useIsMyExperienceId(); + const isMyExperienceId = useIsMyPublishId(); // we still want to show data even when Fetching if ( diff --git a/src/components/ExperienceDetail/index.js b/src/components/ExperienceDetail/index.js index 3c6bc7816..02892f595 100644 --- a/src/components/ExperienceDetail/index.js +++ b/src/components/ExperienceDetail/index.js @@ -48,7 +48,7 @@ import { generateBreadCrumbData } from '../CompanyAndJobTitle/utils'; import styles from './ExperienceDetail.module.css'; import { experienceBoxSelectorAtId } from 'selectors/experienceSelector'; import Button from 'common/button/Button'; -import useIsMyExperienceId from './useIsMyExperienceId'; +import useIsMyPublishId from 'hooks/useIsMyPublishId'; const MODAL_TYPE = { REPORT_DETAIL: 'REPORT_TYPE', @@ -81,7 +81,7 @@ const useExperienceBox = experienceId => { }; const useHideContent = ({ experienceId }) => { - const isMyExperienceId = useIsMyExperienceId(); + const isMyExperienceId = useIsMyPublishId(); const isMyPublish = useMemo(() => isMyExperienceId(experienceId), [ isMyExperienceId, diff --git a/src/components/ExperienceDetail/useIsMyExperienceId.js b/src/components/ExperienceDetail/useIsMyExperienceId.js deleted file mode 100644 index c27b5f780..000000000 --- a/src/components/ExperienceDetail/useIsMyExperienceId.js +++ /dev/null @@ -1,32 +0,0 @@ -import { useCallback, useEffect } from 'react'; -import { queryMyExperienceIdsApi } from 'apis/me'; -import { useToken } from 'hooks/auth'; -import { useAsyncFn } from 'react-use'; - -const useIsMyExperienceId = () => { - const token = useToken(); - - const [{ value: myExperienceIds }, fetchMyExperienceIds] = useAsyncFn( - () => - queryMyExperienceIdsApi({ - token, - }), - [token], - ); - - useEffect(() => { - fetchMyExperienceIds(); - }, [fetchMyExperienceIds]); - - const isMyExperienceId = useCallback( - experienceId => { - if (!myExperienceIds) return false; - return myExperienceIds.includes(experienceId); - }, - [myExperienceIds], - ); - - return isMyExperienceId; -}; - -export default useIsMyExperienceId; diff --git a/src/components/TimeAndSalary/common/injectHideContentBlock.js b/src/components/TimeAndSalary/common/injectHideContentBlock.js index ca33c93f1..0b585d7dc 100644 --- a/src/components/TimeAndSalary/common/injectHideContentBlock.js +++ b/src/components/TimeAndSalary/common/injectHideContentBlock.js @@ -4,7 +4,7 @@ import styles from './injectHideContentBlock.module.css'; import cn from 'classnames'; import { useShareLink } from 'hooks/experiments'; -export default ({ rows, data, fromCol, toCol, isMySalaryWorkTimeId }) => { +export default ({ rows, data, fromCol, toCol, isMyPublishId }) => { const nHides = toCol - fromCol + 1; const shareLink = useShareLink(); @@ -12,8 +12,8 @@ export default ({ rows, data, fromCol, toCol, isMySalaryWorkTimeId }) => { // on small screens rows.forEach((row, i) => { const d = data[i]; - const isMySalaryWorkTime = isMySalaryWorkTimeId(d.id); - if (isMySalaryWorkTime) return; + const isMyPublish = isMyPublishId(d.id); + if (isMyPublish) return; row.props.children.splice( fromCol, @@ -38,8 +38,8 @@ export default ({ rows, data, fromCol, toCol, isMySalaryWorkTimeId }) => { if (rows.length > 0) { for (let i = 0; i < rows.length; i++) { const d = data[i]; - const isMySalaryWorkTime = isMySalaryWorkTimeId(d.id); - if (isMySalaryWorkTime) continue; + const isMyPublish = isMyPublishId(d.id); + if (isMyPublish) continue; const row = rows[i]; row.props.children.splice( diff --git a/src/graphql/me.js b/src/graphql/me.js index 3de459b21..1a934f556 100644 --- a/src/graphql/me.js +++ b/src/graphql/me.js @@ -19,19 +19,12 @@ export const queryMeGql = /* GraphQL */ ` } `; -export const queryMyExperienceIdsGql = /* GraphQL */ ` +export const queryMyPublishIdsGql = /* GraphQL */ ` query MyPublishes { me { experiences { id } - } - } -`; - -export const queryMySalaryWorkTimesIdsGql = /* GraphQL */ ` - query MyPublishes { - me { salary_work_times { id } diff --git a/src/hooks/useIsMyPublishId.js b/src/hooks/useIsMyPublishId.js new file mode 100644 index 000000000..884126682 --- /dev/null +++ b/src/hooks/useIsMyPublishId.js @@ -0,0 +1,36 @@ +import { useCallback, useEffect } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import { myPublishIdsSelector } from 'selectors/me'; +import { queryMyPublishIds } from 'actions/me'; +import { isError, isFetched, isUnfetched } from 'utils/fetchBox'; + +const useIsMyPublishId = () => { + const myPublishIdsBox = useSelector(myPublishIdsSelector); + const dispatch = useDispatch(); + + useEffect(() => { + if (isUnfetched(myPublishIdsBox) || isError(myPublishIdsBox)) { + dispatch(queryMyPublishIds()); + } + }, [dispatch, myPublishIdsBox]); + + const useIsMyPublishId = useCallback( + publishId => { + if (!isFetched(myPublishIdsBox)) { + return false; + } + + const myPublishIds = myPublishIdsBox.data; + if (!myPublishIds) { + return false; + } + + return myPublishIds.includes(publishId); + }, + [myPublishIdsBox], + ); + + return useIsMyPublishId; +}; + +export default useIsMyPublishId; diff --git a/src/reducers/index.js b/src/reducers/index.js index 854f57e06..53da2c421 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -3,6 +3,7 @@ import { persistReducer } from 'redux-persist'; import storage from 'redux-persist/lib/storage'; import auth from './auth'; +import me from './me'; import experience from './experience'; import experiences from './experiences'; import laborRights from './laborRights'; @@ -26,6 +27,7 @@ const persistConfig = { const rootReducer = combineReducers({ auth, + me, experience, experiences, laborRights, diff --git a/src/reducers/me.js b/src/reducers/me.js new file mode 100644 index 000000000..73bbc983a --- /dev/null +++ b/src/reducers/me.js @@ -0,0 +1,16 @@ +import createReducer from 'utils/createReducer'; +import { SET_MY_PUBLISH_IDS } from 'actions/me'; +import { getUnfetched } from 'utils/fetchBox'; + +const preloadedState = { + myPublishIds: getUnfetched(), +}; + +const me = createReducer(preloadedState, { + [SET_MY_PUBLISH_IDS]: (state, { box }) => ({ + ...state, + myPublishIds: box, + }), +}); + +export default me; diff --git a/src/selectors/me.js b/src/selectors/me.js new file mode 100644 index 000000000..54f5755bc --- /dev/null +++ b/src/selectors/me.js @@ -0,0 +1 @@ +export const myPublishIdsSelector = state => state.me.myPublishIds; From b50940ef09323046f6d642636fda665d9ea112f8 Mon Sep 17 00:00:00 2001 From: Peteranny Date: Fri, 20 Sep 2024 00:45:57 +0800 Subject: [PATCH 08/22] re-query my publish ids on create --- src/actions/experiences.js | 31 +++++++++++++++++++++++++------ src/actions/timeAndSalary.js | 12 ++++++++++-- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/src/actions/experiences.js b/src/actions/experiences.js index dfef09a69..d7140ef76 100644 --- a/src/actions/experiences.js +++ b/src/actions/experiences.js @@ -7,6 +7,7 @@ import { postWorkExperience as postWorkExperienceApi, postWorkExperienceWithRating as postWorkExperienceWithRatingApi, } from 'apis/workExperiencesApi'; +import { queryMyPublishIds } from './me'; export const SET_COUNT = '@@EXPERIENCES/SET_COUNT'; @@ -34,35 +35,53 @@ export const queryExperienceCountIfUnfetched = () => async ( } }; -export const createInterviewExperience = ({ body }) => (dispatch, getState) => { +export const createInterviewExperience = ({ body }) => async ( + dispatch, + getState, +) => { const state = getState(); const token = tokenSelector(state); - return postInterviewExperienceApi({ + const result = await postInterviewExperienceApi({ body, token, }); + + await dispatch(queryMyPublishIds()); + + return result; }; -export const createWorkExperience = ({ body }) => (dispatch, getState) => { +export const createWorkExperience = ({ body }) => async ( + dispatch, + getState, +) => { const state = getState(); const token = tokenSelector(state); - return postWorkExperienceApi({ + const result = await postWorkExperienceApi({ body, token, }); + + await dispatch(queryMyPublishIds()); + + return result; }; -export const createWorkExperienceWithRating = ({ body }) => ( +export const createWorkExperienceWithRating = ({ body }) => async ( dispatch, getState, ) => { const state = getState(); const token = tokenSelector(state); - return postWorkExperienceWithRatingApi({ + const result = await postWorkExperienceWithRatingApi({ body, token, }); + + await dispatch(queryMyPublishIds()); + + return result; }; diff --git a/src/actions/timeAndSalary.js b/src/actions/timeAndSalary.js index 849bb18ab..3eb183889 100644 --- a/src/actions/timeAndSalary.js +++ b/src/actions/timeAndSalary.js @@ -3,6 +3,7 @@ import { tokenSelector } from 'selectors/authSelector'; import { salaryWorkTimeCountBoxSelector } from 'selectors/countSelector'; import { postWorkings as postWorkingsApi } from 'apis/timeAndSalaryApi'; import { querySalaryWorkTimeCountApi } from 'apis/salaryWorkTimeApi'; +import { queryMyPublishIds } from './me'; export const SET_COUNT = '@@SALARY_WORK_TIME/SET_COUNT'; @@ -30,12 +31,19 @@ export const querySalaryWorkTimeCountIfUnfetched = () => async ( } }; -export const createSalaryWorkTime = ({ body }) => (dispatch, getState) => { +export const createSalaryWorkTime = ({ body }) => async ( + dispatch, + getState, +) => { const state = getState(); const token = tokenSelector(state); - return postWorkingsApi({ + const result = await postWorkingsApi({ body, token, }); + + await dispatch(queryMyPublishIds()); + + return result; }; From 98151680bfbc2d1d43078f201e0f5587bd052124 Mon Sep 17 00:00:00 2001 From: Peteranny Date: Fri, 20 Sep 2024 00:56:03 +0800 Subject: [PATCH 09/22] do not fetch on no token --- src/actions/me.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/actions/me.js b/src/actions/me.js index e5d4f6406..d4d4ef794 100644 --- a/src/actions/me.js +++ b/src/actions/me.js @@ -11,6 +11,11 @@ const setMyPublishIds = box => ({ export const queryMyPublishIds = () => async (dispatch, getState) => { const token = tokenSelector(getState()); + if (!token) { + dispatch(setMyPublishIds(getFetched([]))); + return; + } + dispatch(setMyPublishIds(toFetching())); try { const myPublishIds = await queryMyPublishIdsApi({ token }); From 37da68b0b2dee0d93c27dacfa9c4b623296a24e8 Mon Sep 17 00:00:00 2001 From: Peteranny Date: Fri, 20 Sep 2024 01:00:05 +0800 Subject: [PATCH 10/22] remove unused code --- src/hooks/useIsMyPublishId.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/hooks/useIsMyPublishId.js b/src/hooks/useIsMyPublishId.js index 884126682..ee01383d8 100644 --- a/src/hooks/useIsMyPublishId.js +++ b/src/hooks/useIsMyPublishId.js @@ -21,10 +21,6 @@ const useIsMyPublishId = () => { } const myPublishIds = myPublishIdsBox.data; - if (!myPublishIds) { - return false; - } - return myPublishIds.includes(publishId); }, [myPublishIdsBox], From 42e8ff8ac44eed9fd82b2199140a683376e73134 Mon Sep 17 00:00:00 2001 From: Peteranny Date: Fri, 20 Sep 2024 01:11:13 +0800 Subject: [PATCH 11/22] reset on login --- src/reducers/me.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/reducers/me.js b/src/reducers/me.js index 73bbc983a..a61fad46c 100644 --- a/src/reducers/me.js +++ b/src/reducers/me.js @@ -1,6 +1,7 @@ import createReducer from 'utils/createReducer'; import { SET_MY_PUBLISH_IDS } from 'actions/me'; import { getUnfetched } from 'utils/fetchBox'; +import { SET_LOGIN } from 'actions/auth'; const preloadedState = { myPublishIds: getUnfetched(), @@ -11,6 +12,10 @@ const me = createReducer(preloadedState, { ...state, myPublishIds: box, }), + [SET_LOGIN]: state => ({ + ...state, + myPublishIds: getUnfetched(), + }), }); export default me; From ad126984ba5bafa1a5e60d270cd949fdd3047cd4 Mon Sep 17 00:00:00 2001 From: Peteranny Date: Fri, 20 Sep 2024 01:36:03 +0800 Subject: [PATCH 12/22] put hide-content in permission --- src/components/ExperienceDetail/index.js | 26 ++---------------------- src/hooks/usePermission.js | 15 +++++++++++--- 2 files changed, 14 insertions(+), 27 deletions(-) diff --git a/src/components/ExperienceDetail/index.js b/src/components/ExperienceDetail/index.js index 02892f595..d95ef1229 100644 --- a/src/components/ExperienceDetail/index.js +++ b/src/components/ExperienceDetail/index.js @@ -48,7 +48,6 @@ import { generateBreadCrumbData } from '../CompanyAndJobTitle/utils'; import styles from './ExperienceDetail.module.css'; import { experienceBoxSelectorAtId } from 'selectors/experienceSelector'; import Button from 'common/button/Button'; -import useIsMyPublishId from 'hooks/useIsMyPublishId'; const MODAL_TYPE = { REPORT_DETAIL: 'REPORT_TYPE', @@ -80,27 +79,6 @@ const useExperienceBox = experienceId => { return useSelector(selector); }; -const useHideContent = ({ experienceId }) => { - const isMyExperienceId = useIsMyPublishId(); - - const isMyPublish = useMemo(() => isMyExperienceId(experienceId), [ - isMyExperienceId, - experienceId, - ]); - - const [, fetchPermission, canView] = usePermission(); - - useEffect(() => { - fetchPermission(); - }, [experienceId, fetchPermission]); - - const hideContent = useMemo(() => { - return !isMyPublish && !canView; - }, [isMyPublish, canView]); - - return hideContent; -}; - const ExperienceDetail = ({ ...props }) => { const experienceId = useExperienceId(); const experienceBox = useExperienceBox(experienceId); @@ -111,7 +89,7 @@ const ExperienceDetail = ({ ...props }) => { dispatch(queryExperienceIfUnfetched(experienceId)); }, [dispatch, experienceId]); - const hideContent = useHideContent({ experienceId }); + const [, , canView] = usePermission({ publishId: experienceId }); const [{ isModalOpen, modalType, modalPayload = {} }, setModal] = useState({ isModalOpen: false, @@ -259,7 +237,7 @@ const ExperienceDetail = ({ ...props }) => { {reportZone}
diff --git a/src/hooks/usePermission.js b/src/hooks/usePermission.js index 2dfb0e7af..e4a3b22ac 100644 --- a/src/hooks/usePermission.js +++ b/src/hooks/usePermission.js @@ -1,7 +1,8 @@ -import { useContext, useCallback } from 'react'; +import { useContext, useCallback, useMemo } from 'react'; import PermissionContext from 'contexts/PermissionContext'; import { useToken } from 'hooks/auth'; import { queryHasSearchPermissionApi } from 'apis/me'; +import useIsMyPublishId from './useIsMyPublishId'; const useGetSearchPermission = ({ token }) => { return useCallback(async () => { @@ -11,7 +12,13 @@ const useGetSearchPermission = ({ token }) => { }, [token]); }; -export default () => { +const usePermission = ({ publishId } = {}) => { + const isMyPublishId = useIsMyPublishId(); + const isMyPublish = useMemo(() => !!publishId && isMyPublishId(publishId), [ + isMyPublishId, + publishId, + ]); + const token = useToken(); const { canView, permissionFetched, setPermissionState } = useContext( PermissionContext, @@ -36,5 +43,7 @@ export default () => { } } }, [getSearchPermission, setPermissionState]); - return [permissionFetched, fetchPermission, canView]; + return [permissionFetched, fetchPermission, isMyPublish || canView]; }; + +export default usePermission; From 7a3a522d356395c745cf958eb735e4d178d66499 Mon Sep 17 00:00:00 2001 From: Peteranny Date: Sun, 22 Sep 2024 01:21:13 +0800 Subject: [PATCH 13/22] add comment --- src/actions/me.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/actions/me.js b/src/actions/me.js index d4d4ef794..a4009e623 100644 --- a/src/actions/me.js +++ b/src/actions/me.js @@ -12,6 +12,7 @@ const setMyPublishIds = box => ({ export const queryMyPublishIds = () => async (dispatch, getState) => { const token = tokenSelector(getState()); if (!token) { + // If user has not logged in, it's assumed to have no publishes. dispatch(setMyPublishIds(getFetched([]))); return; } From 0fdd8a798656ed2206ea884b3f0ff1feb7781a0d Mon Sep 17 00:00:00 2001 From: Peteranny Date: Sun, 22 Sep 2024 01:25:47 +0800 Subject: [PATCH 14/22] query-if-needed --- src/actions/me.js | 17 ++++++++++++++++- src/hooks/useIsMyPublishId.js | 8 +++----- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/actions/me.js b/src/actions/me.js index a4009e623..fa6360006 100644 --- a/src/actions/me.js +++ b/src/actions/me.js @@ -1,6 +1,13 @@ import { queryMyPublishIdsApi } from 'apis/me'; import { tokenSelector } from 'selectors/authSelector'; -import { getError, getFetched, toFetching } from 'utils/fetchBox'; +import { myPublishIdsSelector } from 'selectors/me'; +import { + isUnfetched, + isError, + getError, + getFetched, + toFetching, +} from 'utils/fetchBox'; export const SET_MY_PUBLISH_IDS = '@@me/SET_MY_PUBLISH_IDS'; @@ -9,6 +16,14 @@ const setMyPublishIds = box => ({ box, }); +export const queryMyPublishIdsIfNeeded = () => async (dispatch, getState) => { + const myPublishIdsBox = myPublishIdsSelector(getState()); + + if (isUnfetched(myPublishIdsBox) || isError(myPublishIdsBox)) { + dispatch(queryMyPublishIds()); + } +}; + export const queryMyPublishIds = () => async (dispatch, getState) => { const token = tokenSelector(getState()); if (!token) { diff --git a/src/hooks/useIsMyPublishId.js b/src/hooks/useIsMyPublishId.js index ee01383d8..b96d5e286 100644 --- a/src/hooks/useIsMyPublishId.js +++ b/src/hooks/useIsMyPublishId.js @@ -1,17 +1,15 @@ import { useCallback, useEffect } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { myPublishIdsSelector } from 'selectors/me'; -import { queryMyPublishIds } from 'actions/me'; -import { isError, isFetched, isUnfetched } from 'utils/fetchBox'; +import { queryMyPublishIdsIfNeeded } from 'actions/me'; +import { isFetched } from 'utils/fetchBox'; const useIsMyPublishId = () => { const myPublishIdsBox = useSelector(myPublishIdsSelector); const dispatch = useDispatch(); useEffect(() => { - if (isUnfetched(myPublishIdsBox) || isError(myPublishIdsBox)) { - dispatch(queryMyPublishIds()); - } + dispatch(queryMyPublishIdsIfNeeded()); }, [dispatch, myPublishIdsBox]); const useIsMyPublishId = useCallback( From 34e7e8c3a7e47d65ac12030b9d25af6dd8fb579b Mon Sep 17 00:00:00 2001 From: Peteranny Date: Sun, 22 Sep 2024 01:29:05 +0800 Subject: [PATCH 15/22] remove unneeded dep --- src/hooks/useIsMyPublishId.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hooks/useIsMyPublishId.js b/src/hooks/useIsMyPublishId.js index b96d5e286..ec4e20e42 100644 --- a/src/hooks/useIsMyPublishId.js +++ b/src/hooks/useIsMyPublishId.js @@ -10,7 +10,7 @@ const useIsMyPublishId = () => { useEffect(() => { dispatch(queryMyPublishIdsIfNeeded()); - }, [dispatch, myPublishIdsBox]); + }, [dispatch]); const useIsMyPublishId = useCallback( publishId => { From b2ac7b355a6b69568cebbf33438596d42607eaeb Mon Sep 17 00:00:00 2001 From: Peteranny Date: Sun, 22 Sep 2024 23:01:18 +0800 Subject: [PATCH 16/22] rename --- src/hooks/useIsMyPublishId.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hooks/useIsMyPublishId.js b/src/hooks/useIsMyPublishId.js index ec4e20e42..2df250078 100644 --- a/src/hooks/useIsMyPublishId.js +++ b/src/hooks/useIsMyPublishId.js @@ -12,7 +12,7 @@ const useIsMyPublishId = () => { dispatch(queryMyPublishIdsIfNeeded()); }, [dispatch]); - const useIsMyPublishId = useCallback( + const isMyPublishId = useCallback( publishId => { if (!isFetched(myPublishIdsBox)) { return false; @@ -24,7 +24,7 @@ const useIsMyPublishId = () => { [myPublishIdsBox], ); - return useIsMyPublishId; + return isMyPublishId; }; export default useIsMyPublishId; From 2ce54282d7b68eea4ee5527bbbdeb7082b92dd56 Mon Sep 17 00:00:00 2001 From: Peteranny Date: Sun, 22 Sep 2024 23:07:40 +0800 Subject: [PATCH 17/22] fix behavior change --- src/components/ExperienceDetail/index.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/components/ExperienceDetail/index.js b/src/components/ExperienceDetail/index.js index d95ef1229..08134a287 100644 --- a/src/components/ExperienceDetail/index.js +++ b/src/components/ExperienceDetail/index.js @@ -89,7 +89,13 @@ const ExperienceDetail = ({ ...props }) => { dispatch(queryExperienceIfUnfetched(experienceId)); }, [dispatch, experienceId]); - const [, , canView] = usePermission({ publishId: experienceId }); + const [, fetchPermission, canView] = usePermission({ + publishId: experienceId, + }); + + useEffect(() => { + fetchPermission(); + }, [experienceId, fetchPermission]); const [{ isModalOpen, modalType, modalPayload = {} }, setModal] = useState({ isModalOpen: false, From d31db76878e646f2c0c9c8ccc2c095509120702c Mon Sep 17 00:00:00 2001 From: Peteranny Date: Sun, 22 Sep 2024 23:13:10 +0800 Subject: [PATCH 18/22] canView -> canViewPublishId --- .../InterviewExperiences.js | 8 +++--- .../InterviewExperiences/index.js | 3 --- .../CompanyAndJobTitle/Overview/Overview.js | 16 ++++-------- .../CompanyAndJobTitle/Overview/index.js | 11 +------- .../TimeAndSalary/TimeAndSalary.js | 9 ++----- .../TimeAndSalary/WorkingHourBlock.js | 9 ++----- .../TimeAndSalary/WorkingHourTable.js | 25 ++++++++----------- .../WorkExperiences/WorkExperiences.js | 8 +++--- .../WorkExperiences/index.js | 3 --- .../MoreExperiencesBlock/index.js | 7 ++---- src/components/ExperienceDetail/index.js | 4 +-- .../common/injectHideContentBlock.js | 6 ++--- src/hooks/usePermission.js | 20 ++++++++------- .../CompanyInterviewExperiencesProvider.js | 3 +-- src/pages/Company/CompanyOverviewProvider.js | 3 +-- .../Company/CompanyWorkExperiencesProvider.js | 3 +-- .../JobTitleInterviewExperiencesProvider.js | 3 +-- .../JobTitle/JobTitleOverviewProvider.js | 3 +-- .../JobTitleWorkExperiencesProvider.js | 3 +-- 19 files changed, 51 insertions(+), 96 deletions(-) diff --git a/src/components/CompanyAndJobTitle/InterviewExperiences/InterviewExperiences.js b/src/components/CompanyAndJobTitle/InterviewExperiences/InterviewExperiences.js index a36b713ab..93fce2c0e 100644 --- a/src/components/CompanyAndJobTitle/InterviewExperiences/InterviewExperiences.js +++ b/src/components/CompanyAndJobTitle/InterviewExperiences/InterviewExperiences.js @@ -10,7 +10,7 @@ import EmptyView from '../EmptyView'; import ExperienceEntry from './ExperienceEntry'; import { useQuery } from 'hooks/routing'; -import useIsMyPublishId from 'hooks/useIsMyPublishId'; +import usePermission from 'hooks/usePermission'; const InterviewExperiences = ({ pageType, @@ -20,10 +20,9 @@ const InterviewExperiences = ({ page, pageSize, totalCount, - canView, }) => { const queryParams = useQuery(); - const isMyExperienceId = useIsMyPublishId(); + const [, , canViewPublishId] = usePermission(); if (data.length === 0) { return ( @@ -41,7 +40,7 @@ const InterviewExperiences = ({ key={d.id} pageType={pageType} data={d} - canView={isMyExperienceId(d.id) || canView} + canView={canViewPublishId(d.id)} /> ))} ( ); @@ -53,7 +51,6 @@ const InterviewExperiences = ({ ); InterviewExperiences.propTypes = { - canView: PropTypes.bool.isRequired, interviewExperiences: PropTypes.arrayOf(PropTypes.object), page: PropTypes.number.isRequired, pageName: PropTypes.string.isRequired, diff --git a/src/components/CompanyAndJobTitle/Overview/Overview.js b/src/components/CompanyAndJobTitle/Overview/Overview.js index 9d9a9978f..fefe33a38 100644 --- a/src/components/CompanyAndJobTitle/Overview/Overview.js +++ b/src/components/CompanyAndJobTitle/Overview/Overview.js @@ -9,7 +9,7 @@ import WorkExperienceEntry from '../WorkExperiences/ExperienceEntry'; import InterviewExperienceEntry from '../InterviewExperiences/ExperienceEntry'; import { tabType as TAB_TYPE, generateTabURL } from 'constants/companyJobTitle'; import SummaryBlock from './SummaryBlock'; -import useIsMyPublishId from 'hooks/useIsMyPublishId'; +import usePermission from 'hooks/usePermission'; const Overview = ({ pageType, @@ -24,9 +24,8 @@ const Overview = ({ jobAverageSalaries, averageWeekWorkTime, overtimeFrequencyCount, - canView, }) => { - const isMyExperienceId = useIsMyPublishId(); + const [, , canViewPublishId] = usePermission(); return (
@@ -49,11 +48,7 @@ const Overview = ({ averageWeekWorkTime={averageWeekWorkTime} overtimeFrequencyCount={overtimeFrequencyCount} /> - + ))} @@ -95,7 +90,7 @@ const Overview = ({ key={d.id} pageType={pageType} data={d} - canView={isMyExperienceId(d.id) || canView} + canView={canViewPublishId(d.id)} /> ))} @@ -105,7 +100,6 @@ const Overview = ({ Overview.propTypes = { averageWeekWorkTime: PropTypes.number.isRequired, - canView: PropTypes.bool.isRequired, interviewExperiences: PropTypes.arrayOf(PropTypes.object), interviewExperiencesCount: PropTypes.number.isRequired, jobAverageSalaries: PropTypes.array, diff --git a/src/components/CompanyAndJobTitle/Overview/index.js b/src/components/CompanyAndJobTitle/Overview/index.js index 81e1da0f4..c2f65c981 100644 --- a/src/components/CompanyAndJobTitle/Overview/index.js +++ b/src/components/CompanyAndJobTitle/Overview/index.js @@ -5,14 +5,7 @@ import { BoxStatusRenderer } from '../StatusRenderer'; import OverviewSection from './Overview'; import Helmet from './Helmet'; -const Overview = ({ - pageType, - pageName, - tabType, - overviewBox, - page, - canView, -}) => ( +const Overview = ({ pageType, pageName, tabType, overviewBox, page }) => ( ); @@ -58,7 +50,6 @@ const Overview = ({ ); Overview.propTypes = { - canView: PropTypes.bool.isRequired, overviewBox: PropTypes.shape({ data: PropTypes.shape({ averageWeekWorkTime: PropTypes.number.isRequired, diff --git a/src/components/CompanyAndJobTitle/TimeAndSalary/TimeAndSalary.js b/src/components/CompanyAndJobTitle/TimeAndSalary/TimeAndSalary.js index 07431b6ef..a9050f73d 100644 --- a/src/components/CompanyAndJobTitle/TimeAndSalary/TimeAndSalary.js +++ b/src/components/CompanyAndJobTitle/TimeAndSalary/TimeAndSalary.js @@ -20,7 +20,7 @@ const TimeAndSalary = ({ pageSize, totalCount, }) => { - const [, fetchPermission, canView] = usePermission(); + const [, fetchPermission] = usePermission(); useEffect(() => { fetchPermission(); }, [fetchPermission]); @@ -31,12 +31,7 @@ const TimeAndSalary = ({
{(salaryWorkTimes.length > 0 && ( - + { +const WorkingHourBlock = ({ data, pageType }) => { return (
- +
); @@ -21,7 +17,6 @@ const WorkingHourBlock = ({ data, hideContent, pageType }) => { WorkingHourBlock.propTypes = { data: PropTypes.array, - hideContent: PropTypes.bool.isRequired, pageType: PropTypes.string, }; diff --git a/src/components/CompanyAndJobTitle/TimeAndSalary/WorkingHourTable.js b/src/components/CompanyAndJobTitle/TimeAndSalary/WorkingHourTable.js index 5c4bebbe8..d44ac6615 100644 --- a/src/components/CompanyAndJobTitle/TimeAndSalary/WorkingHourTable.js +++ b/src/components/CompanyAndJobTitle/TimeAndSalary/WorkingHourTable.js @@ -19,7 +19,7 @@ import { formatDate, } from '../../TimeAndSalary/common/formatter'; import injectHideContentBlock from '../../TimeAndSalary/common/injectHideContentBlock'; -import useIsMyPublishId from 'hooks/useIsMyPublishId'; +import usePermission from 'hooks/usePermission'; const SalaryHeader = ({ isInfoSalaryModalOpen, toggleInfoSalaryModal }) => ( @@ -128,7 +128,7 @@ const columnProps = [ }, ]; -const WorkingHourTable = ({ data, hideContent, pageType }) => { +const WorkingHourTable = ({ data, pageType }) => { const [isInfoSalaryModalOpen, setInfoSalaryModalOpen] = useState(false); const [isInfoTimeModalOpen, setInfoTiimeModalOpen] = useState(false); @@ -158,22 +158,20 @@ const WorkingHourTable = ({ data, hideContent, pageType }) => { [filteredColumnProps], ); - const isMyPublishId = useIsMyPublishId(); + const [, , canViewPublishId] = usePermission(); const postProcessRows = useCallback( (rows, data) => { - if (hideContent) { - injectHideContentBlock({ - rows, - data, - fromCol, - toCol, - isMyPublishId, - }); - } + injectHideContentBlock({ + rows, + data, + fromCol, + toCol, + canViewPublishId, + }); return rows; }, - [hideContent, fromCol, toCol, isMyPublishId], + [canViewPublishId, fromCol, toCol], ); return ( @@ -202,7 +200,6 @@ const WorkingHourTable = ({ data, hideContent, pageType }) => { WorkingHourTable.propTypes = { data: PropTypes.array.isRequired, - hideContent: PropTypes.bool.isRequired, pageType: PropTypes.oneOf([ pageTypeMapping.COMPANY, pageTypeMapping.JOB_TITLE, diff --git a/src/components/CompanyAndJobTitle/WorkExperiences/WorkExperiences.js b/src/components/CompanyAndJobTitle/WorkExperiences/WorkExperiences.js index 28425b26d..9054f14ef 100644 --- a/src/components/CompanyAndJobTitle/WorkExperiences/WorkExperiences.js +++ b/src/components/CompanyAndJobTitle/WorkExperiences/WorkExperiences.js @@ -8,7 +8,7 @@ import { Section } from 'common/base'; import Pagination from 'common/Pagination'; import NotFoundStatus from 'common/routing/NotFound'; import { useQuery } from 'hooks/routing'; -import useIsMyPublishId from 'hooks/useIsMyPublishId'; +import usePermission from 'hooks/usePermission'; const WorkExperiences = ({ pageType, @@ -18,10 +18,9 @@ const WorkExperiences = ({ page, pageSize, totalCount, - canView, }) => { const queryParams = useQuery(); - const isMyExperienceId = useIsMyPublishId(); + const [, , canViewPublishId] = usePermission(); if (data.length === 0) { return ( @@ -39,7 +38,7 @@ const WorkExperiences = ({ key={d.id} pageType={pageType} data={d} - canView={isMyExperienceId(d.id) || canView} + canView={canViewPublishId(d.id)} /> ))} ( ); @@ -53,7 +51,6 @@ const WorkExperiences = ({ ); WorkExperiences.propTypes = { - canView: PropTypes.bool.isRequired, page: PropTypes.number.isRequired, pageName: PropTypes.string.isRequired, pageSize: PropTypes.number.isRequired, diff --git a/src/components/ExperienceDetail/MoreExperiencesBlock/index.js b/src/components/ExperienceDetail/MoreExperiencesBlock/index.js index 772d5fe80..56ca71890 100644 --- a/src/components/ExperienceDetail/MoreExperiencesBlock/index.js +++ b/src/components/ExperienceDetail/MoreExperiencesBlock/index.js @@ -13,7 +13,6 @@ import { relatedExperiencesStateSelector } from 'selectors/experienceSelector'; import { pageType as PAGE_TYPE } from 'constants/companyJobTitle'; import Button from 'common/button/Button'; import styles from './MoreExperiencesBlock.module.css'; -import useIsMyPublishId from 'hooks/useIsMyPublishId'; const ExperienceEntry = props => { switch (props.data.type) { @@ -52,14 +51,12 @@ const MoreExperiencesBlock = ({ experience }) => { const location = useLocation(); const { state: { pageType = PAGE_TYPE.COMPANY } = {} } = location; - const [, , canView] = usePermission(); + const [, , canViewPublishId] = usePermission(); const handleLoadMore = useCallback( () => dispatch(loadMoreRelatedExperiences()), [dispatch], ); - const isMyExperienceId = useIsMyPublishId(); - // we still want to show data even when Fetching if ( !relatedExperiencesState.data || @@ -86,7 +83,7 @@ const MoreExperiencesBlock = ({ experience }) => { key={e.id} pageType={pageType} data={e} - canView={isMyExperienceId(e.id) || canView} + canView={canViewPublishId(e.id)} /> ))} {hasMore && } diff --git a/src/components/ExperienceDetail/index.js b/src/components/ExperienceDetail/index.js index 08134a287..ecbb657e1 100644 --- a/src/components/ExperienceDetail/index.js +++ b/src/components/ExperienceDetail/index.js @@ -89,7 +89,7 @@ const ExperienceDetail = ({ ...props }) => { dispatch(queryExperienceIfUnfetched(experienceId)); }, [dispatch, experienceId]); - const [, fetchPermission, canView] = usePermission({ + const [, fetchPermission, canViewPublishId] = usePermission({ publishId: experienceId, }); @@ -243,7 +243,7 @@ const ExperienceDetail = ({ ...props }) => { {reportZone}
diff --git a/src/components/TimeAndSalary/common/injectHideContentBlock.js b/src/components/TimeAndSalary/common/injectHideContentBlock.js index 0b585d7dc..fdcaa3cf0 100644 --- a/src/components/TimeAndSalary/common/injectHideContentBlock.js +++ b/src/components/TimeAndSalary/common/injectHideContentBlock.js @@ -4,7 +4,7 @@ import styles from './injectHideContentBlock.module.css'; import cn from 'classnames'; import { useShareLink } from 'hooks/experiments'; -export default ({ rows, data, fromCol, toCol, isMyPublishId }) => { +export default ({ rows, data, fromCol, toCol, canViewPublishId }) => { const nHides = toCol - fromCol + 1; const shareLink = useShareLink(); @@ -12,7 +12,7 @@ export default ({ rows, data, fromCol, toCol, isMyPublishId }) => { // on small screens rows.forEach((row, i) => { const d = data[i]; - const isMyPublish = isMyPublishId(d.id); + const isMyPublish = canViewPublishId(d.id); if (isMyPublish) return; row.props.children.splice( @@ -38,7 +38,7 @@ export default ({ rows, data, fromCol, toCol, isMyPublishId }) => { if (rows.length > 0) { for (let i = 0; i < rows.length; i++) { const d = data[i]; - const isMyPublish = isMyPublishId(d.id); + const isMyPublish = canViewPublishId(d.id); if (isMyPublish) continue; const row = rows[i]; diff --git a/src/hooks/usePermission.js b/src/hooks/usePermission.js index e4a3b22ac..b3d1a4db1 100644 --- a/src/hooks/usePermission.js +++ b/src/hooks/usePermission.js @@ -1,4 +1,4 @@ -import { useContext, useCallback, useMemo } from 'react'; +import { useContext, useCallback } from 'react'; import PermissionContext from 'contexts/PermissionContext'; import { useToken } from 'hooks/auth'; import { queryHasSearchPermissionApi } from 'apis/me'; @@ -12,13 +12,7 @@ const useGetSearchPermission = ({ token }) => { }, [token]); }; -const usePermission = ({ publishId } = {}) => { - const isMyPublishId = useIsMyPublishId(); - const isMyPublish = useMemo(() => !!publishId && isMyPublishId(publishId), [ - isMyPublishId, - publishId, - ]); - +const usePermission = () => { const token = useToken(); const { canView, permissionFetched, setPermissionState } = useContext( PermissionContext, @@ -43,7 +37,15 @@ const usePermission = ({ publishId } = {}) => { } } }, [getSearchPermission, setPermissionState]); - return [permissionFetched, fetchPermission, isMyPublish || canView]; + + const isMyPublishId = useIsMyPublishId(); + + const canViewPublishId = useCallback( + publishId => isMyPublishId(publishId) || canView, + [canView, isMyPublishId], + ); + + return [permissionFetched, fetchPermission, canViewPublishId]; }; export default usePermission; diff --git a/src/pages/Company/CompanyInterviewExperiencesProvider.js b/src/pages/Company/CompanyInterviewExperiencesProvider.js index 68f9e3b58..07a838c20 100644 --- a/src/pages/Company/CompanyInterviewExperiencesProvider.js +++ b/src/pages/Company/CompanyInterviewExperiencesProvider.js @@ -58,7 +58,7 @@ const CompanyInterviewExperiencesProvider = () => { ); }, [dispatch, pageName, jobTitle, start, limit]); - const [, fetchPermission, canView] = usePermission(); + const [, fetchPermission] = usePermission(); useEffect(() => { fetchPermission(); }, [pageType, pageName, fetchPermission]); @@ -76,7 +76,6 @@ const CompanyInterviewExperiencesProvider = () => { page={page} pageSize={PAGE_SIZE} totalCount={interviewExperiencesCount} - canView={canView} tabType={tabType.INTERVIEW_EXPERIENCE} status={status} interviewExperiences={interviewExperiences} diff --git a/src/pages/Company/CompanyOverviewProvider.js b/src/pages/Company/CompanyOverviewProvider.js index 7bafd5ad1..bf84551cc 100644 --- a/src/pages/Company/CompanyOverviewProvider.js +++ b/src/pages/Company/CompanyOverviewProvider.js @@ -48,7 +48,7 @@ const CompanyOverviewProvider = () => { dispatch(queryCompanyOverview(pageName)); }, [dispatch, pageName]); - const [, fetchPermission, canView] = usePermission(); + const [, fetchPermission] = usePermission(); useEffect(() => { fetchPermission(); }, [pageType, pageName, fetchPermission]); @@ -62,7 +62,6 @@ const CompanyOverviewProvider = () => { tabType={tabType.OVERVIEW} overviewBox={overviewBox} page={page} - canView={canView} /> ); }; diff --git a/src/pages/Company/CompanyWorkExperiencesProvider.js b/src/pages/Company/CompanyWorkExperiencesProvider.js index d17630aed..01bee67f3 100644 --- a/src/pages/Company/CompanyWorkExperiencesProvider.js +++ b/src/pages/Company/CompanyWorkExperiencesProvider.js @@ -57,7 +57,7 @@ const CompanyWorkExperiencesProvider = () => { ); }, [dispatch, pageName, jobTitle, start, limit]); - const [, fetchPermission, canView] = usePermission(); + const [, fetchPermission] = usePermission(); useEffect(() => { fetchPermission(); }, [pageType, pageName, fetchPermission]); @@ -75,7 +75,6 @@ const CompanyWorkExperiencesProvider = () => { page={page} pageSize={PAGE_SIZE} totalCount={workExperiencesCount} - canView={canView} tabType={tabType.WORK_EXPERIENCE} status={status} workExperiences={workExperiences} diff --git a/src/pages/JobTitle/JobTitleInterviewExperiencesProvider.js b/src/pages/JobTitle/JobTitleInterviewExperiencesProvider.js index 4b61c8e0a..b64bb1ab8 100644 --- a/src/pages/JobTitle/JobTitleInterviewExperiencesProvider.js +++ b/src/pages/JobTitle/JobTitleInterviewExperiencesProvider.js @@ -59,7 +59,7 @@ const JobTitleTimeAndSalaryProvider = () => { ); }, [dispatch, pageName, companyName, start, limit]); - const [, fetchPermission, canView] = usePermission(); + const [, fetchPermission] = usePermission(); useEffect(() => { fetchPermission(); }, [pageType, pageName, fetchPermission]); @@ -77,7 +77,6 @@ const JobTitleTimeAndSalaryProvider = () => { page={page} pageSize={PAGE_SIZE} totalCount={interviewExperiencesCount} - canView={canView} tabType={tabType.INTERVIEW_EXPERIENCE} status={status} interviewExperiences={interviewExperiences} diff --git a/src/pages/JobTitle/JobTitleOverviewProvider.js b/src/pages/JobTitle/JobTitleOverviewProvider.js index 6c2ebb23c..8b9d8b8b9 100644 --- a/src/pages/JobTitle/JobTitleOverviewProvider.js +++ b/src/pages/JobTitle/JobTitleOverviewProvider.js @@ -48,7 +48,7 @@ const JobTitleOverviewProvider = () => { dispatch(queryJobTitleOverview(pageName)); }, [dispatch, pageName]); - const [, fetchPermission, canView] = usePermission(); + const [, fetchPermission] = usePermission(); useEffect(() => { fetchPermission(); }, [pageType, pageName, fetchPermission]); @@ -62,7 +62,6 @@ const JobTitleOverviewProvider = () => { tabType={tabType.OVERVIEW} overviewBox={overviewBox} page={page} - canView={canView} /> ); }; diff --git a/src/pages/JobTitle/JobTitleWorkExperiencesProvider.js b/src/pages/JobTitle/JobTitleWorkExperiencesProvider.js index f7faa5473..17b720449 100644 --- a/src/pages/JobTitle/JobTitleWorkExperiencesProvider.js +++ b/src/pages/JobTitle/JobTitleWorkExperiencesProvider.js @@ -57,7 +57,7 @@ const JobTitleWorkExperiencesProvider = () => { ); }, [dispatch, pageName, companyName, start, limit]); - const [, fetchPermission, canView] = usePermission(); + const [, fetchPermission] = usePermission(); useEffect(() => { fetchPermission(); }, [pageType, pageName, fetchPermission]); @@ -75,7 +75,6 @@ const JobTitleWorkExperiencesProvider = () => { page={page} pageSize={PAGE_SIZE} totalCount={workExperiencesCount} - canView={canView} tabType={tabType.WORK_EXPERIENCE} status={status} workExperiences={workExperiences} From a814206125f44a04d948b184043fa8a763badd6a Mon Sep 17 00:00:00 2001 From: Peteranny Date: Wed, 25 Sep 2024 23:02:05 +0800 Subject: [PATCH 19/22] get the token from argument --- src/actions/experiences.js | 6 +++--- src/actions/me.js | 15 ++++++++++----- src/actions/timeAndSalary.js | 2 +- src/hooks/useIsMyPublishId.js | 6 +++--- src/hooks/usePermission.js | 2 +- 5 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/actions/experiences.js b/src/actions/experiences.js index d7140ef76..4cb59fd34 100644 --- a/src/actions/experiences.js +++ b/src/actions/experiences.js @@ -47,7 +47,7 @@ export const createInterviewExperience = ({ body }) => async ( token, }); - await dispatch(queryMyPublishIds()); + await dispatch({ token }); return result; }; @@ -64,7 +64,7 @@ export const createWorkExperience = ({ body }) => async ( token, }); - await dispatch(queryMyPublishIds()); + await dispatch(queryMyPublishIds({ token })); return result; }; @@ -81,7 +81,7 @@ export const createWorkExperienceWithRating = ({ body }) => async ( token, }); - await dispatch(queryMyPublishIds()); + await dispatch(queryMyPublishIds({ token })); return result; }; diff --git a/src/actions/me.js b/src/actions/me.js index fa6360006..dc936f41b 100644 --- a/src/actions/me.js +++ b/src/actions/me.js @@ -1,5 +1,4 @@ import { queryMyPublishIdsApi } from 'apis/me'; -import { tokenSelector } from 'selectors/authSelector'; import { myPublishIdsSelector } from 'selectors/me'; import { isUnfetched, @@ -16,16 +15,22 @@ const setMyPublishIds = box => ({ box, }); -export const queryMyPublishIdsIfNeeded = () => async (dispatch, getState) => { +// We don't obtain the token from the state but from the argument +// to indicate the need to be called on token change. +export const queryMyPublishIdsIfNeeded = ({ token }) => async ( + dispatch, + getState, +) => { const myPublishIdsBox = myPublishIdsSelector(getState()); if (isUnfetched(myPublishIdsBox) || isError(myPublishIdsBox)) { - dispatch(queryMyPublishIds()); + dispatch(queryMyPublishIds({ token })); } }; -export const queryMyPublishIds = () => async (dispatch, getState) => { - const token = tokenSelector(getState()); +// We don't obtain the token from the state but from the argument +// to indicate the need to be called on token change. +export const queryMyPublishIds = ({ token }) => async dispatch => { if (!token) { // If user has not logged in, it's assumed to have no publishes. dispatch(setMyPublishIds(getFetched([]))); diff --git a/src/actions/timeAndSalary.js b/src/actions/timeAndSalary.js index 3eb183889..de03d1b47 100644 --- a/src/actions/timeAndSalary.js +++ b/src/actions/timeAndSalary.js @@ -43,7 +43,7 @@ export const createSalaryWorkTime = ({ body }) => async ( token, }); - await dispatch(queryMyPublishIds()); + await dispatch(queryMyPublishIds({ token })); return result; }; diff --git a/src/hooks/useIsMyPublishId.js b/src/hooks/useIsMyPublishId.js index 2df250078..7c948f492 100644 --- a/src/hooks/useIsMyPublishId.js +++ b/src/hooks/useIsMyPublishId.js @@ -4,13 +4,13 @@ import { myPublishIdsSelector } from 'selectors/me'; import { queryMyPublishIdsIfNeeded } from 'actions/me'; import { isFetched } from 'utils/fetchBox'; -const useIsMyPublishId = () => { +const useIsMyPublishId = ({ token }) => { const myPublishIdsBox = useSelector(myPublishIdsSelector); const dispatch = useDispatch(); useEffect(() => { - dispatch(queryMyPublishIdsIfNeeded()); - }, [dispatch]); + dispatch(queryMyPublishIdsIfNeeded({ token })); + }, [dispatch, token]); const isMyPublishId = useCallback( publishId => { diff --git a/src/hooks/usePermission.js b/src/hooks/usePermission.js index b3d1a4db1..6e4a08803 100644 --- a/src/hooks/usePermission.js +++ b/src/hooks/usePermission.js @@ -38,7 +38,7 @@ const usePermission = () => { } }, [getSearchPermission, setPermissionState]); - const isMyPublishId = useIsMyPublishId(); + const isMyPublishId = useIsMyPublishId({ token }); const canViewPublishId = useCallback( publishId => isMyPublishId(publishId) || canView, From 6d7a5def48fc5c24fea3202e11bb86ee265e71ec Mon Sep 17 00:00:00 2001 From: Peteranny Date: Wed, 25 Sep 2024 23:06:10 +0800 Subject: [PATCH 20/22] empty From 72f4b79fdbfcab39c5604f84d35e19dbe8cdc69d Mon Sep 17 00:00:00 2001 From: Peteranny Date: Sun, 29 Sep 2024 23:07:59 +0800 Subject: [PATCH 21/22] typo --- src/actions/experiences.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/actions/experiences.js b/src/actions/experiences.js index 4cb59fd34..7f1b81bc9 100644 --- a/src/actions/experiences.js +++ b/src/actions/experiences.js @@ -47,7 +47,7 @@ export const createInterviewExperience = ({ body }) => async ( token, }); - await dispatch({ token }); + await dispatch(queryMyPublishIds({ token })); return result; }; From b4dec857a35d8b2d1eb55006ba3b5efd250f7c0f Mon Sep 17 00:00:00 2001 From: Peteranny Date: Mon, 30 Sep 2024 21:20:37 +0800 Subject: [PATCH 22/22] use isLogin rather than token --- src/actions/experiences.js | 6 +++--- src/actions/me.js | 16 ++++++---------- src/actions/timeAndSalary.js | 2 +- src/hooks/useIsMyPublishId.js | 8 +++++--- src/hooks/usePermission.js | 2 +- 5 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/actions/experiences.js b/src/actions/experiences.js index 7f1b81bc9..d7140ef76 100644 --- a/src/actions/experiences.js +++ b/src/actions/experiences.js @@ -47,7 +47,7 @@ export const createInterviewExperience = ({ body }) => async ( token, }); - await dispatch(queryMyPublishIds({ token })); + await dispatch(queryMyPublishIds()); return result; }; @@ -64,7 +64,7 @@ export const createWorkExperience = ({ body }) => async ( token, }); - await dispatch(queryMyPublishIds({ token })); + await dispatch(queryMyPublishIds()); return result; }; @@ -81,7 +81,7 @@ export const createWorkExperienceWithRating = ({ body }) => async ( token, }); - await dispatch(queryMyPublishIds({ token })); + await dispatch(queryMyPublishIds()); return result; }; diff --git a/src/actions/me.js b/src/actions/me.js index dc936f41b..1457cd80b 100644 --- a/src/actions/me.js +++ b/src/actions/me.js @@ -1,4 +1,5 @@ import { queryMyPublishIdsApi } from 'apis/me'; +import { tokenSelector } from 'selectors/authSelector'; import { myPublishIdsSelector } from 'selectors/me'; import { isUnfetched, @@ -15,22 +16,17 @@ const setMyPublishIds = box => ({ box, }); -// We don't obtain the token from the state but from the argument -// to indicate the need to be called on token change. -export const queryMyPublishIdsIfNeeded = ({ token }) => async ( - dispatch, - getState, -) => { +export const queryMyPublishIdsIfNeeded = () => async (dispatch, getState) => { const myPublishIdsBox = myPublishIdsSelector(getState()); if (isUnfetched(myPublishIdsBox) || isError(myPublishIdsBox)) { - dispatch(queryMyPublishIds({ token })); + dispatch(queryMyPublishIds()); } }; -// We don't obtain the token from the state but from the argument -// to indicate the need to be called on token change. -export const queryMyPublishIds = ({ token }) => async dispatch => { +export const queryMyPublishIds = () => async (dispatch, getState) => { + const token = tokenSelector(getState()); + if (!token) { // If user has not logged in, it's assumed to have no publishes. dispatch(setMyPublishIds(getFetched([]))); diff --git a/src/actions/timeAndSalary.js b/src/actions/timeAndSalary.js index de03d1b47..3eb183889 100644 --- a/src/actions/timeAndSalary.js +++ b/src/actions/timeAndSalary.js @@ -43,7 +43,7 @@ export const createSalaryWorkTime = ({ body }) => async ( token, }); - await dispatch(queryMyPublishIds({ token })); + await dispatch(queryMyPublishIds()); return result; }; diff --git a/src/hooks/useIsMyPublishId.js b/src/hooks/useIsMyPublishId.js index 7c948f492..c56d581cb 100644 --- a/src/hooks/useIsMyPublishId.js +++ b/src/hooks/useIsMyPublishId.js @@ -3,14 +3,16 @@ import { useDispatch, useSelector } from 'react-redux'; import { myPublishIdsSelector } from 'selectors/me'; import { queryMyPublishIdsIfNeeded } from 'actions/me'; import { isFetched } from 'utils/fetchBox'; +import { useLogin } from './login'; -const useIsMyPublishId = ({ token }) => { +const useIsMyPublishId = () => { + const [isLoggedIn] = useLogin(); const myPublishIdsBox = useSelector(myPublishIdsSelector); const dispatch = useDispatch(); useEffect(() => { - dispatch(queryMyPublishIdsIfNeeded({ token })); - }, [dispatch, token]); + dispatch(queryMyPublishIdsIfNeeded()); + }, [dispatch, isLoggedIn]); const isMyPublishId = useCallback( publishId => { diff --git a/src/hooks/usePermission.js b/src/hooks/usePermission.js index 6e4a08803..b3d1a4db1 100644 --- a/src/hooks/usePermission.js +++ b/src/hooks/usePermission.js @@ -38,7 +38,7 @@ const usePermission = () => { } }, [getSearchPermission, setPermissionState]); - const isMyPublishId = useIsMyPublishId({ token }); + const isMyPublishId = useIsMyPublishId(); const canViewPublishId = useCallback( publishId => isMyPublishId(publishId) || canView,