Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 32 additions & 16 deletions src/common/actions/cycle.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import {normalize} from 'normalizr'
import socketCluster from 'socketcluster-client'

import {flatten, getGraphQLFetcher} from 'src/common/util'
import {findUsers} from './user'
import {findMembers} from './member'
import types from './types'
import schemas from './schemas'
import queries from './queries'
Expand All @@ -25,33 +26,48 @@ export function getCycleVotingResults(options = {}) {

return dispatch(action)
.then(() => {
return options.withUsers ? _findUsersForCycleVotingResults(dispatch, getState) : null
return options.withMembers ? _findMembersForCycleVotingResults(dispatch, getState) : null
})
}
}

export function receivedCycleVotingResults(cycleVotingResults) {
export function subscribeToCycleVotingResults(cycleId) {
return (dispatch, getState) => {
dispatch(_receivedCycleVotingResultsWithoutLoadingUsers(cycleVotingResults))
return _findUsersForCycleVotingResults(dispatch, getState)
if (cycleId) {
console.log(`subscribing to voting results for cycle ${cycleId} ...`)
this.socket = socketCluster.connect()
this.socket.on('connect', () => console.log('... socket connected'))
this.socket.on('disconnect', () => console.log('socket disconnected, will try to reconnect socket ...'))
this.socket.on('connectAbort', () => null)
this.socket.on('error', error => console.warn(error.message))
const cycleVotingResultsChannel = this.socket.subscribe(`cycleVotingResults-${cycleId}`)
cycleVotingResultsChannel.watch(cycleVotingResults => {
const response = normalize(cycleVotingResults, schemas.cycleVotingResults)
dispatch({type: types.RECEIVED_CYCLE_VOTING_RESULTS, response})
dispatch(_findMembersForCycleVotingResults(dispatch, getState))
})
}
}
}

function _findUsersForCycleVotingResults(dispatch, getState) {
// we'll only load users from IDM that haven't already been loaded, because
export function unsubscribeFromCycleVotingResults(cycleId) {
if (this.socket && cycleId) {
console.log(`unsubscribing from voting results for cycle ${cycleId} ...`)
this.socket.unwatch(`cycleVotingResults-${cycleId}`)
this.socket.unsubscribe(`cycleVotingResults-${cycleId}`)
}
}

function _findMembersForCycleVotingResults(dispatch, getState) {
// we'll only load members that haven't already been loaded, because
// it's unlikely that their names, handles, and avatars have changed since
// the last load, and those are the attributes we use in the voting results
const {
cycleVotingResults: {cycleVotingResults: {CURRENT: cycleVotingResults}},
users: {users},
members: {members},
} = getState()

const memberIds = flatten(cycleVotingResults.pools.map(_ => _.users.map(_ => _.id)))
const userIdsToLoad = memberIds.filter(memberId => !users[memberId])
return userIdsToLoad.length === 0 ? null : dispatch(findUsers(userIdsToLoad))
}

function _receivedCycleVotingResultsWithoutLoadingUsers(cycleVotingResults) {
const response = normalize(cycleVotingResults, schemas.cycleVotingResults)
return {type: types.RECEIVED_CYCLE_VOTING_RESULTS, response}
const memberIds = flatten(cycleVotingResults.pools.map(pool => pool.members.map(m => m.id)))
const memberIdsToLoad = memberIds.filter(memberId => !members[memberId])
return memberIdsToLoad.length === 0 ? null : dispatch(findMembers(memberIdsToLoad))
}
100 changes: 100 additions & 0 deletions src/common/actions/member.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import {normalize} from 'normalizr'

import {getGraphQLFetcher} from 'src/common/util'
import types from './types'
import schemas from './schemas'
import queries from './queries'

export function deactivateMember(memberId) {
return {
types: [
types.DEACTIVATE_MEMBER_REQUEST,
types.DEACTIVATE_MEMBER_SUCCESS,
types.DEACTIVATE_MEMBER_FAILURE,
],
shouldCallAPI: () => true,
callAPI: (dispatch, getState) => {
const query = queries.deactivateMember(memberId)
return getGraphQLFetcher(dispatch, getState().auth)(query)
.then(graphQLResponse => graphQLResponse.data.deactivateMember)
},
redirect: _redirectMember,
payload: {},
}
}

export function findMembers() {
return {
types: [
types.FIND_MEMBERS_REQUEST,
types.FIND_MEMBERS_SUCCESS,
types.FIND_MEMBERS_FAILURE,
],
shouldCallAPI: () => true,
callAPI: (dispatch, getState) => {
const query = queries.findMembers()
return getGraphQLFetcher(dispatch, getState().auth)(query)
.then(graphQLResponse => graphQLResponse.data.findMembers)
.then(members => normalize(members, schemas.members))
},
payload: {},
}
}

export function getMemberSummary(identifier) {
return {
types: [
types.GET_MEMBER_SUMMARY_REQUEST,
types.GET_MEMBER_SUMMARY_SUCCESS,
types.GET_MEMBER_SUMMARY_FAILURE,
],
shouldCallAPI: () => true,
callAPI: (dispatch, getState) => {
const query = queries.getMemberSummary(identifier)
return getGraphQLFetcher(dispatch, getState().auth)(query)
.then(graphQLResponse => graphQLResponse.data.getMemberSummary)
},
payload: {},
}
}

export function reassignMembersToChapter(memberIds, chapterId) {
return {
types: [
types.REASSIGN_MEMBERS_TO_CHAPTER_REQUEST,
types.REASSIGN_MEMBERS_TO_CHAPTER_SUCCESS,
types.REASSIGN_MEMBERS_TO_CHAPTER_FAILURE,
],
shouldCallAPI: () => true,
callAPI: (dispatch, getState) => {
const mutation = queries.reassignMembersToChapter(memberIds, chapterId)
return getGraphQLFetcher(dispatch, getState().auth)(mutation)
.then(graphQLResponse => graphQLResponse.data.reassignMembersToChapter)
.then(members => normalize(members, schemas.members))
},
redirect: '/members',
payload: {memberIds, chapterId},
}
}

export function updateMember(values) {
return {
types: [
types.UPDATE_MEMBER_REQUEST,
types.UPDATE_MEMBER_SUCCESS,
types.UPDATE_MEMBER_FAILURE,
],
shouldCallAPI: () => true,
callAPI: (dispatch, getState) => {
const mutation = queries.updateMember(values)
return getGraphQLFetcher(dispatch, getState().auth)(mutation)
.then(graphQLResponse => graphQLResponse.data.updateMember)
},
redirect: _redirectMember,
payload: {},
}
}

function _redirectMember(member) {
return member && member.handle ? `/members/${member.handle}` : '/members'
}
34 changes: 0 additions & 34 deletions src/common/actions/project.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,40 +103,6 @@ export function importProject(values) {
}
}

export function unlockSurvey(memberId, projectId) {
return {
types: [
types.UNLOCK_SURVEY_REQUEST,
types.UNLOCK_SURVEY_SUCCESS,
types.UNLOCK_SURVEY_FAILURE,
],
shouldCallAPI: () => true,
callAPI: (dispatch, getState) => {
const query = queries.unlockSurvey(memberId, projectId)
return getGraphQLFetcher(dispatch, getState().auth)(query)
.then(graphQLResponse => graphQLResponse.data.unlockRetroSurveyForUser)
},
payload: {memberId, projectId},
}
}

export function lockSurvey(memberId, projectId) {
return {
types: [
types.LOCK_SURVEY_REQUEST,
types.LOCK_SURVEY_SUCCESS,
types.LOCK_SURVEY_FAILURE,
],
shouldCallAPI: () => true,
callAPI: (dispatch, getState) => {
const query = queries.lockSurvey(memberId, projectId)
return getGraphQLFetcher(dispatch, getState().auth)(query)
.then(graphQLResponse => graphQLResponse.data.lockRetroSurveyForUser)
},
payload: {memberId, projectId},
}
}

export function deleteProject(identifier) {
return {
types: [
Expand Down
14 changes: 14 additions & 0 deletions src/common/actions/queries/deactivateMember.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export default function deactivateMember(memberId) {
return {
variables: {memberId},
query: `
mutation ($memberId: ID!) {
deactivateMember(identifier: $memberId) {
id
active
handle
}
}
`,
}
}
22 changes: 18 additions & 4 deletions src/common/actions/queries/findMembers.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,31 @@
export default function findMembers() {
export default function findMembers(identifiers) {
return {
variables: {},
variables: {identifiers},
query: `
query {
findMembers {
query ($identifiers: [String]) {
findMembers(identifiers: $identifiers) {
id
chapterId
chapter {
id
name
channelName
timezone
inviteCodes
}
phone
email
name
handle
avatarUrl
profileUrl
timezone
active
phaseId
phase {
id
number
}
createdAt
updatedAt
}
Expand Down
27 changes: 0 additions & 27 deletions src/common/actions/queries/findUsers.js

This file was deleted.

2 changes: 1 addition & 1 deletion src/common/actions/queries/getCycleVotingResults.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default function getCycleVotingResults() {
id
name
voterMemberIds
users {
members {
id
}
phase {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import {FEEDBACK_TYPE_DESCRIPTORS} from 'src/common/models/feedbackType'

export default function getUserSummary(identifier) {
export default function Member(identifier) {
return {
variables: {identifier},
query: `query ($identifier: String!) {
getUserSummary(identifier: $identifier) {
user {
Member(identifier: $identifier) {
member {
id
phone
email
Expand All @@ -26,7 +26,7 @@ export default function getUserSummary(identifier) {
name
}
}
userProjectSummaries {
memberProjectSummaries {
project {
id
name
Expand All @@ -44,7 +44,7 @@ export default function getUserSummary(identifier) {
phase
}
}
userProjectEvaluations {
memberProjectEvaluations {
${FEEDBACK_TYPE_DESCRIPTORS.GENERAL_FEEDBACK}
}
}
Expand Down
10 changes: 5 additions & 5 deletions src/common/actions/queries/getProjectSummary.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,18 @@ export default function getProjectSummary(identifier) {
number
}
}
projectUserSummaries {
user {
projectMemberSummaries {
member {
id
name
handle
avatarUrl
}
userProjectEvaluations {
memberProjectEvaluations {
${FEEDBACK_TYPE_DESCRIPTORS.GENERAL_FEEDBACK}
}
userRetrospectiveComplete
userRetrospectiveUnlocked
memberRetrospectiveComplete
memberRetrospectiveUnlocked
}
}
}`,
Expand Down
11 changes: 5 additions & 6 deletions src/common/actions/queries/index.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,25 @@
export default {
createInviteCode: require('./createInviteCode'),
deleteProject: require('./deleteProject'),
findChapters: require('./findChapters'),
findPhases: require('./findPhases'),
findPhaseSummaries: require('./findPhaseSummaries'),
findMembers: require('./findMembers'),
findProjects: require('./findProjects'),
findProjectsForCycle: require('./findProjectsForCycle'),
findRetrospectiveSurveys: require('./findRetrospectiveSurveys'),
findUsers: require('./findUsers'),
getChapter: require('./getChapter'),
getCycleVotingResults: require('./getCycleVotingResults'),
getProject: require('./getProject'),
getProjectSummary: require('./getProjectSummary'),
getRetrospectiveSurvey: require('./getRetrospectiveSurvey'),
getUserSummary: require('./getUserSummary'),
getMemberSummary: require('./getMemberSummary'),
importProject: require('./importProject'),
lockSurveyForMember: require('./lockSurveyForMember'),
reassignMembersToChapter: require('./reassignMembersToChapter'),
saveChapter: require('./saveChapter'),
saveRetrospectiveSurveyResponses: require('./saveRetrospectiveSurveyResponses'),
submitSurvey: require('./submitSurvey'),
unlockSurvey: require('./unlockSurvey'),
lockSurvey: require('./lockSurvey'),
deleteProject: require('./deleteProject'),
updateUser: require('./updateUser'),
unlockSurveyForMember: require('./unlockSurveyForMember'),
updateMember: require('./updateMember'),
}
Loading