Routing mostly working as expected now, except for switching docTypes on the edit page
This commit is contained in:
parent
fde36c08d1
commit
e1b4797c52
7
TODO.txt
7
TODO.txt
|
@ -32,11 +32,16 @@ REFACTORING CHECKLIST:
|
||||||
- Switch to Webpack Dev Server and Remove Webpack/Flask Dependencies
|
- Switch to Webpack Dev Server and Remove Webpack/Flask Dependencies
|
||||||
- Write ReadMe
|
- Write ReadMe
|
||||||
- One Pass Through Every Module's Imports
|
- One Pass Through Every Module's Imports
|
||||||
|
- Rename Components
|
||||||
|
|
||||||
NEED:
|
NEED:
|
||||||
- Deploy Process
|
- Deploy Process
|
||||||
- Testing
|
- Testing
|
||||||
|
|
||||||
|
UX NEEDS:
|
||||||
|
- Disable Title Submit Button Without Title
|
||||||
|
- Disable Modal Submit Button with input
|
||||||
|
|
||||||
SHORT LIST:
|
SHORT LIST:
|
||||||
- Make Annotate Mode Ignore Keyboard Input
|
- Make Annotate Mode Ignore Keyboard Input
|
||||||
- More Responsive CSS
|
- More Responsive CSS
|
||||||
|
@ -65,6 +70,7 @@ SHORT LIST:
|
||||||
- Advanced search page
|
- Advanced search page
|
||||||
- Filter by DocType, Chapter
|
- Filter by DocType, Chapter
|
||||||
- Drop Down window
|
- Drop Down window
|
||||||
|
- Handle no search results
|
||||||
|
|
||||||
- v0.5 Pagination
|
- v0.5 Pagination
|
||||||
|
|
||||||
|
@ -80,7 +86,6 @@ SHORT LIST:
|
||||||
- Stats Logging
|
- Stats Logging
|
||||||
|
|
||||||
BUGS:
|
BUGS:
|
||||||
- DraftJS crashes if you backspace on an empty Editor
|
|
||||||
|
|
||||||
Short List:
|
Short List:
|
||||||
- PropTypes
|
- PropTypes
|
||||||
|
|
|
@ -34,6 +34,11 @@
|
||||||
type: 'CANCEL_EDIT'
|
type: 'CANCEL_EDIT'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export const clearCurrentDocument = () =>
|
||||||
|
({
|
||||||
|
type: 'CLEAR_CURRENT_DOCUMENT'
|
||||||
|
})
|
||||||
|
|
||||||
// Click 'Delete' and confirm to delete a document
|
// Click 'Delete' and confirm to delete a document
|
||||||
export const deleteCurrentDocument = (id, docType) =>
|
export const deleteCurrentDocument = (id, docType) =>
|
||||||
({
|
({
|
||||||
|
|
|
@ -2,7 +2,6 @@ import React from 'react'
|
||||||
|
|
||||||
const SearchResultSnippet = ({snippet}) =>
|
const SearchResultSnippet = ({snippet}) =>
|
||||||
<div>
|
<div>
|
||||||
{console.log(snippet)}
|
|
||||||
{snippet}...
|
{snippet}...
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { DocumentList } from '../components/list'
|
||||||
import { NewDocumentButton } from '../components/button'
|
import { NewDocumentButton } from '../components/button'
|
||||||
import { DocTypeDropdown } from '../components/dropdown'
|
import { DocTypeDropdown } from '../components/dropdown'
|
||||||
import SidebarSpacer from '../components/sidebarSpacer'
|
import SidebarSpacer from '../components/sidebarSpacer'
|
||||||
|
import { push } from 'react-router-redux'
|
||||||
|
|
||||||
const JoyceEditorSidebar = ({notes, chapters, docType, currentDocument, onDocumentClick, onNewDocumentClick, setDocType}) =>
|
const JoyceEditorSidebar = ({notes, chapters, docType, currentDocument, onDocumentClick, onNewDocumentClick, setDocType}) =>
|
||||||
<div className="col-md-3 d-none d-md-block" id="sidebar">
|
<div className="col-md-3 d-none d-md-block" id="sidebar">
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { setCurrentDocument, toggleHighlight } from '../actions/userActions'
|
||||||
import { DocumentList } from '../components/list'
|
import { DocumentList } from '../components/list'
|
||||||
import { HighlightButton } from '../components/button'
|
import { HighlightButton } from '../components/button'
|
||||||
import SidebarSpacer from '../components/sidebarSpacer'
|
import SidebarSpacer from '../components/sidebarSpacer'
|
||||||
|
import { push } from 'react-router-redux'
|
||||||
|
|
||||||
const JoyceReaderSidebar = ({chapters, notes, currentDocument, onDocumentClick, highlightToggle, onHighlightClick, docType}) =>
|
const JoyceReaderSidebar = ({chapters, notes, currentDocument, onDocumentClick, highlightToggle, onHighlightClick, docType}) =>
|
||||||
<div className='col-md-3 d-none d-md-block' id='sidebar'>
|
<div className='col-md-3 d-none d-md-block' id='sidebar'>
|
||||||
|
|
14
src/joyce.js
14
src/joyce.js
|
@ -16,8 +16,8 @@ import { getDocumentList } from './actions/apiActions'
|
||||||
import DeleteConfirmModal from './components/deleteConfirmModal'
|
import DeleteConfirmModal from './components/deleteConfirmModal'
|
||||||
import AnnotateModal from './components/annotateModal'
|
import AnnotateModal from './components/annotateModal'
|
||||||
import AnnotationModal from './components/annotationModal'
|
import AnnotationModal from './components/annotationModal'
|
||||||
import { setCurrentDocument, setDocType } from './actions/userActions'
|
import { setDocType } from './actions/userActions'
|
||||||
import { logger, joyceAPI } from './middleware/'
|
import { logger, joyceAPI, joyceInterface, joyceRouter } from './middleware/'
|
||||||
import JoyceReaderPageContainer from './containers/joyceReaderPageContainer'
|
import JoyceReaderPageContainer from './containers/joyceReaderPageContainer'
|
||||||
import JoyceEditorPageContainer from './containers/joyceEditorPageContainer'
|
import JoyceEditorPageContainer from './containers/joyceEditorPageContainer'
|
||||||
import JoyceSearchPageContainer from './containers/joyceSearchPageContainer'
|
import JoyceSearchPageContainer from './containers/joyceSearchPageContainer'
|
||||||
|
@ -26,9 +26,8 @@ import JoyceSearchPageContainer from './containers/joyceSearchPageContainer'
|
||||||
|
|
||||||
const history = createHistory()
|
const history = createHistory()
|
||||||
const router = routerMiddleware(history)
|
const router = routerMiddleware(history)
|
||||||
const store = createStore(reduceReader, applyMiddleware(logger, joyceAPI, router))
|
const store = createStore(reduceReader, applyMiddleware(logger, router, joyceAPI, joyceInterface, joyceRouter))
|
||||||
|
|
||||||
store.dispatch(setDocType('chapters'))
|
|
||||||
store.dispatch(getDocumentList({docType: 'chapters'}))
|
store.dispatch(getDocumentList({docType: 'chapters'}))
|
||||||
store.dispatch(getDocumentList({docType: 'notes'}))
|
store.dispatch(getDocumentList({docType: 'notes'}))
|
||||||
|
|
||||||
|
@ -44,14 +43,15 @@ ReactDOM.render(
|
||||||
<Route exact path='/edit' render={() =>
|
<Route exact path='/edit' render={() =>
|
||||||
<Redirect to={'/edit/:id'}/>
|
<Redirect to={'/edit/:id'}/>
|
||||||
}/>
|
}/>
|
||||||
|
<Route exact path='/edit/notes' render={() =>
|
||||||
|
<Redirect to={'/edit/notes/:id'}/>
|
||||||
|
}/>
|
||||||
<Route exact path='/notes' render={() =>
|
<Route exact path='/notes' render={() =>
|
||||||
<Redirect to={'/notes/:id'}/>
|
<Redirect to={'/notes/:id'}/>
|
||||||
}/>
|
}/>
|
||||||
<Route exact path='/' render={() =>
|
|
||||||
<Redirect to={'/:id'}/>
|
|
||||||
}/>
|
|
||||||
<Route exact path='/notes/:id' component={JoyceReaderPageContainer} />
|
<Route exact path='/notes/:id' component={JoyceReaderPageContainer} />
|
||||||
<Route exact path='/edit/:id' component={JoyceEditorPageContainer} />
|
<Route exact path='/edit/:id' component={JoyceEditorPageContainer} />
|
||||||
|
<Route exact path='/edit/notes/:id' component={JoyceEditorPageContainer} />
|
||||||
<Route exact path='/search/' component={JoyceSearchPageContainer} />
|
<Route exact path='/search/' component={JoyceSearchPageContainer} />
|
||||||
<Route exact path='/:id' component={JoyceReaderPageContainer} />
|
<Route exact path='/:id' component={JoyceReaderPageContainer} />
|
||||||
</Switch>
|
</Switch>
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
import axios from 'axios'
|
|
||||||
|
|
||||||
const apiRoute = '/api/'
|
|
||||||
|
|
||||||
// Axios HTTP Functions
|
|
||||||
export const HTTPGetDocumentList = (docType, state) =>
|
|
||||||
axios.get(apiRoute + docType).then(res => {
|
|
||||||
return {status: 'success', docType: docType, state: state, data: res.data}
|
|
||||||
}).catch(error => {
|
|
||||||
return {status: 'error', docType: docType, state: state, data: error}
|
|
||||||
})
|
|
||||||
|
|
||||||
export const HTTPGetDocumentText = (id, docType, state) =>
|
|
||||||
axios.get(apiRoute + docType + '/' + id).then(res => {
|
|
||||||
return {id: id, status: 'success', docType: docType, state: state, data: res.data}
|
|
||||||
}).catch(error => {
|
|
||||||
return {id: id, status: 'error', docType: docType, state: state, data: error}
|
|
||||||
})
|
|
||||||
|
|
||||||
export const HTTPDeleteDocument = (id, docType) =>
|
|
||||||
axios.delete(apiRoute + docType + '/' + id).then(res => {
|
|
||||||
return {id: id, status: 'success', docType: docType, data: res.data}
|
|
||||||
}).catch(error => {
|
|
||||||
return {id: id, status: 'error', docType: docType, data: error}
|
|
||||||
})
|
|
||||||
|
|
||||||
export const HTTPPutCreateDocument = (docType, data) =>
|
|
||||||
axios.put(apiRoute + docType + '/', data).then(res => {
|
|
||||||
return {status: 'success', docType: docType, data: res.data}
|
|
||||||
}).catch(error => {
|
|
||||||
return {status: 'error', docType: docType, data: error}
|
|
||||||
})
|
|
||||||
|
|
||||||
export const HTTPPostWriteDocument = (id, docType, data) =>
|
|
||||||
axios.post(apiRoute + docType + '/' + id, data).then(res => {
|
|
||||||
return {id: data.id, status: 'success', docType: docType, data: res.data}
|
|
||||||
}).catch(error => {
|
|
||||||
return {id: id, status: 'error', docType: docType, data: error}
|
|
||||||
})
|
|
||||||
|
|
||||||
export const HTTPPostSearchResults = (data) =>
|
|
||||||
axios.post(apiRoute + 'search/', { data }).then(res => {
|
|
||||||
console.log('data is ', data)
|
|
||||||
return {status: 'success', data: res.data}
|
|
||||||
}).catch(error => {
|
|
||||||
return {status: 'error', data: res.data}
|
|
||||||
})
|
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
import { joyceAPI } from './joyceAPI'
|
import joyceAPI from './joyceAPI'
|
||||||
import { logger } from './logger'
|
import joyceInterface from './joyceInterface'
|
||||||
|
import joyceRouter from './joyceRouter'
|
||||||
|
import logger from './logger'
|
||||||
|
|
||||||
export {
|
export {
|
||||||
joyceAPI,
|
joyceAPI,
|
||||||
|
joyceInterface,
|
||||||
|
joyceRouter,
|
||||||
logger
|
logger
|
||||||
}
|
}
|
|
@ -1,4 +1,3 @@
|
||||||
import axios from 'axios'
|
|
||||||
import { push } from 'react-router-redux'
|
import { push } from 'react-router-redux'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -10,42 +9,23 @@ import {
|
||||||
getSearchResults
|
getSearchResults
|
||||||
} from '../actions/apiActions'
|
} from '../actions/apiActions'
|
||||||
|
|
||||||
import { setCurrentDocument } from '../actions/userActions'
|
import api from '../modules/api'
|
||||||
|
import regex from '../modules/regex'
|
||||||
import {
|
|
||||||
HTTPGetDocumentList,
|
|
||||||
HTTPGetDocumentText,
|
|
||||||
HTTPDeleteDocument,
|
|
||||||
HTTPPutCreateDocument,
|
|
||||||
HTTPPostWriteDocument,
|
|
||||||
HTTPPostSearchResults } from './http'
|
|
||||||
|
|
||||||
import helpers from '../modules/helpers'
|
|
||||||
|
|
||||||
// API Middleware
|
// API Middleware
|
||||||
export const joyceAPI = store => next => action => {
|
const joyceAPI = store => next => action => {
|
||||||
next(action)
|
next(action)
|
||||||
switch(action.type) {
|
switch(action.type) {
|
||||||
// API Calls
|
|
||||||
case 'GET_DOCUMENT_LIST':
|
case 'GET_DOCUMENT_LIST':
|
||||||
if (action.status === 'request') {
|
if (action.status === 'request') {
|
||||||
HTTPGetDocumentList(action.docType, action.state).then(response =>
|
api.HTTPGetDocumentList(action.docType, action.state).then(response =>
|
||||||
store.dispatch(getDocumentList(response))
|
store.dispatch(getDocumentList(response))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (action.status === 'success' && action.docType === store.getState().docType && !store.getState().currentDocument.id) {
|
|
||||||
if (helpers.checkIfRedirectPath(store.getState().routerReducer.location.pathname)) {
|
|
||||||
if (action.docType === 'chapters') {
|
|
||||||
store.dispatch(push(action.data[0].number))
|
|
||||||
} else {
|
|
||||||
store.dispatch(push(action.data[0].id))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break
|
break
|
||||||
case 'GET_DOCUMENT_TEXT':
|
case 'GET_DOCUMENT_TEXT':
|
||||||
if (action.status === 'request') {
|
if (action.status === 'request') {
|
||||||
HTTPGetDocumentText(action.id, action.docType, action.state).then(response =>
|
api.HTTPGetDocumentText(action.id, action.docType, action.state).then(response =>
|
||||||
store.dispatch(getDocumentText(response))
|
store.dispatch(getDocumentText(response))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -53,28 +33,33 @@ export const joyceAPI = store => next => action => {
|
||||||
case 'SAVE_DOCUMENT':
|
case 'SAVE_DOCUMENT':
|
||||||
if (action.status === 'request') {
|
if (action.status === 'request') {
|
||||||
if (action.id) {
|
if (action.id) {
|
||||||
HTTPPostWriteDocument(action.id, action.docType, action.data).then(response =>
|
api.HTTPPostWriteDocument(action.id, action.docType, action.data).then(response =>
|
||||||
store.dispatch(saveDocument(response))
|
store.dispatch(saveDocument(response)
|
||||||
|
)
|
||||||
)} else {
|
)} else {
|
||||||
HTTPPutCreateDocument(action.docType, action.data).then(response =>
|
api.HTTPPutCreateDocument(action.docType, action.data).then(response =>
|
||||||
store.dispatch(saveDocument(response)))
|
store.dispatch(saveDocument(response))
|
||||||
|
)
|
||||||
}
|
}
|
||||||
} else if (action.status === 'success' && !action.id) {
|
|
||||||
store.dispatch(setCurrentDocument(action.data.slice(-1)[0].id, action.docType))
|
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case 'DELETE_DOCUMENT':
|
case 'DELETE_DOCUMENT':
|
||||||
if (action.status === 'request') {
|
if (action.status === 'request') {
|
||||||
HTTPDeleteDocument(action.id, action.docType).then(response =>
|
api.HTTPDeleteDocument(action.id, action.docType).then(response =>
|
||||||
store.dispatch(deleteDocument(response))
|
store.dispatch(deleteDocument(response))
|
||||||
)
|
)
|
||||||
} else if (action.status === 'success') {
|
|
||||||
if (action.data[0]) {
|
|
||||||
store.dispatch(setCurrentDocument(action.data[0].id, action.docType, 'currentDocument'))
|
|
||||||
}
|
}
|
||||||
|
break
|
||||||
|
case 'GET_SEARCH_RESULTS':
|
||||||
|
if (action.status === 'request') {
|
||||||
|
api.HTTPPostSearchResults(action.data).then(response =>
|
||||||
|
store.dispatch(getSearchResults(response))
|
||||||
|
)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default joyceAPI
|
|
@ -3,6 +3,17 @@ import { stateToHTML } from 'draft-js-export-html'
|
||||||
import { stateToMarkdown } from 'draft-js-export-markdown'
|
import { stateToMarkdown } from 'draft-js-export-markdown'
|
||||||
import { convertToRaw } from 'draft-js'
|
import { convertToRaw } from 'draft-js'
|
||||||
|
|
||||||
|
import {
|
||||||
|
getDocumentList,
|
||||||
|
getDocumentText,
|
||||||
|
deleteDocument,
|
||||||
|
saveDocument,
|
||||||
|
createNewChapter,
|
||||||
|
getSearchResults
|
||||||
|
} from '../actions/apiActions'
|
||||||
|
|
||||||
|
import { clearCurrentDocument } from '../actions/userActions'
|
||||||
|
|
||||||
import helpers from '../modules/helpers'
|
import helpers from '../modules/helpers'
|
||||||
|
|
||||||
const html_export_options = {
|
const html_export_options = {
|
||||||
|
@ -22,8 +33,7 @@ const html_export_options = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// API Middleware
|
const joyceInterface = store => next => action => {
|
||||||
export const joyceInterface = store => next => action => {
|
|
||||||
next(action)
|
next(action)
|
||||||
switch(action.type) {
|
switch(action.type) {
|
||||||
case 'SET_CURRENT_DOCUMENT':
|
case 'SET_CURRENT_DOCUMENT':
|
||||||
|
@ -57,6 +67,11 @@ export const joyceInterface = store => next => action => {
|
||||||
store.dispatch(getDocumentText({id: notes[0].id, docType: docType, state: 'currentDocument'}))
|
store.dispatch(getDocumentText({id: notes[0].id, docType: docType, state: 'currentDocument'}))
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
case 'SET_DOC_TYPE':
|
||||||
|
if (action.docType !== store.getState().docType) {
|
||||||
|
store.dispatch(clearCurrentDocument())
|
||||||
|
}
|
||||||
|
break
|
||||||
// Annotation Action Middleware
|
// Annotation Action Middleware
|
||||||
case 'SELECT_ANNOTATION_NOTE':
|
case 'SELECT_ANNOTATION_NOTE':
|
||||||
store.dispatch(getDocumentText({id: action.id, docType: 'notes', state: 'annotationNote'}))
|
store.dispatch(getDocumentText({id: action.id, docType: 'notes', state: 'annotationNote'}))
|
||||||
|
@ -65,14 +80,9 @@ export const joyceInterface = store => next => action => {
|
||||||
case 'CLICK_SEARCH':
|
case 'CLICK_SEARCH':
|
||||||
store.dispatch(getSearchResults({data: action.data}))
|
store.dispatch(getSearchResults({data: action.data}))
|
||||||
break
|
break
|
||||||
case 'GET_SEARCH_RESULTS':
|
|
||||||
if (action.status === 'request') {
|
|
||||||
HTTPPostSearchResults(action.data).then(response =>
|
|
||||||
store.dispatch(getSearchResults(response))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
break
|
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default joyceInterface
|
|
@ -1,27 +1,80 @@
|
||||||
export const joyceRouter = store => next => action => {
|
import { push } from 'react-router-redux'
|
||||||
|
|
||||||
|
import { setCurrentDocument, setDocType } from '../actions/userActions'
|
||||||
|
import helpers from '../modules/helpers'
|
||||||
|
import regex from '../modules/regex'
|
||||||
|
|
||||||
|
const joyceRouter = store => next => action => {
|
||||||
next(action)
|
next(action)
|
||||||
switch(action.type) {
|
const path = store.getState().routerReducer.location !== null ? store.getState().routerReducer.location.pathname : '/'
|
||||||
case '@@router/LOCATION_CHANGE':
|
const pathID = regex.checkPathForID(path) ? regex.parseIDFromPath(path) : undefined
|
||||||
const path = action.payload.pathname
|
const pathNumber = regex.checkPathForNumber(path) ? regex.parseNumberFromPath(path) : undefined
|
||||||
const docType = store.getState().docType
|
const docType = store.getState().docType
|
||||||
const currentDocument = store.getState().currentDocument
|
const currentDocument = store.getState().currentDocument
|
||||||
switch(path) {
|
const chapters = store.getState().chapters
|
||||||
case /^\/[0-9]{,3}/.test(path):
|
const notes = store.getState().notes
|
||||||
// set docType = 'chapters'
|
switch(action.type) {
|
||||||
// set Current Chapter
|
case '@@router/LOCATION_CHANGE':
|
||||||
case /^\/notes\/[a-zA-Z\-\_]{18,}/.test(path):
|
if (regex.checkIfRedirectPath(path) && currentDocument.hasOwnProperty('id')) {
|
||||||
// set docType = 'notes'
|
store.dispatch(push(docType === 'chapters' ? String(currentDocument.number) : currentDocument.id))
|
||||||
// set current note
|
|
||||||
case /^\/edit\/notes\/[a-zA-Z\-\_]{18,}]/.test(path):
|
|
||||||
// set docType = 'chapters'
|
|
||||||
// set Current Chapter
|
|
||||||
// case: if /edit/ and docType = notes => /edit/notes/
|
|
||||||
// case: if redirectURL
|
|
||||||
}
|
}
|
||||||
|
if (regex.checkNoteReaderRoute(path) && regex.checkIfRedirectPath(path) && notes.length > 0) {
|
||||||
|
store.dispatch(setCurrentDocument(notes[0].id, 'notes'))
|
||||||
|
}
|
||||||
|
if (regex.checkNoteReaderRoute(path) || regex.checkNoteEditorRoute(path)) {
|
||||||
|
store.dispatch(setDocType('notes'))
|
||||||
|
}
|
||||||
|
if (regex.checkRootRedirectRoute(path) && chapters.length > 0) {
|
||||||
|
store.dispatch(setCurrentDocument(chapters[0].id, 'chapters'))
|
||||||
|
}
|
||||||
|
if (regex.checkNoteBaseRoute(path)) {
|
||||||
|
store.dispatch(setDocType('notes'))
|
||||||
|
}
|
||||||
|
if (regex.checkEditBaseRoute(path)){
|
||||||
|
if (docType === 'notes') {
|
||||||
|
store.dispatch(push('/edit/notes'))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case 'GET_DOCUMENT_LIST':
|
||||||
|
if (action.status === 'success' && action.docType === docType && !currentDocument.id) {
|
||||||
|
if (regex.checkIfRedirectPath(path)) {
|
||||||
|
store.dispatch(setCurrentDocument(action.data[0].id, action.docType))
|
||||||
|
}
|
||||||
|
if (action.docType === 'chapters' && pathNumber !== undefined) {
|
||||||
|
for (const chapter of action.data) {
|
||||||
|
if (chapter.number === pathNumber) {
|
||||||
|
store.dispatch(setCurrentDocument(chapter.id, action.docType))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (pathID !== undefined) {
|
||||||
|
store.dispatch(setCurrentDocument(pathID, action.docType))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case 'GET_DOCUMENT_TEXT':
|
||||||
|
if (action.status === 'success') {
|
||||||
|
store.dispatch(push(action.docType === 'chapters' ? String(action.data.number) : action.data.id))
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case 'SAVE_DOCUMENT':
|
||||||
|
if (action.status === 'success' && !action.id) {
|
||||||
|
store.dispatch(setCurrentDocument(action.data.slice(-1)[0].id, action.docType))
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case 'DELETE_DOCUMENT':
|
||||||
|
if (action.status === 'request') {
|
||||||
|
api.HTTPDeleteDocument(action.id, action.docType).then(response =>
|
||||||
|
store.dispatch(deleteDocument(response))
|
||||||
|
)
|
||||||
|
} else if (action.status === 'success') {
|
||||||
|
if (action.data[0]) {
|
||||||
|
store.dispatch(setCurrentDocument(action.data[0].id, action.docType, 'currentDocument'))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export default joyceRouter
|
export default joyceRouter
|
|
@ -1,4 +1,4 @@
|
||||||
export const logger = store => next => action => {
|
const logger = store => next => action => {
|
||||||
console.group(action.type)
|
console.group(action.type)
|
||||||
console.info('dispatching', action)
|
console.info('dispatching', action)
|
||||||
let result = next(action)
|
let result = next(action)
|
||||||
|
@ -6,3 +6,5 @@ export const logger = store => next => action => {
|
||||||
console.groupEnd(action.type)
|
console.groupEnd(action.type)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default logger
|
|
@ -0,0 +1,44 @@
|
||||||
|
import axios from 'axios'
|
||||||
|
|
||||||
|
const apiRoute = '/api/'
|
||||||
|
const api = {
|
||||||
|
HTTPGetDocumentList: (docType, state) =>
|
||||||
|
axios.get(apiRoute + docType).then(res => {
|
||||||
|
return {status: 'success', docType: docType, state: state, data: res.data}
|
||||||
|
}).catch(error => {
|
||||||
|
return {status: 'error', docType: docType, state: state, data: error}
|
||||||
|
}),
|
||||||
|
HTTPGetDocumentText: (id, docType, state) =>
|
||||||
|
axios.get(apiRoute + docType + '/' + id).then(res => {
|
||||||
|
return {id: id, status: 'success', docType: docType, state: state, data: res.data}
|
||||||
|
}).catch(error => {
|
||||||
|
return {id: id, status: 'error', docType: docType, state: state, data: error}
|
||||||
|
}),
|
||||||
|
HTTPDeleteDocument: (id, docType) =>
|
||||||
|
axios.delete(apiRoute + docType + '/' + id).then(res => {
|
||||||
|
return {id: id, status: 'success', docType: docType, data: res.data}
|
||||||
|
}).catch(error => {
|
||||||
|
return {id: id, status: 'error', docType: docType, data: error}
|
||||||
|
}),
|
||||||
|
HTTPPutCreateDocument: (docType, data) =>
|
||||||
|
axios.put(apiRoute + docType + '/', data).then(res => {
|
||||||
|
return {status: 'success', docType: docType, data: res.data}
|
||||||
|
}).catch(error => {
|
||||||
|
return {status: 'error', docType: docType, data: error}
|
||||||
|
}),
|
||||||
|
HTTPPostWriteDocument: (id, docType, data) =>
|
||||||
|
axios.post(apiRoute + docType + '/' + id, data).then(res => {
|
||||||
|
return {id: data.id, status: 'success', docType: docType, data: res.data}
|
||||||
|
}).catch(error => {
|
||||||
|
return {id: id, status: 'error', docType: docType, data: error}
|
||||||
|
}),
|
||||||
|
HTTPPostSearchResults: (data) =>
|
||||||
|
axios.post(apiRoute + 'search/', { data }).then(res => {
|
||||||
|
console.log('data is ', data)
|
||||||
|
return {status: 'success', data: res.data}
|
||||||
|
}).catch(error => {
|
||||||
|
return {status: 'error', data: res.data}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export default api
|
|
@ -1,26 +1,12 @@
|
||||||
|
import regex from '../modules/regex'
|
||||||
|
|
||||||
const helpers = {
|
const helpers = {
|
||||||
checkIfRedirectPath: path => {
|
getChapterIDFromPath: (path, chapters) => {
|
||||||
const match = /\/(\:id)$/.exec(path)
|
for (const chapter of chapters) {
|
||||||
if (match) {
|
const number = regex.parseNumberFromPath(path)
|
||||||
return true
|
if (chapter.number == number) {
|
||||||
} else {
|
return chapter.id
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
parseNumberFromPath: path => {
|
|
||||||
const match = /\/([0-9]*)$/.exec(path)
|
|
||||||
if (match && parseInt(match[1])) {
|
|
||||||
return Number(match[1])
|
|
||||||
} else {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
parseIDFromPath: path => {
|
|
||||||
const match = /\/([A-Za-z0-9\-\_]{18,})$/.exec(path)
|
|
||||||
if (match) {
|
|
||||||
return match[1]
|
|
||||||
} else {
|
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
const regexCheckBaseFunction = (path, pattern) => {
|
||||||
|
const match = pattern.exec(path)
|
||||||
|
if (match) {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const regexParseBaseFunction = (path, pattern) => {
|
||||||
|
const match = pattern.exec(path)
|
||||||
|
if (match) {
|
||||||
|
return match[1]
|
||||||
|
} else {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const regex = {
|
||||||
|
checkIfRedirectPath: path => {
|
||||||
|
return regexCheckBaseFunction(path, /\/(\:id)$/)
|
||||||
|
},
|
||||||
|
checkNoteBaseRoute: path => {
|
||||||
|
return regexCheckBaseFunction(path, /^\/notes$/)
|
||||||
|
},
|
||||||
|
checkEditBaseRoute: path => {
|
||||||
|
return regexCheckBaseFunction(path, /^\/edit$/)
|
||||||
|
},
|
||||||
|
checkChapterReaderRoute: path => {
|
||||||
|
return regexCheckBaseFunction(path, /^\/[0-9]{1,3}$/)
|
||||||
|
},
|
||||||
|
checkNoteReaderRoute: path => {
|
||||||
|
return regexCheckBaseFunction(path, /^\/notes\/([0-9a-zA-Z\-\_]{18,}|\:id)/)
|
||||||
|
},
|
||||||
|
checkNoteEditorRoute: path => {
|
||||||
|
return regexCheckBaseFunction(path, /^\/edit\/notes\/([0-9a-zA-Z\-\_]{18,}|\:id)/)
|
||||||
|
},
|
||||||
|
checkPathForNumber: path => {
|
||||||
|
return regexCheckBaseFunction(path, /\/[0-9]{1,3}$/)
|
||||||
|
},
|
||||||
|
checkRootRedirectRoute: path => {
|
||||||
|
return regexCheckBaseFunction(path, /^\/\:id$/)
|
||||||
|
},
|
||||||
|
checkPathForID: path => {
|
||||||
|
return regexCheckBaseFunction(path, /\/([0-9A-Za-z0-9\-\_]{18,})$/)
|
||||||
|
},
|
||||||
|
parseNumberFromPath: path => {
|
||||||
|
return Number(regexParseBaseFunction(path, /\/([0-9]{1,3})$/))
|
||||||
|
},
|
||||||
|
parseIDFromPath: path => {
|
||||||
|
return regexParseBaseFunction(path, /\/([0-9A-Za-z0-9\-\_]{18,})$/)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default regex
|
|
@ -7,6 +7,8 @@ const currentDocument = (state={}, action) => {
|
||||||
return {}
|
return {}
|
||||||
}
|
}
|
||||||
else { return state }
|
else { return state }
|
||||||
|
case 'CLEAR_CURRENT_DOCUMENT':
|
||||||
|
return {}
|
||||||
case 'DELETE_DOCUMENT':
|
case 'DELETE_DOCUMENT':
|
||||||
if (action.status === 'success' && action.data.length <= 0) {
|
if (action.status === 'success' && action.data.length <= 0) {
|
||||||
return {}
|
return {}
|
||||||
|
|
|
@ -2,11 +2,8 @@ const docType = (state='chapters', action) => {
|
||||||
switch(action.type) {
|
switch(action.type) {
|
||||||
case 'SET_DOC_TYPE':
|
case 'SET_DOC_TYPE':
|
||||||
return action.docType
|
return action.docType
|
||||||
case '@@router/LOCATION_CHANGE':
|
case 'SET_CURRENT_DOCUMENT':
|
||||||
const path = action.payload.pathname
|
return action.docType
|
||||||
if (/^\/(notes).*/.exec(path)) {
|
|
||||||
return 'notes'
|
|
||||||
} else{ return state }
|
|
||||||
default:
|
default:
|
||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,11 @@ const editorState = (state=blankEditor, action) => {
|
||||||
case 'UPDATE_EDITOR_STATE':
|
case 'UPDATE_EDITOR_STATE':
|
||||||
return action.data
|
return action.data
|
||||||
case 'HANDLE_EDITOR_KEY_COMMAND':
|
case 'HANDLE_EDITOR_KEY_COMMAND':
|
||||||
return RichUtils.handleKeyCommand(action.editorState, action.command)
|
const editorState = RichUtils.handleKeyCommand(action.editorState, action.command)
|
||||||
|
// Null check to handle null editorState when backspacking empty editor
|
||||||
|
if (editorState !== null) {
|
||||||
|
return editorState
|
||||||
|
} else { return state }
|
||||||
case 'APPLY_INLINE_STYLE':
|
case 'APPLY_INLINE_STYLE':
|
||||||
let inlineStyles = ['BOLD', 'ITALIC', 'UNDERLINE']
|
let inlineStyles = ['BOLD', 'ITALIC', 'UNDERLINE']
|
||||||
if (inlineStyles.indexOf(action.style) >= 0) {
|
if (inlineStyles.indexOf(action.style) >= 0) {
|
||||||
|
|
Loading…
Reference in New Issue