FIX: Use a default hashtag icon color for user with no permission (#21825)
One user can create a post or chat message with a hashtag they have permission to use, but then when other users look at that post they will see an empty space next to the hashtag because they do not have the permission to load the colors in CSS classes for the related category. This fixes the issue by adding a default color with a special CSS class if the user doesn't have permission to see the linked channel/category on the hashtag.
This commit is contained in:
parent
af74cf5c77
commit
69eecf92d0
|
@ -31,6 +31,10 @@ export default class CategoryHashtagType extends HashtagTypeBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
generateIconHTML(hashtag) {
|
generateIconHTML(hashtag) {
|
||||||
return `<span class="hashtag-category-badge hashtag-color--${this.type}-${hashtag.id}"></span>`;
|
const hashtagId = parseInt(hashtag.id, 10);
|
||||||
|
const colorCssClass = !this.preloadedData.mapBy("id").includes(hashtagId)
|
||||||
|
? "hashtag-missing"
|
||||||
|
: `hashtag-color--${this.type}-${hashtag.id}`;
|
||||||
|
return `<span class="hashtag-category-badge ${colorCssClass}"></span>`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,10 @@ a.hashtag {
|
||||||
.d-icon {
|
.d-icon {
|
||||||
font-size: var(--font-down-1);
|
font-size: var(--font-down-1);
|
||||||
margin: 0 0.2em 0 0.1em;
|
margin: 0 0.2em 0 0.1em;
|
||||||
|
|
||||||
|
&.hashtag-missing {
|
||||||
|
color: var(--primary-medium);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
img.emoji {
|
img.emoji {
|
||||||
|
@ -43,6 +47,10 @@ a.hashtag {
|
||||||
height: 9px;
|
height: 9px;
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
|
||||||
|
&.hashtag-missing {
|
||||||
|
background-color: var(--primary-medium);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,8 +25,12 @@ export default class ChannelHashtagType extends HashtagTypeBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
generateIconHTML(hashtag) {
|
generateIconHTML(hashtag) {
|
||||||
|
const hashtagId = parseInt(hashtag.id, 10);
|
||||||
|
const colorCssClass = !this.preloadedData.mapBy("id").includes(hashtagId)
|
||||||
|
? "hashtag-missing"
|
||||||
|
: `hashtag-color--${this.type}-${hashtag.id}`;
|
||||||
return iconHTML(hashtag.icon, {
|
return iconHTML(hashtag.icon, {
|
||||||
class: `hashtag-color--${this.type}-${hashtag.id}`,
|
class: colorCssClass,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,4 +80,44 @@ describe "Using #hashtag autocompletion to search for and lookup channels",
|
||||||
<a class=\"hashtag-cooked\" href=\"#{tag.url}\" data-type=\"tag\" data-slug=\"razed\" data-id="#{tag.id}"><svg class=\"fa d-icon d-icon-tag svg-icon hashtag-color--tag-#{tag.id} svg-string\" xmlns=\"http://www.w3.org/2000/svg\"><use href=\"#tag\"></use></svg><span>razed</span></a>
|
<a class=\"hashtag-cooked\" href=\"#{tag.url}\" data-type=\"tag\" data-slug=\"razed\" data-id="#{tag.id}"><svg class=\"fa d-icon d-icon-tag svg-icon hashtag-color--tag-#{tag.id} svg-string\" xmlns=\"http://www.w3.org/2000/svg\"><use href=\"#tag\"></use></svg><span>razed</span></a>
|
||||||
HTML
|
HTML
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "when a user cannot access the category for a cooked channel hashtag" do
|
||||||
|
fab!(:admin) { Fabricate(:admin) }
|
||||||
|
fab!(:manager_group) { Fabricate(:group, name: "Managers") }
|
||||||
|
fab!(:private_category) do
|
||||||
|
Fabricate(:private_category, name: "Management", slug: "management", group: manager_group)
|
||||||
|
end
|
||||||
|
fab!(:admin_group_user) { Fabricate(:group_user, user: admin, group: manager_group) }
|
||||||
|
fab!(:management_channel) do
|
||||||
|
Fabricate(:chat_channel, chatable: private_category, slug: "management")
|
||||||
|
end
|
||||||
|
fab!(:post_with_private_category) do
|
||||||
|
Fabricate(
|
||||||
|
:post,
|
||||||
|
topic: topic,
|
||||||
|
raw: "this is a secret #management::channel channel",
|
||||||
|
user: admin,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
fab!(:message_with_private_channel) do
|
||||||
|
Fabricate(
|
||||||
|
:chat_message,
|
||||||
|
chat_channel: channel1,
|
||||||
|
user: admin,
|
||||||
|
message: "this is a secret #management channel",
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
before { management_channel.add(admin) }
|
||||||
|
|
||||||
|
it "shows a default color and css class for the channel icon in a post" do
|
||||||
|
topic_page.visit_topic(topic, post_number: post_with_private_category.post_number)
|
||||||
|
expect(page).to have_css(".hashtag-cooked .hashtag-missing")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "shows a default color and css class for the channel icon in a channel" do
|
||||||
|
chat_page.visit_channel(channel1)
|
||||||
|
expect(page).to have_css(".hashtag-cooked .hashtag-missing")
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -93,4 +93,21 @@ describe "Using #hashtag autocompletion to search for and lookup categories and
|
||||||
<a class=\"hashtag-cooked\" href=\"#{tag.url}\" data-type=\"tag\" data-slug=\"cooltag\" data-id=\"#{tag.id}\"><svg class=\"fa d-icon d-icon-tag svg-icon hashtag-color--tag-#{tag.id} svg-string\" xmlns=\"http://www.w3.org/2000/svg\"><use href=\"#tag\"></use></svg><span>cooltag</span></a>
|
<a class=\"hashtag-cooked\" href=\"#{tag.url}\" data-type=\"tag\" data-slug=\"cooltag\" data-id=\"#{tag.id}\"><svg class=\"fa d-icon d-icon-tag svg-icon hashtag-color--tag-#{tag.id} svg-string\" xmlns=\"http://www.w3.org/2000/svg\"><use href=\"#tag\"></use></svg><span>cooltag</span></a>
|
||||||
HTML
|
HTML
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "when a user cannot access the category for a hashtag cooked in another post" do
|
||||||
|
fab!(:admin) { Fabricate(:admin) }
|
||||||
|
fab!(:manager_group) { Fabricate(:group, name: "Managers") }
|
||||||
|
fab!(:private_category) do
|
||||||
|
Fabricate(:private_category, name: "Management", slug: "management", group: manager_group)
|
||||||
|
end
|
||||||
|
fab!(:admin_group_user) { Fabricate(:group_user, user: admin, group: manager_group) }
|
||||||
|
fab!(:post_with_private_category) do
|
||||||
|
Fabricate(:post, topic: topic, raw: "this is a secret #management category", user: admin)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "shows a default color and css class for the category icon square" do
|
||||||
|
topic_page.visit_topic(topic, post_number: post_with_private_category.post_number)
|
||||||
|
expect(page).to have_css(".hashtag-cooked .hashtag-missing")
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,8 +8,10 @@ module PageObjects
|
||||||
@fast_edit_component = PageObjects::Components::FastEditor.new
|
@fast_edit_component = PageObjects::Components::FastEditor.new
|
||||||
end
|
end
|
||||||
|
|
||||||
def visit_topic(topic)
|
def visit_topic(topic, post_number: nil)
|
||||||
page.visit "/t/#{topic.id}"
|
url = "/t/#{topic.id}"
|
||||||
|
url += "/#{post_number}" if post_number
|
||||||
|
page.visit url
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue