FEATURE: Display error message when category restriction is applied for tags

This commit is contained in:
Vinoth Kannan 2019-01-04 00:29:13 +05:30
parent cb317430a1
commit 385829d7be
7 changed files with 54 additions and 14 deletions

View File

@ -182,6 +182,7 @@ export default ComboBox.extend(TagsMixin, {
let results = json.results; let results = json.results;
context.set("termMatchesForbidden", json.forbidden ? true : false); context.set("termMatchesForbidden", json.forbidden ? true : false);
context.set("termMatchErrorMessage", json.forbidden_message);
if (context.get("siteSettings.tags_sort_alphabetically")) { if (context.get("siteSettings.tags_sort_alphabetically")) {
results = results.sort((a, b) => a.id > b.id); results = results.sort((a, b) => a.id > b.id);

View File

@ -277,7 +277,9 @@ export default Ember.Component.extend(
collectionComputedContent.length === 0 && collectionComputedContent.length === 0 &&
!isLoading !isLoading
) { ) {
return I18n.t("select_kit.no_content"); return (
this.get("termMatchErrorMessage") || I18n.t("select_kit.no_content")
);
} }
}, },

View File

@ -27,6 +27,7 @@ export default MultiSelectComponent.extend(TagsMixin, {
} }
this.set("termMatchesForbidden", false); this.set("termMatchesForbidden", false);
this.set("termMatchErrorMessage", null);
this.set("templateForRow", rowComponent => { this.set("templateForRow", rowComponent => {
const tag = rowComponent.get("computedContent"); const tag = rowComponent.get("computedContent");
@ -117,6 +118,7 @@ export default MultiSelectComponent.extend(TagsMixin, {
let results = json.results; let results = json.results;
context.set("termMatchesForbidden", json.forbidden ? true : false); context.set("termMatchesForbidden", json.forbidden ? true : false);
context.set("termMatchErrorMessage", json.forbidden_message);
if (context.get("blacklist")) { if (context.get("blacklist")) {
results = results.filter(result => { results = results.filter(result => {

View File

@ -125,10 +125,6 @@
align-items: center; align-items: center;
justify-content: flex-start; justify-content: flex-start;
&.no-content {
white-space: nowrap;
}
.name { .name {
margin: 0; margin: 0;
overflow: hidden; overflow: hidden;

View File

@ -210,9 +210,24 @@ class TagsController < ::ApplicationController
json_response = { results: tags } json_response = { results: tags }
if Tag.where_name(clean_name).exists? && !tags.find { |h| h[:id].downcase == clean_name.downcase } if !tags.find { |h| h[:id].downcase == clean_name.downcase } && tag = Tag.where_name(clean_name).first
# filter_allowed_tags determined that the tag entered is not allowed # filter_allowed_tags determined that the tag entered is not allowed
json_response[:forbidden] = params[:q] json_response[:forbidden] = params[:q]
category_names = tag.categories.where(id: guardian.allowed_category_ids).pluck(:name)
category_names += Category.joins(tag_groups: :tags).where(id: guardian.allowed_category_ids, "tags.id": tag.id).pluck(:name)
if category_names.present?
category_names.uniq!
json_response[:forbidden_message] = I18n.t(
"tags.forbidden.restricted_to",
count: category_names.count,
tag_name: tag.name,
category_names: category_names.join(", ")
)
else
json_response[:forbidden_message] = I18n.t("tags.forbidden.in_this_category", tag_name: tag.name)
end
end end
render json: json_response render json: json_response

View File

@ -4052,6 +4052,11 @@ en:
staff_tag_remove_disallowed: "The tag \"%{tag}\" may only be removed by staff." staff_tag_remove_disallowed: "The tag \"%{tag}\" may only be removed by staff."
minimum_required_tags: "You must select at least %{count} tags." minimum_required_tags: "You must select at least %{count} tags."
upload_row_too_long: "The CSV file should have one tag per line. Optionally the tag can be followed by a comma, then the tag group name." upload_row_too_long: "The CSV file should have one tag per line. Optionally the tag can be followed by a comma, then the tag group name."
forbidden:
in_this_category: "\"%{tag_name}\" cannot be used in this category"
restricted_to:
one: "\"%{tag_name}\" is restricted to the \"%{category_names}\" category"
other: "\"%{tag_name}\" is restricted to the following categories: %{category_names}"
rss_by_tag: "Topics tagged %{tag}" rss_by_tag: "Topics tagged %{tag}"
finish_installation: finish_installation:

View File

@ -319,14 +319,33 @@ describe TagsController do
expect(json['results'].map { |j| j['id'] }).to eq(['tag', 'tag2']) expect(json['results'].map { |j| j['id'] }).to eq(['tag', 'tag2'])
end end
context 'with category restriction' do
let(:yup) { Fabricate(:tag, name: 'yup') }
let(:category) { Fabricate(:category, tags: [yup]) }
it "can say if given tag is not allowed" do it "can say if given tag is not allowed" do
yup, nope = Fabricate(:tag, name: 'yup'), Fabricate(:tag, name: 'nope') nope = Fabricate(:tag, name: 'nope')
category = Fabricate(:category, tags: [yup]) get "/tags/filter/search.json", params: { q: nope.name, categoryId: category.id }
get "/tags/filter/search.json", params: { q: 'nope', categoryId: category.id }
expect(response.status).to eq(200) expect(response.status).to eq(200)
json = ::JSON.parse(response.body) json = ::JSON.parse(response.body)
expect(json["results"].map { |j| j["id"] }.sort).to eq([]) expect(json["results"].map { |j| j["id"] }.sort).to eq([])
expect(json["forbidden"]).to be_present expect(json["forbidden"]).to be_present
expect(json["forbidden_message"]).to eq(I18n.t("tags.forbidden.in_this_category", tag_name: nope.name))
end
it "can say if given tag is restricted to different category" do
category
get "/tags/filter/search.json", params: { q: yup.name, categoryId: Fabricate(:category).id }
json = ::JSON.parse(response.body)
expect(json["results"].map { |j| j["id"] }.sort).to eq([])
expect(json["forbidden"]).to be_present
expect(json["forbidden_message"]).to eq(I18n.t(
"tags.forbidden.restricted_to",
count: 1,
tag_name: yup.name,
category_names: category.name
))
end
end end
it "matches tags after sanitizing input" do it "matches tags after sanitizing input" do