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

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

eatyourgreens
Copy link
Contributor

@eatyourgreens eatyourgreens commented Aug 17, 2024

Fix missing dependency errors in the useAssignedLevel hook by using useSWR to fetch and cache the assigned workflow level. SWR also adds revalidation of the Panoptes API request for cases where I might classify in the same tab over several days or weeks.*

Adds conditional data-fetching, so that we only fetch a workflow configuration if we don’t already have it in the workflows page prop.

Also fixes the workflow assignment tests in ClassifyPageContainer so that they test against the correct levels, and restores skipped tests to double check that nothing is broken.

*do workflow levels change over time? If not, the fetched value can be cached indefinitely.

Please request review from @zooniverse/frontend team or an individual member of that team.

Package

  • app-project

Linked Issue and/or Talk Post

How to Review

Testing for this should be the same as #6201. useAssignedLevel should only call the API once for a given workflow, even if it’s invoked from multiple components.

If you load Gravity Spy with the workflow choice menu, you can check that the Classify page only makes one API request for any missing workflows, even though useAssignedLevel is used twice on the page. The assigned level should also be cached in the client-side project app for the duration of your session.
https://local.zooniverse.org:3000/projects/zooniverse/gravity-spy/classify?env=production

Checklist

PR Creator - Please cater the checklist to fit the review needed for your code changes.
PR Reviewer - Use the checklist during your review. Each point should be checkmarked or discussed before PR approval.

General

  • Tests are passing locally and on Github
  • Documentation is up to date and changelog has been updated if appropriate
  • You can yarn panic && yarn bootstrap or docker-compose up --build and FEM works as expected
  • FEM works in all major desktop browsers: Firefox, Chrome, Edge, Safari (Use Browserstack account as needed)
  • FEM works in a mobile browser

General UX

Example Staging Project: i-fancy-cats

  • All pages of a FEM project load: Home Page, Classify Page, and About Pages
  • Can submit a classification
  • Can sign-in and sign-out
  • The component is accessible

Bug Fix

  • The PR creator has listed user actions to use when testing if bug is fixed
  • The bug is fixed
  • Unit tests are added or updated

@eatyourgreens eatyourgreens force-pushed the use-assigned-level branch 6 times, most recently from 0fbf132 to d9b87f8 Compare August 17, 2024 22:57
@coveralls
Copy link

coveralls commented Aug 17, 2024

Coverage Status

coverage: 78.883% (-0.03%) from 78.912%
when pulling ca9cac5 on eatyourgreens:use-assigned-level
into f7c4e10 on zooniverse:master.

@eatyourgreens
Copy link
Contributor Author

eatyourgreens commented Aug 17, 2024

#6201 broke these tests for assigned workflow level in ClassifyPageContainer. I’ve fixed them here by moving the data fetching up into the connector component.

describe('when the assigned workflow level is greater than or equal to the workflow from URL level', function () {
it('should be able to load the workflow from the url', function () {
const mockStoreWithAssignment = Object.assign({}, mockStore, {
user: {
collections: {
collections: []
},
personalization: {
projectPreferences: {
promptAssignment: () => false,
settings: {
workflow_id: '5678'
}
},
sessionCount: 0,
stats: {
thisWeek: []
}
},
recents: {
recents: []
}
}
})
const wrapper = mount(
<RouterContext.Provider value={mockRouter}>
<Provider store={mockStoreWithAssignment}>
<ClassifyPageContainer
assignedWorkflowID='5678'
workflowAssignmentEnabled
workflowID='1234'
workflows={workflows}
/>
</Provider>
</RouterContext.Provider>, {
wrappingComponent: Grommet,
wrappingComponentProps: { theme: zooTheme }
}
)
expect(wrapper.find(ClassifyPage).props().workflowFromUrl).to.equal(workflows[0])
expect(wrapper.find(ClassifyPage).props().workflowID).to.equal(workflows[0].id)
})
})
describe('when the assigned workflow level is less than the workflow from URL level', function () {
it('should not be able to load the workflow from the url', function () {
const mockStoreWithAssignment = Object.assign({}, mockStore, {
user: {
collections: {
collections: []
},
personalization: {
projectPreferences: {
settings: {
workflow_id: '1234'
}
},
sessionCount: 0,
stats: {
thisWeek: []
}
},
recents: {
recents: []
}
}
})
const wrapper = mount(
<RouterContext.Provider value={mockRouter}>
<Provider store={mockStoreWithAssignment}>
<ClassifyPageContainer
assignedWorkflowID='1234'
workflowAssignmentEnabled
workflowID='5678'
workflows={workflows}
/>
</Provider>
</RouterContext.Provider>, {
wrappingComponent: Grommet,
wrappingComponentProps: { theme: zooTheme }
})
expect(wrapper.find(ClassifyPage).props().workflowFromUrl).to.be.null()
expect(wrapper.find(ClassifyPage).props().workflowID).to.be.undefined()
})
})
})

@goplayoutside3
Copy link
Contributor

@eatyourgreens Re:

*do workflow levels change over time? If not, the fetched value can be cached indefinitely.

Yes they can change levels. The project team has full control over workflow level configuration. Does that fact change any code in this PR?

@eatyourgreens
Copy link
Contributor Author

eatyourgreens commented Aug 18, 2024

I shouldn't imagine so, but you can adjust the revalidation options if the hook is constantly requesting the same level from Panoptes, for a given workflow.

https://swr.vercel.app/docs/revalidation

You can also turn off revalidation completely for immutable resources.

https://swr.vercel.app/docs/revalidation#disable-automatic-revalidations

@eatyourgreens
Copy link
Contributor Author

eatyourgreens commented Aug 18, 2024

Right now, in production, the Classify page requests the workflow config from Panoptes on every visit to the page, even if it already has it. Workflow select buttons then repeat the request, even though the app already has the workflow config for the missing workflow.

EDIT: in Strict Mode, I see the useEffect hook make 2 API requests per component but SWR makes 1 request then reuses the cached response.

That can be improved by checking if the workflow config is already present in page props, before making a request to Panoptes, and by caching the API response for reuse.

@eatyourgreens
Copy link
Contributor Author

if (response.ok) {
const fetchedWorkflow = response.body.workflows?.[0]
setAssignedWorkflowLevel(parseInt(fetchedWorkflow?.configuration?.level), 10)
}

If the assigned workflow ID in my user preferences is an inactive workflow, then fetchedWorkflow will be undefined here and assignedWorkflowLevel will be set to NaN. I've updated this PR to catch that case and return 1.

Fix missing dependency errors in the `useAssignedLevel` hook by using `useSWR` to fetch and cache the assigned workflow level. SWR also adds revalidation for cases where I might classify in the same tab over several days or weeks.

Also fixes the workflow assignment tests in `ClassifyPageContainer` so that they test against the correct levels.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

project build error: missing useEffect dependency for assigned workflows
3 participants