Introduced FontAwesome to replace the glyphicons lost in upgrading Boostrap to4
37
TODO.txt
|
@ -4,23 +4,10 @@
|
|||
+ Basic Layout +
|
||||
+ React Components +
|
||||
+ Front-End Dependency Manager +
|
||||
- Wire React to ES API
|
||||
- Simple CRUID interface
|
||||
|
||||
Short List:
|
||||
- Some Testing
|
||||
- Font Awesome / Better Glyphicons
|
||||
- Env Configs
|
||||
- Collapsable Button Lists
|
||||
- Draft.JS
|
||||
- DRY up Sass Modules
|
||||
- Async API Middleware
|
||||
- CombineReducers in App.js
|
||||
- Import Action consts into Reducers
|
||||
- PropTypes
|
||||
|
||||
- Loading Indicators
|
||||
|
||||
+ Wire React to ES API +
|
||||
+ Simple CRUD interface +
|
||||
+ Async API Middleware +
|
||||
+ Font Awesome / Better Glyphicons +
|
||||
|
||||
- v0.2 Reader
|
||||
- Reader UX
|
||||
|
@ -31,6 +18,19 @@ Short List:
|
|||
- Abstract API Blueprint for Notes
|
||||
- Note Manager Component
|
||||
|
||||
- v0.4 Search
|
||||
|
||||
- v0.5 Pagination
|
||||
|
||||
Short List:
|
||||
- PropTypes
|
||||
- DRY up Sass Modules
|
||||
- Env Configs
|
||||
- Some Testing
|
||||
- Draft.JS
|
||||
- Elasticsearch Versioning and Revert UI
|
||||
- Collapsable Button Lists
|
||||
- Loading Indicators
|
||||
- Error Handling
|
||||
- Unit Testing
|
||||
- Remove Flask-Webpack?
|
||||
|
@ -49,4 +49,5 @@ Short List:
|
|||
- Weed out unneeded dependencies
|
||||
- Implement a pixel to track usage
|
||||
- Default Pagination?
|
||||
- ARIA compliance
|
||||
- ARIA compliance
|
||||
- Docker
|
|
@ -15,10 +15,12 @@
|
|||
"draft-js": "^0.10.4",
|
||||
"draft-js-export-html": "^1.2.0",
|
||||
"draft-js-import-html": "^1.2.1",
|
||||
"font-awesome": "^4.7.0",
|
||||
"object-assign": "^4.1.1",
|
||||
"popper.js": "^1.12.6",
|
||||
"react": "^16.0.0",
|
||||
"react-dom": "^16.0.0",
|
||||
"react-fontawesome": "^1.6.1",
|
||||
"react-redux": "^5.0.6",
|
||||
"redux": "^3.7.2"
|
||||
},
|
||||
|
|
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.4 KiB |
|
@ -1,30 +0,0 @@
|
|||
const glyphiconItalic = require('./glyphicons-102-italic.png')
|
||||
const glyphiconBold = require('./glyphicons-103-bold.png')
|
||||
const glyphiconUnderline = require('./glyphicons-104-text-underline.png')
|
||||
|
||||
const glyphiconAlignLeft = require('./glyphicons-111-align-left.png')
|
||||
const glyphiconAlignCenter = require('./glyphicons-112-align-center.png')
|
||||
const glyphiconAlignRight = require('./glyphicons-113-align-right.png')
|
||||
|
||||
const glyphiconChevronLeft = require('./glyphicons-225-chevron-left.png')
|
||||
const glyphiconChevronRight = require('./glyphicons-224-chevron-right.png')
|
||||
|
||||
const glyphiconPlusSign = require('./glyphicons-191-plus-sign.png')
|
||||
const glyphiconMinusSign = require('./glyphicons-192-minus-sign.png')
|
||||
const glyphiconRemoveSign = require('./glyphicons-193-remove-sign.png')
|
||||
const glyphiconOKSign = require('./glyphicons-194-ok-sign.png')
|
||||
|
||||
export {
|
||||
glyphiconItalic,
|
||||
glyphiconBold,
|
||||
glyphiconUnderline,
|
||||
glyphiconAlignLeft,
|
||||
glyphiconAlignCenter,
|
||||
glyphiconAlignRight,
|
||||
glyphiconChevronLeft,
|
||||
glyphiconChevronRight,
|
||||
glyphiconPlusSign,
|
||||
glyphiconMinusSign,
|
||||
glyphiconRemoveSign,
|
||||
glyphiconOKSign
|
||||
}
|
|
@ -18,7 +18,7 @@ export const HighlightButton = ({highlightActive, onHighlightClick}) =>
|
|||
<div>
|
||||
<div id="highlight_button" className="text-center">
|
||||
<button onClick={onHighlightClick} className={highlightActive ? 'btn btn-primary btn-lg' : 'btn btn-outline-primary btn-lg'}>
|
||||
{highlightActive ? 'Remove Highlight' : 'Highlight Notes'}
|
||||
{highlightActive ? 'Hide Notes' : 'Highlight Notes'}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -27,7 +27,7 @@ export const NewChapterButton = ({onNewChapterClick}) =>
|
|||
<div>
|
||||
<div id="highlight_button" className="text-center">
|
||||
<button onClick={onNewChapterClick} className='btn btn-outline-success btn-lg'>
|
||||
New Chapter <strong>+</strong>
|
||||
New Chapter <i className="fa fa-plus-square-o"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
|
@ -1,8 +1,24 @@
|
|||
import React from 'react'
|
||||
|
||||
const Navbar = () =>
|
||||
<nav className='navbar navbar-toggleable-md navbar-static-top navbar-inverse'>
|
||||
<nav className='navbar navbar-toggleable-md navbar-static-top navbar-expand-lg navbar-inverse'>
|
||||
<a className='navbar-brand' href='/'>The Joyce Project</a>
|
||||
<div id="navbarNav">
|
||||
<ul className="navbar-nav">
|
||||
<li className="nav-item">
|
||||
<a className="nav-link" href="/edit">Edit</a>
|
||||
</li>
|
||||
<li className="nav-item">
|
||||
<a className="nav-link" href="/annotate">Annotate</a>
|
||||
</li>
|
||||
<li className="nav-item">
|
||||
<a className="nav-link" href="/search">Search</a>
|
||||
</li>
|
||||
<li className="nav-item">
|
||||
<a className="nav-link" href="/about">About</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
export default Navbar
|
|
@ -2,8 +2,8 @@ import React from 'react'
|
|||
import { connect } from 'react-redux'
|
||||
import { setCurrentChapter } from '../actions'
|
||||
|
||||
const Page = ({currentChapter}) =>
|
||||
<div id="page">
|
||||
const Page = ({currentChapter, highlightActive}) =>
|
||||
<div id="page" className={highlightActive ? 'show_notes' : 'hide_notes'}>
|
||||
<h2>[{currentChapter.number}]</h2>
|
||||
<h3>{currentChapter.title}</h3>
|
||||
<div dangerouslySetInnerHTML={{__html: currentChapter.text}} />
|
||||
|
@ -11,8 +11,8 @@ const Page = ({currentChapter}) =>
|
|||
|
||||
const mapStateToProps = state => {
|
||||
return {
|
||||
chapters: state.chapters,
|
||||
currentChapter: state.currentChapter
|
||||
currentChapter: state.currentChapter,
|
||||
highlightActive: state.highlightActive
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,12 +3,9 @@ import { connect } from 'react-redux'
|
|||
import { Editor } from 'draft-js'
|
||||
import { stateToHTML } from 'draft-js-export-html'
|
||||
|
||||
|
||||
import { updateEditorState, updateChapterTitleInput, updateChapterNumberInput, submitChapter, deleteChapter } from '../actions'
|
||||
|
||||
|
||||
import { glyphiconBold, glyphiconItalic, glyphiconUnderline, glyphiconAlignLeft, glyphiconAlignCenter, glyphiconAlignRight } from '../assets'
|
||||
|
||||
const TextEditor = ({currentChapter, editorState, onChangeEditorState, chapterTitleInput, onChapterTitleChange, onEditSubmit, onDelete}) =>
|
||||
<div id='editor_container'>
|
||||
<div id='editor_topbar'>
|
||||
|
@ -23,14 +20,14 @@ const TextEditor = ({currentChapter, editorState, onChangeEditorState, chapterTi
|
|||
</div>
|
||||
<div className='row'>
|
||||
<div className='btn-group col-md-3 offset-md-6' role='group'>
|
||||
<button type='button' className='btn btn-info btn-sm'><img src={glyphiconBold} /></button>
|
||||
<button type='button' className='btn btn-info btn-sm'><img src={glyphiconItalic} /></button>
|
||||
<button type='button' className='btn btn-info btn-sm'><img src={glyphiconUnderline} /></button>
|
||||
<button type='button' className='btn btn-info btn-sm'><i className='fa fa-bold'></i></button>
|
||||
<button type='button' className='btn btn-info btn-sm'><i className='fa fa-italic'></i></button>
|
||||
<button type='button' className='btn btn-info btn-sm'><i className='fa fa-underline'></i></button>
|
||||
</div>
|
||||
<div className='btn-group col-md-3' role='group'>
|
||||
<button type='button' className='btn btn-info btn-sm'><img src={glyphiconAlignLeft} /></button>
|
||||
<button type='button' className='btn btn-info btn-sm'><img src={glyphiconAlignCenter} /></button>
|
||||
<button type='button' className='btn btn-info btn-sm'><img src={glyphiconAlignRight} /></button>
|
||||
<button type='button' className='btn btn-info btn-sm'><i className='fa fa-align-left'></i></button>
|
||||
<button type='button' className='btn btn-info btn-sm'><i className='fa fa-align-center'></i></button>
|
||||
<button type='button' className='btn btn-info btn-sm'><i className='fa fa-align-right'></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -42,10 +39,16 @@ const TextEditor = ({currentChapter, editorState, onChangeEditorState, chapterTi
|
|||
<div id='editor_bottombar'>
|
||||
<div className='row'>
|
||||
<div className='col-md-5'>
|
||||
<button id='editor_delete' onClick={()=>onDelete(currentChapter)} type='button' className='btn btn-danger btn-sm'>Delete</button>
|
||||
<button id='editor_delete' onClick={()=>onDelete(currentChapter)} type='button' className='btn btn-danger btn-sm'>
|
||||
Delete
|
||||
<i className='fa fa-trash-o'></i>
|
||||
</button>
|
||||
</div>
|
||||
<div className='col-md-5 offset-md-2'>
|
||||
<button id='editor_save' onClick={()=>onEditSubmit(currentChapter, chapterTitleInput, editorState)} type='button' className='btn btn-success btn-sm'>Save</button>
|
||||
<button id='editor_save' onClick={()=>onEditSubmit(currentChapter, chapterTitleInput, editorState)} type='button' className='btn btn-success btn-sm'>
|
||||
Save
|
||||
<i className='fa fa-check-square-o'></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
@import "custom";
|
||||
@import "node_modules/bootstrap/scss/bootstrap";
|
||||
|
||||
$fa-font-path: "../../node_modules/font-awesome/fonts";
|
||||
@import "node_modules/font-awesome/scss/font-awesome";
|
||||
|
||||
|
||||
$bg_gradient1: #ede9de;
|
||||
$bg_gradient2: #e0dbb5;
|
||||
|
||||
|
@ -91,6 +95,7 @@ nav a:hover {
|
|||
|
||||
#content_window {
|
||||
height: 44em;
|
||||
overflow: hidden;
|
||||
background-color: rgba(250,250,250,.8);
|
||||
margin: 0 2% 1.5% 2%;
|
||||
padding: 2% 2%;
|
||||
|
@ -126,7 +131,8 @@ nav a:hover {
|
|||
}
|
||||
|
||||
#editor_content {
|
||||
height: 100%;
|
||||
height: 35em;
|
||||
overflow: scroll;
|
||||
background-color: rgba(256,256,256,.8);
|
||||
box-shadow: 2px 5px 10px 1px rgba(0, 0, 0, 0.3);
|
||||
margin: 0.8% 0;
|
||||
|
@ -136,7 +142,6 @@ nav a:hover {
|
|||
}
|
||||
|
||||
#editor_content div {
|
||||
height: 100%;
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
@import "custom";
|
||||
@import "node_modules/bootstrap/scss/bootstrap";
|
||||
|
||||
$fa-font-path: "../../node_modules/font-awesome/fonts";
|
||||
@import "node_modules/font-awesome/scss/font-awesome";
|
||||
|
||||
$bg_gradient1: #ede9de;
|
||||
$bg_gradient2: #e0dbb5;
|
||||
|
||||
|
@ -87,6 +90,7 @@ nav a:hover {
|
|||
|
||||
#page {
|
||||
height: 100%;
|
||||
overflow: scroll;
|
||||
background-color: rgba(256,256,256,.8);
|
||||
box-shadow: 2px 5px 10px 1px rgba(0, 0, 0, 0.3);
|
||||
padding: 3% 8%;
|
||||
|
@ -94,6 +98,34 @@ nav a:hover {
|
|||
border-radius: 5px;
|
||||
}
|
||||
|
||||
#page.show_notes a {
|
||||
cursor: pointer;
|
||||
animation-duration: 1s;
|
||||
animation-name: fadeIn;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
|
||||
#page.hide_notes a {
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
cursor: default;
|
||||
pointer-events: none;
|
||||
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
to {
|
||||
color: map-get($theme_colors, "primary");
|
||||
background-color: #f2e9de;
|
||||
border-radius: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
#page {
|
||||
|
||||
h2 {
|
||||
|
|
|
@ -67,6 +67,12 @@ module.exports = {
|
|||
}, {
|
||||
loader: 'sass-loader' // compiles SASS to CSS
|
||||
}]
|
||||
},
|
||||
{
|
||||
test: /.(ttf|otf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/,
|
||||
use: [{
|
||||
loader: 'file-loader'
|
||||
}]
|
||||
}
|
||||
]},
|
||||
plugins: [
|
||||
|
|