diff --git a/packages/lib-classifier/src/components/Classifier/components/ImageToolbar/ImageToolbar.js b/packages/lib-classifier/src/components/Classifier/components/ImageToolbar/ImageToolbar.js index 0f8231f3f62..226765ed3c8 100644 --- a/packages/lib-classifier/src/components/Classifier/components/ImageToolbar/ImageToolbar.js +++ b/packages/lib-classifier/src/components/Classifier/components/ImageToolbar/ImageToolbar.js @@ -1,5 +1,6 @@ import { Box } from 'grommet' import { observer } from 'mobx-react' +import { useStores } from '@hooks' import FieldGuide from '../FieldGuide' import AnnotateButton from './components/AnnotateButton' @@ -12,9 +13,15 @@ import ZoomInButton from './components/ZoomInButton' import ZoomOutButton from './components/ZoomOutButton' import { useKeyZoom } from '@hooks' +function storeMapper(classifierStore) { + return { showAnnotateButton: classifierStore.subjectViewer.showAnnotate } +} + // Generalized ...props here are css rules from the page layout function ImageToolbar (props) { + const { showAnnotateButton } = useStores(storeMapper) const { onKeyZoom } = useKeyZoom() + return ( - + {showAnnotateButton && } diff --git a/packages/lib-classifier/src/components/Classifier/components/ImageToolbar/ImageToolbar.spec.js b/packages/lib-classifier/src/components/Classifier/components/ImageToolbar/ImageToolbar.spec.js index 1f014de70e6..b529601476b 100644 --- a/packages/lib-classifier/src/components/Classifier/components/ImageToolbar/ImageToolbar.spec.js +++ b/packages/lib-classifier/src/components/Classifier/components/ImageToolbar/ImageToolbar.spec.js @@ -1,34 +1,55 @@ -import { render } from '@testing-library/react' -import zooTheme from '@zooniverse/grommet-theme' -import { Grommet } from 'grommet' +import { render, screen } from '@testing-library/react' import { Provider } from 'mobx-react' -import mockStore from '@test/mockStore/mockStore.js' +import { DrawingTaskFactory, SingleChoiceTaskFactory, WorkflowFactory } from '@test/factories' +import mockStore from '@test/mockStore/mockStore.js' import ImageToolbar from './ImageToolbar' describe('Component > ImageToolbar', function () { - function withStore() { - return function Wrapper({ - children = null, - store = mockStore() - }) { - return ( - - - {children} - - - ) - } - } - - it('should render without crashing', function () { + it('should render with the annotate button', function () { + // Create minimal store with drawing task + const store = mockStore({ + workflow: WorkflowFactory.build({ + tasks: { + T1: DrawingTaskFactory.build(), + } + }) + }) + + // SubjectViewerStore.afterAttach() reaction needs to be called manually + // This is because the mockStore is not a real store, so it does not have the afterAttach() reaction + store.subjectViewer.setAnnotateVisibility(store.workflowSteps.hasAnnotateTask); + render( - , - { - wrapper: withStore() - } - ) + + + + ); + + expect(screen.queryByLabelText('ImageToolbar.AnnotateButton.ariaLabel')).to.exist() + }) + + it('should render without the annotate button', function () { + // Create minimal store without drawing task + const store = mockStore({ + workflow: WorkflowFactory.build({ + tasks: { + T1: SingleChoiceTaskFactory.build(), + } + }) + }) + + // SubjectViewerStore.afterAttach() reaction needs to be called manually + // This is because the mockStore is not a real store, so it does not have the afterAttach() reaction + store.subjectViewer.setAnnotateVisibility(store.workflowSteps.hasAnnotateTask); + + render( + + + + ); + + expect(screen.queryByLabelText('ImageToolbar.AnnotateButton.ariaLabel')).to.be.null() }) }) diff --git a/packages/lib-classifier/src/components/Classifier/components/ImageToolbar/components/AnnotateButton/AnnotateButtonContainer.js b/packages/lib-classifier/src/components/Classifier/components/ImageToolbar/components/AnnotateButton/AnnotateButtonContainer.js index 230a1cad564..89063c9d878 100644 --- a/packages/lib-classifier/src/components/Classifier/components/ImageToolbar/components/AnnotateButton/AnnotateButtonContainer.js +++ b/packages/lib-classifier/src/components/Classifier/components/ImageToolbar/components/AnnotateButton/AnnotateButtonContainer.js @@ -19,7 +19,11 @@ function AnnotateButtonContainer({ separateFrameAnnotate = false, separateFrameEnableAnnotate = () => true }) { - const { annotate, enableAnnotate, separateFramesView } = useStores(storeMapper) + const { + annotate, + enableAnnotate, + separateFramesView + } = useStores(storeMapper) return ( getRoot(self)?.workflowSteps.hasAnnotateTask, + self.setAnnotateVisibility + ) }, enableAnnotate () { @@ -93,7 +100,6 @@ const SubjectViewer = types }, invertView () { - console.log('invert view') self.invert = !self.invert }, @@ -157,6 +163,16 @@ const SubjectViewer = types self.rotation -= 90 }, + setAnnotateVisibility (canAnnotate) { + if (canAnnotate) { + self.enableAnnotate() + } else { + self.enableMove() + } + + self.showAnnotate = canAnnotate + }, + setFlipbookSpeed (speed) { self.flipbookSpeed = speed }, diff --git a/packages/lib-classifier/src/store/WorkflowStepStore/WorkflowStepStore.js b/packages/lib-classifier/src/store/WorkflowStepStore/WorkflowStepStore.js index a843df85417..ed8ace94ffb 100644 --- a/packages/lib-classifier/src/store/WorkflowStepStore/WorkflowStepStore.js +++ b/packages/lib-classifier/src/store/WorkflowStepStore/WorkflowStepStore.js @@ -75,6 +75,20 @@ const WorkflowStepStore = types return activeInteractionTask || {} }, + // Needs to check all steps, not just the active one + get hasAnnotateTask () { + let hasTask = false + + for (const key in self.workflow?.tasks) { + const task = self.workflow.tasks[key] + if (task.type === 'drawing' || task.type === 'transcription' || task.type === 'dataVisAnnotation') { + hasTask = true + } + } + + return hasTask + }, + get locale() { return getRoot(self).locale },