Refactored routing, broke some editor components
This commit is contained in:
parent
91be248aea
commit
006a1b2e1f
10
setup.py
10
setup.py
|
@ -66,9 +66,19 @@ tag_mappings = {
|
|||
}
|
||||
}
|
||||
|
||||
media_mappings = {
|
||||
'doc': {
|
||||
'properties': {
|
||||
'title': {'type': 'keyword'},
|
||||
'src': {'type': 'keyword'}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
chapter_index_settings = {'settings': default_index_settings, 'mappings': chapter_mappings}
|
||||
note_index_settings = {'settings': default_index_settings, 'mappings': note_mappings}
|
||||
tag_index_settings = {'settings': default_index_settings, 'mappings': tag_mappings}
|
||||
tag_index_settings = {'settings': default_index_settings, 'mappings': media_mappings}
|
||||
|
||||
# Read Seed Data from Files
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ export const DocTypeDropdown = ({docType, setDocType, size='sm'}) =>
|
|||
<a className='dropdown-item' onClick={()=>setDocType('chapters')}>Chapters</a>
|
||||
<a className='dropdown-item' onClick={()=>setDocType('notes')}>Notes</a>
|
||||
<a className='dropdown-item' onClick={()=>setDocType('tags')}>Tags</a>
|
||||
<a className='dropdown-item' onClick={()=>setDocType('media')}>Media</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ const EditorEditMode = ({
|
|||
onColorSwatchClick,
|
||||
userErrors,
|
||||
}) =>
|
||||
<div id='editor_read_mode' className='editor_wrapper'>
|
||||
<div id='editor_edit_mode' className='editor_wrapper'>
|
||||
<div id='editor_metadata'>
|
||||
{toggles.loading === true &&
|
||||
<LoadingSpinner />
|
||||
|
@ -39,7 +39,7 @@ const EditorEditMode = ({
|
|||
onToolButtonClick={onToolButtonClick}
|
||||
disabled={!currentDocument.id ? true : false}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div id='editor_content' className={'edit_mode ' + docType}>
|
||||
<Editor
|
||||
editorState={editorState}
|
||||
|
|
|
@ -16,9 +16,6 @@ const EditorReadMode = ({
|
|||
}) =>
|
||||
<div id='editor_read_mode' className='editor_wrapper'>
|
||||
<div id='editor_metadata'>
|
||||
{toggles.loading === true &&
|
||||
<LoadingSpinner />
|
||||
}
|
||||
<DocumentTitle docType={docType} currentDocument={currentDocument} />
|
||||
</div>
|
||||
<div id='editor_topbar'>
|
||||
|
|
|
@ -17,6 +17,8 @@ import { EditorSidebarOptions } from '../components/mobileSidebarOptions'
|
|||
const EditorPage = ({
|
||||
chapters,
|
||||
notes,
|
||||
tags,
|
||||
media,
|
||||
currentDocument,
|
||||
annotationNote,
|
||||
annotationTag,
|
||||
|
@ -24,7 +26,6 @@ const EditorPage = ({
|
|||
modalEditorState,
|
||||
docType,
|
||||
mode,
|
||||
tags,
|
||||
toggles,
|
||||
setDocType,
|
||||
onDocumentClick,
|
||||
|
@ -43,7 +44,7 @@ const EditorPage = ({
|
|||
<Content>
|
||||
{mode === 'READ_MODE' &&
|
||||
<EditorSidebarOptions
|
||||
docs={helpers.documentsOfDocType(docType, chapters, notes, tags)}
|
||||
docs={helpers.documentsOfDocType(docType, chapters, notes, tags, media)}
|
||||
currentDocument={currentDocument}
|
||||
docType={docType}
|
||||
setDocType={setDocType}
|
||||
|
@ -83,6 +84,7 @@ const mapStateToProps = state => {
|
|||
chapters: state.chapters,
|
||||
notes: state.notes,
|
||||
tags: state.tags,
|
||||
media: state.media,
|
||||
mode: state.mode,
|
||||
currentDocument: state.currentDocument,
|
||||
annotationNote: state.annotationNote,
|
||||
|
@ -129,6 +131,7 @@ const mapDispatchToProps = dispatch => {
|
|||
EditorPage.propTypes = {
|
||||
notes: PropTypes.arrayOf(PropTypes.object),
|
||||
tags: PropTypes.arrayOf(PropTypes.object),
|
||||
media: PropTypes.arrayOf(PropTypes.object),
|
||||
currentDocument: PropTypes.object,
|
||||
annotationNote: PropTypes.object,
|
||||
annotationTag: PropTypes.object,
|
||||
|
|
|
@ -13,6 +13,7 @@ const EditorSidebar = ({
|
|||
chapters,
|
||||
notes,
|
||||
tags,
|
||||
media,
|
||||
docType,
|
||||
currentDocument,
|
||||
onDocumentClick,
|
||||
|
@ -25,7 +26,7 @@ const EditorSidebar = ({
|
|||
<SidebarSpacer />
|
||||
<NewDocumentButton onClick={()=>onNewDocumentClick(docType)} docType={docType}/>
|
||||
<SidebarSpacer />
|
||||
<DocumentList docs={helpers.documentsOfDocType(docType, chapters, notes, tags)} currentDocument={currentDocument} onDocumentClick={onDocumentClick} docType={docType} path={'/edit/'}/>
|
||||
<DocumentList docs={helpers.documentsOfDocType(docType, chapters, notes, tags, media)} currentDocument={currentDocument} onDocumentClick={onDocumentClick} docType={docType} path={'/edit/'}/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -34,6 +35,7 @@ const mapStateToProps = state => {
|
|||
notes: state.notes,
|
||||
chapters: state.chapters,
|
||||
tags: state.tags,
|
||||
media: state.media,
|
||||
docType: state.docType,
|
||||
currentDocument: state.currentDocument,
|
||||
}
|
||||
|
@ -57,6 +59,7 @@ EditorSidebar.propTypes = {
|
|||
chapters: PropTypes.arrayOf(PropTypes.object),
|
||||
notes: PropTypes.arrayOf(PropTypes.object),
|
||||
tags: PropTypes.arrayOf(PropTypes.object),
|
||||
media: PropTypes.arrayOf(PropTypes.object),
|
||||
currentDocument: PropTypes.object,
|
||||
docType: PropTypes.string,
|
||||
onDocumentClick: PropTypes.func,
|
||||
|
|
|
@ -27,8 +27,10 @@ const ReaderSidebar = ({
|
|||
|
||||
const mapStateToProps = state => {
|
||||
return {
|
||||
chapters: state.chapters,
|
||||
notes: state.notes,
|
||||
chapters: state.chapters,
|
||||
tags: state.tags,
|
||||
media: state.media,
|
||||
docType: state.docType,
|
||||
currentDocument: state.currentDocument,
|
||||
toggles: state.toggles,
|
||||
|
|
|
@ -10,6 +10,7 @@ const joyceRouter = store => next => action => {
|
|||
const chapters = store.getState().chapters
|
||||
const notes = store.getState().notes
|
||||
const tags = store.getState().tags
|
||||
const media = store.getState().media
|
||||
const currentDocument = store.getState().currentDocument
|
||||
const docType = store.getState().docType
|
||||
// Path
|
||||
|
@ -18,55 +19,68 @@ const joyceRouter = store => next => action => {
|
|||
const pathNumber = regex.checkPathForNumber(path) ? regex.parseNumberFromPath(path) : undefined
|
||||
switch(action.type) {
|
||||
case '@@router/LOCATION_CHANGE':
|
||||
if (regex.checkIfRedirectPath(path) && currentDocument.hasOwnProperty('id')) {
|
||||
store.dispatch(push(docType === 'chapters' ? String(currentDocument.number) : currentDocument.id))
|
||||
}
|
||||
if (regex.checkNoteReaderRoute(path) && regex.checkIfRedirectPath(path) && notes.length > 0) {
|
||||
store.dispatch(actions.setCurrentDocument(notes[0].id, 'notes'))
|
||||
}
|
||||
if (regex.checkNoteEditorRoute(path) && regex.checkIfRedirectPath(path) && notes.length > 0) {
|
||||
store.dispatch(actions.setCurrentDocument(notes[0].id, 'notes'))
|
||||
}
|
||||
if (regex.checkTagEditorRoute(path) && regex.checkIfRedirectPath(path) && tags.length > 0) {
|
||||
store.dispatch(actions.setCurrentDocument(tags[0].id, 'tags'))
|
||||
}
|
||||
if (regex.checkChapterEditorRoute(path) && regex.checkIfRedirectPath(path) && chapters.length > 0) {
|
||||
store.dispatch(actions.setCurrentDocument(chapters[0].id, 'chapters'))
|
||||
}
|
||||
if (regex.checkNoteReaderRoute(path) || regex.checkNoteEditorRoute(path)) {
|
||||
store.dispatch(actions.setDocType('notes'))
|
||||
}
|
||||
if (regex.checkTagEditorRoute(path)) {
|
||||
store.dispatch(actions.setDocType('tags'))
|
||||
}
|
||||
if (regex.checkRootRedirectRoute(path) && chapters.length > 0) {
|
||||
store.dispatch(actions.setCurrentDocument(chapters[0].id, 'chapters'))
|
||||
}
|
||||
if (regex.checkNoteBaseRoute(path)) {
|
||||
store.dispatch(actions.setDocType('notes'))
|
||||
// If a docType can be parsed from the path, set it
|
||||
if (regex.checkIfDocTypePath(path)) {
|
||||
store.dispatch(actions.setDocType(regex.parseDocTypeFromPath(path)))
|
||||
}
|
||||
// If path is /edit and docType isn't chapters, push the docType to the path
|
||||
if (regex.checkEditBaseRoute(path)){
|
||||
if (docType === 'notes') {
|
||||
store.dispatch(push('/edit/notes'))
|
||||
if (docType !== 'chapters') {
|
||||
store.dispatch(push('/edit/' + docType))
|
||||
}
|
||||
}
|
||||
// If path ends in :id...
|
||||
if (regex.checkIfRedirectPath(path)) {
|
||||
// And currentDocument is set, push the right identifier
|
||||
if (currentDocument.hasOwnProperty('id')) {
|
||||
store.dispatch(push(docType === 'chapters' ? String(currentDocument.number) : currentDocument.id))
|
||||
}
|
||||
// And path is /:id and chapters are loaded, set currentDocument to first chapter
|
||||
else if (regex.checkIfRootPath(path) && chapters.length > 0) {
|
||||
console.log('THIS IS HAPPENING')
|
||||
store.dispatch(actions.setCurrentDocument(chapters[0].id, 'chapters'))
|
||||
}
|
||||
// And path has a docType and docs are loaded, set currentDocument to first doc of that type
|
||||
else if (regex.checkIfDocTypePath(path)) {
|
||||
switch(regex.parseDocTypeFromPath) {
|
||||
case 'notes':
|
||||
if (notes.length > 0) {
|
||||
store.dispatch(actions.setCurrentDocument(notes[0].id, 'notes'))
|
||||
}
|
||||
case 'tags':
|
||||
if (tags.length > 0) {
|
||||
store.dispatch(actions.setCurrentDocument(tags[0].id, 'tags'))
|
||||
}
|
||||
case 'media':
|
||||
if (media.length > 0) {
|
||||
store.dispatch(actions.setCurrentDocument(media[0].id, 'media'))
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
case 'GET_DOCUMENT_LIST':
|
||||
if (action.status === 'success' && action.docType === docType && !currentDocument.id) {
|
||||
if (regex.checkIfRedirectPath(path)) {
|
||||
// If path ends in :id, set currentDocument to the first from the returned list
|
||||
if (regex.checkIfRedirectPath(path) && action.data.length > 0) {
|
||||
store.dispatch(actions.setCurrentDocument(action.data[0].id, action.docType))
|
||||
}
|
||||
// If docType is chapters and path ends in a number, find chapter matching that number and set its ID to currentDocument
|
||||
if (action.docType === 'chapters' && pathNumber !== undefined) {
|
||||
for (const chapter of action.data) {
|
||||
if (chapter.number === pathNumber) {
|
||||
store.dispatch(actions.setCurrentDocument(chapter.id, action.docType))
|
||||
}
|
||||
}
|
||||
// If path ends in an ID, set it to the currentDocument
|
||||
} else if (pathID !== undefined) {
|
||||
store.dispatch(actions.setCurrentDocument(pathID, action.docType))
|
||||
}
|
||||
}
|
||||
break
|
||||
case 'SET_EDITOR_DOC_TYPE':
|
||||
// If path starts with /edit, set the path appropriate for the docType
|
||||
if (regex.checkEditRoute(path)) {
|
||||
if (action.docType === 'chapters') {
|
||||
store.dispatch(push('/edit'))
|
||||
|
@ -77,6 +91,7 @@ const joyceRouter = store => next => action => {
|
|||
break
|
||||
case 'GET_DOCUMENT_TEXT':
|
||||
if (action.status === 'success' && action.state === 'currentDocument') {
|
||||
// After successfully retrieving a currentDocument, push its identifier to the path
|
||||
store.dispatch(push(action.docType === 'chapters' ? String(action.data.number) : action.data.id))
|
||||
}
|
||||
break
|
||||
|
|
|
@ -19,10 +19,12 @@ const helpers = {
|
|||
break
|
||||
case 'tags':
|
||||
return 'Tags'
|
||||
case 'media':
|
||||
return 'Media'
|
||||
break
|
||||
}
|
||||
},
|
||||
documentsOfDocType: (docType, chapters, notes, tags) => {
|
||||
documentsOfDocType: (docType, chapters, notes, tags, media) => {
|
||||
switch(docType) {
|
||||
case 'chapters':
|
||||
return chapters
|
||||
|
@ -32,6 +34,8 @@ const helpers = {
|
|||
break
|
||||
case 'tags':
|
||||
return tags
|
||||
case 'media':
|
||||
return media
|
||||
break
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,60 +7,61 @@ const regexCheckBaseFunction = (path, pattern) => {
|
|||
}
|
||||
}
|
||||
|
||||
const regexParseBaseFunction = (path, pattern) => {
|
||||
const regexParseBaseFunction = (path, pattern, n=1) => {
|
||||
const match = pattern.exec(path)
|
||||
if (match) {
|
||||
return match[1]
|
||||
return match[n]
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
const patterns = {
|
||||
PATH_WITH_NUMBER: /\/([0-9]{1,3})$/,
|
||||
PATH_WITH_ID: /\/([0-9A-Za-z0-9\-\_]{18,})$/,
|
||||
PATH_WITH_DOC_TYPE: /^\/(edit\/)*(notes|tags|chapters|media)/,
|
||||
PATH_WITH_ID_REDIRECT: /\/(\:id)$/,
|
||||
PATH_ROOT: /^\/(\:id)*$/,
|
||||
PATH_EDITOR: /^\/edit(\/)*/,
|
||||
PATH_BASE_EDITOR: /^\/edit$/,
|
||||
HEX_COLOR: /(^[0-9A-F]{6})$|(^[0-9A-F]{3}$)/,
|
||||
}
|
||||
|
||||
const regex = {
|
||||
// Route Checks
|
||||
checkIfRedirectPath: path => {
|
||||
return regexCheckBaseFunction(path, /\/(\:id)$/)
|
||||
},
|
||||
checkNoteBaseRoute: path => {
|
||||
return regexCheckBaseFunction(path, /^\/notes$/)
|
||||
},
|
||||
checkEditBaseRoute: path => {
|
||||
return regexCheckBaseFunction(path, /^\/edit$/)
|
||||
},
|
||||
checkEditRoute: path => {
|
||||
return regexCheckBaseFunction(path, /^\/edit\//)
|
||||
},
|
||||
checkNoteReaderRoute: path => {
|
||||
return regexCheckBaseFunction(path, /^\/notes\/([0-9a-zA-Z\-\_]{18,}|\:id)/)
|
||||
},
|
||||
checkChapterEditorRoute: path => {
|
||||
return regexCheckBaseFunction(path, /^\/edit\/([0-9]{1,3}|\:id)/)
|
||||
},
|
||||
checkNoteEditorRoute: path => {
|
||||
return regexCheckBaseFunction(path, /^\/edit\/notes\/([0-9a-zA-Z\-\_]{18,}|\:id)/)
|
||||
},
|
||||
checkTagEditorRoute : path => {
|
||||
return regexCheckBaseFunction(path, /^\/edit\/tags\/([0-9a-zA-Z\-\_]{18,}|\:id)/)
|
||||
},
|
||||
checkPathForNumber: path => {
|
||||
return regexCheckBaseFunction(path, /\/[0-9]{1,3}$/)
|
||||
},
|
||||
checkRootRedirectRoute: path => {
|
||||
return regexCheckBaseFunction(path, /^\/\:id$/)
|
||||
return regexCheckBaseFunction(path, patterns.PATH_WITH_NUMBER)
|
||||
},
|
||||
checkPathForID: path => {
|
||||
return regexCheckBaseFunction(path, /\/([0-9A-Za-z0-9\-\_]{18,})$/)
|
||||
return regexCheckBaseFunction(path, patterns.PATH_WITH_ID)
|
||||
},
|
||||
checkIfDocTypePath: path => {
|
||||
return regexCheckBaseFunction(path, patterns.PATH_WITH_DOC_TYPE)
|
||||
},
|
||||
checkIfRedirectPath: path => {
|
||||
return regexCheckBaseFunction(path, patterns.PATH_WITH_ID_REDIRECT)
|
||||
},
|
||||
checkIfRootPath: path => {
|
||||
return regexCheckBaseFunction(path, patterns.PATH_ROOT)
|
||||
},
|
||||
checkEditRoute: path => {
|
||||
return regexCheckBaseFunction(path, patterns.PATH_EDITOR)
|
||||
},
|
||||
checkEditBaseRoute: path => {
|
||||
return regexCheckBaseFunction(path, patterns.PATH_BASE_EDITOR)
|
||||
},
|
||||
// Route Parsers
|
||||
parseNumberFromPath: path => {
|
||||
return Number(regexParseBaseFunction(path, /\/([0-9]{1,3})$/))
|
||||
return Number(regexParseBaseFunction(path, patterns.PATH_WITH_NUMBER))
|
||||
},
|
||||
parseIDFromPath: path => {
|
||||
return regexParseBaseFunction(path, /\/([0-9A-Za-z0-9\-\_]{18,})$/)
|
||||
return regexParseBaseFunction(path, patterns.PATH_WITH_ID)
|
||||
},
|
||||
parseDocTypeFromPath: path => {
|
||||
return regexParseBaseFunction(path, patterns.PATH_WITH_DOC_TYPE, 2)
|
||||
},
|
||||
// Validation Checks
|
||||
checkColorPickerHexValue: input => {
|
||||
return regexCheckBaseFunction(input, /(^[0-9A-F]{6})$|(^[0-9A-F]{3}$)/)
|
||||
return regexCheckBaseFunction(input, patterns.HEX_COLOR)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
const loadingToggle = (state=true, action) => {
|
||||
switch(action.type) {
|
||||
case 'GET_DOCUMENT_TEXT':
|
||||
if (action.status === 'request' && action.state === 'currentDocument') {
|
||||
return true
|
||||
} else if (action.status === 'success' && action.state === 'currentDocument') {
|
||||
return false
|
||||
}
|
||||
case 'GET_DOCUMENT_LIST':
|
||||
if (action.status === 'success' && !action.data[0] && action.state === 'currentDocType') {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
return state
|
||||
}
|
||||
}
|
||||
|
||||
export default loadingToggle
|
|
@ -0,0 +1,20 @@
|
|||
const media = (state=[], action) => {
|
||||
switch(action.type) {
|
||||
case 'GET_DOCUMENT_LIST':
|
||||
if (action.status === 'success' && action.docType === 'media') {
|
||||
return action.data
|
||||
} else { return state }
|
||||
case 'DELETE_DOCUMENT':
|
||||
if (action.status === 'success' && action.docType === 'media') {
|
||||
return action.data
|
||||
} else { return state }
|
||||
case 'SAVE_DOCUMENT':
|
||||
if (action.status === 'success' && action.docType === 'media') {
|
||||
return action.data
|
||||
} else { return state }
|
||||
default:
|
||||
return state
|
||||
}
|
||||
}
|
||||
|
||||
export default media
|
|
@ -6,6 +6,7 @@ import { routerReducer } from 'react-router-redux'
|
|||
import chapters from './chapters'
|
||||
import notes from './notes'
|
||||
import tags from './tags'
|
||||
import media from './media'
|
||||
import currentDocument from './currentDocument'
|
||||
import annotationNote from './annotationNote'
|
||||
import annotationTag from './annotationTag'
|
||||
|
@ -36,6 +37,7 @@ const reduceJoyce = combineReducers({
|
|||
chapters,
|
||||
notes,
|
||||
tags,
|
||||
media,
|
||||
currentDocument,
|
||||
annotationNote,
|
||||
annotationTag,
|
||||
|
|
|
@ -21,11 +21,17 @@ const toggles = (state=initialState, action) => {
|
|||
}
|
||||
case 'GET_DOCUMENT_LIST':
|
||||
if (action.status === 'success' && !action.data[0] && action.state === 'currentDocType') {
|
||||
// if (action.status === 'success' && action.state === 'currentDocType') {
|
||||
return {
|
||||
...state,
|
||||
loading: false
|
||||
}
|
||||
}
|
||||
case 'CREATE_DOCUMENT':
|
||||
return {
|
||||
...state,
|
||||
loading: false
|
||||
}
|
||||
// Highlights
|
||||
case 'TOGGLE_HIGHLIGHT':
|
||||
return {
|
||||
|
|
|
@ -65,6 +65,9 @@
|
|||
height: 68vh;
|
||||
}
|
||||
|
||||
// #editor_content.edit_mode.media {
|
||||
// height: 30vh;
|
||||
// }
|
||||
|
||||
#editor_content.annotate_mode {
|
||||
height: 73vh;
|
||||
|
|
Loading…
Reference in New Issue