diff options
| author | Jules Laplace <julescarbon@gmail.com> | 2020-09-26 14:56:02 +0200 |
|---|---|---|
| committer | Jules Laplace <julescarbon@gmail.com> | 2020-09-26 14:56:02 +0200 |
| commit | a17b76ac75f506f5da6fe8adf9c36632b60d4226 (patch) | |
| tree | abb0af0c4409b830dea2ef808c146223ee973933 /frontend/views/graph | |
| parent | 2231a6e1c05b07bb7ec5906716aedec93d02429c (diff) | |
refactor to use app-rooted js imports
Diffstat (limited to 'frontend/views/graph')
| -rw-r--r-- | frontend/views/graph/components/graph.canvas.js | 138 | ||||
| -rw-r--r-- | frontend/views/graph/components/graph.editor.js | 212 | ||||
| -rw-r--r-- | frontend/views/graph/components/graph.header.js | 31 | ||||
| -rw-r--r-- | frontend/views/graph/components/page.edit.js | 65 | ||||
| -rw-r--r-- | frontend/views/graph/components/page.form.js | 185 | ||||
| -rw-r--r-- | frontend/views/graph/components/page.handle.js | 59 | ||||
| -rw-r--r-- | frontend/views/graph/components/page.new.js | 47 | ||||
| -rw-r--r-- | frontend/views/graph/graph.actions.js | 37 | ||||
| -rw-r--r-- | frontend/views/graph/graph.container.js | 82 | ||||
| -rw-r--r-- | frontend/views/graph/graph.css | 172 | ||||
| -rw-r--r-- | frontend/views/graph/graph.reducer.js | 100 |
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 - } -} |
