beginning to come together

This commit is contained in:
Connor Turland 2017-09-18 23:30:33 -04:00
parent 6e1878413f
commit e290244404
7 changed files with 144 additions and 46 deletions

View file

@ -113,6 +113,7 @@ const ReactApp = {
self.getFilterProps(),
self.getCommonProps(),
self.getMapsProps(),
self.getContextMenuProps(),
self.getTopicCardProps(),
self.getChatProps())
},
@ -155,6 +156,29 @@ const ReactApp = {
onTopicFollow: Topic.onTopicFollow
}
},
getContextMenuProps: function() {
const self = ReactApp
return {
// values
contextMenu: !!(ContextMenu.clickedNode || ContextMenu.clickedEdge),
contextNode: ContextMenu.clickedNode,
contextEdge: ContextMenu.clickedEdge,
contextPos: ContextMenu.pos,
contextFetchingSiblingsData: ContextMenu.fetchingSiblingsData,
contextSiblingsData: ContextMenu.siblingsData,
// functions
contextReset: ContextMenu.reset,
contextDelete: ContextMenu.delete,
contextRemove: ContextMenu.remove,
contextHide: ContextMenu.hide,
contextCenterOn: ContextMenu.centerOn,
contextPopoutTopic: ContextMenu.popoutTopic,
contextUpdatePermissions: ContextMenu.updatePermissions,
contextOnMetacodeSelect: ContextMenu.onMetacodeSelect,
contextFetchSiblings: ContextMenu.fetchSiblings,
contextPopulateSiblings: ContextMenu.populateSiblings
}
},
getTopicProps: function() {
const self = ReactApp
return {

View file

@ -152,12 +152,12 @@ const Listeners = {
var node = nodes[nodes.length - 1]
if (opts.center && opts.reveal) {
Topic.centerOn(node.id, function() {
Topic.fetchRelatives(nodes)
Topic.fetchSiblings(nodes)
})
} else if (opts.center) {
Topic.centerOn(node.id)
} else if (opts.reveal) {
Topic.fetchRelatives(nodes)
Topic.fetchSiblings(nodes)
}
}
}

View file

@ -74,7 +74,7 @@ const Topic = {
}
},
centerOn: function(nodeid, callback) {
// don't clash with fetchRelatives
// don't clash with fetchSiblings
if (!Visualize.mGraph.busy) {
Visualize.mGraph.onClick(nodeid, {
hideLabels: false,
@ -100,7 +100,7 @@ const Topic = {
}
ReactApp.render()
},
fetchRelatives: function(nodes, metacodeId) {
fetchSiblings: function(nodes, metacodeId) {
var self = this
var node = $.isArray(nodes) ? nodes[0] : nodes
@ -156,7 +156,7 @@ const Topic = {
})
})
if ($.isArray(nodes) && nodes.length > 1) {
self.fetchRelatives(nodes.slice(1), metacodeId)
self.fetchSiblings(nodes.slice(1), metacodeId)
}
}

View file

@ -1,6 +1,6 @@
import Control from '../Control'
import DataModel from '../DataModel'
import ReactApp from '../GlobalUI/ReactApp'
import { ReactApp } from '../GlobalUI'
import Selected from '../Selected'
import Topic from '../Topic'
@ -8,11 +8,13 @@ const ContextMenu = {
clickedNode: null,
clickedEdge: null,
pos: {x: 0, y: 0},
fetchingSiblingsData: false,
siblingsData: null,
selectNode: (node, pos) => {
ContextMenu.pos = pos
ContextMenu.clickedNode = node
ContextMenu.clickedEdge = null
ContextMenu.fetchingSiblingsData = false
ContextMenu.siblingsData = null
ReactApp.render()
},
@ -20,16 +22,21 @@ const ContextMenu = {
ContextMenu.pos = pos
ContextMenu.clickedNode = null
ContextMenu.clickedEdge = edge
ContextMenu.fetchingSiblingsData = false
ContextMenu.siblingsData = null
ReactApp.render()
},
reset: () => {
ContextMenu.fetchingSiblingsData = false
ContextMenu.siblingsData = null
ContextMenu.clickedNode = null
ContextMenu.clickedEdge = null
ReactApp.render()
},
delete: Control.deleteSelected,
delete: () => {
Control.deleteSelected()
ContextMenu.reset()
},
remove: () => {
Control.removeSelectedEdges()
Control.removeSelectedNodes()
@ -66,39 +73,27 @@ const ContextMenu = {
}
ContextMenu.reset()
},
fetchRelatives: (node, metacodeId) => {
Topic.fetchRelatives(node, metacodeId)
fetchSiblings: (node, metacodeId) => {
Topic.fetchSiblings(node, metacodeId)
ContextMenu.reset()
},
populateSiblings: function(id) {
// depending on how many topics are selected, do different things
// add a loading icon for now
/*const loader = new CanvasLoader('loadingSiblings')
loader.setColor('#4FC059') // default is '#000000'
loader.setDiameter(15) // default is 40
loader.setDensity(41) // default is 40
loader.setRange(0.9) // default is 1.3
loader.show() // Hidden by default*/
ContextMenu.fetchingSiblingsData = true
ReactApp.render()
const topics = DataModel.Topics.map(function(t) { return t.id })
const topicsString = topics.join()
const successCallback = function(data) {
ContextMenu.fetchingSiblingsData = false
// adjust the data for consumption by react
for (var key in data) {
data[key] = `${DataModel.Metacodes.get(key).get('name')} (${data[key]})`
}
ContextMenu.siblingsData = data
ReactApp.render()
/*$('#loadingSiblings').remove()
for (var key in data) {
const string = `${DataModel.Metacodes.get(key).get('name')} (${data[key]})`
$('#fetchSiblingList').append(`<li class="getSiblings" data-id="${key}">${string}</li>`)
}
$('.rc-siblings .getSiblings').click(function() {
$('.rightclickmenu').remove()
// data-id is a metacode id
Topic.fetchRelatives(node, $(this).attr('data-id'))
})*/
}
$.ajax({

View file

@ -1,6 +1,7 @@
import React, { Component } from 'react'
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import ContextMenu from '../common/ContextMenu'
import DataVis from '../common/DataVis'
import UpperOptions from '../common/UpperOptions'
import InfoAndHelp from '../common/InfoAndHelp'
@ -9,9 +10,11 @@ import VisualizationControls from '../common/VisualizationControls'
import MapChat from './MapChat'
import TopicCard from '../TopicCard'
export default class MapView extends Component {
static propTypes = {
contextMenu: PropTypes.bool,
mobile: PropTypes.bool,
mapId: PropTypes.string,
map: PropTypes.object,
@ -79,7 +82,8 @@ export default class MapView extends Component {
filterAllMappers, filterAllSynapses, filterData,
openImportLightbox, forkMap, openHelpLightbox,
mapIsStarred, onMapStar, onMapUnstar, openTopic,
onZoomExtents, onZoomIn, onZoomOut, hasLearnedTopicCreation } = this.props
onZoomExtents, onZoomIn, onZoomOut, hasLearnedTopicCreation,
contextMenu } = this.props
const { chatOpen } = this.state
const onChatOpen = () => {
this.setState({chatOpen: true})
@ -109,6 +113,7 @@ export default class MapView extends Component {
filterAllSynapses={filterAllSynapses} />
<DataVis />
{openTopic && <TopicCard {...this.props} />}
{contextMenu && <ContextMenu {...this.props} />}
{currentUser && <Instructions mobile={mobile} hasLearnedTopicCreation={hasLearnedTopicCreation} />}
{currentUser && <MapChat {...this.props} onOpen={onChatOpen} onClose={onChatClose} chatOpen={chatOpen} ref={x => this.mapChat = x} />}
<VisualizationControls map={map}

View file

@ -1,6 +1,7 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import ContextMenu from '../common/ContextMenu'
import DataVis from '../common/DataVis'
import UpperOptions from '../common/UpperOptions'
import InfoAndHelp from '../common/InfoAndHelp'
@ -10,6 +11,7 @@ import TopicCard from '../TopicCard'
export default class TopicView extends Component {
static propTypes = {
contextMenu: PropTypes.bool,
mobile: PropTypes.bool,
topicId: PropTypes.string,
topic: PropTypes.object,
@ -55,7 +57,7 @@ export default class TopicView extends Component {
const { mobile, topic, currentUser, allForFiltering, visibleForFiltering,
toggleMetacode, toggleMapper, toggleSynapse, filterAllMetacodes,
filterAllMappers, filterAllSynapses, filterData, forkMap,
openHelpLightbox, onZoomIn, onZoomOut } = this.props
openHelpLightbox, onZoomIn, onZoomOut, contextMenu } = this.props
// TODO: stop using {...this.props} and make explicit
return <div className="topicWrapper">
<UpperOptions ref={x => this.upperOptions = x}
@ -73,6 +75,7 @@ export default class TopicView extends Component {
filterAllSynapses={filterAllSynapses} />
<DataVis />
<TopicCard {...this.props} />
{contextMenu && <ContextMenu {...this.props} />}
<VisualizationControls onClickZoomIn={onZoomIn}
onClickZoomOut={onZoomOut} />
<InfoAndHelp topic={topic}

View file

@ -1,43 +1,114 @@
import React, { Component, PropTypes } from 'react'
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import MetacodeSelect from '../MetacodeSelect'
class ContextMenu extends Component {
static propTypes = {
node: PropTypes.object,
edge: PropTypes.object
topicId: PropTypes.string,
contextNode: PropTypes.object,
contextEdge: PropTypes.object,
contextPos: PropTypes.object,
contextFetchingSiblingsData: PropTypes.bool,
contextSiblingsData: PropTypes.object,
metacodeSets: PropTypes.array,
contextReset: PropTypes.func,
contextDelete: PropTypes.func,
contextRemove: PropTypes.func,
contextHide: PropTypes.func,
contextCenterOn: PropTypes.func,
contextPopoutTopic: PropTypes.func,
contextUpdatePermissions: PropTypes.func,
contextOnMetacodeSelect: PropTypes.func,
contextFetchSiblings: PropTypes.func,
contextPopulateSiblings: PropTypes.func
}
constructor(props) {
super(props)
this.state = {
populateSiblingsSent: false
}
}
render () {
const { contextNode, contextPos, contextOnMetacodeSelect, metacodeSets,
contextSiblingsData, contextFetchSiblings,
contextPopulateSiblings, contextFetchingSiblingsData,
topicId } = this.props
const style = {
position: 'absolute',
top: '10px',
left: '10px'
top: contextPos.y + 'px',
left: contextPos.x + 'px'
}
const populateSiblings = () => {
if (!this.state.populateSiblingsSent) {
contextPopulateSiblings(contextNode.id)
this.setState({populateSiblingsSent: true})
}
}
// TODO: add checks for logged in and other context
return <div className="rightclickmenu" style={style}>
<ul>
<li className="rc-hide">
<div className="rc-icon"></div>Hide until refresh<div className="rc-keyboard">Ctrl+H</div>
<div className="rc-icon" />Hide until refresh
<div className="rc-keyboard">Ctrl+H</div>
</li>
<li className="rc-remove ">
<div className="rc-icon"></div>Remove from map<div className="rc-keyboard">Ctrl+M</div>
<div className="rc-icon" />Remove from map
<div className="rc-keyboard">Ctrl+M</div>
</li>
<li className="rc-delete ">
<div className="rc-icon"></div>Delete<div className="rc-keyboard">Ctrl+D</div>
<div className="rc-icon" />Delete
<div className="rc-keyboard">Ctrl+D</div>
</li>
<li className="rc-popout">
<div className="rc-icon"></div>Open in new tab
<div className="rc-icon" />Open in new tab
</li>
<li className="rc-spacer"></li>
<li className="rc-permission">
<div className="rc-icon"></div>Change permissions
<div className="rc-icon" />Change permissions
<ul>
<li className="changeP toCommons"><div className="rc-perm-icon"></div>commons</li>
<li className="changeP toPublic"><div className="rc-perm-icon"></div>public</li>
<li className="changeP toPrivate"><div className="rc-perm-icon"></div>private</li>
<li className="changeP toCommons">
<div className="rc-perm-icon" />commons
</li>
<li className="changeP toPublic">
<div className="rc-perm-icon" />public
</li>
<li className="changeP toPrivate">
<div className="rc-perm-icon" />private
</li>
</ul>
<div className="expandLi"></div>
<div className="expandLi" />
</li>
<li className="rc-metacode">
<div className="rc-icon" />Change metacode
<div id="metacodeOptionsWrapper">
<MetacodeSelect onMetacodeSelect={contextOnMetacodeSelect}
metacodeSets={metacodeSets} />
</div>
<div className="expandLi" />
</li>
{contextNode && topicId && <li className="rc-siblings"
onMouseOver={populateSiblings}>
<div className="rc-icon" />Reveal siblings
<ul id="fetchSiblingList">
<li className="fetchAll"
onClick={() => contextFetchSiblings(contextNode)}>All
<div className="rc-keyboard">Alt+R</div>
</li>
{contextSiblingsData && Object.keys(contextSiblingsData).map(key => {
return <li key={key}
onClick={() => contextFetchSiblings(contextNode, key)}>
{contextSiblingsData[key]}
</li>
})}
{contextFetchingSiblingsData && <li id="loadingSiblings">loading</li>}
</ul>
<div className="expandLi" />
</li>}
</ul>
</div>