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>
|
||||
|
||||
<script>
|
||||
Metamaps.ServerData = Metamaps.ServerData || {}
|
||||
Metamaps.ServerData.selectedMetacodes = []
|
||||
Metamaps.ServerData.newSelectedMetacodes = []
|
||||
Metamaps.ServerData.selectedMetacodeNames = []
|
||||
Metamaps.ServerData.newSelectedMetacodeNames = []
|
||||
<% @metacodes.each do |metacode| %>
|
||||
Metamaps.Create.selectedMetacodes.push("<%= metacode.id %>");
|
||||
Metamaps.Create.newSelectedMetacodes.push("<%= metacode.id %>");
|
||||
Metamaps.Create.selectedMetacodeNames.push("<%= metacode.name %>");
|
||||
Metamaps.Create.newSelectedMetacodeNames.push("<%= metacode.name %>");
|
||||
Metamaps.ServerData.selectedMetacodes.push("<%= metacode.id %>");
|
||||
Metamaps.ServerData.newSelectedMetacodes.push("<%= metacode.id %>");
|
||||
Metamaps.ServerData.selectedMetacodeNames.push("<%= metacode.name %>");
|
||||
Metamaps.ServerData.newSelectedMetacodeNames.push("<%= metacode.name %>");
|
||||
<% end %>
|
||||
</script>
|
||||
<% end %>
|
||||
|
|
|
@ -116,6 +116,7 @@
|
|||
<div class="clearfloat"></div>
|
||||
|
||||
<script>
|
||||
Metamaps.Create.selectedMetacodeSet = "metacodeset-<%= selectedSet %>"
|
||||
Metamaps.Create.selectedMetacodeSetIndex = <%= index %>
|
||||
Metamaps.ServerData = Metamaps.ServerData || {}
|
||||
Metamaps.ServerData.selectedMetacodeSet = "metacodeset-<%= selectedSet %>"
|
||||
Metamaps.ServerData.selectedMetacodeSetIndex = <%= index %>
|
||||
</script>
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
const Active = {
|
||||
Map: null,
|
||||
Mapper: null,
|
||||
Topic: null
|
||||
const Active = (map = null, mapper = null, topic = null) => {
|
||||
return {
|
||||
Map: map,
|
||||
Mapper: mapper,
|
||||
Topic: topic
|
||||
}
|
||||
}
|
||||
|
||||
export default Active
|
||||
|
|
|
@ -1,77 +1,79 @@
|
|||
const AutoLayout = {
|
||||
nextX: 0,
|
||||
nextY: 0,
|
||||
sideLength: 1,
|
||||
turnCount: 0,
|
||||
nextXshift: 1,
|
||||
nextYshift: 0,
|
||||
timeToTurn: 0,
|
||||
const AutoLayout = () => {
|
||||
return {
|
||||
nextX: 0,
|
||||
nextY: 0,
|
||||
sideLength: 1,
|
||||
turnCount: 0,
|
||||
nextXshift: 1,
|
||||
nextYshift: 0,
|
||||
timeToTurn: 0,
|
||||
|
||||
getNextCoord: function(opts = {}) {
|
||||
var self = AutoLayout
|
||||
var nextX = self.nextX
|
||||
var nextY = self.nextY
|
||||
getNextCoord: function(opts = {}) {
|
||||
var self = AutoLayout
|
||||
var nextX = self.nextX
|
||||
var nextY = self.nextY
|
||||
|
||||
var DISTANCE_BETWEEN = 120
|
||||
var DISTANCE_BETWEEN = 120
|
||||
|
||||
self.nextX = self.nextX + DISTANCE_BETWEEN * self.nextXshift
|
||||
self.nextY = self.nextY + DISTANCE_BETWEEN * self.nextYshift
|
||||
self.nextX = self.nextX + DISTANCE_BETWEEN * self.nextXshift
|
||||
self.nextY = self.nextY + DISTANCE_BETWEEN * self.nextYshift
|
||||
|
||||
self.timeToTurn += 1
|
||||
// if true, it's time to turn
|
||||
if (self.timeToTurn === self.sideLength) {
|
||||
self.turnCount += 1
|
||||
// if true, it's time to increase side length
|
||||
if (self.turnCount % 2 === 0) {
|
||||
self.sideLength += 1
|
||||
self.timeToTurn += 1
|
||||
// if true, it's time to turn
|
||||
if (self.timeToTurn === self.sideLength) {
|
||||
self.turnCount += 1
|
||||
// if true, it's time to increase side length
|
||||
if (self.turnCount % 2 === 0) {
|
||||
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
|
||||
|
||||
// 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
|
||||
}
|
||||
self.turnCount = 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 Active from './Active'
|
||||
import Control from './Control'
|
||||
import DataModel from './DataModel'
|
||||
import Map from './Map'
|
||||
import Mapper from './Mapper'
|
||||
import Synapse from './Synapse'
|
||||
import Topic from './Topic'
|
||||
import { ChatView } from './Views'
|
||||
import Visualize from './Visualize'
|
||||
|
||||
const Cable = {
|
||||
init: () => {
|
||||
let self = Cable
|
||||
self.cable = ActionCable.createConsumer()
|
||||
},
|
||||
const Cable = ({Active, Control, DataModel, Map, Synapse, Topic, ChatView, Visualize}) => {
|
||||
const toExport = {
|
||||
subscribeToMap: id => {
|
||||
let self = Cable
|
||||
self.sub = self.cable.subscriptions.create({
|
||||
let self = toExport
|
||||
self.sub = Cable.cable.subscriptions.create({
|
||||
channel: 'MapChannel',
|
||||
id: id
|
||||
}, {
|
||||
|
@ -27,7 +16,7 @@ const Cable = {
|
|||
})
|
||||
},
|
||||
unsubscribeFromMap: () => {
|
||||
let self = Cable
|
||||
let self = toExport
|
||||
self.sub.unsubscribe()
|
||||
delete self.sub
|
||||
},
|
||||
|
@ -230,5 +219,10 @@ const Cable = {
|
|||
})
|
||||
}
|
||||
}
|
||||
return toExport
|
||||
}
|
||||
Cable.init = () => {
|
||||
Cable.cable = ActionCable.createConsumer()
|
||||
}
|
||||
|
||||
export default Cable
|
||||
|
|
|
@ -1,452 +1,448 @@
|
|||
import _ from 'lodash'
|
||||
import outdent from 'outdent'
|
||||
|
||||
import Active from './Active'
|
||||
import DataModel from './DataModel'
|
||||
import Filter from './Filter'
|
||||
import GlobalUI from './GlobalUI'
|
||||
import Mouse from './Mouse'
|
||||
import Selected from './Selected'
|
||||
import Settings from './Settings'
|
||||
import Visualize from './Visualize'
|
||||
|
||||
const Control = {
|
||||
selectNode: function(node, e) {
|
||||
var filtered = node.getData('alpha') === 0
|
||||
const Control = ({Active, DataModel, Filter, Mouse, Selected, Visualize}) => {
|
||||
return {
|
||||
selectNode: function(node, e) {
|
||||
var filtered = node.getData('alpha') === 0
|
||||
|
||||
if (filtered || Selected.Nodes.indexOf(node) !== -1) return
|
||||
node.selected = true
|
||||
node.setData('dim', 30, 'current')
|
||||
Selected.Nodes.push(node)
|
||||
},
|
||||
selectNeighbors: function() {
|
||||
if (Selected.Nodes.length > 0) {
|
||||
//For each selected node, select all connected node and the synapses too
|
||||
Selected.Nodes.forEach((item) => {
|
||||
if (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.selectEdge(Visualize.mGraph.graph.getNode(item.id).adjacencies[adjID])
|
||||
if (filtered || Selected.Nodes.indexOf(node) !== -1) return
|
||||
node.selected = true
|
||||
node.setData('dim', 30, 'current')
|
||||
Selected.Nodes.push(node)
|
||||
},
|
||||
selectNeighbors: function() {
|
||||
if (Selected.Nodes.length > 0) {
|
||||
//For each selected node, select all connected node and the synapses too
|
||||
Selected.Nodes.forEach((item) => {
|
||||
if (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.selectEdge(Visualize.mGraph.graph.getNode(item.id).adjacencies[adjID])
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
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.plot()
|
||||
}
|
||||
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
|
||||
},
|
||||
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')
|
||||
|
||||
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
|
||||
edge.setDataset('current', {
|
||||
showDesc: true,
|
||||
lineWidth: width,
|
||||
color: Settings.colors.synapses.selected
|
||||
})
|
||||
Visualize.mGraph.plot()
|
||||
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'
|
||||
|
||||
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')
|
||||
var authorized = Active.Map.authorizeToEdit(Active.Mapper)
|
||||
|
||||
edge.setDataset('current', {
|
||||
lineWidth: 2,
|
||||
color: Settings.colors.synapses.normal
|
||||
})
|
||||
if (!authorized) {
|
||||
GlobalUI.notifyUser('Cannot edit Public map.')
|
||||
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', {
|
||||
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
|
||||
Selected.Edges.splice(
|
||||
Selected.Edges.indexOf(edge), 1)
|
||||
},
|
||||
deleteSelectedEdges: function() { // refers to deleting topics permanently
|
||||
if (!Active.Map) return
|
||||
edge.setDataset('current', {
|
||||
lineWidth: 2,
|
||||
color: Settings.colors.synapses.normal
|
||||
})
|
||||
|
||||
var authorized = Active.Map.authorizeToEdit(Active.Mapper)
|
||||
if (Mouse.edgeHoveringOver === edge) {
|
||||
edge.setDataset('current', {
|
||||
showDesc: true,
|
||||
lineWidth: 4
|
||||
})
|
||||
}
|
||||
|
||||
if (!authorized) {
|
||||
GlobalUI.notifyUser('Cannot edit Public map.')
|
||||
return
|
||||
}
|
||||
Visualize.mGraph.plot()
|
||||
|
||||
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
|
||||
// remove the edge
|
||||
Selected.Edges.splice(
|
||||
Selected.Edges.indexOf(edge), 1)
|
||||
},
|
||||
deleteSelectedEdges: function() { // refers to deleting topics permanently
|
||||
if (!Active.Map) return
|
||||
|
||||
var authorized = Active.Map.authorizeToEdit(Active.Mapper)
|
||||
var authorized = Active.Map.authorizeToEdit(Active.Mapper)
|
||||
|
||||
if (!authorized) {
|
||||
GlobalUI.notifyUser('Cannot edit Public map.')
|
||||
return
|
||||
}
|
||||
if (!authorized) {
|
||||
GlobalUI.notifyUser('Cannot edit Public map.')
|
||||
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 mapping = edge.getData('mappings')[index]
|
||||
var authorized = Active.Map.authorizeToEdit(Active.Mapper)
|
||||
|
||||
var permToDelete = Active.Mapper.id === synapse.get('user_id') || Active.Mapper.get('admin')
|
||||
if (permToDelete) {
|
||||
if (edge.getData('synapses').length - 1 === 0) {
|
||||
if (!authorized) {
|
||||
GlobalUI.notifyUser('Cannot edit Public map.')
|
||||
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)
|
||||
}
|
||||
synapse.destroy()
|
||||
|
||||
// the server will destroy the mapping, we just need to remove it here
|
||||
DataModel.Mappings.remove(mapping)
|
||||
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
|
||||
}
|
||||
} 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)
|
||||
}
|
||||
|
||||
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++
|
||||
},
|
||||
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
|
||||
|
||||
// change the permission of the selected topics, if logged in user is the original creator
|
||||
const nodesLength = Selected.Nodes.length
|
||||
for (let i = nodesLength - 1; i >= 0; i -= 1) {
|
||||
node = Selected.Nodes[i]
|
||||
topic = node.getData('topic')
|
||||
GlobalUI.notifyUser('Working...')
|
||||
|
||||
if (topic.authorizePermissionChange(Active.Mapper)) {
|
||||
topic.save({
|
||||
permission: permission
|
||||
})
|
||||
nCount++
|
||||
// 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++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var nString = nCount === 1 ? (nCount.toString() + ' topic and ') : (nCount.toString() + ' topics and ')
|
||||
var sString = sCount === 1 ? (sCount.toString() + ' synapse') : (sCount.toString() + ' synapses')
|
||||
// change the permission of the selected topics, if logged in user is the original creator
|
||||
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
|
||||
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++
|
||||
if (topic.authorizePermissionChange(Active.Mapper)) {
|
||||
topic.save({
|
||||
permission: permission
|
||||
})
|
||||
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 */
|
||||
|
||||
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'
|
||||
|
||||
const Create = {
|
||||
const toExport = ({DataModel, Map, Mouse, Selected, Synapse, Topic, Visualize}) => {
|
||||
const toExport = {
|
||||
isSwitchingSet: false, // indicates whether the metacode set switch lightbox is open
|
||||
selectedMetacodeSet: null,
|
||||
selectedMetacodeSetIndex: null,
|
||||
|
@ -17,52 +11,54 @@ const Create = {
|
|||
newSelectedMetacodeNames: [],
|
||||
selectedMetacodes: [],
|
||||
newSelectedMetacodes: [],
|
||||
init: function() {
|
||||
var self = Create
|
||||
self.newTopic.init()
|
||||
self.newSynapse.init()
|
||||
|
||||
init: function(serverData) {
|
||||
toExport.newTopic.init()
|
||||
toExport.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
|
||||
|
||||
$('#metacodeSwitchTabs').tabs({
|
||||
active: self.selectedMetacodeSetIndex
|
||||
active: toExport.selectedMetacodeSetIndex
|
||||
}).addClass('ui-tabs-vertical ui-helper-clearfix')
|
||||
$('#metacodeSwitchTabs .ui-tabs-nav li').removeClass('ui-corner-top').addClass('ui-corner-left')
|
||||
$('.customMetacodeList li').click(self.toggleMetacodeSelected) // within the custom metacode set tab
|
||||
$('.selectAll').click(self.metacodeSelectorSelectAll)
|
||||
$('.selectNone').click(self.metacodeSelectorSelectNone)
|
||||
$('.customMetacodeList li').click(toExport.toggleMetacodeSelected) // within the custom metacode set tab
|
||||
$('.selectAll').click(toExport.metacodeSelectorSelectAll)
|
||||
$('.selectNone').click(toExport.metacodeSelectorSelectNone)
|
||||
},
|
||||
toggleMetacodeSelected: function() {
|
||||
var self = Create
|
||||
|
||||
if ($(this).attr('class') !== 'toggledOff') {
|
||||
$(this).addClass('toggledOff')
|
||||
var valueToRemove = $(this).attr('id')
|
||||
var nameToRemove = $(this).attr('data-name')
|
||||
self.newSelectedMetacodes.splice(self.newSelectedMetacodes.indexOf(valueToRemove), 1)
|
||||
self.newSelectedMetacodeNames.splice(self.newSelectedMetacodeNames.indexOf(nameToRemove), 1)
|
||||
toExport.newSelectedMetacodes.splice(self.newSelectedMetacodes.indexOf(valueToRemove), 1)
|
||||
toExport.newSelectedMetacodeNames.splice(self.newSelectedMetacodeNames.indexOf(nameToRemove), 1)
|
||||
} else if ($(this).attr('class') === 'toggledOff') {
|
||||
$(this).removeClass('toggledOff')
|
||||
self.newSelectedMetacodes.push($(this).attr('id'))
|
||||
self.newSelectedMetacodeNames.push($(this).attr('data-name'))
|
||||
toExport.newSelectedMetacodes.push($(this).attr('id'))
|
||||
toExport.newSelectedMetacodeNames.push($(this).attr('data-name'))
|
||||
}
|
||||
self.updateSelectAllColors()
|
||||
toExport.updateSelectAllColors()
|
||||
},
|
||||
updateSelectAllColors: function() {
|
||||
$('.selectAll, .selectNone').removeClass('selected')
|
||||
if (Create.metacodeSelectorAreAllSelected()) {
|
||||
if (toExport.metacodeSelectorAreAllSelected()) {
|
||||
$('.selectAll').addClass('selected')
|
||||
} else if (Create.metacodeSelectorAreNoneSelected()) {
|
||||
} else if (toExport.metacodeSelectorAreNoneSelected()) {
|
||||
$('.selectNone').addClass('selected')
|
||||
}
|
||||
},
|
||||
metacodeSelectorSelectAll: function() {
|
||||
$('.customMetacodeList li.toggledOff').each(Create.toggleMetacodeSelected)
|
||||
Create.updateSelectAllColors()
|
||||
$('.customMetacodeList li.toggledOff').each(toExport.toggleMetacodeSelected)
|
||||
toExport.updateSelectAllColors()
|
||||
},
|
||||
metacodeSelectorSelectNone: function() {
|
||||
$('.customMetacodeList li').not('.toggledOff').each(Create.toggleMetacodeSelected)
|
||||
Create.updateSelectAllColors()
|
||||
$('.customMetacodeList li').not('.toggledOff').each(toExport.toggleMetacodeSelected)
|
||||
toExport.updateSelectAllColors()
|
||||
},
|
||||
metacodeSelectorAreAllSelected: function() {
|
||||
return $('.customMetacodeList li').toArray()
|
||||
|
@ -75,41 +71,41 @@ const Create = {
|
|||
.reduce((curr, prev) => curr && prev)
|
||||
},
|
||||
metacodeSelectorToggleSelectAll: function() {
|
||||
// should be called when Create.isSwitchingSet is true and .customMetacodeList is visible
|
||||
if (!Create.isSwitchingSet) return
|
||||
// should be called when toExport.isSwitchingSet is true and .customMetacodeList is visible
|
||||
if (!toExport.isSwitchingSet) return
|
||||
if (!$('.customMetacodeList').is(':visible')) return
|
||||
|
||||
// If all are selected, then select none. Otherwise, select all.
|
||||
if (Create.metacodeSelectorAreAllSelected()) {
|
||||
Create.metacodeSelectorSelectNone()
|
||||
if (toExport.metacodeSelectorAreAllSelected()) {
|
||||
toExport.metacodeSelectorSelectNone()
|
||||
} else {
|
||||
// if some, but not all, are selected, it still runs this function
|
||||
Create.metacodeSelectorSelectAll()
|
||||
toExport.metacodeSelectorSelectAll()
|
||||
}
|
||||
},
|
||||
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!')
|
||||
return false
|
||||
}
|
||||
|
||||
var codesToSwitchToIds
|
||||
var metacodeModels = new DataModel.MetacodeCollection()
|
||||
Create.selectedMetacodeSetIndex = index
|
||||
Create.selectedMetacodeSet = 'metacodeset-' + set
|
||||
toExport.selectedMetacodeSetIndex = index
|
||||
toExport.selectedMetacodeSet = 'metacodeset-' + set
|
||||
|
||||
if (!custom) {
|
||||
codesToSwitchToIds = $('#metacodeSwitchTabs' + set).attr('data-metacodes').split(',')
|
||||
$('.customMetacodeList li').addClass('toggledOff')
|
||||
Create.selectedMetacodes = []
|
||||
Create.selectedMetacodeNames = []
|
||||
Create.newSelectedMetacodes = []
|
||||
Create.newSelectedMetacodeNames = []
|
||||
toExport.selectedMetacodes = []
|
||||
toExport.selectedMetacodeNames = []
|
||||
toExport.newSelectedMetacodes = []
|
||||
toExport.newSelectedMetacodeNames = []
|
||||
} else if (custom) {
|
||||
// uses .slice to avoid setting the two arrays to the same actual array
|
||||
Create.selectedMetacodes = Create.newSelectedMetacodes.slice(0)
|
||||
Create.selectedMetacodeNames = Create.newSelectedMetacodeNames.slice(0)
|
||||
codesToSwitchToIds = Create.selectedMetacodes.slice(0)
|
||||
toExport.selectedMetacodes = Create.newSelectedMetacodes.slice(0)
|
||||
toExport.selectedMetacodeNames = Create.newSelectedMetacodeNames.slice(0)
|
||||
codesToSwitchToIds = toExport.selectedMetacodes.slice(0)
|
||||
}
|
||||
|
||||
// sort by name
|
||||
|
@ -141,7 +137,7 @@ const Create = {
|
|||
|
||||
var mdata = {
|
||||
'metacodes': {
|
||||
'value': custom ? Create.selectedMetacodes.toString() : Create.selectedMetacodeSet
|
||||
'value': custom ? toExport.selectedMetacodes.toString() : Create.selectedMetacodeSet
|
||||
}
|
||||
}
|
||||
$.ajax({
|
||||
|
@ -158,26 +154,25 @@ const Create = {
|
|||
})
|
||||
},
|
||||
cancelMetacodeSetSwitch: function() {
|
||||
var self = Create
|
||||
self.isSwitchingSet = false
|
||||
toExport.isSwitchingSet = false
|
||||
|
||||
if (self.selectedMetacodeSet !== 'metacodeset-custom') {
|
||||
if (toExport.selectedMetacodeSet !== 'metacodeset-custom') {
|
||||
$('.customMetacodeList li').addClass('toggledOff')
|
||||
self.selectedMetacodes = []
|
||||
self.selectedMetacodeNames = []
|
||||
self.newSelectedMetacodes = []
|
||||
self.newSelectedMetacodeNames = []
|
||||
toExport.selectedMetacodes = []
|
||||
toExport.selectedMetacodeNames = []
|
||||
toExport.newSelectedMetacodes = []
|
||||
toExport.newSelectedMetacodeNames = []
|
||||
} else { // custom set is selected
|
||||
// reset it to the current actual selection
|
||||
$('.customMetacodeList li').addClass('toggledOff')
|
||||
for (var i = 0; i < self.selectedMetacodes.length; i++) {
|
||||
$('#' + self.selectedMetacodes[i]).removeClass('toggledOff')
|
||||
for (var i = 0; i < toExport.selectedMetacodes.length; i++) {
|
||||
$('#' + toExport.selectedMetacodes[i]).removeClass('toggledOff')
|
||||
}
|
||||
// uses .slice to avoid setting the two arrays to the same actual array
|
||||
self.newSelectedMetacodeNames = self.selectedMetacodeNames.slice(0)
|
||||
self.newSelectedMetacodes = self.selectedMetacodes.slice(0)
|
||||
toExport.newSelectedMetacodeNames = self.selectedMetacodeNames.slice(0)
|
||||
toExport.newSelectedMetacodes = self.selectedMetacodes.slice(0)
|
||||
}
|
||||
$('#metacodeSwitchTabs').tabs('option', 'active', self.selectedMetacodeSetIndex)
|
||||
$('#metacodeSwitchTabs').tabs('option', 'active', toExport.selectedMetacodeSetIndex)
|
||||
$('#topic_name').focus()
|
||||
},
|
||||
newTopic: {
|
||||
|
@ -186,19 +181,19 @@ const Create = {
|
|||
const ESC = 27
|
||||
|
||||
if (e.keyCode === ESC) {
|
||||
Create.newTopic.hide()
|
||||
toExport.newTopic.hide()
|
||||
} // if
|
||||
|
||||
Create.newTopic.name = $(this).val()
|
||||
toExport.newTopic.name = $(this).val()
|
||||
})
|
||||
|
||||
$('.pinCarousel').click(function() {
|
||||
if (Create.newTopic.pinned) {
|
||||
if (toExport.newTopic.pinned) {
|
||||
$('.pinCarousel').removeClass('isPinned')
|
||||
Create.newTopic.pinned = false
|
||||
toExport.newTopic.pinned = false
|
||||
} else {
|
||||
$('.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
|
||||
$('#topic_name').bind('typeahead:select', function(event, datum, dataset) {
|
||||
Create.newTopic.beingCreated = false
|
||||
toExport.newTopic.beingCreated = false
|
||||
if (datum.rtype === 'topic') {
|
||||
Topic.getTopicFromAutocomplete(datum.id)
|
||||
} else if (datum.rtype === 'map') {
|
||||
|
@ -259,7 +254,7 @@ const Create = {
|
|||
},
|
||||
name: null,
|
||||
newId: 1,
|
||||
beingCreated: false,
|
||||
beingtoExportd: false,
|
||||
metacode: null,
|
||||
x: null,
|
||||
y: null,
|
||||
|
@ -269,22 +264,22 @@ const Create = {
|
|||
$('#new_topic').fadeIn('fast', function() {
|
||||
$('#topic_name').focus()
|
||||
})
|
||||
Create.newTopic.beingCreated = true
|
||||
Create.newTopic.name = ''
|
||||
Map.setHasLearnedTopicCreation(true)
|
||||
toExport.newTopic.beingCreated = true
|
||||
toExport.newTopic.name = ''
|
||||
//Map.setHasLearnedTopicCreation(true)
|
||||
},
|
||||
hide: function(force) {
|
||||
if (force || !Create.newTopic.pinned) {
|
||||
if (force || !toExport.newTopic.pinned) {
|
||||
$('#new_topic').fadeOut('fast')
|
||||
}
|
||||
if (force) {
|
||||
$('.pinCarousel').removeClass('isPinned')
|
||||
Create.newTopic.pinned = false
|
||||
toExport.newTopic.pinned = false
|
||||
}
|
||||
if (DataModel.Topics.length === 0) {
|
||||
Map.setHasLearnedTopicCreation(false)
|
||||
}
|
||||
Create.newTopic.beingCreated = false
|
||||
toExport.newTopic.beingCreated = false
|
||||
},
|
||||
reset: function() {
|
||||
$('#topic_name').typeahead('val', '')
|
||||
|
@ -306,9 +301,8 @@ const Create = {
|
|||
remote: {
|
||||
url: '/search/synapses?topic1id=%TOPIC1&topic2id=%TOPIC2',
|
||||
prepare: function(query, settings) {
|
||||
var self = Create.newSynapse
|
||||
if (Selected.Nodes.length < 2 && self.topic1id && self.topic2id) {
|
||||
settings.url = settings.url.replace('%TOPIC1', self.topic1id).replace('%TOPIC2', self.topic2id)
|
||||
if (Selected.Nodes.length < 2 && toExport.newSynapse.topic1id && self.newSynapse.topic2id) {
|
||||
settings.url = settings.url.replace('%TOPIC1', toExport.newSynapse.topic1id).replace('%TOPIC2', toExport.newSynapse.topic2id)
|
||||
return settings
|
||||
} else {
|
||||
return null
|
||||
|
@ -351,21 +345,21 @@ const Create = {
|
|||
const ESC = 27
|
||||
|
||||
if (e.keyCode === ESC) {
|
||||
Create.newSynapse.hide()
|
||||
toExport.newSynapse.hide()
|
||||
} // if
|
||||
|
||||
Create.newSynapse.description = $(this).val()
|
||||
toExport.newSynapse.description = $(this).val()
|
||||
})
|
||||
|
||||
$('#synapse_desc').focusout(function() {
|
||||
if (Create.newSynapse.beingCreated) {
|
||||
if (toExport.newSynapse.beingCreated) {
|
||||
Synapse.createSynapseLocally()
|
||||
}
|
||||
})
|
||||
|
||||
$('#synapse_desc').keydown(function(e) {
|
||||
const TAB = 9
|
||||
if (Create.newSynapse.beingCreated && e.keyCode === TAB) {
|
||||
if (toExport.newSynapse.beingCreated && e.keyCode === TAB) {
|
||||
e.preventDefault()
|
||||
Synapse.createSynapseLocally()
|
||||
}
|
||||
|
@ -375,12 +369,12 @@ const Create = {
|
|||
if (datum.id) { // if they clicked on an existing synapse get it
|
||||
Synapse.getSynapseFromAutocomplete(datum.id)
|
||||
} else {
|
||||
Create.newSynapse.description = datum.value
|
||||
toExport.newSynapse.description = datum.value
|
||||
Synapse.createSynapseLocally()
|
||||
}
|
||||
})
|
||||
},
|
||||
beingCreated: false,
|
||||
beingtoExportd: false,
|
||||
description: null,
|
||||
topic1id: null,
|
||||
topic2id: null,
|
||||
|
@ -389,19 +383,21 @@ const Create = {
|
|||
$('#new_synapse').fadeIn(100, function() {
|
||||
$('#synapse_desc').focus()
|
||||
})
|
||||
Create.newSynapse.beingCreated = true
|
||||
toExport.newSynapse.beingCreated = true
|
||||
},
|
||||
hide: function() {
|
||||
$('#new_synapse').fadeOut('fast')
|
||||
$('#synapse_desc').typeahead('val', '')
|
||||
Create.newSynapse.beingCreated = false
|
||||
Create.newTopic.addSynapse = false
|
||||
Create.newSynapse.topic1id = 0
|
||||
Create.newSynapse.topic2id = 0
|
||||
toExport.newSynapse.beingCreated = false
|
||||
toExport.newTopic.addSynapse = false
|
||||
toExport.newSynapse.topic1id = 0
|
||||
toExport.newSynapse.topic2id = 0
|
||||
Mouse.synapseStartCoordinates = []
|
||||
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 MapCollection from './MapCollection'
|
||||
import Message from './Message'
|
||||
|
@ -17,57 +13,20 @@ import SynapseCollection from './SynapseCollection'
|
|||
import Mapping from './Mapping'
|
||||
import MappingCollection from './MappingCollection'
|
||||
|
||||
const DataModel = {
|
||||
Map: Map,
|
||||
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,
|
||||
|
||||
const DataModel = ({Filter, InfoBox}) => {
|
||||
const toExport = {
|
||||
Collaborators: new MapperCollection(),
|
||||
Creators: new MapperCollection(),
|
||||
Mappers: new MapperCollection(),
|
||||
Mappings: new MappingCollection(),
|
||||
Maps: {
|
||||
Mine: [],
|
||||
Shared: [],
|
||||
Starred: [],
|
||||
Mapper: {
|
||||
models: [],
|
||||
mapperId: null
|
||||
},
|
||||
Featured: [],
|
||||
Active: []
|
||||
},
|
||||
Messages: [],
|
||||
Metacodes: new MetacodeCollection(),
|
||||
Stars: [],
|
||||
Synapses: new SynapseCollection(),
|
||||
Topics: new TopicCollection(),
|
||||
|
||||
init: function(serverData) {
|
||||
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)
|
||||
|
||||
setMap: function(serverData) {
|
||||
var self = toExport
|
||||
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.Mappings) self.Mappings = new MappingCollection(serverData.Mappings)
|
||||
if (serverData.Messages) self.Messages = serverData.Messages
|
||||
|
@ -75,42 +34,28 @@ const DataModel = {
|
|||
if (serverData.Stars) self.Stars = serverData.Stars
|
||||
if (serverData.Synapses) self.Synapses = new SynapseCollection(serverData.Synapses)
|
||||
if (serverData.Topics) self.Topics = new TopicCollection(serverData.Topics)
|
||||
|
||||
// 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' })
|
||||
|
||||
self.attachCollectionEvents()
|
||||
},
|
||||
setTopic: function(serverData) {
|
||||
var self = toExport
|
||||
if (serverData.Creators) self.Creators = new MapperCollection(serverData.Creators)
|
||||
if (serverData.Metacodes) self.Metacodes = new MetacodeCollection(serverData.Metacodes)
|
||||
if (serverData.Synapses) self.Synapses = new SynapseCollection(serverData.Synapses)
|
||||
if (serverData.Topics) self.Topics = new TopicCollection(serverData.Topics)
|
||||
self.attachCollectionEvents()
|
||||
},
|
||||
attachCollectionEvents: function() {
|
||||
DataModel.Topics.on('add remove', function(topic) {
|
||||
toExport.Topics.on('add remove', function(topic) {
|
||||
InfoBox.updateNumbers()
|
||||
Filter.checkMetacodes()
|
||||
Filter.checkMappers()
|
||||
})
|
||||
DataModel.Synapses.on('add remove', function(synapse) {
|
||||
toExport.Synapses.on('add remove', function(synapse) {
|
||||
InfoBox.updateNumbers()
|
||||
Filter.checkSynapses()
|
||||
Filter.checkMappers()
|
||||
})
|
||||
DataModel.Mappings.on('add remove', function(mapping) {
|
||||
toExport.Mappings.on('add remove', function(mapping) {
|
||||
InfoBox.updateNumbers()
|
||||
Filter.checkSynapses()
|
||||
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
|
||||
// You can access them by importing DataModel
|
||||
|
||||
|
|
|
@ -2,14 +2,11 @@
|
|||
|
||||
import _ from 'lodash'
|
||||
|
||||
import Active from './Active'
|
||||
import Control from './Control'
|
||||
import DataModel from './DataModel'
|
||||
import GlobalUI, { ReactApp } from './GlobalUI'
|
||||
import Settings from './Settings'
|
||||
import Visualize from './Visualize'
|
||||
|
||||
const Filter = {
|
||||
const Filter = ({Active, Control, DataModel, Visualize}) => {
|
||||
const toExport = {
|
||||
dataForPresentation: {
|
||||
metacodes: {},
|
||||
mappers: {},
|
||||
|
@ -26,7 +23,7 @@ const Filter = {
|
|||
synapses: []
|
||||
},
|
||||
reset: function() {
|
||||
var self = Filter
|
||||
var self = toExport
|
||||
self.filters.metacodes = []
|
||||
self.filters.mappers = []
|
||||
self.filters.synapses = []
|
||||
|
@ -41,7 +38,7 @@ const Filter = {
|
|||
// an abstraction function for checkMetacodes, checkMappers, checkSynapses to reduce
|
||||
// code redundancy
|
||||
updateFilters: function(collection, propertyToCheck, correlatedModel, filtersToUse, listToModify) {
|
||||
var self = Filter
|
||||
var self = toExport
|
||||
var newList = []
|
||||
var removed = []
|
||||
var added = []
|
||||
|
@ -97,11 +94,11 @@ const Filter = {
|
|||
ReactApp.render()
|
||||
},
|
||||
checkMetacodes: function() {
|
||||
var self = Filter
|
||||
var self = toExport
|
||||
self.updateFilters('Topics', 'metacode_id', 'Metacodes', 'metacodes', 'metacode')
|
||||
},
|
||||
checkMappers: function() {
|
||||
var self = Filter
|
||||
var self = toExport
|
||||
if (Active.Map) {
|
||||
self.updateFilters('Mappings', 'user_id', 'Mappers', 'mappers', 'mapper')
|
||||
} else {
|
||||
|
@ -110,23 +107,23 @@ const Filter = {
|
|||
}
|
||||
},
|
||||
checkSynapses: function() {
|
||||
var self = Filter
|
||||
var self = toExport
|
||||
self.updateFilters('Synapses', 'desc', 'Synapses', 'synapses', 'synapse')
|
||||
},
|
||||
filterAllMetacodes: function(toVisible) {
|
||||
var self = Filter
|
||||
var self = toExport
|
||||
self.visible.metacodes = toVisible ? self.filters.metacodes.slice() : []
|
||||
ReactApp.render()
|
||||
self.passFilters()
|
||||
},
|
||||
filterAllMappers: function(toVisible) {
|
||||
var self = Filter
|
||||
var self = toExport
|
||||
self.visible.mappers = toVisible ? self.filters.mappers.slice() : []
|
||||
ReactApp.render()
|
||||
self.passFilters()
|
||||
},
|
||||
filterAllSynapses: function(toVisible) {
|
||||
var self = Filter
|
||||
var self = toExport
|
||||
self.visible.synapses = toVisible ? self.filters.synapses.slice() : []
|
||||
ReactApp.render()
|
||||
self.passFilters()
|
||||
|
@ -135,7 +132,7 @@ const Filter = {
|
|||
// to reduce code redundancy
|
||||
// gets called in the context of a list item in a filter box
|
||||
toggleLi: function(whichToFilter, id) {
|
||||
var self = Filter
|
||||
var self = toExport
|
||||
if (self.visible[whichToFilter].indexOf(id) === -1) {
|
||||
self.visible[whichToFilter].push(id)
|
||||
} else {
|
||||
|
@ -146,19 +143,19 @@ const Filter = {
|
|||
self.passFilters()
|
||||
},
|
||||
toggleMetacode: function(id) {
|
||||
var self = Filter
|
||||
var self = toExport
|
||||
self.toggleLi('metacodes', id)
|
||||
},
|
||||
toggleMapper: function(id) {
|
||||
var self = Filter
|
||||
var self = toExport
|
||||
self.toggleLi('mappers', id)
|
||||
},
|
||||
toggleSynapse: function(id) {
|
||||
var self = Filter
|
||||
var self = toExport
|
||||
self.toggleLi('synapses', id)
|
||||
},
|
||||
passFilters: function() {
|
||||
var self = Filter
|
||||
var self = toExport
|
||||
var visible = self.visible
|
||||
|
||||
var passesMetacode, passesMapper, passesSynapse
|
||||
|
@ -276,5 +273,7 @@ const Filter = {
|
|||
})
|
||||
}
|
||||
}
|
||||
return toExport
|
||||
}
|
||||
|
||||
export default Filter
|
||||
|
|
|
@ -7,13 +7,12 @@ import { merge } from 'lodash'
|
|||
|
||||
import { notifyUser } from './index.js'
|
||||
import ImportDialog from './ImportDialog'
|
||||
import Active from '../Active'
|
||||
import DataModel from '../DataModel'
|
||||
import Mapper from '../DataModel/Mapper'
|
||||
import { ExploreMaps, ChatView, TopicCard } from '../Views'
|
||||
import Filter from '../Filter'
|
||||
import JIT from '../JIT'
|
||||
import Realtime from '../Realtime'
|
||||
import Map, { InfoBox } from '../Map'
|
||||
import Map, { mapControl } from '../Map'
|
||||
import Topic from '../Topic'
|
||||
import Visualize from '../Visualize'
|
||||
import makeRoutes from '../../components/makeRoutes'
|
||||
|
@ -27,8 +26,11 @@ const MAX_COLUMNS = 4
|
|||
|
||||
const ReactApp = {
|
||||
serverData: {},
|
||||
currentUser: null,
|
||||
mapId: null,
|
||||
openMap: null,
|
||||
topicId: null,
|
||||
openTopic: null,
|
||||
unreadNotificationsCount: 0,
|
||||
mapsWidth: 0,
|
||||
toast: '',
|
||||
|
@ -36,9 +38,11 @@ const ReactApp = {
|
|||
mobileTitle: '',
|
||||
mobileTitleWidth: 0,
|
||||
metacodeSets: [],
|
||||
juntoState: { connectedPeople: {}, liveMaps: {} },
|
||||
init: function(serverData, openLightbox) {
|
||||
const self = ReactApp
|
||||
self.serverData = serverData
|
||||
self.currentUser = new Mapper(serverData.ActiveMapper)
|
||||
self.unreadNotificationsCount = serverData.unreadNotificationsCount
|
||||
self.mobileTitle = serverData.mobileTitle
|
||||
self.openLightbox = openLightbox
|
||||
|
@ -52,12 +56,13 @@ const ReactApp = {
|
|||
const pathname = this.state.location.pathname
|
||||
switch (pathname.split('/')[1]) {
|
||||
case '':
|
||||
if (Active.Mapper && Active.Mapper.id) {
|
||||
if (self.currentUser && self.currentUser.id) {
|
||||
$('#yield').hide()
|
||||
ExploreMaps.updateFromPath(pathname)
|
||||
self.mapId = null
|
||||
Active.Map = null
|
||||
Active.Topic = null
|
||||
self.topicId = null
|
||||
self.openMap = null
|
||||
self.openTopic = null
|
||||
}
|
||||
break
|
||||
case 'explore':
|
||||
|
@ -65,19 +70,19 @@ const ReactApp = {
|
|||
ExploreMaps.updateFromPath(pathname)
|
||||
self.mapId = null
|
||||
self.topicId = null
|
||||
Active.Map = null
|
||||
Active.Topic = null
|
||||
self.openMap = null
|
||||
self.openTopic = null
|
||||
break
|
||||
case 'topics':
|
||||
$('#yield').hide()
|
||||
Active.Map = null
|
||||
self.openMap = null
|
||||
self.mapId = null
|
||||
self.topicId = pathname.split('/')[2]
|
||||
break
|
||||
case 'maps':
|
||||
if (!pathname.includes('request_access')) {
|
||||
$('#yield').hide()
|
||||
Active.Topic = null
|
||||
self.openTopic = null
|
||||
self.topicId = null
|
||||
self.mapId = pathname.split('/')[2]
|
||||
}
|
||||
|
@ -99,14 +104,18 @@ const ReactApp = {
|
|||
const self = ReactApp
|
||||
return merge({
|
||||
unreadNotificationsCount: self.unreadNotificationsCount,
|
||||
currentUser: Active.Mapper,
|
||||
currentUser: self.currentUser,
|
||||
toast: self.toast,
|
||||
mobile: self.mobile,
|
||||
mobileTitle: self.mobileTitle,
|
||||
mobileTitleWidth: self.mobileTitleWidth,
|
||||
mobileTitleClick: (e) => Active.Map && InfoBox.toggleBox(e),
|
||||
mobileTitleClick: (e) => self.openMap && self.openMap.InfoBox.toggleBox(e),
|
||||
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.getTopicProps(),
|
||||
|
@ -118,27 +127,27 @@ const ReactApp = {
|
|||
},
|
||||
getMapProps: function() {
|
||||
const self = ReactApp
|
||||
if (!self.openMap) return {}
|
||||
return {
|
||||
mapId: self.mapId,
|
||||
map: Active.Map,
|
||||
hasLearnedTopicCreation: Map.hasLearnedTopicCreation,
|
||||
userRequested: Map.userRequested,
|
||||
requestAnswered: Map.requestAnswered,
|
||||
requestApproved: Map.requestApproved,
|
||||
onRequestAccess: Map.requestAccess,
|
||||
mapIsStarred: Map.mapIsStarred,
|
||||
endActiveMap: Map.end,
|
||||
launchNewMap: Map.launch,
|
||||
toggleMapInfoBox: InfoBox.toggleBox,
|
||||
infoBoxHtml: InfoBox.html,
|
||||
map: self.openMap.Active.Map,
|
||||
hasLearnedTopicCreation: self.openMap.Map.hasLearnedTopicCreation,
|
||||
userRequested: self.openMap.Map.userRequested,
|
||||
requestAnswered: self.openMap.Map.requestAnswered,
|
||||
requestApproved: self.openMap.Map.requestApproved,
|
||||
onRequestAccess: self.openMap.Map.requestAccess,
|
||||
mapIsStarred: self.openMap.Map.mapIsStarred,
|
||||
toggleMapInfoBox: self.openMap.InfoBox.toggleBox,
|
||||
infoBoxHtml: self.openMap.InfoBox.html,
|
||||
openImportLightbox: () => ImportDialog.show(),
|
||||
forkMap: Map.fork,
|
||||
onMapStar: Map.star,
|
||||
onMapUnstar: Map.unstar
|
||||
forkMap: self.openMap.Map.fork,
|
||||
onMapStar: self.openMap.Map.star,
|
||||
onMapUnstar: self.openMap.Map.unstar
|
||||
}
|
||||
},
|
||||
getCommonProps: function() {
|
||||
const self = ReactApp
|
||||
if (!(self.openMap || self.openTopic)) return {}
|
||||
const { JIT, Visualize } = self.openMap || self.openTopic
|
||||
return {
|
||||
openHelpLightbox: () => self.openLightbox('cheatsheet'),
|
||||
onZoomExtents: event => JIT.zoomExtents(event, Visualize.mGraph.canvas),
|
||||
|
@ -148,20 +157,22 @@ const ReactApp = {
|
|||
},
|
||||
getTopicCardProps: function() {
|
||||
const self = ReactApp
|
||||
if (!(self.openMap || self.openTopic)) return {}
|
||||
const { TopicCard } = self.openMap || self.openTopic
|
||||
return {
|
||||
openTopic: TopicCard.openTopic,
|
||||
metacodeSets: self.metacodeSets,
|
||||
updateTopic: (topic, obj) => topic.save(obj),
|
||||
onTopicFollow: Topic.onTopicFollow
|
||||
onTopicFollow: Topic.onTopicFollow // todo
|
||||
}
|
||||
},
|
||||
getTopicProps: function() {
|
||||
const self = ReactApp
|
||||
if (!self.openTopic) return {}
|
||||
return {
|
||||
topicId: self.topicId,
|
||||
topic: Active.Topic,
|
||||
endActiveTopic: Topic.end,
|
||||
launchNewTopic: Topic.launch
|
||||
topic: self.openTopic.Active.Topic,
|
||||
endActiveTopic: Topic.end, // todo
|
||||
launchNewTopic: Topic.launch // todo
|
||||
}
|
||||
},
|
||||
getMapsProps: function() {
|
||||
|
@ -169,7 +180,7 @@ const ReactApp = {
|
|||
return {
|
||||
section: ExploreMaps.collection && ExploreMaps.collection.id,
|
||||
maps: ExploreMaps.collection,
|
||||
juntoState: Realtime.juntoState,
|
||||
juntoState: self.juntoState,
|
||||
moreToLoad: ExploreMaps.collection && ExploreMaps.collection.page !== 'loadedAll',
|
||||
user: ExploreMaps.collection && ExploreMaps.collection.id === 'mapper' ? ExploreMaps.mapper : null,
|
||||
loadMore: ExploreMaps.loadMore,
|
||||
|
@ -182,6 +193,11 @@ const ReactApp = {
|
|||
},
|
||||
getChatProps: function() {
|
||||
const self = ReactApp
|
||||
if (!self.openMap) return {
|
||||
participants: [],
|
||||
messages: []
|
||||
}
|
||||
const { ChatView, Realtime } = self.openMap
|
||||
return {
|
||||
unreadMessages: ChatView.unreadMessages,
|
||||
conversationLive: ChatView.conversationLive,
|
||||
|
@ -204,6 +220,8 @@ const ReactApp = {
|
|||
},
|
||||
getFilterProps: function() {
|
||||
const self = ReactApp
|
||||
if (!self.openMap) return {}
|
||||
const { Filter } = self.openMap
|
||||
return {
|
||||
filterData: Filter.dataForPresentation,
|
||||
allForFiltering: Filter.filters,
|
||||
|
@ -219,7 +237,7 @@ const ReactApp = {
|
|||
resize: function() {
|
||||
const self = ReactApp
|
||||
const maps = ExploreMaps.collection
|
||||
const currentUser = Active.Mapper
|
||||
const currentUser = self.currentUser
|
||||
const user = maps && maps.id === 'mapper' ? ExploreMaps.mapper : null
|
||||
const numCards = (maps ? maps.length : 0) + (user || currentUser ? 1 : 0)
|
||||
const mapSpaces = Math.floor(document.body.clientWidth / MAP_WIDTH)
|
||||
|
|
|
@ -3,15 +3,10 @@
|
|||
import parse from 'csv-parse'
|
||||
import _ from 'lodash'
|
||||
|
||||
import Active from './Active'
|
||||
import AutoLayout from './AutoLayout'
|
||||
import DataModel from './DataModel'
|
||||
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
|
||||
topicWhitelist: [
|
||||
'id', 'name', 'metacode', 'x', 'y', 'description', 'link', 'permission'
|
||||
|
@ -22,12 +17,12 @@ const Import = {
|
|||
cidMappings: {}, // to be filled by importId => cid mappings
|
||||
|
||||
handleTSV: function(text) {
|
||||
const results = Import.parseTabbedString(text)
|
||||
Import.handle(results)
|
||||
const results = toExport.parseTabbedString(text)
|
||||
toExport.handle(results)
|
||||
},
|
||||
|
||||
handleCSV: function(text, parserOpts = {}) {
|
||||
const self = Import
|
||||
const self = toExport
|
||||
|
||||
const topicsRegex = /("?Topics"?[, \t"]*)([\s\S]*)/mi
|
||||
const synapsesRegex = /("?Synapses"?[, \t"]*)([\s\S]*)/mi
|
||||
|
@ -68,11 +63,11 @@ const Import = {
|
|||
|
||||
handleJSON: function(text) {
|
||||
const results = JSON.parse(text)
|
||||
Import.handle(results)
|
||||
toExport.handle(results)
|
||||
},
|
||||
|
||||
handle: function(results) {
|
||||
var self = Import
|
||||
var self = toExport
|
||||
var topics = results.topics.map(topic => self.normalizeKeys(topic))
|
||||
var synapses = results.synapses.map(synapse => self.normalizeKeys(synapse))
|
||||
|
||||
|
@ -87,7 +82,7 @@ const Import = {
|
|||
},
|
||||
|
||||
parseTabbedString: function(text) {
|
||||
var self = Import
|
||||
var self = toExport
|
||||
|
||||
// determine line ending and split lines
|
||||
var delim = '\n'
|
||||
|
@ -213,7 +208,7 @@ const Import = {
|
|||
},
|
||||
|
||||
importTopics: function(parsedTopics) {
|
||||
var self = Import
|
||||
var self = toExport
|
||||
|
||||
parsedTopics.forEach(topic => {
|
||||
let coords = { x: topic.x, y: topic.y }
|
||||
|
@ -240,7 +235,7 @@ const Import = {
|
|||
},
|
||||
|
||||
importSynapses: function(parsedSynapses) {
|
||||
var self = Import
|
||||
var self = toExport
|
||||
|
||||
parsedSynapses.forEach(function(synapse) {
|
||||
// only createSynapseWithParameters once both topics are persisted
|
||||
|
@ -279,7 +274,7 @@ const Import = {
|
|||
|
||||
createTopicWithParameters: function(name, metacodeName, permission, desc,
|
||||
link, xloc, yloc, importId, opts = {}) {
|
||||
var self = Import
|
||||
var self = toExport
|
||||
$(document).trigger(Map.events.editedByActiveMapper)
|
||||
var metacode = DataModel.Metacodes.where({name: metacodeName})[0] || null
|
||||
if (metacode === null) {
|
||||
|
@ -359,7 +354,7 @@ const Import = {
|
|||
const permission = opts.permission || null // use default
|
||||
const desc = opts.desc || url
|
||||
|
||||
Import.createTopicWithParameters(
|
||||
toExport.createTopicWithParameters(
|
||||
name,
|
||||
metacode,
|
||||
permission,
|
||||
|
@ -423,5 +418,7 @@ const Import = {
|
|||
})
|
||||
}
|
||||
}
|
||||
return toExport
|
||||
}
|
||||
|
||||
export default Import
|
||||
|
|
|
@ -35,17 +35,6 @@ return {
|
|||
animationDone: 'Metamaps:JIT:events:animationDone'
|
||||
},
|
||||
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
|
||||
*/
|
||||
|
@ -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
|
||||
|
|
|
@ -5,9 +5,9 @@ import { Search } from './GlobalUI'
|
|||
|
||||
const Listeners = ({ Active, Create, Control, DataModel, JIT, Realtime, Selected, Topic, Visualize }) => {
|
||||
return {
|
||||
init: function() {
|
||||
activate: function() {
|
||||
var self = this
|
||||
$(document).on('keydown', function(e) {
|
||||
$(document).on('keydown.map', function(e) {
|
||||
if (!(Active.Map || Active.Topic)) return
|
||||
|
||||
const onCanvas = e.target.tagName === 'BODY'
|
||||
|
@ -131,7 +131,7 @@ return {
|
|||
break
|
||||
}
|
||||
})
|
||||
$(window).resize(function() {
|
||||
$(window).on('resize.map', function() {
|
||||
if (Visualize && Visualize.mGraph) {
|
||||
Util.resizeCanvas(Visualize.mGraph.canvas)
|
||||
}
|
||||
|
|
|
@ -3,12 +3,11 @@
|
|||
import outdent from 'outdent'
|
||||
import { browserHistory } from 'react-router'
|
||||
|
||||
import Active from '../Active'
|
||||
import DataModel from '../DataModel'
|
||||
import GlobalUI, { ReactApp } from '../GlobalUI'
|
||||
import Util from '../Util'
|
||||
|
||||
const InfoBox = {
|
||||
const InfoBox = ({Active, DataModel}) => {
|
||||
const toExport = {
|
||||
isOpen: 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>",
|
||||
|
@ -36,32 +35,32 @@ const InfoBox = {
|
|||
userImageUrl: '',
|
||||
html: '',
|
||||
init: function(serverData, updateThumbnail) {
|
||||
var self = InfoBox
|
||||
var self = toExport
|
||||
|
||||
self.updateThumbnail = updateThumbnail
|
||||
|
||||
$('.mapInfoBox').click(function(event) {
|
||||
$('.maptoExport').click(function(event) {
|
||||
event.stopPropagation()
|
||||
})
|
||||
$('body').click(self.close)
|
||||
|
||||
self.attachEventListeners()
|
||||
|
||||
self.generateBoxHTML = Hogan.compile($('#mapInfoBoxTemplate').html())
|
||||
self.generateBoxHTML = Hogan.compile($('#maptoExportTemplate').html())
|
||||
|
||||
self.userImageUrl = serverData['user.png']
|
||||
|
||||
var querystring = window.location.search.replace(/^\?/, '')
|
||||
if (querystring === 'new') {
|
||||
self.open()
|
||||
$('.mapInfoBox').addClass('mapRequestTitle')
|
||||
$('.maptoExport').addClass('mapRequestTitle')
|
||||
$('#mapInfoName').trigger('click')
|
||||
$('#mapInfoName textarea').focus()
|
||||
$('#mapInfoName textarea').select()
|
||||
}
|
||||
},
|
||||
toggleBox: function(event) {
|
||||
var self = InfoBox
|
||||
var self = toExport
|
||||
|
||||
if (self.isOpen) self.close()
|
||||
else self.open()
|
||||
|
@ -69,23 +68,23 @@ const InfoBox = {
|
|||
event.stopPropagation()
|
||||
},
|
||||
open: function() {
|
||||
var self = InfoBox
|
||||
var self = toExport
|
||||
$('.mapInfoIcon div').addClass('hide')
|
||||
$('.mapInfoBox').fadeIn(200, function() {
|
||||
$('.maptoExport').fadeIn(200, function() {
|
||||
self.isOpen = true
|
||||
})
|
||||
},
|
||||
close: function() {
|
||||
var self = InfoBox
|
||||
var self = toExport
|
||||
$('.mapInfoIcon div').removeClass('hide')
|
||||
$('.mapInfoBox').fadeOut(200, function() {
|
||||
$('.maptoExport').fadeOut(200, function() {
|
||||
self.isOpen = false
|
||||
self.hidePermissionSelect()
|
||||
$('.mapContributors .tip').hide()
|
||||
})
|
||||
},
|
||||
load: function() {
|
||||
var self = InfoBox
|
||||
var self = toExport
|
||||
|
||||
var map = Active.Map
|
||||
|
||||
|
@ -115,12 +114,12 @@ const InfoBox = {
|
|||
self.attachEventListeners()
|
||||
},
|
||||
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
|
||||
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() {
|
||||
var $el = bipName.find('textarea')
|
||||
var el = $el[0]
|
||||
|
@ -144,7 +143,7 @@ const InfoBox = {
|
|||
Active.Map.trigger('saved')
|
||||
// mobile menu
|
||||
$('#header_content').html(name)
|
||||
$('.mapInfoBox').removeClass('mapRequestTitle')
|
||||
$('.maptoExport').removeClass('mapRequestTitle')
|
||||
document.title = `${name} | Metamaps`
|
||||
window.history.replaceState('', `${name} | Metamaps`, window.location.pathname)
|
||||
})
|
||||
|
@ -164,8 +163,8 @@ const InfoBox = {
|
|||
|
||||
$('.yourMap .mapPermission').unbind().click(self.onPermissionClick)
|
||||
// .yourMap in the unbind/bind is just a namespace for the events
|
||||
// not a reference to the class .yourMap on the .mapInfoBox
|
||||
$('.mapInfoBox.yourMap').unbind('.yourMap').bind('click.yourMap', self.hidePermissionSelect)
|
||||
// not a reference to the class .yourMap on the .maptoExport
|
||||
$('.maptoExport.yourMap').unbind('.yourMap').bind('click.yourMap', self.hidePermissionSelect)
|
||||
|
||||
$('.yourMap .mapInfoDelete').unbind().click(self.deleteActiveMap)
|
||||
$('.mapInfoThumbnail').unbind().click(self.updateThumbnail)
|
||||
|
@ -178,14 +177,14 @@ const InfoBox = {
|
|||
event.stopPropagation()
|
||||
})
|
||||
|
||||
$('.mapInfoBox').unbind('.hideTip').bind('click.hideTip', function() {
|
||||
$('.maptoExport').unbind('.hideTip').bind('click.hideTip', function() {
|
||||
$('.mapContributors .tip').hide()
|
||||
})
|
||||
|
||||
self.addTypeahead()
|
||||
},
|
||||
addTypeahead: function() {
|
||||
var self = InfoBox
|
||||
var self = toExport
|
||||
|
||||
if (!Active.Map) return
|
||||
|
||||
|
@ -232,14 +231,14 @@ const InfoBox = {
|
|||
}
|
||||
},
|
||||
removeCollaborator: function(collaboratorId) {
|
||||
var self = InfoBox
|
||||
var self = toExport
|
||||
DataModel.Collaborators.remove(DataModel.Collaborators.get(collaboratorId))
|
||||
var mapperIds = DataModel.Collaborators.models.map(function(mapper) { return mapper.id })
|
||||
$.post('/maps/' + Active.Map.id + '/access', { access: mapperIds })
|
||||
self.updateNumbers()
|
||||
},
|
||||
addCollaborator: function(newCollaboratorId) {
|
||||
var self = InfoBox
|
||||
var self = toExport
|
||||
|
||||
if (DataModel.Collaborators.get(newCollaboratorId)) {
|
||||
GlobalUI.notifyUser('That user already has access')
|
||||
|
@ -258,16 +257,16 @@ const InfoBox = {
|
|||
$.getJSON('/users/' + newCollaboratorId + '.json', callback)
|
||||
},
|
||||
handleResultClick: function(event, item) {
|
||||
var self = InfoBox
|
||||
var self = toExport
|
||||
|
||||
self.addCollaborator(item.id)
|
||||
$('.collaboratorSearchField').typeahead('val', '')
|
||||
},
|
||||
updateNameDescPerm: function(name, desc, perm) {
|
||||
$('.mapInfoBox').removeClass('mapRequestTitle')
|
||||
$('.maptoExport').removeClass('mapRequestTitle')
|
||||
$('.mapInfoName .best_in_place_name').html(name)
|
||||
$('.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() {
|
||||
var relevantPeople = Active.Map.get('permission') === 'commons' ? DataModel.Mappers : DataModel.Collaborators
|
||||
|
@ -294,7 +293,7 @@ const InfoBox = {
|
|||
updateNumbers: function() {
|
||||
if (!Active.Map) return
|
||||
|
||||
const self = InfoBox
|
||||
const self = toExport
|
||||
|
||||
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())
|
||||
},
|
||||
onPermissionClick: function(event) {
|
||||
var self = InfoBox
|
||||
var self = toExport
|
||||
|
||||
if (!self.selectingPermission) {
|
||||
self.selectingPermission = true
|
||||
|
@ -340,14 +339,14 @@ const InfoBox = {
|
|||
}
|
||||
},
|
||||
hidePermissionSelect: function() {
|
||||
var self = InfoBox
|
||||
var self = toExport
|
||||
|
||||
self.selectingPermission = false
|
||||
$('.mapPermission').removeClass('minimize') // this line flips the pull up arrow to a drop down arrow
|
||||
$('.mapPermission .permissionSelect').remove()
|
||||
},
|
||||
selectPermission: function(event) {
|
||||
var self = InfoBox
|
||||
var self = toExport
|
||||
|
||||
self.selectingPermission = false
|
||||
var permission = $(this).attr('class')
|
||||
|
@ -358,7 +357,7 @@ const InfoBox = {
|
|||
const shareable = permission === 'private' ? '' : 'shareable'
|
||||
$('.mapPermission').removeClass('commons public private minimize').addClass(permission)
|
||||
$('.mapPermission .permissionSelect').remove()
|
||||
$('.mapInfoBox').removeClass('shareable').addClass(shareable)
|
||||
$('.maptoExport').removeClass('shareable').addClass(shareable)
|
||||
event.stopPropagation()
|
||||
},
|
||||
deleteActiveMap: function() {
|
||||
|
@ -371,7 +370,7 @@ const InfoBox = {
|
|||
var authorized = map.authorizePermissionChange(mapper)
|
||||
|
||||
if (doIt && authorized) {
|
||||
InfoBox.close()
|
||||
toExport.close()
|
||||
DataModel.Maps.Active.remove(map)
|
||||
DataModel.Maps.Featured.remove(map)
|
||||
DataModel.Maps.Mine.remove(map)
|
||||
|
@ -384,5 +383,7 @@ const InfoBox = {
|
|||
}
|
||||
}
|
||||
}
|
||||
return toExport
|
||||
}
|
||||
|
||||
export default InfoBox
|
||||
|
|
|
@ -6,414 +6,442 @@ import { browserHistory } from 'react-router'
|
|||
|
||||
import Active from '../Active'
|
||||
import AutoLayout from '../AutoLayout'
|
||||
import Cable from '../Cable'
|
||||
import Control from '../Control'
|
||||
import Create from '../Create'
|
||||
import DataModel from '../DataModel'
|
||||
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 GlobalUI, { ReactApp } from '../GlobalUI'
|
||||
import Import from '../Import'
|
||||
import InfoBox from './InfoBox'
|
||||
import JIT from '../JIT'
|
||||
import Listeners from '../Listeners'
|
||||
import Loading from '../Loading'
|
||||
import Mouse from '../Mouse'
|
||||
import Organize from '../Organize'
|
||||
import PasteInput from '../PasteInput'
|
||||
import Realtime from '../Realtime'
|
||||
import Selected from '../Selected'
|
||||
import Synapse from '../Synapse'
|
||||
import SynapseCard from '../SynapseCard'
|
||||
import Topic from '../Topic'
|
||||
import TopicCard from '../Views/TopicCard'
|
||||
import ChatView from '../Views/ChatView'
|
||||
import Visualize from '../Visualize'
|
||||
|
||||
import CheatSheet from './CheatSheet'
|
||||
import InfoBox from './InfoBox'
|
||||
|
||||
const Map = {
|
||||
events: {
|
||||
editedByActiveMapper: 'Metamaps:Map:events:editedByActiveMapper'
|
||||
},
|
||||
mapIsStarred: false,
|
||||
requests: [],
|
||||
userRequested: false,
|
||||
requestAnswered: false,
|
||||
requestApproved: false,
|
||||
hasLearnedTopicCreation: true,
|
||||
init: function(serverData) {
|
||||
var self = Map
|
||||
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 = 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
|
||||
const mapControl = {
|
||||
launch: function(id, serverData) {
|
||||
var dataIsReadySetupMap = function(data) {
|
||||
const newMap = {
|
||||
Active: null,
|
||||
AutoLayout: null,
|
||||
Cable: null,
|
||||
ChatView: null,
|
||||
Control: null,
|
||||
Create: null,
|
||||
DataModel: null,
|
||||
Filter: null,
|
||||
Import: null,
|
||||
JIT: null,
|
||||
Listeners: null,
|
||||
Mouse: null,
|
||||
Organize: null,
|
||||
PasteInput: null,
|
||||
Realtime: null,
|
||||
Selected: null,
|
||||
Synapse: null,
|
||||
SynapseCard: null,
|
||||
Topic: null,
|
||||
TopicCard: null,
|
||||
Visualize: null
|
||||
}
|
||||
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()
|
||||
},
|
||||
launch: function(id) {
|
||||
const self = Map
|
||||
|
||||
const 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() {
|
||||
Map.setAccessRequest()
|
||||
Visualize.type = 'ForceDirected'
|
||||
newMap.Active = Active()
|
||||
newMap.AutoLayout = AutoLayout(newMap)
|
||||
newMap.Cable = Cable(newMap)
|
||||
newMap.ChatView = ChatView(newMap)
|
||||
newMap.Control = Control(newMap)
|
||||
newMap.Create = Create(newMap)
|
||||
newMap.DataModel = DataModel(newMap)
|
||||
newMap.Filter = Filter(newMap)
|
||||
newMap.Import = Import(newMap)
|
||||
newMap.InfoBox = InfoBox(newMap)
|
||||
newMap.JIT = JIT(newMap)
|
||||
newMap.Listeners = Listeners(newMap)
|
||||
newMap.Map = Map(newMap)
|
||||
newMap.Mouse = Mouse(newMap)
|
||||
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)
|
||||
|
||||
console.log(newMap)
|
||||
|
||||
newMap.Active.Map = new DataModelMap(data.map)
|
||||
newMap.DataModel.Mappers = new MapperCollection(data.mappers)
|
||||
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()
|
||||
Selected.reset()
|
||||
InfoBox.load()
|
||||
Filter.reset()
|
||||
Filter.checkMetacodes()
|
||||
Filter.checkSynapses()
|
||||
Filter.checkMappers()
|
||||
Realtime.startActiveMap()
|
||||
newMap.InfoBox.load()
|
||||
newMap.Filter.checkMetacodes()
|
||||
newMap.Filter.checkSynapses()
|
||||
newMap.Filter.checkMappers()
|
||||
newMap.Realtime.startActiveMap()
|
||||
Loading.hide()
|
||||
document.title = Active.Map.get('name') + ' | Metamaps'
|
||||
ReactApp.mobileTitle = Active.Map.get('name')
|
||||
document.title = newMap.Active.Map.get('name') + ' | Metamaps'
|
||||
ReactApp.openMap = newMap
|
||||
ReactApp.mobileTitle = newMap.Active.Map.get('name')
|
||||
ReactApp.render()
|
||||
}
|
||||
function isLoaded() {
|
||||
if (InfoBox.generateBoxHTML) dataIsReadySetupMap()
|
||||
else setTimeout(() => isLoaded(), 50)
|
||||
}
|
||||
if (Active.Map && Active.Map.id === id) {
|
||||
isLoaded()
|
||||
if (false) {
|
||||
// do something with serverData here
|
||||
dataIsReadySetupMap()
|
||||
}
|
||||
else {
|
||||
Loading.show()
|
||||
$.ajax({
|
||||
url: '/maps/' + id + '/contains.json',
|
||||
success: function(data) {
|
||||
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()
|
||||
}
|
||||
success: dataIsReadySetupMap
|
||||
})
|
||||
}
|
||||
},
|
||||
end: function() {
|
||||
if (Active.Map) {
|
||||
$('.main').removeClass('compressed')
|
||||
AutoLayout.resetSpiral()
|
||||
$('.rightclickmenu').remove()
|
||||
TopicCard.hideCard()
|
||||
SynapseCard.hideCard()
|
||||
Create.newTopic.hide(true) // true means force (and override pinned)
|
||||
Create.newSynapse.hide()
|
||||
InfoBox.close()
|
||||
Realtime.endActiveMap()
|
||||
self.requests = []
|
||||
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
|
||||
end: function(map) {
|
||||
$('.main').removeClass('compressed')
|
||||
$('.rightclickmenu').remove()
|
||||
map.AutoLayout.resetSpiral()
|
||||
map.TopicCard.hideCard()
|
||||
map.SynapseCard.hideCard()
|
||||
map.Create.newTopic.hide(true) // true means force (and override pinned)
|
||||
map.Create.newSynapse.hide()
|
||||
map.InfoBox.close()
|
||||
map.Realtime.endActiveMap()
|
||||
map.Map.requests = []
|
||||
map.Map.hasLearnedTopicCreation = true
|
||||
}
|
||||
}
|
||||
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
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
const Mouse = {
|
||||
didPan: false,
|
||||
didBoxZoom: false,
|
||||
changeInX: 0,
|
||||
changeInY: 0,
|
||||
edgeHoveringOver: false,
|
||||
boxStartCoordinates: false,
|
||||
boxEndCoordinates: false,
|
||||
synapseStartCoordinates: [],
|
||||
synapseEndCoordinates: null,
|
||||
lastNodeClick: 0,
|
||||
lastCanvasClick: 0,
|
||||
DOUBLE_CLICK_TOLERANCE: 300
|
||||
const Mouse = () => {
|
||||
return {
|
||||
didPan: false,
|
||||
didBoxZoom: false,
|
||||
changeInX: 0,
|
||||
changeInY: 0,
|
||||
edgeHoveringOver: false,
|
||||
boxStartCoordinates: false,
|
||||
boxEndCoordinates: false,
|
||||
synapseStartCoordinates: [],
|
||||
synapseEndCoordinates: null,
|
||||
lastNodeClick: 0,
|
||||
lastCanvasClick: 0,
|
||||
DOUBLE_CLICK_TOLERANCE: 300
|
||||
}
|
||||
}
|
||||
|
||||
export default Mouse
|
||||
|
|
|
@ -2,10 +2,8 @@ import _ from 'lodash'
|
|||
|
||||
import $jit from '../patched/JIT'
|
||||
|
||||
import Visualize from './Visualize'
|
||||
import JIT from './JIT'
|
||||
|
||||
const Organize = {
|
||||
const Organize = ({Visualize, JIT}) => {
|
||||
const toExport = {
|
||||
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
|
||||
if (layout === 'grid') {
|
||||
|
@ -112,5 +110,7 @@ const Organize = {
|
|||
}
|
||||
}
|
||||
}
|
||||
return toExport
|
||||
}
|
||||
|
||||
export default Organize
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
/* global $ */
|
||||
|
||||
import Import from './Import'
|
||||
import Util from './Util'
|
||||
import Visualize from './Visualize'
|
||||
|
||||
const PasteInput = {
|
||||
const PasteInput = ({Import, Visualize}) => {
|
||||
const toReturn = {
|
||||
// thanks to https://github.com/kevva/url-regex
|
||||
// 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"]*)?$'),
|
||||
|
||||
init: function() {
|
||||
var self = PasteInput
|
||||
var self = toReturn
|
||||
|
||||
// intercept dragged files
|
||||
// see http://stackoverflow.com/questions/6756583
|
||||
|
@ -50,7 +49,7 @@ const PasteInput = {
|
|||
},
|
||||
|
||||
handleFile: (file, coords = null) => {
|
||||
var self = PasteInput
|
||||
var self = toReturn
|
||||
var fileReader = new window.FileReader()
|
||||
fileReader.readAsText(file)
|
||||
fileReader.onload = function(e) {
|
||||
|
@ -64,7 +63,7 @@ const PasteInput = {
|
|||
},
|
||||
|
||||
handle: function(text, coords = {}) {
|
||||
var self = PasteInput
|
||||
var self = toReturn
|
||||
|
||||
if (text.match(self.URL_REGEX)) {
|
||||
Import.handleURL(text, coords)
|
||||
|
@ -78,5 +77,7 @@ const PasteInput = {
|
|||
}
|
||||
}
|
||||
}
|
||||
return toReturn
|
||||
}
|
||||
|
||||
export default PasteInput
|
||||
|
|
|
@ -3,13 +3,8 @@
|
|||
import SimpleWebRTC from 'simplewebrtc'
|
||||
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 Views, { ChatView } from '../Views'
|
||||
import Visualize from '../Visualize'
|
||||
import Views from '../Views'
|
||||
|
||||
import {
|
||||
JUNTO_UPDATED,
|
||||
|
@ -63,8 +58,8 @@ import {
|
|||
dragTopic
|
||||
} from './sendable'
|
||||
|
||||
let Realtime = {
|
||||
juntoState: { connectedPeople: {}, liveMaps: {} },
|
||||
const Realtime = ({Active, Cable, DataModel, JIT, Visualize}) => {
|
||||
const toExport = {
|
||||
videoId: 'video-wrapper',
|
||||
socket: null,
|
||||
webrtc: null,
|
||||
|
@ -78,7 +73,7 @@ let Realtime = {
|
|||
localVideo: null,
|
||||
'junto_spinner_darkgrey.gif': '',
|
||||
init: function(serverData) {
|
||||
var self = Realtime
|
||||
var self = toExport
|
||||
|
||||
self.addJuntoListeners()
|
||||
|
||||
|
@ -154,7 +149,7 @@ let Realtime = {
|
|||
} // if Active.Mapper
|
||||
},
|
||||
addJuntoListeners: function() {
|
||||
var self = Realtime
|
||||
var self = toExport
|
||||
|
||||
$(document).on(ChatView.events.openTray, function() {
|
||||
$('.main').addClass('compressed')
|
||||
|
@ -180,7 +175,7 @@ let Realtime = {
|
|||
})
|
||||
},
|
||||
startActiveMap: function() {
|
||||
var self = Realtime
|
||||
var self = toExport
|
||||
if (Active.Map && Active.Mapper) {
|
||||
if (Active.Map.authorizeToEdit(Active.Mapper)) {
|
||||
self.turnOn()
|
||||
|
@ -192,7 +187,7 @@ let Realtime = {
|
|||
}
|
||||
},
|
||||
endActiveMap: function() {
|
||||
var self = Realtime
|
||||
var self = toExport
|
||||
$(document).off('.map')
|
||||
// leave the appropriate rooms to leave
|
||||
if (self.inConversation) self.leaveCall()
|
||||
|
@ -202,7 +197,7 @@ let Realtime = {
|
|||
Cable.unsubscribeFromMap()
|
||||
},
|
||||
turnOn: function(notify) {
|
||||
var self = Realtime
|
||||
var self = toExport
|
||||
$('.collabCompass').show()
|
||||
self.room.room = 'map-' + Active.Map.id
|
||||
self.activeMapper = {
|
||||
|
@ -219,13 +214,13 @@ let Realtime = {
|
|||
self.setupLocalEvents()
|
||||
},
|
||||
setupChat: function() {
|
||||
const self = Realtime
|
||||
const self = toExport
|
||||
ChatView.setNewMap()
|
||||
ChatView.addParticipant(self.activeMapper)
|
||||
ChatView.addMessages(new DataModel.MessageCollection(DataModel.Messages), true)
|
||||
},
|
||||
setupLocalEvents: function() {
|
||||
var self = Realtime
|
||||
var self = toExport
|
||||
// local event listeners that trigger events
|
||||
$(document).on(JIT.events.zoom + '.map', self.positionPeerIcons)
|
||||
$(document).on(JIT.events.pan + '.map', self.positionPeerIcons)
|
||||
|
@ -242,7 +237,7 @@ let Realtime = {
|
|||
})
|
||||
},
|
||||
countOthersInConversation: function() {
|
||||
var self = Realtime
|
||||
var self = toExport
|
||||
var count = 0
|
||||
for (var key in self.mappersOnMap) {
|
||||
if (self.mappersOnMap[key].inConversation) count++
|
||||
|
@ -250,7 +245,7 @@ let Realtime = {
|
|||
return count
|
||||
},
|
||||
handleVideoAdded: function(v, id) {
|
||||
var self = Realtime
|
||||
var self = toExport
|
||||
self.positionVideos()
|
||||
v.setParent($('#wrapper'))
|
||||
v.$container.find('.video-cutoff').css({
|
||||
|
@ -259,7 +254,7 @@ let Realtime = {
|
|||
$('#wrapper').append(v.$container)
|
||||
},
|
||||
positionVideos: function() {
|
||||
var self = Realtime
|
||||
var self = toExport
|
||||
var videoIds = Object.keys(self.room.videos)
|
||||
// var numOfVideos = videoIds.length
|
||||
// var numOfVideosToPosition = _.filter(videoIds, function(id) {
|
||||
|
@ -290,7 +285,7 @@ let Realtime = {
|
|||
}
|
||||
|
||||
// do self first
|
||||
var myVideo = Realtime.localVideo.view
|
||||
var myVideo = toExport.localVideo.view
|
||||
if (!myVideo.manuallyPositioned) {
|
||||
myVideo.$container.css({
|
||||
top: yFormula() + 'px',
|
||||
|
@ -308,7 +303,7 @@ let Realtime = {
|
|||
})
|
||||
},
|
||||
callEnded: function() {
|
||||
var self = Realtime
|
||||
var self = toExport
|
||||
|
||||
ChatView.conversationEnded()
|
||||
self.room.leaveVideoOnly()
|
||||
|
@ -336,13 +331,13 @@ let Realtime = {
|
|||
})
|
||||
},
|
||||
positionPeerIcons: function() {
|
||||
var self = Realtime
|
||||
var self = toExport
|
||||
for (var key in self.mappersOnMap) {
|
||||
self.positionPeerIcon(key)
|
||||
}
|
||||
},
|
||||
positionPeerIcon: function(id) {
|
||||
var self = Realtime
|
||||
var self = toExport
|
||||
var mapper = self.mappersOnMap[id]
|
||||
|
||||
var origPixels = Util.coordsToPixels(Visualize.mGraph, mapper.coords)
|
||||
|
@ -371,7 +366,7 @@ let Realtime = {
|
|||
}
|
||||
},
|
||||
limitPixelsToScreen: function(pixels) {
|
||||
var self = Realtime
|
||||
var self = toExport
|
||||
|
||||
var boundary = self.chatOpen ? '#wrapper' : document
|
||||
var xLimit, yLimit
|
||||
|
@ -405,25 +400,28 @@ const sendables = [
|
|||
['dragTopic', dragTopic]
|
||||
]
|
||||
sendables.forEach(sendable => {
|
||||
Realtime[sendable[0]] = sendable[1](Realtime)
|
||||
toExport[sendable[0]] = sendable[1](toExport)
|
||||
})
|
||||
|
||||
const subscribeToEvents = (Realtime, socket) => {
|
||||
socket.on(JUNTO_UPDATED, juntoUpdated(Realtime))
|
||||
socket.on(INVITED_TO_CALL, invitedToCall(Realtime))
|
||||
socket.on(INVITED_TO_JOIN, invitedToJoin(Realtime))
|
||||
socket.on(CALL_ACCEPTED, callAccepted(Realtime))
|
||||
socket.on(CALL_DENIED, callDenied(Realtime))
|
||||
socket.on(INVITE_DENIED, inviteDenied(Realtime))
|
||||
socket.on(CALL_IN_PROGRESS, callInProgress(Realtime))
|
||||
socket.on(CALL_STARTED, callStarted(Realtime))
|
||||
socket.on(MAPPER_LIST_UPDATED, mapperListUpdated(Realtime))
|
||||
socket.on(MAPPER_JOINED_CALL, mapperJoinedCall(Realtime))
|
||||
socket.on(MAPPER_LEFT_CALL, mapperLeftCall(Realtime))
|
||||
socket.on(PEER_COORDS_UPDATED, peerCoordsUpdated(Realtime))
|
||||
socket.on(NEW_MAPPER, newMapper(Realtime))
|
||||
socket.on(LOST_MAPPER, lostMapper(Realtime))
|
||||
socket.on(TOPIC_DRAGGED, topicDragged(Realtime))
|
||||
const subscribeToEvents = (toExport, socket) => {
|
||||
socket.on(JUNTO_UPDATED, juntoUpdated(toExport))
|
||||
socket.on(INVITED_TO_CALL, invitedToCall(toExport))
|
||||
socket.on(INVITED_TO_JOIN, invitedToJoin(toExport))
|
||||
socket.on(CALL_ACCEPTED, callAccepted(toExport))
|
||||
socket.on(CALL_DENIED, callDenied(toExport))
|
||||
socket.on(INVITE_DENIED, inviteDenied(toExport))
|
||||
socket.on(CALL_IN_PROGRESS, callInProgress(toExport))
|
||||
socket.on(CALL_STARTED, callStarted(toExport))
|
||||
socket.on(MAPPER_LIST_UPDATED, mapperListUpdated(toExport))
|
||||
socket.on(MAPPER_JOINED_CALL, mapperJoinedCall(toExport))
|
||||
socket.on(MAPPER_LEFT_CALL, mapperLeftCall(toExport))
|
||||
socket.on(PEER_COORDS_UPDATED, peerCoordsUpdated(toExport))
|
||||
socket.on(NEW_MAPPER, newMapper(toExport))
|
||||
socket.on(LOST_MAPPER, lostMapper(toExport))
|
||||
socket.on(TOPIC_DRAGGED, topicDragged(toExport))
|
||||
}
|
||||
return toExport
|
||||
}
|
||||
|
||||
|
||||
export default Realtime
|
||||
|
|
|
@ -9,12 +9,12 @@ import { JUNTO_UPDATED } from './events'
|
|||
import Active from '../Active'
|
||||
import { ChatView } from '../Views'
|
||||
import DataModel from '../DataModel'
|
||||
import GlobalUI from '../GlobalUI'
|
||||
import GlobalUI, { ReactApp } from '../GlobalUI'
|
||||
import Util from '../Util'
|
||||
import Visualize from '../Visualize'
|
||||
|
||||
export const juntoUpdated = self => state => {
|
||||
self.juntoState = state
|
||||
ReactApp.juntoState = state
|
||||
$(document).trigger(JUNTO_UPDATED)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
const Selected = {
|
||||
reset: function() {
|
||||
var self = Selected
|
||||
self.Nodes = []
|
||||
self.Edges = []
|
||||
},
|
||||
Nodes: [],
|
||||
Edges: []
|
||||
const Selected = () => {
|
||||
const toExport = {
|
||||
reset: function() {
|
||||
var self = toExport
|
||||
self.Nodes = []
|
||||
self.Edges = []
|
||||
},
|
||||
Nodes: [],
|
||||
Edges: []
|
||||
}
|
||||
return toExport
|
||||
}
|
||||
|
||||
export default Selected
|
||||
|
|
|
@ -1,17 +1,11 @@
|
|||
/* 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 Visualize from './Visualize'
|
||||
|
||||
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
|
||||
// @param id = the id of the synapse to retrieve
|
||||
get: function(id, callback = noOp) {
|
||||
|
@ -77,7 +71,7 @@ const Synapse = {
|
|||
}
|
||||
},
|
||||
createSynapseLocally: function() {
|
||||
var self = Synapse
|
||||
var self = toExport
|
||||
let topic1
|
||||
let topic2
|
||||
let node1
|
||||
|
@ -124,7 +118,7 @@ const Synapse = {
|
|||
Create.newSynapse.hide()
|
||||
},
|
||||
getSynapseFromAutocomplete: function(id) {
|
||||
var self = Synapse
|
||||
var self = toExport
|
||||
|
||||
self.get(id, synapse => {
|
||||
const mapping = new DataModel.Mapping({
|
||||
|
@ -141,5 +135,7 @@ const Synapse = {
|
|||
})
|
||||
}
|
||||
}
|
||||
return toExport
|
||||
}
|
||||
|
||||
export default Synapse
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
/* global $ */
|
||||
import Active from './Active'
|
||||
import Control from './Control'
|
||||
import Mapper from './Mapper'
|
||||
import Visualize from './Visualize'
|
||||
|
||||
const SynapseCard = {
|
||||
const SynapseCard = ({Active, Control, Visualize}) => {
|
||||
const toExport = {
|
||||
openSynapseCard: null,
|
||||
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
|
||||
var myX = $('#edit_synapse').css('left')
|
||||
|
@ -53,11 +51,11 @@ const SynapseCard = {
|
|||
|
||||
hideCard: function() {
|
||||
$('#edit_synapse').remove()
|
||||
SynapseCard.openSynapseCard = null
|
||||
toExport.openSynapseCard = null
|
||||
},
|
||||
|
||||
populateShowCard: function(edge, synapse) {
|
||||
var self = SynapseCard
|
||||
var self = toExport
|
||||
|
||||
self.add_synapse_count(edge)
|
||||
self.add_desc_form(synapse)
|
||||
|
@ -156,7 +154,7 @@ const SynapseCard = {
|
|||
var index = parseInt($(this).attr('data-synapse-index'))
|
||||
edge.setData('displayIndex', index)
|
||||
Visualize.mGraph.plot()
|
||||
SynapseCard.showCard(edge, false)
|
||||
toExport.showCard(edge, false)
|
||||
})
|
||||
}
|
||||
},
|
||||
|
@ -291,5 +289,7 @@ const SynapseCard = {
|
|||
} // if
|
||||
} // add_direction_form
|
||||
}
|
||||
return toExport
|
||||
}
|
||||
|
||||
export default SynapseCard
|
||||
|
|
|
@ -2,27 +2,15 @@
|
|||
|
||||
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 JIT from './JIT'
|
||||
import Loading from './Loading'
|
||||
import Map from './Map'
|
||||
import Selected from './Selected'
|
||||
import Settings from './Settings'
|
||||
import SynapseCard from './SynapseCard'
|
||||
import TopicCard from './Views/TopicCard'
|
||||
import Util from './Util'
|
||||
import Visualize from './Visualize'
|
||||
|
||||
const noOp = () => {}
|
||||
|
||||
const Topic = {
|
||||
// this function is to retrieve a topic JSON object from the database
|
||||
// @param id = the id of the topic to retrieve
|
||||
const Topic = ({Active, AutoLayout, Create, DataModel, Filter, JIT, MAP, Selected, SynapseCard, TopicCard, Visualize}) => {
|
||||
const toExport = {
|
||||
get: function(id, callback = noOp) {
|
||||
// if the desired topic is not yet in the local topic repository, fetch it
|
||||
if (DataModel.Topics.get(id) === undefined) {
|
||||
|
@ -101,7 +89,7 @@ const Topic = {
|
|||
ReactApp.render()
|
||||
},
|
||||
fetchRelatives: function(nodes, metacodeId) {
|
||||
var self = this
|
||||
var self = toExport
|
||||
|
||||
var node = $.isArray(nodes) ? nodes[0] : nodes
|
||||
|
||||
|
@ -292,7 +280,7 @@ const Topic = {
|
|||
}
|
||||
},
|
||||
createTopicLocally: function() {
|
||||
var self = Topic
|
||||
var self = toExport
|
||||
|
||||
if (Create.newTopic.name === '') {
|
||||
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
|
||||
},
|
||||
getTopicFromAutocomplete: function(id) {
|
||||
var self = Topic
|
||||
var self = toExport
|
||||
|
||||
Map.setHasLearnedTopicCreation(true)
|
||||
|
||||
|
@ -357,7 +345,7 @@ const Topic = {
|
|||
})
|
||||
},
|
||||
getMapFromAutocomplete: function(data) {
|
||||
var self = Topic
|
||||
var self = toExport
|
||||
|
||||
$(document).trigger(Map.events.editedByActiveMapper)
|
||||
|
||||
|
@ -387,7 +375,7 @@ const Topic = {
|
|||
if (Create.newTopic.pinned) Create.newTopic.beingCreated = true
|
||||
},
|
||||
getTopicFromSearch: function(event, id) {
|
||||
var self = Topic
|
||||
var self = toExport
|
||||
|
||||
$(document).trigger(Map.events.editedByActiveMapper)
|
||||
|
||||
|
@ -409,5 +397,7 @@ const Topic = {
|
|||
return false
|
||||
}
|
||||
}
|
||||
return toExport
|
||||
}
|
||||
|
||||
export default Topic
|
||||
|
|
|
@ -3,18 +3,17 @@
|
|||
import Backbone from 'backbone'
|
||||
import { Howl } from 'howler'
|
||||
|
||||
import Active from '../Active'
|
||||
import DataModel from '../DataModel'
|
||||
import ReactApp from '../GlobalUI/ReactApp'
|
||||
|
||||
const ChatView = {
|
||||
const ChatView = ({Active, DataModel}) => {
|
||||
const toExport = {
|
||||
isOpen: false,
|
||||
unreadMessages: 0,
|
||||
messages: new Backbone.Collection(),
|
||||
conversationLive: false,
|
||||
isParticipating: false,
|
||||
init: function(urls) {
|
||||
const self = ChatView
|
||||
const self = toExport
|
||||
self.sound = new Howl({
|
||||
src: urls,
|
||||
sprite: {
|
||||
|
@ -27,7 +26,7 @@ const ChatView = {
|
|||
})
|
||||
},
|
||||
setNewMap: function() {
|
||||
const self = ChatView
|
||||
const self = toExport
|
||||
self.unreadMessages = 0
|
||||
self.isOpen = false
|
||||
self.conversationLive = false
|
||||
|
@ -41,74 +40,74 @@ const ChatView = {
|
|||
},
|
||||
render: () => {
|
||||
if (!Active.Map) return
|
||||
const self = ChatView
|
||||
const self = toExport
|
||||
ReactApp.render()
|
||||
},
|
||||
onOpen: () => {
|
||||
const self = ChatView
|
||||
const self = toExport
|
||||
self.isOpen = true
|
||||
self.unreadMessages = 0
|
||||
self.render()
|
||||
$(document).trigger(ChatView.events.openTray)
|
||||
},
|
||||
onClose: () => {
|
||||
const self = ChatView
|
||||
const self = toExport
|
||||
self.isOpen = false
|
||||
$(document).trigger(ChatView.events.closeTray)
|
||||
},
|
||||
addParticipant: participant => {
|
||||
ChatView.participants.add(participant)
|
||||
ChatView.render()
|
||||
toExport.participants.add(participant)
|
||||
toExport.render()
|
||||
},
|
||||
removeParticipant: participant => {
|
||||
ChatView.participants.remove(participant)
|
||||
ChatView.render()
|
||||
toExport.participants.remove(participant)
|
||||
toExport.render()
|
||||
},
|
||||
leaveConversation: () => {
|
||||
ChatView.isParticipating = false
|
||||
ChatView.render()
|
||||
toExport.isParticipating = false
|
||||
toExport.render()
|
||||
},
|
||||
mapperJoinedCall: id => {
|
||||
const mapper = ChatView.participants.findWhere({id})
|
||||
const mapper = toExport.participants.findWhere({id})
|
||||
mapper && mapper.set('isParticipating', true)
|
||||
ChatView.render()
|
||||
toExport.render()
|
||||
},
|
||||
mapperLeftCall: id => {
|
||||
const mapper = ChatView.participants.findWhere({id})
|
||||
const mapper = toExport.participants.findWhere({id})
|
||||
mapper && mapper.set('isParticipating', false)
|
||||
ChatView.render()
|
||||
toExport.render()
|
||||
},
|
||||
invitationPending: id => {
|
||||
const mapper = ChatView.participants.findWhere({id})
|
||||
const mapper = toExport.participants.findWhere({id})
|
||||
mapper && mapper.set('isPending', true)
|
||||
ChatView.render()
|
||||
toExport.render()
|
||||
},
|
||||
invitationAnswered: id => {
|
||||
const mapper = ChatView.participants.findWhere({id})
|
||||
const mapper = toExport.participants.findWhere({id})
|
||||
mapper && mapper.set('isPending', false)
|
||||
ChatView.render()
|
||||
toExport.render()
|
||||
},
|
||||
conversationInProgress: participating => {
|
||||
ChatView.conversationLive = true
|
||||
ChatView.isParticipating = participating
|
||||
ChatView.render()
|
||||
toExport.conversationLive = true
|
||||
toExport.isParticipating = participating
|
||||
toExport.render()
|
||||
},
|
||||
conversationEnded: () => {
|
||||
ChatView.conversationLive = false
|
||||
ChatView.isParticipating = false
|
||||
ChatView.participants.forEach(p => p.set({isParticipating: false, isPending: false}))
|
||||
ChatView.render()
|
||||
toExport.conversationLive = false
|
||||
toExport.isParticipating = false
|
||||
toExport.participants.forEach(p => p.set({isParticipating: false, isPending: false}))
|
||||
toExport.render()
|
||||
},
|
||||
videoToggleClick: function() {
|
||||
ChatView.videosShowing = !ChatView.videosShowing
|
||||
$(document).trigger(ChatView.videosShowing ? ChatView.events.videosOn : ChatView.events.videosOff)
|
||||
toExport.videosShowing = !toExport.videosShowing
|
||||
$(document).trigger(toExport.videosShowing ? ChatView.events.videosOn : ChatView.events.videosOff)
|
||||
},
|
||||
cursorToggleClick: function() {
|
||||
ChatView.cursorsShowing = !ChatView.cursorsShowing
|
||||
$(document).trigger(ChatView.cursorsShowing ? ChatView.events.cursorsOn : ChatView.events.cursorsOff)
|
||||
toExport.cursorsShowing = !toExport.cursorsShowing
|
||||
$(document).trigger(toExport.cursorsShowing ? ChatView.events.cursorsOn : ChatView.events.cursorsOff)
|
||||
},
|
||||
soundToggleClick: function() {
|
||||
ChatView.alertSound = !ChatView.alertSound
|
||||
toExport.alertSound = !toExport.alertSound
|
||||
},
|
||||
inputFocus: () => {
|
||||
$(document).trigger(ChatView.events.inputFocus)
|
||||
|
@ -117,15 +116,15 @@ const ChatView = {
|
|||
$(document).trigger(ChatView.events.inputBlur)
|
||||
},
|
||||
addMessage: (message, isInitial, wasMe) => {
|
||||
const self = ChatView
|
||||
const self = toExport
|
||||
if (!isInitial && !self.isOpen) self.unreadMessages += 1
|
||||
if (!wasMe && !isInitial && self.alertSound) self.sound.play('receivechat')
|
||||
self.messages.add(message)
|
||||
if (!isInitial && self.isOpen) self.render()
|
||||
},
|
||||
sendChatMessage: message => {
|
||||
var self = ChatView
|
||||
if (ChatView.alertSound) ChatView.sound.play('sendchat')
|
||||
var self = toExport
|
||||
if (toExport.alertSound) toExport.sound.play('sendchat')
|
||||
var m = new DataModel.Message({
|
||||
message: message.message,
|
||||
resource_id: Active.Map.id,
|
||||
|
@ -141,14 +140,16 @@ const ChatView = {
|
|||
})
|
||||
},
|
||||
handleInputMessage: text => {
|
||||
ChatView.sendChatMessage({message: text})
|
||||
toExport.sendChatMessage({message: text})
|
||||
},
|
||||
// they should be instantiated as backbone models before they get
|
||||
// passed to this function
|
||||
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
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
import { ReactApp } from '../GlobalUI'
|
||||
|
||||
const TopicCard = {
|
||||
const TopicCard = () => {
|
||||
const toExport = {
|
||||
openTopic: null,
|
||||
showCard: function(node) {
|
||||
TopicCard.openTopic = node.getData('topic')
|
||||
toExport.openTopic = node.getData('topic')
|
||||
ReactApp.render()
|
||||
},
|
||||
hideCard: function() {
|
||||
TopicCard.openTopic = null
|
||||
toExport.openTopic = null
|
||||
ReactApp.render()
|
||||
}
|
||||
}
|
||||
return toExport
|
||||
}
|
||||
|
||||
export default TopicCard
|
||||
|
|
|
@ -10,7 +10,7 @@ import { JUNTO_UPDATED } from '../Realtime/events'
|
|||
const Views = {
|
||||
init: (serverData) => {
|
||||
$(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,
|
||||
ChatView,
|
||||
|
|
|
@ -10,14 +10,15 @@ import JIT from './JIT'
|
|||
import Loading from './Loading'
|
||||
import TopicCard from './Views/TopicCard'
|
||||
|
||||
const Visualize = {
|
||||
const Visualize = ({Active, DataModel, JIT, TopicCard}) => {
|
||||
const toExport = {
|
||||
mGraph: null, // a reference to the graph object.
|
||||
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"
|
||||
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,
|
||||
init: function(serverData) {
|
||||
var self = Visualize
|
||||
var self = toExport
|
||||
|
||||
if (serverData.VisualizeType) self.type = serverData.VisualizeType
|
||||
|
||||
|
@ -45,7 +46,7 @@ const Visualize = {
|
|||
})
|
||||
},
|
||||
computePositions: function() {
|
||||
const self = Visualize
|
||||
const self = toExport
|
||||
|
||||
if (self.type === 'RGraph') {
|
||||
let i
|
||||
|
@ -107,7 +108,7 @@ const Visualize = {
|
|||
*
|
||||
*/
|
||||
render: function() {
|
||||
const self = Visualize
|
||||
const self = toExport
|
||||
|
||||
if (self.type === 'RGraph') {
|
||||
// clear the previous canvas from #infovis
|
||||
|
@ -199,11 +200,14 @@ const Visualize = {
|
|||
hold()
|
||||
},
|
||||
clearVisualization: function() {
|
||||
Visualize.mGraph.graph.empty()
|
||||
Visualize.mGraph.plot()
|
||||
const self = toExport
|
||||
self.mGraph.graph.empty()
|
||||
self.mGraph.plot()
|
||||
JIT.centerMap(Visualize.mGraph.canvas)
|
||||
$('#infovis').empty()
|
||||
}
|
||||
}
|
||||
return toExport
|
||||
}
|
||||
|
||||
export default Visualize
|
||||
|
|
|
@ -1,32 +1,72 @@
|
|||
import Account from './Account'
|
||||
import Active from './Active'
|
||||
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 Filter from './Filter'
|
||||
import GlobalUI, {
|
||||
ReactApp, Search, CreateMap, ImportDialog
|
||||
} from './GlobalUI'
|
||||
import Import from './Import'
|
||||
import JIT from './JIT'
|
||||
import Listeners from './Listeners'
|
||||
import Loading from './Loading'
|
||||
import Map, { CheatSheet } from './Map'
|
||||
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 Util from './Util'
|
||||
import Views from './Views'
|
||||
import Visualize from './Visualize'
|
||||
|
||||
const Metamaps = window.Metamaps || {}
|
||||
Metamaps.Account = Account
|
||||
Metamaps.Active = Active
|
||||
Metamaps.Admin = Admin
|
||||
Metamaps.AutoLayout = AutoLayout
|
||||
Metamaps.Cable = Cable
|
||||
Metamaps.Control = Control
|
||||
Metamaps.Create = Create
|
||||
Metamaps.DataModel = DataModel
|
||||
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.ReactApp = ReactApp
|
||||
Metamaps.GlobalUI.Search = Search
|
||||
Metamaps.GlobalUI.CreateMap = CreateMap
|
||||
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() {
|
||||
// initialize all the modules
|
||||
|
@ -37,6 +77,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||
Metamaps[prop].hasOwnProperty('init') &&
|
||||
typeof (Metamaps[prop].init) === 'function'
|
||||
) {
|
||||
console.log(prop)
|
||||
Metamaps[prop].init(Metamaps.ServerData)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue