Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(app-project): data-fetching for assigned workflow level #6219

Merged
merged 8 commits into from
Nov 13, 2024
59 changes: 32 additions & 27 deletions packages/app-project/src/hooks/useAssignedLevel.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,39 +3,44 @@
so we fetch the assigned workflow's config just in case.
https://github.com/zooniverse/front-end-monorepo/issues/6198
*/

import { useEffect, useState } from 'react'
import { panoptes } from '@zooniverse/panoptes-js'
import useSWR from 'swr'

function useAssignedLevel(assignedWorkflowID) {
const [assignedWorkflowLevel, setAssignedWorkflowLevel] = useState(1)
const SWRoptions = {
revalidateIfStale: false,
revalidateOnMount: false,
revalidateOnFocus: false,
revalidateOnReconnect: false,
refreshInterval: 0
}

async function checkAssignedLevel() {
const query = {
fields: 'configuration',
id: assignedWorkflowID
}
try {
const response = await panoptes.get('/workflows', query)
if (response.ok) {
const fetchedWorkflow = response.body.workflows?.[0]
setAssignedWorkflowLevel(parseInt(fetchedWorkflow?.configuration?.level), 10)
}
} catch (error) {
throw error
}
async function fetchAssignedWorkflow({
fields = 'configuration',
assignedWorkflowID,
}) {
const query = {
fields,
id: assignedWorkflowID
}
const response = await panoptes.get('/workflows', query)
if (response.ok && response.body.workflows?.length) {
const fetchedWorkflow = response.body.workflows[0]
return parseInt(fetchedWorkflow?.configuration?.level, 10)
}
return 1
}

useEffect(
function () {
if (assignedWorkflowID) {
checkAssignedLevel()
}
},
[assignedWorkflowID]
)
function useAssignedLevel(assignedWorkflowID, workflows = []) {
const existingWorkflow = workflows.find(workflow => workflow.id === assignedWorkflowID)
const defaultWorkflowLevel = existingWorkflow?.configuration?.level
? parseInt(existingWorkflow.configuration.level, 10)
: 1
const key = !existingWorkflow && assignedWorkflowID
? { assignedWorkflowID }
: null // skip data fetching when we already have the workflow level
const { data: fetchedWorkflowLevel } = useSWR(key, fetchAssignedWorkflow, SWRoptions)

return assignedWorkflowLevel
return fetchedWorkflowLevel || defaultWorkflowLevel
}

export default useAssignedLevel
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { MobXProviderContext, observer } from 'mobx-react'
import { useContext } from 'react'
import useAssignedLevel from '@hooks/useAssignedLevel'
import ClassifyPageContainer from './ClassifyPageContainer'

function useStore(store) {
Expand All @@ -25,14 +26,16 @@ function ClassifyPageConnector(props) {
projectPreferences,
workflowAssignmentEnabled = false
} = useStore(store)
const assignedWorkflowID = projectPreferences?.settings?.workflow_id
const assignedWorkflowLevel = useAssignedLevel(assignedWorkflowID, props.workflows)

return (
<ClassifyPageContainer
{...props}
appLoadingState={appLoadingState}
assignedWorkflowID={projectPreferences?.settings?.workflow_id}
assignedWorkflowLevel={assignedWorkflowLevel}
projectPreferences={projectPreferences}
workflowAssignmentEnabled={workflowAssignmentEnabled}
{...props}
/>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@ import { useCallback, useEffect, useState } from 'react'
import { array, bool, string } from 'prop-types'

import ClassifyPage from './ClassifyPage'
import useAssignedLevel from '@hooks/useAssignedLevel.js'

function ClassifyPageContainer ({
assignedWorkflowID = '',
assignedWorkflowLevel = 1,
subjectID,
workflowAssignmentEnabled = false,
workflowID,
Expand All @@ -16,7 +15,6 @@ function ClassifyPageContainer ({
but can be reset by the Classifier component via onSubjectReset().
This state does not change via components of the prioritized subjects UI (Next/Prev buttons) */
const [selectedSubjectID, setSelectedSubjectID] = useState(subjectID)
const assignedWorkflowLevel = useAssignedLevel(assignedWorkflowID)

let allowedWorkflows = workflows.slice()
/* Double check that a volunteer navigating to url with workflowID is allowed to load that workflow */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ describe('Component > ClassifyPageContainer', function () {
<RouterContext.Provider value={mockRouter}>
<Provider store={mockStoreWithAssignment}>
<ClassifyPageContainer
assignedWorkflowID='5678'
assignedWorkflowLevel={2}
workflowAssignmentEnabled
workflowID='1234'
workflows={workflows}
Expand Down Expand Up @@ -279,7 +279,7 @@ describe('Component > ClassifyPageContainer', function () {
<RouterContext.Provider value={mockRouter}>
<Provider store={mockStoreWithAssignment}>
<ClassifyPageContainer
assignedWorkflowID='1234'
assignedWorkflowLevel={1}
workflowAssignmentEnabled
workflowID='5678'
workflows={workflows}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import useAssignedLevel from '@hooks/useAssignedLevel.js'
function LevelingUpButtons({ assignedWorkflowID = '', workflows = [] }) {
const { t } = useTranslation('components')

const assignedWorkflowLevel = useAssignedLevel(assignedWorkflowID)
const assignedWorkflowLevel = useAssignedLevel(assignedWorkflowID, workflows)
const filteredWorkflowsByLevel = { allowed: [], disallowed: [] }

if (assignedWorkflowLevel) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,8 @@ describe('Component > WorkflowSelector > WorkflowSelectorButtons', function () {
})
})

/** Skipped because I added a custom hook to WorkflowSelectButtons > LevelingUpButtons */
describe('when workflow assignment is enabled', function () {
describe.skip('when there is an assigned workflow', function () {
describe('when there is an assigned workflow', function () {
it('should only render links for unlocked workflows', function () {
const { getAllByRole } = render(
<RouterContext.Provider value={mockRouter}>
Expand Down