FEATURE: add category banner for why a user cannot post (#9576)
* FEATURE: add category banner for why a user cannot post Adds a category banner for why a user is unable to post in a category. Also adds an extra alert for the user when a user is unable to create a topic in a category and they still try and click on the disabled-looking new topic button.
This commit is contained in:
parent
03815f9795
commit
2cb9e85d14
|
@ -0,0 +1,11 @@
|
|||
import Component from "@ember/component";
|
||||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
import { and } from "@ember/object/computed";
|
||||
|
||||
export default Component.extend({
|
||||
@discourseComputed
|
||||
user() {
|
||||
return this.currentUser;
|
||||
},
|
||||
shouldShow: and("category.read_only_banner", "readOnly", "user")
|
||||
});
|
|
@ -1,5 +1,6 @@
|
|||
import Component from "@ember/component";
|
||||
export default Component.extend({
|
||||
tagName: "",
|
||||
label: "topic.create"
|
||||
label: "topic.create",
|
||||
btnClass: "btn-default"
|
||||
});
|
||||
|
|
|
@ -15,6 +15,38 @@ export default Component.extend(FilterModeMixin, {
|
|||
return category && this.currentUser;
|
||||
},
|
||||
|
||||
@discourseComputed("category", "createTopicDisabled")
|
||||
categoryReadOnlyBanner(category, createTopicDisabled) {
|
||||
if (category && this.currentUser && createTopicDisabled) {
|
||||
return category.read_only_banner;
|
||||
}
|
||||
},
|
||||
|
||||
@discourseComputed(
|
||||
"createTopicDisabled",
|
||||
"hasDraft",
|
||||
"categoryReadOnlyBanner"
|
||||
)
|
||||
createTopicButtonDisabled(
|
||||
createTopicDisabled,
|
||||
hasDraft,
|
||||
categoryReadOnlyBanner
|
||||
) {
|
||||
if (categoryReadOnlyBanner && !hasDraft) {
|
||||
return false;
|
||||
}
|
||||
return createTopicDisabled;
|
||||
},
|
||||
|
||||
@discourseComputed("categoryReadOnlyBanner", "hasDraft")
|
||||
createTopicClass(categoryReadOnlyBanner, hasDraft) {
|
||||
if (categoryReadOnlyBanner && !hasDraft) {
|
||||
return "btn-default disabled";
|
||||
} else {
|
||||
return "btn-default";
|
||||
}
|
||||
},
|
||||
|
||||
@discourseComputed()
|
||||
categories() {
|
||||
return this.site.get("categoriesList");
|
||||
|
@ -65,6 +97,14 @@ export default Component.extend(FilterModeMixin, {
|
|||
this.reorderCategories();
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
clickCreateTopicButton() {
|
||||
if (this.categoryReadOnlyBanner && !this.hasDraft) {
|
||||
bootbox.alert(this.categoryReadOnlyBanner);
|
||||
} else {
|
||||
this.createTopic();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -187,7 +187,8 @@ const Category = RestModel.extend({
|
|||
"navigate_to_first_post_after_read"
|
||||
),
|
||||
search_priority: this.search_priority,
|
||||
reviewable_by_group_name: this.reviewable_by_group_name
|
||||
reviewable_by_group_name: this.reviewable_by_group_name,
|
||||
read_only_banner: this.read_only_banner
|
||||
},
|
||||
type: id ? "PUT" : "POST"
|
||||
});
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
{{#if shouldShow}}
|
||||
<div class="row">
|
||||
<div class="alert alert-info category-read-only-banner">
|
||||
{{category.read_only_banner}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
|
@ -1,6 +1,6 @@
|
|||
{{#if canCreateTopic}}
|
||||
{{d-button
|
||||
class="btn-default"
|
||||
class=btnClass
|
||||
id="create-topic"
|
||||
action=action
|
||||
icon="plus"
|
||||
|
|
|
@ -25,9 +25,10 @@
|
|||
|
||||
{{create-topic-button
|
||||
canCreateTopic=canCreateTopic
|
||||
action=createTopic
|
||||
disabled=createTopicDisabled
|
||||
action=(action "clickCreateTopicButton")
|
||||
disabled=createTopicButtonDisabled
|
||||
label=createTopicLabel
|
||||
btnClass=createTopicClass
|
||||
}}
|
||||
|
||||
{{#if showCategoryEdit}}
|
||||
|
|
|
@ -221,6 +221,20 @@
|
|||
}}
|
||||
</section>
|
||||
{{/if}}
|
||||
|
||||
<section class="field category-read-only-banner">
|
||||
<label for="category-read-only-banner">
|
||||
{{i18n "category.read_only_banner"}}
|
||||
</label>
|
||||
{{text-field
|
||||
valueProperty="value"
|
||||
id="read-only-message"
|
||||
value=category.read_only_banner
|
||||
options=(hash
|
||||
placementStrategy="absolute"
|
||||
)
|
||||
}}
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
{{else}}
|
||||
<div class="container">
|
||||
{{discourse-banner user=currentUser banner=site.banner}}
|
||||
{{category-read-only-banner category=category readOnly=navigationCategory.cannotCreateTopicOnCategory}}
|
||||
</div>
|
||||
|
||||
<div class="list-controls">
|
||||
|
|
|
@ -328,6 +328,7 @@ class CategoriesController < ApplicationController
|
|||
:allow_global_tags,
|
||||
:required_tag_group_name,
|
||||
:min_tags_from_required_group,
|
||||
:read_only_banner,
|
||||
custom_fields: [params[:custom_fields].try(:keys)],
|
||||
permissions: [*p.try(:keys)],
|
||||
allowed_tags: [],
|
||||
|
|
|
@ -978,6 +978,7 @@ end
|
|||
# reviewable_by_group_id :integer
|
||||
# required_tag_group_id :integer
|
||||
# min_tags_from_required_group :integer default(1), not null
|
||||
# read_only_banner :string
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
|
|
|
@ -6,7 +6,8 @@ class SiteCategorySerializer < BasicCategorySerializer
|
|||
:allowed_tag_groups,
|
||||
:allow_global_tags,
|
||||
:min_tags_from_required_group,
|
||||
:required_tag_group_name
|
||||
:required_tag_group_name,
|
||||
:read_only_banner
|
||||
|
||||
def include_allowed_tags?
|
||||
SiteSetting.tagging_enabled
|
||||
|
|
|
@ -2795,6 +2795,7 @@ en:
|
|||
email_in_disabled_click: 'enable the "email in" setting.'
|
||||
mailinglist_mirror: "Category mirrors a mailing list"
|
||||
show_subcategory_list: "Show subcategory list above topics in this category."
|
||||
read_only_banner: "Banner text when a user cannot create a topic in this category:"
|
||||
num_featured_topics: "Number of topics shown on the categories page:"
|
||||
subcategory_num_featured_topics: "Number of featured topics on parent category's page:"
|
||||
all_topics_wiki: "Make new topics wikis by default"
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddReadOnlyToCategories < ActiveRecord::Migration[6.0]
|
||||
def change
|
||||
add_column :categories, :read_only_banner, :string
|
||||
end
|
||||
end
|
|
@ -0,0 +1,89 @@
|
|||
import { acceptance } from "helpers/qunit-helpers";
|
||||
import DiscoveryFixtures from "fixtures/discovery_fixtures";
|
||||
|
||||
acceptance("Category Banners", {
|
||||
pretend(server, helper) {
|
||||
server.get("/c/test-read-only-without-banner/5/l/latest.json", () => {
|
||||
return helper.response(
|
||||
DiscoveryFixtures["/latest_can_create_topic.json"]
|
||||
);
|
||||
});
|
||||
server.get("/c/test-read-only-with-banner/6/l/latest.json", () => {
|
||||
return helper.response(
|
||||
DiscoveryFixtures["/latest_can_create_topic.json"]
|
||||
);
|
||||
});
|
||||
},
|
||||
loggedIn: true,
|
||||
site: {
|
||||
categories: [
|
||||
{
|
||||
id: 5,
|
||||
name: "test read only without banner",
|
||||
slug: "test-read-only-without-banner",
|
||||
permission: null
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
name: "test read only with banner",
|
||||
slug: "test-read-only-with-banner",
|
||||
permission: null,
|
||||
read_only_banner:
|
||||
"You need to video yourself doing the secret handshake to post here"
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
QUnit.test("Does not display category banners when not set", async assert => {
|
||||
await visit("/c/test-read-only-without-banner");
|
||||
|
||||
await click("#create-topic");
|
||||
assert.ok(!visible(".bootbox.modal"), "it does not pop up a modal");
|
||||
assert.ok(
|
||||
!visible(".category-read-only-banner"),
|
||||
"it does not show a banner"
|
||||
);
|
||||
});
|
||||
|
||||
QUnit.test("Displays category banners when set", async assert => {
|
||||
await visit("/c/test-read-only-with-banner");
|
||||
|
||||
await click("#create-topic");
|
||||
assert.ok(visible(".bootbox.modal"), "it pops up a modal");
|
||||
|
||||
await click(".modal-footer>.btn-primary");
|
||||
assert.ok(!visible(".bootbox.modal"), "it closes the modal");
|
||||
assert.ok(visible(".category-read-only-banner"), "it shows a banner");
|
||||
});
|
||||
|
||||
acceptance("Anonymous Category Banners", {
|
||||
pretend(server, helper) {
|
||||
server.get("/c/test-read-only-with-banner/6/l/latest.json", () => {
|
||||
return helper.response(
|
||||
DiscoveryFixtures["/latest_can_create_topic.json"]
|
||||
);
|
||||
});
|
||||
},
|
||||
loggedIn: false,
|
||||
site: {
|
||||
categories: [
|
||||
{
|
||||
id: 6,
|
||||
name: "test read only with banner",
|
||||
slug: "test-read-only-with-banner",
|
||||
permission: null,
|
||||
read_only_banner:
|
||||
"You need to video yourself doing the secret handshake to post here"
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
QUnit.test("Does not display category banners when set", async assert => {
|
||||
await visit("/c/test-read-only-with-banner");
|
||||
assert.ok(
|
||||
!visible(".category-read-only-banner"),
|
||||
"it does not show a banner"
|
||||
);
|
||||
});
|
|
@ -6120,5 +6120,107 @@ export default {
|
|||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/latest_can_create_topic.json": {
|
||||
users: [
|
||||
{
|
||||
id: 1,
|
||||
username: "tt1",
|
||||
name: null,
|
||||
avatar_template: "/letter_avatar_proxy/v4/letter/t/6de8d8/{size}.png"
|
||||
}
|
||||
],
|
||||
primary_groups: [],
|
||||
topic_list: {
|
||||
can_create_topic: true,
|
||||
draft: null,
|
||||
draft_key: "new_topic",
|
||||
draft_sequence: 0,
|
||||
per_page: 30,
|
||||
topics: [
|
||||
{
|
||||
id: 30,
|
||||
title: "I am also creating a new topic here new topic",
|
||||
fancy_title: "I am also creating a new topic here new topic",
|
||||
slug: "i-am-also-creating-a-new-topic-here-new-topic",
|
||||
posts_count: 6,
|
||||
reply_count: 0,
|
||||
highest_post_number: 6,
|
||||
image_url: null,
|
||||
created_at: "2020-04-27T23:47:44.218Z",
|
||||
last_posted_at: "2020-04-28T22:45:47.529Z",
|
||||
bumped: true,
|
||||
bumped_at: "2020-04-28T22:02:20.215Z",
|
||||
archetype: "regular",
|
||||
unseen: false,
|
||||
last_read_post_number: 5,
|
||||
unread: 0,
|
||||
new_posts: 0,
|
||||
pinned: false,
|
||||
unpinned: null,
|
||||
visible: true,
|
||||
closed: false,
|
||||
archived: false,
|
||||
notification_level: 1,
|
||||
bookmarked: false,
|
||||
liked: false,
|
||||
tags: ["test", "test-tag"],
|
||||
views: 6,
|
||||
like_count: 0,
|
||||
has_summary: false,
|
||||
last_poster_username: "tt1",
|
||||
category_id: 5,
|
||||
pinned_globally: false,
|
||||
featured_link: null,
|
||||
posters: [
|
||||
{
|
||||
extras: "latest single",
|
||||
description: "Original Poster, Most Recent Poster",
|
||||
user_id: 1,
|
||||
primary_group_id: null
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 29,
|
||||
title: "About the test category category",
|
||||
fancy_title: "About the test category category",
|
||||
slug: "about-the-test-category-category",
|
||||
posts_count: 5,
|
||||
reply_count: 0,
|
||||
highest_post_number: 5,
|
||||
image_url: null,
|
||||
created_at: "2020-04-27T22:15:49.424Z",
|
||||
last_posted_at: "2020-04-27T23:51:06.249Z",
|
||||
bumped: true,
|
||||
bumped_at: "2020-04-27T22:15:49.424Z",
|
||||
archetype: "regular",
|
||||
unseen: false,
|
||||
pinned: false,
|
||||
unpinned: null,
|
||||
visible: true,
|
||||
closed: false,
|
||||
archived: false,
|
||||
bookmarked: null,
|
||||
liked: null,
|
||||
tags: [],
|
||||
views: 1,
|
||||
like_count: 0,
|
||||
has_summary: false,
|
||||
last_poster_username: "tt1",
|
||||
category_id: 5,
|
||||
pinned_globally: false,
|
||||
featured_link: null,
|
||||
posters: [
|
||||
{
|
||||
extras: "latest single",
|
||||
description: "Original Poster, Most Recent Poster",
|
||||
user_id: 1,
|
||||
primary_group_id: null
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue