Convert Annotation action and reducer to TS
parent
392ee489e3
commit
e90ab6433e
|
@ -1,7 +1,19 @@
|
|||
import * as api from 'src/shared/apis/annotation'
|
||||
|
||||
import {AnnotationInterface} from 'src/types'
|
||||
|
||||
export type Action =
|
||||
| EditingAnnotationAction
|
||||
| DismissEditingAnnotationAction
|
||||
| AddingAnnotationAction
|
||||
| AddingAnnotationSuccessAction
|
||||
| DismissAddingAnnotationAction
|
||||
| MouseEnterTempAnnotationAction
|
||||
| MouseLeaveTempAnnotationAction
|
||||
| LoadAnnotationsAction
|
||||
| UpdateAnnotationAction
|
||||
| DeleteAnnotationAction
|
||||
| AddAnnotationAction
|
||||
|
||||
export interface EditingAnnotationAction {
|
||||
type: 'EDITING_ANNOTATION'
|
||||
}
|
||||
|
@ -122,8 +134,8 @@ export const addAnnotationAsync = (
|
|||
}
|
||||
|
||||
export interface AnnotationRange {
|
||||
since: string
|
||||
until: string
|
||||
since: number
|
||||
until: number
|
||||
}
|
||||
|
||||
export const getAnnotationsAsync = (
|
||||
|
|
|
@ -11,6 +11,7 @@ export const TEMP_ANNOTATION: AnnotationInterface = {
|
|||
type: '',
|
||||
startTime: null,
|
||||
endTime: null,
|
||||
links: {self: ''},
|
||||
}
|
||||
|
||||
export const visibleAnnotations = (
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
import AJAX from 'src/utils/ajax'
|
||||
|
||||
const msToRFC = ms => ms && new Date(parseInt(ms, 10)).toISOString()
|
||||
const rfcToMS = rfc3339 => rfc3339 && JSON.stringify(Date.parse(rfc3339))
|
||||
const annoToMillisecond = anno => ({
|
||||
...anno,
|
||||
startTime: rfcToMS(anno.startTime),
|
||||
endTime: rfcToMS(anno.endTime),
|
||||
})
|
||||
const annoToRFC = anno => ({
|
||||
...anno,
|
||||
startTime: msToRFC(anno.startTime),
|
||||
endTime: msToRFC(anno.endTime),
|
||||
})
|
||||
|
||||
export const createAnnotation = async (url, annotation) => {
|
||||
const data = annoToRFC(annotation)
|
||||
const response = await AJAX({method: 'POST', url, data})
|
||||
return annoToMillisecond(response.data)
|
||||
}
|
||||
|
||||
export const getAnnotations = async (url, since, until) => {
|
||||
const {data} = await AJAX({
|
||||
method: 'GET',
|
||||
url,
|
||||
params: {since: msToRFC(since), until: msToRFC(until)},
|
||||
})
|
||||
return data.annotations.map(annoToMillisecond)
|
||||
}
|
||||
|
||||
export const deleteAnnotation = async annotation => {
|
||||
const url = annotation.links.self
|
||||
await AJAX({method: 'DELETE', url})
|
||||
}
|
||||
|
||||
export const updateAnnotation = async annotation => {
|
||||
const url = annotation.links.self
|
||||
const data = annoToRFC(annotation)
|
||||
await AJAX({method: 'PATCH', url, data})
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
import AJAX from 'src/utils/ajax'
|
||||
import {AnnotationInterface} from 'src/types'
|
||||
|
||||
const msToRFCString = (ms: number) =>
|
||||
ms && new Date(Math.round(ms)).toISOString()
|
||||
|
||||
const rfcStringToMS = (rfc3339: string) => rfc3339 && Date.parse(rfc3339)
|
||||
|
||||
interface ServerAnnotation {
|
||||
id: string
|
||||
startTime: string
|
||||
endTime: string
|
||||
text: string
|
||||
type: string
|
||||
links: {self: string}
|
||||
}
|
||||
|
||||
const annoToMillisecond = (
|
||||
annotation: ServerAnnotation
|
||||
): AnnotationInterface => ({
|
||||
...annotation,
|
||||
startTime: rfcStringToMS(annotation.startTime),
|
||||
endTime: rfcStringToMS(annotation.endTime),
|
||||
})
|
||||
|
||||
const annoToRFC = (annotation: AnnotationInterface): ServerAnnotation => ({
|
||||
...annotation,
|
||||
startTime: msToRFCString(annotation.startTime),
|
||||
endTime: msToRFCString(annotation.endTime),
|
||||
})
|
||||
|
||||
export const createAnnotation = async (
|
||||
url: string,
|
||||
annotation: AnnotationInterface
|
||||
) => {
|
||||
const data = annoToRFC(annotation)
|
||||
const response = await AJAX({method: 'POST', url, data})
|
||||
return annoToMillisecond(response.data)
|
||||
}
|
||||
|
||||
export const getAnnotations = async (
|
||||
url: string,
|
||||
since: number,
|
||||
until: number
|
||||
) => {
|
||||
const {data} = await AJAX({
|
||||
method: 'GET',
|
||||
url,
|
||||
params: {since: msToRFCString(since), until: msToRFCString(until)},
|
||||
})
|
||||
return data.annotations.map(annoToMillisecond)
|
||||
}
|
||||
|
||||
export const deleteAnnotation = async (annotation: AnnotationInterface) => {
|
||||
const url = annotation.links.self
|
||||
await AJAX({method: 'DELETE', url})
|
||||
}
|
||||
|
||||
export const updateAnnotation = async (annotation: AnnotationInterface) => {
|
||||
const url = annotation.links.self
|
||||
const data = annoToRFC(annotation)
|
||||
await AJAX({method: 'PATCH', url, data})
|
||||
}
|
|
@ -1,12 +1,24 @@
|
|||
import {ADDING, EDITING, TEMP_ANNOTATION} from 'src/shared/annotations/helpers'
|
||||
|
||||
import {Action} from 'src/shared/actions/annotations'
|
||||
import {AnnotationInterface} from 'src/types'
|
||||
|
||||
export interface AnnotationState {
|
||||
mode: string
|
||||
isTempHovering: boolean
|
||||
annotations: AnnotationInterface[]
|
||||
}
|
||||
|
||||
const initialState = {
|
||||
mode: null,
|
||||
isTempHovering: false,
|
||||
annotations: [],
|
||||
}
|
||||
|
||||
const annotationsReducer = (state = initialState, action) => {
|
||||
const annotationsReducer = (
|
||||
state: AnnotationState = initialState,
|
||||
action: Action
|
||||
) => {
|
||||
switch (action.type) {
|
||||
case 'EDITING_ANNOTATION': {
|
||||
return {
|
|
@ -4,4 +4,5 @@ export interface AnnotationInterface {
|
|||
endTime: number
|
||||
text: string
|
||||
type: string
|
||||
links: {self: string}
|
||||
}
|
||||
|
|
|
@ -1,45 +1,47 @@
|
|||
import reducer from 'shared/reducers/annotations'
|
||||
import reducer from 'src/shared/reducers/annotations'
|
||||
import {AnnotationInterface} from 'src/types'
|
||||
import {AnnotationState} from 'src/shared/reducers/annotations'
|
||||
|
||||
import {
|
||||
addAnnotation,
|
||||
deleteAnnotation,
|
||||
loadAnnotations,
|
||||
updateAnnotation,
|
||||
} from 'shared/actions/annotations'
|
||||
} from 'src/shared/actions/annotations'
|
||||
|
||||
const a1 = {
|
||||
const a1: AnnotationInterface = {
|
||||
id: '1',
|
||||
group: '',
|
||||
name: 'anno1',
|
||||
time: '1515716169000',
|
||||
duration: '',
|
||||
startTime: 1515716169000,
|
||||
endTime: 1515716169000,
|
||||
type: '',
|
||||
text: 'you have no swoggels',
|
||||
links: {self: 'to/thine/own/self/be/true'},
|
||||
}
|
||||
|
||||
const a2 = {
|
||||
const a2: AnnotationInterface = {
|
||||
id: '2',
|
||||
group: '',
|
||||
name: 'anno1',
|
||||
time: '1515716169000',
|
||||
duration: '',
|
||||
text: 'you have no swoggels',
|
||||
startTime: 1515716169000,
|
||||
endTime: 1515716169002,
|
||||
type: '',
|
||||
text: 'you have so many swoggels',
|
||||
links: {self: 'self/in/eye/of/beholder'},
|
||||
}
|
||||
|
||||
const state = {
|
||||
const state: AnnotationState = {
|
||||
isTempHovering: false,
|
||||
mode: null,
|
||||
annotations: [],
|
||||
}
|
||||
|
||||
describe('Shared.Reducers.annotations', () => {
|
||||
it('can load the annotations', () => {
|
||||
const expected = [{time: '0', duration: ''}]
|
||||
const expected = [a1]
|
||||
const actual = reducer(state, loadAnnotations(expected))
|
||||
|
||||
expect(actual.annotations).toEqual(expected)
|
||||
})
|
||||
|
||||
it('can update an annotation', () => {
|
||||
const expected = [{...a1, time: ''}]
|
||||
const expected = [{...a1, startTime: 6666666666666}]
|
||||
const actual = reducer(
|
||||
{...state, annotations: [a1]},
|
||||
updateAnnotation(expected[0])
|
Loading…
Reference in New Issue