mirror of
https://github.com/discourse/discourse.git
synced 2026-08-04 10:23:17 -05:00
UX: add welcome banner location site setting to admin interface (#33438)
Add a Welcome banner location setting to the *Interface & layout* page that admins can adjust to change the location of the welcome banner. --------- Co-authored-by: chapoi <101828855+chapoi@users.noreply.github.com>
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
import Component from "@glimmer/component";
|
||||
import { service } from "@ember/service";
|
||||
import { dasherize } from "@ember/string";
|
||||
import { htmlSafe } from "@ember/template";
|
||||
import { modifier } from "ember-modifier";
|
||||
import DButton from "discourse/components/d-button";
|
||||
import PluginOutlet from "discourse/components/plugin-outlet";
|
||||
import SearchMenu from "discourse/components/search-menu";
|
||||
import bodyClass from "discourse/helpers/body-class";
|
||||
import concatClass from "discourse/helpers/concat-class";
|
||||
import { prioritizeNameFallback } from "discourse/lib/settings";
|
||||
import { applyValueTransformer } from "discourse/lib/transformer";
|
||||
import I18n, { i18n } from "discourse-i18n";
|
||||
@@ -98,12 +100,15 @@ export default class WelcomeBanner extends Component {
|
||||
: "";
|
||||
}
|
||||
|
||||
get locationClass() {
|
||||
return `--${dasherize(this.siteSettings.welcome_banner_location)}`;
|
||||
}
|
||||
|
||||
<template>
|
||||
{{bodyClass this.bodyClasses}}
|
||||
{{#if this.shouldDisplay}}
|
||||
|
||||
<div
|
||||
class="welcome-banner"
|
||||
class={{concatClass "welcome-banner" this.locationClass}}
|
||||
{{this.checkViewport}}
|
||||
{{this.handleKeyboardShortcut}}
|
||||
>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import didInsert from "@ember/render-modifiers/modifiers/did-insert";
|
||||
import DialogHolder from "dialog-holder/components/dialog-holder";
|
||||
import RouteTemplate from "ember-route-template";
|
||||
import { and } from "truth-helpers";
|
||||
import { and, eq } from "truth-helpers";
|
||||
import CardContainer from "discourse/components/card-container";
|
||||
import ComposerContainer from "discourse/components/composer-container";
|
||||
import CustomHtml from "discourse/components/custom-html";
|
||||
@@ -73,6 +73,14 @@ export default RouteTemplate(
|
||||
<OfflineIndicator />
|
||||
{{/if}}
|
||||
|
||||
{{#if
|
||||
(eq
|
||||
@controller.siteSettings.welcome_banner_location "below_site_header"
|
||||
)
|
||||
}}
|
||||
<WelcomeBanner />
|
||||
{{/if}}
|
||||
|
||||
<PluginOutlet
|
||||
@name="below-site-header"
|
||||
@connectorTagName="div"
|
||||
@@ -96,7 +104,14 @@ export default RouteTemplate(
|
||||
<div id="main-outlet">
|
||||
<PluginOutlet @name="above-main-container" @connectorTagName="div" />
|
||||
|
||||
<WelcomeBanner />
|
||||
{{#if
|
||||
(eq
|
||||
@controller.siteSettings.welcome_banner_location
|
||||
"above_topic_content"
|
||||
)
|
||||
}}
|
||||
<WelcomeBanner />
|
||||
{{/if}}
|
||||
|
||||
<div class="container" id="main-container">
|
||||
{{#if @controller.showTop}}
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
.welcome-banner {
|
||||
border-radius: var(--d-border-radius-large);
|
||||
|
||||
@include viewport.until(sm) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&__wrap {
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
@@ -32,18 +36,11 @@
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
> div {
|
||||
margin: 0 auto;
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
.search-menu {
|
||||
display: flex;
|
||||
position: relative;
|
||||
|
||||
@include viewport.until(sm) {
|
||||
display: none;
|
||||
}
|
||||
margin-inline: auto;
|
||||
max-width: 600px;
|
||||
|
||||
.search-menu-container {
|
||||
width: 100%;
|
||||
@@ -62,41 +59,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.welcome-banner__title {
|
||||
font-size: var(--font-up-6);
|
||||
line-height: $line-height-medium;
|
||||
font-weight: bold;
|
||||
margin-bottom: var(--space-2);
|
||||
|
||||
@include viewport.until(md) {
|
||||
font-size: var(--font-up-4);
|
||||
}
|
||||
|
||||
@include viewport.until(sm) {
|
||||
font-size: var(--font-up-1);
|
||||
}
|
||||
}
|
||||
|
||||
.welcome-banner__title,
|
||||
p {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.welcome-banner__subheader {
|
||||
font-size: var(--font-down-6);
|
||||
font-weight: normal;
|
||||
margin: 0;
|
||||
padding: 0.25rem 0;
|
||||
|
||||
@include viewport.until(md) {
|
||||
font-size: var(--font-down-4);
|
||||
}
|
||||
|
||||
@include viewport.until(sm) {
|
||||
font-size: var(--font-down-1);
|
||||
}
|
||||
}
|
||||
|
||||
.btn.search-icon {
|
||||
z-index: 2;
|
||||
background: transparent;
|
||||
@@ -183,6 +145,31 @@
|
||||
}
|
||||
}
|
||||
|
||||
.welcome-banner__title {
|
||||
font-size: var(--font-up-6);
|
||||
line-height: $line-height-medium;
|
||||
font-weight: bold;
|
||||
margin-bottom: var(--space-2);
|
||||
margin-inline: auto;
|
||||
max-width: 600px;
|
||||
text-align: center;
|
||||
|
||||
@include viewport.until(md) {
|
||||
font-size: var(--font-up-4);
|
||||
}
|
||||
|
||||
@include viewport.until(sm) {
|
||||
font-size: var(--font-up-1);
|
||||
}
|
||||
}
|
||||
|
||||
.welcome-banner__subheader {
|
||||
font-size: var(--font-up-1-rem);
|
||||
font-weight: normal;
|
||||
margin: 0;
|
||||
padding: 0.25rem 0;
|
||||
}
|
||||
|
||||
// hide search icon from default search menu
|
||||
.search-menu.glimmer-search-menu .search-icon {
|
||||
display: none;
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "enum_site_setting"
|
||||
|
||||
class WelcomeBannerLocation < EnumSiteSetting
|
||||
def self.valid_value?(val)
|
||||
values.any? { |v| v[:value].to_s == val.to_s }
|
||||
end
|
||||
|
||||
def self.values
|
||||
@values ||= [
|
||||
{ name: "welcome_banner_location.above_topic_content", value: "above_topic_content" },
|
||||
{ name: "welcome_banner_location.below_site_header", value: "below_site_header" },
|
||||
]
|
||||
end
|
||||
|
||||
def self.translate_names?
|
||||
true
|
||||
end
|
||||
end
|
||||
@@ -2678,6 +2678,9 @@ en:
|
||||
disabled: "Do not display"
|
||||
sidebar_footer: "Display in sidebar footer"
|
||||
header: "Display in header"
|
||||
welcome_banner_location:
|
||||
above_topic_content: "Above topic content"
|
||||
below_site_header: "Below site header"
|
||||
|
||||
shortcut_modifier_key:
|
||||
shift: "Shift"
|
||||
|
||||
@@ -2711,6 +2711,7 @@ en:
|
||||
show_bottom_topic_map: "Shows the topic map at the bottom of the topic when it has 10 replies or more."
|
||||
show_topic_map_in_topics_without_replies: "Shows the topic map even if the topic has no replies."
|
||||
enable_welcome_banner: "Display a banner on your main topic list pages to welcome members and allow them to search site content"
|
||||
welcome_banner_location: "Determines where on the page the welcome banner will appear."
|
||||
|
||||
splash_screen: "Displays a temporary loading screen while site assets load"
|
||||
navigation_menu: "Specify sidebar or header dropdown as the main navigation menu for your site. Sidebar is recommended."
|
||||
|
||||
@@ -3648,6 +3648,12 @@ uncategorized:
|
||||
themeable: true
|
||||
area: "interface"
|
||||
|
||||
welcome_banner_location:
|
||||
client: true
|
||||
enum: "WelcomeBannerLocation"
|
||||
default: "above_topic_content"
|
||||
area: "interface"
|
||||
|
||||
user_preferences:
|
||||
default_email_digest_frequency:
|
||||
enum: "DigestEmailSiteSetting"
|
||||
|
||||
@@ -47,6 +47,14 @@ module PageObjects
|
||||
text: I18n.t("js.welcome_banner.subheader.logged_in_members"),
|
||||
)
|
||||
end
|
||||
|
||||
def above_topic_content?
|
||||
has_css?("#main-outlet > .--above-topic-content", visible: :visible)
|
||||
end
|
||||
|
||||
def below_site_header?
|
||||
has_css?(".discourse-root > .--below-site-header", visible: :visible)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -145,6 +145,20 @@ describe "Welcome banner", type: :system do
|
||||
expect(search_page).to have_no_search_icon
|
||||
end
|
||||
end
|
||||
|
||||
context "with interface location setting" do
|
||||
it "shows above topic content" do
|
||||
SiteSetting.welcome_banner_location = "above_topic_content"
|
||||
visit "/"
|
||||
expect(banner).to be_above_topic_content
|
||||
end
|
||||
|
||||
it "shows below site header" do
|
||||
SiteSetting.welcome_banner_location = "below_site_header"
|
||||
visit "/"
|
||||
expect(banner).to be_below_site_header
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when disabled" do
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
html:not(:has(.has-full-page-chat)) {
|
||||
background-color: var(--background-color);
|
||||
|
||||
@include viewport.until(sm) {
|
||||
@include viewport.until(lg) {
|
||||
background-color: var(--d-content-background);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,34 @@
|
||||
@use "lib/viewport";
|
||||
|
||||
.welcome-banner {
|
||||
&__wrap {
|
||||
display: grid;
|
||||
grid-template-rows: 0.33fr 0.33fr 0.33fr;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-column-gap: 1em;
|
||||
grid-row-gap: 0.5em;
|
||||
border-bottom: 1px solid var(--primary-300);
|
||||
padding: 1.5em 0 2.5em;
|
||||
margin-bottom: 0;
|
||||
&.--below-site-header {
|
||||
background-color: var(--background-color);
|
||||
border-radius: 0;
|
||||
|
||||
@media screen and (width <= 768px) {
|
||||
padding: 1em;
|
||||
@include viewport.until(lg) {
|
||||
margin-bottom: var(--space-4);
|
||||
}
|
||||
}
|
||||
|
||||
&__inner-wrapper {
|
||||
container-type: inline-size;
|
||||
}
|
||||
|
||||
&__wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--space-8);
|
||||
border-bottom: 1px solid var(--primary-300);
|
||||
margin-block: 0;
|
||||
padding-block: var(--space-4) var(--space-8);
|
||||
|
||||
@include viewport.from(xl) {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
@include viewport.until(md) {
|
||||
flex-direction: column;
|
||||
gap: var(--space-4);
|
||||
}
|
||||
|
||||
@include viewport.until(sm) {
|
||||
@@ -21,29 +37,42 @@
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.--below-site-header & {
|
||||
border-bottom: 0;
|
||||
padding: var(--space-4) var(--space-4) var(--space-8);
|
||||
|
||||
@include viewport.from(xl) {
|
||||
margin-left: max(var(--d-sidebar-width), var(--space-4));
|
||||
}
|
||||
|
||||
@include viewport.until(lg) {
|
||||
padding: var(--space-8) var(--space-4) var(--space-8);
|
||||
}
|
||||
}
|
||||
|
||||
.--above-topic-content & {
|
||||
@container (width <= 800px) {
|
||||
flex-direction: column;
|
||||
gap: var(--space-4);
|
||||
}
|
||||
|
||||
@include viewport.until(lg) {
|
||||
padding-inline: var(--space-4);
|
||||
}
|
||||
}
|
||||
|
||||
.search-menu {
|
||||
grid-column: 2/3;
|
||||
grid-row: 1/-1;
|
||||
width: 100%;
|
||||
align-self: center;
|
||||
|
||||
@media screen and (width <= 1028px) {
|
||||
grid-row: 2/-1;
|
||||
grid-column: 1/-1;
|
||||
.--above-topic-content & {
|
||||
@container (width >= 800px) {
|
||||
width: 50cqw;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (width <= 768px) {
|
||||
grid-column: 2/-1;
|
||||
grid-row: 1/-1;
|
||||
}
|
||||
|
||||
@media screen and (width <= 600px) {
|
||||
grid-row: 2/-1;
|
||||
grid-column: 1/-1;
|
||||
}
|
||||
|
||||
@include viewport.until(sm) {
|
||||
display: none;
|
||||
@include viewport.from(xl) {
|
||||
margin-inline: unset;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,38 +109,39 @@
|
||||
}
|
||||
|
||||
&__title {
|
||||
grid-column: 1/2;
|
||||
grid-row: 1/-1;
|
||||
text-align: left;
|
||||
align-self: center;
|
||||
margin: 0;
|
||||
font-weight: 400;
|
||||
color: var(--search-color);
|
||||
|
||||
@media screen and (width <= 1028px) {
|
||||
.--above-topic-content & {
|
||||
@container (width >= 800px) {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
@container (width <= 800px) {
|
||||
white-space: nowrap;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
@include viewport.from(xl) {
|
||||
margin-inline: unset;
|
||||
}
|
||||
|
||||
@include viewport.from(md) {
|
||||
font-size: clamp(var(--font-up-4), 4vw, var(--font-up-6));
|
||||
}
|
||||
|
||||
@include viewport.until(md) {
|
||||
font-size: var(--font-up-4);
|
||||
grid-column: 1/-1;
|
||||
grid-row: 1;
|
||||
text-align: center;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
@media screen and (width <= 768px) {
|
||||
text-align: left;
|
||||
grid-column: 1/2;
|
||||
grid-row: 1/-1;
|
||||
font-size: var(--font-up-3);
|
||||
}
|
||||
|
||||
@media screen and (width <= 600px) {
|
||||
grid-column: 1/-1;
|
||||
grid-row: 1;
|
||||
text-align: center;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
@include viewport.until(sm) {
|
||||
font-size: var(--font-up-2);
|
||||
}
|
||||
}
|
||||
|
||||
&__subheader {
|
||||
white-space: wrap;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user