summaryrefslogtreecommitdiff
path: root/animism-align
diff options
context:
space:
mode:
authorJules Laplace <julescarbon@gmail.com>2020-07-04 16:37:19 +0200
committerJules Laplace <julescarbon@gmail.com>2020-07-04 16:37:19 +0200
commite973412b5ea29685f4fa260d8eb44baae095fb81 (patch)
tree0e859ab0541187ed769e654663730834b998f3d1 /animism-align
parent3e1c6f81bbdad758b8756955fce82da49a564611 (diff)
rename timestamp to annotation
Diffstat (limited to 'animism-align')
-rw-r--r--animism-align/cli/app/controllers/__pycache__/crud_controller.cpython-37.pycbin3968 -> 4047 bytes
-rw-r--r--animism-align/cli/app/controllers/annotation_controller.py (renamed from animism-align/cli/app/controllers/timestamp_controller.py)10
-rw-r--r--animism-align/cli/app/controllers/paragraph_controller.py18
-rw-r--r--animism-align/cli/app/server/web.py4
-rw-r--r--animism-align/cli/app/sql/__pycache__/common.cpython-37.pycbin910 -> 0 bytes
-rw-r--r--animism-align/cli/app/sql/__pycache__/env.cpython-37.pycbin1701 -> 0 bytes
-rw-r--r--animism-align/cli/app/sql/common.py2
-rw-r--r--animism-align/cli/app/sql/env.py2
-rw-r--r--animism-align/cli/app/sql/models/annotation.py (renamed from animism-align/cli/app/sql/models/timestamp.py)10
-rw-r--r--animism-align/cli/app/sql/versions/202007041633_create_database.py (renamed from animism-align/cli/app/sql/versions/202006271347_add_paragraphs.py)14
-rw-r--r--animism-align/frontend/actions.js9
-rw-r--r--animism-align/frontend/api/index.js6
-rw-r--r--animism-align/frontend/store.js5
-rw-r--r--animism-align/frontend/types.js4
-rw-r--r--animism-align/frontend/views/align/align.actions.js11
-rw-r--r--animism-align/frontend/views/align/align.reducer.js21
-rw-r--r--animism-align/frontend/views/align/components/annotations/annotation.form.js95
-rw-r--r--animism-align/frontend/views/align/containers/timeline.container.js2
-rw-r--r--animism-align/frontend/views/annotation/annotation.reducer.js (renamed from animism-align/frontend/views/timestamp/timestamp.reducer.js)6
-rw-r--r--animism-align/frontend/views/timestamp/components/timestamp.form.js153
-rw-r--r--animism-align/frontend/views/timestamp/containers/timestamp.edit.js53
-rw-r--r--animism-align/frontend/views/timestamp/containers/timestamp.index.js53
-rw-r--r--animism-align/frontend/views/timestamp/containers/timestamp.new.js44
23 files changed, 132 insertions, 390 deletions
diff --git a/animism-align/cli/app/controllers/__pycache__/crud_controller.cpython-37.pyc b/animism-align/cli/app/controllers/__pycache__/crud_controller.cpython-37.pyc
index 7f7d98d..e28baa6 100644
--- a/animism-align/cli/app/controllers/__pycache__/crud_controller.cpython-37.pyc
+++ b/animism-align/cli/app/controllers/__pycache__/crud_controller.cpython-37.pyc
Binary files differ
diff --git a/animism-align/cli/app/controllers/timestamp_controller.py b/animism-align/cli/app/controllers/annotation_controller.py
index d4cef82..8d91d1c 100644
--- a/animism-align/cli/app/controllers/timestamp_controller.py
+++ b/animism-align/cli/app/controllers/annotation_controller.py
@@ -3,14 +3,12 @@ from flask_classful import route
from werkzeug.datastructures import MultiDict
from app.sql.common import db, Session
-from app.sql.models.graph import Timestamp, TimestampForm
-from app.sql.models.page import Page
-from app.sql.models.tile import Tile
+from app.sql.models.annotation import Annotation, AnnotationForm
from app.controllers.crud_controller import CrudView
-class TimestampView(CrudView):
- model = Timestamp
- form = TimestampForm
+class AnnotationView(CrudView):
+ model = Annotation
+ form = AnnotationForm
default_sort = "start_ts"
def on_create(self, session, form, item):
diff --git a/animism-align/cli/app/controllers/paragraph_controller.py b/animism-align/cli/app/controllers/paragraph_controller.py
new file mode 100644
index 0000000..8056f51
--- /dev/null
+++ b/animism-align/cli/app/controllers/paragraph_controller.py
@@ -0,0 +1,18 @@
+from flask import request, jsonify, redirect
+from flask_classful import route
+from werkzeug.datastructures import MultiDict
+
+from app.sql.common import db, Session
+from app.sql.models.paragraph import Paragraph, ParagraphForm
+from app.controllers.crud_controller import CrudView
+
+class ParagraphView(CrudView):
+ model = Paragraph
+ form = ParagraphForm
+ default_sort = "start_ts"
+
+ def on_create(self, session, form, item):
+ item.settings = form['settings']
+
+ def on_update(self, session, form, item):
+ item.settings = form['settings']
diff --git a/animism-align/cli/app/server/web.py b/animism-align/cli/app/server/web.py
index c3a812a..8c7bbc2 100644
--- a/animism-align/cli/app/server/web.py
+++ b/animism-align/cli/app/server/web.py
@@ -16,6 +16,8 @@ from flask import Flask, Blueprint, send_from_directory, request
from app.sql.common import db, connection_url
from app.settings import app_cfg
+from app.controllers.annotation_controller import AnnotationView
+from app.controllers.paragraph_controller import ParagraphView
from app.controllers.upload_controller import UploadView
def create_app(script_info=None):
@@ -32,6 +34,8 @@ def create_app(script_info=None):
db.init_app(app)
+ AnnotationView.register(app, route_prefix='/api/v1/')
+ ParagraphView.register(app, route_prefix='/api/v1/')
UploadView.register(app, route_prefix='/api/v1/')
index_html = 'index.html'
diff --git a/animism-align/cli/app/sql/__pycache__/common.cpython-37.pyc b/animism-align/cli/app/sql/__pycache__/common.cpython-37.pyc
deleted file mode 100644
index f995f96..0000000
--- a/animism-align/cli/app/sql/__pycache__/common.cpython-37.pyc
+++ /dev/null
Binary files differ
diff --git a/animism-align/cli/app/sql/__pycache__/env.cpython-37.pyc b/animism-align/cli/app/sql/__pycache__/env.cpython-37.pyc
deleted file mode 100644
index 96f3d85..0000000
--- a/animism-align/cli/app/sql/__pycache__/env.cpython-37.pyc
+++ /dev/null
Binary files differ
diff --git a/animism-align/cli/app/sql/common.py b/animism-align/cli/app/sql/common.py
index d79bc06..f291daa 100644
--- a/animism-align/cli/app/sql/common.py
+++ b/animism-align/cli/app/sql/common.py
@@ -31,6 +31,6 @@ Base.metadata.bind = engine
db = SQLAlchemy()
# include the models in reverse dependency order, so relationships work
-from app.sql.models.timestamp import Timestamp
+from app.sql.models.annotation import Annotation
from app.sql.models.paragraph import Paragraph
from app.sql.models.upload import Upload
diff --git a/animism-align/cli/app/sql/env.py b/animism-align/cli/app/sql/env.py
index af21e0e..0defa88 100644
--- a/animism-align/cli/app/sql/env.py
+++ b/animism-align/cli/app/sql/env.py
@@ -14,7 +14,7 @@ config.set_main_option("sqlalchemy.url", connection_url)
target_metadata = Base.metadata
# include the models in reverse dependency order, so relationships work
-from app.sql.models.timestamp import Timestamp
+from app.sql.models.annotation import Annotation
from app.sql.models.paragraph import Paragraph
from app.sql.models.upload import Upload
diff --git a/animism-align/cli/app/sql/models/timestamp.py b/animism-align/cli/app/sql/models/annotation.py
index c2bf410..6cc476c 100644
--- a/animism-align/cli/app/sql/models/timestamp.py
+++ b/animism-align/cli/app/sql/models/annotation.py
@@ -9,15 +9,15 @@ from app.sql.common import db, Base, Session
from app.settings import app_cfg
-class Timestamp(Base):
+class Annotation(Base):
"""Table for storing references to graphs"""
- __tablename__ = 'timestamp'
+ __tablename__ = 'annotation'
id = Column(Integer, primary_key=True)
type = Column(String(16, convert_unicode=True), nullable=False)
paragraph_id = Column(Integer, ForeignKey('paragraph.id'), nullable=True)
start_ts = Column(Float, nullable=False)
end_ts = Column(Float, nullable=True)
- sentence = Column(Text(convert_unicode=True), nullable=True)
+ text = Column(Text(convert_unicode=True), nullable=True)
settings = Column(JSON, default={}, nullable=True)
def toJSON(self):
@@ -31,9 +31,9 @@ class Timestamp(Base):
'settings': self.settings,
}
-class TimestampForm(ModelForm):
+class AnnotationForm(ModelForm):
class Meta:
- model = Timestamp
+ model = Annotation
exclude = ['settings']
def get_session():
return Session()
diff --git a/animism-align/cli/app/sql/versions/202006271347_add_paragraphs.py b/animism-align/cli/app/sql/versions/202007041633_create_database.py
index cc134b5..f8336e5 100644
--- a/animism-align/cli/app/sql/versions/202006271347_add_paragraphs.py
+++ b/animism-align/cli/app/sql/versions/202007041633_create_database.py
@@ -1,8 +1,8 @@
-"""add paragraphs
+"""create database
-Revision ID: 650f7cdb3174
+Revision ID: f8936a84e584
Revises:
-Create Date: 2020-06-27 13:47:33.766574
+Create Date: 2020-07-04 16:33:01.643193
"""
from alembic import op
@@ -11,7 +11,7 @@ import sqlalchemy_utc
# revision identifiers, used by Alembic.
-revision = '650f7cdb3174'
+revision = 'f8936a84e584'
down_revision = None
branch_labels = None
depends_on = None
@@ -34,13 +34,13 @@ def upgrade():
sa.Column('created_at', sqlalchemy_utc.sqltypes.UtcDateTime(timezone=True), nullable=True),
sa.PrimaryKeyConstraint('id')
)
- op.create_table('timestamp',
+ op.create_table('annotation',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('type', sa.String(length=16, _expect_unicode=True), nullable=False),
sa.Column('paragraph_id', sa.Integer(), nullable=True),
sa.Column('start_ts', sa.Float(), nullable=False),
sa.Column('end_ts', sa.Float(), nullable=True),
- sa.Column('sentence', sa.Text(_expect_unicode=True), nullable=True),
+ sa.Column('text', sa.Text(_expect_unicode=True), nullable=True),
sa.Column('settings', sa.JSON(), nullable=True),
sa.ForeignKeyConstraint(['paragraph_id'], ['paragraph.id'], ),
sa.PrimaryKeyConstraint('id')
@@ -50,7 +50,7 @@ def upgrade():
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
- op.drop_table('timestamp')
+ op.drop_table('annotation')
op.drop_table('upload')
op.drop_table('paragraph')
# ### end Alembic commands ###
diff --git a/animism-align/frontend/actions.js b/animism-align/frontend/actions.js
index 1b5f15e..4153296 100644
--- a/animism-align/frontend/actions.js
+++ b/animism-align/frontend/actions.js
@@ -1,5 +1,6 @@
import { bindActionCreators } from 'redux'
-import { actions as crudActions } from './api'
+// import { actions as crudActions } from './api'
+import { crud_actions } from './api/crud.actions'
import * as audioActions from './views/audio/audio.actions'
import * as alignActions from './views/align/align.actions'
@@ -7,6 +8,12 @@ import * as siteActions from './views/site/site.actions'
import { store } from './store'
+const crudActions = [
+ 'paragraph',
+ 'annotation',
+ 'upload',
+].reduce((a,b) => (a[b] = crud_actions(b)) && a, {})
+
export default
Object.keys(crudActions)
.map(a => [a, crudActions[a]])
diff --git a/animism-align/frontend/api/index.js b/animism-align/frontend/api/index.js
index 96c4e5c..05f6b8b 100644
--- a/animism-align/frontend/api/index.js
+++ b/animism-align/frontend/api/index.js
@@ -15,9 +15,3 @@ so you can do ...
*/
export { util }
-
-export const actions = [
- 'paragraph',
- 'timestamp',
- 'upload',
-].reduce((a,b) => (a[b] = crud_actions(b)) && a, {})
diff --git a/animism-align/frontend/store.js b/animism-align/frontend/store.js
index accf1b1..24542ff 100644
--- a/animism-align/frontend/store.js
+++ b/animism-align/frontend/store.js
@@ -9,7 +9,7 @@ import uploadReducer from './views/upload/upload.reducer'
import alignReducer from './views/align/align.reducer'
import audioReducer from './views/audio/audio.reducer'
import paragraphReducer from './views/paragraph/paragraph.reducer'
-import timestampReducer from './views/timestamp/timestamp.reducer'
+import annotationReducer from './views/annotation/annotation.reducer'
import siteReducer from './views/site/site.reducer'
// import collectionReducer from './views/collection/collection.reducer'
@@ -22,8 +22,7 @@ const createRootReducer = history => (
align: alignReducer,
audio: audioReducer,
paragraph: paragraphReducer,
- timestamp: timestampReducer,
- // collection: collectionReducer,
+ annotation: annotationReducer,
})
)
diff --git a/animism-align/frontend/types.js b/animism-align/frontend/types.js
index d888a0a..45c9caf 100644
--- a/animism-align/frontend/types.js
+++ b/animism-align/frontend/types.js
@@ -5,11 +5,13 @@ export const api = crud_type('api', [])
export const upload = crud_type('upload', [])
export const peaks = crud_type('peaks', [])
export const text = crud_type('text', [])
-export const timestamp = crud_type('timestamp', [])
+export const annotation = crud_type('annotation', [])
export const paragraph = crud_type('paragraph', [])
export const align = crud_type('align', [
'set_display_setting',
'set_temporary_annotation',
+ 'update_temporary_annotation',
+ 'update_temporary_annotation_settings',
])
export const audio = with_type('audio', [
diff --git a/animism-align/frontend/views/align/align.actions.js b/animism-align/frontend/views/align/align.actions.js
index 82e4799..b3883ae 100644
--- a/animism-align/frontend/views/align/align.actions.js
+++ b/animism-align/frontend/views/align/align.actions.js
@@ -25,7 +25,7 @@ export const setCursor = cursor_ts => dispatch => (
dispatch({ type: types.align.set_display_setting, key: 'cursor_ts', value: cursor_ts })
)
-export const showNewTimestampForm = (start_ts, text) => dispatch => {
+export const showNewAnnotationForm = (start_ts, text) => dispatch => {
let croppedText;
if (store.getState().align.annotation.start_ts) {
croppedText = store.getState().align.annotation.text
@@ -44,6 +44,13 @@ export const showNewTimestampForm = (start_ts, text) => dispatch => {
})
}
+export const updateAnnotationForm = (key, value) => dispatch => {
+ dispatch({ type: types.align.update_temporary_annotation, key, value })
+}
+export const updateAnnotationSettings = (key, value) => dispatch => {
+ dispatch({ type: types.align.update_temporary_annotation_settings, key, value })
+}
+
const cutFirstSentence = text => {
const textToCrop = text.trim().replace("\n", " ").split("\n")[0]
let cropIndex = textToCrop.indexOf('. ') + 1
@@ -54,7 +61,7 @@ const cutFirstSentence = text => {
return croppedText
}
-export const hideTimestampForm = () => dispatch => {
+export const hideAnnotationForm = () => dispatch => {
dispatch({
type: types.align.set_temporary_annotation,
data: {}
diff --git a/animism-align/frontend/views/align/align.reducer.js b/animism-align/frontend/views/align/align.reducer.js
index 9064b56..f080c24 100644
--- a/animism-align/frontend/views/align/align.reducer.js
+++ b/animism-align/frontend/views/align/align.reducer.js
@@ -41,6 +41,27 @@ export default function alignReducer(state = initialState, action) {
annotation: action.data,
}
+ case types.align.update_temporary_annotation:
+ return {
+ ...state,
+ annotation: {
+ ...state.annotation,
+ [action.key]: action.value,
+ }
+ }
+
+ case types.align.update_temporary_annotation_settings:
+ return {
+ ...state,
+ annotation: {
+ ...state.annotation,
+ settings: {
+ ...state.annotation.settings,
+ [action.key]: action.value,
+ }
+ }
+ }
+
default:
return state
}
diff --git a/animism-align/frontend/views/align/components/annotations/annotation.form.js b/animism-align/frontend/views/align/components/annotations/annotation.form.js
index 03e44e1..9432948 100644
--- a/animism-align/frontend/views/align/components/annotations/annotation.form.js
+++ b/animism-align/frontend/views/align/components/annotations/annotation.form.js
@@ -11,36 +11,42 @@ import { clamp } from '../../../../util'
import { timeToPosition } from '../../align.util'
import { Select } from '../../../../common'
-const TIMESTAMP_TYPES = ['sentence', 'header'].map(name => ({ name, label: name }))
+const ANNOTATION_TYPES = [
+ 'sentence', 'header'
+].map(name => ({ name, label: name }))
class AnnotationForm extends Component {
- state = {
- data: {},
- }
constructor(props){
super(props)
this.handleChange = this.handleChange.bind(this)
this.handleSelect = this.handleSelect.bind(this)
this.handleKeyDown = this.handleKeyDown.bind(this)
- }
- componentDidMount(){
- this.setState({
- data: { ...this.props.annotation },
- })
- }
- componentDidUpdate(prevProps){
- if (this.props.annotation !== prevProps.annotation) {
- this.setState({
- data: {
- ...this.props.annotation,
- text: this.state.data.text,
- type: this.state.data.text,
- },
- })
- }
+ this.handleSubmit = this.handleSubmit.bind(this)
}
handleKeyDown(e) {
+ if (!e.metaKey && !e.ctrlKey) return
+ let { start_ts } = this.props.annotation
+ console.log(e.keyCode)
switch (e.keyCode) {
+ case 38: // up
+ e.preventDefault()
+ start_ts -= 0.1
+ actions.align.updateAnnotationForm('start_ts', start_ts)
+ actions.audio.seek(start_ts)
+ actions.align.setCursor(start_ts)
+ break
+ case 40: // down
+ e.preventDefault()
+ start_ts += 0.1
+ actions.align.updateAnnotationForm('start_ts', start_ts)
+ actions.audio.seek(start_ts)
+ actions.align.setCursor(start_ts)
+ break
+ case 83: // ctrl-S
+ e.preventDefault()
+ this.handleSubmit()
+ default:
+ break
}
}
handleChange(e) {
@@ -48,62 +54,57 @@ class AnnotationForm extends Component {
this.handleSelect(name, value)
}
handleSelect(name, value) {
- this.setState({
- data: {
- ...this.state.data,
- [name]: value,
- }
- })
+ actions.align.updateAnnotationForm(name, value)
}
handleSubmit() {
- const { data } = this.state
- if (data.id === 'new') {
- delete data.id
- actions.graph.create(data)
+ const { annotation } = this.props
+ if (annotation.id === 'new') {
+ delete annotation.id
+ actions.annotation.create(annotation)
.then(response => {
console.log(response)
- actions.align.hideTimestampForm()
+ actions.align.hideAnnotationForm()
})
} else {
- actions.graph.update(data)
+ actions.annotation.update(annotation)
.then(response => {
console.log(response)
- actions.align.hideTimestampForm()
+ actions.align.hideAnnotationForm()
})
}
}
render() {
- const { timeline } = this.props
- const { data } = this.state
- if (!data.start_ts) return <div></div>
+ const { timeline, annotation } = this.props
+ if (!annotation.start_ts) return <div></div>
return (
<div
className='annotationForm'
style={{
- top: timeToPosition(data.start_ts, timeline),
+ top: timeToPosition(annotation.start_ts, timeline),
}}
>
- {data.type === 'sentence' && this.renderTextarea()}
- {data.type === 'header' && this.renderTextarea()}
+ {annotation.type === 'sentence' && this.renderTextarea()}
+ {annotation.type === 'header' && this.renderTextarea()}
<div className='row'>
<Select
name='type'
- selected={data.type}
- options={TIMESTAMP_TYPES}
+ selected={annotation.type}
+ options={ANNOTATION_TYPES}
defaultOption='text'
onChange={this.handleSelect}
/>
- <button>Save</button>
+ <button onClick={this.handleSubmit}>Save</button>
</div>
</div>
)
}
renderTextarea() {
- const { data } = this.state
+ const { annotation } = this.props
return (
<div>
<textarea
- value={data.text}
+ name='text'
+ value={annotation.text}
onKeyDown={this.handleKeyDown}
onChange={this.handleChange}
/>
@@ -112,12 +113,6 @@ class AnnotationForm extends Component {
}
}
-
-/*
-- get the first sentence from the text
-- display the form at that point
-*/
-
const mapStateToProps = state => ({
annotation: state.align.annotation,
timeline: state.align.timeline,
diff --git a/animism-align/frontend/views/align/containers/timeline.container.js b/animism-align/frontend/views/align/containers/timeline.container.js
index 3795751..4167d2d 100644
--- a/animism-align/frontend/views/align/containers/timeline.container.js
+++ b/animism-align/frontend/views/align/containers/timeline.container.js
@@ -91,7 +91,7 @@ class Timeline extends Component {
handleClick(e) {
const play_ts = positionToTime(e.pageY, this.props.timeline)
if (e.pageX > WAVEFORM_SIZE * 0.67) {
- actions.align.showNewTimestampForm(play_ts, this.props.text)
+ actions.align.showNewAnnotationForm(play_ts, this.props.text)
} else {
actions.audio.seek(play_ts)
}
diff --git a/animism-align/frontend/views/timestamp/timestamp.reducer.js b/animism-align/frontend/views/annotation/annotation.reducer.js
index e57110e..80be5b2 100644
--- a/animism-align/frontend/views/timestamp/timestamp.reducer.js
+++ b/animism-align/frontend/views/annotation/annotation.reducer.js
@@ -3,15 +3,15 @@ import { session, getDefault, getDefaultInt } from '../../session'
import { crudState, crudReducer } from '../../api/crud.reducer'
-const initialState = crudState('timestamp', {
+const initialState = crudState('annotation', {
options: {
sort: 'start_ts desc',
}
})
-const reducer = crudReducer('timestamp')
+const reducer = crudReducer('annotation')
-export default function timestampReducer(state = initialState, action) {
+export default function annotationReducer(state = initialState, action) {
// console.log(action.type, action)
state = reducer(state, action)
switch (action.type) {
diff --git a/animism-align/frontend/views/timestamp/components/timestamp.form.js b/animism-align/frontend/views/timestamp/components/timestamp.form.js
deleted file mode 100644
index d90b663..0000000
--- a/animism-align/frontend/views/timestamp/components/timestamp.form.js
+++ /dev/null
@@ -1,153 +0,0 @@
-import React, { Component } from 'react'
-import { Link } from 'react-router-dom'
-
-import { session } from '../../../session'
-
-import { TextInput, LabelDescription, TextArea, Checkbox, SubmitButton, Loader } from '../../../common'
-
-const newGraph = () => ({
- path: '',
- title: '',
- username: session('username'),
- description: '',
-})
-
-export default class GraphForm extends Component {
- state = {
- title: "",
- submitTitle: "",
- data: { ...newGraph() },
- errorFields: new Set([]),
- }
-
- componentDidMount() {
- const { data, isNew } = this.props
- const title = isNew ? 'new project' : 'editing ' + data.title
- const submitTitle = isNew ? "Create Graph" : "Save Changes"
- this.setState({
- title,
- submitTitle,
- errorFields: new Set([]),
- data: {
- ...newGraph(),
- ...data
- },
- })
- }
-
- handleChange(e) {
- const { errorFields } = this.state
- const { name, value } = e.target
- if (errorFields.has(name)) {
- errorFields.delete(name)
- }
- let sanitizedValue = value
- if (name === 'path') {
- sanitizedValue = sanitizedValue.toLowerCase().replace(/ /, '-').replace(/[!@#$%^&*()[\]{}]/, '-').replace(/-+/, '-')
- }
- this.setState({
- errorFields,
- data: {
- ...this.state.data,
- [name]: sanitizedValue,
- }
- })
- }
-
- handleSelect(name, value) {
- const { errorFields } = this.state
- if (errorFields.has(name)) {
- errorFields.delete(name)
- }
- this.setState({
- errorFields,
- data: {
- ...this.state.data,
- [name]: value,
- }
- })
- }
-
- handleSubmit(e) {
- e.preventDefault()
- const { isNew, onSubmit } = this.props
- const { data } = this.state
- const requiredKeys = "title username path description".split(" ")
- const validKeys = "title username path description".split(" ")
- const validData = validKeys.reduce((a,b) => { a[b] = data[b]; return a }, {})
- const errorFields = requiredKeys.filter(key => !validData[key])
- if (errorFields.length) {
- console.log('error', errorFields, validData)
- this.setState({ errorFields: new Set(errorFields) })
- } else {
- if (isNew) {
- // side effect: set username if we're creating a new graph
- session.set('username', data.username)
- } else {
- validData.id = data.id
- }
- console.log('submit', validData)
- onSubmit(validData)
- }
- }
-
- render() {
- const { isNew } = this.props
- const { title, submitTitle, errorFields, data } = this.state
- return (
- <div className='form'>
- <h1>{title}</h1>
- <form onSubmit={this.handleSubmit.bind(this)}>
- <TextInput
- title="Path"
- name="path"
- required
- data={data}
- error={errorFields.has('path')}
- onChange={this.handleChange.bind(this)}
- autoComplete="off"
- />
- <LabelDescription>
- {data.path
- ? 'Project URLs will be: /' + data.path + '/example'
- : 'Enter the base path for this project.'}
- </LabelDescription>
- <TextInput
- title="Title"
- name="title"
- required
- data={data}
- error={errorFields.has('title')}
- onChange={this.handleChange.bind(this)}
- autoComplete="off"
- />
- <TextInput
- title="Author"
- name="username"
- required
- data={data}
- error={errorFields.has('username')}
- onChange={this.handleChange.bind(this)}
- autoComplete="off"
- />
- <TextArea
- title="Description"
- name="description"
- data={data}
- onChange={this.handleChange.bind(this)}
- />
- <SubmitButton
- title={submitTitle}
- onClick={this.handleSubmit.bind(this)}
- />
- {!!errorFields.size &&
- <label>
- <span></span>
- <span>Please complete the required fields =)</span>
- </label>
- }
- </form>
- </div>
- )
- }
-}
diff --git a/animism-align/frontend/views/timestamp/containers/timestamp.edit.js b/animism-align/frontend/views/timestamp/containers/timestamp.edit.js
deleted file mode 100644
index ce1b404..0000000
--- a/animism-align/frontend/views/timestamp/containers/timestamp.edit.js
+++ /dev/null
@@ -1,53 +0,0 @@
-import React, { Component } from 'react'
-import { Link } from 'react-router-dom'
-import { connect } from 'react-redux'
-
-import { history } from '../../../store'
-import actions from '../../../actions'
-
-import { Loader } from '../../../common'
-
-import GraphForm from '../components/graph.form'
-
-class GraphEdit extends Component {
- componentDidMount() {
- console.log(this.props.match.params.id)
- actions.graph.show(this.props.match.params.id)
- }
-
- handleSubmit(data) {
- actions.graph.update(data)
- .then(response => {
- // response
- console.log(response)
- history.push('/' + data.path)
- })
- }
-
- render() {
- const { show } = this.props.graph
- if (show.loading || !show.res) {
- return (
- <div className='form'>
- <Loader />
- </div>
- )
- }
- return (
- <GraphForm
- data={show.res}
- onSubmit={this.handleSubmit.bind(this)}
- />
- )
- }
-}
-
-const mapStateToProps = state => ({
- graph: state.graph,
-})
-
-const mapDispatchToProps = dispatch => ({
- // searchActions: bindActionCreators({ ...searchActions }, dispatch),
-})
-
-export default connect(mapStateToProps, mapDispatchToProps)(GraphEdit)
diff --git a/animism-align/frontend/views/timestamp/containers/timestamp.index.js b/animism-align/frontend/views/timestamp/containers/timestamp.index.js
deleted file mode 100644
index 6d0cdd5..0000000
--- a/animism-align/frontend/views/timestamp/containers/timestamp.index.js
+++ /dev/null
@@ -1,53 +0,0 @@
-import React, { Component } from 'react'
-import { Link } from 'react-router-dom'
-import { bindActionCreators } from 'redux'
-import { connect } from 'react-redux'
-
-import { Loader } from '../../../common'
-import actions from '../../../actions'
-// import * as uploadActions from './upload.actions'
-
-class GraphIndex extends Component {
- componentDidMount() {
- actions.graph.index()
- }
- render() {
- const { index } = this.props
- // console.log(this.props)
- if (!index.order) {
- return (
- <div className='graphIndex'>
- <Loader />
- </div>
- )
- }
- // console.log(state)
- return (
- <div className='graphIndex'>
- <div>
- <b>welcome, swimmer</b>
- <Link to='/index/new'>+ new project</Link>
- </div>
- {index.order.map(id => {
- const graph = index.lookup[id]
- return (
- <div key={id}>
- <Link to={'/' + graph.path}>{graph.title}</Link>
- <Link to={'/index/' + id + '/edit'}>{'edit project'}</Link>
- </div>
- )
- })}
- </div>
- )
- }
-}
-
-const mapStateToProps = state => ({
- index: state.graph.index,
-})
-
-const mapDispatchToProps = dispatch => ({
- // uploadActions: bindActionCreators({ ...uploadActions }, dispatch),
-})
-
-export default connect(mapStateToProps, mapDispatchToProps)(GraphIndex)
diff --git a/animism-align/frontend/views/timestamp/containers/timestamp.new.js b/animism-align/frontend/views/timestamp/containers/timestamp.new.js
deleted file mode 100644
index be96bf5..0000000
--- a/animism-align/frontend/views/timestamp/containers/timestamp.new.js
+++ /dev/null
@@ -1,44 +0,0 @@
-import React, { Component } from 'react'
-import { Link } from 'react-router-dom'
-import { connect } from 'react-redux'
-
-import { history } from '../../../store'
-import actions from '../../../actions'
-
-import GraphForm from '../components/graph.form'
-
-class GraphNew extends Component {
- handleSubmit(data) {
- console.log(data)
- actions.graph.create(data)
- .then(res => {
- console.log(res)
- if (res.res && res.res.id) {
- history.push('/' + res.res.path)
- }
- })
- .catch(err => {
- console.error('error')
- })
- }
-
- render() {
- return (
- <GraphForm
- isNew
- data={{}}
- onSubmit={this.handleSubmit.bind(this)}
- />
- )
- }
-}
-
-const mapStateToProps = state => ({
- graph: state.graph,
-})
-
-const mapDispatchToProps = dispatch => ({
- // searchActions: bindActionCreators({ ...searchActions }, dispatch),
-})
-
-export default connect(mapStateToProps, mapDispatchToProps)(GraphNew)