diff --git a/app/assets/javascripts/admin/components/permalink-form.js b/app/assets/javascripts/admin/components/permalink-form.js index 0a15f51f572..81e9346d6fc 100644 --- a/app/assets/javascripts/admin/components/permalink-form.js +++ b/app/assets/javascripts/admin/components/permalink-form.js @@ -17,6 +17,7 @@ export default Component.extend({ { id: "topic_id", name: I18n.t("admin.permalink.topic_id") }, { id: "post_id", name: I18n.t("admin.permalink.post_id") }, { id: "category_id", name: I18n.t("admin.permalink.category_id") }, + { id: "tag_name", name: I18n.t("admin.permalink.tag_name") }, { id: "external_url", name: I18n.t("admin.permalink.external_url") } ]; }, diff --git a/app/assets/javascripts/admin/templates/permalinks.hbs b/app/assets/javascripts/admin/templates/permalinks.hbs index dcfca2a9187..1424e530b9c 100644 --- a/app/assets/javascripts/admin/templates/permalinks.hbs +++ b/app/assets/javascripts/admin/templates/permalinks.hbs @@ -32,6 +32,9 @@ {{#if pl.category_id}} {{category-link pl.category}} {{/if}} + {{#if pl.tag_id}} + {{pl.tag_name}} + {{/if}} {{#if pl.external_url}} {{#if pl.linkIsExternal}} {{d-icon "external-link-alt"}} diff --git a/app/controllers/admin/permalinks_controller.rb b/app/controllers/admin/permalinks_controller.rb index 4b042490597..4e60a1ad010 100644 --- a/app/controllers/admin/permalinks_controller.rb +++ b/app/controllers/admin/permalinks_controller.rb @@ -15,6 +15,11 @@ class Admin::PermalinksController < Admin::AdminController params.require(:permalink_type) params.require(:permalink_type_value) + if params[:permalink_type] == "tag_name" + params[:permalink_type] = "tag_id" + params[:permalink_type_value] = Tag.find_by_name(params[:permalink_type_value])&.id + end + permalink = Permalink.new(:url => params[:url], params[:permalink_type] => params[:permalink_type_value]) if permalink.save render_serialized(permalink, PermalinkSerializer) diff --git a/app/models/permalink.rb b/app/models/permalink.rb index 925f640f7e0..9e1e2d1a4e2 100644 --- a/app/models/permalink.rb +++ b/app/models/permalink.rb @@ -4,6 +4,7 @@ class Permalink < ActiveRecord::Base belongs_to :topic belongs_to :post belongs_to :category + belongs_to :tag before_validation :normalize_url @@ -80,12 +81,13 @@ class Permalink < ActiveRecord::Base return "#{Discourse::base_uri}#{post.url}" if post return topic.relative_url if topic return "#{category.url}/#{category.id}" if category + return tag.full_url if tag nil end def self.filter_by(url = nil) permalinks = Permalink - .includes(:topic, :post, :category) + .includes(:topic, :post, :category, :tag) .order('permalinks.created_at desc') permalinks.where!('url ILIKE :url OR external_url ILIKE :url', url: "%#{url}%") if url.present? @@ -106,6 +108,7 @@ end # created_at :datetime not null # updated_at :datetime not null # external_url :string(1000) +# tag_id :integer # # Indexes # diff --git a/app/serializers/permalink_serializer.rb b/app/serializers/permalink_serializer.rb index 89189100c44..78b46fd9a76 100644 --- a/app/serializers/permalink_serializer.rb +++ b/app/serializers/permalink_serializer.rb @@ -3,7 +3,8 @@ class PermalinkSerializer < ApplicationSerializer attributes :id, :url, :topic_id, :topic_title, :topic_url, :post_id, :post_url, :post_number, :post_topic_title, - :category_id, :category_name, :category_url, :external_url + :category_id, :category_name, :category_url, :external_url, + :tag_id, :tag_name, :tag_url def topic_title object&.topic&.title @@ -33,4 +34,12 @@ class PermalinkSerializer < ApplicationSerializer def category_url object&.category&.url end + + def tag_name + object&.tag&.name + end + + def tag_url + object&.tag&.full_url + end end diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 673cb435240..a8ff521a7a2 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -336,7 +336,7 @@ en: tomorrow_with_time: "tomorrow at %{time}" at_time: "at %{date_time}" existing_reminder: "You have a reminder set for this bookmark which will be sent" - + copy_codeblock: copied: "copied!" @@ -4715,6 +4715,7 @@ en: post_title: "Post" category_id: "Category ID" category_title: "Category" + tag_name: "Tag name" external_url: "External URL" destination: "Destination" delete_confirm: Are you sure you want to delete this permalink? diff --git a/db/migrate/20200522204356_add_tag_to_permalink.rb b/db/migrate/20200522204356_add_tag_to_permalink.rb new file mode 100644 index 00000000000..d48a3d7fdf5 --- /dev/null +++ b/db/migrate/20200522204356_add_tag_to_permalink.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class AddTagToPermalink < ActiveRecord::Migration[6.0] + def change + add_column :permalinks, :tag_id, :integer + end +end diff --git a/spec/models/permalink_spec.rb b/spec/models/permalink_spec.rb index 8cd9d30a46a..869d38fba5f 100644 --- a/spec/models/permalink_spec.rb +++ b/spec/models/permalink_spec.rb @@ -32,6 +32,7 @@ describe Permalink do let(:topic) { Fabricate(:topic) } let(:post) { Fabricate(:post, topic: topic) } let(:category) { Fabricate(:category) } + let(:tag) { Fabricate(:tag) } subject(:target_url) { permalink.target_url } it "returns a topic url when topic_id is set" do @@ -77,6 +78,24 @@ describe Permalink do expect(target_url).to eq(post.url) end + it "returns a tag url when tag_id is set" do + permalink.tag_id = tag.id + expect(target_url).to eq(tag.full_url) + end + + it "returns nil when tag_id is set but tag is not found" do + permalink.tag_id = 99999 + expect(target_url).to eq(nil) + end + + it "returns a post url when topic_id, post_id, category_id and tag_id are all set for some reason" do + permalink.post_id = post.id + permalink.topic_id = topic.id + permalink.category_id = category.id + permalink.tag_id = tag.id + expect(target_url).to eq(post.url) + end + it "returns nil when nothing is set" do expect(target_url).to eq(nil) end diff --git a/spec/requests/admin/permalinks_controller_spec.rb b/spec/requests/admin/permalinks_controller_spec.rb index a84a0b2935c..ad3344b27a7 100644 --- a/spec/requests/admin/permalinks_controller_spec.rb +++ b/spec/requests/admin/permalinks_controller_spec.rb @@ -54,4 +54,58 @@ describe Admin::PermalinksController do expect(result.length).to eq(3) end end + + describe "#create" do + it "works for topics" do + topic = Fabricate(:topic) + + post "/admin/permalinks.json", params: { + url: "/topics/771", + permalink_type: "topic_id", + permalink_type_value: topic.id + } + + expect(response.status).to eq(200) + expect(Permalink.last).to have_attributes(url: "topics/771", topic_id: topic.id, post_id: nil, category_id: nil, tag_id: nil) + end + + it "works for posts" do + some_post = Fabricate(:post) + + post "/admin/permalinks.json", params: { + url: "/topics/771/8291", + permalink_type: "post_id", + permalink_type_value: some_post.id + } + + expect(response.status).to eq(200) + expect(Permalink.last).to have_attributes(url: "topics/771/8291", topic_id: nil, post_id: some_post.id, category_id: nil, tag_id: nil) + end + + it "works for categories" do + category = Fabricate(:category) + + post "/admin/permalinks.json", params: { + url: "/forums/11", + permalink_type: "category_id", + permalink_type_value: category.id + } + + expect(response.status).to eq(200) + expect(Permalink.last).to have_attributes(url: "forums/11", topic_id: nil, post_id: nil, category_id: category.id, tag_id: nil) + end + + it "works for tags" do + tag = Fabricate(:tag) + + post "/admin/permalinks.json", params: { + url: "/forums/12", + permalink_type: "tag_name", + permalink_type_value: tag.name + } + + expect(response.status).to eq(200) + expect(Permalink.last).to have_attributes(url: "forums/12", topic_id: nil, post_id: nil, category_id: nil, tag_id: tag.id) + end + end end