Track everything we need to reconstruct maps (#984)
* feature/more.events * keep mapping.user as the creator * cleanup cruft and include slack notifs * capture topic and synapse updates, store the old values * avoid the mapping gets deleted problem * include an indicator of which values changed * style cleanup * remove the hack in favor of a legit way * updated schema file
This commit is contained in:
parent
9ab1c9c647
commit
fb12c7e202
31 changed files with 233 additions and 154 deletions
|
@ -5,6 +5,27 @@ module Api
|
||||||
def searchable_columns
|
def searchable_columns
|
||||||
[]
|
[]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
instantiate_resource
|
||||||
|
resource.user = current_user if current_user.present?
|
||||||
|
resource.updated_by = current_user if current_user.present?
|
||||||
|
authorize resource
|
||||||
|
create_action
|
||||||
|
respond_with_resource
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
resource.updated_by = current_user if current_user.present?
|
||||||
|
update_action
|
||||||
|
respond_with_resource
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
resource.updated_by = current_user if current_user.present?
|
||||||
|
destroy_action
|
||||||
|
head :no_content
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -19,10 +19,10 @@ class MappingsController < ApplicationController
|
||||||
@mapping = Mapping.new(mapping_params)
|
@mapping = Mapping.new(mapping_params)
|
||||||
authorize @mapping
|
authorize @mapping
|
||||||
@mapping.user = current_user
|
@mapping.user = current_user
|
||||||
|
@mapping.updated_by = current_user
|
||||||
|
|
||||||
if @mapping.save
|
if @mapping.save
|
||||||
render json: @mapping, status: :created
|
render json: @mapping, status: :created
|
||||||
Events::NewMapping.publish!(@mapping, current_user)
|
|
||||||
else
|
else
|
||||||
render json: @mapping.errors, status: :unprocessable_entity
|
render json: @mapping.errors, status: :unprocessable_entity
|
||||||
end
|
end
|
||||||
|
@ -32,8 +32,10 @@ class MappingsController < ApplicationController
|
||||||
def update
|
def update
|
||||||
@mapping = Mapping.find(params[:id])
|
@mapping = Mapping.find(params[:id])
|
||||||
authorize @mapping
|
authorize @mapping
|
||||||
|
@mapping.updated_by = current_user
|
||||||
|
@mapping.assign_attributes(mapping_params)
|
||||||
|
|
||||||
if @mapping.update_attributes(mapping_params)
|
if @mapping.save
|
||||||
head :no_content
|
head :no_content
|
||||||
else
|
else
|
||||||
render json: @mapping.errors, status: :unprocessable_entity
|
render json: @mapping.errors, status: :unprocessable_entity
|
||||||
|
@ -44,14 +46,7 @@ class MappingsController < ApplicationController
|
||||||
def destroy
|
def destroy
|
||||||
@mapping = Mapping.find(params[:id])
|
@mapping = Mapping.find(params[:id])
|
||||||
authorize @mapping
|
authorize @mapping
|
||||||
|
@mapping.updated_by = current_user
|
||||||
mappable = @mapping.mappable
|
|
||||||
if mappable.defer_to_map
|
|
||||||
mappable.permission = mappable.defer_to_map.permission
|
|
||||||
mappable.defer_to_map_id = nil
|
|
||||||
mappable.save
|
|
||||||
end
|
|
||||||
|
|
||||||
@mapping.destroy
|
@mapping.destroy
|
||||||
|
|
||||||
head :no_content
|
head :no_content
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
class Event < ApplicationRecord
|
class Event < ApplicationRecord
|
||||||
KINDS = %w(user_present_on_map conversation_started_on_map topic_added_to_map synapse_added_to_map).freeze
|
KINDS = %w(user_present_on_map conversation_started_on_map
|
||||||
|
topic_added_to_map topic_moved_on_map topic_removed_from_map
|
||||||
|
synapse_added_to_map synapse_removed_from_map
|
||||||
|
topic_updated synapse_updated).freeze
|
||||||
|
|
||||||
# has_many :notifications, dependent: :destroy
|
|
||||||
belongs_to :eventable, polymorphic: true
|
belongs_to :eventable, polymorphic: true
|
||||||
belongs_to :map
|
belongs_to :map
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
|
@ -14,18 +16,12 @@ class Event < ApplicationRecord
|
||||||
validates :kind, inclusion: { in: KINDS }
|
validates :kind, inclusion: { in: KINDS }
|
||||||
validates :eventable, presence: true
|
validates :eventable, presence: true
|
||||||
|
|
||||||
# def notify!(user)
|
|
||||||
# notifications.create!(user: user)
|
|
||||||
# end
|
|
||||||
|
|
||||||
def belongs_to?(this_user)
|
def belongs_to?(this_user)
|
||||||
user_id == this_user.id
|
user_id == this_user.id
|
||||||
end
|
end
|
||||||
|
|
||||||
def notify_webhooks!
|
def notify_webhooks!
|
||||||
# group = self.discussion.group
|
|
||||||
map.webhooks.each { |webhook| WebhookService.publish! webhook: webhook, event: self }
|
map.webhooks.each { |webhook| WebhookService.publish! webhook: webhook, event: self }
|
||||||
# group.webhooks.each { |webhook| WebhookService.publish! webhook: webhook, event: self }
|
|
||||||
end
|
end
|
||||||
handle_asynchronously :notify_webhooks!
|
handle_asynchronously :notify_webhooks!
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
class Events::NewMapping < Event
|
|
||||||
# after_create :notify_users!
|
|
||||||
|
|
||||||
def self.publish!(mapping, user)
|
|
||||||
create!(kind: mapping.mappable_type == 'Topic' ? 'topic_added_to_map' : 'synapse_added_to_map',
|
|
||||||
eventable: mapping,
|
|
||||||
map: mapping.map,
|
|
||||||
user: user)
|
|
||||||
end
|
|
||||||
end
|
|
12
app/models/events/synapse_added_to_map.rb
Normal file
12
app/models/events/synapse_added_to_map.rb
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
class Events::SynapseAddedToMap < Event
|
||||||
|
# after_create :notify_users!
|
||||||
|
|
||||||
|
def self.publish!(synapse, map, user, meta)
|
||||||
|
create!(kind: 'synapse_added_to_map',
|
||||||
|
eventable: synapse,
|
||||||
|
map: map,
|
||||||
|
user: user,
|
||||||
|
meta: meta)
|
||||||
|
end
|
||||||
|
end
|
12
app/models/events/synapse_removed_from_map.rb
Normal file
12
app/models/events/synapse_removed_from_map.rb
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
class Events::SynapseRemovedFromMap < Event
|
||||||
|
# after_create :notify_users!
|
||||||
|
|
||||||
|
def self.publish!(synapse, map, user, meta)
|
||||||
|
create!(kind: 'synapse_removed_from_map',
|
||||||
|
eventable: synapse,
|
||||||
|
map: map,
|
||||||
|
user: user,
|
||||||
|
meta: meta)
|
||||||
|
end
|
||||||
|
end
|
11
app/models/events/synapse_updated.rb
Normal file
11
app/models/events/synapse_updated.rb
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
class Events::SynapseUpdated < Event
|
||||||
|
# after_create :notify_users!
|
||||||
|
|
||||||
|
def self.publish!(synapse, user, meta)
|
||||||
|
create!(kind: 'synapse_updated',
|
||||||
|
eventable: synapse,
|
||||||
|
user: user,
|
||||||
|
meta: meta)
|
||||||
|
end
|
||||||
|
end
|
12
app/models/events/topic_added_to_map.rb
Normal file
12
app/models/events/topic_added_to_map.rb
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
class Events::TopicAddedToMap < Event
|
||||||
|
# after_create :notify_users!
|
||||||
|
|
||||||
|
def self.publish!(topic, map, user, meta)
|
||||||
|
create!(kind: 'topic_added_to_map',
|
||||||
|
eventable: topic,
|
||||||
|
map: map,
|
||||||
|
user: user,
|
||||||
|
meta: meta)
|
||||||
|
end
|
||||||
|
end
|
12
app/models/events/topic_moved_on_map.rb
Normal file
12
app/models/events/topic_moved_on_map.rb
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
class Events::TopicMovedOnMap < Event
|
||||||
|
# after_create :notify_users!
|
||||||
|
|
||||||
|
def self.publish!(topic, map, user, meta)
|
||||||
|
create!(kind: 'topic_moved_on_map',
|
||||||
|
eventable: topic,
|
||||||
|
map: map,
|
||||||
|
user: user,
|
||||||
|
meta: meta)
|
||||||
|
end
|
||||||
|
end
|
12
app/models/events/topic_removed_from_map.rb
Normal file
12
app/models/events/topic_removed_from_map.rb
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
class Events::TopicRemovedFromMap < Event
|
||||||
|
# after_create :notify_users!
|
||||||
|
|
||||||
|
def self.publish!(topic, map, user, meta)
|
||||||
|
create!(kind: 'topic_removed_from_map',
|
||||||
|
eventable: topic,
|
||||||
|
map: map,
|
||||||
|
user: user,
|
||||||
|
meta: meta)
|
||||||
|
end
|
||||||
|
end
|
11
app/models/events/topic_updated.rb
Normal file
11
app/models/events/topic_updated.rb
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
class Events::TopicUpdated < Event
|
||||||
|
# after_create :notify_users!
|
||||||
|
|
||||||
|
def self.publish!(topic, user, meta)
|
||||||
|
create!(kind: 'topic_updated',
|
||||||
|
eventable: topic,
|
||||||
|
user: user,
|
||||||
|
meta: meta)
|
||||||
|
end
|
||||||
|
end
|
|
@ -6,6 +6,7 @@ class Mapping < ApplicationRecord
|
||||||
belongs_to :mappable, polymorphic: true
|
belongs_to :mappable, polymorphic: true
|
||||||
belongs_to :map, class_name: 'Map', foreign_key: 'map_id', touch: true
|
belongs_to :map, class_name: 'Map', foreign_key: 'map_id', touch: true
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
|
belongs_to :updated_by, class_name: 'User'
|
||||||
|
|
||||||
validates :xloc, presence: true,
|
validates :xloc, presence: true,
|
||||||
unless: proc { |m| m.mappable_type == 'Synapse' }
|
unless: proc { |m| m.mappable_type == 'Synapse' }
|
||||||
|
@ -16,6 +17,10 @@ class Mapping < ApplicationRecord
|
||||||
|
|
||||||
delegate :name, to: :user, prefix: true
|
delegate :name, to: :user, prefix: true
|
||||||
|
|
||||||
|
after_create :after_created
|
||||||
|
after_update :after_updated
|
||||||
|
before_destroy :before_destroyed
|
||||||
|
|
||||||
def user_image
|
def user_image
|
||||||
user.image.url
|
user.image.url
|
||||||
end
|
end
|
||||||
|
@ -23,4 +28,35 @@ class Mapping < ApplicationRecord
|
||||||
def as_json(_options = {})
|
def as_json(_options = {})
|
||||||
super(methods: [:user_name, :user_image])
|
super(methods: [:user_name, :user_image])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def after_created
|
||||||
|
if mappable_type == 'Topic'
|
||||||
|
meta = {'x': xloc, 'y': yloc, 'mapping_id': id}
|
||||||
|
Events::TopicAddedToMap.publish!(mappable, map, user, meta)
|
||||||
|
elsif mappable_type == 'Synapse'
|
||||||
|
Events::SynapseAddedToMap.publish!(mappable, map, user, meta)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def after_updated
|
||||||
|
if mappable_type == 'Topic' and (xloc_changed? or yloc_changed?)
|
||||||
|
meta = {'x': xloc, 'y': yloc, 'mapping_id': id}
|
||||||
|
Events::TopicMovedOnMap.publish!(mappable, map, updated_by, meta)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def before_destroyed
|
||||||
|
if mappable.defer_to_map
|
||||||
|
mappable.permission = mappable.defer_to_map.permission
|
||||||
|
mappable.defer_to_map_id = nil
|
||||||
|
mappable.save
|
||||||
|
end
|
||||||
|
|
||||||
|
meta = {'mapping_id': id}
|
||||||
|
if mappable_type == 'Topic'
|
||||||
|
Events::TopicRemovedFromMap.publish!(mappable, map, updated_by, meta)
|
||||||
|
elsif mappable_type == 'Synapse'
|
||||||
|
Events::SynapseRemovedFromMap.publish!(mappable, map, updated_by, meta)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -22,6 +22,8 @@ class Synapse < ApplicationRecord
|
||||||
where(topic1_id: topic_id).or(where(topic2_id: topic_id))
|
where(topic1_id: topic_id).or(where(topic2_id: topic_id))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
after_update :after_updated
|
||||||
|
|
||||||
delegate :name, to: :user, prefix: true
|
delegate :name, to: :user, prefix: true
|
||||||
|
|
||||||
def user_image
|
def user_image
|
||||||
|
@ -39,4 +41,15 @@ class Synapse < ApplicationRecord
|
||||||
def as_json(_options = {})
|
def as_json(_options = {})
|
||||||
super(methods: [:user_name, :user_image, :collaborator_ids])
|
super(methods: [:user_name, :user_image, :collaborator_ids])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def after_updated
|
||||||
|
attrs = ['desc', 'category', 'permission', 'defer_to_map_id']
|
||||||
|
if attrs.any? {|k| changed_attributes.key?(k)}
|
||||||
|
new = self.attributes.select {|k| attrs.include?(k) }
|
||||||
|
old = changed_attributes.select {|k| attrs.include?(k) }
|
||||||
|
meta = new.merge(old) # we are prioritizing the old values, keeping them
|
||||||
|
meta['changed'] = changed_attributes.keys.select {|k| attrs.include?(k) }
|
||||||
|
Events::SynapseUpdated.publish!(self, user, meta)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,6 +16,7 @@ class Topic < ApplicationRecord
|
||||||
belongs_to :metacode
|
belongs_to :metacode
|
||||||
|
|
||||||
before_create :create_metamap?
|
before_create :create_metamap?
|
||||||
|
after_update :after_updated
|
||||||
|
|
||||||
validates :permission, presence: true
|
validates :permission, presence: true
|
||||||
validates :permission, inclusion: { in: Perm::ISSIONS.map(&:to_s) }
|
validates :permission, inclusion: { in: Perm::ISSIONS.map(&:to_s) }
|
||||||
|
@ -135,4 +136,15 @@ class Topic < ApplicationRecord
|
||||||
self.link = Rails.application.routes.url_helpers
|
self.link = Rails.application.routes.url_helpers
|
||||||
.map_url(host: ENV['MAILER_DEFAULT_URL'], id: @map.id)
|
.map_url(host: ENV['MAILER_DEFAULT_URL'], id: @map.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def after_updated
|
||||||
|
attrs = ['name', 'desc', 'link', 'metacode_id', 'permission', 'defer_to_map_id']
|
||||||
|
if attrs.any? {|k| changed_attributes.key?(k)}
|
||||||
|
new = self.attributes.select {|k| attrs.include?(k) }
|
||||||
|
old = changed_attributes.select {|k| attrs.include?(k) }
|
||||||
|
meta = new.merge(old) # we are prioritizing the old values, keeping them
|
||||||
|
meta['changed'] = changed_attributes.keys.select {|k| attrs.include?(k) }
|
||||||
|
Events::TopicUpdated.publish!(self, user, meta)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,45 +16,14 @@ Webhooks::Slack::Base = Struct.new(:webhook, :event) do
|
||||||
|
|
||||||
delegate :channel, to: :webhook
|
delegate :channel, to: :webhook
|
||||||
|
|
||||||
def attachments
|
|
||||||
[{
|
|
||||||
title: attachment_title,
|
|
||||||
text: attachment_text,
|
|
||||||
fields: attachment_fields,
|
|
||||||
fallback: attachment_fallback
|
|
||||||
}]
|
|
||||||
end
|
|
||||||
|
|
||||||
alias_method :read_attribute_for_serialization, :send
|
alias_method :read_attribute_for_serialization, :send
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# def motion_vote_field
|
|
||||||
# {
|
|
||||||
# title: "Vote on this proposal",
|
|
||||||
# value: "#{proposal_link(eventable, "yes")} · " +
|
|
||||||
# "#{proposal_link(eventable, "abstain")} · " +
|
|
||||||
# "#{proposal_link(eventable, "no")} · " +
|
|
||||||
# "#{proposal_link(eventable, "block")}"
|
|
||||||
# }
|
|
||||||
# end
|
|
||||||
|
|
||||||
def view_map_on_metamaps(text = nil)
|
def view_map_on_metamaps(text = nil)
|
||||||
"<#{map_url(event.map)}|#{text || event.map.name}>"
|
"<#{map_url(event.map)}|#{text || event.map.name}>"
|
||||||
end
|
end
|
||||||
|
|
||||||
# def view_discussion_on_loomio(params = {})
|
|
||||||
# { value: discussion_link(I18n.t(:"webhooks.slack.view_it_on_loomio"), params) }
|
|
||||||
# end
|
|
||||||
|
|
||||||
# def proposal_link(proposal, position = nil)
|
|
||||||
# discussion_link position || proposal.name, { proposal: proposal.key, position: position }
|
|
||||||
# end
|
|
||||||
|
|
||||||
# def discussion_link(text = nil, params = {})
|
|
||||||
# "<#{discussion_url(eventable.map, params)}|#{text || eventable.discussion.title}>"
|
|
||||||
# end
|
|
||||||
|
|
||||||
def eventable
|
def eventable
|
||||||
@eventable ||= event.eventable
|
@eventable ||= event.eventable
|
||||||
end
|
end
|
||||||
|
@ -63,12 +32,3 @@ Webhooks::Slack::Base = Struct.new(:webhook, :event) do
|
||||||
@author ||= eventable.author
|
@author ||= eventable.author
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# webhooks:
|
|
||||||
# slack:
|
|
||||||
# motion_closed: "*%{name}* has closed"
|
|
||||||
# motion_closing_soon: "*%{name}* has a proposal closing in 24 hours"
|
|
||||||
# motion_outcome_created: "*%{author}* published an outcome in *%{name}*"
|
|
||||||
# motion_outcome_updated: "*%{author}* updated the outcome for *%{name}*"
|
|
||||||
# new_motion: "*%{author}* started a new proposal in *%{name}*"
|
|
||||||
# view_it_on_loomio: "View it on Loomio"
|
|
||||||
|
|
|
@ -3,24 +3,4 @@ class Webhooks::Slack::ConversationStartedOnMap < Webhooks::Slack::Base
|
||||||
def text
|
def text
|
||||||
"There is a live conversation starting on map *#{event.map.name}*. #{view_map_on_metamaps('Join in!')}"
|
"There is a live conversation starting on map *#{event.map.name}*. #{view_map_on_metamaps('Join in!')}"
|
||||||
end
|
end
|
||||||
# TODO: it would be sweet if it sends it with the metacode as the icon_url
|
|
||||||
|
|
||||||
def attachment_fallback
|
|
||||||
'' # {}"*#{eventable.name}*\n#{eventable.description}\n"
|
|
||||||
end
|
|
||||||
|
|
||||||
def attachment_title
|
|
||||||
'' # proposal_link(eventable)
|
|
||||||
end
|
|
||||||
|
|
||||||
def attachment_text
|
|
||||||
'' # "#{eventable.description}\n"
|
|
||||||
end
|
|
||||||
|
|
||||||
def attachment_fields
|
|
||||||
[{
|
|
||||||
title: 'nothing',
|
|
||||||
value: 'nothing'
|
|
||||||
}] # [motion_vote_field]
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,25 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
class Webhooks::Slack::SynapseAddedToMap < Webhooks::Slack::Base
|
class Webhooks::Slack::SynapseAddedToMap < Webhooks::Slack::Base
|
||||||
def text
|
def text
|
||||||
"\"*#{eventable.mappable.topic1.name}* #{eventable.mappable.desc || '->'} *#{eventable.mappable.topic2.name}*\" was added as a connection to the map *#{view_map_on_metamaps}*"
|
connector = eventable.desc.empty? ? '->' : eventable.desc
|
||||||
end
|
"\"*#{eventable.topic1.name}* #{connector} *#{eventable.topic2.name}*\" was added as a connection by *#{event.user.name}* to the map *#{view_map_on_metamaps}*"
|
||||||
|
|
||||||
def attachment_fallback
|
|
||||||
'' # {}"*#{eventable.name}*\n#{eventable.description}\n"
|
|
||||||
end
|
|
||||||
|
|
||||||
def attachment_title
|
|
||||||
'' # proposal_link(eventable)
|
|
||||||
end
|
|
||||||
|
|
||||||
def attachment_text
|
|
||||||
'' # "#{eventable.description}\n"
|
|
||||||
end
|
|
||||||
|
|
||||||
def attachment_fields
|
|
||||||
[{
|
|
||||||
title: 'nothing',
|
|
||||||
value: 'nothing'
|
|
||||||
}] # [motion_vote_field]
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
8
app/models/webhooks/slack/synapse_removed_from_map.rb
Normal file
8
app/models/webhooks/slack/synapse_removed_from_map.rb
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
class Webhooks::Slack::SynapseRemovedFromMap < Webhooks::Slack::Base
|
||||||
|
def text
|
||||||
|
connector = eventable.desc.empty? ? '->' : eventable.desc
|
||||||
|
# todo express correct directionality of arrows when desc is empty
|
||||||
|
"\"*#{eventable.topic1.name}* #{connector} *#{eventable.topic2.name}*\" was removed by *#{event.user.name}* as a connection from the map *#{view_map_on_metamaps}*"
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,26 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
class Webhooks::Slack::TopicAddedToMap < Webhooks::Slack::Base
|
class Webhooks::Slack::TopicAddedToMap < Webhooks::Slack::Base
|
||||||
def text
|
def text
|
||||||
"New #{eventable.mappable.metacode.name} topic *#{eventable.mappable.name}* was added to the map *#{view_map_on_metamaps}*"
|
"*#{eventable.name}* was added by *#{event.user.name}* to the map *#{view_map_on_metamaps}*"
|
||||||
end
|
end
|
||||||
# TODO: it would be sweet if it sends it with the metacode as the icon_url
|
# TODO: it would be sweet if it sends it with the metacode as the icon_url
|
||||||
|
|
||||||
def attachment_fallback
|
|
||||||
'' # {}"*#{eventable.name}*\n#{eventable.description}\n"
|
|
||||||
end
|
|
||||||
|
|
||||||
def attachment_title
|
|
||||||
'' # proposal_link(eventable)
|
|
||||||
end
|
|
||||||
|
|
||||||
def attachment_text
|
|
||||||
'' # "#{eventable.description}\n"
|
|
||||||
end
|
|
||||||
|
|
||||||
def attachment_fields
|
|
||||||
[{
|
|
||||||
title: 'nothing',
|
|
||||||
value: 'nothing'
|
|
||||||
}] # [motion_vote_field]
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
6
app/models/webhooks/slack/topic_moved_on_map.rb
Normal file
6
app/models/webhooks/slack/topic_moved_on_map.rb
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
class Webhooks::Slack::TopicMovedOnMap < Webhooks::Slack::Base
|
||||||
|
def text
|
||||||
|
"*#{eventable.name}* was moved by *#{event.user.name}* on the map *#{view_map_on_metamaps}*"
|
||||||
|
end
|
||||||
|
end
|
6
app/models/webhooks/slack/topic_removed_from_map.rb
Normal file
6
app/models/webhooks/slack/topic_removed_from_map.rb
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
class Webhooks::Slack::TopicRemovedFromMap < Webhooks::Slack::Base
|
||||||
|
def text
|
||||||
|
"*#{eventable.name}* was removed by *#{event.user.name}* from the map *#{view_map_on_metamaps}*"
|
||||||
|
end
|
||||||
|
end
|
|
@ -3,24 +3,4 @@ class Webhooks::Slack::UserPresentOnMap < Webhooks::Slack::Base
|
||||||
def text
|
def text
|
||||||
"Mapper *#{event.user.name}* has joined the map *#{event.map.name}*. #{view_map_on_metamaps('Map with them')}"
|
"Mapper *#{event.user.name}* has joined the map *#{event.map.name}*. #{view_map_on_metamaps('Map with them')}"
|
||||||
end
|
end
|
||||||
# TODO: it would be sweet if it sends it with the metacode as the icon_url
|
|
||||||
|
|
||||||
def attachment_fallback
|
|
||||||
'' # {}"*#{eventable.name}*\n#{eventable.description}\n"
|
|
||||||
end
|
|
||||||
|
|
||||||
def attachment_title
|
|
||||||
'' # proposal_link(eventable)
|
|
||||||
end
|
|
||||||
|
|
||||||
def attachment_text
|
|
||||||
'' # "#{eventable.description}\n"
|
|
||||||
end
|
|
||||||
|
|
||||||
def attachment_fields
|
|
||||||
[{
|
|
||||||
title: 'nothing',
|
|
||||||
value: 'nothing'
|
|
||||||
}] # [motion_vote_field]
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -14,6 +14,7 @@ module Api
|
||||||
def self.embeddable
|
def self.embeddable
|
||||||
{
|
{
|
||||||
user: {},
|
user: {},
|
||||||
|
updated_by: {},
|
||||||
map: {}
|
map: {}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
class WebhookSerializer < ActiveModel::Serializer
|
class WebhookSerializer < ActiveModel::Serializer
|
||||||
attributes :text, :username, :icon_url # , :attachments
|
attributes :text, :username, :icon_url
|
||||||
attribute :channel, if: :has_channel?
|
attribute :channel, if: :has_channel?
|
||||||
|
|
||||||
def has_channel?
|
def has_channel?
|
||||||
|
|
5
db/migrate/20161214140124_add_meta_to_events.rb
Normal file
5
db/migrate/20161214140124_add_meta_to_events.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
class AddMetaToEvents < ActiveRecord::Migration[5.0]
|
||||||
|
def change
|
||||||
|
add_column :events, :meta, :json
|
||||||
|
end
|
||||||
|
end
|
5
db/migrate/20161216174257_add_updated_by_to_mappings.rb
Normal file
5
db/migrate/20161216174257_add_updated_by_to_mappings.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
class AddUpdatedByToMappings < ActiveRecord::Migration[5.0]
|
||||||
|
def change
|
||||||
|
add_reference :mappings, :updated_by, foreign_key: {to_table: :users}
|
||||||
|
end
|
||||||
|
end
|
|
@ -10,7 +10,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 20161125175229) do
|
ActiveRecord::Schema.define(version: 20161216174257) do
|
||||||
|
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
enable_extension "plpgsql"
|
||||||
|
@ -49,6 +49,7 @@ ActiveRecord::Schema.define(version: 20161125175229) do
|
||||||
t.integer "map_id"
|
t.integer "map_id"
|
||||||
t.datetime "created_at"
|
t.datetime "created_at"
|
||||||
t.datetime "updated_at"
|
t.datetime "updated_at"
|
||||||
|
t.json "meta"
|
||||||
t.index ["eventable_type", "eventable_id"], name: "index_events_on_eventable_type_and_eventable_id", using: :btree
|
t.index ["eventable_type", "eventable_id"], name: "index_events_on_eventable_type_and_eventable_id", using: :btree
|
||||||
t.index ["map_id"], name: "index_events_on_map_id", using: :btree
|
t.index ["map_id"], name: "index_events_on_map_id", using: :btree
|
||||||
t.index ["user_id"], name: "index_events_on_user_id", using: :btree
|
t.index ["user_id"], name: "index_events_on_user_id", using: :btree
|
||||||
|
@ -128,10 +129,12 @@ ActiveRecord::Schema.define(version: 20161125175229) do
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", null: false
|
||||||
t.integer "mappable_id"
|
t.integer "mappable_id"
|
||||||
t.string "mappable_type"
|
t.string "mappable_type"
|
||||||
|
t.integer "updated_by_id"
|
||||||
t.index ["map_id", "synapse_id"], name: "index_mappings_on_map_id_and_synapse_id", using: :btree
|
t.index ["map_id", "synapse_id"], name: "index_mappings_on_map_id_and_synapse_id", using: :btree
|
||||||
t.index ["map_id", "topic_id"], name: "index_mappings_on_map_id_and_topic_id", using: :btree
|
t.index ["map_id", "topic_id"], name: "index_mappings_on_map_id_and_topic_id", using: :btree
|
||||||
t.index ["map_id"], name: "index_mappings_on_map_id", using: :btree
|
t.index ["map_id"], name: "index_mappings_on_map_id", using: :btree
|
||||||
t.index ["mappable_id", "mappable_type"], name: "index_mappings_on_mappable_id_and_mappable_type", using: :btree
|
t.index ["mappable_id", "mappable_type"], name: "index_mappings_on_mappable_id_and_mappable_type", using: :btree
|
||||||
|
t.index ["updated_by_id"], name: "index_mappings_on_updated_by_id", using: :btree
|
||||||
t.index ["user_id"], name: "index_mappings_on_user_id", using: :btree
|
t.index ["user_id"], name: "index_mappings_on_user_id", using: :btree
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -336,5 +339,6 @@ ActiveRecord::Schema.define(version: 20161125175229) do
|
||||||
add_foreign_key "mailboxer_conversation_opt_outs", "mailboxer_conversations", column: "conversation_id", name: "mb_opt_outs_on_conversations_id"
|
add_foreign_key "mailboxer_conversation_opt_outs", "mailboxer_conversations", column: "conversation_id", name: "mb_opt_outs_on_conversations_id"
|
||||||
add_foreign_key "mailboxer_notifications", "mailboxer_conversations", column: "conversation_id", name: "notifications_on_conversation_id"
|
add_foreign_key "mailboxer_notifications", "mailboxer_conversations", column: "conversation_id", name: "notifications_on_conversation_id"
|
||||||
add_foreign_key "mailboxer_receipts", "mailboxer_notifications", column: "notification_id", name: "receipts_on_notification_id"
|
add_foreign_key "mailboxer_receipts", "mailboxer_notifications", column: "notification_id", name: "receipts_on_notification_id"
|
||||||
|
add_foreign_key "mappings", "users", column: "updated_by_id"
|
||||||
add_foreign_key "tokens", "users"
|
add_foreign_key "tokens", "users"
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#type: collection
|
#type: collection
|
||||||
get:
|
get:
|
||||||
is: [ embeddable: { embedFields: "user,map" }, orderable, pageable ]
|
is: [ embeddable: { embedFields: "user,updated_by,map" }, orderable, pageable ]
|
||||||
securedBy: [ null, token, oauth_2_0, cookie ]
|
securedBy: [ null, token, oauth_2_0, cookie ]
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
|
@ -31,7 +31,7 @@ post:
|
||||||
/{id}:
|
/{id}:
|
||||||
#type: item
|
#type: item
|
||||||
get:
|
get:
|
||||||
is: [ embeddable: { embedFields: "user,map" } ]
|
is: [ embeddable: { embedFields: "user,updated_by,map" } ]
|
||||||
securedBy: [ null, token, oauth_2_0, cookie ]
|
securedBy: [ null, token, oauth_2_0, cookie ]
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
"mappable_id": 1,
|
"mappable_id": 1,
|
||||||
"mappable_type": "Synapse",
|
"mappable_type": "Synapse",
|
||||||
"user_id": 1,
|
"user_id": 1,
|
||||||
|
"updated_by_id": 1,
|
||||||
"map_id": 1
|
"map_id": 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
"mappable_type": "Topic",
|
"mappable_type": "Topic",
|
||||||
"updated_at": "2016-03-25T08:44:07.152Z",
|
"updated_at": "2016-03-25T08:44:07.152Z",
|
||||||
"user_id": 1,
|
"user_id": 1,
|
||||||
|
"updated_by_id": 1,
|
||||||
"xloc": -271,
|
"xloc": -271,
|
||||||
"yloc": 22
|
"yloc": 22
|
||||||
},
|
},
|
||||||
|
@ -19,6 +20,7 @@
|
||||||
"mappable_type": "Topic",
|
"mappable_type": "Topic",
|
||||||
"updated_at": "2016-03-25T08:44:13.907Z",
|
"updated_at": "2016-03-25T08:44:13.907Z",
|
||||||
"user_id": 1,
|
"user_id": 1,
|
||||||
|
"updated_by_id": 1,
|
||||||
"xloc": -12,
|
"xloc": -12,
|
||||||
"yloc": 61
|
"yloc": 61
|
||||||
},
|
},
|
||||||
|
@ -30,6 +32,7 @@
|
||||||
"mappable_type": "Topic",
|
"mappable_type": "Topic",
|
||||||
"updated_at": "2016-03-25T08:44:19.333Z",
|
"updated_at": "2016-03-25T08:44:19.333Z",
|
||||||
"user_id": 1,
|
"user_id": 1,
|
||||||
|
"updated_by_id": 1,
|
||||||
"xloc": -93,
|
"xloc": -93,
|
||||||
"yloc": -90
|
"yloc": -90
|
||||||
},
|
},
|
||||||
|
@ -40,7 +43,8 @@
|
||||||
"mappable_id": 1,
|
"mappable_id": 1,
|
||||||
"mappable_type": "Synapse",
|
"mappable_type": "Synapse",
|
||||||
"updated_at": "2016-03-25T08:44:21.337Z",
|
"updated_at": "2016-03-25T08:44:21.337Z",
|
||||||
"user_id": 1
|
"user_id": 1,
|
||||||
|
"updated_by_id": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"page": {
|
"page": {
|
||||||
|
|
|
@ -35,6 +35,12 @@
|
||||||
},
|
},
|
||||||
"user": {
|
"user": {
|
||||||
"$ref": "_user.json"
|
"$ref": "_user.json"
|
||||||
|
},
|
||||||
|
"updated_by_id": {
|
||||||
|
"$ref": "_id.json"
|
||||||
|
},
|
||||||
|
"updated_by": {
|
||||||
|
"$ref": "_user.json"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
|
@ -56,6 +62,12 @@
|
||||||
{ "required": [ "user_id" ] },
|
{ "required": [ "user_id" ] },
|
||||||
{ "required": [ "user" ] }
|
{ "required": [ "user" ] }
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"oneOf": [
|
||||||
|
{ "required": [ "updated_by_id" ] },
|
||||||
|
{ "required": [ "updated_by" ] }
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue