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

Classifier: add a loading state #2986

Merged
merged 1 commit into from
Mar 23, 2022
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { GraphQLClient } from 'graphql-request'
import { Paragraph } from 'grommet'
import { Provider } from 'mobx-react'
import PropTypes from 'prop-types'
import React, { useEffect } from 'react'
import React, { useEffect, useState } from 'react'
import '../../translations/i18n'
import {
env,
Expand Down Expand Up @@ -62,24 +62,19 @@ export default function ClassifierContainer({
workflowID
}) {

const [loaded, setLoaded] = useState(false)
const storeEnvironment = { authClient, client }

const workflowSnapshot = useWorkflowSnapshot(workflowID)

const classifierStore = useHydratedStore(storeEnvironment, cachePanoptesData, `fem-classifier-${project.id}`)
const loaded = !!classifierStore

useEffect(function onMount() {
console.log('resetting stale user data')
classifierStore?.userProjectPreferences.reset()
}, [])

useEffect(function onLoad() {
/*
If the project uses session storage, we need to do some
processing of the store after it loads.
*/
if (cachePanoptesData && loaded) {
if (cachePanoptesData) {
const { subjects, workflows } = classifierStore
if (!workflows.active?.prioritized) {
/*
Expand All @@ -104,16 +99,17 @@ export default function ClassifierContainer({
Otherwise, hydration will overwrite the callbacks with
their defaults.
*/
if (loaded) {
const { classifications, subjects } = classifierStore
console.log('setting classifier event callbacks')
classifications.setOnComplete(onCompleteClassification)
subjects.setOnReset(onSubjectReset)
classifierStore.setOnAddToCollection(onAddToCollection)
classifierStore.setOnSubjectChange(onSubjectChange)
classifierStore.setOnToggleFavourite(onToggleFavourite)
}
}, [cachePanoptesData, loaded])
const { classifications, subjects, userProjectPreferences } = classifierStore
console.log('resetting stale user data')
userProjectPreferences.reset()
console.log('setting classifier event callbacks')
classifications.setOnComplete(onCompleteClassification)
subjects.setOnReset(onSubjectReset)
classifierStore.setOnAddToCollection(onAddToCollection)
classifierStore.setOnSubjectChange(onSubjectChange)
classifierStore.setOnToggleFavourite(onToggleFavourite)
setLoaded(true)
}, [])

useEffect(function onAuthChange() {
if (loaded) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,21 @@ describe('Model > Tutorial', function () {
store.tutorials.setTutorials([tutorialSnapshot])
})

it('should be false when the store first loads', function () {
it('should be false while UPP loads', function () {
store.userProjectPreferences.fetchUPP({ id: 'test' })
const tutorial = store.tutorials.active
expect(tutorial.hasNotBeenSeen).to.be.false()
})

it('should be true for anonymous users', async function () {
let tutorial = store.tutorials.active
expect(tutorial.hasNotBeenSeen).to.be.false()
await when(() => store.userProjectPreferences.loadingState === asyncStates.success)
tutorial = store.tutorials.active
expect(tutorial.hasNotBeenSeen).to.be.true()
})

it('should be true after the user has loaded', async function () {
let tutorial = store.tutorials.active
expect(tutorial.hasNotBeenSeen).to.be.false()
await when(() => store.userProjectPreferences.loadingState === asyncStates.success)
const upp = UPPFactory.build()
store.userProjectPreferences.setUPP(upp)
Expand All @@ -45,7 +44,6 @@ describe('Model > Tutorial', function () {

it('should be false after a user has seen the tutorial', async function () {
let tutorial = store.tutorials.active
expect(tutorial.hasNotBeenSeen).to.be.false()
await when(() => store.userProjectPreferences.loadingState === asyncStates.success)
const upp = UPPFactory.build()
store.userProjectPreferences.setUPP(upp)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,10 @@ const UserProjectPreferencesStore = types
const { authClient } = getRoot(self)

try {
const authorization = yield getBearerToken(authClient)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if this can be reliably reproduced, but I was seeing this occasionally return an empty string, even when I was logged in.

const user = yield authClient.checkCurrent()

if (authorization && user) {
self.fetchUPP(authorization, user)
if (user) {
self.fetchUPP(user)
} else {
self.reset()
self.loadingState = asyncStates.success
Expand All @@ -71,14 +70,16 @@ const UserProjectPreferencesStore = types
}
}

function * fetchUPP (authorization, user) {
function * fetchUPP (user) {
let resource
const { type } = self
const { authClient } = getRoot(self)
const client = getRoot(self).client.panoptes
const project = getRoot(self).projects.active

self.loadingState = asyncStates.loading
try {
const authorization = yield getBearerToken(authClient)
const response = yield client.get(`/${type}`, { project_id: project.id, user_id: user.id }, { authorization })
if (response.body[type][0]) {
// We don't store the headers from this get response because it's by query params
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ describe('Model > UserProjectPreferencesStore', function () {
it('should check for a user upon initialization when there is a project', async function () {
rootStore = setupStores(clientStub, authClientStubWithoutUser)
await rootStore.projects.setActive(project.id)
expect(authClientStubWithoutUser.checkBearerToken).to.have.been.called()
expect(authClientStubWithoutUser.checkCurrent).to.have.been.called()
})

Expand Down