summaryrefslogtreecommitdiff
path: root/frontend/views/graph
diff options
context:
space:
mode:
authorJules Laplace <julescarbon@gmail.com>2020-09-26 14:56:02 +0200
committerJules Laplace <julescarbon@gmail.com>2020-09-26 14:56:02 +0200
commita17b76ac75f506f5da6fe8adf9c36632b60d4226 (patch)
treeabb0af0c4409b830dea2ef808c146223ee973933 /frontend/views/graph
parent2231a6e1c05b07bb7ec5906716aedec93d02429c (diff)
refactor to use app-rooted js imports
Diffstat (limited to 'frontend/views/graph')
-rw-r--r--frontend/views/graph/components/graph.canvas.js138
-rw-r--r--frontend/views/graph/components/graph.editor.js212
-rw-r--r--frontend/views/graph/components/graph.header.js31
-rw-r--r--frontend/views/graph/components/page.edit.js65
-rw-r--r--frontend/views/graph/components/page.form.js185
-rw-r--r--frontend/views/graph/components/page.handle.js59
-rw-r--r--frontend/views/graph/components/page.new.js47
-rw-r--r--frontend/views/graph/graph.actions.js37
-rw-r--r--frontend/views/graph/graph.container.js82
-rw-r--r--frontend/views/graph/graph.css172
-rw-r--r--frontend/views/graph/graph.reducer.js100
11 files changed, 0 insertions, 1128 deletions
diff --git a/frontend/views/graph/components/graph.canvas.js b/frontend/views/graph/components/graph.canvas.js
deleted file mode 100644
index d10de4f..0000000
--- a/frontend/views/graph/components/graph.canvas.js
+++ /dev/null
@@ -1,138 +0,0 @@
-import React, { Component } from 'react'
-
-import { mod, angle } from '../../../util'
-
-const DEFAULT_MEASUREMENT = { width: 16, height: 16 }
-const BACKLINK_SPACING = 10
-const ARROWHEAD_LENGTH = 10
-const GRAPH_LINK_COLOR = "#ff88ff"
-const GRAPH_BACKLINK_COLOR = "#88ffff"
-const GRAPH_UNHOVER_LINK_COLOR = "#884488"
-const GRAPH_UNHOVER_BACKLINK_COLOR = "#448888"
-
-export default class GraphCanvas extends Component {
- constructor(props) {
- super(props)
- this.canvasRef = React.createRef()
- }
-
- componentDidMount() {
- if (this.props.bounds) {
- this.draw({})
- }
- }
-
- componentDidUpdate(prevProps) {
- this.draw(prevProps)
- }
-
- draw(prevProps) {
- const { current: canvas } = this.canvasRef
- const { bounds, pages, currentPage, box, measurements, highlightedPageId } = this.props
- const { width, height } = bounds
- if (prevProps.bounds !== bounds) {
- canvas.width = width
- canvas.height = height
- }
- const ctx = canvas.getContext('2d')
- ctx.clearRect(0, 0, width, height)
- ctx.lineWidth = 2
- const coordsLookup = pages.reduce((a,b) => {
- if (currentPage && box && b.id === currentPage.id) {
- a[b.id] = {
- x: box.x,
- y: box.y,
- backlinks: new Set([]),
- }
- } else {
- a[b.id] = {
- x: b.settings.x,
- y: b.settings.y,
- backlinks: new Set([]),
- }
- }
- return a
- }, {})
- pages.map(page => {
- const sourceCoord = coordsLookup[page.id]
- page.backlinks.map(tile => {
- if (tile.target_page_id <= 0) return
- const targetCoord = coordsLookup[tile.page_id]
- const isHighlightedPage = !highlightedPageId || highlightedPageId === page.id || highlightedPageId === tile.page_id
- let tile_measurement = measurements[tile.page_id] || DEFAULT_MEASUREMENT
- let target_measurement = measurements[tile.target_page_id] || DEFAULT_MEASUREMENT
- let theta = angle(targetCoord.x, targetCoord.y, sourceCoord.x, sourceCoord.y)
- let x1_offset = tile_measurement.width / 2 // * (0.5 - Math.cos(theta))
- let y1_offset = tile_measurement.height / 2
- let x2_offset = target_measurement.width / 2 // (0.5 - Math.cos(theta))
- let y2_offset = target_measurement.height / 2
- // skip duplicate links
- if (sourceCoord.backlinks.has(tile.page_id)) {
- return
- }
- /*
- if it's pointing right, cos(t) is 1
- if it's pointing left, cos(t) is -1
- */
- // if (Math.abs(Math.cos(theta)) > 0.5) {
- // x1_offset += target_measurement.width / 3 * (- Math.cos(theta))
- // x1_offset += target_measurement.height / 4 * (- Math.sin(theta))
- x2_offset += target_measurement.width / 3 * (- Math.cos(theta))
- y2_offset += target_measurement.height / 6 * (- Math.sin(theta))
- // }
- // if this is the first time encountering this link...
- if (!targetCoord.backlinks.has(tile.target_page_id)) {
- sourceCoord.backlinks.add(tile.page_id)
- ctx.strokeStyle = isHighlightedPage
- ? GRAPH_LINK_COLOR
- : GRAPH_UNHOVER_LINK_COLOR
- } else { // otherwise this is a two-way link
- x1_offset += BACKLINK_SPACING * Math.sin(theta)
- y1_offset += BACKLINK_SPACING * Math.cos(theta)
- x2_offset += BACKLINK_SPACING * Math.sin(theta)
- y2_offset += BACKLINK_SPACING * Math.cos(theta)
- // x1_offset += BACKLINK_SPACING * Math.cos(theta + Math.PI /2)
- // y1_offset += BACKLINK_SPACING * Math.sin(theta + Math.PI /2)
- // x2_offset += BACKLINK_SPACING * Math.cos(theta + Math.PI /2)
- // y2_offset += BACKLINK_SPACING * Math.sin(theta + Math.PI /2)
- ctx.strokeStyle = isHighlightedPage
- ? GRAPH_BACKLINK_COLOR
- : GRAPH_UNHOVER_BACKLINK_COLOR
- }
- ctx.beginPath()
- const x1 = targetCoord.x * width + x1_offset
- const y1 = targetCoord.y * height + y1_offset
- const x2 = sourceCoord.x * width + x2_offset
- const y2 = sourceCoord.y * height + y2_offset
- this.arrow(ctx, x1, y1, x2, y2)
- ctx.stroke()
- })
- })
- }
-
- arrow(ctx, x1, y1, x2, y2) {
- const farOffset = 20
- const endOffset = 1
- const theta = angle(x1, y1, x2, y2)
- x1 += Math.cos(theta) * 0
- x2 -= Math.cos(theta) * farOffset
- y1 += Math.sin(theta) * 0
- y2 -= Math.sin(theta) * farOffset
- const xEnd = x2 - Math.cos(theta) * endOffset
- const yEnd = y2 - Math.sin(theta) * endOffset
- const leftAngle = mod(theta - Math.PI / 6, Math.PI * 2)
- const rightAngle = mod(theta + Math.PI / 6, Math.PI * 2)
- ctx.moveTo(x1, y1)
- ctx.lineTo(xEnd, yEnd)
- ctx.moveTo(x2, y2)
- ctx.lineTo(x2 - ARROWHEAD_LENGTH * Math.cos(leftAngle), y2 - ARROWHEAD_LENGTH * Math.sin(leftAngle))
- ctx.moveTo(x2, y2)
- ctx.lineTo(x2 - ARROWHEAD_LENGTH * Math.cos(rightAngle), y2 - ARROWHEAD_LENGTH * Math.sin(rightAngle))
- }
-
- render() {
- return (
- <canvas ref={this.canvasRef} />
- )
- }
-}
diff --git a/frontend/views/graph/components/graph.editor.js b/frontend/views/graph/components/graph.editor.js
deleted file mode 100644
index f0a5753..0000000
--- a/frontend/views/graph/components/graph.editor.js
+++ /dev/null
@@ -1,212 +0,0 @@
-import React, { Component } from 'react'
-import { Route, Link } from 'react-router-dom'
-import { bindActionCreators } from 'redux'
-import { connect } from 'react-redux'
-
-import { session } from '../../../session'
-import actions from '../../../actions'
-import * as graphActions from '../graph.actions'
-
-import { Loader } from '../../../common'
-import { clamp, dist, mod, angle } from '../../../util'
-
-import GraphCanvas from './graph.canvas'
-import PageHandle from './page.handle'
-
-const defaultState = {
- dragging: false,
- bounds: null,
- mouseX: 0,
- mouseY: 0,
- box: {
- x: 0, y: 0,
- w: 0, h: 0,
- },
- page: null,
- highlightedPageId: null,
- measurements: {},
-}
-
-class GraphEditor extends Component {
- state = {
- ...defaultState,
- }
-
- constructor() {
- super()
- // bind these events in the constructor, so we can remove event listeners later
- this.handleMouseDown = this.handleMouseDown.bind(this)
- this.handleMouseMove = this.handleMouseMove.bind(this)
- this.handleMouseUp = this.handleMouseUp.bind(this)
- this.handleWindowResize = this.handleWindowResize.bind(this)
- this.handleMouseEnter = this.handleMouseEnter.bind(this)
- this.handleMouseLeave = this.handleMouseLeave.bind(this)
- this.graphRef = React.createRef()
- this.measurements = {}
- }
-
- getBoundingClientRect() {
- if (!this.graphRef.current) return null
- const rect = this.graphRef.current.getBoundingClientRect()
- const scrollTop = document.body.scrollTop || document.body.parentNode.scrollTop
- const scrollLeft = document.body.scrollLeft || document.body.parentNode.scrollLeft
- const bounds = {
- top: rect.top + scrollTop,
- left: rect.left + scrollLeft,
- width: rect.width,
- height: rect.height,
- }
- // console.log(bounds)
- return bounds
- }
-
- componentDidMount() {
- document.body.addEventListener('mousemove', this.handleMouseMove)
- document.body.addEventListener('mouseup', this.handleMouseUp)
- window.addEventListener('resize', this.handleWindowResize)
- this.setState({ bounds: this.getBoundingClientRect() })
- }
-
- componentDidUpdate(prevProps) {
- if (!this.state.bounds) {
- this.setState({ bounds: this.getBoundingClientRect() })
- }
- }
-
- addMeasurement({ id, width, height }) {
- this.measurements[id] = { width, height }
- this.setState({
- measurements: { ...this.measurements },
- })
- }
-
- handleWindowResize() {
- this.setState({ bounds: this.getBoundingClientRect() })
- }
-
- handleMouseDown(e, page) {
- if (e.shiftKey) {
- e.preventDefault()
- this.props.graphActions.setHomePageId(this.props.graph.show.res, page)
- return
- }
- const bounds = this.getBoundingClientRect()
- const mouseX = e.pageX
- const mouseY = e.pageY
- let w = 128 / bounds.width
- let h = 16 / bounds.height
- let { x, y } = page.settings
- x = clamp(x, 0, 1)
- y = clamp(y, 0, 1)
- this.setState({
- page,
- dragging: true,
- bounds,
- mouseX,
- mouseY,
- box: {
- x, y,
- w, h,
- },
- initialBox: {
- x, y,
- w, h,
- }
- })
- }
-
- handleMouseMove(e) {
- const {
- dragging,
- bounds, mouseX, mouseY, initialBox, box
- } = this.state
- if (dragging) {
- e.preventDefault()
- let { x, y, w, h } = initialBox
- let dx = (e.pageX - mouseX) / bounds.width
- let dy = (e.pageY - mouseY) / bounds.height
- this.setState({
- box: {
- x: clamp(x + dx, 0, 1.0 - w),
- y: clamp(y + dy, 0, 1.0 - h),
- w, h,
- }
- })
- }
- }
-
- handleMouseUp(e) {
- // const { actions } = this.props
- const { dragging, bounds, initialBox, box, page } = this.state
- if (!dragging) return
- e.preventDefault()
- const { width, height } = bounds
- const { x, y, w, h } = box
- let url = window.location.pathname
- this.setState({
- page: null,
- box: null,
- initialBox: null,
- dragging: false,
- })
- if (dist(width * x, height * y, width * initialBox.x, height * initialBox.y) < 3) return
- const updatedPage = {
- ...page,
- settings: {
- ...page.settings,
- x, y,
- }
- }
- this.props.graphActions.updateGraphPage(updatedPage)
- actions.page.update(updatedPage)
- }
-
- handleMouseEnter(e, page) {
- this.setState({ highlightedPageId: page.id })
- }
- handleMouseLeave(e, page) {
- this.setState({ highlightedPageId: null })
- }
-
- render(){
- // console.log(this.props.graph.show.res)
- const { page: currentPage, box, measurements, highlightedPageId } = this.state
- const { res: graph } = this.props.graph.show
- // console.log(res.pages)
- return (
- <div className='graph' ref={this.graphRef}>
- <GraphCanvas
- bounds={this.state.bounds}
- pages={graph.pages}
- currentPage={currentPage}
- highlightedPageId={highlightedPageId}
- measurements={measurements}
- box={box}
- />
- {this.state.bounds && graph.pages.map(page => (
- <PageHandle
- key={page.id}
- graph={graph}
- page={page}
- bounds={this.state.bounds}
- box={currentPage && page.id === currentPage.id && box}
- onMouseDown={e => this.handleMouseDown(e, page)}
- onMouseEnter={e => this.handleMouseEnter(e, page)}
- onMouseLeave={e => this.handleMouseLeave(e, page)}
- onMeasure={measurement => this.addMeasurement(measurement)}
- />
- ))}
- </div>
- )
- }
-}
-
-const mapStateToProps = state => ({
- graph: state.graph,
-})
-
-const mapDispatchToProps = dispatch => ({
- graphActions: bindActionCreators({ ...graphActions }, dispatch),
-})
-
-export default connect(mapStateToProps, mapDispatchToProps)(GraphEditor)
diff --git a/frontend/views/graph/components/graph.header.js b/frontend/views/graph/components/graph.header.js
deleted file mode 100644
index 46ad962..0000000
--- a/frontend/views/graph/components/graph.header.js
+++ /dev/null
@@ -1,31 +0,0 @@
-import React from 'react'
-import { bindActionCreators } from 'redux'
-import { connect } from 'react-redux'
-import { Link } from 'react-router-dom'
-
-import * as graphActions from '../graph.actions'
-
-function GraphHeader(props) {
- return (
- <header>
- <div>
- <Link to="/" className="logo"><b>{props.site.siteTitle}</b></Link>
- </div>
- <div>
- <button onClick={() => props.graphActions.toggleAddPageForm()}>+ Add page</button>
- </div>
- </header>
- )
-}
-
-const mapStateToProps = (state) => ({
- // auth: state.auth,
- site: state.site,
- // isAuthenticated: state.auth.isAuthenticated,
-})
-
-const mapDispatchToProps = (dispatch) => ({
- graphActions: bindActionCreators({ ...graphActions }, dispatch),
-})
-
-export default connect(mapStateToProps, mapDispatchToProps)(GraphHeader)
diff --git a/frontend/views/graph/components/page.edit.js b/frontend/views/graph/components/page.edit.js
deleted file mode 100644
index 5bc64d6..0000000
--- a/frontend/views/graph/components/page.edit.js
+++ /dev/null
@@ -1,65 +0,0 @@
-import React, { Component } from 'react'
-import { Link } from 'react-router-dom'
-import { connect } from 'react-redux'
-import { bindActionCreators } from 'redux'
-
-import { history } from '../../../store'
-import actions from '../../../actions'
-import * as siteActions from '../../site/site.actions'
-import * as graphActions from '../../graph/graph.actions'
-
-import { Loader } from '../../../common'
-
-import PageForm from '../components/page.form'
-
-class PageEdit extends Component {
- componentDidMount() {
- // actions.page.show(this.props.match.params.id)
- }
-
- handleSubmit(data) {
- const { path: graphPath } = this.props.graph.show.res
- const { path: oldPagePath } = this.props.page.show.res
- const { path: newPagePath } = data
- actions.page.update(data)
- .then(response => {
- // console.log(response)
- actions.site.setSiteTitle(response.res.title)
- this.props.graphActions.hideEditPageForm()
- if (oldPagePath !== newPagePath) {
- const newPath = '/' + graphPath + '/' + newPagePath
- history.push(newPath)
- }
- })
- }
-
- render() {
- const { show } = this.props.page
- if (show.loading || !show.res) {
- return (
- <div className='form'>
- <Loader />
- </div>
- )
- }
- return (
- <PageForm
- data={show.res}
- graph={this.props.graph.show.res}
- onSubmit={this.handleSubmit.bind(this)}
- />
- )
- }
-}
-
-const mapStateToProps = state => ({
- graph: state.graph,
- page: state.page,
-})
-
-const mapDispatchToProps = dispatch => ({
- siteActions: bindActionCreators({ ...siteActions }, dispatch),
- graphActions: bindActionCreators({ ...graphActions }, dispatch),
-})
-
-export default connect(mapStateToProps, mapDispatchToProps)(PageEdit)
diff --git a/frontend/views/graph/components/page.form.js b/frontend/views/graph/components/page.form.js
deleted file mode 100644
index 38fee18..0000000
--- a/frontend/views/graph/components/page.form.js
+++ /dev/null
@@ -1,185 +0,0 @@
-import React, { Component } from 'react'
-import { Link } from 'react-router-dom'
-
-import { session } from '../../../session'
-
-import { TextInput, ColorInput, LabelDescription, TextArea, Checkbox, SubmitButton, Loader } from '../../../common'
-
-const newPage = (data) => ({
- path: '',
- title: '',
- username: session('username'),
- description: '',
- settings: {
- x: 0.05,
- y: 0.05,
- background_color: '#000000',
- },
- ...data,
-})
-
-export default class PageForm extends Component {
- state = {
- title: "",
- submitTitle: "",
- data: { ...newPage() },
- errorFields: new Set([]),
- }
-
- componentDidMount() {
- const { graph, data, isNew } = this.props
- const title = isNew ? 'new page' : 'editing ' + data.title
- const submitTitle = isNew ? "Create Page" : "Save Changes"
- this.setState({
- title,
- submitTitle,
- errorFields: new Set([]),
- data: {
- ...newPage({ graph_id: graph.id }),
- ...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,
- }
- })
- }
-
- handleSettingsChange(e) {
- const { name, value } = e.target
- this.setState({
- data: {
- ...this.state.data,
- settings: {
- ...this.state.data.settings,
- [name]: value,
- }
- }
- })
- }
-
- handleSubmit(e) {
- e.preventDefault()
- const { isNew, onSubmit } = this.props
- const { data } = this.state
- const requiredKeys = "path title".split(" ")
- const validKeys = "graph_id path title username description settings".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 page
- // session.set('username', data.username)
- } else {
- validData.id = data.id
- }
- console.log('submit', validData)
- onSubmit(validData)
- }
- }
-
- handleDelete() {
- const { data } = this.state
- console.log(data)
- if (confirm('Really delete this page?')) {
- actions.page.delete(page_id)
- }
- }
-
- render() {
- const { graph, isNew } = this.props
- const { title, submitTitle, errorFields, data } = this.state
- return (
- <div className='box'>
- <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>
- {'Page URL: /' + graph.path + '/'}<b>{data.path}</b>
- </LabelDescription>
- <TextInput
- title="Title"
- name="title"
- required
- data={data}
- error={errorFields.has('title')}
- onChange={this.handleChange.bind(this)}
- autoComplete="off"
- />
- <ColorInput
- title='BG'
- name='background_color'
- data={data.settings}
- onChange={this.handleSettingsChange.bind(this)}
- autoComplete="off"
- />
- <TextArea
- title="Description"
- name="description"
- data={data}
- onChange={this.handleChange.bind(this)}
- />
- <div className='row buttons'>
- <SubmitButton
- title={submitTitle}
- onClick={this.handleSubmit.bind(this)}
- />
- {!isNew &&
- <SubmitButton
- title={'Delete'}
- className='destroy'
- onClick={this.handleDelete.bind(this)}
- />
- }
- </div>
- {!!errorFields.size &&
- <label>
- <span></span>
- <span>Please complete the required fields =)</span>
- </label>
- }
- </form>
- </div>
- )
- }
-}
diff --git a/frontend/views/graph/components/page.handle.js b/frontend/views/graph/components/page.handle.js
deleted file mode 100644
index 7093399..0000000
--- a/frontend/views/graph/components/page.handle.js
+++ /dev/null
@@ -1,59 +0,0 @@
-import React, { Component } from 'react'
-import { Link } from 'react-router-dom'
-
-import { history } from '../../../store'
-
-export default class PageHandle extends Component {
- constructor(props){
- super(props)
- this.ref = React.createRef()
- }
- componentDidMount(){
- this.measure()
- }
- componentDidUpdate(prevProps){
- if (this.props.page.title !== prevProps.page.title) {
- this.measure()
- }
- }
- measure() {
- const { offsetWidth: width, offsetHeight: height } = this.ref.current
- const { id } = this.props.page
- // console.log(id, width, height)
- this.props.onMeasure({ id, width, height })
- }
- render() {
- const { graph, page, bounds, box, onMouseDown, onMouseEnter, onMouseLeave } = this.props
- let style;
- if (box) {
- style = {
- top: (bounds.height) * box.y,
- left: (bounds.width) * box.x,
- }
- } else {
- style = {
- top: (bounds.height) * Math.min(page.settings.y, 0.95),
- left: (bounds.width) * Math.min(page.settings.x, 0.95),
- }
- }
- const className = (graph.home_page_id === page.id)
- ? 'handle homepage'
- : 'handle'
- const url = '/' + graph.path + '/' + page.path
- // console.log(style)
- return (
- <div
- className={className}
- ref={this.ref}
- onMouseDown={onMouseDown}
- onMouseEnter={onMouseEnter}
- onMouseLeave={onMouseLeave}
- onDoubleClick={() => history.push(url)}
- style={style}
- >
- {page.path}
- <Link to={url}>{'>'}</Link>
- </div>
- )
- }
-}
diff --git a/frontend/views/graph/components/page.new.js b/frontend/views/graph/components/page.new.js
deleted file mode 100644
index bc74358..0000000
--- a/frontend/views/graph/components/page.new.js
+++ /dev/null
@@ -1,47 +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 PageForm from '../components/page.form'
-
-class PageNew extends Component {
- handleSubmit(data) {
- console.log(data)
- actions.page.create(data)
- .then(res => {
- console.log(res)
- const graph = this.props.graph.show.res
- if (res.res && res.res.id) {
- history.push('/' + graph.path + '/' + res.res.path)
- }
- })
- .catch(err => {
- console.error('error', err)
- })
- }
-
- render() {
- return (
- <PageForm
- isNew
- graph={this.props.graph.show.res}
- data={{}}
- onSubmit={this.handleSubmit.bind(this)}
- />
- )
- }
-}
-
-const mapStateToProps = state => ({
- graph: state.graph,
- page: state.page,
-})
-
-const mapDispatchToProps = dispatch => ({
- // searchActions: bindActionCreators({ ...searchActions }, dispatch),
-})
-
-export default connect(mapStateToProps, mapDispatchToProps)(PageNew)
diff --git a/frontend/views/graph/graph.actions.js b/frontend/views/graph/graph.actions.js
deleted file mode 100644
index bf6b643..0000000
--- a/frontend/views/graph/graph.actions.js
+++ /dev/null
@@ -1,37 +0,0 @@
-import * as types from '../../types'
-import actions from '../../actions'
-
-export const showAddPageForm = () => dispatch => {
- dispatch({ type: types.graph.show_add_page_form })
-}
-
-export const hideAddPageForm = () => dispatch => {
- dispatch({ type: types.graph.hide_add_page_form })
-}
-
-export const toggleAddPageForm = () => dispatch => {
- dispatch({ type: types.graph.toggle_add_page_form })
-}
-
-export const showEditPageForm = () => dispatch => {
- dispatch({ type: types.graph.show_edit_page_form })
-}
-
-export const hideEditPageForm = () => dispatch => {
- dispatch({ type: types.graph.hide_edit_page_form })
-}
-
-export const toggleEditPageForm = () => dispatch => {
- dispatch({ type: types.graph.toggle_edit_page_form })
-}
-
-export const updateGraphPage = page => dispatch => {
- dispatch({ type: types.graph.update_graph_page, page })
-}
-
-export const setHomePageId = (graph, page) => dispatch => {
- let updated_graph = { ...graph }
- delete updated_graph.pages
- updated_graph.home_page_id = page.id
- actions.graph.update(updated_graph)
-} \ No newline at end of file
diff --git a/frontend/views/graph/graph.container.js b/frontend/views/graph/graph.container.js
deleted file mode 100644
index 7f53d64..0000000
--- a/frontend/views/graph/graph.container.js
+++ /dev/null
@@ -1,82 +0,0 @@
-import React, { Component } from 'react'
-import { Route } from 'react-router-dom'
-import { bindActionCreators } from 'redux'
-import { connect } from 'react-redux'
-
-import './graph.css'
-
-import actions from '../../actions'
-import { Loader } from '../../common'
-
-// import * as uploadActions from './upload.actions'
-
-import PageNew from './components/page.new'
-import PageEdit from './components/page.edit'
-
-import GraphHeader from './components/graph.header'
-import GraphEditor from './components/graph.editor'
-
-class GraphContainer extends Component {
- componentDidMount() {
- if (this.shouldShowGraph()) this.load()
- }
- componentDidUpdate(prevProps) {
- if (this.shouldLoadGraph(prevProps)) this.load()
- }
- shouldShowGraph() {
- const { graph_name, page_name } = this.props.match.params
- return (graph_name && !page_name && graph_name !== 'index')
- }
- shouldLoadGraph(prevProps) {
- const { graph, location } = this.props
- const { key } = location
- if (key === prevProps.location.key) return false
- if (!this.shouldShowGraph()) return false
- return (graph.show.name === prevProps.graph.show.name)
- }
- load() {
- actions.site.setSiteTitle("loading " + this.props.match.params.graph_name + "...")
- actions.graph.show('name/' + this.props.match.params.graph_name)
- .then(data => {
- actions.site.setSiteTitle(data.res.title)
- })
- }
- render() {
- if (!this.shouldShowGraph()) return <div />
- if (!this.props.graph.show.res || this.props.graph.show.loading) {
- return (
- <div>
- <GraphHeader />
- <div className='body'>
- <div className='graph loading'>
- <Loader />
- </div>
- </div>
- </div>
- )
- }
- return (
- <div>
- <GraphHeader />
- <div className='body'>
- <GraphEditor />
- <div className='sidebar'>
- {this.props.graph.editor.addingPage && <PageNew />}
- {this.props.graph.editor.editingPage && <PageEdit />}
- </div>
- </div>
- </div>
- )
- }
-}
-
-// <Route exact path='/:graph_name' component={GraphView} />
-const mapStateToProps = state => ({
- graph: state.graph,
-})
-
-const mapDispatchToProps = dispatch => ({
- // uploadActions: bindActionCreators({ ...uploadActions }, dispatch),
-})
-
-export default connect(mapStateToProps, mapDispatchToProps)(GraphContainer)
diff --git a/frontend/views/graph/graph.css b/frontend/views/graph/graph.css
deleted file mode 100644
index 389a55d..0000000
--- a/frontend/views/graph/graph.css
+++ /dev/null
@@ -1,172 +0,0 @@
-.graph.loading {
- padding: 1rem;
-}
-.graph {
- position: relative;
- width: 100%;
- height: 100%;
- overflow: hidden;
- background: linear-gradient(
- 0deg,
- rgba(128, 0, 64, 0.5),
- rgba(0, 0, 64, 0.5)
- );
-}
-.graph canvas {
- position: absolute;
- top: 0;
- left: 0;
-}
-
-/* Sidebar boxes */
-
-.sidebar {
- position: absolute;
- top: 0;
- right: 0;
- padding: 1rem;
- overflow: auto;
- max-height: 100%;
- z-index: 20;
-}
-.box {
- width: 15rem;
- padding: 0.5rem;
- background: rgba(64,12,64,0.9);
- border: 2px solid #000;
- box-shadow: 2px 2px 4px rgba(0,0,0,0.5);
-}
-.box h1,
-.box h2 {
- font-size: 1rem;
- margin: 0 0 0.5rem 0;
-}
-.box form label {
- display: flex;
- flex-direction: column;
- align-items: flex-start;
- margin-bottom: 0.25rem;
-}
-.box form .buttons {
- justify-content: space-between;
-}
-.box form .buttons label {
- width: auto;
- min-width: auto;
-}
-.box form .buttons label span {
- display: none;
-}
-.box form .buttons button:last-child {
- margin-right: 0;
-}
-.box form label.checkbox {
- flex-direction: row;
- justify-content: flex-start;
- align-items: center;
-}
-.box form input[type="checkbox"] {
- margin-left: 0rem;
-}
-.box form input[type=checkbox] + span {
- color: #ddd;
-}
-.box form input[type=checkbox]:hover + span {
- color: #fff;
-}
-.box form input[type="checkbox"]:after {
- border-color: #84f;
-}
-.box form input[type="checkbox"]:checked:after {
- border-color: #84f;
- background-color: #84f;
-}
-.box form input[type=checkbox]:hover + span {
- color: #84f;
-}
-.box input[type=text],
-.box input[type=number],
-.box input[type=password] {
- padding: 0.25rem;
- max-width: 100%;
- border-color: #888;
-}
-.box textarea {
- max-width: 100%;
- height: 5rem;
- border-color: #888;
-}
-.box .select {
- padding: 0.25rem;
- margin-right: 0;
-}
-.box .selects label {
- flex-direction: row;
- width: 6.5rem;
- margin-right: 0.5rem;
- min-width: auto;
-}
-.box form textarea {
- padding: 0.25rem;
-}
-
-.box form .pair label span {
- min-width: 3rem;
- padding: 0.25rem 0;
-}
-.box .pair label {
- flex-direction: row;
- width: 6.5rem;
- margin-right: 0.5px;
- min-width: auto;
-}
-.box .pair input[type=text] {
- width: 3rem;
-}
-.box .position {
- font-size: smaller;
- margin-bottom: 0.25rem;
-}
-
-.box .slider {
- display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: space-between;
-}
-.box .slider span {
- min-width: 4rem;
- width: 4rem;
- padding: 0.125rem 0;
-}
-.box .slider input[type='number'] {
- width: 3.5rem;
-}
-.box .slider input[type='range'] {
- width: 5.5rem;
-}
-
-/* Graph handles */
-
-.handle {
- position: absolute;
- border: 2px solid #888;
- background: #8833dd;
- padding: 0.25rem;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- max-width: 8rem;
- user-select: none;
- cursor: arrow;
-}
-.handle.homepage {
- background: #533854;
- border-color: #edc40e;
-}
-.handle a {
- margin-left: 0.25rem;
- color: #fff;
- font-weight: bold;
- text-decoration: none;
-}
diff --git a/frontend/views/graph/graph.reducer.js b/frontend/views/graph/graph.reducer.js
deleted file mode 100644
index 37798b3..0000000
--- a/frontend/views/graph/graph.reducer.js
+++ /dev/null
@@ -1,100 +0,0 @@
-import * as types from '../../types'
-// import { session, getDefault, getDefaultInt } from '../../session'
-
-import { crudState, crudReducer } from '../../api/crud.reducer'
-
-const initialState = crudState('graph', {
- editor: {
- addingPage: false,
- editingPage: false,
- },
- options: {
- }
-})
-
-const reducer = crudReducer('graph')
-
-export default function graphReducer(state = initialState, action) {
- // console.log(action.type, action)
- state = reducer(state, action)
- switch (action.type) {
- case types.graph.update_graph_page:
- return {
- ...state,
- show: {
- ...state.show,
- res: {
- ...state.show.res,
- pages: state.show.res.pages.map(page => {
- if (page.id === action.page.id) {
- return { ...action.page }
- } else {
- return page
- }
- }),
- }
- }
- }
-
- case types.graph.show_add_page_form:
- return {
- ...state,
- editor: {
- ...state.editor,
- addingPage: true,
- editingPage: false,
- }
- }
-
- case types.graph.hide_add_page_form:
- return {
- ...state,
- editor: {
- ...state.editor,
- addingPage: false,
- }
- }
-
- case types.graph.toggle_add_page_form:
- return {
- ...state,
- editor: {
- ...state.editor,
- addingPage: !state.editor.addingPage,
- editingPage: false,
- }
- }
-
- case types.graph.show_edit_page_form:
- return {
- ...state,
- editor: {
- ...state.editor,
- addingPage: false,
- editingPage: true,
- }
- }
-
- case types.graph.hide_edit_page_form:
- return {
- ...state,
- editor: {
- ...state.editor,
- editingPage: false,
- }
- }
-
- case types.graph.toggle_edit_page_form:
- return {
- ...state,
- editor: {
- ...state.editor,
- addingPage: false,
- editingPage: !state.editor.editingPage,
- }
- }
-
- default:
- return state
- }
-}