Consolidating annotation in redux
parent
f473fc0872
commit
c953205baf
|
@ -27,36 +27,43 @@ const a2 = {
|
|||
text: 'you have no swoggels',
|
||||
}
|
||||
|
||||
const state = {
|
||||
mode: null,
|
||||
annotations: [],
|
||||
}
|
||||
|
||||
describe.only('Shared.Reducers.annotations', () => {
|
||||
it('can load the annotations', () => {
|
||||
const state = []
|
||||
const expected = [{time: '0', duration: ''}]
|
||||
const actual = reducer(state, loadAnnotations(expected))
|
||||
|
||||
expect(actual).to.deep.equal(expected)
|
||||
expect(actual.annotations).to.deep.equal(expected)
|
||||
})
|
||||
|
||||
it('can update an annotation', () => {
|
||||
const state = [a1]
|
||||
const expected = [{...a1, time: ''}]
|
||||
const actual = reducer(state, updateAnnotation(expected[0]))
|
||||
const actual = reducer(
|
||||
{...state, annotations: [a1]},
|
||||
updateAnnotation(expected[0])
|
||||
)
|
||||
|
||||
expect(actual).to.deep.equal(expected)
|
||||
expect(actual.annotations).to.deep.equal(expected)
|
||||
})
|
||||
|
||||
it('can delete an annotation', () => {
|
||||
const state = [a1, a2]
|
||||
const expected = [a2]
|
||||
const actual = reducer(state, deleteAnnotation(a1))
|
||||
const actual = reducer(
|
||||
{...state, annotations: [a1, a2]},
|
||||
deleteAnnotation(a1)
|
||||
)
|
||||
|
||||
expect(actual).to.deep.equal(expected)
|
||||
expect(actual.annotations).to.deep.equal(expected)
|
||||
})
|
||||
|
||||
it('can add an annotation', () => {
|
||||
const state = []
|
||||
const expected = [{...a1, id: DEFAULT_ANNOTATION_ID}]
|
||||
const actual = reducer(state, addAnnotation(a1))
|
||||
|
||||
expect(actual).to.deep.equal(expected)
|
||||
expect(actual.annotations).to.deep.equal(expected)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -23,6 +23,7 @@ const Dashboard = ({
|
|||
onSummonOverlayTechnologies,
|
||||
onSelectTemplate,
|
||||
showTemplateControlBar,
|
||||
onStartAddingAnnotation,
|
||||
}) => {
|
||||
const cells = dashboard.cells.map(cell => {
|
||||
const dashboardCell = {...cell}
|
||||
|
@ -63,6 +64,7 @@ const Dashboard = ({
|
|||
onDeleteCell={onDeleteCell}
|
||||
onPositionChange={onPositionChange}
|
||||
templates={templatesIncludingDashTime}
|
||||
onStartAddingAnnotation={onStartAddingAnnotation}
|
||||
onSummonOverlayTechnologies={onSummonOverlayTechnologies}
|
||||
/>
|
||||
: <div className="dashboard__empty">
|
||||
|
@ -119,6 +121,7 @@ Dashboard.propTypes = {
|
|||
onSelectTemplate: func.isRequired,
|
||||
showTemplateControlBar: bool,
|
||||
onZoom: func,
|
||||
onStartAddingAnnotation: func.isRequired,
|
||||
}
|
||||
|
||||
export default Dashboard
|
||||
|
|
|
@ -25,6 +25,7 @@ import {
|
|||
setAutoRefresh,
|
||||
templateControlBarVisibilityToggled as templateControlBarVisibilityToggledAction,
|
||||
} from 'shared/actions/app'
|
||||
import {addingAnnotation} from 'shared/actions/annotations'
|
||||
import {presentationButtonDispatcher} from 'shared/dispatchers'
|
||||
|
||||
const FORMAT_INFLUXQL = 'influxql'
|
||||
|
@ -248,6 +249,7 @@ class DashboardPage extends Component {
|
|||
handleChooseAutoRefresh,
|
||||
handleClickPresentationButton,
|
||||
params: {sourceID, dashboardID},
|
||||
handleStartAddingAnnotation,
|
||||
} = this.props
|
||||
|
||||
const low = zoomedLower ? zoomedLower : lower
|
||||
|
@ -387,6 +389,7 @@ class DashboardPage extends Component {
|
|||
showTemplateControlBar={showTemplateControlBar}
|
||||
onOpenTemplateManager={this.handleOpenTemplateManager}
|
||||
templatesIncludingDashTime={templatesIncludingDashTime}
|
||||
onStartAddingAnnotation={handleStartAddingAnnotation}
|
||||
onSummonOverlayTechnologies={this.handleSummonOverlayTechnologies}
|
||||
/>
|
||||
: null}
|
||||
|
@ -467,6 +470,7 @@ DashboardPage.propTypes = {
|
|||
isUsingAuth: bool.isRequired,
|
||||
router: shape().isRequired,
|
||||
notify: func.isRequired,
|
||||
handleStartAddingAnnotation: func.isRequired,
|
||||
}
|
||||
|
||||
const mapStateToProps = (state, {params: {dashboardID}}) => {
|
||||
|
@ -516,6 +520,7 @@ const mapDispatchToProps = dispatch => ({
|
|||
dashboardActions: bindActionCreators(dashboardActionCreators, dispatch),
|
||||
errorThrown: bindActionCreators(errorThrownAction, dispatch),
|
||||
notify: bindActionCreators(publishNotification, dispatch),
|
||||
handleStartAddingAnnotation: bindActionCreators(addingAnnotation, dispatch),
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
export const addingAnnotation = () => ({
|
||||
type: 'ADDING_ANNOTATION',
|
||||
})
|
||||
|
||||
export const addingAnnotationSuccess = () => ({
|
||||
type: 'ADDING_ANNOTATION_SUCCESS',
|
||||
})
|
||||
|
||||
export const loadAnnotations = annotations => ({
|
||||
type: 'LOAD_ANNOTATIONS',
|
||||
payload: {
|
||||
|
|
|
@ -1,3 +1,15 @@
|
|||
export const ADDING = 'adding'
|
||||
export const EDITING = 'editing'
|
||||
|
||||
export const TEMP_ANNOTATION = {
|
||||
id: 'tempAnnotation',
|
||||
group: '',
|
||||
name: 'New Annotation',
|
||||
time: '',
|
||||
duration: '',
|
||||
text: '',
|
||||
}
|
||||
|
||||
export const getAnnotations = (graph, annotations = []) => {
|
||||
if (!graph) {
|
||||
return []
|
||||
|
|
|
@ -4,11 +4,15 @@ import {bindActionCreators} from 'redux'
|
|||
|
||||
import Annotation from 'src/shared/components/Annotation'
|
||||
import AnnotationWindow from 'src/shared/components/AnnotationWindow'
|
||||
import NewAnnotation from 'src/shared/components/NewAnnotation'
|
||||
|
||||
import {ADDING} from 'src/shared/annotations/helpers'
|
||||
|
||||
import {
|
||||
addAnnotation,
|
||||
updateAnnotation,
|
||||
deleteAnnotation,
|
||||
addingAnnotationSuccess,
|
||||
} from 'src/shared/actions/annotations'
|
||||
import {getAnnotations} from 'src/shared/annotations/helpers'
|
||||
|
||||
|
@ -23,7 +27,13 @@ class Annotations extends Component {
|
|||
|
||||
render() {
|
||||
const {dygraph} = this.state
|
||||
const {mode, handleUpdateAnnotation, handleDeleteAnnotation} = this.props
|
||||
const {
|
||||
mode,
|
||||
handleUpdateAnnotation,
|
||||
handleDeleteAnnotation,
|
||||
handleAddAnnotation,
|
||||
handleAddingAnnotationSuccess,
|
||||
} = this.props
|
||||
|
||||
if (!dygraph) {
|
||||
return null
|
||||
|
@ -33,6 +43,12 @@ class Annotations extends Component {
|
|||
|
||||
return (
|
||||
<div className="annotations-container">
|
||||
{mode === ADDING &&
|
||||
<NewAnnotation
|
||||
dygraph={dygraph}
|
||||
onAddAnnotation={handleAddAnnotation}
|
||||
onAddingAnnotationSuccess={handleAddingAnnotationSuccess}
|
||||
/>}
|
||||
{annotations.map(a =>
|
||||
<Annotation
|
||||
key={a.id}
|
||||
|
@ -63,13 +79,19 @@ Annotations.propTypes = {
|
|||
handleDeleteAnnotation: func.isRequired,
|
||||
handleUpdateAnnotation: func.isRequired,
|
||||
handleAddAnnotation: func.isRequired,
|
||||
handleAddingAnnotationSuccess: func.isRequired,
|
||||
}
|
||||
|
||||
const mapStateToProps = ({annotations}) => ({
|
||||
const mapStateToProps = ({annotations: {annotations, mode}}) => ({
|
||||
annotations,
|
||||
mode,
|
||||
})
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
handleAddingAnnotationSuccess: bindActionCreators(
|
||||
addingAnnotationSuccess,
|
||||
dispatch
|
||||
),
|
||||
handleAddAnnotation: bindActionCreators(addAnnotation, dispatch),
|
||||
handleUpdateAnnotation: bindActionCreators(updateAnnotation, dispatch),
|
||||
handleDeleteAnnotation: bindActionCreators(deleteAnnotation, dispatch),
|
||||
|
|
|
@ -295,17 +295,12 @@ export default class Dygraph extends Component {
|
|||
handleAnnotationsRef = ref => (this.annotationsRef = ref)
|
||||
|
||||
render() {
|
||||
const {annotationMode} = this.props
|
||||
const {isHidden} = this.state
|
||||
|
||||
return (
|
||||
<div className="dygraph-child" onMouseLeave={this.deselectCrosshair}>
|
||||
<Annotations
|
||||
mode={annotationMode}
|
||||
annotationsRef={this.handleAnnotationsRef}
|
||||
/>
|
||||
<Annotations annotationsRef={this.handleAnnotationsRef} />
|
||||
{this.dygraph &&
|
||||
annotationMode !== 'adding' &&
|
||||
<DygraphLegend
|
||||
isHidden={isHidden}
|
||||
dygraph={this.dygraph}
|
||||
|
@ -379,5 +374,4 @@ Dygraph.propTypes = {
|
|||
setResolution: func,
|
||||
dygraphRef: func,
|
||||
onZoom: func,
|
||||
annotationMode: string,
|
||||
}
|
||||
|
|
|
@ -53,9 +53,9 @@ const Layout = (
|
|||
onDeleteCell,
|
||||
synchronizer,
|
||||
resizeCoords,
|
||||
annotationMode,
|
||||
onCancelEditCell,
|
||||
onStartAddAnnotation,
|
||||
onStopAddAnnotation,
|
||||
onStartAddingAnnotation,
|
||||
onSummonOverlayTechnologies,
|
||||
grabDataForDownload,
|
||||
},
|
||||
|
@ -68,7 +68,7 @@ const Layout = (
|
|||
onEditCell={onEditCell}
|
||||
onDeleteCell={onDeleteCell}
|
||||
onCancelEditCell={onCancelEditCell}
|
||||
onStartAddAnnotation={onStartAddAnnotation}
|
||||
onStartAddingAnnotation={onStartAddingAnnotation}
|
||||
onSummonOverlayTechnologies={onSummonOverlayTechnologies}
|
||||
>
|
||||
{cell.isWidget
|
||||
|
@ -85,7 +85,7 @@ const Layout = (
|
|||
autoRefresh={autoRefresh}
|
||||
synchronizer={synchronizer}
|
||||
manualRefresh={manualRefresh}
|
||||
annotationMode={annotationMode}
|
||||
onStopAddAnnotation={onStopAddAnnotation}
|
||||
grabDataForDownload={grabDataForDownload}
|
||||
resizeCoords={resizeCoords}
|
||||
queries={buildQueriesForLayouts(
|
||||
|
|
|
@ -35,7 +35,7 @@ class LayoutCell extends Component {
|
|||
children,
|
||||
isEditable,
|
||||
celldata,
|
||||
onStartAddAnnotation,
|
||||
onStartAddingAnnotation,
|
||||
} = this.props
|
||||
|
||||
const queries = _.get(cell, ['queries'], [])
|
||||
|
@ -52,7 +52,7 @@ class LayoutCell extends Component {
|
|||
onEdit={this.handleSummonOverlay}
|
||||
handleClickOutside={this.closeMenu}
|
||||
onCSVDownload={this.handleCSVDownload}
|
||||
onStartAddAnnotation={onStartAddAnnotation}
|
||||
onStartAddingAnnotation={onStartAddingAnnotation}
|
||||
/>
|
||||
</Authorized>
|
||||
<LayoutCellHeader cellName={cell.name} isEditable={isEditable} />
|
||||
|
@ -91,7 +91,7 @@ LayoutCell.propTypes = {
|
|||
isEditable: bool,
|
||||
onCancelEditCell: func,
|
||||
celldata: arrayOf(shape()),
|
||||
onStartAddAnnotation: func.isRequired,
|
||||
onStartAddingAnnotation: func.isRequired,
|
||||
}
|
||||
|
||||
export default LayoutCell
|
||||
|
|
|
@ -23,7 +23,7 @@ class LayoutCellMenu extends Component {
|
|||
isEditable,
|
||||
dataExists,
|
||||
onCSVDownload,
|
||||
onStartAddAnnotation,
|
||||
onStartAddingAnnotation,
|
||||
} = this.props
|
||||
|
||||
return (
|
||||
|
@ -45,7 +45,7 @@ class LayoutCellMenu extends Component {
|
|||
icon="pencil"
|
||||
menuOptions={[
|
||||
{text: 'Queries', action: onEdit(cell)},
|
||||
{text: 'Add Annotation', action: onStartAddAnnotation},
|
||||
{text: 'Add Annotation', action: onStartAddingAnnotation},
|
||||
]}
|
||||
informParent={this.handleToggleSubMenu}
|
||||
/>
|
||||
|
@ -79,7 +79,7 @@ LayoutCellMenu.propTypes = {
|
|||
dataExists: bool,
|
||||
onCSVDownload: func,
|
||||
queries: arrayOf(shape()),
|
||||
onStartAddAnnotation: func.isRequired,
|
||||
onStartAddingAnnotation: func.isRequired,
|
||||
}
|
||||
|
||||
export default LayoutCellMenu
|
||||
|
|
|
@ -26,14 +26,9 @@ class LayoutRenderer extends Component {
|
|||
this.state = {
|
||||
rowHeight: this.calculateRowHeight(),
|
||||
resizeCoords: null,
|
||||
annotationMode: null,
|
||||
}
|
||||
}
|
||||
|
||||
handleStartAddAnnotation = () => {
|
||||
this.setState({annotationMode: 'adding'})
|
||||
}
|
||||
|
||||
handleLayoutChange = layout => {
|
||||
if (!this.props.onPositionChange) {
|
||||
return
|
||||
|
@ -86,10 +81,11 @@ class LayoutRenderer extends Component {
|
|||
onDeleteCell,
|
||||
synchronizer,
|
||||
onCancelEditCell,
|
||||
onStartAddingAnnotation,
|
||||
onSummonOverlayTechnologies,
|
||||
} = this.props
|
||||
|
||||
const {rowHeight, resizeCoords, annotationMode} = this.state
|
||||
const {rowHeight, resizeCoords} = this.state
|
||||
const isDashboard = !!this.props.onPositionChange
|
||||
|
||||
return (
|
||||
|
@ -139,9 +135,9 @@ class LayoutRenderer extends Component {
|
|||
onDeleteCell={onDeleteCell}
|
||||
synchronizer={synchronizer}
|
||||
manualRefresh={manualRefresh}
|
||||
annotationMode={annotationMode}
|
||||
onCancelEditCell={onCancelEditCell}
|
||||
onStartAddAnnotation={this.handleStartAddAnnotation}
|
||||
onStopAddAnnotation={this.handleStopAddAnnotation}
|
||||
onStartAddingAnnotation={onStartAddingAnnotation}
|
||||
onSummonOverlayTechnologies={onSummonOverlayTechnologies}
|
||||
/>
|
||||
</Authorized>
|
||||
|
@ -199,6 +195,7 @@ LayoutRenderer.propTypes = {
|
|||
onCancelEditCell: func,
|
||||
onZoom: func,
|
||||
sources: arrayOf(shape({})),
|
||||
onStartAddingAnnotation: func.isRequired,
|
||||
}
|
||||
|
||||
export default LayoutRenderer
|
||||
|
|
|
@ -51,7 +51,6 @@ class LineGraph extends Component {
|
|||
isRefreshing,
|
||||
setResolution,
|
||||
isGraphFilled,
|
||||
annotationMode,
|
||||
showSingleStat,
|
||||
displayOptions,
|
||||
underlayCallback,
|
||||
|
@ -112,7 +111,6 @@ class LineGraph extends Component {
|
|||
setResolution={setResolution}
|
||||
overrideLineColors={lineColors}
|
||||
containerStyle={containerStyle}
|
||||
annotationMode={annotationMode}
|
||||
isGraphFilled={showSingleStat ? false : isGraphFilled}
|
||||
/>
|
||||
{showSingleStat
|
||||
|
@ -180,7 +178,6 @@ LineGraph.propTypes = {
|
|||
resizeCoords: shape(),
|
||||
queries: arrayOf(shape({}).isRequired).isRequired,
|
||||
data: arrayOf(shape({}).isRequired).isRequired,
|
||||
annotationMode: string,
|
||||
}
|
||||
|
||||
export default LineGraph
|
||||
|
|
|
@ -38,12 +38,13 @@ const prompterContainerStyle = isMouseHovering => {
|
|||
|
||||
const prompterStyle = isMouseHovering => {
|
||||
return {
|
||||
padding: '16px',
|
||||
padding: '16px 32px',
|
||||
textAlign: 'center',
|
||||
backgroundColor: 'rgba(255,0,0,0.2)',
|
||||
backgroundColor: 'rgba(255,0,0,0.7)',
|
||||
color: '#fff',
|
||||
borderRadius: '4px',
|
||||
fontSize: '16px',
|
||||
borderRadius: '5px',
|
||||
fontSize: '17px',
|
||||
lineHeight: '30px',
|
||||
fontWeight: '400',
|
||||
opacity: isMouseHovering ? '0' : '1',
|
||||
transition: 'opacity 0.25s ease',
|
||||
|
@ -53,7 +54,7 @@ const prompterStyle = isMouseHovering => {
|
|||
class NewAnnotation extends Component {
|
||||
state = {
|
||||
xPos: null,
|
||||
isMouseHovering: false,
|
||||
isMouseHovering: true,
|
||||
}
|
||||
|
||||
handleMouseEnter = () => {
|
||||
|
@ -67,38 +68,39 @@ class NewAnnotation extends Component {
|
|||
|
||||
const wrapperRect = this.wrapper.getBoundingClientRect()
|
||||
const trueGraphX = e.pageX - wrapperRect.left
|
||||
console.log('mouseMove')
|
||||
this.setState({xPos: trueGraphX})
|
||||
}
|
||||
|
||||
handleMouseLeave = () => {
|
||||
console.log('mouseLeave')
|
||||
this.setState({xPos: null, isMouseHovering: false})
|
||||
}
|
||||
|
||||
handleClick = () => {
|
||||
const {onAddAnnotation, dygraph} = this.props
|
||||
const {onAddAnnotation, onAddingAnnotationSuccess, dygraph} = this.props
|
||||
const {xPos} = this.state
|
||||
|
||||
const time = dygraph.toDataXCoord(xPos)
|
||||
const time = `${dygraph.toDataXCoord(xPos)}`
|
||||
|
||||
const annotation = {
|
||||
id: 'newannotationid',
|
||||
id: 'newannotationid', // TODO generate real ID
|
||||
group: '',
|
||||
name: 'New Annotation',
|
||||
time,
|
||||
duration: '',
|
||||
text: '',
|
||||
}
|
||||
console.log(annotation)
|
||||
onAddAnnotation(annotation)
|
||||
|
||||
this.setState({xPos: null, isMouseHovering: false})
|
||||
onAddingAnnotationSuccess()
|
||||
onAddAnnotation(annotation)
|
||||
}
|
||||
|
||||
render() {
|
||||
// const {dygraph} = this.props
|
||||
const {dygraph} = this.props
|
||||
const {xPos, isMouseHovering} = this.state
|
||||
|
||||
const timestamp = `${new Date(dygraph.toDataXCoord(xPos))}`
|
||||
|
||||
return (
|
||||
<div
|
||||
className="new-annotation"
|
||||
|
@ -114,13 +116,17 @@ class NewAnnotation extends Component {
|
|||
style={prompterContainerStyle(isMouseHovering)}
|
||||
>
|
||||
<div style={prompterStyle(isMouseHovering)}>
|
||||
<strong>Click</strong> to add Annotation
|
||||
<strong>Click</strong> to create Annotation
|
||||
<br />
|
||||
<strong>Drag</strong> to add Range
|
||||
<strong>Drag</strong> to create Range
|
||||
</div>
|
||||
</div>
|
||||
<div className="new-annotation--crosshair" style={newLineStyle(xPos)}>
|
||||
<div className="new-annotation--tooltip" />
|
||||
<div className="new-annotation--tooltip">
|
||||
Create Annotation at:
|
||||
<br />
|
||||
{timestamp}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
@ -132,7 +138,7 @@ const {func, shape} = PropTypes
|
|||
NewAnnotation.propTypes = {
|
||||
dygraph: shape({}).isRequired,
|
||||
onAddAnnotation: func.isRequired,
|
||||
onCancelAddAnnotation: func.isRequired,
|
||||
onAddingAnnotationSuccess: func.isRequired,
|
||||
}
|
||||
|
||||
export default NewAnnotation
|
||||
|
|
|
@ -22,7 +22,6 @@ const RefreshingGraph = ({
|
|||
cellHeight,
|
||||
autoRefresh,
|
||||
resizerTopHeight,
|
||||
annotationMode,
|
||||
manualRefresh, // when changed, re-mounts the component
|
||||
synchronizer,
|
||||
resizeCoords,
|
||||
|
@ -86,7 +85,6 @@ const RefreshingGraph = ({
|
|||
isBarGraph={type === 'bar'}
|
||||
synchronizer={synchronizer}
|
||||
resizeCoords={resizeCoords}
|
||||
annotationMode={annotationMode}
|
||||
displayOptions={displayOptions}
|
||||
editQueryStatus={editQueryStatus}
|
||||
grabDataForDownload={grabDataForDownload}
|
||||
|
@ -98,7 +96,6 @@ const RefreshingGraph = ({
|
|||
const {arrayOf, func, number, shape, string} = PropTypes
|
||||
|
||||
RefreshingGraph.propTypes = {
|
||||
annotationMode: string,
|
||||
timeRange: shape({
|
||||
lower: string.isRequired,
|
||||
}),
|
||||
|
|
|
@ -1,48 +1,76 @@
|
|||
import {DEFAULT_ANNOTATION_ID} from 'src/shared/constants/annotations'
|
||||
import {ADDING, TEMP_ANNOTATION} from 'src/shared/annotations/helpers'
|
||||
|
||||
const initialState = [
|
||||
{
|
||||
id: '0',
|
||||
group: '',
|
||||
name: 'anno1',
|
||||
time: '1515716169000',
|
||||
duration: '33600000', // 1 hour
|
||||
text: 'you have no swoggels',
|
||||
},
|
||||
{
|
||||
id: '1',
|
||||
group: '',
|
||||
name: 'anno2',
|
||||
time: '1515772377000',
|
||||
duration: '',
|
||||
text: 'another annotation',
|
||||
},
|
||||
]
|
||||
const initialState = {
|
||||
mode: null,
|
||||
annotations: [
|
||||
{
|
||||
id: '0',
|
||||
group: '',
|
||||
name: 'anno1',
|
||||
time: '1515716169000',
|
||||
duration: '33600000', // 1 hour
|
||||
text: 'you have no swoggels',
|
||||
},
|
||||
{
|
||||
id: '1',
|
||||
group: '',
|
||||
name: 'anno2',
|
||||
time: '1515772377000',
|
||||
duration: '',
|
||||
text: 'another annotation',
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
const annotationsReducer = (state = initialState, action) => {
|
||||
switch (action.type) {
|
||||
case 'ADDING_ANNOTATION': {
|
||||
return {
|
||||
...state,
|
||||
mode: ADDING,
|
||||
annotations: [...state.annotations, TEMP_ANNOTATION],
|
||||
}
|
||||
}
|
||||
|
||||
case 'ADDING_ANNOTATION_SUCCESS': {
|
||||
const annotations = state.annotations.filter(
|
||||
a => a.id !== TEMP_ANNOTATION.id
|
||||
)
|
||||
|
||||
return {...state, mode: null, annotations}
|
||||
}
|
||||
|
||||
case 'LOAD_ANNOTATIONS': {
|
||||
return action.payload.annotations
|
||||
const {annotations} = action.payload
|
||||
|
||||
return {...state, annotations}
|
||||
}
|
||||
|
||||
case 'UPDATE_ANNOTATION': {
|
||||
const {annotation} = action.payload
|
||||
const newState = state.map(a => (a.id === annotation.id ? annotation : a))
|
||||
const annotations = state.annotations.map(
|
||||
a => (a.id === annotation.id ? annotation : a)
|
||||
)
|
||||
|
||||
return newState
|
||||
return {...state, annotations}
|
||||
}
|
||||
|
||||
case 'DELETE_ANNOTATION': {
|
||||
const {annotation} = action.payload
|
||||
const newState = state.filter(a => a.id !== annotation.id)
|
||||
const annotations = state.annotations.filter(a => a.id !== annotation.id)
|
||||
|
||||
return newState
|
||||
return {...state, annotations}
|
||||
}
|
||||
|
||||
case 'ADD_ANNOTATION': {
|
||||
const {annotation} = action.payload
|
||||
const annotations = [
|
||||
...state.annotations,
|
||||
{...annotation, id: DEFAULT_ANNOTATION_ID},
|
||||
]
|
||||
|
||||
return [...state, {...annotation, id: DEFAULT_ANNOTATION_ID}]
|
||||
return {...state, annotations}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue