mirror of
https://github.com/discourse/discourse.git
synced 2024-11-22 08:57:10 -06:00
FEATURE: add welcome topic cta banner (#17821)
This commit is contained in:
parent
5138347e48
commit
d57bea4de3
@ -0,0 +1,25 @@
|
|||||||
|
import GlimmerComponent from "discourse/components/glimmer";
|
||||||
|
import { action } from "@ember/object";
|
||||||
|
import { getOwner } from "discourse-common/lib/get-owner";
|
||||||
|
import Topic from "discourse/models/topic";
|
||||||
|
import Composer from "discourse/models/composer";
|
||||||
|
|
||||||
|
export default class WelcomeTopicBanner extends GlimmerComponent {
|
||||||
|
@action
|
||||||
|
editWelcomeTopic() {
|
||||||
|
const topicController = getOwner(this).lookup("controller:topic");
|
||||||
|
|
||||||
|
Topic.find(this.siteSettings.welcome_topic_id, {}).then((topic) => {
|
||||||
|
this.store
|
||||||
|
.createRecord("topic", {
|
||||||
|
id: topic.id,
|
||||||
|
slug: topic.slug,
|
||||||
|
})
|
||||||
|
.postStream.loadPostByPostNumber(1)
|
||||||
|
.then((post) => {
|
||||||
|
post.topic.set("draft_key", Composer.EDIT);
|
||||||
|
topicController.send("editPost", post);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -24,6 +24,13 @@ const controllerOpts = {
|
|||||||
showTopicPostBadges: not("new"),
|
showTopicPostBadges: not("new"),
|
||||||
redirectedReason: alias("currentUser.redirected_to_top.reason"),
|
redirectedReason: alias("currentUser.redirected_to_top.reason"),
|
||||||
|
|
||||||
|
@discourseComputed("model.filter", "site.show_welcome_topic_banner")
|
||||||
|
showEditWelcomeTopicBanner(filter, showWelcomeTopicBanner) {
|
||||||
|
return (
|
||||||
|
this.currentUser?.staff && filter === "latest" && showWelcomeTopicBanner
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
expandGloballyPinned: false,
|
expandGloballyPinned: false,
|
||||||
expandAllPinned: false,
|
expandAllPinned: false,
|
||||||
|
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
<div class="welcome-topic-banner">
|
||||||
|
<div class="col-text">
|
||||||
|
<h1 class="title">{{i18n "welcome_topic_banner.title"}}</h1>
|
||||||
|
<p class="description">{{i18n "welcome_topic_banner.description"}}</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-button">
|
||||||
|
<DButton @class="btn-primary welcome-topic-cta" @action={{action "editWelcomeTopic"}} @label="welcome_topic_banner.button_title" />
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -2,6 +2,10 @@
|
|||||||
<div class="alert alert-info">{{this.redirectedReason}}</div>
|
<div class="alert alert-info">{{this.redirectedReason}}</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if this.showEditWelcomeTopicBanner}}
|
||||||
|
<WelcomeTopicBanner />
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
<TopicDismissButtons @position="top" @selectedTopics={{this.selected}} @model={{this.model}} @showResetNew={{this.showResetNew}} @showDismissRead={{this.showDismissRead}} @resetNew={{action "resetNew"}} />
|
<TopicDismissButtons @position="top" @selectedTopics={{this.selected}} @model={{this.model}} @showResetNew={{this.showResetNew}} @showDismissRead={{this.showDismissRead}} @resetNew={{action "resetNew"}} />
|
||||||
|
|
||||||
{{#if this.model.sharedDrafts}}
|
{{#if this.model.sharedDrafts}}
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
import { acceptance, exists } from "discourse/tests/helpers/qunit-helpers";
|
||||||
|
import { test } from "qunit";
|
||||||
|
import { visit } from "@ember/test-helpers";
|
||||||
|
|
||||||
|
acceptance("Welcome Topic Banner", function (needs) {
|
||||||
|
needs.user();
|
||||||
|
needs.site({ show_welcome_topic_banner: true });
|
||||||
|
|
||||||
|
test("Navigation", async function (assert) {
|
||||||
|
await visit("/");
|
||||||
|
assert.ok(exists(".welcome-topic-banner"), "has the welcome topic banner");
|
||||||
|
assert.ok(
|
||||||
|
exists("button.welcome-topic-cta"),
|
||||||
|
"has the welcome topic edit button"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
@ -252,3 +252,22 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.welcome-topic-banner {
|
||||||
|
border: 1px solid var(--primary-low);
|
||||||
|
box-shadow: 0px 0px 6px 0px rgba(0, 0, 0, 0.12);
|
||||||
|
padding: 10px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
|
||||||
|
.col-text {
|
||||||
|
width: 70%;
|
||||||
|
}
|
||||||
|
.col-button {
|
||||||
|
width: 30%;
|
||||||
|
display: flex;
|
||||||
|
align-self: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
padding-right: 30px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -203,4 +203,10 @@ class Site
|
|||||||
MessageBus.publish(SITE_JSON_CHANNEL, '')
|
MessageBus.publish(SITE_JSON_CHANNEL, '')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.show_welcome_topic_banner?(guardian)
|
||||||
|
return false unless guardian.is_admin?
|
||||||
|
return false unless guardian.user.id == User.first_login_admin_id
|
||||||
|
|
||||||
|
Post.find_by("topic_id = :topic_id AND post_number = 1 AND version = 1 AND created_at > :created_at", topic_id: SiteSetting.welcome_topic_id, created_at: 1.month.ago).present?
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -1878,6 +1878,14 @@ class User < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.first_login_admin_id
|
||||||
|
User.where(admin: true)
|
||||||
|
.human_users
|
||||||
|
.joins(:user_auth_tokens)
|
||||||
|
.order('user_auth_tokens.created_at')
|
||||||
|
.pluck_first(:id)
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def stat
|
def stat
|
||||||
|
@ -34,7 +34,8 @@ class SiteSerializer < ApplicationSerializer
|
|||||||
:watched_words_link,
|
:watched_words_link,
|
||||||
:categories,
|
:categories,
|
||||||
:markdown_additional_options,
|
:markdown_additional_options,
|
||||||
:displayed_about_plugin_stat_groups
|
:displayed_about_plugin_stat_groups,
|
||||||
|
:show_welcome_topic_banner
|
||||||
)
|
)
|
||||||
|
|
||||||
has_many :archetypes, embed: :objects, serializer: ArchetypeSerializer
|
has_many :archetypes, embed: :objects, serializer: ArchetypeSerializer
|
||||||
@ -213,6 +214,10 @@ class SiteSerializer < ApplicationSerializer
|
|||||||
About.displayed_plugin_stat_groups
|
About.displayed_plugin_stat_groups
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def show_welcome_topic_banner
|
||||||
|
Site.show_welcome_topic_banner?(scope)
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def ordered_flags(flags)
|
def ordered_flags(flags)
|
||||||
|
@ -4136,6 +4136,11 @@ en:
|
|||||||
one: "%{count} draft"
|
one: "%{count} draft"
|
||||||
other: "%{count} drafts"
|
other: "%{count} drafts"
|
||||||
|
|
||||||
|
welcome_topic_banner:
|
||||||
|
title: "Create your Welcome Topic"
|
||||||
|
description: 'Your welcome topic is the first thing new arrivals will read. Think of it as your one paragraph "elevator pitch" or "mission statement"'
|
||||||
|
button_title: "Start Editing"
|
||||||
|
|
||||||
# This section is exported to the javascript for i18n in the admin section
|
# This section is exported to the javascript for i18n in the admin section
|
||||||
admin_js:
|
admin_js:
|
||||||
type_to_filter: "type to filter..."
|
type_to_filter: "type to filter..."
|
||||||
|
@ -2325,6 +2325,7 @@ uncategorized:
|
|||||||
welcome_topic_id:
|
welcome_topic_id:
|
||||||
default: -1
|
default: -1
|
||||||
hidden: true
|
hidden: true
|
||||||
|
client: true
|
||||||
lounge_welcome_topic_id:
|
lounge_welcome_topic_id:
|
||||||
default: -1
|
default: -1
|
||||||
hidden: true
|
hidden: true
|
||||||
|
@ -106,13 +106,7 @@ class Wizard
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
first_admin_id = User.where(admin: true)
|
if @user&.id && User.first_login_admin_id == @user.id
|
||||||
.human_users
|
|
||||||
.joins(:user_auth_tokens)
|
|
||||||
.order('user_auth_tokens.created_at')
|
|
||||||
.pluck_first(:id)
|
|
||||||
|
|
||||||
if @user&.id && first_admin_id == @user.id
|
|
||||||
!Wizard::Builder.new(@user).build.completed?
|
!Wizard::Builder.new(@user).build.completed?
|
||||||
else
|
else
|
||||||
false
|
false
|
||||||
|
@ -183,4 +183,50 @@ RSpec.describe Site do
|
|||||||
expect(data["auth_providers"].map { |a| a["name"] }).to contain_exactly('facebook', 'twitter')
|
expect(data["auth_providers"].map { |a| a["name"] }).to contain_exactly('facebook', 'twitter')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe ".show_welcome_topic_banner?" do
|
||||||
|
it "returns false when the user is not admin" do
|
||||||
|
first_post = Fabricate(:post, created_at: 25.days.ago)
|
||||||
|
SiteSetting.welcome_topic_id = first_post.topic.id
|
||||||
|
|
||||||
|
expect(Site.show_welcome_topic_banner?(Guardian.new(Fabricate(:user)))).to eq(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns false when the user is not first admin who logs in" do
|
||||||
|
first_post = Fabricate(:post, created_at: 25.days.ago)
|
||||||
|
SiteSetting.welcome_topic_id = first_post.topic.id
|
||||||
|
|
||||||
|
expect(Site.show_welcome_topic_banner?(Guardian.new(Fabricate(:admin)))).to eq(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns true when welcome topic is less than month old" do
|
||||||
|
admin = Fabricate(:admin)
|
||||||
|
UserAuthToken.generate!(user_id: admin.id)
|
||||||
|
|
||||||
|
first_post = Fabricate(:post, created_at: 25.days.ago)
|
||||||
|
SiteSetting.welcome_topic_id = first_post.topic.id
|
||||||
|
|
||||||
|
expect(Site.show_welcome_topic_banner?(Guardian.new(admin))).to eq(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns false when welcome topic is more than month old" do
|
||||||
|
admin = Fabricate(:admin)
|
||||||
|
UserAuthToken.generate!(user_id: admin.id)
|
||||||
|
|
||||||
|
first_post = Fabricate(:post, created_at: 35.days.ago)
|
||||||
|
SiteSetting.welcome_topic_id = first_post.topic.id
|
||||||
|
|
||||||
|
expect(Site.show_welcome_topic_banner?(Guardian.new(admin))).to eq(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns false when welcome topic has been edited" do
|
||||||
|
admin = Fabricate(:admin)
|
||||||
|
UserAuthToken.generate!(user_id: admin.id)
|
||||||
|
|
||||||
|
first_post = Fabricate(:post, version: 2, created_at: 25.days.ago)
|
||||||
|
SiteSetting.welcome_topic_id = first_post.topic.id
|
||||||
|
|
||||||
|
expect(Site.show_welcome_topic_banner?(Guardian.new(admin))).to eq(false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -685,6 +685,9 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"show_welcome_topic_banner": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"archetypes": {
|
"archetypes": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items":
|
"items":
|
||||||
|
@ -112,4 +112,16 @@ RSpec.describe SiteSerializer do
|
|||||||
serialized = described_class.new(Site.new(admin_guardian), scope: admin_guardian, root: false).as_json
|
serialized = described_class.new(Site.new(admin_guardian), scope: admin_guardian, root: false).as_json
|
||||||
expect(serialized[:shared_drafts_category_id]).to eq(nil)
|
expect(serialized[:shared_drafts_category_id]).to eq(nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'includes show_welcome_topic_banner' do
|
||||||
|
admin = Fabricate(:admin)
|
||||||
|
admin_guardian = Guardian.new(admin)
|
||||||
|
UserAuthToken.generate!(user_id: admin.id)
|
||||||
|
|
||||||
|
first_post = Fabricate(:post, created_at: 25.days.ago)
|
||||||
|
SiteSetting.welcome_topic_id = first_post.topic.id
|
||||||
|
|
||||||
|
serialized = described_class.new(Site.new(admin_guardian), scope: admin_guardian, root: false).as_json
|
||||||
|
expect(serialized[:show_welcome_topic_banner]).to eq(true)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user