trying to scope all the modules per map or topic
This commit is contained in:
parent
663706b1f7
commit
f07b97d573
29 changed files with 1366 additions and 1311 deletions
|
@ -22,11 +22,16 @@
|
||||||
<div class="clearfloat"></div>
|
<div class="clearfloat"></div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
Metamaps.ServerData = Metamaps.ServerData || {}
|
||||||
|
Metamaps.ServerData.selectedMetacodes = []
|
||||||
|
Metamaps.ServerData.newSelectedMetacodes = []
|
||||||
|
Metamaps.ServerData.selectedMetacodeNames = []
|
||||||
|
Metamaps.ServerData.newSelectedMetacodeNames = []
|
||||||
<% @metacodes.each do |metacode| %>
|
<% @metacodes.each do |metacode| %>
|
||||||
Metamaps.Create.selectedMetacodes.push("<%= metacode.id %>");
|
Metamaps.ServerData.selectedMetacodes.push("<%= metacode.id %>");
|
||||||
Metamaps.Create.newSelectedMetacodes.push("<%= metacode.id %>");
|
Metamaps.ServerData.newSelectedMetacodes.push("<%= metacode.id %>");
|
||||||
Metamaps.Create.selectedMetacodeNames.push("<%= metacode.name %>");
|
Metamaps.ServerData.selectedMetacodeNames.push("<%= metacode.name %>");
|
||||||
Metamaps.Create.newSelectedMetacodeNames.push("<%= metacode.name %>");
|
Metamaps.ServerData.newSelectedMetacodeNames.push("<%= metacode.name %>");
|
||||||
<% end %>
|
<% end %>
|
||||||
</script>
|
</script>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
|
@ -116,6 +116,7 @@
|
||||||
<div class="clearfloat"></div>
|
<div class="clearfloat"></div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
Metamaps.Create.selectedMetacodeSet = "metacodeset-<%= selectedSet %>"
|
Metamaps.ServerData = Metamaps.ServerData || {}
|
||||||
Metamaps.Create.selectedMetacodeSetIndex = <%= index %>
|
Metamaps.ServerData.selectedMetacodeSet = "metacodeset-<%= selectedSet %>"
|
||||||
|
Metamaps.ServerData.selectedMetacodeSetIndex = <%= index %>
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
const Active = {
|
const Active = (map = null, mapper = null, topic = null) => {
|
||||||
Map: null,
|
return {
|
||||||
Mapper: null,
|
Map: map,
|
||||||
Topic: null
|
Mapper: mapper,
|
||||||
|
Topic: topic
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Active
|
export default Active
|
||||||
|
|
|
@ -1,77 +1,79 @@
|
||||||
const AutoLayout = {
|
const AutoLayout = () => {
|
||||||
nextX: 0,
|
return {
|
||||||
nextY: 0,
|
nextX: 0,
|
||||||
sideLength: 1,
|
nextY: 0,
|
||||||
turnCount: 0,
|
sideLength: 1,
|
||||||
nextXshift: 1,
|
turnCount: 0,
|
||||||
nextYshift: 0,
|
nextXshift: 1,
|
||||||
timeToTurn: 0,
|
nextYshift: 0,
|
||||||
|
timeToTurn: 0,
|
||||||
|
|
||||||
getNextCoord: function(opts = {}) {
|
getNextCoord: function(opts = {}) {
|
||||||
var self = AutoLayout
|
var self = AutoLayout
|
||||||
var nextX = self.nextX
|
var nextX = self.nextX
|
||||||
var nextY = self.nextY
|
var nextY = self.nextY
|
||||||
|
|
||||||
var DISTANCE_BETWEEN = 120
|
var DISTANCE_BETWEEN = 120
|
||||||
|
|
||||||
self.nextX = self.nextX + DISTANCE_BETWEEN * self.nextXshift
|
self.nextX = self.nextX + DISTANCE_BETWEEN * self.nextXshift
|
||||||
self.nextY = self.nextY + DISTANCE_BETWEEN * self.nextYshift
|
self.nextY = self.nextY + DISTANCE_BETWEEN * self.nextYshift
|
||||||
|
|
||||||
self.timeToTurn += 1
|
self.timeToTurn += 1
|
||||||
// if true, it's time to turn
|
// if true, it's time to turn
|
||||||
if (self.timeToTurn === self.sideLength) {
|
if (self.timeToTurn === self.sideLength) {
|
||||||
self.turnCount += 1
|
self.turnCount += 1
|
||||||
// if true, it's time to increase side length
|
// if true, it's time to increase side length
|
||||||
if (self.turnCount % 2 === 0) {
|
if (self.turnCount % 2 === 0) {
|
||||||
self.sideLength += 1
|
self.sideLength += 1
|
||||||
|
}
|
||||||
|
self.timeToTurn = 0
|
||||||
|
|
||||||
|
// going right? turn down
|
||||||
|
if (self.nextXshift === 1 && self.nextYshift === 0) {
|
||||||
|
self.nextXshift = 0
|
||||||
|
self.nextYshift = 1
|
||||||
|
} else if (self.nextXshift === 0 && self.nextYshift === 1) {
|
||||||
|
// going down? turn left
|
||||||
|
self.nextXshift = -1
|
||||||
|
self.nextYshift = 0
|
||||||
|
} else if (self.nextXshift === -1 && self.nextYshift === 0) {
|
||||||
|
// going left? turn up
|
||||||
|
self.nextXshift = 0
|
||||||
|
self.nextYshift = -1
|
||||||
|
} else if (self.nextXshift === 0 && self.nextYshift === -1) {
|
||||||
|
// going up? turn right
|
||||||
|
self.nextXshift = 1
|
||||||
|
self.nextYshift = 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (opts.mappings && self.coordsTaken(nextX, nextY, opts.mappings)) {
|
||||||
|
// check if the coordinate is already taken on the current map
|
||||||
|
return self.getNextCoord(opts)
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
x: nextX,
|
||||||
|
y: nextY
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
coordsTaken: function(x, y, mappings) {
|
||||||
|
if (mappings.findWhere({ xloc: x, yloc: y })) {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
resetSpiral: function() {
|
||||||
|
var self = AutoLayout
|
||||||
|
self.nextX = 0
|
||||||
|
self.nextY = 0
|
||||||
|
self.nextXshift = 1
|
||||||
|
self.nextYshift = 0
|
||||||
|
self.sideLength = 1
|
||||||
self.timeToTurn = 0
|
self.timeToTurn = 0
|
||||||
|
self.turnCount = 0
|
||||||
// going right? turn down
|
|
||||||
if (self.nextXshift === 1 && self.nextYshift === 0) {
|
|
||||||
self.nextXshift = 0
|
|
||||||
self.nextYshift = 1
|
|
||||||
} else if (self.nextXshift === 0 && self.nextYshift === 1) {
|
|
||||||
// going down? turn left
|
|
||||||
self.nextXshift = -1
|
|
||||||
self.nextYshift = 0
|
|
||||||
} else if (self.nextXshift === -1 && self.nextYshift === 0) {
|
|
||||||
// going left? turn up
|
|
||||||
self.nextXshift = 0
|
|
||||||
self.nextYshift = -1
|
|
||||||
} else if (self.nextXshift === 0 && self.nextYshift === -1) {
|
|
||||||
// going up? turn right
|
|
||||||
self.nextXshift = 1
|
|
||||||
self.nextYshift = 0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opts.mappings && self.coordsTaken(nextX, nextY, opts.mappings)) {
|
|
||||||
// check if the coordinate is already taken on the current map
|
|
||||||
return self.getNextCoord(opts)
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
x: nextX,
|
|
||||||
y: nextY
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
coordsTaken: function(x, y, mappings) {
|
|
||||||
if (mappings.findWhere({ xloc: x, yloc: y })) {
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
resetSpiral: function() {
|
|
||||||
var self = AutoLayout
|
|
||||||
self.nextX = 0
|
|
||||||
self.nextY = 0
|
|
||||||
self.nextXshift = 1
|
|
||||||
self.nextYshift = 0
|
|
||||||
self.sideLength = 1
|
|
||||||
self.timeToTurn = 0
|
|
||||||
self.turnCount = 0
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,24 +2,13 @@
|
||||||
|
|
||||||
import { indexOf } from 'lodash'
|
import { indexOf } from 'lodash'
|
||||||
|
|
||||||
import Active from './Active'
|
|
||||||
import Control from './Control'
|
|
||||||
import DataModel from './DataModel'
|
|
||||||
import Map from './Map'
|
|
||||||
import Mapper from './Mapper'
|
import Mapper from './Mapper'
|
||||||
import Synapse from './Synapse'
|
|
||||||
import Topic from './Topic'
|
|
||||||
import { ChatView } from './Views'
|
|
||||||
import Visualize from './Visualize'
|
|
||||||
|
|
||||||
const Cable = {
|
const Cable = ({Active, Control, DataModel, Map, Synapse, Topic, ChatView, Visualize}) => {
|
||||||
init: () => {
|
const toExport = {
|
||||||
let self = Cable
|
|
||||||
self.cable = ActionCable.createConsumer()
|
|
||||||
},
|
|
||||||
subscribeToMap: id => {
|
subscribeToMap: id => {
|
||||||
let self = Cable
|
let self = toExport
|
||||||
self.sub = self.cable.subscriptions.create({
|
self.sub = Cable.cable.subscriptions.create({
|
||||||
channel: 'MapChannel',
|
channel: 'MapChannel',
|
||||||
id: id
|
id: id
|
||||||
}, {
|
}, {
|
||||||
|
@ -27,7 +16,7 @@ const Cable = {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
unsubscribeFromMap: () => {
|
unsubscribeFromMap: () => {
|
||||||
let self = Cable
|
let self = toExport
|
||||||
self.sub.unsubscribe()
|
self.sub.unsubscribe()
|
||||||
delete self.sub
|
delete self.sub
|
||||||
},
|
},
|
||||||
|
@ -230,5 +219,10 @@ const Cable = {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return toExport
|
||||||
|
}
|
||||||
|
Cable.init = () => {
|
||||||
|
Cable.cable = ActionCable.createConsumer()
|
||||||
|
}
|
||||||
|
|
||||||
export default Cable
|
export default Cable
|
||||||
|
|
|
@ -1,452 +1,448 @@
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
import outdent from 'outdent'
|
import outdent from 'outdent'
|
||||||
|
|
||||||
import Active from './Active'
|
|
||||||
import DataModel from './DataModel'
|
|
||||||
import Filter from './Filter'
|
|
||||||
import GlobalUI from './GlobalUI'
|
import GlobalUI from './GlobalUI'
|
||||||
import Mouse from './Mouse'
|
|
||||||
import Selected from './Selected'
|
|
||||||
import Settings from './Settings'
|
import Settings from './Settings'
|
||||||
import Visualize from './Visualize'
|
|
||||||
|
|
||||||
const Control = {
|
const Control = ({Active, DataModel, Filter, Mouse, Selected, Visualize}) => {
|
||||||
selectNode: function(node, e) {
|
return {
|
||||||
var filtered = node.getData('alpha') === 0
|
selectNode: function(node, e) {
|
||||||
|
var filtered = node.getData('alpha') === 0
|
||||||
|
|
||||||
if (filtered || Selected.Nodes.indexOf(node) !== -1) return
|
if (filtered || Selected.Nodes.indexOf(node) !== -1) return
|
||||||
node.selected = true
|
node.selected = true
|
||||||
node.setData('dim', 30, 'current')
|
node.setData('dim', 30, 'current')
|
||||||
Selected.Nodes.push(node)
|
Selected.Nodes.push(node)
|
||||||
},
|
},
|
||||||
selectNeighbors: function() {
|
selectNeighbors: function() {
|
||||||
if (Selected.Nodes.length > 0) {
|
if (Selected.Nodes.length > 0) {
|
||||||
//For each selected node, select all connected node and the synapses too
|
//For each selected node, select all connected node and the synapses too
|
||||||
Selected.Nodes.forEach((item) => {
|
Selected.Nodes.forEach((item) => {
|
||||||
if (Visualize.mGraph.graph.getNode(item.id).adjacencies) {
|
if (Visualize.mGraph.graph.getNode(item.id).adjacencies) {
|
||||||
for (const adjID in Visualize.mGraph.graph.getNode(item.id).adjacencies) {
|
for (const adjID in Visualize.mGraph.graph.getNode(item.id).adjacencies) {
|
||||||
Control.selectNode(Visualize.mGraph.graph.getNode(adjID))
|
Control.selectNode(Visualize.mGraph.graph.getNode(adjID))
|
||||||
Control.selectEdge(Visualize.mGraph.graph.getNode(item.id).adjacencies[adjID])
|
Control.selectEdge(Visualize.mGraph.graph.getNode(item.id).adjacencies[adjID])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
})
|
|
||||||
|
|
||||||
Visualize.mGraph.plot()
|
Visualize.mGraph.plot()
|
||||||
}
|
|
||||||
},
|
|
||||||
deselectAllNodes: function() {
|
|
||||||
var l = Selected.Nodes.length
|
|
||||||
for (var i = l - 1; i >= 0; i -= 1) {
|
|
||||||
var node = Selected.Nodes[i]
|
|
||||||
Control.deselectNode(node)
|
|
||||||
}
|
|
||||||
Visualize.mGraph.plot()
|
|
||||||
},
|
|
||||||
deselectNode: function(node) {
|
|
||||||
delete node.selected
|
|
||||||
node.setData('dim', 25, 'current')
|
|
||||||
|
|
||||||
// remove the node
|
|
||||||
Selected.Nodes.splice(
|
|
||||||
Selected.Nodes.indexOf(node), 1)
|
|
||||||
},
|
|
||||||
deleteSelected: function() {
|
|
||||||
if (!Active.Map) return
|
|
||||||
|
|
||||||
var n = Selected.Nodes.length
|
|
||||||
var e = Selected.Edges.length
|
|
||||||
var ntext = n === 1 ? '1 topic' : n + ' topics'
|
|
||||||
var etext = e === 1 ? '1 synapse' : e + ' synapses'
|
|
||||||
|
|
||||||
var authorized = Active.Map.authorizeToEdit(Active.Mapper)
|
|
||||||
|
|
||||||
if (!authorized) {
|
|
||||||
GlobalUI.notifyUser('Cannot edit Public map.')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var r = window.confirm(outdent`
|
|
||||||
You have ${ntext} and ${etext} selected. Are you sure you want
|
|
||||||
to permanently delete them all? This will remove them from all
|
|
||||||
maps they appear on.`)
|
|
||||||
if (r) {
|
|
||||||
Control.deleteSelectedEdges()
|
|
||||||
Control.deleteSelectedNodes()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DataModel.Topics.length === 0) {
|
|
||||||
Map.setHasLearnedTopicCreation(false)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
deleteSelectedNodes: function() { // refers to deleting topics permanently
|
|
||||||
if (!Active.Map) return
|
|
||||||
|
|
||||||
var authorized = Active.Map.authorizeToEdit(Active.Mapper)
|
|
||||||
|
|
||||||
if (!authorized) {
|
|
||||||
GlobalUI.notifyUser('Cannot edit Public map.')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var l = Selected.Nodes.length
|
|
||||||
for (var i = l - 1; i >= 0; i -= 1) {
|
|
||||||
var node = Selected.Nodes[i]
|
|
||||||
Control.deleteNode(node.id)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
deleteNode: function(nodeid) { // refers to deleting topics permanently
|
|
||||||
if (!Active.Map) return
|
|
||||||
|
|
||||||
var authorized = Active.Map.authorizeToEdit(Active.Mapper)
|
|
||||||
|
|
||||||
if (!authorized) {
|
|
||||||
GlobalUI.notifyUser('Cannot edit Public map.')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var node = Visualize.mGraph.graph.getNode(nodeid)
|
|
||||||
var topic = node.getData('topic')
|
|
||||||
|
|
||||||
var permToDelete = Active.Mapper.id === topic.get('user_id') || Active.Mapper.get('admin')
|
|
||||||
if (permToDelete) {
|
|
||||||
var mapping = node.getData('mapping')
|
|
||||||
topic.destroy()
|
|
||||||
DataModel.Mappings.remove(mapping)
|
|
||||||
Control.hideNode(nodeid)
|
|
||||||
} else {
|
|
||||||
GlobalUI.notifyUser('Only topics you created can be deleted')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
removeSelectedNodes: function() { // refers to removing topics permanently from a map
|
|
||||||
if (Active.Topic) {
|
|
||||||
// hideNode will handle synapses as well
|
|
||||||
var nodeids = _.map(Selected.Nodes, function(node) {
|
|
||||||
return node.id
|
|
||||||
})
|
|
||||||
_.each(nodeids, function(nodeid) {
|
|
||||||
if (Active.Topic.id !== nodeid) {
|
|
||||||
DataModel.Topics.remove(nodeid)
|
|
||||||
Control.hideNode(nodeid)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (!Active.Map) return
|
|
||||||
|
|
||||||
const l = Selected.Nodes.length
|
|
||||||
const authorized = Active.Map.authorizeToEdit(Active.Mapper)
|
|
||||||
|
|
||||||
if (!authorized) {
|
|
||||||
GlobalUI.notifyUser('Cannot edit this map.')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Active.Mapper.get('follow_map_on_contributed')) {
|
|
||||||
Active.Mapper.followMap(Active.Map.id)
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = l - 1; i >= 0; i -= 1) {
|
|
||||||
const node = Selected.Nodes[i]
|
|
||||||
Control.removeNode(node.id)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
removeNode: function(nodeid) { // refers to removing topics permanently from a map
|
|
||||||
if (!Active.Map) return
|
|
||||||
|
|
||||||
var authorized = Active.Map.authorizeToEdit(Active.Mapper)
|
|
||||||
var node = Visualize.mGraph.graph.getNode(nodeid)
|
|
||||||
|
|
||||||
if (!authorized) {
|
|
||||||
GlobalUI.notifyUser('Cannot edit this map.')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Active.Mapper.get('follow_map_on_contributed')) {
|
|
||||||
Active.Mapper.followMap(Active.Map.id)
|
|
||||||
}
|
|
||||||
|
|
||||||
var topic = node.getData('topic')
|
|
||||||
var mapping = node.getData('mapping')
|
|
||||||
mapping.destroy()
|
|
||||||
DataModel.Topics.remove(topic)
|
|
||||||
Control.hideNode(nodeid)
|
|
||||||
},
|
|
||||||
hideSelectedNodes: function() {
|
|
||||||
const l = Selected.Nodes.length
|
|
||||||
for (let i = l - 1; i >= 0; i -= 1) {
|
|
||||||
const node = Selected.Nodes[i]
|
|
||||||
Control.hideNode(node.id)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
hideNode: function(nodeid) {
|
|
||||||
var node = Visualize.mGraph.graph.getNode(nodeid)
|
|
||||||
var graph = Visualize.mGraph
|
|
||||||
|
|
||||||
Control.deselectNode(node)
|
|
||||||
|
|
||||||
node.setData('alpha', 0, 'end')
|
|
||||||
node.eachAdjacency(function(adj) {
|
|
||||||
adj.setData('alpha', 0, 'end')
|
|
||||||
})
|
|
||||||
Visualize.mGraph.fx.animate({
|
|
||||||
modes: ['node-property:alpha',
|
|
||||||
'edge-property:alpha'
|
|
||||||
],
|
|
||||||
duration: 500
|
|
||||||
})
|
|
||||||
setTimeout(function() {
|
|
||||||
if (nodeid === Visualize.mGraph.root) { // && Visualize.type === "RGraph"
|
|
||||||
var newroot = _.find(graph.graph.nodes, function(n) { return n.id !== nodeid })
|
|
||||||
graph.root = newroot ? newroot.id : null
|
|
||||||
}
|
}
|
||||||
Visualize.mGraph.graph.removeNode(nodeid)
|
},
|
||||||
}, 500)
|
deselectAllNodes: function() {
|
||||||
Filter.checkMetacodes()
|
var l = Selected.Nodes.length
|
||||||
Filter.checkMappers()
|
for (var i = l - 1; i >= 0; i -= 1) {
|
||||||
},
|
var node = Selected.Nodes[i]
|
||||||
selectEdge: function(edge) {
|
Control.deselectNode(node)
|
||||||
var filtered = edge.getData('alpha') === 0 // don't select if the edge is filtered
|
}
|
||||||
|
Visualize.mGraph.plot()
|
||||||
|
},
|
||||||
|
deselectNode: function(node) {
|
||||||
|
delete node.selected
|
||||||
|
node.setData('dim', 25, 'current')
|
||||||
|
|
||||||
if (filtered || Selected.Edges.indexOf(edge) !== -1) return
|
// remove the node
|
||||||
|
Selected.Nodes.splice(
|
||||||
|
Selected.Nodes.indexOf(node), 1)
|
||||||
|
},
|
||||||
|
deleteSelected: function() {
|
||||||
|
if (!Active.Map) return
|
||||||
|
|
||||||
var width = Mouse.edgeHoveringOver === edge ? 4 : 2
|
var n = Selected.Nodes.length
|
||||||
edge.setDataset('current', {
|
var e = Selected.Edges.length
|
||||||
showDesc: true,
|
var ntext = n === 1 ? '1 topic' : n + ' topics'
|
||||||
lineWidth: width,
|
var etext = e === 1 ? '1 synapse' : e + ' synapses'
|
||||||
color: Settings.colors.synapses.selected
|
|
||||||
})
|
|
||||||
Visualize.mGraph.plot()
|
|
||||||
|
|
||||||
Selected.Edges.push(edge)
|
var authorized = Active.Map.authorizeToEdit(Active.Mapper)
|
||||||
},
|
|
||||||
deselectAllEdges: function() {
|
|
||||||
var l = Selected.Edges.length
|
|
||||||
for (var i = l - 1; i >= 0; i -= 1) {
|
|
||||||
var edge = Selected.Edges[i]
|
|
||||||
Control.deselectEdge(edge)
|
|
||||||
}
|
|
||||||
Visualize.mGraph.plot()
|
|
||||||
},
|
|
||||||
deselectEdge: function(edge) {
|
|
||||||
edge.setData('showDesc', false, 'current')
|
|
||||||
|
|
||||||
edge.setDataset('current', {
|
if (!authorized) {
|
||||||
lineWidth: 2,
|
GlobalUI.notifyUser('Cannot edit Public map.')
|
||||||
color: Settings.colors.synapses.normal
|
return
|
||||||
})
|
}
|
||||||
|
|
||||||
if (Mouse.edgeHoveringOver === edge) {
|
var r = window.confirm(outdent`
|
||||||
|
You have ${ntext} and ${etext} selected. Are you sure you want
|
||||||
|
to permanently delete them all? This will remove them from all
|
||||||
|
maps they appear on.`)
|
||||||
|
if (r) {
|
||||||
|
Control.deleteSelectedEdges()
|
||||||
|
Control.deleteSelectedNodes()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DataModel.Topics.length === 0) {
|
||||||
|
Map.setHasLearnedTopicCreation(false)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
deleteSelectedNodes: function() { // refers to deleting topics permanently
|
||||||
|
if (!Active.Map) return
|
||||||
|
|
||||||
|
var authorized = Active.Map.authorizeToEdit(Active.Mapper)
|
||||||
|
|
||||||
|
if (!authorized) {
|
||||||
|
GlobalUI.notifyUser('Cannot edit Public map.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var l = Selected.Nodes.length
|
||||||
|
for (var i = l - 1; i >= 0; i -= 1) {
|
||||||
|
var node = Selected.Nodes[i]
|
||||||
|
Control.deleteNode(node.id)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
deleteNode: function(nodeid) { // refers to deleting topics permanently
|
||||||
|
if (!Active.Map) return
|
||||||
|
|
||||||
|
var authorized = Active.Map.authorizeToEdit(Active.Mapper)
|
||||||
|
|
||||||
|
if (!authorized) {
|
||||||
|
GlobalUI.notifyUser('Cannot edit Public map.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var node = Visualize.mGraph.graph.getNode(nodeid)
|
||||||
|
var topic = node.getData('topic')
|
||||||
|
|
||||||
|
var permToDelete = Active.Mapper.id === topic.get('user_id') || Active.Mapper.get('admin')
|
||||||
|
if (permToDelete) {
|
||||||
|
var mapping = node.getData('mapping')
|
||||||
|
topic.destroy()
|
||||||
|
DataModel.Mappings.remove(mapping)
|
||||||
|
Control.hideNode(nodeid)
|
||||||
|
} else {
|
||||||
|
GlobalUI.notifyUser('Only topics you created can be deleted')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
removeSelectedNodes: function() { // refers to removing topics permanently from a map
|
||||||
|
if (Active.Topic) {
|
||||||
|
// hideNode will handle synapses as well
|
||||||
|
var nodeids = _.map(Selected.Nodes, function(node) {
|
||||||
|
return node.id
|
||||||
|
})
|
||||||
|
_.each(nodeids, function(nodeid) {
|
||||||
|
if (Active.Topic.id !== nodeid) {
|
||||||
|
DataModel.Topics.remove(nodeid)
|
||||||
|
Control.hideNode(nodeid)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!Active.Map) return
|
||||||
|
|
||||||
|
const l = Selected.Nodes.length
|
||||||
|
const authorized = Active.Map.authorizeToEdit(Active.Mapper)
|
||||||
|
|
||||||
|
if (!authorized) {
|
||||||
|
GlobalUI.notifyUser('Cannot edit this map.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Active.Mapper.get('follow_map_on_contributed')) {
|
||||||
|
Active.Mapper.followMap(Active.Map.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = l - 1; i >= 0; i -= 1) {
|
||||||
|
const node = Selected.Nodes[i]
|
||||||
|
Control.removeNode(node.id)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
removeNode: function(nodeid) { // refers to removing topics permanently from a map
|
||||||
|
if (!Active.Map) return
|
||||||
|
|
||||||
|
var authorized = Active.Map.authorizeToEdit(Active.Mapper)
|
||||||
|
var node = Visualize.mGraph.graph.getNode(nodeid)
|
||||||
|
|
||||||
|
if (!authorized) {
|
||||||
|
GlobalUI.notifyUser('Cannot edit this map.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Active.Mapper.get('follow_map_on_contributed')) {
|
||||||
|
Active.Mapper.followMap(Active.Map.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
var topic = node.getData('topic')
|
||||||
|
var mapping = node.getData('mapping')
|
||||||
|
mapping.destroy()
|
||||||
|
DataModel.Topics.remove(topic)
|
||||||
|
Control.hideNode(nodeid)
|
||||||
|
},
|
||||||
|
hideSelectedNodes: function() {
|
||||||
|
const l = Selected.Nodes.length
|
||||||
|
for (let i = l - 1; i >= 0; i -= 1) {
|
||||||
|
const node = Selected.Nodes[i]
|
||||||
|
Control.hideNode(node.id)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
hideNode: function(nodeid) {
|
||||||
|
var node = Visualize.mGraph.graph.getNode(nodeid)
|
||||||
|
var graph = Visualize.mGraph
|
||||||
|
|
||||||
|
Control.deselectNode(node)
|
||||||
|
|
||||||
|
node.setData('alpha', 0, 'end')
|
||||||
|
node.eachAdjacency(function(adj) {
|
||||||
|
adj.setData('alpha', 0, 'end')
|
||||||
|
})
|
||||||
|
Visualize.mGraph.fx.animate({
|
||||||
|
modes: ['node-property:alpha',
|
||||||
|
'edge-property:alpha'
|
||||||
|
],
|
||||||
|
duration: 500
|
||||||
|
})
|
||||||
|
setTimeout(function() {
|
||||||
|
if (nodeid === Visualize.mGraph.root) { // && Visualize.type === "RGraph"
|
||||||
|
var newroot = _.find(graph.graph.nodes, function(n) { return n.id !== nodeid })
|
||||||
|
graph.root = newroot ? newroot.id : null
|
||||||
|
}
|
||||||
|
Visualize.mGraph.graph.removeNode(nodeid)
|
||||||
|
}, 500)
|
||||||
|
Filter.checkMetacodes()
|
||||||
|
Filter.checkMappers()
|
||||||
|
},
|
||||||
|
selectEdge: function(edge) {
|
||||||
|
var filtered = edge.getData('alpha') === 0 // don't select if the edge is filtered
|
||||||
|
|
||||||
|
if (filtered || Selected.Edges.indexOf(edge) !== -1) return
|
||||||
|
|
||||||
|
var width = Mouse.edgeHoveringOver === edge ? 4 : 2
|
||||||
edge.setDataset('current', {
|
edge.setDataset('current', {
|
||||||
showDesc: true,
|
showDesc: true,
|
||||||
lineWidth: 4
|
lineWidth: width,
|
||||||
|
color: Settings.colors.synapses.selected
|
||||||
})
|
})
|
||||||
}
|
Visualize.mGraph.plot()
|
||||||
|
|
||||||
Visualize.mGraph.plot()
|
Selected.Edges.push(edge)
|
||||||
|
},
|
||||||
|
deselectAllEdges: function() {
|
||||||
|
var l = Selected.Edges.length
|
||||||
|
for (var i = l - 1; i >= 0; i -= 1) {
|
||||||
|
var edge = Selected.Edges[i]
|
||||||
|
Control.deselectEdge(edge)
|
||||||
|
}
|
||||||
|
Visualize.mGraph.plot()
|
||||||
|
},
|
||||||
|
deselectEdge: function(edge) {
|
||||||
|
edge.setData('showDesc', false, 'current')
|
||||||
|
|
||||||
// remove the edge
|
edge.setDataset('current', {
|
||||||
Selected.Edges.splice(
|
lineWidth: 2,
|
||||||
Selected.Edges.indexOf(edge), 1)
|
color: Settings.colors.synapses.normal
|
||||||
},
|
})
|
||||||
deleteSelectedEdges: function() { // refers to deleting topics permanently
|
|
||||||
if (!Active.Map) return
|
|
||||||
|
|
||||||
var authorized = Active.Map.authorizeToEdit(Active.Mapper)
|
if (Mouse.edgeHoveringOver === edge) {
|
||||||
|
edge.setDataset('current', {
|
||||||
|
showDesc: true,
|
||||||
|
lineWidth: 4
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
if (!authorized) {
|
Visualize.mGraph.plot()
|
||||||
GlobalUI.notifyUser('Cannot edit Public map.')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const l = Selected.Edges.length
|
// remove the edge
|
||||||
for (let i = l - 1; i >= 0; i -= 1) {
|
Selected.Edges.splice(
|
||||||
const edge = Selected.Edges[i]
|
Selected.Edges.indexOf(edge), 1)
|
||||||
Control.deleteEdge(edge)
|
},
|
||||||
}
|
deleteSelectedEdges: function() { // refers to deleting topics permanently
|
||||||
},
|
if (!Active.Map) return
|
||||||
deleteEdge: function(edge) {
|
|
||||||
if (!Active.Map) return
|
|
||||||
|
|
||||||
var authorized = Active.Map.authorizeToEdit(Active.Mapper)
|
var authorized = Active.Map.authorizeToEdit(Active.Mapper)
|
||||||
|
|
||||||
if (!authorized) {
|
if (!authorized) {
|
||||||
GlobalUI.notifyUser('Cannot edit Public map.')
|
GlobalUI.notifyUser('Cannot edit Public map.')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var index = edge.getData('displayIndex') ? edge.getData('displayIndex') : 0
|
const l = Selected.Edges.length
|
||||||
|
for (let i = l - 1; i >= 0; i -= 1) {
|
||||||
|
const edge = Selected.Edges[i]
|
||||||
|
Control.deleteEdge(edge)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
deleteEdge: function(edge) {
|
||||||
|
if (!Active.Map) return
|
||||||
|
|
||||||
var synapse = edge.getData('synapses')[index]
|
var authorized = Active.Map.authorizeToEdit(Active.Mapper)
|
||||||
var mapping = edge.getData('mappings')[index]
|
|
||||||
|
|
||||||
var permToDelete = Active.Mapper.id === synapse.get('user_id') || Active.Mapper.get('admin')
|
if (!authorized) {
|
||||||
if (permToDelete) {
|
GlobalUI.notifyUser('Cannot edit Public map.')
|
||||||
if (edge.getData('synapses').length - 1 === 0) {
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var index = edge.getData('displayIndex') ? edge.getData('displayIndex') : 0
|
||||||
|
|
||||||
|
var synapse = edge.getData('synapses')[index]
|
||||||
|
var mapping = edge.getData('mappings')[index]
|
||||||
|
|
||||||
|
var permToDelete = Active.Mapper.id === synapse.get('user_id') || Active.Mapper.get('admin')
|
||||||
|
if (permToDelete) {
|
||||||
|
if (edge.getData('synapses').length - 1 === 0) {
|
||||||
|
Control.hideEdge(edge)
|
||||||
|
}
|
||||||
|
synapse.destroy()
|
||||||
|
|
||||||
|
// the server will destroy the mapping, we just need to remove it here
|
||||||
|
DataModel.Mappings.remove(mapping)
|
||||||
|
edge.getData('mappings').splice(index, 1)
|
||||||
|
edge.getData('synapses').splice(index, 1)
|
||||||
|
if (edge.getData('displayIndex')) {
|
||||||
|
delete edge.data.$displayIndex
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
GlobalUI.notifyUser('Only synapses you created can be deleted')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
removeSelectedEdges: function() {
|
||||||
|
// Topic view is handled by removeSelectedNodes
|
||||||
|
if (!Active.Map) return
|
||||||
|
|
||||||
|
const l = Selected.Edges.length
|
||||||
|
|
||||||
|
var authorized = Active.Map.authorizeToEdit(Active.Mapper)
|
||||||
|
|
||||||
|
if (!authorized) {
|
||||||
|
GlobalUI.notifyUser('Cannot edit this map.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Active.Mapper.get('follow_map_on_contributed')) {
|
||||||
|
Active.Mapper.followMap(Active.Map.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = l - 1; i >= 0; i -= 1) {
|
||||||
|
const edge = Selected.Edges[i]
|
||||||
|
Control.removeEdge(edge)
|
||||||
|
}
|
||||||
|
Selected.Edges = [ ]
|
||||||
|
},
|
||||||
|
removeEdge: function(edge) {
|
||||||
|
if (!Active.Map) return
|
||||||
|
|
||||||
|
var authorized = Active.Map.authorizeToEdit(Active.Mapper)
|
||||||
|
|
||||||
|
if (!authorized) {
|
||||||
|
GlobalUI.notifyUser('Cannot edit this map.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Active.Mapper.get('follow_map_on_contributed')) {
|
||||||
|
Active.Mapper.followMap(Active.Map.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (edge.getData('mappings').length - 1 === 0) {
|
||||||
Control.hideEdge(edge)
|
Control.hideEdge(edge)
|
||||||
}
|
}
|
||||||
synapse.destroy()
|
|
||||||
|
|
||||||
// the server will destroy the mapping, we just need to remove it here
|
var index = edge.getData('displayIndex') ? edge.getData('displayIndex') : 0
|
||||||
DataModel.Mappings.remove(mapping)
|
|
||||||
|
var synapse = edge.getData('synapses')[index]
|
||||||
|
var mapping = edge.getData('mappings')[index]
|
||||||
|
mapping.destroy()
|
||||||
|
|
||||||
|
DataModel.Synapses.remove(synapse)
|
||||||
|
|
||||||
edge.getData('mappings').splice(index, 1)
|
edge.getData('mappings').splice(index, 1)
|
||||||
edge.getData('synapses').splice(index, 1)
|
edge.getData('synapses').splice(index, 1)
|
||||||
if (edge.getData('displayIndex')) {
|
if (edge.getData('displayIndex')) {
|
||||||
delete edge.data.$displayIndex
|
delete edge.data.$displayIndex
|
||||||
}
|
}
|
||||||
} else {
|
},
|
||||||
GlobalUI.notifyUser('Only synapses you created can be deleted')
|
hideSelectedEdges: function() {
|
||||||
}
|
const l = Selected.Edges.length
|
||||||
},
|
for (let i = l - 1; i >= 0; i -= 1) {
|
||||||
removeSelectedEdges: function() {
|
const edge = Selected.Edges[i]
|
||||||
// Topic view is handled by removeSelectedNodes
|
Control.hideEdge(edge)
|
||||||
if (!Active.Map) return
|
|
||||||
|
|
||||||
const l = Selected.Edges.length
|
|
||||||
|
|
||||||
var authorized = Active.Map.authorizeToEdit(Active.Mapper)
|
|
||||||
|
|
||||||
if (!authorized) {
|
|
||||||
GlobalUI.notifyUser('Cannot edit this map.')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Active.Mapper.get('follow_map_on_contributed')) {
|
|
||||||
Active.Mapper.followMap(Active.Map.id)
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = l - 1; i >= 0; i -= 1) {
|
|
||||||
const edge = Selected.Edges[i]
|
|
||||||
Control.removeEdge(edge)
|
|
||||||
}
|
|
||||||
Selected.Edges = [ ]
|
|
||||||
},
|
|
||||||
removeEdge: function(edge) {
|
|
||||||
if (!Active.Map) return
|
|
||||||
|
|
||||||
var authorized = Active.Map.authorizeToEdit(Active.Mapper)
|
|
||||||
|
|
||||||
if (!authorized) {
|
|
||||||
GlobalUI.notifyUser('Cannot edit this map.')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Active.Mapper.get('follow_map_on_contributed')) {
|
|
||||||
Active.Mapper.followMap(Active.Map.id)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (edge.getData('mappings').length - 1 === 0) {
|
|
||||||
Control.hideEdge(edge)
|
|
||||||
}
|
|
||||||
|
|
||||||
var index = edge.getData('displayIndex') ? edge.getData('displayIndex') : 0
|
|
||||||
|
|
||||||
var synapse = edge.getData('synapses')[index]
|
|
||||||
var mapping = edge.getData('mappings')[index]
|
|
||||||
mapping.destroy()
|
|
||||||
|
|
||||||
DataModel.Synapses.remove(synapse)
|
|
||||||
|
|
||||||
edge.getData('mappings').splice(index, 1)
|
|
||||||
edge.getData('synapses').splice(index, 1)
|
|
||||||
if (edge.getData('displayIndex')) {
|
|
||||||
delete edge.data.$displayIndex
|
|
||||||
}
|
|
||||||
},
|
|
||||||
hideSelectedEdges: function() {
|
|
||||||
const l = Selected.Edges.length
|
|
||||||
for (let i = l - 1; i >= 0; i -= 1) {
|
|
||||||
const edge = Selected.Edges[i]
|
|
||||||
Control.hideEdge(edge)
|
|
||||||
}
|
|
||||||
Selected.Edges = [ ]
|
|
||||||
},
|
|
||||||
hideEdge: function(edge) {
|
|
||||||
var from = edge.nodeFrom.id
|
|
||||||
var to = edge.nodeTo.id
|
|
||||||
edge.setData('alpha', 0, 'end')
|
|
||||||
Control.deselectEdge(edge)
|
|
||||||
Visualize.mGraph.fx.animate({
|
|
||||||
modes: ['edge-property:alpha'],
|
|
||||||
duration: 500
|
|
||||||
})
|
|
||||||
setTimeout(function() {
|
|
||||||
Visualize.mGraph.graph.removeAdjacence(from, to)
|
|
||||||
}, 500)
|
|
||||||
Filter.checkSynapses()
|
|
||||||
Filter.checkMappers()
|
|
||||||
},
|
|
||||||
updateSelectedPermissions: function(permission) {
|
|
||||||
var edge, synapse, node, topic
|
|
||||||
|
|
||||||
GlobalUI.notifyUser('Working...')
|
|
||||||
|
|
||||||
// variables to keep track of how many nodes and synapses you had the ability to change the permission of
|
|
||||||
var nCount = 0
|
|
||||||
var sCount = 0
|
|
||||||
|
|
||||||
// change the permission of the selected synapses, if logged in user is the original creator
|
|
||||||
const edgesLength = Selected.Edges.length
|
|
||||||
for (let i = edgesLength - 1; i >= 0; i -= 1) {
|
|
||||||
edge = Selected.Edges[i]
|
|
||||||
synapse = edge.getData('synapses')[0]
|
|
||||||
|
|
||||||
if (synapse.authorizePermissionChange(Active.Mapper)) {
|
|
||||||
synapse.save({
|
|
||||||
permission: permission
|
|
||||||
})
|
|
||||||
sCount++
|
|
||||||
}
|
}
|
||||||
}
|
Selected.Edges = [ ]
|
||||||
|
},
|
||||||
|
hideEdge: function(edge) {
|
||||||
|
var from = edge.nodeFrom.id
|
||||||
|
var to = edge.nodeTo.id
|
||||||
|
edge.setData('alpha', 0, 'end')
|
||||||
|
Control.deselectEdge(edge)
|
||||||
|
Visualize.mGraph.fx.animate({
|
||||||
|
modes: ['edge-property:alpha'],
|
||||||
|
duration: 500
|
||||||
|
})
|
||||||
|
setTimeout(function() {
|
||||||
|
Visualize.mGraph.graph.removeAdjacence(from, to)
|
||||||
|
}, 500)
|
||||||
|
Filter.checkSynapses()
|
||||||
|
Filter.checkMappers()
|
||||||
|
},
|
||||||
|
updateSelectedPermissions: function(permission) {
|
||||||
|
var edge, synapse, node, topic
|
||||||
|
|
||||||
// change the permission of the selected topics, if logged in user is the original creator
|
GlobalUI.notifyUser('Working...')
|
||||||
const nodesLength = Selected.Nodes.length
|
|
||||||
for (let i = nodesLength - 1; i >= 0; i -= 1) {
|
|
||||||
node = Selected.Nodes[i]
|
|
||||||
topic = node.getData('topic')
|
|
||||||
|
|
||||||
if (topic.authorizePermissionChange(Active.Mapper)) {
|
// variables to keep track of how many nodes and synapses you had the ability to change the permission of
|
||||||
topic.save({
|
var nCount = 0
|
||||||
permission: permission
|
var sCount = 0
|
||||||
})
|
|
||||||
nCount++
|
// change the permission of the selected synapses, if logged in user is the original creator
|
||||||
|
const edgesLength = Selected.Edges.length
|
||||||
|
for (let i = edgesLength - 1; i >= 0; i -= 1) {
|
||||||
|
edge = Selected.Edges[i]
|
||||||
|
synapse = edge.getData('synapses')[0]
|
||||||
|
|
||||||
|
if (synapse.authorizePermissionChange(Active.Mapper)) {
|
||||||
|
synapse.save({
|
||||||
|
permission: permission
|
||||||
|
})
|
||||||
|
sCount++
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
var nString = nCount === 1 ? (nCount.toString() + ' topic and ') : (nCount.toString() + ' topics and ')
|
// change the permission of the selected topics, if logged in user is the original creator
|
||||||
var sString = sCount === 1 ? (sCount.toString() + ' synapse') : (sCount.toString() + ' synapses')
|
const nodesLength = Selected.Nodes.length
|
||||||
|
for (let i = nodesLength - 1; i >= 0; i -= 1) {
|
||||||
|
node = Selected.Nodes[i]
|
||||||
|
topic = node.getData('topic')
|
||||||
|
|
||||||
var message = nString + sString + ' you created updated to ' + permission
|
if (topic.authorizePermissionChange(Active.Mapper)) {
|
||||||
GlobalUI.notifyUser(message)
|
topic.save({
|
||||||
},
|
permission: permission
|
||||||
updateSelectedMetacodes: function(metacodeId) {
|
})
|
||||||
var node, topic
|
nCount++
|
||||||
|
}
|
||||||
GlobalUI.notifyUser('Working...')
|
|
||||||
|
|
||||||
var metacode = DataModel.Metacodes.get(metacodeId)
|
|
||||||
|
|
||||||
// variables to keep track of how many nodes and synapses you had the ability to change the permission of
|
|
||||||
var nCount = 0
|
|
||||||
|
|
||||||
// change the permission of the selected topics, if logged in user is the original creator
|
|
||||||
var l = Selected.Nodes.length
|
|
||||||
for (var i = l - 1; i >= 0; i -= 1) {
|
|
||||||
node = Selected.Nodes[i]
|
|
||||||
topic = node.getData('topic')
|
|
||||||
|
|
||||||
if (topic.authorizeToEdit(Active.Mapper)) {
|
|
||||||
topic.save({
|
|
||||||
'metacode_id': metacodeId
|
|
||||||
})
|
|
||||||
nCount++
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var nString = nCount === 1 ? (nCount.toString() + ' topic and ') : (nCount.toString() + ' topics and ')
|
||||||
|
var sString = sCount === 1 ? (sCount.toString() + ' synapse') : (sCount.toString() + ' synapses')
|
||||||
|
|
||||||
|
var message = nString + sString + ' you created updated to ' + permission
|
||||||
|
GlobalUI.notifyUser(message)
|
||||||
|
},
|
||||||
|
updateSelectedMetacodes: function(metacodeId) {
|
||||||
|
var node, topic
|
||||||
|
|
||||||
|
GlobalUI.notifyUser('Working...')
|
||||||
|
|
||||||
|
var metacode = DataModel.Metacodes.get(metacodeId)
|
||||||
|
|
||||||
|
// variables to keep track of how many nodes and synapses you had the ability to change the permission of
|
||||||
|
var nCount = 0
|
||||||
|
|
||||||
|
// change the permission of the selected topics, if logged in user is the original creator
|
||||||
|
var l = Selected.Nodes.length
|
||||||
|
for (var i = l - 1; i >= 0; i -= 1) {
|
||||||
|
node = Selected.Nodes[i]
|
||||||
|
topic = node.getData('topic')
|
||||||
|
|
||||||
|
if (topic.authorizeToEdit(Active.Mapper)) {
|
||||||
|
topic.save({
|
||||||
|
'metacode_id': metacodeId
|
||||||
|
})
|
||||||
|
nCount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var nString = nCount === 1 ? (nCount.toString() + ' topic') : (nCount.toString() + ' topics')
|
||||||
|
|
||||||
|
var message = nString + ' you can edit updated to ' + metacode.get('name')
|
||||||
|
GlobalUI.notifyUser(message)
|
||||||
|
Visualize.mGraph.plot()
|
||||||
}
|
}
|
||||||
|
|
||||||
var nString = nCount === 1 ? (nCount.toString() + ' topic') : (nCount.toString() + ' topics')
|
|
||||||
|
|
||||||
var message = nString + ' you can edit updated to ' + metacode.get('name')
|
|
||||||
GlobalUI.notifyUser(message)
|
|
||||||
Visualize.mGraph.plot()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,9 @@
|
||||||
/* global $, Hogan, Bloodhound */
|
/* global $, Hogan, Bloodhound */
|
||||||
|
|
||||||
import DataModel from './DataModel'
|
|
||||||
import Map from './Map'
|
|
||||||
import Mouse from './Mouse'
|
|
||||||
import Selected from './Selected'
|
|
||||||
import Synapse from './Synapse'
|
|
||||||
import Topic from './Topic'
|
|
||||||
import Visualize from './Visualize'
|
|
||||||
import GlobalUI from './GlobalUI'
|
import GlobalUI from './GlobalUI'
|
||||||
|
|
||||||
const Create = {
|
const toExport = ({DataModel, Map, Mouse, Selected, Synapse, Topic, Visualize}) => {
|
||||||
|
const toExport = {
|
||||||
isSwitchingSet: false, // indicates whether the metacode set switch lightbox is open
|
isSwitchingSet: false, // indicates whether the metacode set switch lightbox is open
|
||||||
selectedMetacodeSet: null,
|
selectedMetacodeSet: null,
|
||||||
selectedMetacodeSetIndex: null,
|
selectedMetacodeSetIndex: null,
|
||||||
|
@ -17,52 +11,54 @@ const Create = {
|
||||||
newSelectedMetacodeNames: [],
|
newSelectedMetacodeNames: [],
|
||||||
selectedMetacodes: [],
|
selectedMetacodes: [],
|
||||||
newSelectedMetacodes: [],
|
newSelectedMetacodes: [],
|
||||||
init: function() {
|
init: function(serverData) {
|
||||||
var self = Create
|
toExport.newTopic.init()
|
||||||
self.newTopic.init()
|
toExport.newSynapse.init()
|
||||||
self.newSynapse.init()
|
toExport.selectedMetacodeSet = serverData.selectedMetacodeSet
|
||||||
|
toExport.selectedMetacodeSetIndex = serverData.selectedMetacodeSetIndex
|
||||||
|
toExport.selectedMetacodes = serverData.selectedMetacodes
|
||||||
|
toExport.newSelectedMetacodes = serverData.newSelectedMetacodes
|
||||||
|
toExport.selectedMetacodeNames = serverData.newSelectedMetacodeNames
|
||||||
|
toExport.newSelectedMetacodeNames = serverData.newSelectedMetacodeNames
|
||||||
// // SWITCHING METACODE SETS
|
// // SWITCHING METACODE SETS
|
||||||
|
|
||||||
$('#metacodeSwitchTabs').tabs({
|
$('#metacodeSwitchTabs').tabs({
|
||||||
active: self.selectedMetacodeSetIndex
|
active: toExport.selectedMetacodeSetIndex
|
||||||
}).addClass('ui-tabs-vertical ui-helper-clearfix')
|
}).addClass('ui-tabs-vertical ui-helper-clearfix')
|
||||||
$('#metacodeSwitchTabs .ui-tabs-nav li').removeClass('ui-corner-top').addClass('ui-corner-left')
|
$('#metacodeSwitchTabs .ui-tabs-nav li').removeClass('ui-corner-top').addClass('ui-corner-left')
|
||||||
$('.customMetacodeList li').click(self.toggleMetacodeSelected) // within the custom metacode set tab
|
$('.customMetacodeList li').click(toExport.toggleMetacodeSelected) // within the custom metacode set tab
|
||||||
$('.selectAll').click(self.metacodeSelectorSelectAll)
|
$('.selectAll').click(toExport.metacodeSelectorSelectAll)
|
||||||
$('.selectNone').click(self.metacodeSelectorSelectNone)
|
$('.selectNone').click(toExport.metacodeSelectorSelectNone)
|
||||||
},
|
},
|
||||||
toggleMetacodeSelected: function() {
|
toggleMetacodeSelected: function() {
|
||||||
var self = Create
|
|
||||||
|
|
||||||
if ($(this).attr('class') !== 'toggledOff') {
|
if ($(this).attr('class') !== 'toggledOff') {
|
||||||
$(this).addClass('toggledOff')
|
$(this).addClass('toggledOff')
|
||||||
var valueToRemove = $(this).attr('id')
|
var valueToRemove = $(this).attr('id')
|
||||||
var nameToRemove = $(this).attr('data-name')
|
var nameToRemove = $(this).attr('data-name')
|
||||||
self.newSelectedMetacodes.splice(self.newSelectedMetacodes.indexOf(valueToRemove), 1)
|
toExport.newSelectedMetacodes.splice(self.newSelectedMetacodes.indexOf(valueToRemove), 1)
|
||||||
self.newSelectedMetacodeNames.splice(self.newSelectedMetacodeNames.indexOf(nameToRemove), 1)
|
toExport.newSelectedMetacodeNames.splice(self.newSelectedMetacodeNames.indexOf(nameToRemove), 1)
|
||||||
} else if ($(this).attr('class') === 'toggledOff') {
|
} else if ($(this).attr('class') === 'toggledOff') {
|
||||||
$(this).removeClass('toggledOff')
|
$(this).removeClass('toggledOff')
|
||||||
self.newSelectedMetacodes.push($(this).attr('id'))
|
toExport.newSelectedMetacodes.push($(this).attr('id'))
|
||||||
self.newSelectedMetacodeNames.push($(this).attr('data-name'))
|
toExport.newSelectedMetacodeNames.push($(this).attr('data-name'))
|
||||||
}
|
}
|
||||||
self.updateSelectAllColors()
|
toExport.updateSelectAllColors()
|
||||||
},
|
},
|
||||||
updateSelectAllColors: function() {
|
updateSelectAllColors: function() {
|
||||||
$('.selectAll, .selectNone').removeClass('selected')
|
$('.selectAll, .selectNone').removeClass('selected')
|
||||||
if (Create.metacodeSelectorAreAllSelected()) {
|
if (toExport.metacodeSelectorAreAllSelected()) {
|
||||||
$('.selectAll').addClass('selected')
|
$('.selectAll').addClass('selected')
|
||||||
} else if (Create.metacodeSelectorAreNoneSelected()) {
|
} else if (toExport.metacodeSelectorAreNoneSelected()) {
|
||||||
$('.selectNone').addClass('selected')
|
$('.selectNone').addClass('selected')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
metacodeSelectorSelectAll: function() {
|
metacodeSelectorSelectAll: function() {
|
||||||
$('.customMetacodeList li.toggledOff').each(Create.toggleMetacodeSelected)
|
$('.customMetacodeList li.toggledOff').each(toExport.toggleMetacodeSelected)
|
||||||
Create.updateSelectAllColors()
|
toExport.updateSelectAllColors()
|
||||||
},
|
},
|
||||||
metacodeSelectorSelectNone: function() {
|
metacodeSelectorSelectNone: function() {
|
||||||
$('.customMetacodeList li').not('.toggledOff').each(Create.toggleMetacodeSelected)
|
$('.customMetacodeList li').not('.toggledOff').each(toExport.toggleMetacodeSelected)
|
||||||
Create.updateSelectAllColors()
|
toExport.updateSelectAllColors()
|
||||||
},
|
},
|
||||||
metacodeSelectorAreAllSelected: function() {
|
metacodeSelectorAreAllSelected: function() {
|
||||||
return $('.customMetacodeList li').toArray()
|
return $('.customMetacodeList li').toArray()
|
||||||
|
@ -75,41 +71,41 @@ const Create = {
|
||||||
.reduce((curr, prev) => curr && prev)
|
.reduce((curr, prev) => curr && prev)
|
||||||
},
|
},
|
||||||
metacodeSelectorToggleSelectAll: function() {
|
metacodeSelectorToggleSelectAll: function() {
|
||||||
// should be called when Create.isSwitchingSet is true and .customMetacodeList is visible
|
// should be called when toExport.isSwitchingSet is true and .customMetacodeList is visible
|
||||||
if (!Create.isSwitchingSet) return
|
if (!toExport.isSwitchingSet) return
|
||||||
if (!$('.customMetacodeList').is(':visible')) return
|
if (!$('.customMetacodeList').is(':visible')) return
|
||||||
|
|
||||||
// If all are selected, then select none. Otherwise, select all.
|
// If all are selected, then select none. Otherwise, select all.
|
||||||
if (Create.metacodeSelectorAreAllSelected()) {
|
if (toExport.metacodeSelectorAreAllSelected()) {
|
||||||
Create.metacodeSelectorSelectNone()
|
toExport.metacodeSelectorSelectNone()
|
||||||
} else {
|
} else {
|
||||||
// if some, but not all, are selected, it still runs this function
|
// if some, but not all, are selected, it still runs this function
|
||||||
Create.metacodeSelectorSelectAll()
|
toExport.metacodeSelectorSelectAll()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
updateMetacodeSet: function(set, index, custom) {
|
updateMetacodeSet: function(set, index, custom) {
|
||||||
if (custom && Create.newSelectedMetacodes.length === 0) {
|
if (custom && toExport.newSelectedMetacodes.length === 0) {
|
||||||
window.alert('Please select at least one metacode to use!')
|
window.alert('Please select at least one metacode to use!')
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
var codesToSwitchToIds
|
var codesToSwitchToIds
|
||||||
var metacodeModels = new DataModel.MetacodeCollection()
|
var metacodeModels = new DataModel.MetacodeCollection()
|
||||||
Create.selectedMetacodeSetIndex = index
|
toExport.selectedMetacodeSetIndex = index
|
||||||
Create.selectedMetacodeSet = 'metacodeset-' + set
|
toExport.selectedMetacodeSet = 'metacodeset-' + set
|
||||||
|
|
||||||
if (!custom) {
|
if (!custom) {
|
||||||
codesToSwitchToIds = $('#metacodeSwitchTabs' + set).attr('data-metacodes').split(',')
|
codesToSwitchToIds = $('#metacodeSwitchTabs' + set).attr('data-metacodes').split(',')
|
||||||
$('.customMetacodeList li').addClass('toggledOff')
|
$('.customMetacodeList li').addClass('toggledOff')
|
||||||
Create.selectedMetacodes = []
|
toExport.selectedMetacodes = []
|
||||||
Create.selectedMetacodeNames = []
|
toExport.selectedMetacodeNames = []
|
||||||
Create.newSelectedMetacodes = []
|
toExport.newSelectedMetacodes = []
|
||||||
Create.newSelectedMetacodeNames = []
|
toExport.newSelectedMetacodeNames = []
|
||||||
} else if (custom) {
|
} else if (custom) {
|
||||||
// uses .slice to avoid setting the two arrays to the same actual array
|
// uses .slice to avoid setting the two arrays to the same actual array
|
||||||
Create.selectedMetacodes = Create.newSelectedMetacodes.slice(0)
|
toExport.selectedMetacodes = Create.newSelectedMetacodes.slice(0)
|
||||||
Create.selectedMetacodeNames = Create.newSelectedMetacodeNames.slice(0)
|
toExport.selectedMetacodeNames = Create.newSelectedMetacodeNames.slice(0)
|
||||||
codesToSwitchToIds = Create.selectedMetacodes.slice(0)
|
codesToSwitchToIds = toExport.selectedMetacodes.slice(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// sort by name
|
// sort by name
|
||||||
|
@ -141,7 +137,7 @@ const Create = {
|
||||||
|
|
||||||
var mdata = {
|
var mdata = {
|
||||||
'metacodes': {
|
'metacodes': {
|
||||||
'value': custom ? Create.selectedMetacodes.toString() : Create.selectedMetacodeSet
|
'value': custom ? toExport.selectedMetacodes.toString() : Create.selectedMetacodeSet
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$.ajax({
|
$.ajax({
|
||||||
|
@ -158,26 +154,25 @@ const Create = {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
cancelMetacodeSetSwitch: function() {
|
cancelMetacodeSetSwitch: function() {
|
||||||
var self = Create
|
toExport.isSwitchingSet = false
|
||||||
self.isSwitchingSet = false
|
|
||||||
|
|
||||||
if (self.selectedMetacodeSet !== 'metacodeset-custom') {
|
if (toExport.selectedMetacodeSet !== 'metacodeset-custom') {
|
||||||
$('.customMetacodeList li').addClass('toggledOff')
|
$('.customMetacodeList li').addClass('toggledOff')
|
||||||
self.selectedMetacodes = []
|
toExport.selectedMetacodes = []
|
||||||
self.selectedMetacodeNames = []
|
toExport.selectedMetacodeNames = []
|
||||||
self.newSelectedMetacodes = []
|
toExport.newSelectedMetacodes = []
|
||||||
self.newSelectedMetacodeNames = []
|
toExport.newSelectedMetacodeNames = []
|
||||||
} else { // custom set is selected
|
} else { // custom set is selected
|
||||||
// reset it to the current actual selection
|
// reset it to the current actual selection
|
||||||
$('.customMetacodeList li').addClass('toggledOff')
|
$('.customMetacodeList li').addClass('toggledOff')
|
||||||
for (var i = 0; i < self.selectedMetacodes.length; i++) {
|
for (var i = 0; i < toExport.selectedMetacodes.length; i++) {
|
||||||
$('#' + self.selectedMetacodes[i]).removeClass('toggledOff')
|
$('#' + toExport.selectedMetacodes[i]).removeClass('toggledOff')
|
||||||
}
|
}
|
||||||
// uses .slice to avoid setting the two arrays to the same actual array
|
// uses .slice to avoid setting the two arrays to the same actual array
|
||||||
self.newSelectedMetacodeNames = self.selectedMetacodeNames.slice(0)
|
toExport.newSelectedMetacodeNames = self.selectedMetacodeNames.slice(0)
|
||||||
self.newSelectedMetacodes = self.selectedMetacodes.slice(0)
|
toExport.newSelectedMetacodes = self.selectedMetacodes.slice(0)
|
||||||
}
|
}
|
||||||
$('#metacodeSwitchTabs').tabs('option', 'active', self.selectedMetacodeSetIndex)
|
$('#metacodeSwitchTabs').tabs('option', 'active', toExport.selectedMetacodeSetIndex)
|
||||||
$('#topic_name').focus()
|
$('#topic_name').focus()
|
||||||
},
|
},
|
||||||
newTopic: {
|
newTopic: {
|
||||||
|
@ -186,19 +181,19 @@ const Create = {
|
||||||
const ESC = 27
|
const ESC = 27
|
||||||
|
|
||||||
if (e.keyCode === ESC) {
|
if (e.keyCode === ESC) {
|
||||||
Create.newTopic.hide()
|
toExport.newTopic.hide()
|
||||||
} // if
|
} // if
|
||||||
|
|
||||||
Create.newTopic.name = $(this).val()
|
toExport.newTopic.name = $(this).val()
|
||||||
})
|
})
|
||||||
|
|
||||||
$('.pinCarousel').click(function() {
|
$('.pinCarousel').click(function() {
|
||||||
if (Create.newTopic.pinned) {
|
if (toExport.newTopic.pinned) {
|
||||||
$('.pinCarousel').removeClass('isPinned')
|
$('.pinCarousel').removeClass('isPinned')
|
||||||
Create.newTopic.pinned = false
|
toExport.newTopic.pinned = false
|
||||||
} else {
|
} else {
|
||||||
$('.pinCarousel').addClass('isPinned')
|
$('.pinCarousel').addClass('isPinned')
|
||||||
Create.newTopic.pinned = true
|
toExport.newTopic.pinned = true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -232,7 +227,7 @@ const Create = {
|
||||||
|
|
||||||
// tell the autocomplete to submit the form with the topic you clicked on if you pick from the autocomplete
|
// tell the autocomplete to submit the form with the topic you clicked on if you pick from the autocomplete
|
||||||
$('#topic_name').bind('typeahead:select', function(event, datum, dataset) {
|
$('#topic_name').bind('typeahead:select', function(event, datum, dataset) {
|
||||||
Create.newTopic.beingCreated = false
|
toExport.newTopic.beingCreated = false
|
||||||
if (datum.rtype === 'topic') {
|
if (datum.rtype === 'topic') {
|
||||||
Topic.getTopicFromAutocomplete(datum.id)
|
Topic.getTopicFromAutocomplete(datum.id)
|
||||||
} else if (datum.rtype === 'map') {
|
} else if (datum.rtype === 'map') {
|
||||||
|
@ -259,7 +254,7 @@ const Create = {
|
||||||
},
|
},
|
||||||
name: null,
|
name: null,
|
||||||
newId: 1,
|
newId: 1,
|
||||||
beingCreated: false,
|
beingtoExportd: false,
|
||||||
metacode: null,
|
metacode: null,
|
||||||
x: null,
|
x: null,
|
||||||
y: null,
|
y: null,
|
||||||
|
@ -269,22 +264,22 @@ const Create = {
|
||||||
$('#new_topic').fadeIn('fast', function() {
|
$('#new_topic').fadeIn('fast', function() {
|
||||||
$('#topic_name').focus()
|
$('#topic_name').focus()
|
||||||
})
|
})
|
||||||
Create.newTopic.beingCreated = true
|
toExport.newTopic.beingCreated = true
|
||||||
Create.newTopic.name = ''
|
toExport.newTopic.name = ''
|
||||||
Map.setHasLearnedTopicCreation(true)
|
//Map.setHasLearnedTopicCreation(true)
|
||||||
},
|
},
|
||||||
hide: function(force) {
|
hide: function(force) {
|
||||||
if (force || !Create.newTopic.pinned) {
|
if (force || !toExport.newTopic.pinned) {
|
||||||
$('#new_topic').fadeOut('fast')
|
$('#new_topic').fadeOut('fast')
|
||||||
}
|
}
|
||||||
if (force) {
|
if (force) {
|
||||||
$('.pinCarousel').removeClass('isPinned')
|
$('.pinCarousel').removeClass('isPinned')
|
||||||
Create.newTopic.pinned = false
|
toExport.newTopic.pinned = false
|
||||||
}
|
}
|
||||||
if (DataModel.Topics.length === 0) {
|
if (DataModel.Topics.length === 0) {
|
||||||
Map.setHasLearnedTopicCreation(false)
|
Map.setHasLearnedTopicCreation(false)
|
||||||
}
|
}
|
||||||
Create.newTopic.beingCreated = false
|
toExport.newTopic.beingCreated = false
|
||||||
},
|
},
|
||||||
reset: function() {
|
reset: function() {
|
||||||
$('#topic_name').typeahead('val', '')
|
$('#topic_name').typeahead('val', '')
|
||||||
|
@ -306,9 +301,8 @@ const Create = {
|
||||||
remote: {
|
remote: {
|
||||||
url: '/search/synapses?topic1id=%TOPIC1&topic2id=%TOPIC2',
|
url: '/search/synapses?topic1id=%TOPIC1&topic2id=%TOPIC2',
|
||||||
prepare: function(query, settings) {
|
prepare: function(query, settings) {
|
||||||
var self = Create.newSynapse
|
if (Selected.Nodes.length < 2 && toExport.newSynapse.topic1id && self.newSynapse.topic2id) {
|
||||||
if (Selected.Nodes.length < 2 && self.topic1id && self.topic2id) {
|
settings.url = settings.url.replace('%TOPIC1', toExport.newSynapse.topic1id).replace('%TOPIC2', toExport.newSynapse.topic2id)
|
||||||
settings.url = settings.url.replace('%TOPIC1', self.topic1id).replace('%TOPIC2', self.topic2id)
|
|
||||||
return settings
|
return settings
|
||||||
} else {
|
} else {
|
||||||
return null
|
return null
|
||||||
|
@ -351,21 +345,21 @@ const Create = {
|
||||||
const ESC = 27
|
const ESC = 27
|
||||||
|
|
||||||
if (e.keyCode === ESC) {
|
if (e.keyCode === ESC) {
|
||||||
Create.newSynapse.hide()
|
toExport.newSynapse.hide()
|
||||||
} // if
|
} // if
|
||||||
|
|
||||||
Create.newSynapse.description = $(this).val()
|
toExport.newSynapse.description = $(this).val()
|
||||||
})
|
})
|
||||||
|
|
||||||
$('#synapse_desc').focusout(function() {
|
$('#synapse_desc').focusout(function() {
|
||||||
if (Create.newSynapse.beingCreated) {
|
if (toExport.newSynapse.beingCreated) {
|
||||||
Synapse.createSynapseLocally()
|
Synapse.createSynapseLocally()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
$('#synapse_desc').keydown(function(e) {
|
$('#synapse_desc').keydown(function(e) {
|
||||||
const TAB = 9
|
const TAB = 9
|
||||||
if (Create.newSynapse.beingCreated && e.keyCode === TAB) {
|
if (toExport.newSynapse.beingCreated && e.keyCode === TAB) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
Synapse.createSynapseLocally()
|
Synapse.createSynapseLocally()
|
||||||
}
|
}
|
||||||
|
@ -375,12 +369,12 @@ const Create = {
|
||||||
if (datum.id) { // if they clicked on an existing synapse get it
|
if (datum.id) { // if they clicked on an existing synapse get it
|
||||||
Synapse.getSynapseFromAutocomplete(datum.id)
|
Synapse.getSynapseFromAutocomplete(datum.id)
|
||||||
} else {
|
} else {
|
||||||
Create.newSynapse.description = datum.value
|
toExport.newSynapse.description = datum.value
|
||||||
Synapse.createSynapseLocally()
|
Synapse.createSynapseLocally()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
beingCreated: false,
|
beingtoExportd: false,
|
||||||
description: null,
|
description: null,
|
||||||
topic1id: null,
|
topic1id: null,
|
||||||
topic2id: null,
|
topic2id: null,
|
||||||
|
@ -389,19 +383,21 @@ const Create = {
|
||||||
$('#new_synapse').fadeIn(100, function() {
|
$('#new_synapse').fadeIn(100, function() {
|
||||||
$('#synapse_desc').focus()
|
$('#synapse_desc').focus()
|
||||||
})
|
})
|
||||||
Create.newSynapse.beingCreated = true
|
toExport.newSynapse.beingCreated = true
|
||||||
},
|
},
|
||||||
hide: function() {
|
hide: function() {
|
||||||
$('#new_synapse').fadeOut('fast')
|
$('#new_synapse').fadeOut('fast')
|
||||||
$('#synapse_desc').typeahead('val', '')
|
$('#synapse_desc').typeahead('val', '')
|
||||||
Create.newSynapse.beingCreated = false
|
toExport.newSynapse.beingCreated = false
|
||||||
Create.newTopic.addSynapse = false
|
toExport.newTopic.addSynapse = false
|
||||||
Create.newSynapse.topic1id = 0
|
toExport.newSynapse.topic1id = 0
|
||||||
Create.newSynapse.topic2id = 0
|
toExport.newSynapse.topic2id = 0
|
||||||
Mouse.synapseStartCoordinates = []
|
Mouse.synapseStartCoordinates = []
|
||||||
if (Visualize.mGraph) Visualize.mGraph.plot()
|
if (Visualize.mGraph) Visualize.mGraph.plot()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return toExport
|
||||||
|
}
|
||||||
|
|
||||||
export default Create
|
export default toExport
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
import Active from '../Active'
|
|
||||||
import Filter from '../Filter'
|
|
||||||
import { InfoBox } from '../Map'
|
|
||||||
|
|
||||||
import Map from './Map'
|
import Map from './Map'
|
||||||
import MapCollection from './MapCollection'
|
import MapCollection from './MapCollection'
|
||||||
import Message from './Message'
|
import Message from './Message'
|
||||||
|
@ -17,57 +13,20 @@ import SynapseCollection from './SynapseCollection'
|
||||||
import Mapping from './Mapping'
|
import Mapping from './Mapping'
|
||||||
import MappingCollection from './MappingCollection'
|
import MappingCollection from './MappingCollection'
|
||||||
|
|
||||||
const DataModel = {
|
const DataModel = ({Filter, InfoBox}) => {
|
||||||
Map: Map,
|
const toExport = {
|
||||||
MapCollection: MapCollection,
|
|
||||||
Message: Message,
|
|
||||||
MessageCollection: MessageCollection,
|
|
||||||
Mapper: Mapper,
|
|
||||||
MapperCollection: MapperCollection,
|
|
||||||
Metacode: Metacode,
|
|
||||||
MetacodeCollection: MetacodeCollection,
|
|
||||||
Topic: Topic,
|
|
||||||
TopicCollection: TopicCollection,
|
|
||||||
Synapse: Synapse,
|
|
||||||
SynapseCollection: SynapseCollection,
|
|
||||||
Mapping: Mapping,
|
|
||||||
MappingCollection: MappingCollection,
|
|
||||||
|
|
||||||
Collaborators: new MapperCollection(),
|
Collaborators: new MapperCollection(),
|
||||||
Creators: new MapperCollection(),
|
Creators: new MapperCollection(),
|
||||||
Mappers: new MapperCollection(),
|
Mappers: new MapperCollection(),
|
||||||
Mappings: new MappingCollection(),
|
Mappings: new MappingCollection(),
|
||||||
Maps: {
|
|
||||||
Mine: [],
|
|
||||||
Shared: [],
|
|
||||||
Starred: [],
|
|
||||||
Mapper: {
|
|
||||||
models: [],
|
|
||||||
mapperId: null
|
|
||||||
},
|
|
||||||
Featured: [],
|
|
||||||
Active: []
|
|
||||||
},
|
|
||||||
Messages: [],
|
Messages: [],
|
||||||
Metacodes: new MetacodeCollection(),
|
Metacodes: new MetacodeCollection(),
|
||||||
Stars: [],
|
Stars: [],
|
||||||
Synapses: new SynapseCollection(),
|
Synapses: new SynapseCollection(),
|
||||||
Topics: new TopicCollection(),
|
Topics: new TopicCollection(),
|
||||||
|
setMap: function(serverData) {
|
||||||
init: function(serverData) {
|
var self = toExport
|
||||||
var self = DataModel
|
|
||||||
|
|
||||||
// workaround circular import problem
|
|
||||||
if (!self.MapCollection.model) self.MapCollection.model = Map
|
|
||||||
|
|
||||||
self.synapseIconUrl = serverData['synapse16.png']
|
|
||||||
|
|
||||||
if (serverData.ActiveMap) Active.Map = new Map(serverData.ActiveMap)
|
|
||||||
if (serverData.ActiveMapper) Active.Mapper = new Mapper(serverData.ActiveMapper)
|
|
||||||
if (serverData.ActiveTopic) Active.Topic = new Topic(serverData.ActiveTopic)
|
|
||||||
|
|
||||||
if (serverData.Collaborators) self.Collaborators = new MapperCollection(serverData.Collaborators)
|
if (serverData.Collaborators) self.Collaborators = new MapperCollection(serverData.Collaborators)
|
||||||
if (serverData.Creators) self.Creators = new MapperCollection(serverData.Creators)
|
|
||||||
if (serverData.Mappers) self.Mappers = new MapperCollection(serverData.Mappers)
|
if (serverData.Mappers) self.Mappers = new MapperCollection(serverData.Mappers)
|
||||||
if (serverData.Mappings) self.Mappings = new MappingCollection(serverData.Mappings)
|
if (serverData.Mappings) self.Mappings = new MappingCollection(serverData.Mappings)
|
||||||
if (serverData.Messages) self.Messages = serverData.Messages
|
if (serverData.Messages) self.Messages = serverData.Messages
|
||||||
|
@ -75,42 +34,28 @@ const DataModel = {
|
||||||
if (serverData.Stars) self.Stars = serverData.Stars
|
if (serverData.Stars) self.Stars = serverData.Stars
|
||||||
if (serverData.Synapses) self.Synapses = new SynapseCollection(serverData.Synapses)
|
if (serverData.Synapses) self.Synapses = new SynapseCollection(serverData.Synapses)
|
||||||
if (serverData.Topics) self.Topics = new TopicCollection(serverData.Topics)
|
if (serverData.Topics) self.Topics = new TopicCollection(serverData.Topics)
|
||||||
|
self.attachCollectionEvents()
|
||||||
// initialize global backbone models and collections
|
},
|
||||||
var myCollection = serverData.Mine ? serverData.Mine : []
|
setTopic: function(serverData) {
|
||||||
var sharedCollection = serverData.Shared ? serverData.Shared : []
|
var self = toExport
|
||||||
var starredCollection = serverData.Starred ? serverData.Starred : []
|
if (serverData.Creators) self.Creators = new MapperCollection(serverData.Creators)
|
||||||
var mapperCollection = serverData.Mapper ? serverData.Mapper : []
|
if (serverData.Metacodes) self.Metacodes = new MetacodeCollection(serverData.Metacodes)
|
||||||
var mapperOptionsObj = { id: 'mapper', sortBy: 'updated_at' }
|
if (serverData.Synapses) self.Synapses = new SynapseCollection(serverData.Synapses)
|
||||||
if (serverData.Mapper && serverData.Mapper.mapperId) {
|
if (serverData.Topics) self.Topics = new TopicCollection(serverData.Topics)
|
||||||
mapperCollection = serverData.Mapper.models
|
|
||||||
mapperOptionsObj.mapperId = serverData.Mapper.mapperId
|
|
||||||
}
|
|
||||||
var featuredCollection = serverData.Featured ? serverData.Featured : []
|
|
||||||
var activeCollection = serverData.Active ? serverData.Active : []
|
|
||||||
|
|
||||||
self.Maps.Mine = new MapCollection(myCollection, { id: 'mine', sortBy: 'updated_at' })
|
|
||||||
self.Maps.Shared = new MapCollection(sharedCollection, { id: 'shared', sortBy: 'updated_at' })
|
|
||||||
self.Maps.Starred = new MapCollection(starredCollection, { id: 'starred', sortBy: 'updated_at' })
|
|
||||||
// 'Mapper' refers to another mapper
|
|
||||||
self.Maps.Mapper = new MapCollection(mapperCollection, mapperOptionsObj)
|
|
||||||
self.Maps.Featured = new MapCollection(featuredCollection, { id: 'featured', sortBy: 'updated_at' })
|
|
||||||
self.Maps.Active = new MapCollection(activeCollection, { id: 'active', sortBy: 'updated_at' })
|
|
||||||
|
|
||||||
self.attachCollectionEvents()
|
self.attachCollectionEvents()
|
||||||
},
|
},
|
||||||
attachCollectionEvents: function() {
|
attachCollectionEvents: function() {
|
||||||
DataModel.Topics.on('add remove', function(topic) {
|
toExport.Topics.on('add remove', function(topic) {
|
||||||
InfoBox.updateNumbers()
|
InfoBox.updateNumbers()
|
||||||
Filter.checkMetacodes()
|
Filter.checkMetacodes()
|
||||||
Filter.checkMappers()
|
Filter.checkMappers()
|
||||||
})
|
})
|
||||||
DataModel.Synapses.on('add remove', function(synapse) {
|
toExport.Synapses.on('add remove', function(synapse) {
|
||||||
InfoBox.updateNumbers()
|
InfoBox.updateNumbers()
|
||||||
Filter.checkSynapses()
|
Filter.checkSynapses()
|
||||||
Filter.checkMappers()
|
Filter.checkMappers()
|
||||||
})
|
})
|
||||||
DataModel.Mappings.on('add remove', function(mapping) {
|
toExport.Mappings.on('add remove', function(mapping) {
|
||||||
InfoBox.updateNumbers()
|
InfoBox.updateNumbers()
|
||||||
Filter.checkSynapses()
|
Filter.checkSynapses()
|
||||||
Filter.checkMetacodes()
|
Filter.checkMetacodes()
|
||||||
|
@ -118,7 +63,43 @@ const DataModel = {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return toExport
|
||||||
|
}
|
||||||
|
|
||||||
|
DataModel.Maps = {
|
||||||
|
Mine: [],
|
||||||
|
Shared: [],
|
||||||
|
Starred: [],
|
||||||
|
Mapper: {
|
||||||
|
models: [],
|
||||||
|
mapperId: null
|
||||||
|
},
|
||||||
|
Featured: [],
|
||||||
|
Active: []
|
||||||
|
}
|
||||||
|
DataModel.init = function(serverData) {
|
||||||
|
var self = DataModel
|
||||||
|
self.synapseIconUrl = serverData['synapse16.png']
|
||||||
|
// initialize global backbone models and collections
|
||||||
|
var myCollection = serverData.Mine ? serverData.Mine : []
|
||||||
|
var sharedCollection = serverData.Shared ? serverData.Shared : []
|
||||||
|
var starredCollection = serverData.Starred ? serverData.Starred : []
|
||||||
|
var mapperCollection = serverData.Mapper ? serverData.Mapper : []
|
||||||
|
var mapperOptionsObj = { id: 'mapper', sortBy: 'updated_at' }
|
||||||
|
if (serverData.Mapper && serverData.Mapper.mapperId) {
|
||||||
|
mapperCollection = serverData.Mapper.models
|
||||||
|
mapperOptionsObj.mapperId = serverData.Mapper.mapperId
|
||||||
|
}
|
||||||
|
var featuredCollection = serverData.Featured ? serverData.Featured : []
|
||||||
|
var activeCollection = serverData.Active ? serverData.Active : []
|
||||||
|
self.Maps.Mine = new MapCollection(myCollection, { id: 'mine', sortBy: 'updated_at' })
|
||||||
|
self.Maps.Shared = new MapCollection(sharedCollection, { id: 'shared', sortBy: 'updated_at' })
|
||||||
|
self.Maps.Starred = new MapCollection(starredCollection, { id: 'starred', sortBy: 'updated_at' })
|
||||||
|
// 'Mapper' refers to another mapper
|
||||||
|
self.Maps.Mapper = new MapCollection(mapperCollection, mapperOptionsObj)
|
||||||
|
self.Maps.Featured = new MapCollection(featuredCollection, { id: 'featured', sortBy: 'updated_at' })
|
||||||
|
self.Maps.Active = new MapCollection(activeCollection, { id: 'active', sortBy: 'updated_at' })
|
||||||
|
}
|
||||||
// Note: Topics, Metacodes, Synapses, Mappers, Mappings, Collaborators, Creators are not exported
|
// Note: Topics, Metacodes, Synapses, Mappers, Mappings, Collaborators, Creators are not exported
|
||||||
// You can access them by importing DataModel
|
// You can access them by importing DataModel
|
||||||
|
|
||||||
|
|
|
@ -2,14 +2,11 @@
|
||||||
|
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
|
|
||||||
import Active from './Active'
|
|
||||||
import Control from './Control'
|
|
||||||
import DataModel from './DataModel'
|
|
||||||
import GlobalUI, { ReactApp } from './GlobalUI'
|
import GlobalUI, { ReactApp } from './GlobalUI'
|
||||||
import Settings from './Settings'
|
import Settings from './Settings'
|
||||||
import Visualize from './Visualize'
|
|
||||||
|
|
||||||
const Filter = {
|
const Filter = ({Active, Control, DataModel, Visualize}) => {
|
||||||
|
const toExport = {
|
||||||
dataForPresentation: {
|
dataForPresentation: {
|
||||||
metacodes: {},
|
metacodes: {},
|
||||||
mappers: {},
|
mappers: {},
|
||||||
|
@ -26,7 +23,7 @@ const Filter = {
|
||||||
synapses: []
|
synapses: []
|
||||||
},
|
},
|
||||||
reset: function() {
|
reset: function() {
|
||||||
var self = Filter
|
var self = toExport
|
||||||
self.filters.metacodes = []
|
self.filters.metacodes = []
|
||||||
self.filters.mappers = []
|
self.filters.mappers = []
|
||||||
self.filters.synapses = []
|
self.filters.synapses = []
|
||||||
|
@ -41,7 +38,7 @@ const Filter = {
|
||||||
// an abstraction function for checkMetacodes, checkMappers, checkSynapses to reduce
|
// an abstraction function for checkMetacodes, checkMappers, checkSynapses to reduce
|
||||||
// code redundancy
|
// code redundancy
|
||||||
updateFilters: function(collection, propertyToCheck, correlatedModel, filtersToUse, listToModify) {
|
updateFilters: function(collection, propertyToCheck, correlatedModel, filtersToUse, listToModify) {
|
||||||
var self = Filter
|
var self = toExport
|
||||||
var newList = []
|
var newList = []
|
||||||
var removed = []
|
var removed = []
|
||||||
var added = []
|
var added = []
|
||||||
|
@ -97,11 +94,11 @@ const Filter = {
|
||||||
ReactApp.render()
|
ReactApp.render()
|
||||||
},
|
},
|
||||||
checkMetacodes: function() {
|
checkMetacodes: function() {
|
||||||
var self = Filter
|
var self = toExport
|
||||||
self.updateFilters('Topics', 'metacode_id', 'Metacodes', 'metacodes', 'metacode')
|
self.updateFilters('Topics', 'metacode_id', 'Metacodes', 'metacodes', 'metacode')
|
||||||
},
|
},
|
||||||
checkMappers: function() {
|
checkMappers: function() {
|
||||||
var self = Filter
|
var self = toExport
|
||||||
if (Active.Map) {
|
if (Active.Map) {
|
||||||
self.updateFilters('Mappings', 'user_id', 'Mappers', 'mappers', 'mapper')
|
self.updateFilters('Mappings', 'user_id', 'Mappers', 'mappers', 'mapper')
|
||||||
} else {
|
} else {
|
||||||
|
@ -110,23 +107,23 @@ const Filter = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
checkSynapses: function() {
|
checkSynapses: function() {
|
||||||
var self = Filter
|
var self = toExport
|
||||||
self.updateFilters('Synapses', 'desc', 'Synapses', 'synapses', 'synapse')
|
self.updateFilters('Synapses', 'desc', 'Synapses', 'synapses', 'synapse')
|
||||||
},
|
},
|
||||||
filterAllMetacodes: function(toVisible) {
|
filterAllMetacodes: function(toVisible) {
|
||||||
var self = Filter
|
var self = toExport
|
||||||
self.visible.metacodes = toVisible ? self.filters.metacodes.slice() : []
|
self.visible.metacodes = toVisible ? self.filters.metacodes.slice() : []
|
||||||
ReactApp.render()
|
ReactApp.render()
|
||||||
self.passFilters()
|
self.passFilters()
|
||||||
},
|
},
|
||||||
filterAllMappers: function(toVisible) {
|
filterAllMappers: function(toVisible) {
|
||||||
var self = Filter
|
var self = toExport
|
||||||
self.visible.mappers = toVisible ? self.filters.mappers.slice() : []
|
self.visible.mappers = toVisible ? self.filters.mappers.slice() : []
|
||||||
ReactApp.render()
|
ReactApp.render()
|
||||||
self.passFilters()
|
self.passFilters()
|
||||||
},
|
},
|
||||||
filterAllSynapses: function(toVisible) {
|
filterAllSynapses: function(toVisible) {
|
||||||
var self = Filter
|
var self = toExport
|
||||||
self.visible.synapses = toVisible ? self.filters.synapses.slice() : []
|
self.visible.synapses = toVisible ? self.filters.synapses.slice() : []
|
||||||
ReactApp.render()
|
ReactApp.render()
|
||||||
self.passFilters()
|
self.passFilters()
|
||||||
|
@ -135,7 +132,7 @@ const Filter = {
|
||||||
// to reduce code redundancy
|
// to reduce code redundancy
|
||||||
// gets called in the context of a list item in a filter box
|
// gets called in the context of a list item in a filter box
|
||||||
toggleLi: function(whichToFilter, id) {
|
toggleLi: function(whichToFilter, id) {
|
||||||
var self = Filter
|
var self = toExport
|
||||||
if (self.visible[whichToFilter].indexOf(id) === -1) {
|
if (self.visible[whichToFilter].indexOf(id) === -1) {
|
||||||
self.visible[whichToFilter].push(id)
|
self.visible[whichToFilter].push(id)
|
||||||
} else {
|
} else {
|
||||||
|
@ -146,19 +143,19 @@ const Filter = {
|
||||||
self.passFilters()
|
self.passFilters()
|
||||||
},
|
},
|
||||||
toggleMetacode: function(id) {
|
toggleMetacode: function(id) {
|
||||||
var self = Filter
|
var self = toExport
|
||||||
self.toggleLi('metacodes', id)
|
self.toggleLi('metacodes', id)
|
||||||
},
|
},
|
||||||
toggleMapper: function(id) {
|
toggleMapper: function(id) {
|
||||||
var self = Filter
|
var self = toExport
|
||||||
self.toggleLi('mappers', id)
|
self.toggleLi('mappers', id)
|
||||||
},
|
},
|
||||||
toggleSynapse: function(id) {
|
toggleSynapse: function(id) {
|
||||||
var self = Filter
|
var self = toExport
|
||||||
self.toggleLi('synapses', id)
|
self.toggleLi('synapses', id)
|
||||||
},
|
},
|
||||||
passFilters: function() {
|
passFilters: function() {
|
||||||
var self = Filter
|
var self = toExport
|
||||||
var visible = self.visible
|
var visible = self.visible
|
||||||
|
|
||||||
var passesMetacode, passesMapper, passesSynapse
|
var passesMetacode, passesMapper, passesSynapse
|
||||||
|
@ -276,5 +273,7 @@ const Filter = {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return toExport
|
||||||
|
}
|
||||||
|
|
||||||
export default Filter
|
export default Filter
|
||||||
|
|
|
@ -7,13 +7,12 @@ import { merge } from 'lodash'
|
||||||
|
|
||||||
import { notifyUser } from './index.js'
|
import { notifyUser } from './index.js'
|
||||||
import ImportDialog from './ImportDialog'
|
import ImportDialog from './ImportDialog'
|
||||||
import Active from '../Active'
|
import Mapper from '../DataModel/Mapper'
|
||||||
import DataModel from '../DataModel'
|
|
||||||
import { ExploreMaps, ChatView, TopicCard } from '../Views'
|
import { ExploreMaps, ChatView, TopicCard } from '../Views'
|
||||||
import Filter from '../Filter'
|
import Filter from '../Filter'
|
||||||
import JIT from '../JIT'
|
import JIT from '../JIT'
|
||||||
import Realtime from '../Realtime'
|
import Realtime from '../Realtime'
|
||||||
import Map, { InfoBox } from '../Map'
|
import Map, { mapControl } from '../Map'
|
||||||
import Topic from '../Topic'
|
import Topic from '../Topic'
|
||||||
import Visualize from '../Visualize'
|
import Visualize from '../Visualize'
|
||||||
import makeRoutes from '../../components/makeRoutes'
|
import makeRoutes from '../../components/makeRoutes'
|
||||||
|
@ -27,8 +26,11 @@ const MAX_COLUMNS = 4
|
||||||
|
|
||||||
const ReactApp = {
|
const ReactApp = {
|
||||||
serverData: {},
|
serverData: {},
|
||||||
|
currentUser: null,
|
||||||
mapId: null,
|
mapId: null,
|
||||||
|
openMap: null,
|
||||||
topicId: null,
|
topicId: null,
|
||||||
|
openTopic: null,
|
||||||
unreadNotificationsCount: 0,
|
unreadNotificationsCount: 0,
|
||||||
mapsWidth: 0,
|
mapsWidth: 0,
|
||||||
toast: '',
|
toast: '',
|
||||||
|
@ -36,9 +38,11 @@ const ReactApp = {
|
||||||
mobileTitle: '',
|
mobileTitle: '',
|
||||||
mobileTitleWidth: 0,
|
mobileTitleWidth: 0,
|
||||||
metacodeSets: [],
|
metacodeSets: [],
|
||||||
|
juntoState: { connectedPeople: {}, liveMaps: {} },
|
||||||
init: function(serverData, openLightbox) {
|
init: function(serverData, openLightbox) {
|
||||||
const self = ReactApp
|
const self = ReactApp
|
||||||
self.serverData = serverData
|
self.serverData = serverData
|
||||||
|
self.currentUser = new Mapper(serverData.ActiveMapper)
|
||||||
self.unreadNotificationsCount = serverData.unreadNotificationsCount
|
self.unreadNotificationsCount = serverData.unreadNotificationsCount
|
||||||
self.mobileTitle = serverData.mobileTitle
|
self.mobileTitle = serverData.mobileTitle
|
||||||
self.openLightbox = openLightbox
|
self.openLightbox = openLightbox
|
||||||
|
@ -52,12 +56,13 @@ const ReactApp = {
|
||||||
const pathname = this.state.location.pathname
|
const pathname = this.state.location.pathname
|
||||||
switch (pathname.split('/')[1]) {
|
switch (pathname.split('/')[1]) {
|
||||||
case '':
|
case '':
|
||||||
if (Active.Mapper && Active.Mapper.id) {
|
if (self.currentUser && self.currentUser.id) {
|
||||||
$('#yield').hide()
|
$('#yield').hide()
|
||||||
ExploreMaps.updateFromPath(pathname)
|
ExploreMaps.updateFromPath(pathname)
|
||||||
self.mapId = null
|
self.mapId = null
|
||||||
Active.Map = null
|
self.topicId = null
|
||||||
Active.Topic = null
|
self.openMap = null
|
||||||
|
self.openTopic = null
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case 'explore':
|
case 'explore':
|
||||||
|
@ -65,19 +70,19 @@ const ReactApp = {
|
||||||
ExploreMaps.updateFromPath(pathname)
|
ExploreMaps.updateFromPath(pathname)
|
||||||
self.mapId = null
|
self.mapId = null
|
||||||
self.topicId = null
|
self.topicId = null
|
||||||
Active.Map = null
|
self.openMap = null
|
||||||
Active.Topic = null
|
self.openTopic = null
|
||||||
break
|
break
|
||||||
case 'topics':
|
case 'topics':
|
||||||
$('#yield').hide()
|
$('#yield').hide()
|
||||||
Active.Map = null
|
self.openMap = null
|
||||||
self.mapId = null
|
self.mapId = null
|
||||||
self.topicId = pathname.split('/')[2]
|
self.topicId = pathname.split('/')[2]
|
||||||
break
|
break
|
||||||
case 'maps':
|
case 'maps':
|
||||||
if (!pathname.includes('request_access')) {
|
if (!pathname.includes('request_access')) {
|
||||||
$('#yield').hide()
|
$('#yield').hide()
|
||||||
Active.Topic = null
|
self.openTopic = null
|
||||||
self.topicId = null
|
self.topicId = null
|
||||||
self.mapId = pathname.split('/')[2]
|
self.mapId = pathname.split('/')[2]
|
||||||
}
|
}
|
||||||
|
@ -99,14 +104,18 @@ const ReactApp = {
|
||||||
const self = ReactApp
|
const self = ReactApp
|
||||||
return merge({
|
return merge({
|
||||||
unreadNotificationsCount: self.unreadNotificationsCount,
|
unreadNotificationsCount: self.unreadNotificationsCount,
|
||||||
currentUser: Active.Mapper,
|
currentUser: self.currentUser,
|
||||||
toast: self.toast,
|
toast: self.toast,
|
||||||
mobile: self.mobile,
|
mobile: self.mobile,
|
||||||
mobileTitle: self.mobileTitle,
|
mobileTitle: self.mobileTitle,
|
||||||
mobileTitleWidth: self.mobileTitleWidth,
|
mobileTitleWidth: self.mobileTitleWidth,
|
||||||
mobileTitleClick: (e) => Active.Map && InfoBox.toggleBox(e),
|
mobileTitleClick: (e) => self.openMap && self.openMap.InfoBox.toggleBox(e),
|
||||||
openInviteLightbox: () => self.openLightbox('invite'),
|
openInviteLightbox: () => self.openLightbox('invite'),
|
||||||
serverData: self.serverData
|
serverData: self.serverData,
|
||||||
|
endActiveMap: mapControl.end,
|
||||||
|
launchNewMap: mapControl.launch,
|
||||||
|
mapId: self.mapId,
|
||||||
|
topicId: self.topicId
|
||||||
},
|
},
|
||||||
self.getMapProps(),
|
self.getMapProps(),
|
||||||
self.getTopicProps(),
|
self.getTopicProps(),
|
||||||
|
@ -118,27 +127,27 @@ const ReactApp = {
|
||||||
},
|
},
|
||||||
getMapProps: function() {
|
getMapProps: function() {
|
||||||
const self = ReactApp
|
const self = ReactApp
|
||||||
|
if (!self.openMap) return {}
|
||||||
return {
|
return {
|
||||||
mapId: self.mapId,
|
map: self.openMap.Active.Map,
|
||||||
map: Active.Map,
|
hasLearnedTopicCreation: self.openMap.Map.hasLearnedTopicCreation,
|
||||||
hasLearnedTopicCreation: Map.hasLearnedTopicCreation,
|
userRequested: self.openMap.Map.userRequested,
|
||||||
userRequested: Map.userRequested,
|
requestAnswered: self.openMap.Map.requestAnswered,
|
||||||
requestAnswered: Map.requestAnswered,
|
requestApproved: self.openMap.Map.requestApproved,
|
||||||
requestApproved: Map.requestApproved,
|
onRequestAccess: self.openMap.Map.requestAccess,
|
||||||
onRequestAccess: Map.requestAccess,
|
mapIsStarred: self.openMap.Map.mapIsStarred,
|
||||||
mapIsStarred: Map.mapIsStarred,
|
toggleMapInfoBox: self.openMap.InfoBox.toggleBox,
|
||||||
endActiveMap: Map.end,
|
infoBoxHtml: self.openMap.InfoBox.html,
|
||||||
launchNewMap: Map.launch,
|
|
||||||
toggleMapInfoBox: InfoBox.toggleBox,
|
|
||||||
infoBoxHtml: InfoBox.html,
|
|
||||||
openImportLightbox: () => ImportDialog.show(),
|
openImportLightbox: () => ImportDialog.show(),
|
||||||
forkMap: Map.fork,
|
forkMap: self.openMap.Map.fork,
|
||||||
onMapStar: Map.star,
|
onMapStar: self.openMap.Map.star,
|
||||||
onMapUnstar: Map.unstar
|
onMapUnstar: self.openMap.Map.unstar
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getCommonProps: function() {
|
getCommonProps: function() {
|
||||||
const self = ReactApp
|
const self = ReactApp
|
||||||
|
if (!(self.openMap || self.openTopic)) return {}
|
||||||
|
const { JIT, Visualize } = self.openMap || self.openTopic
|
||||||
return {
|
return {
|
||||||
openHelpLightbox: () => self.openLightbox('cheatsheet'),
|
openHelpLightbox: () => self.openLightbox('cheatsheet'),
|
||||||
onZoomExtents: event => JIT.zoomExtents(event, Visualize.mGraph.canvas),
|
onZoomExtents: event => JIT.zoomExtents(event, Visualize.mGraph.canvas),
|
||||||
|
@ -148,20 +157,22 @@ const ReactApp = {
|
||||||
},
|
},
|
||||||
getTopicCardProps: function() {
|
getTopicCardProps: function() {
|
||||||
const self = ReactApp
|
const self = ReactApp
|
||||||
|
if (!(self.openMap || self.openTopic)) return {}
|
||||||
|
const { TopicCard } = self.openMap || self.openTopic
|
||||||
return {
|
return {
|
||||||
openTopic: TopicCard.openTopic,
|
openTopic: TopicCard.openTopic,
|
||||||
metacodeSets: self.metacodeSets,
|
metacodeSets: self.metacodeSets,
|
||||||
updateTopic: (topic, obj) => topic.save(obj),
|
updateTopic: (topic, obj) => topic.save(obj),
|
||||||
onTopicFollow: Topic.onTopicFollow
|
onTopicFollow: Topic.onTopicFollow // todo
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getTopicProps: function() {
|
getTopicProps: function() {
|
||||||
const self = ReactApp
|
const self = ReactApp
|
||||||
|
if (!self.openTopic) return {}
|
||||||
return {
|
return {
|
||||||
topicId: self.topicId,
|
topic: self.openTopic.Active.Topic,
|
||||||
topic: Active.Topic,
|
endActiveTopic: Topic.end, // todo
|
||||||
endActiveTopic: Topic.end,
|
launchNewTopic: Topic.launch // todo
|
||||||
launchNewTopic: Topic.launch
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getMapsProps: function() {
|
getMapsProps: function() {
|
||||||
|
@ -169,7 +180,7 @@ const ReactApp = {
|
||||||
return {
|
return {
|
||||||
section: ExploreMaps.collection && ExploreMaps.collection.id,
|
section: ExploreMaps.collection && ExploreMaps.collection.id,
|
||||||
maps: ExploreMaps.collection,
|
maps: ExploreMaps.collection,
|
||||||
juntoState: Realtime.juntoState,
|
juntoState: self.juntoState,
|
||||||
moreToLoad: ExploreMaps.collection && ExploreMaps.collection.page !== 'loadedAll',
|
moreToLoad: ExploreMaps.collection && ExploreMaps.collection.page !== 'loadedAll',
|
||||||
user: ExploreMaps.collection && ExploreMaps.collection.id === 'mapper' ? ExploreMaps.mapper : null,
|
user: ExploreMaps.collection && ExploreMaps.collection.id === 'mapper' ? ExploreMaps.mapper : null,
|
||||||
loadMore: ExploreMaps.loadMore,
|
loadMore: ExploreMaps.loadMore,
|
||||||
|
@ -182,6 +193,11 @@ const ReactApp = {
|
||||||
},
|
},
|
||||||
getChatProps: function() {
|
getChatProps: function() {
|
||||||
const self = ReactApp
|
const self = ReactApp
|
||||||
|
if (!self.openMap) return {
|
||||||
|
participants: [],
|
||||||
|
messages: []
|
||||||
|
}
|
||||||
|
const { ChatView, Realtime } = self.openMap
|
||||||
return {
|
return {
|
||||||
unreadMessages: ChatView.unreadMessages,
|
unreadMessages: ChatView.unreadMessages,
|
||||||
conversationLive: ChatView.conversationLive,
|
conversationLive: ChatView.conversationLive,
|
||||||
|
@ -204,6 +220,8 @@ const ReactApp = {
|
||||||
},
|
},
|
||||||
getFilterProps: function() {
|
getFilterProps: function() {
|
||||||
const self = ReactApp
|
const self = ReactApp
|
||||||
|
if (!self.openMap) return {}
|
||||||
|
const { Filter } = self.openMap
|
||||||
return {
|
return {
|
||||||
filterData: Filter.dataForPresentation,
|
filterData: Filter.dataForPresentation,
|
||||||
allForFiltering: Filter.filters,
|
allForFiltering: Filter.filters,
|
||||||
|
@ -219,7 +237,7 @@ const ReactApp = {
|
||||||
resize: function() {
|
resize: function() {
|
||||||
const self = ReactApp
|
const self = ReactApp
|
||||||
const maps = ExploreMaps.collection
|
const maps = ExploreMaps.collection
|
||||||
const currentUser = Active.Mapper
|
const currentUser = self.currentUser
|
||||||
const user = maps && maps.id === 'mapper' ? ExploreMaps.mapper : null
|
const user = maps && maps.id === 'mapper' ? ExploreMaps.mapper : null
|
||||||
const numCards = (maps ? maps.length : 0) + (user || currentUser ? 1 : 0)
|
const numCards = (maps ? maps.length : 0) + (user || currentUser ? 1 : 0)
|
||||||
const mapSpaces = Math.floor(document.body.clientWidth / MAP_WIDTH)
|
const mapSpaces = Math.floor(document.body.clientWidth / MAP_WIDTH)
|
||||||
|
|
|
@ -3,15 +3,10 @@
|
||||||
import parse from 'csv-parse'
|
import parse from 'csv-parse'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
|
|
||||||
import Active from './Active'
|
|
||||||
import AutoLayout from './AutoLayout'
|
|
||||||
import DataModel from './DataModel'
|
|
||||||
import GlobalUI from './GlobalUI'
|
import GlobalUI from './GlobalUI'
|
||||||
import Map from './Map'
|
|
||||||
import Synapse from './Synapse'
|
|
||||||
import Topic from './Topic'
|
|
||||||
|
|
||||||
const Import = {
|
const Import = ({Active, AutoLayout, DataModel, Map, Synapse, Topic}) => {
|
||||||
|
const toExport = {
|
||||||
// note that user is not imported
|
// note that user is not imported
|
||||||
topicWhitelist: [
|
topicWhitelist: [
|
||||||
'id', 'name', 'metacode', 'x', 'y', 'description', 'link', 'permission'
|
'id', 'name', 'metacode', 'x', 'y', 'description', 'link', 'permission'
|
||||||
|
@ -22,12 +17,12 @@ const Import = {
|
||||||
cidMappings: {}, // to be filled by importId => cid mappings
|
cidMappings: {}, // to be filled by importId => cid mappings
|
||||||
|
|
||||||
handleTSV: function(text) {
|
handleTSV: function(text) {
|
||||||
const results = Import.parseTabbedString(text)
|
const results = toExport.parseTabbedString(text)
|
||||||
Import.handle(results)
|
toExport.handle(results)
|
||||||
},
|
},
|
||||||
|
|
||||||
handleCSV: function(text, parserOpts = {}) {
|
handleCSV: function(text, parserOpts = {}) {
|
||||||
const self = Import
|
const self = toExport
|
||||||
|
|
||||||
const topicsRegex = /("?Topics"?[, \t"]*)([\s\S]*)/mi
|
const topicsRegex = /("?Topics"?[, \t"]*)([\s\S]*)/mi
|
||||||
const synapsesRegex = /("?Synapses"?[, \t"]*)([\s\S]*)/mi
|
const synapsesRegex = /("?Synapses"?[, \t"]*)([\s\S]*)/mi
|
||||||
|
@ -68,11 +63,11 @@ const Import = {
|
||||||
|
|
||||||
handleJSON: function(text) {
|
handleJSON: function(text) {
|
||||||
const results = JSON.parse(text)
|
const results = JSON.parse(text)
|
||||||
Import.handle(results)
|
toExport.handle(results)
|
||||||
},
|
},
|
||||||
|
|
||||||
handle: function(results) {
|
handle: function(results) {
|
||||||
var self = Import
|
var self = toExport
|
||||||
var topics = results.topics.map(topic => self.normalizeKeys(topic))
|
var topics = results.topics.map(topic => self.normalizeKeys(topic))
|
||||||
var synapses = results.synapses.map(synapse => self.normalizeKeys(synapse))
|
var synapses = results.synapses.map(synapse => self.normalizeKeys(synapse))
|
||||||
|
|
||||||
|
@ -87,7 +82,7 @@ const Import = {
|
||||||
},
|
},
|
||||||
|
|
||||||
parseTabbedString: function(text) {
|
parseTabbedString: function(text) {
|
||||||
var self = Import
|
var self = toExport
|
||||||
|
|
||||||
// determine line ending and split lines
|
// determine line ending and split lines
|
||||||
var delim = '\n'
|
var delim = '\n'
|
||||||
|
@ -213,7 +208,7 @@ const Import = {
|
||||||
},
|
},
|
||||||
|
|
||||||
importTopics: function(parsedTopics) {
|
importTopics: function(parsedTopics) {
|
||||||
var self = Import
|
var self = toExport
|
||||||
|
|
||||||
parsedTopics.forEach(topic => {
|
parsedTopics.forEach(topic => {
|
||||||
let coords = { x: topic.x, y: topic.y }
|
let coords = { x: topic.x, y: topic.y }
|
||||||
|
@ -240,7 +235,7 @@ const Import = {
|
||||||
},
|
},
|
||||||
|
|
||||||
importSynapses: function(parsedSynapses) {
|
importSynapses: function(parsedSynapses) {
|
||||||
var self = Import
|
var self = toExport
|
||||||
|
|
||||||
parsedSynapses.forEach(function(synapse) {
|
parsedSynapses.forEach(function(synapse) {
|
||||||
// only createSynapseWithParameters once both topics are persisted
|
// only createSynapseWithParameters once both topics are persisted
|
||||||
|
@ -279,7 +274,7 @@ const Import = {
|
||||||
|
|
||||||
createTopicWithParameters: function(name, metacodeName, permission, desc,
|
createTopicWithParameters: function(name, metacodeName, permission, desc,
|
||||||
link, xloc, yloc, importId, opts = {}) {
|
link, xloc, yloc, importId, opts = {}) {
|
||||||
var self = Import
|
var self = toExport
|
||||||
$(document).trigger(Map.events.editedByActiveMapper)
|
$(document).trigger(Map.events.editedByActiveMapper)
|
||||||
var metacode = DataModel.Metacodes.where({name: metacodeName})[0] || null
|
var metacode = DataModel.Metacodes.where({name: metacodeName})[0] || null
|
||||||
if (metacode === null) {
|
if (metacode === null) {
|
||||||
|
@ -359,7 +354,7 @@ const Import = {
|
||||||
const permission = opts.permission || null // use default
|
const permission = opts.permission || null // use default
|
||||||
const desc = opts.desc || url
|
const desc = opts.desc || url
|
||||||
|
|
||||||
Import.createTopicWithParameters(
|
toExport.createTopicWithParameters(
|
||||||
name,
|
name,
|
||||||
metacode,
|
metacode,
|
||||||
permission,
|
permission,
|
||||||
|
@ -423,5 +418,7 @@ const Import = {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return toExport
|
||||||
|
}
|
||||||
|
|
||||||
export default Import
|
export default Import
|
||||||
|
|
|
@ -35,17 +35,6 @@ return {
|
||||||
animationDone: 'Metamaps:JIT:events:animationDone'
|
animationDone: 'Metamaps:JIT:events:animationDone'
|
||||||
},
|
},
|
||||||
vizData: [], // contains the visualization-compatible graph
|
vizData: [], // contains the visualization-compatible graph
|
||||||
/**
|
|
||||||
* This method will bind the event handlers it is interested and initialize the class.
|
|
||||||
*/
|
|
||||||
init: function(serverData) {
|
|
||||||
const self = JIT
|
|
||||||
self.topicDescImage = new Image()
|
|
||||||
self.topicDescImage.src = serverData['topic_description_signifier.png']
|
|
||||||
|
|
||||||
self.topicLinkImage = new Image()
|
|
||||||
self.topicLinkImage.src = serverData['topic_link_signifier.png']
|
|
||||||
},
|
|
||||||
/**
|
/**
|
||||||
* convert our topic JSON into something JIT can use
|
* convert our topic JSON into something JIT can use
|
||||||
*/
|
*/
|
||||||
|
@ -1968,5 +1957,12 @@ return {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
JIT.init = function(serverData) {
|
||||||
|
JIT.topicDescImage = new Image()
|
||||||
|
JIT.topicDescImage.src = serverData['topic_description_signifier.png']
|
||||||
|
|
||||||
|
JIT.topicLinkImage = new Image()
|
||||||
|
JIT.topicLinkImage.src = serverData['topic_link_signifier.png']
|
||||||
|
}
|
||||||
|
|
||||||
export default JIT
|
export default JIT
|
||||||
|
|
|
@ -5,9 +5,9 @@ import { Search } from './GlobalUI'
|
||||||
|
|
||||||
const Listeners = ({ Active, Create, Control, DataModel, JIT, Realtime, Selected, Topic, Visualize }) => {
|
const Listeners = ({ Active, Create, Control, DataModel, JIT, Realtime, Selected, Topic, Visualize }) => {
|
||||||
return {
|
return {
|
||||||
init: function() {
|
activate: function() {
|
||||||
var self = this
|
var self = this
|
||||||
$(document).on('keydown', function(e) {
|
$(document).on('keydown.map', function(e) {
|
||||||
if (!(Active.Map || Active.Topic)) return
|
if (!(Active.Map || Active.Topic)) return
|
||||||
|
|
||||||
const onCanvas = e.target.tagName === 'BODY'
|
const onCanvas = e.target.tagName === 'BODY'
|
||||||
|
@ -131,7 +131,7 @@ return {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
$(window).resize(function() {
|
$(window).on('resize.map', function() {
|
||||||
if (Visualize && Visualize.mGraph) {
|
if (Visualize && Visualize.mGraph) {
|
||||||
Util.resizeCanvas(Visualize.mGraph.canvas)
|
Util.resizeCanvas(Visualize.mGraph.canvas)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,12 +3,11 @@
|
||||||
import outdent from 'outdent'
|
import outdent from 'outdent'
|
||||||
import { browserHistory } from 'react-router'
|
import { browserHistory } from 'react-router'
|
||||||
|
|
||||||
import Active from '../Active'
|
|
||||||
import DataModel from '../DataModel'
|
|
||||||
import GlobalUI, { ReactApp } from '../GlobalUI'
|
import GlobalUI, { ReactApp } from '../GlobalUI'
|
||||||
import Util from '../Util'
|
import Util from '../Util'
|
||||||
|
|
||||||
const InfoBox = {
|
const InfoBox = ({Active, DataModel}) => {
|
||||||
|
const toExport = {
|
||||||
isOpen: false,
|
isOpen: false,
|
||||||
selectingPermission: false,
|
selectingPermission: false,
|
||||||
changePermissionText: "<div class='tooltips'>As the creator, you can change the permission of this map, and the permission of all the topics and synapses you have authority to change will change as well.</div>",
|
changePermissionText: "<div class='tooltips'>As the creator, you can change the permission of this map, and the permission of all the topics and synapses you have authority to change will change as well.</div>",
|
||||||
|
@ -36,32 +35,32 @@ const InfoBox = {
|
||||||
userImageUrl: '',
|
userImageUrl: '',
|
||||||
html: '',
|
html: '',
|
||||||
init: function(serverData, updateThumbnail) {
|
init: function(serverData, updateThumbnail) {
|
||||||
var self = InfoBox
|
var self = toExport
|
||||||
|
|
||||||
self.updateThumbnail = updateThumbnail
|
self.updateThumbnail = updateThumbnail
|
||||||
|
|
||||||
$('.mapInfoBox').click(function(event) {
|
$('.maptoExport').click(function(event) {
|
||||||
event.stopPropagation()
|
event.stopPropagation()
|
||||||
})
|
})
|
||||||
$('body').click(self.close)
|
$('body').click(self.close)
|
||||||
|
|
||||||
self.attachEventListeners()
|
self.attachEventListeners()
|
||||||
|
|
||||||
self.generateBoxHTML = Hogan.compile($('#mapInfoBoxTemplate').html())
|
self.generateBoxHTML = Hogan.compile($('#maptoExportTemplate').html())
|
||||||
|
|
||||||
self.userImageUrl = serverData['user.png']
|
self.userImageUrl = serverData['user.png']
|
||||||
|
|
||||||
var querystring = window.location.search.replace(/^\?/, '')
|
var querystring = window.location.search.replace(/^\?/, '')
|
||||||
if (querystring === 'new') {
|
if (querystring === 'new') {
|
||||||
self.open()
|
self.open()
|
||||||
$('.mapInfoBox').addClass('mapRequestTitle')
|
$('.maptoExport').addClass('mapRequestTitle')
|
||||||
$('#mapInfoName').trigger('click')
|
$('#mapInfoName').trigger('click')
|
||||||
$('#mapInfoName textarea').focus()
|
$('#mapInfoName textarea').focus()
|
||||||
$('#mapInfoName textarea').select()
|
$('#mapInfoName textarea').select()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
toggleBox: function(event) {
|
toggleBox: function(event) {
|
||||||
var self = InfoBox
|
var self = toExport
|
||||||
|
|
||||||
if (self.isOpen) self.close()
|
if (self.isOpen) self.close()
|
||||||
else self.open()
|
else self.open()
|
||||||
|
@ -69,23 +68,23 @@ const InfoBox = {
|
||||||
event.stopPropagation()
|
event.stopPropagation()
|
||||||
},
|
},
|
||||||
open: function() {
|
open: function() {
|
||||||
var self = InfoBox
|
var self = toExport
|
||||||
$('.mapInfoIcon div').addClass('hide')
|
$('.mapInfoIcon div').addClass('hide')
|
||||||
$('.mapInfoBox').fadeIn(200, function() {
|
$('.maptoExport').fadeIn(200, function() {
|
||||||
self.isOpen = true
|
self.isOpen = true
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
close: function() {
|
close: function() {
|
||||||
var self = InfoBox
|
var self = toExport
|
||||||
$('.mapInfoIcon div').removeClass('hide')
|
$('.mapInfoIcon div').removeClass('hide')
|
||||||
$('.mapInfoBox').fadeOut(200, function() {
|
$('.maptoExport').fadeOut(200, function() {
|
||||||
self.isOpen = false
|
self.isOpen = false
|
||||||
self.hidePermissionSelect()
|
self.hidePermissionSelect()
|
||||||
$('.mapContributors .tip').hide()
|
$('.mapContributors .tip').hide()
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
load: function() {
|
load: function() {
|
||||||
var self = InfoBox
|
var self = toExport
|
||||||
|
|
||||||
var map = Active.Map
|
var map = Active.Map
|
||||||
|
|
||||||
|
@ -115,12 +114,12 @@ const InfoBox = {
|
||||||
self.attachEventListeners()
|
self.attachEventListeners()
|
||||||
},
|
},
|
||||||
attachEventListeners: function() {
|
attachEventListeners: function() {
|
||||||
var self = InfoBox
|
var self = toExport
|
||||||
|
|
||||||
$('.mapInfoBox.canEdit .best_in_place').best_in_place()
|
$('.maptoExport.canEdit .best_in_place').best_in_place()
|
||||||
|
|
||||||
// because anyone who can edit the map can change the map title
|
// because anyone who can edit the map can change the map title
|
||||||
var bipName = $('.mapInfoBox .best_in_place_name')
|
var bipName = $('.maptoExport .best_in_place_name')
|
||||||
bipName.unbind('best_in_place:activate').bind('best_in_place:activate', function() {
|
bipName.unbind('best_in_place:activate').bind('best_in_place:activate', function() {
|
||||||
var $el = bipName.find('textarea')
|
var $el = bipName.find('textarea')
|
||||||
var el = $el[0]
|
var el = $el[0]
|
||||||
|
@ -144,7 +143,7 @@ const InfoBox = {
|
||||||
Active.Map.trigger('saved')
|
Active.Map.trigger('saved')
|
||||||
// mobile menu
|
// mobile menu
|
||||||
$('#header_content').html(name)
|
$('#header_content').html(name)
|
||||||
$('.mapInfoBox').removeClass('mapRequestTitle')
|
$('.maptoExport').removeClass('mapRequestTitle')
|
||||||
document.title = `${name} | Metamaps`
|
document.title = `${name} | Metamaps`
|
||||||
window.history.replaceState('', `${name} | Metamaps`, window.location.pathname)
|
window.history.replaceState('', `${name} | Metamaps`, window.location.pathname)
|
||||||
})
|
})
|
||||||
|
@ -164,8 +163,8 @@ const InfoBox = {
|
||||||
|
|
||||||
$('.yourMap .mapPermission').unbind().click(self.onPermissionClick)
|
$('.yourMap .mapPermission').unbind().click(self.onPermissionClick)
|
||||||
// .yourMap in the unbind/bind is just a namespace for the events
|
// .yourMap in the unbind/bind is just a namespace for the events
|
||||||
// not a reference to the class .yourMap on the .mapInfoBox
|
// not a reference to the class .yourMap on the .maptoExport
|
||||||
$('.mapInfoBox.yourMap').unbind('.yourMap').bind('click.yourMap', self.hidePermissionSelect)
|
$('.maptoExport.yourMap').unbind('.yourMap').bind('click.yourMap', self.hidePermissionSelect)
|
||||||
|
|
||||||
$('.yourMap .mapInfoDelete').unbind().click(self.deleteActiveMap)
|
$('.yourMap .mapInfoDelete').unbind().click(self.deleteActiveMap)
|
||||||
$('.mapInfoThumbnail').unbind().click(self.updateThumbnail)
|
$('.mapInfoThumbnail').unbind().click(self.updateThumbnail)
|
||||||
|
@ -178,14 +177,14 @@ const InfoBox = {
|
||||||
event.stopPropagation()
|
event.stopPropagation()
|
||||||
})
|
})
|
||||||
|
|
||||||
$('.mapInfoBox').unbind('.hideTip').bind('click.hideTip', function() {
|
$('.maptoExport').unbind('.hideTip').bind('click.hideTip', function() {
|
||||||
$('.mapContributors .tip').hide()
|
$('.mapContributors .tip').hide()
|
||||||
})
|
})
|
||||||
|
|
||||||
self.addTypeahead()
|
self.addTypeahead()
|
||||||
},
|
},
|
||||||
addTypeahead: function() {
|
addTypeahead: function() {
|
||||||
var self = InfoBox
|
var self = toExport
|
||||||
|
|
||||||
if (!Active.Map) return
|
if (!Active.Map) return
|
||||||
|
|
||||||
|
@ -232,14 +231,14 @@ const InfoBox = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
removeCollaborator: function(collaboratorId) {
|
removeCollaborator: function(collaboratorId) {
|
||||||
var self = InfoBox
|
var self = toExport
|
||||||
DataModel.Collaborators.remove(DataModel.Collaborators.get(collaboratorId))
|
DataModel.Collaborators.remove(DataModel.Collaborators.get(collaboratorId))
|
||||||
var mapperIds = DataModel.Collaborators.models.map(function(mapper) { return mapper.id })
|
var mapperIds = DataModel.Collaborators.models.map(function(mapper) { return mapper.id })
|
||||||
$.post('/maps/' + Active.Map.id + '/access', { access: mapperIds })
|
$.post('/maps/' + Active.Map.id + '/access', { access: mapperIds })
|
||||||
self.updateNumbers()
|
self.updateNumbers()
|
||||||
},
|
},
|
||||||
addCollaborator: function(newCollaboratorId) {
|
addCollaborator: function(newCollaboratorId) {
|
||||||
var self = InfoBox
|
var self = toExport
|
||||||
|
|
||||||
if (DataModel.Collaborators.get(newCollaboratorId)) {
|
if (DataModel.Collaborators.get(newCollaboratorId)) {
|
||||||
GlobalUI.notifyUser('That user already has access')
|
GlobalUI.notifyUser('That user already has access')
|
||||||
|
@ -258,16 +257,16 @@ const InfoBox = {
|
||||||
$.getJSON('/users/' + newCollaboratorId + '.json', callback)
|
$.getJSON('/users/' + newCollaboratorId + '.json', callback)
|
||||||
},
|
},
|
||||||
handleResultClick: function(event, item) {
|
handleResultClick: function(event, item) {
|
||||||
var self = InfoBox
|
var self = toExport
|
||||||
|
|
||||||
self.addCollaborator(item.id)
|
self.addCollaborator(item.id)
|
||||||
$('.collaboratorSearchField').typeahead('val', '')
|
$('.collaboratorSearchField').typeahead('val', '')
|
||||||
},
|
},
|
||||||
updateNameDescPerm: function(name, desc, perm) {
|
updateNameDescPerm: function(name, desc, perm) {
|
||||||
$('.mapInfoBox').removeClass('mapRequestTitle')
|
$('.maptoExport').removeClass('mapRequestTitle')
|
||||||
$('.mapInfoName .best_in_place_name').html(name)
|
$('.mapInfoName .best_in_place_name').html(name)
|
||||||
$('.mapInfoDesc .best_in_place_desc').html(desc)
|
$('.mapInfoDesc .best_in_place_desc').html(desc)
|
||||||
$('.mapInfoBox .mapPermission').removeClass('commons public private').addClass(perm)
|
$('.maptoExport .mapPermission').removeClass('commons public private').addClass(perm)
|
||||||
},
|
},
|
||||||
createContributorList: function() {
|
createContributorList: function() {
|
||||||
var relevantPeople = Active.Map.get('permission') === 'commons' ? DataModel.Mappers : DataModel.Collaborators
|
var relevantPeople = Active.Map.get('permission') === 'commons' ? DataModel.Mappers : DataModel.Collaborators
|
||||||
|
@ -294,7 +293,7 @@ const InfoBox = {
|
||||||
updateNumbers: function() {
|
updateNumbers: function() {
|
||||||
if (!Active.Map) return
|
if (!Active.Map) return
|
||||||
|
|
||||||
const self = InfoBox
|
const self = toExport
|
||||||
|
|
||||||
var relevantPeople = Active.Map.get('permission') === 'commons' ? DataModel.Mappers : DataModel.Collaborators
|
var relevantPeople = Active.Map.get('permission') === 'commons' ? DataModel.Mappers : DataModel.Collaborators
|
||||||
|
|
||||||
|
@ -323,7 +322,7 @@ const InfoBox = {
|
||||||
$('.mapEditedAt').html('<span>Last edited: </span>' + Util.nowDateFormatted())
|
$('.mapEditedAt').html('<span>Last edited: </span>' + Util.nowDateFormatted())
|
||||||
},
|
},
|
||||||
onPermissionClick: function(event) {
|
onPermissionClick: function(event) {
|
||||||
var self = InfoBox
|
var self = toExport
|
||||||
|
|
||||||
if (!self.selectingPermission) {
|
if (!self.selectingPermission) {
|
||||||
self.selectingPermission = true
|
self.selectingPermission = true
|
||||||
|
@ -340,14 +339,14 @@ const InfoBox = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
hidePermissionSelect: function() {
|
hidePermissionSelect: function() {
|
||||||
var self = InfoBox
|
var self = toExport
|
||||||
|
|
||||||
self.selectingPermission = false
|
self.selectingPermission = false
|
||||||
$('.mapPermission').removeClass('minimize') // this line flips the pull up arrow to a drop down arrow
|
$('.mapPermission').removeClass('minimize') // this line flips the pull up arrow to a drop down arrow
|
||||||
$('.mapPermission .permissionSelect').remove()
|
$('.mapPermission .permissionSelect').remove()
|
||||||
},
|
},
|
||||||
selectPermission: function(event) {
|
selectPermission: function(event) {
|
||||||
var self = InfoBox
|
var self = toExport
|
||||||
|
|
||||||
self.selectingPermission = false
|
self.selectingPermission = false
|
||||||
var permission = $(this).attr('class')
|
var permission = $(this).attr('class')
|
||||||
|
@ -358,7 +357,7 @@ const InfoBox = {
|
||||||
const shareable = permission === 'private' ? '' : 'shareable'
|
const shareable = permission === 'private' ? '' : 'shareable'
|
||||||
$('.mapPermission').removeClass('commons public private minimize').addClass(permission)
|
$('.mapPermission').removeClass('commons public private minimize').addClass(permission)
|
||||||
$('.mapPermission .permissionSelect').remove()
|
$('.mapPermission .permissionSelect').remove()
|
||||||
$('.mapInfoBox').removeClass('shareable').addClass(shareable)
|
$('.maptoExport').removeClass('shareable').addClass(shareable)
|
||||||
event.stopPropagation()
|
event.stopPropagation()
|
||||||
},
|
},
|
||||||
deleteActiveMap: function() {
|
deleteActiveMap: function() {
|
||||||
|
@ -371,7 +370,7 @@ const InfoBox = {
|
||||||
var authorized = map.authorizePermissionChange(mapper)
|
var authorized = map.authorizePermissionChange(mapper)
|
||||||
|
|
||||||
if (doIt && authorized) {
|
if (doIt && authorized) {
|
||||||
InfoBox.close()
|
toExport.close()
|
||||||
DataModel.Maps.Active.remove(map)
|
DataModel.Maps.Active.remove(map)
|
||||||
DataModel.Maps.Featured.remove(map)
|
DataModel.Maps.Featured.remove(map)
|
||||||
DataModel.Maps.Mine.remove(map)
|
DataModel.Maps.Mine.remove(map)
|
||||||
|
@ -384,5 +383,7 @@ const InfoBox = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return toExport
|
||||||
|
}
|
||||||
|
|
||||||
export default InfoBox
|
export default InfoBox
|
||||||
|
|
|
@ -6,414 +6,442 @@ import { browserHistory } from 'react-router'
|
||||||
|
|
||||||
import Active from '../Active'
|
import Active from '../Active'
|
||||||
import AutoLayout from '../AutoLayout'
|
import AutoLayout from '../AutoLayout'
|
||||||
|
import Cable from '../Cable'
|
||||||
|
import Control from '../Control'
|
||||||
import Create from '../Create'
|
import Create from '../Create'
|
||||||
import DataModel from '../DataModel'
|
import DataModel from '../DataModel'
|
||||||
import DataModelMap from '../DataModel/Map'
|
import DataModelMap from '../DataModel/Map'
|
||||||
|
import MapperCollection from '../DataModel/MapperCollection'
|
||||||
|
import TopicCollection from '../DataModel/TopicCollection'
|
||||||
|
import SynapseCollection from '../DataModel/SynapseCollection'
|
||||||
|
import MappingCollection from '../DataModel/MappingCollection'
|
||||||
import Filter from '../Filter'
|
import Filter from '../Filter'
|
||||||
import GlobalUI, { ReactApp } from '../GlobalUI'
|
import GlobalUI, { ReactApp } from '../GlobalUI'
|
||||||
|
import Import from '../Import'
|
||||||
|
import InfoBox from './InfoBox'
|
||||||
import JIT from '../JIT'
|
import JIT from '../JIT'
|
||||||
import Listeners from '../Listeners'
|
import Listeners from '../Listeners'
|
||||||
import Loading from '../Loading'
|
import Loading from '../Loading'
|
||||||
|
import Mouse from '../Mouse'
|
||||||
import Organize from '../Organize'
|
import Organize from '../Organize'
|
||||||
|
import PasteInput from '../PasteInput'
|
||||||
import Realtime from '../Realtime'
|
import Realtime from '../Realtime'
|
||||||
import Selected from '../Selected'
|
import Selected from '../Selected'
|
||||||
|
import Synapse from '../Synapse'
|
||||||
import SynapseCard from '../SynapseCard'
|
import SynapseCard from '../SynapseCard'
|
||||||
import Topic from '../Topic'
|
import Topic from '../Topic'
|
||||||
import TopicCard from '../Views/TopicCard'
|
import TopicCard from '../Views/TopicCard'
|
||||||
|
import ChatView from '../Views/ChatView'
|
||||||
import Visualize from '../Visualize'
|
import Visualize from '../Visualize'
|
||||||
|
|
||||||
import CheatSheet from './CheatSheet'
|
import CheatSheet from './CheatSheet'
|
||||||
import InfoBox from './InfoBox'
|
|
||||||
|
|
||||||
const Map = {
|
const mapControl = {
|
||||||
events: {
|
launch: function(id, serverData) {
|
||||||
editedByActiveMapper: 'Metamaps:Map:events:editedByActiveMapper'
|
var dataIsReadySetupMap = function(data) {
|
||||||
},
|
const newMap = {
|
||||||
mapIsStarred: false,
|
Active: null,
|
||||||
requests: [],
|
AutoLayout: null,
|
||||||
userRequested: false,
|
Cable: null,
|
||||||
requestAnswered: false,
|
ChatView: null,
|
||||||
requestApproved: false,
|
Control: null,
|
||||||
hasLearnedTopicCreation: true,
|
Create: null,
|
||||||
init: function(serverData) {
|
DataModel: null,
|
||||||
var self = Map
|
Filter: null,
|
||||||
self.mapIsStarred = serverData.mapIsStarred
|
Import: null,
|
||||||
self.requests = serverData.requests
|
JIT: null,
|
||||||
self.setAccessRequest()
|
Listeners: null,
|
||||||
$('#wrapper').mousedown(function(e) {
|
Mouse: null,
|
||||||
if (e.button === 1) return false
|
Organize: null,
|
||||||
})
|
PasteInput: null,
|
||||||
GlobalUI.CreateMap.emptyForkMapForm = $('#fork_map').html()
|
Realtime: null,
|
||||||
InfoBox.init(serverData, function updateThumbnail() {
|
Selected: null,
|
||||||
self.uploadMapScreenshot()
|
Synapse: null,
|
||||||
})
|
SynapseCard: null,
|
||||||
CheatSheet.init(serverData)
|
Topic: null,
|
||||||
$(document).on(Map.events.editedByActiveMapper, self.editedByActiveMapper)
|
TopicCard: null,
|
||||||
},
|
Visualize: null
|
||||||
setHasLearnedTopicCreation: function(value) {
|
|
||||||
const self = Map
|
|
||||||
self.hasLearnedTopicCreation = value
|
|
||||||
ReactApp.render()
|
|
||||||
},
|
|
||||||
requestAccess: function() {
|
|
||||||
const self = Map
|
|
||||||
self.requests.push({
|
|
||||||
user_id: Active.Mapper.id,
|
|
||||||
answered: false,
|
|
||||||
approved: false
|
|
||||||
})
|
|
||||||
self.setAccessRequest()
|
|
||||||
const mapId = Active.Map.id
|
|
||||||
$.post({
|
|
||||||
url: `/maps/${mapId}/access_request`
|
|
||||||
})
|
|
||||||
GlobalUI.notifyUser('Map creator will be notified of your request')
|
|
||||||
},
|
|
||||||
setAccessRequest: function() {
|
|
||||||
const self = Map
|
|
||||||
if (Active.Mapper) {
|
|
||||||
const request = _find(self.requests, r => r.user_id === Active.Mapper.id)
|
|
||||||
if (!request) {
|
|
||||||
self.userRequested = false
|
|
||||||
self.requestAnswered = false
|
|
||||||
self.requestApproved = false
|
|
||||||
}
|
}
|
||||||
else if (request && !request.answered) {
|
newMap.Active = Active()
|
||||||
self.userRequested = true
|
newMap.AutoLayout = AutoLayout(newMap)
|
||||||
self.requestAnswered = false
|
newMap.Cable = Cable(newMap)
|
||||||
self.requestApproved = false
|
newMap.ChatView = ChatView(newMap)
|
||||||
}
|
newMap.Control = Control(newMap)
|
||||||
else if (request && request.answered && !request.approved) {
|
newMap.Create = Create(newMap)
|
||||||
self.userRequested = true
|
newMap.DataModel = DataModel(newMap)
|
||||||
self.requestAnswered = true
|
newMap.Filter = Filter(newMap)
|
||||||
self.requestApproved = false
|
newMap.Import = Import(newMap)
|
||||||
}
|
newMap.InfoBox = InfoBox(newMap)
|
||||||
}
|
newMap.JIT = JIT(newMap)
|
||||||
ReactApp.render()
|
newMap.Listeners = Listeners(newMap)
|
||||||
},
|
newMap.Map = Map(newMap)
|
||||||
launch: function(id) {
|
newMap.Mouse = Mouse(newMap)
|
||||||
const self = Map
|
newMap.Organize = Organize(newMap)
|
||||||
|
newMap.PasteInput = PasteInput(newMap)
|
||||||
|
newMap.Realtime = Realtime(newMap)
|
||||||
|
newMap.Selected = Selected(newMap)
|
||||||
|
newMap.Synapse = Synapse(newMap)
|
||||||
|
newMap.SynapseCard = SynapseCard(newMap)
|
||||||
|
newMap.Topic = Topic(newMap)
|
||||||
|
newMap.TopicCard = TopicCard(newMap)
|
||||||
|
newMap.Visualize = Visualize(newMap)
|
||||||
|
|
||||||
const newMap = {
|
console.log(newMap)
|
||||||
Active: null,
|
|
||||||
AutoLayout: null,
|
|
||||||
Cable: null,
|
|
||||||
Control: null,
|
|
||||||
Create: null,
|
|
||||||
DataModel: null,
|
|
||||||
Filter: null,
|
|
||||||
Import: null,
|
|
||||||
JIT: null,
|
|
||||||
Listeners: null,
|
|
||||||
Loading: null,
|
|
||||||
Map: null,
|
|
||||||
Mouse: null,
|
|
||||||
Organize: null,
|
|
||||||
PasteInput: null,
|
|
||||||
Realtime: null,
|
|
||||||
Selected: null,
|
|
||||||
Settings: null,
|
|
||||||
Synapse: null,
|
|
||||||
SynapseCard: null,
|
|
||||||
Topic: null,
|
|
||||||
Views: null,
|
|
||||||
Visualize: null
|
|
||||||
}
|
|
||||||
newMap.JIT = JIT(newMap)
|
|
||||||
newMap.Listeners = Listeners(newMap)
|
|
||||||
console.log(newMap)
|
|
||||||
|
|
||||||
var dataIsReadySetupMap = function() {
|
newMap.Active.Map = new DataModelMap(data.map)
|
||||||
Map.setAccessRequest()
|
newMap.DataModel.Mappers = new MapperCollection(data.mappers)
|
||||||
Visualize.type = 'ForceDirected'
|
newMap.DataModel.Collaborators = new MapperCollection(data.collaborators)
|
||||||
|
newMap.DataModel.Topics = new TopicCollection(data.topics)
|
||||||
|
newMap.DataModel.Synapses = new SynapseCollection(data.synapses)
|
||||||
|
newMap.DataModel.Mappings = new MappingCollection(data.mappings)
|
||||||
|
newMap.DataModel.Messages = data.messages
|
||||||
|
newMap.DataModel.Stars = data.stars
|
||||||
|
newMap.DataModel.attachCollectionEvents()
|
||||||
|
newMap.Map.requests = data.requests
|
||||||
|
newMap.Map.setAccessRequest()
|
||||||
|
newMap.Visualize.type = 'ForceDirected'
|
||||||
newMap.JIT.prepareVizData()
|
newMap.JIT.prepareVizData()
|
||||||
Selected.reset()
|
newMap.InfoBox.load()
|
||||||
InfoBox.load()
|
newMap.Filter.checkMetacodes()
|
||||||
Filter.reset()
|
newMap.Filter.checkSynapses()
|
||||||
Filter.checkMetacodes()
|
newMap.Filter.checkMappers()
|
||||||
Filter.checkSynapses()
|
newMap.Realtime.startActiveMap()
|
||||||
Filter.checkMappers()
|
|
||||||
Realtime.startActiveMap()
|
|
||||||
Loading.hide()
|
Loading.hide()
|
||||||
document.title = Active.Map.get('name') + ' | Metamaps'
|
document.title = newMap.Active.Map.get('name') + ' | Metamaps'
|
||||||
ReactApp.mobileTitle = Active.Map.get('name')
|
ReactApp.openMap = newMap
|
||||||
|
ReactApp.mobileTitle = newMap.Active.Map.get('name')
|
||||||
ReactApp.render()
|
ReactApp.render()
|
||||||
}
|
}
|
||||||
function isLoaded() {
|
if (false) {
|
||||||
if (InfoBox.generateBoxHTML) dataIsReadySetupMap()
|
// do something with serverData here
|
||||||
else setTimeout(() => isLoaded(), 50)
|
dataIsReadySetupMap()
|
||||||
}
|
|
||||||
if (Active.Map && Active.Map.id === id) {
|
|
||||||
isLoaded()
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Loading.show()
|
Loading.show()
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: '/maps/' + id + '/contains.json',
|
url: '/maps/' + id + '/contains.json',
|
||||||
success: function(data) {
|
success: dataIsReadySetupMap
|
||||||
Active.Map = new DataModelMap(data.map)
|
|
||||||
DataModel.Mappers = new DataModel.MapperCollection(data.mappers)
|
|
||||||
DataModel.Collaborators = new DataModel.MapperCollection(data.collaborators)
|
|
||||||
DataModel.Topics = new DataModel.TopicCollection(data.topics)
|
|
||||||
DataModel.Synapses = new DataModel.SynapseCollection(data.synapses)
|
|
||||||
DataModel.Mappings = new DataModel.MappingCollection(data.mappings)
|
|
||||||
DataModel.Messages = data.messages
|
|
||||||
DataModel.Stars = data.stars
|
|
||||||
DataModel.attachCollectionEvents()
|
|
||||||
self.requests = data.requests
|
|
||||||
isLoaded()
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
end: function() {
|
end: function(map) {
|
||||||
if (Active.Map) {
|
$('.main').removeClass('compressed')
|
||||||
$('.main').removeClass('compressed')
|
$('.rightclickmenu').remove()
|
||||||
AutoLayout.resetSpiral()
|
map.AutoLayout.resetSpiral()
|
||||||
$('.rightclickmenu').remove()
|
map.TopicCard.hideCard()
|
||||||
TopicCard.hideCard()
|
map.SynapseCard.hideCard()
|
||||||
SynapseCard.hideCard()
|
map.Create.newTopic.hide(true) // true means force (and override pinned)
|
||||||
Create.newTopic.hide(true) // true means force (and override pinned)
|
map.Create.newSynapse.hide()
|
||||||
Create.newSynapse.hide()
|
map.InfoBox.close()
|
||||||
InfoBox.close()
|
map.Realtime.endActiveMap()
|
||||||
Realtime.endActiveMap()
|
map.Map.requests = []
|
||||||
self.requests = []
|
map.Map.hasLearnedTopicCreation = true
|
||||||
self.hasLearnedTopicCreation = true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
star: function() {
|
|
||||||
var self = Map
|
|
||||||
|
|
||||||
if (!Active.Map) return
|
|
||||||
$.post('/maps/' + Active.Map.id + '/star')
|
|
||||||
DataModel.Stars.push({ user_id: Active.Mapper.id, map_id: Active.Map.id })
|
|
||||||
DataModel.Maps.Starred.add(Active.Map)
|
|
||||||
GlobalUI.notifyUser('Map is now starred')
|
|
||||||
self.mapIsStarred = true
|
|
||||||
ReactApp.render()
|
|
||||||
},
|
|
||||||
unstar: function() {
|
|
||||||
var self = Map
|
|
||||||
|
|
||||||
if (!Active.Map) return
|
|
||||||
$.post('/maps/' + Active.Map.id + '/unstar')
|
|
||||||
DataModel.Stars = DataModel.Stars.filter(function(s) { return s.user_id !== Active.Mapper.id })
|
|
||||||
DataModel.Maps.Starred.remove(Active.Map)
|
|
||||||
self.mapIsStarred = false
|
|
||||||
ReactApp.render()
|
|
||||||
},
|
|
||||||
fork: function() {
|
|
||||||
GlobalUI.openLightbox('forkmap')
|
|
||||||
|
|
||||||
let nodesData = ''
|
|
||||||
let synapsesData = ''
|
|
||||||
let nodesArray = []
|
|
||||||
let synapsesArray = []
|
|
||||||
// collect the unfiltered topics
|
|
||||||
Visualize.mGraph.graph.eachNode(function(n) {
|
|
||||||
// if the opacity is less than 1 then it's filtered
|
|
||||||
if (n.getData('alpha') === 1) {
|
|
||||||
var id = n.getData('topic').id
|
|
||||||
nodesArray.push(id)
|
|
||||||
let x, y
|
|
||||||
if (n.pos.x && n.pos.y) {
|
|
||||||
x = n.pos.x
|
|
||||||
y = n.pos.y
|
|
||||||
} else {
|
|
||||||
x = Math.cos(n.pos.theta) * n.pos.rho
|
|
||||||
y = Math.sin(n.pos.theta) * n.pos.rho
|
|
||||||
}
|
|
||||||
nodesData += id + '/' + x + '/' + y + ','
|
|
||||||
}
|
|
||||||
})
|
|
||||||
// collect the unfiltered synapses
|
|
||||||
DataModel.Synapses.each(function(synapse) {
|
|
||||||
var desc = synapse.get('desc')
|
|
||||||
|
|
||||||
var descNotFiltered = Filter.visible.synapses.indexOf(desc) > -1
|
|
||||||
// make sure that both topics are being added, otherwise, it
|
|
||||||
// doesn't make sense to add the synapse
|
|
||||||
var topicsNotFiltered = nodesArray.indexOf(synapse.get('topic1_id')) > -1
|
|
||||||
topicsNotFiltered = topicsNotFiltered && nodesArray.indexOf(synapse.get('topic2_id')) > -1
|
|
||||||
if (descNotFiltered && topicsNotFiltered) {
|
|
||||||
synapsesArray.push(synapse.id)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
synapsesData = synapsesArray.join()
|
|
||||||
nodesData = nodesData.slice(0, -1)
|
|
||||||
|
|
||||||
GlobalUI.CreateMap.topicsToMap = nodesData
|
|
||||||
GlobalUI.CreateMap.synapsesToMap = synapsesData
|
|
||||||
},
|
|
||||||
leavePrivateMap: function() {
|
|
||||||
var map = Active.Map
|
|
||||||
DataModel.Maps.Active.remove(map)
|
|
||||||
DataModel.Maps.Featured.remove(map)
|
|
||||||
browserHistory.push('/')
|
|
||||||
GlobalUI.notifyUser('Sorry! That map has been changed to Private.')
|
|
||||||
},
|
|
||||||
cantEditNow: function() {
|
|
||||||
Realtime.turnOff(true) // true is for 'silence'
|
|
||||||
GlobalUI.notifyUser('Map was changed to Public. Editing is disabled.')
|
|
||||||
Active.Map.trigger('changeByOther')
|
|
||||||
},
|
|
||||||
canEditNow: function() {
|
|
||||||
var confirmString = "You've been granted permission to edit this map. "
|
|
||||||
confirmString += 'Do you want to reload and enable realtime collaboration?'
|
|
||||||
var c = window.confirm(confirmString)
|
|
||||||
if (c) {
|
|
||||||
window.location.reload()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
editedByActiveMapper: function() {
|
|
||||||
if (Active.Mapper) {
|
|
||||||
DataModel.Mappers.add(Active.Mapper)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
offerScreenshotDownload: () => {
|
|
||||||
const canvas = Map.getMapCanvasForScreenshots()
|
|
||||||
const filename = Map.getMapScreenshotFilename(Active.Map)
|
|
||||||
|
|
||||||
var downloadMessage = outdent`
|
|
||||||
Captured map screenshot!
|
|
||||||
<a id="map-screenshot-download-link"
|
|
||||||
href="${canvas.canvas.toDataURL()}"
|
|
||||||
download="${filename}"
|
|
||||||
>
|
|
||||||
DOWNLOAD
|
|
||||||
</a>`
|
|
||||||
GlobalUI.notifyUser(downloadMessage)
|
|
||||||
},
|
|
||||||
uploadMapScreenshot: () => {
|
|
||||||
const canvas = Map.getMapCanvasForScreenshots()
|
|
||||||
const filename = Map.getMapScreenshotFilename(Active.Map)
|
|
||||||
|
|
||||||
canvas.canvas.toBlob(imageBlob => {
|
|
||||||
const formData = new window.FormData()
|
|
||||||
formData.append('map[screenshot]', imageBlob, filename)
|
|
||||||
$.ajax({
|
|
||||||
type: 'PATCH',
|
|
||||||
dataType: 'json',
|
|
||||||
url: `/maps/${Active.Map.id}`,
|
|
||||||
data: formData,
|
|
||||||
processData: false,
|
|
||||||
contentType: false,
|
|
||||||
success: function(data) {
|
|
||||||
GlobalUI.notifyUser('Successfully updated map screenshot.')
|
|
||||||
},
|
|
||||||
error: function() {
|
|
||||||
GlobalUI.notifyUser('Failed to update map screenshot.')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
|
||||||
getMapCanvasForScreenshots: () => {
|
|
||||||
var canvas = {}
|
|
||||||
|
|
||||||
canvas.canvas = document.createElement('canvas')
|
|
||||||
canvas.canvas.width = 1880 // 960
|
|
||||||
canvas.canvas.height = 1260 // 630
|
|
||||||
|
|
||||||
canvas.scaleOffsetX = 1
|
|
||||||
canvas.scaleOffsetY = 1
|
|
||||||
canvas.translateOffsetY = 0
|
|
||||||
canvas.translateOffsetX = 0
|
|
||||||
canvas.denySelected = true
|
|
||||||
|
|
||||||
canvas.getSize = function() {
|
|
||||||
if (this.size) return this.size
|
|
||||||
var canvas = this.canvas
|
|
||||||
this.size = {
|
|
||||||
width: canvas.width,
|
|
||||||
height: canvas.height
|
|
||||||
}
|
|
||||||
return this.size
|
|
||||||
}
|
|
||||||
canvas.scale = function(x, y) {
|
|
||||||
const px = this.scaleOffsetX * x
|
|
||||||
const py = this.scaleOffsetY * y
|
|
||||||
const dx = this.translateOffsetX * (x - 1) / px
|
|
||||||
const dy = this.translateOffsetY * (y - 1) / py
|
|
||||||
this.scaleOffsetX = px
|
|
||||||
this.scaleOffsetY = py
|
|
||||||
this.getCtx().scale(x, y)
|
|
||||||
this.translate(dx, dy)
|
|
||||||
}
|
|
||||||
canvas.translate = function(x, y) {
|
|
||||||
const sx = this.scaleOffsetX
|
|
||||||
const sy = this.scaleOffsetY
|
|
||||||
this.translateOffsetX += x * sx
|
|
||||||
this.translateOffsetY += y * sy
|
|
||||||
this.getCtx().translate(x, y)
|
|
||||||
}
|
|
||||||
canvas.getCtx = function() {
|
|
||||||
return this.canvas.getContext('2d')
|
|
||||||
}
|
|
||||||
// center it
|
|
||||||
canvas.getCtx().translate(1880 / 2, 1260 / 2)
|
|
||||||
|
|
||||||
var mGraph = Visualize.mGraph
|
|
||||||
|
|
||||||
var id = mGraph.root
|
|
||||||
var root = mGraph.graph.getNode(id)
|
|
||||||
var T = !!root.visited
|
|
||||||
|
|
||||||
// pass true to avoid basing it on a selection
|
|
||||||
JIT.zoomExtents(null, canvas, true)
|
|
||||||
|
|
||||||
const c = canvas.canvas
|
|
||||||
const ctx = canvas.getCtx()
|
|
||||||
const scale = canvas.scaleOffsetX
|
|
||||||
|
|
||||||
// draw a grey background
|
|
||||||
ctx.fillStyle = '#d8d9da'
|
|
||||||
const xPoint = (-(c.width / scale) / 2) - (canvas.translateOffsetX / scale)
|
|
||||||
const yPoint = (-(c.height / scale) / 2) - (canvas.translateOffsetY / scale)
|
|
||||||
ctx.fillRect(xPoint, yPoint, c.width / scale, c.height / scale)
|
|
||||||
|
|
||||||
// draw the graph
|
|
||||||
mGraph.graph.eachNode(function(node) {
|
|
||||||
var nodeAlpha = node.getData('alpha')
|
|
||||||
node.eachAdjacency(function(adj) {
|
|
||||||
var nodeTo = adj.nodeTo
|
|
||||||
if (!!nodeTo.visited === T && node.drawn && nodeTo.drawn) {
|
|
||||||
mGraph.fx.plotLine(adj, canvas)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
if (node.drawn) {
|
|
||||||
mGraph.fx.plotNode(node, canvas)
|
|
||||||
}
|
|
||||||
if (!mGraph.labelsHidden) {
|
|
||||||
if (node.drawn && nodeAlpha >= 0.95) {
|
|
||||||
mGraph.labels.plotLabel(canvas, node)
|
|
||||||
} else {
|
|
||||||
mGraph.labels.hideLabel(node, false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
node.visited = !T
|
|
||||||
})
|
|
||||||
|
|
||||||
return canvas
|
|
||||||
},
|
|
||||||
getMapScreenshotFilename: map => {
|
|
||||||
var today = new Date()
|
|
||||||
var dd = today.getDate()
|
|
||||||
var mm = today.getMonth() + 1 // January is 0!
|
|
||||||
var yyyy = today.getFullYear()
|
|
||||||
if (dd < 10) {
|
|
||||||
dd = '0' + dd
|
|
||||||
}
|
|
||||||
if (mm < 10) {
|
|
||||||
mm = '0' + mm
|
|
||||||
}
|
|
||||||
today = mm + '/' + dd + '/' + yyyy
|
|
||||||
|
|
||||||
var mapName = map.get('name').split(' ').join(['-'])
|
|
||||||
const filename = `metamap-${map.id}-${mapName}-${today}.png`
|
|
||||||
return filename
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
export { mapControl }
|
||||||
|
|
||||||
export { CheatSheet, InfoBox }
|
const Map = ({Active, DataModel, JIT, Visualize, Realtime}) => {
|
||||||
|
const toExport = {
|
||||||
|
mapIsStarred: false,
|
||||||
|
requests: [],
|
||||||
|
userRequested: false,
|
||||||
|
requestAnswered: false,
|
||||||
|
requestApproved: false,
|
||||||
|
hasLearnedTopicCreation: true,
|
||||||
|
init: function(serverData) {
|
||||||
|
var self = toExport
|
||||||
|
self.mapIsStarred = serverData.mapIsStarred
|
||||||
|
self.requests = serverData.requests
|
||||||
|
self.setAccessRequest()
|
||||||
|
$('#wrapper').mousedown(function(e) {
|
||||||
|
if (e.button === 1) return false
|
||||||
|
})
|
||||||
|
GlobalUI.CreateMap.emptyForkMapForm = $('#fork_map').html()
|
||||||
|
//InfoBox.init(serverData, function updateThumbnail() {
|
||||||
|
// self.uploadMapScreenshot()
|
||||||
|
//})
|
||||||
|
CheatSheet.init(serverData)
|
||||||
|
$(document).on(Map.events.editedByActiveMapper, self.editedByActiveMapper)
|
||||||
|
},
|
||||||
|
setHasLearnedTopicCreation: function(value) {
|
||||||
|
const self = toExport
|
||||||
|
self.hasLearnedTopicCreation = value
|
||||||
|
ReactApp.render()
|
||||||
|
},
|
||||||
|
requestAccess: function() {
|
||||||
|
const self = toExport
|
||||||
|
self.requests.push({
|
||||||
|
user_id: Active.Mapper.id,
|
||||||
|
answered: false,
|
||||||
|
approved: false
|
||||||
|
})
|
||||||
|
self.setAccessRequest()
|
||||||
|
const mapId = Active.Map.id
|
||||||
|
$.post({
|
||||||
|
url: `/maps/${mapId}/access_request`
|
||||||
|
})
|
||||||
|
GlobalUI.notifyUser('Map creator will be notified of your request')
|
||||||
|
},
|
||||||
|
setAccessRequest: function() {
|
||||||
|
const self = toExport
|
||||||
|
if (Active.Mapper) {
|
||||||
|
const request = _find(self.requests, r => r.user_id === Active.Mapper.id)
|
||||||
|
if (!request) {
|
||||||
|
self.userRequested = false
|
||||||
|
self.requestAnswered = false
|
||||||
|
self.requestApproved = false
|
||||||
|
}
|
||||||
|
else if (request && !request.answered) {
|
||||||
|
self.userRequested = true
|
||||||
|
self.requestAnswered = false
|
||||||
|
self.requestApproved = false
|
||||||
|
}
|
||||||
|
else if (request && request.answered && !request.approved) {
|
||||||
|
self.userRequested = true
|
||||||
|
self.requestAnswered = true
|
||||||
|
self.requestApproved = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ReactApp.render()
|
||||||
|
},
|
||||||
|
star: function() {
|
||||||
|
var self = toExport
|
||||||
|
|
||||||
|
if (!Active.Map) return
|
||||||
|
$.post('/maps/' + Active.Map.id + '/star')
|
||||||
|
DataModel.Stars.push({ user_id: Active.Mapper.id, map_id: Active.Map.id })
|
||||||
|
DataModel.Maps.Starred.add(Active.Map)
|
||||||
|
GlobalUI.notifyUser('Map is now starred')
|
||||||
|
self.mapIsStarred = true
|
||||||
|
ReactApp.render()
|
||||||
|
},
|
||||||
|
unstar: function() {
|
||||||
|
var self = toExport
|
||||||
|
|
||||||
|
if (!Active.Map) return
|
||||||
|
$.post('/maps/' + Active.Map.id + '/unstar')
|
||||||
|
DataModel.Stars = DataModel.Stars.filter(function(s) { return s.user_id !== Active.Mapper.id })
|
||||||
|
DataModel.Maps.Starred.remove(Active.Map)
|
||||||
|
self.mapIsStarred = false
|
||||||
|
ReactApp.render()
|
||||||
|
},
|
||||||
|
fork: function() {
|
||||||
|
GlobalUI.openLightbox('forkmap')
|
||||||
|
|
||||||
|
let nodesData = ''
|
||||||
|
let synapsesData = ''
|
||||||
|
let nodesArray = []
|
||||||
|
let synapsesArray = []
|
||||||
|
// collect the unfiltered topics
|
||||||
|
Visualize.mGraph.graph.eachNode(function(n) {
|
||||||
|
// if the opacity is less than 1 then it's filtered
|
||||||
|
if (n.getData('alpha') === 1) {
|
||||||
|
var id = n.getData('topic').id
|
||||||
|
nodesArray.push(id)
|
||||||
|
let x, y
|
||||||
|
if (n.pos.x && n.pos.y) {
|
||||||
|
x = n.pos.x
|
||||||
|
y = n.pos.y
|
||||||
|
} else {
|
||||||
|
x = Math.cos(n.pos.theta) * n.pos.rho
|
||||||
|
y = Math.sin(n.pos.theta) * n.pos.rho
|
||||||
|
}
|
||||||
|
nodesData += id + '/' + x + '/' + y + ','
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// collect the unfiltered synapses
|
||||||
|
DataModel.Synapses.each(function(synapse) {
|
||||||
|
var desc = synapse.get('desc')
|
||||||
|
|
||||||
|
var descNotFiltered = Filter.visible.synapses.indexOf(desc) > -1
|
||||||
|
// make sure that both topics are being added, otherwise, it
|
||||||
|
// doesn't make sense to add the synapse
|
||||||
|
var topicsNotFiltered = nodesArray.indexOf(synapse.get('topic1_id')) > -1
|
||||||
|
topicsNotFiltered = topicsNotFiltered && nodesArray.indexOf(synapse.get('topic2_id')) > -1
|
||||||
|
if (descNotFiltered && topicsNotFiltered) {
|
||||||
|
synapsesArray.push(synapse.id)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
synapsesData = synapsesArray.join()
|
||||||
|
nodesData = nodesData.slice(0, -1)
|
||||||
|
|
||||||
|
GlobalUI.CreateMap.topicsToMap = nodesData
|
||||||
|
GlobalUI.CreateMap.synapsesToMap = synapsesData
|
||||||
|
},
|
||||||
|
leavePrivateMap: function() {
|
||||||
|
var map = Active.Map
|
||||||
|
DataModel.Maps.Active.remove(map)
|
||||||
|
DataModel.Maps.Featured.remove(map)
|
||||||
|
browserHistory.push('/')
|
||||||
|
GlobalUI.notifyUser('Sorry! That map has been changed to Private.')
|
||||||
|
},
|
||||||
|
cantEditNow: function() {
|
||||||
|
Realtime.turnOff(true) // true is for 'silence'
|
||||||
|
GlobalUI.notifyUser('Map was changed to Public. Editing is disabled.')
|
||||||
|
Active.Map.trigger('changeByOther')
|
||||||
|
},
|
||||||
|
canEditNow: function() {
|
||||||
|
var confirmString = "You've been granted permission to edit this map. "
|
||||||
|
confirmString += 'Do you want to reload and enable realtime collaboration?'
|
||||||
|
var c = window.confirm(confirmString)
|
||||||
|
if (c) {
|
||||||
|
window.location.reload()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
editedByActiveMapper: function() {
|
||||||
|
if (Active.Mapper) {
|
||||||
|
DataModel.Mappers.add(Active.Mapper)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
offerScreenshotDownload: () => {
|
||||||
|
const canvas = toExport.getMapCanvasForScreenshots()
|
||||||
|
const filename = toExport.getMapScreenshotFilename(Active.Map)
|
||||||
|
|
||||||
|
var downloadMessage = outdent`
|
||||||
|
Captured map screenshot!
|
||||||
|
<a id="map-screenshot-download-link"
|
||||||
|
href="${canvas.canvas.toDataURL()}"
|
||||||
|
download="${filename}"
|
||||||
|
>
|
||||||
|
DOWNLOAD
|
||||||
|
</a>`
|
||||||
|
GlobalUI.notifyUser(downloadMessage)
|
||||||
|
},
|
||||||
|
uploadMapScreenshot: () => {
|
||||||
|
const canvas = toExport.getMapCanvasForScreenshots()
|
||||||
|
const filename = toExport.getMapScreenshotFilename(Active.Map)
|
||||||
|
|
||||||
|
canvas.canvas.toBlob(imageBlob => {
|
||||||
|
const formData = new window.FormData()
|
||||||
|
formData.append('map[screenshot]', imageBlob, filename)
|
||||||
|
$.ajax({
|
||||||
|
type: 'PATCH',
|
||||||
|
dataType: 'json',
|
||||||
|
url: `/maps/${Active.Map.id}`,
|
||||||
|
data: formData,
|
||||||
|
processData: false,
|
||||||
|
contentType: false,
|
||||||
|
success: function(data) {
|
||||||
|
GlobalUI.notifyUser('Successfully updated map screenshot.')
|
||||||
|
},
|
||||||
|
error: function() {
|
||||||
|
GlobalUI.notifyUser('Failed to update map screenshot.')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getMapCanvasForScreenshots: () => {
|
||||||
|
var canvas = {}
|
||||||
|
|
||||||
|
canvas.canvas = document.createElement('canvas')
|
||||||
|
canvas.canvas.width = 1880 // 960
|
||||||
|
canvas.canvas.height = 1260 // 630
|
||||||
|
|
||||||
|
canvas.scaleOffsetX = 1
|
||||||
|
canvas.scaleOffsetY = 1
|
||||||
|
canvas.translateOffsetY = 0
|
||||||
|
canvas.translateOffsetX = 0
|
||||||
|
canvas.denySelected = true
|
||||||
|
|
||||||
|
canvas.getSize = function() {
|
||||||
|
if (this.size) return this.size
|
||||||
|
var canvas = this.canvas
|
||||||
|
this.size = {
|
||||||
|
width: canvas.width,
|
||||||
|
height: canvas.height
|
||||||
|
}
|
||||||
|
return this.size
|
||||||
|
}
|
||||||
|
canvas.scale = function(x, y) {
|
||||||
|
const px = this.scaleOffsetX * x
|
||||||
|
const py = this.scaleOffsetY * y
|
||||||
|
const dx = this.translateOffsetX * (x - 1) / px
|
||||||
|
const dy = this.translateOffsetY * (y - 1) / py
|
||||||
|
this.scaleOffsetX = px
|
||||||
|
this.scaleOffsetY = py
|
||||||
|
this.getCtx().scale(x, y)
|
||||||
|
this.translate(dx, dy)
|
||||||
|
}
|
||||||
|
canvas.translate = function(x, y) {
|
||||||
|
const sx = this.scaleOffsetX
|
||||||
|
const sy = this.scaleOffsetY
|
||||||
|
this.translateOffsetX += x * sx
|
||||||
|
this.translateOffsetY += y * sy
|
||||||
|
this.getCtx().translate(x, y)
|
||||||
|
}
|
||||||
|
canvas.getCtx = function() {
|
||||||
|
return this.canvas.getContext('2d')
|
||||||
|
}
|
||||||
|
// center it
|
||||||
|
canvas.getCtx().translate(1880 / 2, 1260 / 2)
|
||||||
|
|
||||||
|
var mGraph = Visualize.mGraph
|
||||||
|
|
||||||
|
var id = mGraph.root
|
||||||
|
var root = mGraph.graph.getNode(id)
|
||||||
|
var T = !!root.visited
|
||||||
|
|
||||||
|
// pass true to avoid basing it on a selection
|
||||||
|
JIT.zoomExtents(null, canvas, true)
|
||||||
|
|
||||||
|
const c = canvas.canvas
|
||||||
|
const ctx = canvas.getCtx()
|
||||||
|
const scale = canvas.scaleOffsetX
|
||||||
|
|
||||||
|
// draw a grey background
|
||||||
|
ctx.fillStyle = '#d8d9da'
|
||||||
|
const xPoint = (-(c.width / scale) / 2) - (canvas.translateOffsetX / scale)
|
||||||
|
const yPoint = (-(c.height / scale) / 2) - (canvas.translateOffsetY / scale)
|
||||||
|
ctx.fillRect(xPoint, yPoint, c.width / scale, c.height / scale)
|
||||||
|
|
||||||
|
// draw the graph
|
||||||
|
mGraph.graph.eachNode(function(node) {
|
||||||
|
var nodeAlpha = node.getData('alpha')
|
||||||
|
node.eachAdjacency(function(adj) {
|
||||||
|
var nodeTo = adj.nodeTo
|
||||||
|
if (!!nodeTo.visited === T && node.drawn && nodeTo.drawn) {
|
||||||
|
mGraph.fx.plotLine(adj, canvas)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (node.drawn) {
|
||||||
|
mGraph.fx.plotNode(node, canvas)
|
||||||
|
}
|
||||||
|
if (!mGraph.labelsHidden) {
|
||||||
|
if (node.drawn && nodeAlpha >= 0.95) {
|
||||||
|
mGraph.labels.plotLabel(canvas, node)
|
||||||
|
} else {
|
||||||
|
mGraph.labels.hideLabel(node, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
node.visited = !T
|
||||||
|
})
|
||||||
|
|
||||||
|
return canvas
|
||||||
|
},
|
||||||
|
getMapScreenshotFilename: map => {
|
||||||
|
var today = new Date()
|
||||||
|
var dd = today.getDate()
|
||||||
|
var mm = today.getMonth() + 1 // January is 0!
|
||||||
|
var yyyy = today.getFullYear()
|
||||||
|
if (dd < 10) {
|
||||||
|
dd = '0' + dd
|
||||||
|
}
|
||||||
|
if (mm < 10) {
|
||||||
|
mm = '0' + mm
|
||||||
|
}
|
||||||
|
today = mm + '/' + dd + '/' + yyyy
|
||||||
|
|
||||||
|
var mapName = map.get('name').split(' ').join(['-'])
|
||||||
|
const filename = `metamap-${map.id}-${mapName}-${today}.png`
|
||||||
|
return filename
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return toExport
|
||||||
|
}
|
||||||
|
Map.events = {
|
||||||
|
editedByActiveMapper: 'Metamaps:Map:events:editedByActiveMapper'
|
||||||
|
}
|
||||||
|
|
||||||
|
export { CheatSheet }
|
||||||
export default Map
|
export default Map
|
||||||
|
|
|
@ -1,16 +1,18 @@
|
||||||
const Mouse = {
|
const Mouse = () => {
|
||||||
didPan: false,
|
return {
|
||||||
didBoxZoom: false,
|
didPan: false,
|
||||||
changeInX: 0,
|
didBoxZoom: false,
|
||||||
changeInY: 0,
|
changeInX: 0,
|
||||||
edgeHoveringOver: false,
|
changeInY: 0,
|
||||||
boxStartCoordinates: false,
|
edgeHoveringOver: false,
|
||||||
boxEndCoordinates: false,
|
boxStartCoordinates: false,
|
||||||
synapseStartCoordinates: [],
|
boxEndCoordinates: false,
|
||||||
synapseEndCoordinates: null,
|
synapseStartCoordinates: [],
|
||||||
lastNodeClick: 0,
|
synapseEndCoordinates: null,
|
||||||
lastCanvasClick: 0,
|
lastNodeClick: 0,
|
||||||
DOUBLE_CLICK_TOLERANCE: 300
|
lastCanvasClick: 0,
|
||||||
|
DOUBLE_CLICK_TOLERANCE: 300
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Mouse
|
export default Mouse
|
||||||
|
|
|
@ -2,10 +2,8 @@ import _ from 'lodash'
|
||||||
|
|
||||||
import $jit from '../patched/JIT'
|
import $jit from '../patched/JIT'
|
||||||
|
|
||||||
import Visualize from './Visualize'
|
const Organize = ({Visualize, JIT}) => {
|
||||||
import JIT from './JIT'
|
const toExport = {
|
||||||
|
|
||||||
const Organize = {
|
|
||||||
arrange: function(layout, centerNode) {
|
arrange: function(layout, centerNode) {
|
||||||
// first option for layout to implement is 'grid', will do an evenly spaced grid with its center at the 0,0 origin
|
// first option for layout to implement is 'grid', will do an evenly spaced grid with its center at the 0,0 origin
|
||||||
if (layout === 'grid') {
|
if (layout === 'grid') {
|
||||||
|
@ -112,5 +110,7 @@ const Organize = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return toExport
|
||||||
|
}
|
||||||
|
|
||||||
export default Organize
|
export default Organize
|
||||||
|
|
|
@ -1,16 +1,15 @@
|
||||||
/* global $ */
|
/* global $ */
|
||||||
|
|
||||||
import Import from './Import'
|
|
||||||
import Util from './Util'
|
import Util from './Util'
|
||||||
import Visualize from './Visualize'
|
|
||||||
|
|
||||||
const PasteInput = {
|
const PasteInput = ({Import, Visualize}) => {
|
||||||
|
const toReturn = {
|
||||||
// thanks to https://github.com/kevva/url-regex
|
// thanks to https://github.com/kevva/url-regex
|
||||||
// eslint-disable-next-line no-useless-escape
|
// eslint-disable-next-line no-useless-escape
|
||||||
URL_REGEX: new RegExp('^(?:(?:(?:[a-z]+:)?//)|www\.)(?:\S+(?::\S*)?@)?(?:localhost|(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(?:\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])){3}|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,}))\.?)(?::\d{2,5})?(?:[/?#][^\s"]*)?$'),
|
URL_REGEX: new RegExp('^(?:(?:(?:[a-z]+:)?//)|www\.)(?:\S+(?::\S*)?@)?(?:localhost|(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(?:\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])){3}|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,}))\.?)(?::\d{2,5})?(?:[/?#][^\s"]*)?$'),
|
||||||
|
|
||||||
init: function() {
|
init: function() {
|
||||||
var self = PasteInput
|
var self = toReturn
|
||||||
|
|
||||||
// intercept dragged files
|
// intercept dragged files
|
||||||
// see http://stackoverflow.com/questions/6756583
|
// see http://stackoverflow.com/questions/6756583
|
||||||
|
@ -50,7 +49,7 @@ const PasteInput = {
|
||||||
},
|
},
|
||||||
|
|
||||||
handleFile: (file, coords = null) => {
|
handleFile: (file, coords = null) => {
|
||||||
var self = PasteInput
|
var self = toReturn
|
||||||
var fileReader = new window.FileReader()
|
var fileReader = new window.FileReader()
|
||||||
fileReader.readAsText(file)
|
fileReader.readAsText(file)
|
||||||
fileReader.onload = function(e) {
|
fileReader.onload = function(e) {
|
||||||
|
@ -64,7 +63,7 @@ const PasteInput = {
|
||||||
},
|
},
|
||||||
|
|
||||||
handle: function(text, coords = {}) {
|
handle: function(text, coords = {}) {
|
||||||
var self = PasteInput
|
var self = toReturn
|
||||||
|
|
||||||
if (text.match(self.URL_REGEX)) {
|
if (text.match(self.URL_REGEX)) {
|
||||||
Import.handleURL(text, coords)
|
Import.handleURL(text, coords)
|
||||||
|
@ -78,5 +77,7 @@ const PasteInput = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return toReturn
|
||||||
|
}
|
||||||
|
|
||||||
export default PasteInput
|
export default PasteInput
|
||||||
|
|
|
@ -3,13 +3,8 @@
|
||||||
import SimpleWebRTC from 'simplewebrtc'
|
import SimpleWebRTC from 'simplewebrtc'
|
||||||
import SocketIoConnection from 'simplewebrtc/socketioconnection'
|
import SocketIoConnection from 'simplewebrtc/socketioconnection'
|
||||||
|
|
||||||
import Active from '../Active'
|
|
||||||
import Cable from '../Cable'
|
|
||||||
import DataModel from '../DataModel'
|
|
||||||
import JIT from '../JIT'
|
|
||||||
import Util from '../Util'
|
import Util from '../Util'
|
||||||
import Views, { ChatView } from '../Views'
|
import Views from '../Views'
|
||||||
import Visualize from '../Visualize'
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
JUNTO_UPDATED,
|
JUNTO_UPDATED,
|
||||||
|
@ -63,8 +58,8 @@ import {
|
||||||
dragTopic
|
dragTopic
|
||||||
} from './sendable'
|
} from './sendable'
|
||||||
|
|
||||||
let Realtime = {
|
const Realtime = ({Active, Cable, DataModel, JIT, Visualize}) => {
|
||||||
juntoState: { connectedPeople: {}, liveMaps: {} },
|
const toExport = {
|
||||||
videoId: 'video-wrapper',
|
videoId: 'video-wrapper',
|
||||||
socket: null,
|
socket: null,
|
||||||
webrtc: null,
|
webrtc: null,
|
||||||
|
@ -78,7 +73,7 @@ let Realtime = {
|
||||||
localVideo: null,
|
localVideo: null,
|
||||||
'junto_spinner_darkgrey.gif': '',
|
'junto_spinner_darkgrey.gif': '',
|
||||||
init: function(serverData) {
|
init: function(serverData) {
|
||||||
var self = Realtime
|
var self = toExport
|
||||||
|
|
||||||
self.addJuntoListeners()
|
self.addJuntoListeners()
|
||||||
|
|
||||||
|
@ -154,7 +149,7 @@ let Realtime = {
|
||||||
} // if Active.Mapper
|
} // if Active.Mapper
|
||||||
},
|
},
|
||||||
addJuntoListeners: function() {
|
addJuntoListeners: function() {
|
||||||
var self = Realtime
|
var self = toExport
|
||||||
|
|
||||||
$(document).on(ChatView.events.openTray, function() {
|
$(document).on(ChatView.events.openTray, function() {
|
||||||
$('.main').addClass('compressed')
|
$('.main').addClass('compressed')
|
||||||
|
@ -180,7 +175,7 @@ let Realtime = {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
startActiveMap: function() {
|
startActiveMap: function() {
|
||||||
var self = Realtime
|
var self = toExport
|
||||||
if (Active.Map && Active.Mapper) {
|
if (Active.Map && Active.Mapper) {
|
||||||
if (Active.Map.authorizeToEdit(Active.Mapper)) {
|
if (Active.Map.authorizeToEdit(Active.Mapper)) {
|
||||||
self.turnOn()
|
self.turnOn()
|
||||||
|
@ -192,7 +187,7 @@ let Realtime = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
endActiveMap: function() {
|
endActiveMap: function() {
|
||||||
var self = Realtime
|
var self = toExport
|
||||||
$(document).off('.map')
|
$(document).off('.map')
|
||||||
// leave the appropriate rooms to leave
|
// leave the appropriate rooms to leave
|
||||||
if (self.inConversation) self.leaveCall()
|
if (self.inConversation) self.leaveCall()
|
||||||
|
@ -202,7 +197,7 @@ let Realtime = {
|
||||||
Cable.unsubscribeFromMap()
|
Cable.unsubscribeFromMap()
|
||||||
},
|
},
|
||||||
turnOn: function(notify) {
|
turnOn: function(notify) {
|
||||||
var self = Realtime
|
var self = toExport
|
||||||
$('.collabCompass').show()
|
$('.collabCompass').show()
|
||||||
self.room.room = 'map-' + Active.Map.id
|
self.room.room = 'map-' + Active.Map.id
|
||||||
self.activeMapper = {
|
self.activeMapper = {
|
||||||
|
@ -219,13 +214,13 @@ let Realtime = {
|
||||||
self.setupLocalEvents()
|
self.setupLocalEvents()
|
||||||
},
|
},
|
||||||
setupChat: function() {
|
setupChat: function() {
|
||||||
const self = Realtime
|
const self = toExport
|
||||||
ChatView.setNewMap()
|
ChatView.setNewMap()
|
||||||
ChatView.addParticipant(self.activeMapper)
|
ChatView.addParticipant(self.activeMapper)
|
||||||
ChatView.addMessages(new DataModel.MessageCollection(DataModel.Messages), true)
|
ChatView.addMessages(new DataModel.MessageCollection(DataModel.Messages), true)
|
||||||
},
|
},
|
||||||
setupLocalEvents: function() {
|
setupLocalEvents: function() {
|
||||||
var self = Realtime
|
var self = toExport
|
||||||
// local event listeners that trigger events
|
// local event listeners that trigger events
|
||||||
$(document).on(JIT.events.zoom + '.map', self.positionPeerIcons)
|
$(document).on(JIT.events.zoom + '.map', self.positionPeerIcons)
|
||||||
$(document).on(JIT.events.pan + '.map', self.positionPeerIcons)
|
$(document).on(JIT.events.pan + '.map', self.positionPeerIcons)
|
||||||
|
@ -242,7 +237,7 @@ let Realtime = {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
countOthersInConversation: function() {
|
countOthersInConversation: function() {
|
||||||
var self = Realtime
|
var self = toExport
|
||||||
var count = 0
|
var count = 0
|
||||||
for (var key in self.mappersOnMap) {
|
for (var key in self.mappersOnMap) {
|
||||||
if (self.mappersOnMap[key].inConversation) count++
|
if (self.mappersOnMap[key].inConversation) count++
|
||||||
|
@ -250,7 +245,7 @@ let Realtime = {
|
||||||
return count
|
return count
|
||||||
},
|
},
|
||||||
handleVideoAdded: function(v, id) {
|
handleVideoAdded: function(v, id) {
|
||||||
var self = Realtime
|
var self = toExport
|
||||||
self.positionVideos()
|
self.positionVideos()
|
||||||
v.setParent($('#wrapper'))
|
v.setParent($('#wrapper'))
|
||||||
v.$container.find('.video-cutoff').css({
|
v.$container.find('.video-cutoff').css({
|
||||||
|
@ -259,7 +254,7 @@ let Realtime = {
|
||||||
$('#wrapper').append(v.$container)
|
$('#wrapper').append(v.$container)
|
||||||
},
|
},
|
||||||
positionVideos: function() {
|
positionVideos: function() {
|
||||||
var self = Realtime
|
var self = toExport
|
||||||
var videoIds = Object.keys(self.room.videos)
|
var videoIds = Object.keys(self.room.videos)
|
||||||
// var numOfVideos = videoIds.length
|
// var numOfVideos = videoIds.length
|
||||||
// var numOfVideosToPosition = _.filter(videoIds, function(id) {
|
// var numOfVideosToPosition = _.filter(videoIds, function(id) {
|
||||||
|
@ -290,7 +285,7 @@ let Realtime = {
|
||||||
}
|
}
|
||||||
|
|
||||||
// do self first
|
// do self first
|
||||||
var myVideo = Realtime.localVideo.view
|
var myVideo = toExport.localVideo.view
|
||||||
if (!myVideo.manuallyPositioned) {
|
if (!myVideo.manuallyPositioned) {
|
||||||
myVideo.$container.css({
|
myVideo.$container.css({
|
||||||
top: yFormula() + 'px',
|
top: yFormula() + 'px',
|
||||||
|
@ -308,7 +303,7 @@ let Realtime = {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
callEnded: function() {
|
callEnded: function() {
|
||||||
var self = Realtime
|
var self = toExport
|
||||||
|
|
||||||
ChatView.conversationEnded()
|
ChatView.conversationEnded()
|
||||||
self.room.leaveVideoOnly()
|
self.room.leaveVideoOnly()
|
||||||
|
@ -336,13 +331,13 @@ let Realtime = {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
positionPeerIcons: function() {
|
positionPeerIcons: function() {
|
||||||
var self = Realtime
|
var self = toExport
|
||||||
for (var key in self.mappersOnMap) {
|
for (var key in self.mappersOnMap) {
|
||||||
self.positionPeerIcon(key)
|
self.positionPeerIcon(key)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
positionPeerIcon: function(id) {
|
positionPeerIcon: function(id) {
|
||||||
var self = Realtime
|
var self = toExport
|
||||||
var mapper = self.mappersOnMap[id]
|
var mapper = self.mappersOnMap[id]
|
||||||
|
|
||||||
var origPixels = Util.coordsToPixels(Visualize.mGraph, mapper.coords)
|
var origPixels = Util.coordsToPixels(Visualize.mGraph, mapper.coords)
|
||||||
|
@ -371,7 +366,7 @@ let Realtime = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
limitPixelsToScreen: function(pixels) {
|
limitPixelsToScreen: function(pixels) {
|
||||||
var self = Realtime
|
var self = toExport
|
||||||
|
|
||||||
var boundary = self.chatOpen ? '#wrapper' : document
|
var boundary = self.chatOpen ? '#wrapper' : document
|
||||||
var xLimit, yLimit
|
var xLimit, yLimit
|
||||||
|
@ -405,25 +400,28 @@ const sendables = [
|
||||||
['dragTopic', dragTopic]
|
['dragTopic', dragTopic]
|
||||||
]
|
]
|
||||||
sendables.forEach(sendable => {
|
sendables.forEach(sendable => {
|
||||||
Realtime[sendable[0]] = sendable[1](Realtime)
|
toExport[sendable[0]] = sendable[1](toExport)
|
||||||
})
|
})
|
||||||
|
|
||||||
const subscribeToEvents = (Realtime, socket) => {
|
const subscribeToEvents = (toExport, socket) => {
|
||||||
socket.on(JUNTO_UPDATED, juntoUpdated(Realtime))
|
socket.on(JUNTO_UPDATED, juntoUpdated(toExport))
|
||||||
socket.on(INVITED_TO_CALL, invitedToCall(Realtime))
|
socket.on(INVITED_TO_CALL, invitedToCall(toExport))
|
||||||
socket.on(INVITED_TO_JOIN, invitedToJoin(Realtime))
|
socket.on(INVITED_TO_JOIN, invitedToJoin(toExport))
|
||||||
socket.on(CALL_ACCEPTED, callAccepted(Realtime))
|
socket.on(CALL_ACCEPTED, callAccepted(toExport))
|
||||||
socket.on(CALL_DENIED, callDenied(Realtime))
|
socket.on(CALL_DENIED, callDenied(toExport))
|
||||||
socket.on(INVITE_DENIED, inviteDenied(Realtime))
|
socket.on(INVITE_DENIED, inviteDenied(toExport))
|
||||||
socket.on(CALL_IN_PROGRESS, callInProgress(Realtime))
|
socket.on(CALL_IN_PROGRESS, callInProgress(toExport))
|
||||||
socket.on(CALL_STARTED, callStarted(Realtime))
|
socket.on(CALL_STARTED, callStarted(toExport))
|
||||||
socket.on(MAPPER_LIST_UPDATED, mapperListUpdated(Realtime))
|
socket.on(MAPPER_LIST_UPDATED, mapperListUpdated(toExport))
|
||||||
socket.on(MAPPER_JOINED_CALL, mapperJoinedCall(Realtime))
|
socket.on(MAPPER_JOINED_CALL, mapperJoinedCall(toExport))
|
||||||
socket.on(MAPPER_LEFT_CALL, mapperLeftCall(Realtime))
|
socket.on(MAPPER_LEFT_CALL, mapperLeftCall(toExport))
|
||||||
socket.on(PEER_COORDS_UPDATED, peerCoordsUpdated(Realtime))
|
socket.on(PEER_COORDS_UPDATED, peerCoordsUpdated(toExport))
|
||||||
socket.on(NEW_MAPPER, newMapper(Realtime))
|
socket.on(NEW_MAPPER, newMapper(toExport))
|
||||||
socket.on(LOST_MAPPER, lostMapper(Realtime))
|
socket.on(LOST_MAPPER, lostMapper(toExport))
|
||||||
socket.on(TOPIC_DRAGGED, topicDragged(Realtime))
|
socket.on(TOPIC_DRAGGED, topicDragged(toExport))
|
||||||
|
}
|
||||||
|
return toExport
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export default Realtime
|
export default Realtime
|
||||||
|
|
|
@ -9,12 +9,12 @@ import { JUNTO_UPDATED } from './events'
|
||||||
import Active from '../Active'
|
import Active from '../Active'
|
||||||
import { ChatView } from '../Views'
|
import { ChatView } from '../Views'
|
||||||
import DataModel from '../DataModel'
|
import DataModel from '../DataModel'
|
||||||
import GlobalUI from '../GlobalUI'
|
import GlobalUI, { ReactApp } from '../GlobalUI'
|
||||||
import Util from '../Util'
|
import Util from '../Util'
|
||||||
import Visualize from '../Visualize'
|
import Visualize from '../Visualize'
|
||||||
|
|
||||||
export const juntoUpdated = self => state => {
|
export const juntoUpdated = self => state => {
|
||||||
self.juntoState = state
|
ReactApp.juntoState = state
|
||||||
$(document).trigger(JUNTO_UPDATED)
|
$(document).trigger(JUNTO_UPDATED)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
const Selected = {
|
const Selected = () => {
|
||||||
reset: function() {
|
const toExport = {
|
||||||
var self = Selected
|
reset: function() {
|
||||||
self.Nodes = []
|
var self = toExport
|
||||||
self.Edges = []
|
self.Nodes = []
|
||||||
},
|
self.Edges = []
|
||||||
Nodes: [],
|
},
|
||||||
Edges: []
|
Nodes: [],
|
||||||
|
Edges: []
|
||||||
|
}
|
||||||
|
return toExport
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Selected
|
export default Selected
|
||||||
|
|
|
@ -1,17 +1,11 @@
|
||||||
/* global $ */
|
/* global $ */
|
||||||
|
|
||||||
import Active from './Active'
|
|
||||||
import Control from './Control'
|
|
||||||
import Create from './Create'
|
|
||||||
import DataModel from './DataModel'
|
|
||||||
import Map from './Map'
|
|
||||||
import Selected from './Selected'
|
|
||||||
import Settings from './Settings'
|
import Settings from './Settings'
|
||||||
import Visualize from './Visualize'
|
|
||||||
|
|
||||||
const noOp = () => {}
|
const noOp = () => {}
|
||||||
|
|
||||||
const Synapse = {
|
const Synapse = ({Active, Control, Create, DataModel, Map, Selected, Visualize}) => {
|
||||||
|
const toExport = {
|
||||||
// this function is to retrieve a synapse JSON object from the database
|
// this function is to retrieve a synapse JSON object from the database
|
||||||
// @param id = the id of the synapse to retrieve
|
// @param id = the id of the synapse to retrieve
|
||||||
get: function(id, callback = noOp) {
|
get: function(id, callback = noOp) {
|
||||||
|
@ -77,7 +71,7 @@ const Synapse = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
createSynapseLocally: function() {
|
createSynapseLocally: function() {
|
||||||
var self = Synapse
|
var self = toExport
|
||||||
let topic1
|
let topic1
|
||||||
let topic2
|
let topic2
|
||||||
let node1
|
let node1
|
||||||
|
@ -124,7 +118,7 @@ const Synapse = {
|
||||||
Create.newSynapse.hide()
|
Create.newSynapse.hide()
|
||||||
},
|
},
|
||||||
getSynapseFromAutocomplete: function(id) {
|
getSynapseFromAutocomplete: function(id) {
|
||||||
var self = Synapse
|
var self = toExport
|
||||||
|
|
||||||
self.get(id, synapse => {
|
self.get(id, synapse => {
|
||||||
const mapping = new DataModel.Mapping({
|
const mapping = new DataModel.Mapping({
|
||||||
|
@ -141,5 +135,7 @@ const Synapse = {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return toExport
|
||||||
|
}
|
||||||
|
|
||||||
export default Synapse
|
export default Synapse
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
/* global $ */
|
/* global $ */
|
||||||
import Active from './Active'
|
|
||||||
import Control from './Control'
|
|
||||||
import Mapper from './Mapper'
|
import Mapper from './Mapper'
|
||||||
import Visualize from './Visualize'
|
|
||||||
|
|
||||||
const SynapseCard = {
|
const SynapseCard = ({Active, Control, Visualize}) => {
|
||||||
|
const toExport = {
|
||||||
openSynapseCard: null,
|
openSynapseCard: null,
|
||||||
showCard: function(edge, e) {
|
showCard: function(edge, e) {
|
||||||
var self = SynapseCard
|
var self = toExport
|
||||||
|
|
||||||
// reset so we don't interfere with other edges, but first, save its x and y
|
// reset so we don't interfere with other edges, but first, save its x and y
|
||||||
var myX = $('#edit_synapse').css('left')
|
var myX = $('#edit_synapse').css('left')
|
||||||
|
@ -53,11 +51,11 @@ const SynapseCard = {
|
||||||
|
|
||||||
hideCard: function() {
|
hideCard: function() {
|
||||||
$('#edit_synapse').remove()
|
$('#edit_synapse').remove()
|
||||||
SynapseCard.openSynapseCard = null
|
toExport.openSynapseCard = null
|
||||||
},
|
},
|
||||||
|
|
||||||
populateShowCard: function(edge, synapse) {
|
populateShowCard: function(edge, synapse) {
|
||||||
var self = SynapseCard
|
var self = toExport
|
||||||
|
|
||||||
self.add_synapse_count(edge)
|
self.add_synapse_count(edge)
|
||||||
self.add_desc_form(synapse)
|
self.add_desc_form(synapse)
|
||||||
|
@ -156,7 +154,7 @@ const SynapseCard = {
|
||||||
var index = parseInt($(this).attr('data-synapse-index'))
|
var index = parseInt($(this).attr('data-synapse-index'))
|
||||||
edge.setData('displayIndex', index)
|
edge.setData('displayIndex', index)
|
||||||
Visualize.mGraph.plot()
|
Visualize.mGraph.plot()
|
||||||
SynapseCard.showCard(edge, false)
|
toExport.showCard(edge, false)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -291,5 +289,7 @@ const SynapseCard = {
|
||||||
} // if
|
} // if
|
||||||
} // add_direction_form
|
} // add_direction_form
|
||||||
}
|
}
|
||||||
|
return toExport
|
||||||
|
}
|
||||||
|
|
||||||
export default SynapseCard
|
export default SynapseCard
|
||||||
|
|
|
@ -2,27 +2,15 @@
|
||||||
|
|
||||||
import $jit from '../patched/JIT'
|
import $jit from '../patched/JIT'
|
||||||
|
|
||||||
import Active from './Active'
|
|
||||||
import AutoLayout from './AutoLayout'
|
|
||||||
import Create from './Create'
|
|
||||||
import DataModel from './DataModel'
|
|
||||||
import Filter from './Filter'
|
|
||||||
import GlobalUI, { ReactApp } from './GlobalUI'
|
import GlobalUI, { ReactApp } from './GlobalUI'
|
||||||
import JIT from './JIT'
|
|
||||||
import Loading from './Loading'
|
import Loading from './Loading'
|
||||||
import Map from './Map'
|
|
||||||
import Selected from './Selected'
|
|
||||||
import Settings from './Settings'
|
import Settings from './Settings'
|
||||||
import SynapseCard from './SynapseCard'
|
|
||||||
import TopicCard from './Views/TopicCard'
|
|
||||||
import Util from './Util'
|
import Util from './Util'
|
||||||
import Visualize from './Visualize'
|
|
||||||
|
|
||||||
const noOp = () => {}
|
const noOp = () => {}
|
||||||
|
|
||||||
const Topic = {
|
const Topic = ({Active, AutoLayout, Create, DataModel, Filter, JIT, MAP, Selected, SynapseCard, TopicCard, Visualize}) => {
|
||||||
// this function is to retrieve a topic JSON object from the database
|
const toExport = {
|
||||||
// @param id = the id of the topic to retrieve
|
|
||||||
get: function(id, callback = noOp) {
|
get: function(id, callback = noOp) {
|
||||||
// if the desired topic is not yet in the local topic repository, fetch it
|
// if the desired topic is not yet in the local topic repository, fetch it
|
||||||
if (DataModel.Topics.get(id) === undefined) {
|
if (DataModel.Topics.get(id) === undefined) {
|
||||||
|
@ -101,7 +89,7 @@ const Topic = {
|
||||||
ReactApp.render()
|
ReactApp.render()
|
||||||
},
|
},
|
||||||
fetchRelatives: function(nodes, metacodeId) {
|
fetchRelatives: function(nodes, metacodeId) {
|
||||||
var self = this
|
var self = toExport
|
||||||
|
|
||||||
var node = $.isArray(nodes) ? nodes[0] : nodes
|
var node = $.isArray(nodes) ? nodes[0] : nodes
|
||||||
|
|
||||||
|
@ -292,7 +280,7 @@ const Topic = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
createTopicLocally: function() {
|
createTopicLocally: function() {
|
||||||
var self = Topic
|
var self = toExport
|
||||||
|
|
||||||
if (Create.newTopic.name === '') {
|
if (Create.newTopic.name === '') {
|
||||||
GlobalUI.notifyUser('Please enter a topic title...')
|
GlobalUI.notifyUser('Please enter a topic title...')
|
||||||
|
@ -330,7 +318,7 @@ const Topic = {
|
||||||
self.renderTopic(mapping, topic, true, true) // this function also includes the creation of the topic in the database
|
self.renderTopic(mapping, topic, true, true) // this function also includes the creation of the topic in the database
|
||||||
},
|
},
|
||||||
getTopicFromAutocomplete: function(id) {
|
getTopicFromAutocomplete: function(id) {
|
||||||
var self = Topic
|
var self = toExport
|
||||||
|
|
||||||
Map.setHasLearnedTopicCreation(true)
|
Map.setHasLearnedTopicCreation(true)
|
||||||
|
|
||||||
|
@ -357,7 +345,7 @@ const Topic = {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
getMapFromAutocomplete: function(data) {
|
getMapFromAutocomplete: function(data) {
|
||||||
var self = Topic
|
var self = toExport
|
||||||
|
|
||||||
$(document).trigger(Map.events.editedByActiveMapper)
|
$(document).trigger(Map.events.editedByActiveMapper)
|
||||||
|
|
||||||
|
@ -387,7 +375,7 @@ const Topic = {
|
||||||
if (Create.newTopic.pinned) Create.newTopic.beingCreated = true
|
if (Create.newTopic.pinned) Create.newTopic.beingCreated = true
|
||||||
},
|
},
|
||||||
getTopicFromSearch: function(event, id) {
|
getTopicFromSearch: function(event, id) {
|
||||||
var self = Topic
|
var self = toExport
|
||||||
|
|
||||||
$(document).trigger(Map.events.editedByActiveMapper)
|
$(document).trigger(Map.events.editedByActiveMapper)
|
||||||
|
|
||||||
|
@ -409,5 +397,7 @@ const Topic = {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return toExport
|
||||||
|
}
|
||||||
|
|
||||||
export default Topic
|
export default Topic
|
||||||
|
|
|
@ -3,18 +3,17 @@
|
||||||
import Backbone from 'backbone'
|
import Backbone from 'backbone'
|
||||||
import { Howl } from 'howler'
|
import { Howl } from 'howler'
|
||||||
|
|
||||||
import Active from '../Active'
|
|
||||||
import DataModel from '../DataModel'
|
|
||||||
import ReactApp from '../GlobalUI/ReactApp'
|
import ReactApp from '../GlobalUI/ReactApp'
|
||||||
|
|
||||||
const ChatView = {
|
const ChatView = ({Active, DataModel}) => {
|
||||||
|
const toExport = {
|
||||||
isOpen: false,
|
isOpen: false,
|
||||||
unreadMessages: 0,
|
unreadMessages: 0,
|
||||||
messages: new Backbone.Collection(),
|
messages: new Backbone.Collection(),
|
||||||
conversationLive: false,
|
conversationLive: false,
|
||||||
isParticipating: false,
|
isParticipating: false,
|
||||||
init: function(urls) {
|
init: function(urls) {
|
||||||
const self = ChatView
|
const self = toExport
|
||||||
self.sound = new Howl({
|
self.sound = new Howl({
|
||||||
src: urls,
|
src: urls,
|
||||||
sprite: {
|
sprite: {
|
||||||
|
@ -27,7 +26,7 @@ const ChatView = {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
setNewMap: function() {
|
setNewMap: function() {
|
||||||
const self = ChatView
|
const self = toExport
|
||||||
self.unreadMessages = 0
|
self.unreadMessages = 0
|
||||||
self.isOpen = false
|
self.isOpen = false
|
||||||
self.conversationLive = false
|
self.conversationLive = false
|
||||||
|
@ -41,74 +40,74 @@ const ChatView = {
|
||||||
},
|
},
|
||||||
render: () => {
|
render: () => {
|
||||||
if (!Active.Map) return
|
if (!Active.Map) return
|
||||||
const self = ChatView
|
const self = toExport
|
||||||
ReactApp.render()
|
ReactApp.render()
|
||||||
},
|
},
|
||||||
onOpen: () => {
|
onOpen: () => {
|
||||||
const self = ChatView
|
const self = toExport
|
||||||
self.isOpen = true
|
self.isOpen = true
|
||||||
self.unreadMessages = 0
|
self.unreadMessages = 0
|
||||||
self.render()
|
self.render()
|
||||||
$(document).trigger(ChatView.events.openTray)
|
$(document).trigger(ChatView.events.openTray)
|
||||||
},
|
},
|
||||||
onClose: () => {
|
onClose: () => {
|
||||||
const self = ChatView
|
const self = toExport
|
||||||
self.isOpen = false
|
self.isOpen = false
|
||||||
$(document).trigger(ChatView.events.closeTray)
|
$(document).trigger(ChatView.events.closeTray)
|
||||||
},
|
},
|
||||||
addParticipant: participant => {
|
addParticipant: participant => {
|
||||||
ChatView.participants.add(participant)
|
toExport.participants.add(participant)
|
||||||
ChatView.render()
|
toExport.render()
|
||||||
},
|
},
|
||||||
removeParticipant: participant => {
|
removeParticipant: participant => {
|
||||||
ChatView.participants.remove(participant)
|
toExport.participants.remove(participant)
|
||||||
ChatView.render()
|
toExport.render()
|
||||||
},
|
},
|
||||||
leaveConversation: () => {
|
leaveConversation: () => {
|
||||||
ChatView.isParticipating = false
|
toExport.isParticipating = false
|
||||||
ChatView.render()
|
toExport.render()
|
||||||
},
|
},
|
||||||
mapperJoinedCall: id => {
|
mapperJoinedCall: id => {
|
||||||
const mapper = ChatView.participants.findWhere({id})
|
const mapper = toExport.participants.findWhere({id})
|
||||||
mapper && mapper.set('isParticipating', true)
|
mapper && mapper.set('isParticipating', true)
|
||||||
ChatView.render()
|
toExport.render()
|
||||||
},
|
},
|
||||||
mapperLeftCall: id => {
|
mapperLeftCall: id => {
|
||||||
const mapper = ChatView.participants.findWhere({id})
|
const mapper = toExport.participants.findWhere({id})
|
||||||
mapper && mapper.set('isParticipating', false)
|
mapper && mapper.set('isParticipating', false)
|
||||||
ChatView.render()
|
toExport.render()
|
||||||
},
|
},
|
||||||
invitationPending: id => {
|
invitationPending: id => {
|
||||||
const mapper = ChatView.participants.findWhere({id})
|
const mapper = toExport.participants.findWhere({id})
|
||||||
mapper && mapper.set('isPending', true)
|
mapper && mapper.set('isPending', true)
|
||||||
ChatView.render()
|
toExport.render()
|
||||||
},
|
},
|
||||||
invitationAnswered: id => {
|
invitationAnswered: id => {
|
||||||
const mapper = ChatView.participants.findWhere({id})
|
const mapper = toExport.participants.findWhere({id})
|
||||||
mapper && mapper.set('isPending', false)
|
mapper && mapper.set('isPending', false)
|
||||||
ChatView.render()
|
toExport.render()
|
||||||
},
|
},
|
||||||
conversationInProgress: participating => {
|
conversationInProgress: participating => {
|
||||||
ChatView.conversationLive = true
|
toExport.conversationLive = true
|
||||||
ChatView.isParticipating = participating
|
toExport.isParticipating = participating
|
||||||
ChatView.render()
|
toExport.render()
|
||||||
},
|
},
|
||||||
conversationEnded: () => {
|
conversationEnded: () => {
|
||||||
ChatView.conversationLive = false
|
toExport.conversationLive = false
|
||||||
ChatView.isParticipating = false
|
toExport.isParticipating = false
|
||||||
ChatView.participants.forEach(p => p.set({isParticipating: false, isPending: false}))
|
toExport.participants.forEach(p => p.set({isParticipating: false, isPending: false}))
|
||||||
ChatView.render()
|
toExport.render()
|
||||||
},
|
},
|
||||||
videoToggleClick: function() {
|
videoToggleClick: function() {
|
||||||
ChatView.videosShowing = !ChatView.videosShowing
|
toExport.videosShowing = !toExport.videosShowing
|
||||||
$(document).trigger(ChatView.videosShowing ? ChatView.events.videosOn : ChatView.events.videosOff)
|
$(document).trigger(toExport.videosShowing ? ChatView.events.videosOn : ChatView.events.videosOff)
|
||||||
},
|
},
|
||||||
cursorToggleClick: function() {
|
cursorToggleClick: function() {
|
||||||
ChatView.cursorsShowing = !ChatView.cursorsShowing
|
toExport.cursorsShowing = !toExport.cursorsShowing
|
||||||
$(document).trigger(ChatView.cursorsShowing ? ChatView.events.cursorsOn : ChatView.events.cursorsOff)
|
$(document).trigger(toExport.cursorsShowing ? ChatView.events.cursorsOn : ChatView.events.cursorsOff)
|
||||||
},
|
},
|
||||||
soundToggleClick: function() {
|
soundToggleClick: function() {
|
||||||
ChatView.alertSound = !ChatView.alertSound
|
toExport.alertSound = !toExport.alertSound
|
||||||
},
|
},
|
||||||
inputFocus: () => {
|
inputFocus: () => {
|
||||||
$(document).trigger(ChatView.events.inputFocus)
|
$(document).trigger(ChatView.events.inputFocus)
|
||||||
|
@ -117,15 +116,15 @@ const ChatView = {
|
||||||
$(document).trigger(ChatView.events.inputBlur)
|
$(document).trigger(ChatView.events.inputBlur)
|
||||||
},
|
},
|
||||||
addMessage: (message, isInitial, wasMe) => {
|
addMessage: (message, isInitial, wasMe) => {
|
||||||
const self = ChatView
|
const self = toExport
|
||||||
if (!isInitial && !self.isOpen) self.unreadMessages += 1
|
if (!isInitial && !self.isOpen) self.unreadMessages += 1
|
||||||
if (!wasMe && !isInitial && self.alertSound) self.sound.play('receivechat')
|
if (!wasMe && !isInitial && self.alertSound) self.sound.play('receivechat')
|
||||||
self.messages.add(message)
|
self.messages.add(message)
|
||||||
if (!isInitial && self.isOpen) self.render()
|
if (!isInitial && self.isOpen) self.render()
|
||||||
},
|
},
|
||||||
sendChatMessage: message => {
|
sendChatMessage: message => {
|
||||||
var self = ChatView
|
var self = toExport
|
||||||
if (ChatView.alertSound) ChatView.sound.play('sendchat')
|
if (toExport.alertSound) toExport.sound.play('sendchat')
|
||||||
var m = new DataModel.Message({
|
var m = new DataModel.Message({
|
||||||
message: message.message,
|
message: message.message,
|
||||||
resource_id: Active.Map.id,
|
resource_id: Active.Map.id,
|
||||||
|
@ -141,14 +140,16 @@ const ChatView = {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
handleInputMessage: text => {
|
handleInputMessage: text => {
|
||||||
ChatView.sendChatMessage({message: text})
|
toExport.sendChatMessage({message: text})
|
||||||
},
|
},
|
||||||
// they should be instantiated as backbone models before they get
|
// they should be instantiated as backbone models before they get
|
||||||
// passed to this function
|
// passed to this function
|
||||||
addMessages: (messages, isInitial, wasMe) => {
|
addMessages: (messages, isInitial, wasMe) => {
|
||||||
messages.models.forEach(m => ChatView.addMessage(m, isInitial, wasMe))
|
messages.models.forEach(m => toExport.addMessage(m, isInitial, wasMe))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return toExport
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @class
|
* @class
|
||||||
|
|
|
@ -1,15 +1,18 @@
|
||||||
import { ReactApp } from '../GlobalUI'
|
import { ReactApp } from '../GlobalUI'
|
||||||
|
|
||||||
const TopicCard = {
|
const TopicCard = () => {
|
||||||
|
const toExport = {
|
||||||
openTopic: null,
|
openTopic: null,
|
||||||
showCard: function(node) {
|
showCard: function(node) {
|
||||||
TopicCard.openTopic = node.getData('topic')
|
toExport.openTopic = node.getData('topic')
|
||||||
ReactApp.render()
|
ReactApp.render()
|
||||||
},
|
},
|
||||||
hideCard: function() {
|
hideCard: function() {
|
||||||
TopicCard.openTopic = null
|
toExport.openTopic = null
|
||||||
ReactApp.render()
|
ReactApp.render()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return toExport
|
||||||
|
}
|
||||||
|
|
||||||
export default TopicCard
|
export default TopicCard
|
||||||
|
|
|
@ -10,7 +10,7 @@ import { JUNTO_UPDATED } from '../Realtime/events'
|
||||||
const Views = {
|
const Views = {
|
||||||
init: (serverData) => {
|
init: (serverData) => {
|
||||||
$(document).on(JUNTO_UPDATED, () => ExploreMaps.render())
|
$(document).on(JUNTO_UPDATED, () => ExploreMaps.render())
|
||||||
ChatView.init([serverData['sounds/MM_sounds.mp3'], serverData['sounds/MM_sounds.ogg']])
|
//ChatView.init([serverData['sounds/MM_sounds.mp3'], serverData['sounds/MM_sounds.ogg']])
|
||||||
},
|
},
|
||||||
ExploreMaps,
|
ExploreMaps,
|
||||||
ChatView,
|
ChatView,
|
||||||
|
|
|
@ -10,14 +10,15 @@ import JIT from './JIT'
|
||||||
import Loading from './Loading'
|
import Loading from './Loading'
|
||||||
import TopicCard from './Views/TopicCard'
|
import TopicCard from './Views/TopicCard'
|
||||||
|
|
||||||
const Visualize = {
|
const Visualize = ({Active, DataModel, JIT, TopicCard}) => {
|
||||||
|
const toExport = {
|
||||||
mGraph: null, // a reference to the graph object.
|
mGraph: null, // a reference to the graph object.
|
||||||
cameraPosition: null, // stores the camera position when using a 3D visualization
|
cameraPosition: null, // stores the camera position when using a 3D visualization
|
||||||
type: 'ForceDirected', // the type of graph we're building, could be "RGraph", "ForceDirected", or "ForceDirected3D"
|
type: 'ForceDirected', // the type of graph we're building, could be "RGraph", "ForceDirected", or "ForceDirected3D"
|
||||||
loadLater: false, // indicates whether there is JSON that should be loaded right in the offset, or whether to wait till the first topic is created
|
loadLater: false, // indicates whether there is JSON that should be loaded right in the offset, or whether to wait till the first topic is created
|
||||||
touchDragNode: null,
|
touchDragNode: null,
|
||||||
init: function(serverData) {
|
init: function(serverData) {
|
||||||
var self = Visualize
|
var self = toExport
|
||||||
|
|
||||||
if (serverData.VisualizeType) self.type = serverData.VisualizeType
|
if (serverData.VisualizeType) self.type = serverData.VisualizeType
|
||||||
|
|
||||||
|
@ -45,7 +46,7 @@ const Visualize = {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
computePositions: function() {
|
computePositions: function() {
|
||||||
const self = Visualize
|
const self = toExport
|
||||||
|
|
||||||
if (self.type === 'RGraph') {
|
if (self.type === 'RGraph') {
|
||||||
let i
|
let i
|
||||||
|
@ -107,7 +108,7 @@ const Visualize = {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
render: function() {
|
render: function() {
|
||||||
const self = Visualize
|
const self = toExport
|
||||||
|
|
||||||
if (self.type === 'RGraph') {
|
if (self.type === 'RGraph') {
|
||||||
// clear the previous canvas from #infovis
|
// clear the previous canvas from #infovis
|
||||||
|
@ -199,11 +200,14 @@ const Visualize = {
|
||||||
hold()
|
hold()
|
||||||
},
|
},
|
||||||
clearVisualization: function() {
|
clearVisualization: function() {
|
||||||
Visualize.mGraph.graph.empty()
|
const self = toExport
|
||||||
Visualize.mGraph.plot()
|
self.mGraph.graph.empty()
|
||||||
|
self.mGraph.plot()
|
||||||
JIT.centerMap(Visualize.mGraph.canvas)
|
JIT.centerMap(Visualize.mGraph.canvas)
|
||||||
$('#infovis').empty()
|
$('#infovis').empty()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return toExport
|
||||||
|
}
|
||||||
|
|
||||||
export default Visualize
|
export default Visualize
|
||||||
|
|
|
@ -1,32 +1,72 @@
|
||||||
import Account from './Account'
|
import Account from './Account'
|
||||||
import Active from './Active'
|
import Active from './Active'
|
||||||
import Admin from './Admin'
|
import Admin from './Admin'
|
||||||
|
import AutoLayout from './AutoLayout'
|
||||||
|
import Cable from './Cable'
|
||||||
|
import Control from './Control'
|
||||||
|
import Create from './Create'
|
||||||
|
import DataModel from './DataModel'
|
||||||
import Debug from './Debug'
|
import Debug from './Debug'
|
||||||
|
import Filter from './Filter'
|
||||||
import GlobalUI, {
|
import GlobalUI, {
|
||||||
ReactApp, Search, CreateMap, ImportDialog
|
ReactApp, Search, CreateMap, ImportDialog
|
||||||
} from './GlobalUI'
|
} from './GlobalUI'
|
||||||
import Import from './Import'
|
import Import from './Import'
|
||||||
|
import JIT from './JIT'
|
||||||
|
import Listeners from './Listeners'
|
||||||
import Loading from './Loading'
|
import Loading from './Loading'
|
||||||
|
import Map, { CheatSheet } from './Map'
|
||||||
import Mapper from './Mapper'
|
import Mapper from './Mapper'
|
||||||
|
import Mouse from './Mouse'
|
||||||
|
import Organize from './Organize'
|
||||||
|
import PasteInput from './PasteInput'
|
||||||
|
import Realtime from './Realtime'
|
||||||
|
import Selected from './Selected'
|
||||||
|
import Settings from './Settings'
|
||||||
|
import Synapse from './Synapse'
|
||||||
|
import SynapseCard from './SynapseCard'
|
||||||
import Topic from './Topic'
|
import Topic from './Topic'
|
||||||
import Util from './Util'
|
import Util from './Util'
|
||||||
|
import Views from './Views'
|
||||||
|
import Visualize from './Visualize'
|
||||||
|
|
||||||
const Metamaps = window.Metamaps || {}
|
const Metamaps = window.Metamaps || {}
|
||||||
Metamaps.Account = Account
|
Metamaps.Account = Account
|
||||||
Metamaps.Active = Active
|
Metamaps.Active = Active
|
||||||
Metamaps.Admin = Admin
|
Metamaps.Admin = Admin
|
||||||
|
Metamaps.AutoLayout = AutoLayout
|
||||||
|
Metamaps.Cable = Cable
|
||||||
|
Metamaps.Control = Control
|
||||||
|
Metamaps.Create = Create
|
||||||
|
Metamaps.DataModel = DataModel
|
||||||
Metamaps.Debug = Debug
|
Metamaps.Debug = Debug
|
||||||
|
Metamaps.Filter = Filter
|
||||||
|
Metamaps.Import = Import
|
||||||
|
Metamaps.JIT = JIT
|
||||||
|
Metamaps.Listeners = Listeners
|
||||||
|
Metamaps.Loading = Loading
|
||||||
|
Metamaps.Map = Map
|
||||||
|
Metamaps.Map.CheatSheet = CheatSheet
|
||||||
|
Metamaps.Maps = {}
|
||||||
|
Metamaps.Mapper = Mapper
|
||||||
|
Metamaps.Mouse = Mouse
|
||||||
|
Metamaps.Organize = Organize
|
||||||
|
Metamaps.PasteInput = PasteInput
|
||||||
|
Metamaps.Realtime = Realtime
|
||||||
|
Metamaps.Selected = Selected
|
||||||
|
Metamaps.Settings = Settings
|
||||||
|
Metamaps.Synapse = Synapse
|
||||||
|
Metamaps.SynapseCard = SynapseCard
|
||||||
|
Metamaps.Topic = Topic
|
||||||
|
Metamaps.Util = Util
|
||||||
|
Metamaps.Views = Views
|
||||||
|
Metamaps.Visualize = Visualize
|
||||||
|
|
||||||
Metamaps.GlobalUI = GlobalUI
|
Metamaps.GlobalUI = GlobalUI
|
||||||
Metamaps.GlobalUI.ReactApp = ReactApp
|
Metamaps.GlobalUI.ReactApp = ReactApp
|
||||||
Metamaps.GlobalUI.Search = Search
|
Metamaps.GlobalUI.Search = Search
|
||||||
Metamaps.GlobalUI.CreateMap = CreateMap
|
Metamaps.GlobalUI.CreateMap = CreateMap
|
||||||
Metamaps.GlobalUI.ImportDialog = ImportDialog
|
Metamaps.GlobalUI.ImportDialog = ImportDialog
|
||||||
Metamaps.Import = Import
|
|
||||||
Metamaps.Loading = Loading
|
|
||||||
Metamaps.Maps = {}
|
|
||||||
Metamaps.Mapper = Mapper
|
|
||||||
Metamaps.Topic = Topic
|
|
||||||
Metamaps.Util = Util
|
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
// initialize all the modules
|
// initialize all the modules
|
||||||
|
@ -37,6 +77,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||||
Metamaps[prop].hasOwnProperty('init') &&
|
Metamaps[prop].hasOwnProperty('init') &&
|
||||||
typeof (Metamaps[prop].init) === 'function'
|
typeof (Metamaps[prop].init) === 'function'
|
||||||
) {
|
) {
|
||||||
|
console.log(prop)
|
||||||
Metamaps[prop].init(Metamaps.ServerData)
|
Metamaps[prop].init(Metamaps.ServerData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue