Skip to content

Commit e6f13e0

Browse files
committed
PM-973 - fetch project invites sepparately
1 parent 7c2a793 commit e6f13e0

File tree

8 files changed

+72
-15
lines changed

8 files changed

+72
-15
lines changed

src/actions/projects.js

+16-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ import {
2020
UPDATE_PROJECT_FAILURE,
2121
ADD_PROJECT_ATTACHMENT_SUCCESS,
2222
UPDATE_PROJECT_ATTACHMENT_SUCCESS,
23-
REMOVE_PROJECT_ATTACHMENT_SUCCESS
23+
REMOVE_PROJECT_ATTACHMENT_SUCCESS,
24+
LOAD_PROJECT_INVITES
2425
} from '../config/constants'
2526
import {
2627
fetchProjectById,
@@ -30,7 +31,8 @@ import {
3031
createProjectApi,
3132
fetchBillingAccounts,
3233
fetchMemberProjects,
33-
updateProjectApi
34+
updateProjectApi,
35+
getProjectInvites
3436
} from '../services/projects'
3537
import { checkAdmin, checkManager } from '../util/tc'
3638

@@ -171,6 +173,18 @@ export function loadProjectTypes () {
171173
}
172174
}
173175

176+
/**
177+
* Loads project invites
178+
*/
179+
export function loadProjectInvites (projectId) {
180+
return (dispatch) => {
181+
return dispatch({
182+
type: LOAD_PROJECT_INVITES,
183+
payload: getProjectInvites(projectId)
184+
})
185+
}
186+
}
187+
174188
/**
175189
* Creates a project
176190
*/

src/components/ProjectCard/index.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ import { PROJECT_STATUSES } from '../../config/constants'
88

99
import styles from './ProjectCard.module.scss'
1010

11-
const ProjectCard = ({ projectName, projectStatus, projectId, selected }) => {
11+
const ProjectCard = ({ projectName, projectStatus, projectId, selected, isInvited }) => {
1212
return (
1313
<div className={styles.container}>
1414
<Link
15-
to={`/projects/${projectId}/challenges`}
15+
to={`/projects/${projectId}/${isInvited ? 'invitation' : 'challenges'}`}
1616
className={cn(styles.projectName, { [styles.selected]: selected })}
1717
>
1818
<div className={styles.name}>
@@ -28,6 +28,7 @@ ProjectCard.propTypes = {
2828
projectStatus: PT.string.isRequired,
2929
projectId: PT.number.isRequired,
3030
projectName: PT.string.isRequired,
31+
isInvited: PT.bool.isRequired,
3132
selected: PT.bool
3233
}
3334

src/config/constants.js

+5
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,11 @@ export const LOAD_PROJECT_TYPES_SUCCESS = 'LOAD_PROJECT_TYPES_SUCCESS'
181181
export const LOAD_PROJECT_TYPES_PENDING = 'LOAD_PROJECT_TYPES_PENDING'
182182
export const LOAD_PROJECT_TYPES_FAILURE = 'LOAD_PROJECT_TYPES_FAILURE'
183183

184+
export const LOAD_PROJECT_INVITES = 'LOAD_PROJECT_INVITES'
185+
export const LOAD_PROJECT_INVITES_SUCCESS = 'LOAD_PROJECT_INVITES_SUCCESS'
186+
export const LOAD_PROJECT_INVITES_PENDING = 'LOAD_PROJECT_INVITES_PENDING'
187+
export const LOAD_PROJECT_INVITES_FAILURE = 'LOAD_PROJECT_INVITES_FAILURE'
188+
184189
export const CREATE_PROJECT = 'CREATE_PROJECT'
185190
export const CREATE_PROJECT_PENDING = 'CREATE_PROJECT_PENDING'
186191
export const CREATE_PROJECT_SUCCESS = 'CREATE_PROJECT_SUCCESS'

src/containers/Challenges/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ class Challenges extends Component {
6060
const { auth } = this.props
6161

6262
if (checkIsUserInvited(auth.token, this.props.projectDetail)) {
63-
this.props.history.push(`/projects/${this.props.projectDetail.id}/invitation`)
63+
this.props.history.push(`/projects/${this.props.projectId}/invitation`)
6464
}
6565
}
6666

src/containers/ProjectInvitations/index.js

+8-8
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { withRouter } from 'react-router-dom'
55
import { toastr } from 'react-redux-toastr'
66
import { checkIsUserInvited } from '../../util/tc'
77
import { isEmpty } from 'lodash'
8-
import { loadProject } from '../../actions/projects'
8+
import { loadProjectInvites } from '../../actions/projects'
99
import ConfirmationModal from '../../components/Modal/ConfirmationModal'
1010

1111
import styles from './ProjectInvitations.module.scss'
@@ -17,7 +17,7 @@ const theme = {
1717
container: styles.modalContainer
1818
}
1919

20-
const ProjectInvitations = ({ match, auth, isProjectLoading, history, projectDetail, loadProject }) => {
20+
const ProjectInvitations = ({ match, auth, isProjectLoading, history, projectDetail, loadProjectInvites }) => {
2121
const automaticAction = useMemo(() => [PROJECT_MEMBER_INVITE_STATUS_ACCEPTED, PROJECT_MEMBER_INVITE_STATUS_REFUSED].includes(match.params.action) ? match.params.action : undefined, [match.params])
2222
const projectId = useMemo(() => parseInt(match.params.projectId), [match.params])
2323
const invitation = useMemo(() => checkIsUserInvited(auth.token, projectDetail), [auth.token, projectDetail])
@@ -32,7 +32,7 @@ const ProjectInvitations = ({ match, auth, isProjectLoading, history, projectDet
3232

3333
if (isProjectLoading || isEmpty(projectDetail)) {
3434
if (!isProjectLoading) {
35-
loadProject(projectId)
35+
loadProjectInvites(projectId)
3636
}
3737
return
3838
}
@@ -48,13 +48,13 @@ const ProjectInvitations = ({ match, auth, isProjectLoading, history, projectDet
4848

4949
// await for the project details to propagate
5050
await delay(1000)
51-
await loadProject(projectId)
51+
await loadProjectInvites(projectId)
5252
toastr.success('Success', `Successfully ${status} the invitation.`)
5353

5454
// await for the project details to fetch
5555
await delay(1000)
5656
history.push(status === PROJECT_MEMBER_INVITE_STATUS_ACCEPTED ? `/projects/${projectId}/challenges` : '/projects')
57-
}, [projectId, invitation, loadProject, history])
57+
}, [projectId, invitation, loadProjectInvites, history])
5858

5959
const acceptInvite = useCallback(() => updateInvite(PROJECT_MEMBER_INVITE_STATUS_ACCEPTED), [updateInvite])
6060
const declineInvite = useCallback(() => updateInvite(PROJECT_MEMBER_INVITE_STATUS_REFUSED), [updateInvite])
@@ -104,20 +104,20 @@ ProjectInvitations.propTypes = {
104104
auth: PropTypes.object.isRequired,
105105
isProjectLoading: PropTypes.bool,
106106
history: PropTypes.object,
107-
loadProject: PropTypes.func.isRequired,
107+
loadProjectInvites: PropTypes.func.isRequired,
108108
projectDetail: PropTypes.object
109109
}
110110

111111
const mapStateToProps = ({ projects, auth }) => {
112112
return {
113113
projectDetail: projects.projectDetail,
114-
isProjectLoading: projects.isLoading,
114+
isProjectLoading: projects.isLoading || projects.isProjectInvitationsLoading,
115115
auth
116116
}
117117
}
118118

119119
const mapDispatchToProps = {
120-
loadProject
120+
loadProjectInvites
121121
}
122122

123123
export default withRouter(

src/containers/Projects/index.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { withRouter, Link } from 'react-router-dom'
55
import { connect } from 'react-redux'
66
import PropTypes from 'prop-types'
77
import Loader from '../../components/Loader'
8-
import { checkAdminOrCopilot, checkManager } from '../../util/tc'
8+
import { checkAdminOrCopilot, checkIsUserInvited, checkManager } from '../../util/tc'
99
import { PrimaryButton } from '../../components/Buttons'
1010
import Select from '../../components/Select'
1111
import ProjectCard from '../../components/ProjectCard'
@@ -112,6 +112,7 @@ const Projects = ({ projects, auth, isLoading, projectsCount, loadProjects, load
112112
{projects.map(p => (
113113
<li key={p.id}>
114114
<ProjectCard
115+
isInvited={!!checkIsUserInvited(auth.token, p)}
115116
projectStatus={p.status}
116117
projectName={p.name}
117118
projectId={p.id}

src/reducers/projects.js

+28-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,10 @@ import {
3030
UPDATE_PROJECT_DETAILS_SUCCESS,
3131
ADD_PROJECT_ATTACHMENT_SUCCESS,
3232
UPDATE_PROJECT_ATTACHMENT_SUCCESS,
33-
REMOVE_PROJECT_ATTACHMENT_SUCCESS
33+
REMOVE_PROJECT_ATTACHMENT_SUCCESS,
34+
LOAD_PROJECT_INVITES_PENDING,
35+
LOAD_PROJECT_INVITES_SUCCESS,
36+
LOAD_PROJECT_INVITES_FAILURE
3437
} from '../config/constants'
3538
import { toastSuccess, toastFailure } from '../util/toaster'
3639
import moment from 'moment-timezone'
@@ -78,6 +81,7 @@ const initialState = {
7881
isBillingAccountExpired: false,
7982
isBillingAccountLoading: false,
8083
isBillingAccountLoadingFailed: false,
84+
isProjectInvitationsLoading: false,
8185
currentBillingAccount: null,
8286
billingStartDate: null,
8387
billingEndDate: null,
@@ -261,6 +265,29 @@ export default function (state = initialState, action) {
261265
...state,
262266
isProjectTypesLoading: false
263267
}
268+
case LOAD_PROJECT_INVITES_PENDING:
269+
return {
270+
...state,
271+
projectDetail: {
272+
...state.projectDetail,
273+
invites: []
274+
},
275+
isProjectInvitationsLoading: true
276+
}
277+
case LOAD_PROJECT_INVITES_SUCCESS:
278+
return {
279+
...state,
280+
projectDetail: {
281+
...state.projectDetail,
282+
invites: action.payload
283+
},
284+
isProjectInvitationsLoading: false
285+
}
286+
case LOAD_PROJECT_INVITES_FAILURE:
287+
return {
288+
...state,
289+
isProjectInvitationsLoading: false
290+
}
264291
case UPDATE_PROJECT_PENDING:
265292
return {
266293
...state,

src/services/projects.js

+9
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,15 @@ export async function getProjectTypes () {
224224
return _.get(response, 'data')
225225
}
226226

227+
/**
228+
* Get project invites
229+
* @returns {Promise<*>}
230+
*/
231+
export async function getProjectInvites (projectId) {
232+
const response = await axiosInstance.get(`${PROJECTS_API_URL}/${projectId}/invites`)
233+
return _.get(response, 'data')
234+
}
235+
227236
/**
228237
* Get project attachment
229238
* @param projectId project id

0 commit comments

Comments
 (0)