From 8fc477ab07d58e8667907582e80c83f2be310cb2 Mon Sep 17 00:00:00 2001 From: Robin Ward Date: Wed, 28 Jan 2015 11:01:01 -0500 Subject: [PATCH] More refactoring to support extensibility of history --- .../discourse/components/disabled-icon.js.es6 | 4 ++ .../discourse/controllers/history.js.es6 | 19 ++----- .../discourse/helpers/fa-icon.js.es6 | 18 ++++-- .../javascripts/discourse/models/_post.js | 2 +- .../templates/components/disabled-icon.hbs | 5 ++ .../discourse/templates/modal/history.hbs | 11 ++-- app/controllers/posts_controller.rb | 2 +- app/controllers/topics_controller.rb | 2 +- app/serializers/post_revision_serializer.rb | 30 ++++++---- app/serializers/topic_view_serializer.rb | 56 +++++++++---------- lib/post_revisor.rb | 42 ++++++++------ 11 files changed, 105 insertions(+), 86 deletions(-) create mode 100644 app/assets/javascripts/discourse/components/disabled-icon.js.es6 create mode 100644 app/assets/javascripts/discourse/templates/components/disabled-icon.hbs diff --git a/app/assets/javascripts/discourse/components/disabled-icon.js.es6 b/app/assets/javascripts/discourse/components/disabled-icon.js.es6 new file mode 100644 index 00000000000..abcd8e72796 --- /dev/null +++ b/app/assets/javascripts/discourse/components/disabled-icon.js.es6 @@ -0,0 +1,4 @@ +export default Ember.Component.extend({ + tagName: 'span', + classNameBindings: [':fa-stack'], +}); diff --git a/app/assets/javascripts/discourse/controllers/history.js.es6 b/app/assets/javascripts/discourse/controllers/history.js.es6 index a69da38ddc0..e3603089e90 100644 --- a/app/assets/javascripts/discourse/controllers/history.js.es6 +++ b/app/assets/javascripts/discourse/controllers/history.js.es6 @@ -81,23 +81,14 @@ export default ObjectController.extend(ModalFunctionality, { } }.property("category_id_changes"), - wikiDiff: function() { + wikiDisabled: function() { var changes = this.get("wiki_changes"); - if (changes) { - return changes["current"] ? - '' : - ''; - } - }.property("wiki_changes"), + return changes && !changes['current']; + }.property('wiki_changes'), - postTypeDiff: function () { - var moderator = Discourse.Site.currentProp('post_types.moderator_action'); + postTypeDisabled: function () { var changes = this.get("post_type_changes"); - if (changes) { - return changes["current"] === moderator ? - '' : - ''; - } + return (changes && changes['current'] !== this.site.get('post_types.moderator_action')); }.property("post_type_changes"), titleDiff: function() { diff --git a/app/assets/javascripts/discourse/helpers/fa-icon.js.es6 b/app/assets/javascripts/discourse/helpers/fa-icon.js.es6 index 73d8b0d0684..cce1f3aa8b1 100644 --- a/app/assets/javascripts/discourse/helpers/fa-icon.js.es6 +++ b/app/assets/javascripts/discourse/helpers/fa-icon.js.es6 @@ -1,5 +1,13 @@ -export function iconHTML(icon, label) { - var html = " - {{{wikiDiff}}} + {{disabled-icon icon="pencil-square-o" secondary=wikiDisabled}} {{/if}} {{#if post_type_changes}}
- {{{postTypeDiff}}} + {{disabled-icon icon="shield" disabled=postTypeDisabled}}
{{/if}} {{#if category_id_changes}} @@ -79,6 +79,9 @@ {{/if}} {{/if}} + + {{plugin-outlet "post-revisions"}} +
{{{bodyDiff}}}
diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index aef950324f4..a395b98fb13 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -414,7 +414,7 @@ class PostsController < ApplicationController result[:is_warning] = (params[:is_warning] == "true") end - PostRevisor.tracked_fields.keys.each do |f| + PostRevisor.tracked_topic_fields.keys.each do |f| params.permit(f => []) result[f] = params[f] if params.has_key?(f) end diff --git a/app/controllers/topics_controller.rb b/app/controllers/topics_controller.rb index b9cdbf92233..c2f9be7c658 100644 --- a/app/controllers/topics_controller.rb +++ b/app/controllers/topics_controller.rb @@ -126,7 +126,7 @@ class TopicsController < ApplicationController guardian.ensure_can_edit!(topic) changes = {} - PostRevisor.tracked_fields.keys.each do |f| + PostRevisor.tracked_topic_fields.keys.each do |f| changes[f] = params[f] if params.has_key?(f) end diff --git a/app/serializers/post_revision_serializer.rb b/app/serializers/post_revision_serializer.rb index 1d24b6630d8..fceac5e35c5 100644 --- a/app/serializers/post_revision_serializer.rb +++ b/app/serializers/post_revision_serializer.rb @@ -40,9 +40,7 @@ class PostRevisionSerializer < ApplicationSerializer end end - add_compared_field :category_id add_compared_field :wiki - add_compared_field :post_type def previous_hidden previous["hidden"] @@ -167,19 +165,27 @@ class PostRevisionSerializer < ApplicationSerializer return @all_revisions if @all_revisions post_revisions = PostRevision.where(post_id: object.post_id).order(:number).to_a + + latest_modifications = { + "raw" => [post.raw], + "cooked" => [post.cooked], + "edit_reason" => [post.edit_reason], + "wiki" => [post.wiki], + "post_type" => [post.post_type], + "user_id" => [post.user_id] + } + + # For the topic fields, let's get the values from a serializer + PostRevisor.tracked_topic_fields.keys.each do |field| + if topic.respond_to?(field) + latest_modifications[field.to_s] = [topic.send(field)] + end + end + post_revisions << PostRevision.new( number: post_revisions.last.number + 1, hidden: post.hidden, - modifications: { - "raw" => [post.raw], - "cooked" => [post.cooked], - "edit_reason" => [post.edit_reason], - "wiki" => [post.wiki], - "post_type" => [post.post_type], - "user_id" => [post.user_id], - "title" => [topic.title], - "category_id" => [topic.category_id], - } + modifications: latest_modifications ) @all_revisions = [] diff --git a/app/serializers/topic_view_serializer.rb b/app/serializers/topic_view_serializer.rb index d0fc7f281a1..eec7b2c447a 100644 --- a/app/serializers/topic_view_serializer.rb +++ b/app/serializers/topic_view_serializer.rb @@ -3,29 +3,35 @@ require_dependency 'pinned_check' class TopicViewSerializer < ApplicationSerializer include PostStreamSerializerMixin - # These attributes will be delegated to the topic - def self.topic_attributes - [:id, - :title, - :fancy_title, - :posts_count, - :created_at, - :views, - :reply_count, - :participant_count, - :like_count, - :last_posted_at, - :visible, - :closed, - :archived, - :has_summary, - :archetype, - :slug, - :category_id, - :word_count, - :deleted_at] + def self.attributes_from_topic(*list) + [list].flatten.each do |attribute| + attributes(attribute) + class_eval %{def #{attribute} + object.topic.#{attribute} + end} + end end + attributes_from_topic :id, + :title, + :fancy_title, + :posts_count, + :created_at, + :views, + :reply_count, + :participant_count, + :like_count, + :last_posted_at, + :visible, + :closed, + :archived, + :has_summary, + :archetype, + :slug, + :category_id, + :word_count, + :deleted_at + attributes :draft, :draft_key, :draft_sequence, @@ -45,14 +51,6 @@ class TopicViewSerializer < ApplicationSerializer :chunk_size, :bookmarked - # Define a delegator for each attribute of the topic we want - attributes(*topic_attributes) - topic_attributes.each do |ta| - class_eval %{def #{ta} - object.topic.#{ta} - end} - end - # TODO: Split off into proper object / serializer def details result = { diff --git a/lib/post_revisor.rb b/lib/post_revisor.rb index 594162853fd..c445668e760 100644 --- a/lib/post_revisor.rb +++ b/lib/post_revisor.rb @@ -4,7 +4,7 @@ class PostRevisor # Helps us track changes to a topic. # - # It's passed to `Topic.track_field` callbacks so they can record if they + # It's passed to `track_topic_fields` callbacks so they can record if they # changed a value or not. This is needed for things like custom fields. class TopicChanges attr_reader :topic, :user @@ -47,13 +47,29 @@ class PostRevisor @topic = topic || post.topic end - def self.tracked_fields - @@tracked_fields ||= {} - @@tracked_fields + def self.tracked_topic_fields + @@tracked_topic_fields ||= {} + @@tracked_topic_fields end - def self.track_field(field, &block) - tracked_fields[field] = block + def self.track_topic_field(field, &block) + tracked_topic_fields[field] = block + + # Define it in the serializer unless it already has been defined + unless PostRevisionSerializer.instance_methods(false).include?("#{field}_changes".to_sym) + PostRevisionSerializer.add_compared_field(field) + end + end + + # Fields we want to record revisions for by default + track_topic_field(:title) do |tc, title| + tc.record_change('title', tc.topic.title, title) + tc.topic.title = title + end + + track_topic_field(:category_id) do |tc, category_id| + tc.record_change('category_id', tc.topic.category_id, category_id) + tc.check_result(tc.topic.change_category_to_id(category_id)) end # AVAILABLE OPTIONS: @@ -139,7 +155,7 @@ class PostRevisor end def topic_changed? - PostRevisor.tracked_fields.keys.any? {|f| @fields.has_key?(f)} + PostRevisor.tracked_topic_fields.keys.any? {|f| @fields.has_key?(f)} end def revise_post @@ -217,7 +233,7 @@ class PostRevisor def update_topic Topic.transaction do - PostRevisor.tracked_fields.each do |f, cb| + PostRevisor.tracked_topic_fields.each do |f, cb| if !@topic_changes.errored? && @fields.has_key?(f) cb.call(@topic_changes, @fields[f]) end @@ -360,13 +376,3 @@ class PostRevisor end -# Fields we want to record revisions for by default -PostRevisor.track_field(:title) do |tc, title| - tc.record_change('title', tc.topic.title, title) - tc.topic.title = title -end - -PostRevisor.track_field(:category_id) do |tc, category_id| - tc.record_change('category_id', tc.topic.category_id, category_id) - tc.check_result(tc.topic.change_category_to_id(category_id)) -end