diff --git a/app/policies/synapse_policy.rb b/app/policies/synapse_policy.rb
index e3190c18..54cb47c1 100644
--- a/app/policies/synapse_policy.rb
+++ b/app/policies/synapse_policy.rb
@@ -38,7 +38,7 @@ class SynapsePolicy < ApplicationPolicy
end
def destroy?
- record.user == user || admin_override
+ record.mappings.empty? && (record.user == user || admin_override)
end
# Helpers
diff --git a/app/policies/topic_policy.rb b/app/policies/topic_policy.rb
index 64463b4a..178f3d96 100644
--- a/app/policies/topic_policy.rb
+++ b/app/policies/topic_policy.rb
@@ -36,7 +36,7 @@ class TopicPolicy < ApplicationPolicy
end
def destroy?
- record.user == user || admin_override
+ record.mappings.empty? && (record.user == user || admin_override)
end
def autocomplete_topic?
diff --git a/frontend/src/Metamaps/Control.js b/frontend/src/Metamaps/Control.js
index 8f613b16..bc5266e6 100644
--- a/frontend/src/Metamaps/Control.js
+++ b/frontend/src/Metamaps/Control.js
@@ -39,76 +39,13 @@ const Control = {
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) {
- GlobalUI.showDiv('#instructions')
- }
+ removeSelected: function() {
+ Control.removeSelectedEdges()
+ Control.removeSelectedNodes()
},
- 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 mappableid = topic.id
- var mapping = node.getData('mapping')
- topic.destroy()
- DataModel.Mappings.remove(mapping)
- $(document).trigger(JIT.events.deleteTopic, [{
- mappableid: mappableid
- }])
- Control.hideNode(nodeid)
- } else {
- GlobalUI.notifyUser('Only topics you created can be deleted')
- }
+ hideSelected: function() {
+ Control.hideSelectedEdges()
+ Control.hideSelectedNodes()
},
removeSelectedNodes: function() { // refers to removing topics permanently from a map
if (Active.Topic) {
@@ -237,59 +174,6 @@ const Control = {
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)
-
- if (!authorized) {
- GlobalUI.notifyUser('Cannot edit Public map.')
- return
- }
-
- 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 authorized = Active.Map.authorizeToEdit(Active.Mapper)
-
- 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)
- }
- var mappableid = synapse.id
- 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
- }
- $(document).trigger(JIT.events.deleteSynapse, [{
- mappableid: mappableid
- }])
- } else {
- GlobalUI.notifyUser('Only synapses you created can be deleted')
- }
- },
removeSelectedEdges: function() {
// Topic view is handled by removeSelectedNodes
if (!Active.Map) return
@@ -299,7 +183,7 @@ const Control = {
var authorized = Active.Map.authorizeToEdit(Active.Mapper)
if (!authorized) {
- GlobalUI.notifyUser('Cannot edit Public map.')
+ GlobalUI.notifyUser('Cannot edit this map.')
return
}
diff --git a/frontend/src/Metamaps/JIT.js b/frontend/src/Metamaps/JIT.js
index 903cc11d..8a0ac7c6 100644
--- a/frontend/src/Metamaps/JIT.js
+++ b/frontend/src/Metamaps/JIT.js
@@ -37,10 +37,8 @@ const JIT = {
events: {
topicDrag: 'Metamaps:JIT:events:topicDrag',
newTopic: 'Metamaps:JIT:events:newTopic',
- deleteTopic: 'Metamaps:JIT:events:deleteTopic',
removeTopic: 'Metamaps:JIT:events:removeTopic',
newSynapse: 'Metamaps:JIT:events:newSynapse',
- deleteSynapse: 'Metamaps:JIT:events:deleteSynapse',
removeSynapse: 'Metamaps:JIT:events:removeSynapse',
pan: 'Metamaps:JIT:events:pan',
zoom: 'Metamaps:JIT:events:zoom',
@@ -1396,9 +1394,8 @@ const JIT = {
const disabled = authorized ? '' : 'disabled'
if (Active.Map) menustring += '
Hide until refreshCtrl+H
'
- if (Active.Map && Active.Mapper) menustring += 'Remove from mapCtrl+M
'
- if (Active.Topic) menustring += 'Remove from viewCtrl+M
'
- if (Active.Map && Active.Mapper) menustring += 'DeleteCtrl+D
'
+ if (Active.Map && Active.Mapper) menustring += 'RemoveCtrl+D
'
+ if (Active.Topic) menustring += 'Remove from viewCtrl+D
'
if (Active.Topic) {
menustring += 'Center this topicAlt+E
'
@@ -1483,28 +1480,18 @@ const JIT = {
// attach events to clicks on the list items
- // delete the selected things from the database
- if (authorized) {
- $('.rc-delete').click(function() {
- $('.rightclickmenu').remove()
- Control.deleteSelected()
- })
- }
-
// remove the selected things from the map
if (Active.Topic || authorized) {
$('.rc-remove').click(function() {
$('.rightclickmenu').remove()
- Control.removeSelectedEdges()
- Control.removeSelectedNodes()
+ Control.removeSelected()
})
}
// hide selected nodes and synapses until refresh
$('.rc-hide').click(function() {
$('.rightclickmenu').remove()
- Control.hideSelectedEdges()
- Control.hideSelectedNodes()
+ Control.hideSelected()
})
// when in radial, center on the topic you picked
@@ -1654,9 +1641,8 @@ const JIT = {
const disabled = authorized ? '' : 'disabled'
if (Active.Map) menustring += 'Hide until refreshCtrl+H
'
- if (Active.Map && Active.Mapper) menustring += 'Remove from mapCtrl+M
'
- if (Active.Topic) menustring += 'Remove from viewCtrl+M
'
- if (Active.Map && Active.Mapper) menustring += 'DeleteCtrl+D
'
+ if (Active.Map && Active.Mapper) menustring += 'RemoveCtrl+D
'
+ if (Active.Topic) menustring += 'Remove from viewCtrl+D
'
if (Active.Map && Active.Mapper) menustring += ''
@@ -1703,28 +1689,18 @@ const JIT = {
// attach events to clicks on the list items
- // delete the selected things from the database
- if (authorized) {
- $('.rc-delete').click(function() {
- $('.rightclickmenu').remove()
- Control.deleteSelected()
- })
- }
-
// remove the selected things from the map
if (authorized) {
$('.rc-remove').click(function() {
$('.rightclickmenu').remove()
- Control.removeSelectedEdges()
- Control.removeSelectedNodes()
+ Control.removeSelected()
})
}
// hide selected nodes and synapses until refresh
$('.rc-hide').click(function() {
$('.rightclickmenu').remove()
- Control.hideSelectedEdges()
- Control.hideSelectedNodes()
+ Control.hideSelected()
})
// change the permission of all the selected nodes and synapses that you were the originator of
diff --git a/frontend/src/Metamaps/Listeners.js b/frontend/src/Metamaps/Listeners.js
index 756227b1..76c5e540 100644
--- a/frontend/src/Metamaps/Listeners.js
+++ b/frontend/src/Metamaps/Listeners.js
@@ -60,7 +60,7 @@ const Listeners = {
case 68: // if d or D is pressed
if (e.ctrlKey || e.metaKey) {
e.preventDefault()
- Control.deleteSelected()
+ Control.removeSelected()
}
break
case 69: // if e or E is pressed
@@ -84,15 +84,16 @@ const Listeners = {
case 72: // if h or H is pressed
if (e.ctrlKey || e.metaKey) {
e.preventDefault()
- Control.hideSelectedNodes()
- Control.hideSelectedEdges()
+ Control.hideSelected()
}
break
case 77: // if m or M is pressed
+ // since we're removing 'deletion', we have Ctrl-D available for this now, but leave this in
+ // as a deprecated function, just in case its what people got used to
+ // or should we do a GlobalUI.notifyUser to ask them to switch?
if (e.ctrlKey || e.metaKey) {
e.preventDefault()
- Control.removeSelectedNodes()
- Control.removeSelectedEdges()
+ Control.removeSelected()
}
break
case 82: // if r or R is pressed
diff --git a/frontend/src/Metamaps/Realtime/index.js b/frontend/src/Metamaps/Realtime/index.js
index 318753f0..65bbceea 100644
--- a/frontend/src/Metamaps/Realtime/index.js
+++ b/frontend/src/Metamaps/Realtime/index.js
@@ -29,11 +29,9 @@ import {
TOPIC_CREATED,
TOPIC_UPDATED,
TOPIC_REMOVED,
- TOPIC_DELETED,
SYNAPSE_CREATED,
SYNAPSE_UPDATED,
SYNAPSE_REMOVED,
- SYNAPSE_DELETED,
PEER_COORDS_UPDATED,
MAP_UPDATED
} from './events'
@@ -58,11 +56,9 @@ import {
topicCreated,
topicUpdated,
topicRemoved,
- topicDeleted,
synapseCreated,
synapseUpdated,
synapseRemoved,
- synapseDeleted,
mapUpdated
} from './receivable'
@@ -84,11 +80,9 @@ import {
createTopic,
updateTopic,
removeTopic,
- deleteTopic,
createSynapse,
updateSynapse,
removeSynapse,
- deleteSynapse,
updateMap
} from './sendable'
@@ -304,11 +298,6 @@ let Realtime = {
}
$(document).on(JIT.events.newTopic + '.map', createTopic)
- var deleteTopic = function(event, data) {
- self.deleteTopic(data)
- }
- $(document).on(JIT.events.deleteTopic + '.map', deleteTopic)
-
var removeTopic = function(event, data) {
self.removeTopic(data)
}
@@ -319,11 +308,6 @@ let Realtime = {
}
$(document).on(JIT.events.newSynapse + '.map', createSynapse)
- var deleteSynapse = function(event, data) {
- self.deleteSynapse(data)
- }
- $(document).on(JIT.events.deleteSynapse + '.map', deleteSynapse)
-
var removeSynapse = function(event, data) {
self.removeSynapse(data)
}
@@ -500,11 +484,9 @@ const sendables = [
['createTopic', createTopic],
['updateTopic', updateTopic],
['removeTopic', removeTopic],
- ['deleteTopic', deleteTopic],
['createSynapse', createSynapse],
['updateSynapse', updateSynapse],
['removeSynapse', removeSynapse],
- ['deleteSynapse', deleteSynapse],
['updateMap', updateMap]
]
sendables.forEach(sendable => {
@@ -531,11 +513,9 @@ const subscribeToEvents = (Realtime, socket) => {
socket.on(TOPIC_CREATED, topicCreated(Realtime))
socket.on(TOPIC_UPDATED, topicUpdated(Realtime))
socket.on(TOPIC_REMOVED, topicRemoved(Realtime))
- socket.on(TOPIC_DELETED, topicDeleted(Realtime))
socket.on(SYNAPSE_CREATED, synapseCreated(Realtime))
socket.on(SYNAPSE_UPDATED, synapseUpdated(Realtime))
socket.on(SYNAPSE_REMOVED, synapseRemoved(Realtime))
- socket.on(SYNAPSE_DELETED, synapseDeleted(Realtime))
socket.on(MAP_UPDATED, mapUpdated(Realtime))
}
diff --git a/realtime/global.js b/realtime/global.js
index 485085a6..0a00b3fd 100644
--- a/realtime/global.js
+++ b/realtime/global.js
@@ -1,9 +1,7 @@
const {
// server sendable, client receivable
TOPIC_UPDATED,
- TOPIC_DELETED,
SYNAPSE_UPDATED,
- SYNAPSE_DELETED,
MAP_UPDATED,
JUNTO_UPDATED,
@@ -13,15 +11,12 @@ const {
JOIN_MAP,
LEAVE_MAP,
UPDATE_TOPIC,
- DELETE_TOPIC,
UPDATE_SYNAPSE,
- DELETE_SYNAPSE,
UPDATE_MAP
} = require('../frontend/src/Metamaps/Realtime/events')
module.exports = function(io, store) {
store.subscribe(() => {
- console.log(store.getState())
io.sockets.emit(JUNTO_UPDATED, store.getState())
})
@@ -38,18 +33,10 @@ module.exports = function(io, store) {
socket.broadcast.emit(TOPIC_UPDATED, data)
})
- socket.on(DELETE_TOPIC, function(data) {
- socket.broadcast.emit(TOPIC_DELETED, data)
- })
-
socket.on(UPDATE_SYNAPSE, function(data) {
socket.broadcast.emit(SYNAPSE_UPDATED, data)
})
- socket.on(DELETE_SYNAPSE, function(data) {
- socket.broadcast.emit(SYNAPSE_DELETED, data)
- })
-
socket.on(UPDATE_MAP, function(data) {
socket.broadcast.emit(MAP_UPDATED, data)
})