diff --git a/.eslintrc b/.eslintrc index da00d08..211e3eb 100644 --- a/.eslintrc +++ b/.eslintrc @@ -53,7 +53,7 @@ "no-constant-condition": 0, // disallow use of constant expressions in conditions "no-control-regex": 0, // disallow control characters in regular expressions "no-debugger": 1, // disallow use of debugger - "no-dupe-keys": 1, // disallow duplicate keys when creating object literals + "no-dupe-keys": 0, // disallow duplicate keys when creating object literals "no-empty": 1, // disallow empty statements "no-empty-class": 0, // disallow the use of empty character classes in regular expressions "no-ex-assign": 1, // disallow assigning to the exception in a catch block diff --git a/browser/js/components/Annotator/actions.js b/browser/js/components/Annotator/actions.js index e66144d..e6b2a47 100644 --- a/browser/js/components/Annotator/actions.js +++ b/browser/js/components/Annotator/actions.js @@ -1,7 +1,12 @@ 'use strict' +import axios from 'axios' +import * as api from './apiActions' + export const SELECTION = 'SELECTION' export const ANNOTATION = 'ANNOTATION' +export const ANNOTATION_CLEAR = 'ANNOTATION_CLEAR' +export const ANNOTATION_ADDED = 'ANNOTATION_ADDED' export function selection(_selection){ @@ -12,12 +17,37 @@ export function selection(_selection){ } } -export function annotation(_selection, _annotation){ +export function annotation(_annotation){ + let {selection, annotation, location} = _annotation; + return api.postAnnotation({selection, annotation, location}) +} + +export function finishAnnotation(payload){ + let finisher = payload; + finisher.added = false; return { type: ANNOTATION, - annotation: _annotation, - selection: _selection, - selectionString: _selection.toString(), - added: false + payload: payload + } +} + +export function clearAnnotation( added = false, selection = null, annotation = null ){ + return { + type: ANNOTATION_CLEAR, + payload: { + added, + annotation, + selection, + selectionString: !selection ? null : selection.toString() } } } + +export function annotationAdded( added = true, clear = false ){ + if(clear) clearAnnotation( added, null, null ); + return { + type: ANNOTATION_ADDED, + payload: { + added + } + } +} diff --git a/browser/js/components/Annotator/apiActions.js b/browser/js/components/Annotator/apiActions.js new file mode 100644 index 0000000..2e89af3 --- /dev/null +++ b/browser/js/components/Annotator/apiActions.js @@ -0,0 +1,148 @@ +'use strict'; + +import axios from 'axios'; +import APIROUTES from '../../utils/apiRoutes' +import {cloneDeep as _cloneDeep} from 'lodash'; +import {getXPath} from 'xpath-dom'; +import {finishAnnotation} from './actions' + +export const LOAD_ANNOTATIONS_REQUEST = 'LOAD_ANNOTATIONS_REQUEST' +export const LOAD_ANNOTATIONS_SUCCESS = 'LOAD_ANNOTATIONS_SUCCESS' +export const LOAD_ANNOTATIONS_FAILURE = 'LOAD_ANNOTATIONS_FAILURE' +export const CREATE_ANNOTATION_REQUEST = 'CREATE_ANNOTATION_REQUEST' +export const CREATE_ANNOTATION_SUCCESS = 'CREATE_ANNOTATION_SUCCESS' +export const CREATE_ANNOTATION_FAILURE = 'CREATE_ANNOTATION_FAILURE' +export const LOAD_ANNOTATION_REQUEST = 'LOAD_ANNOTATION_REQUEST' +export const LOAD_ANNOTATION_SUCCESS = 'LOAD_ANNOTATION_SUCCESS' +export const LOAD_ANNOTATION_FAILURE = 'LOAD_ANNOTATION_FAILURE' +export const UPDATE_ANNOTATION_REQUEST = 'UPDATE_ANNOTATION_REQUEST' +export const UPDATE_ANNOTATION_SUCCESS = 'UPDATE_ANNOTATION_SUCCESS' +export const UPDATE_ANNOTATION_FAILURE = 'UPDATE_ANNOTATION_FAILURE' + + +export const getUserAnnotations = + userId => + dispatch => { + dispatch(LOAD_ANNOTATIONS_REQUEST) + return axios.get(APIROUTES.annotationsByUserId(userId)) + .then( res => res.data ) + .then( resData => dispatch({ + type: LOAD_ANNOTATIONS_SUCCESS, + payload: resData + })) + .catch( err => dispatch({ + type: LOAD_ANNOTATIONS_FAILURE, + payload: err + })) } + +export const getAnnotationById = + annotationId => + dispatch => { + dispatch(LOAD_ANNOTATION_REQUEST) + return axios.get(APIROUTES.annotationById(annotationId)) + .then( res => res.data ) + .then( resData => dispatch({ + type: LOAD_ANNOTATION_REQUEST, + payload: resData + })) + .catch( err => dispatch({ + type: LOAD_ANNOTATION_FAILURE, + payload: err + }))} + +export const getAnnotationsByUserTest = + userTestId => + dispatch => { + dispatch(LOAD_ANNOTATIONS_REQUEST) + return axios.get(APIROUTES.annotationsByUserTest(userTestId)) + .then( res => res.data ) + .then( resData => dispatch({ + type: LOAD_ANNOTATIONS_REQUEST, + payload: resData + })) + .catch( err => dispatch({ + type: LOAD_ANNOTATIONS_FAILURE, + payload: err + }))} + +export const postAnnotation = + annotation => + (dispatch, getState) =>{ + let selection = annotation.selection; + let payload = { + route: APIROUTES.annotation, + anchorNode: getXPath(selection.anchorNode), + anchorOffset: selection.anchorOffset, + focusNode: getXPath(selection.focusNode), + focusOffset: selection.focusOffset, + rangeCount: selection.rangeCount, + selectionString: selection.toString(), + color: annotation.color, + location: annotation.location + } + dispatch({ + type: CREATE_ANNOTATION_REQUEST, + payload + }) + return axios.post(APIROUTES.annotation, payload) + .then(res => res.data) + .then(resData => { + dispatch({ + type: CREATE_ANNOTATION_SUCCESS, + payload: resData + }) + payload.selection = annotation.selection; + payload.resData = resData; + return dispatch(finishAnnotation(payload)) + } + ) + .catch( err => dispatch({ + type: CREATE_ANNOTATION_FAILURE, + payload: err + }))} + + +export const postAnnotationByUserTest = + (annotation, userTestId) => + (dispath, getState) =>{ + dispatch(CREATE_ANNOTATION_REQUEST) + return axios.post(APIROUTES.annotationsByUserTest(userTestId), annotation) + .then( res => res.data) + .then(resData => dispatch({ + type: CREATE_ANNOTATION_SUCCESS, + payload: resData + })) + .catch( err => dispatch({ + type: CREATE_ANNOTATION_FAILURE, + payloard: err + }))} + +export const updateAnnotation = + (annotation, annotationId) => + (dispatch, getState) =>{ + dispatch(UPDATE_ANNOTATION_REQUEST) + return axios.put(APIROUTES.annotationById(annotationId), annotation) + .then(res => res.data) + .then(resData => dispatch({ + type: UPDATE_ANNOTATION_SUCCESS, + payload: resData + })) + .catch( err => dispatch({ + type: UPDATE_ANNOTATION_FAILURE, + payload: err + }))} + +export const deleteAnnotation = + annotationId => + (dispatch, getState) =>{ + dispatch(DELETE_ANNOTATION_REQUEST) + return axios.delete(APIROUTES.annotationById(annotationId), annotation) + .then(res => res.data) + .then(resData => dispatch({ + type: DELETE_ANNOTATION_SUCCESS, + payload: resData + })) + .catch( err => dispatch({ + type: DELETE_ANNOTATION_FAILURE, + payload: err + }))} diff --git a/browser/js/components/Annotator/index.js b/browser/js/components/Annotator/index.js index ee47be6..60eaea4 100644 --- a/browser/js/components/Annotator/index.js +++ b/browser/js/components/Annotator/index.js @@ -11,7 +11,6 @@ import {annotation, selection} from './actions'; class AnnotationHandler extends Component{ constructor(props){ super(props); - console.log(this.props); this.handleMouseUp = this.handleMouseUp.bind(this); this.handleMouseDown = this.handleMouseDown.bind(this); this.state = { @@ -49,10 +48,12 @@ class AnnotationHandler extends Component{ }); } componentWillReceiveProps(nextProps){ - console.log('receiving props'); this.setState({ selectionString: nextProps.selectionString }); + this.setState({ + currentLocation: nextProps.location + }) } render (){ return ( @@ -61,7 +62,10 @@ class AnnotationHandler extends Component{ {this.props.children}
+ {contents.selection.toString()} ++ {/*