-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Classifier tasks: Add SubjectViewerStore to task stories (#2031)
Rewrite all task stories as CSF. Move common task story code into a `MockTask` component, which takes a `tasks` object and renders it in a `Tasks` component, with a classifier store. Adds `@stories` as an alias for storybook helper code and `@components` as an alias for the root of the Classify components tree. Fixes a small bug where feature detection helpers weren't being exported properly.
- Loading branch information
1 parent
1cc8ca1
commit c09f091
Showing
17 changed files
with
559 additions
and
977 deletions.
There are no files selected for viewing
193 changes: 62 additions & 131 deletions
193
...lassifier/src/components/Classifier/components/TaskArea/components/Tasks/Tasks.stories.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,144 +1,75 @@ | ||
import { withKnobs, boolean, radios, select } from '@storybook/addon-knobs' | ||
import asyncStates from '@zooniverse/async-states' | ||
import { storiesOf } from '@storybook/react' | ||
import zooTheme from '@zooniverse/grommet-theme' | ||
import { types } from 'mobx-state-tree' | ||
import React from 'react' | ||
import { Box, Grommet } from 'grommet' | ||
import { Provider } from 'mobx-react' | ||
import { Tasks } from './Tasks' | ||
import ClassificationStore from '@store/ClassificationStore' | ||
import SubjectStore from '@store/SubjectStore' | ||
import WorkflowStore from '@store/WorkflowStore' | ||
import WorkflowStepStore from '@store/WorkflowStepStore' | ||
import { MockTask } from '@stories/components' | ||
import Tasks from './Tasks' | ||
|
||
function createStore() { | ||
const classifications = ClassificationStore.create() | ||
const mockSubject = { | ||
id: 'subject', | ||
metadata: {} | ||
} | ||
const mockWorkflow = { | ||
id: 'workflow', | ||
version: '1.0' | ||
} | ||
const mockProject = { | ||
id: 'project' | ||
export default { | ||
title: 'Tasks / General', | ||
component: Tasks, | ||
args: { | ||
dark: false, | ||
isThereTaskHelp: true, | ||
required: false, | ||
subjectReadyState: asyncStates.success | ||
}, | ||
argTypes: { | ||
subjectReadyState: { | ||
control: { | ||
type: 'select', | ||
options: asyncStates | ||
} | ||
} | ||
}, | ||
parameters: { | ||
viewport: { | ||
defaultViewport: 'responsive' | ||
} | ||
} | ||
|
||
const store = types.model('MockStore', { | ||
classifications: ClassificationStore, | ||
subjects: SubjectStore, | ||
workflows: WorkflowStore, | ||
workflowSteps: WorkflowStepStore | ||
}) | ||
.create({ | ||
classifications, | ||
subjects: SubjectStore.create({}), | ||
workflows: WorkflowStore.create({}), | ||
workflowSteps: WorkflowStepStore.create({}) | ||
}) | ||
classifications.createClassification(mockSubject, mockWorkflow, mockProject) | ||
return store | ||
} | ||
|
||
const store = createStore() | ||
function addStepToStore (step, tasks) { | ||
const steps = [ ['S1', step] ] | ||
store.workflowSteps.setStepsAndTasks({ steps, tasks }) | ||
store.workflowSteps.active.tasks.forEach(task => store.classifications.addAnnotation(task)) | ||
export function Loading({ dark, isThereTaskHelp, required, subjectReadyState }) { | ||
return ( | ||
<MockTask | ||
dark={dark} | ||
loadingState={asyncStates.loading} | ||
/> | ||
) | ||
} | ||
|
||
function MockTask (props) { | ||
const { dark, ...taskProps } = props | ||
|
||
export function Error({ dark, isThereTaskHelp, required, subjectReadyState }) { | ||
return ( | ||
<Grommet | ||
background={{ | ||
dark: 'dark-1', | ||
light: 'light-1' | ||
}} | ||
theme={Object.assign({}, zooTheme, { dark })} | ||
themeMode={(dark) ? 'dark' : 'light'} | ||
> | ||
<Box | ||
background={{ | ||
dark: 'dark-3', | ||
light: 'neutral-6' | ||
}} | ||
pad='1em' | ||
width='380px' | ||
> | ||
<Tasks | ||
{...taskProps} | ||
/> | ||
</Box> | ||
</Grommet> | ||
<MockTask | ||
dark={dark} | ||
loadingState={asyncStates.error} | ||
/> | ||
) | ||
} | ||
|
||
storiesOf('Tasks / General', module) | ||
.addDecorator(withKnobs) | ||
.addParameters({ | ||
viewport: { | ||
defaultViewport: 'responsive' | ||
} | ||
}) | ||
.add('loading', function () { | ||
return ( | ||
<Provider classifierStore={{}}> | ||
<MockTask | ||
loadingState={asyncStates.loading} | ||
/> | ||
</Provider> | ||
) | ||
}) | ||
.add('error', function () { | ||
return ( | ||
<Provider classifierStore={{}}> | ||
<MockTask | ||
loadingState={asyncStates.error} | ||
/> | ||
</Provider> | ||
) | ||
}) | ||
.add('multiple tasks', function () { | ||
const tasks = { | ||
init: { | ||
answers: [{ label: 'yes' }, { label: 'no' }], | ||
help: 'Choose an answer from the choices given, then press Done.', | ||
question: 'Is there a cat?', | ||
required: radios('Required', { true: 'true', false: '' }, ''), | ||
taskKey: 'init', | ||
type: 'single' | ||
}, | ||
T1: { | ||
answers: [{ label: 'sleeping' }, { label: 'playing' }, { label: 'looking indifferent' }], | ||
help: 'Pick as many answers as apply, then press Done.', | ||
question: 'What is it doing?', | ||
required: radios('Required', { true: 'true', false: '' }, ''), | ||
taskKey: 'T1', | ||
type: 'multiple' | ||
} | ||
export function MultipleTasks({ dark, isThereTaskHelp, required, subjectReadyState }) { | ||
const tasks = { | ||
init: { | ||
answers: [{ label: 'yes' }, { label: 'no' }], | ||
help: 'Choose an answer from the choices given, then press Done.', | ||
question: 'Is there a cat?', | ||
required, | ||
taskKey: 'init', | ||
type: 'single' | ||
}, | ||
T1: { | ||
answers: [{ label: 'sleeping' }, { label: 'playing' }, { label: 'looking indifferent' }], | ||
help: 'Pick as many answers as apply, then press Done.', | ||
question: 'What is it doing?', | ||
required, | ||
taskKey: 'T1', | ||
type: 'multiple' | ||
} | ||
const step = { | ||
stepKey: 'S1', | ||
taskKeys: ['init', 'T1'] | ||
} | ||
addStepToStore(step, tasks) | ||
const dark = boolean('Dark theme', false) | ||
const subjectReadyState = select('Subject loading', asyncStates, asyncStates.success) | ||
const isThereTaskHelp = boolean('Enable task help', true) | ||
return ( | ||
<Provider classifierStore={store}> | ||
<MockTask | ||
dark={dark} | ||
classification={store.classifications.active} | ||
isThereTaskHelp={isThereTaskHelp} | ||
loadingState={asyncStates.success} | ||
step={store.workflowSteps.active} | ||
subjectReadyState={subjectReadyState} | ||
/> | ||
</Provider> | ||
) | ||
}) | ||
} | ||
return ( | ||
<MockTask | ||
dark={dark} | ||
isThereTaskHelp={isThereTaskHelp} | ||
subjectReadyState={subjectReadyState} | ||
tasks={tasks} | ||
/> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,9 @@ | ||
import * as featureDetection from './featureDetection' | ||
export { default as createLocationCounts } from './createLocationCounts' | ||
export { default as featureDetection } from './featureDetection' | ||
export { featureDetection } | ||
export { default as findLocationsByMediaType } from './findLocationsByMediaType' | ||
export { default as layouts } from './layouts' | ||
export { default as shownMarks } from './shownMarks' | ||
export { default as subjectViewers } from './subjectViewers' | ||
export { default as validateMimeType } from './validateMimeType' | ||
export { default as validateSubjectLocations } from './validateSubjectLocations' | ||
export { default as shownMarks } from './shownMarks' |
158 changes: 45 additions & 113 deletions
158
...ifier/src/plugins/tasks/DataVisAnnotationTask/components/DataVisAnnotationTask.stories.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,122 +1,54 @@ | ||
import { withKnobs, boolean, select } from '@storybook/addon-knobs' | ||
import asyncStates from '@zooniverse/async-states' | ||
import { storiesOf } from '@storybook/react' | ||
import zooTheme from '@zooniverse/grommet-theme' | ||
import { types } from 'mobx-state-tree' | ||
import React from 'react' | ||
import { Box, Grommet } from 'grommet' | ||
import { Provider } from 'mobx-react' | ||
import { Tasks } from '../../../../components/Classifier/components/TaskArea/components/Tasks/Tasks' | ||
import ClassificationStore from '@store/ClassificationStore' | ||
import SubjectStore from '@store/SubjectStore' | ||
import WorkflowStore from '@store/WorkflowStore' | ||
import WorkflowStepStore from '@store/WorkflowStepStore' | ||
import { MockTask } from '@stories/components' | ||
import DataVisAnnotationTask from './DataVisAnnotationTask' | ||
|
||
function createStore() { | ||
const classifications = ClassificationStore.create() | ||
const mockSubject = { | ||
id: 'subject', | ||
metadata: {} | ||
} | ||
const mockWorkflow = { | ||
id: 'workflow', | ||
version: '1.0' | ||
} | ||
const mockProject = { | ||
id: 'project' | ||
export default { | ||
title: 'Tasks / Data Visualization Annotation', | ||
component: DataVisAnnotationTask, | ||
args: { | ||
dark: false, | ||
isThereTaskHelp: true, | ||
required: false, | ||
subjectReadyState: asyncStates.success | ||
}, | ||
argTypes: { | ||
subjectReadyState: { | ||
control: { | ||
type: 'select', | ||
options: asyncStates | ||
} | ||
} | ||
}, | ||
parameters: { | ||
viewport: { | ||
defaultViewport: 'responsive' | ||
} | ||
} | ||
|
||
const store = types.model('MockStore', { | ||
classifications: ClassificationStore, | ||
subjects: SubjectStore, | ||
workflows: WorkflowStore, | ||
workflowSteps: WorkflowStepStore | ||
}) | ||
.create({ | ||
classifications, | ||
subjects: SubjectStore.create({}), | ||
workflows: WorkflowStore.create({}), | ||
workflowSteps: WorkflowStepStore.create({}) | ||
}) | ||
classifications.createClassification(mockSubject, mockWorkflow, mockProject) | ||
return store | ||
} | ||
|
||
const store = createStore() | ||
function addStepToStore(step, tasks) { | ||
const steps = [['S1', step]] | ||
store.workflowSteps.setStepsAndTasks({ steps, tasks }) | ||
store.workflowSteps.active.tasks.forEach(task => store.classifications.addAnnotation(task)) | ||
} | ||
|
||
function MockTask(props) { | ||
const { dark, ...taskProps } = props | ||
|
||
export function LightTheme({ dark, isThereTaskHelp, required, subjectReadyState }) { | ||
const tasks = { | ||
T4: { | ||
instruction: 'Do you spot a transit?', | ||
required, | ||
taskKey: 'T4', | ||
tools: [ | ||
{ | ||
help: '', | ||
label: 'Transit?', | ||
type: 'graph2dRangeX' | ||
} | ||
], | ||
type: 'dataVisAnnotation' | ||
} | ||
} | ||
return ( | ||
<Grommet | ||
background={{ | ||
dark: 'dark-1', | ||
light: 'light-1' | ||
}} | ||
theme={Object.assign({}, zooTheme, { dark })} | ||
themeMode={(dark) ? 'dark' : 'light'} | ||
> | ||
<Box | ||
background={{ | ||
dark: 'dark-3', | ||
light: 'neutral-6' | ||
}} | ||
pad='1em' | ||
width='380px' | ||
> | ||
<Tasks | ||
{...taskProps} | ||
/> | ||
</Box> | ||
</Grommet> | ||
<MockTask | ||
dark={dark} | ||
isThereTaskHelp={isThereTaskHelp} | ||
subjectReadyState={subjectReadyState} | ||
tasks={tasks} | ||
/> | ||
) | ||
} | ||
|
||
storiesOf('Tasks / Data Visualization Annotation', module) | ||
.addDecorator(withKnobs) | ||
.addParameters({ | ||
viewport: { | ||
defaultViewport: 'responsive' | ||
} | ||
}) | ||
.add('light theme', function () { | ||
const tasks = { | ||
T4: { | ||
instruction: 'Do you spot a transit?', | ||
taskKey: 'T4', | ||
tools: [ | ||
{ | ||
help: '', | ||
label: 'Transit?', | ||
type: 'graph2dRangeX' | ||
} | ||
], | ||
type: 'dataVisAnnotation' | ||
} | ||
} | ||
const step = { | ||
stepKey: 'S1', | ||
taskKeys: ['T4'] | ||
} | ||
addStepToStore(step, tasks) | ||
const dark = boolean('Dark theme', false) | ||
const subjectReadyState = select('Subject loading', asyncStates, asyncStates.success) | ||
const isThereTaskHelp = boolean('Enable task help', true) | ||
return ( | ||
<Provider classifierStore={store}> | ||
<MockTask | ||
dark={dark} | ||
classification={store.classifications.active} | ||
isThereTaskHelp={isThereTaskHelp} | ||
loadingState={asyncStates.success} | ||
step={store.workflowSteps.active} | ||
subjectReadyState={subjectReadyState} | ||
/> | ||
</Provider> | ||
) | ||
}) |
Oops, something went wrong.