mirror of
https://github.com/discourse/discourse.git
synced 2025-03-22 11:16:39 +08:00
FEATURE: update bootstrap mode notice to add invite and wizard links (#17822)
* FEATURE: update bootstrap mode notice to add invite and wizard links * Updates per feedback on PR * Fix the wizard link not showing * Remove unneeded function * Remove router service injection
This commit is contained in:
parent
d57bea4de3
commit
10a1b6b0a9
22
app/assets/javascripts/discourse/app/components/bootstrap_mode_notice.js
vendored
Normal file
22
app/assets/javascripts/discourse/app/components/bootstrap_mode_notice.js
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import GlimmerComponent from "@glimmer/component";
|
||||||
|
import { htmlSafe } from "@ember/template";
|
||||||
|
import I18n from "I18n";
|
||||||
|
import { inject as service } from "@ember/service";
|
||||||
|
|
||||||
|
export default class BootstrapModeNotice extends GlimmerComponent {
|
||||||
|
@service siteSettings;
|
||||||
|
@service site;
|
||||||
|
|
||||||
|
get message() {
|
||||||
|
let msg = null;
|
||||||
|
const bootstrapModeMinUsers = this.siteSettings.bootstrap_mode_min_users;
|
||||||
|
|
||||||
|
if (bootstrapModeMinUsers > 0) {
|
||||||
|
msg = "bootstrap_mode_enabled";
|
||||||
|
} else {
|
||||||
|
msg = "bootstrap_mode_disabled";
|
||||||
|
}
|
||||||
|
|
||||||
|
return htmlSafe(I18n.t(msg, { count: bootstrapModeMinUsers }));
|
||||||
|
}
|
||||||
|
}
|
@ -3,7 +3,6 @@ import cookie, { removeCookie } from "discourse/lib/cookie";
|
|||||||
import Component from "@ember/component";
|
import Component from "@ember/component";
|
||||||
import I18n from "I18n";
|
import I18n from "I18n";
|
||||||
import discourseComputed, { bind } from "discourse-common/utils/decorators";
|
import discourseComputed, { bind } from "discourse-common/utils/decorators";
|
||||||
import getURL from "discourse-common/lib/get-url";
|
|
||||||
import { htmlSafe } from "@ember/template";
|
import { htmlSafe } from "@ember/template";
|
||||||
import { inject as service } from "@ember/service";
|
import { inject as service } from "@ember/service";
|
||||||
|
|
||||||
@ -78,23 +77,17 @@ export default Component.extend({
|
|||||||
|
|
||||||
@discourseComputed(
|
@discourseComputed(
|
||||||
"site.isReadOnly",
|
"site.isReadOnly",
|
||||||
"site.wizard_required",
|
|
||||||
"siteSettings.login_required",
|
"siteSettings.login_required",
|
||||||
"siteSettings.disable_emails",
|
"siteSettings.disable_emails",
|
||||||
"siteSettings.global_notice",
|
"siteSettings.global_notice",
|
||||||
"siteSettings.bootstrap_mode_enabled",
|
|
||||||
"siteSettings.bootstrap_mode_min_users",
|
|
||||||
"session.safe_mode",
|
"session.safe_mode",
|
||||||
"logNotice.{id,text,hidden}"
|
"logNotice.{id,text,hidden}"
|
||||||
)
|
)
|
||||||
notices(
|
notices(
|
||||||
isReadOnly,
|
isReadOnly,
|
||||||
wizardRequired,
|
|
||||||
loginRequired,
|
loginRequired,
|
||||||
disableEmails,
|
disableEmails,
|
||||||
globalNotice,
|
globalNotice,
|
||||||
bootstrapModeEnabled,
|
|
||||||
bootstrapModeMinUsers,
|
|
||||||
safeMode,
|
safeMode,
|
||||||
logNotice
|
logNotice
|
||||||
) {
|
) {
|
||||||
@ -143,35 +136,6 @@ export default Component.extend({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wizardRequired) {
|
|
||||||
const requiredText = I18n.t("wizard_required", {
|
|
||||||
url: getURL("/wizard"),
|
|
||||||
});
|
|
||||||
notices.push(
|
|
||||||
Notice.create({ text: htmlSafe(requiredText), id: "alert-wizard" })
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.currentUser?.staff && bootstrapModeEnabled) {
|
|
||||||
if (bootstrapModeMinUsers > 0) {
|
|
||||||
notices.push(
|
|
||||||
Notice.create({
|
|
||||||
text: I18n.t("bootstrap_mode_enabled", {
|
|
||||||
count: bootstrapModeMinUsers,
|
|
||||||
}),
|
|
||||||
id: "alert-bootstrap-mode",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
notices.push(
|
|
||||||
Notice.create({
|
|
||||||
text: I18n.t("bootstrap_mode_disabled"),
|
|
||||||
id: "alert-bootstrap-mode",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (globalNotice?.length > 0) {
|
if (globalNotice?.length > 0) {
|
||||||
notices.push(
|
notices.push(
|
||||||
Notice.create({
|
Notice.create({
|
||||||
|
@ -36,6 +36,15 @@ export default Controller.extend({
|
|||||||
return this.siteSettings.login_required && !this.currentUser;
|
return this.siteSettings.login_required && !this.currentUser;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@discourseComputed
|
||||||
|
showBootstrapModeNotice() {
|
||||||
|
return (
|
||||||
|
this.currentUser?.get("staff") &&
|
||||||
|
this.siteSettings.bootstrap_mode_enabled &&
|
||||||
|
!this.router.currentRouteName.startsWith("wizard")
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
@discourseComputed
|
@discourseComputed
|
||||||
showFooterNav() {
|
showFooterNav() {
|
||||||
return this.capabilities.isAppWebview || this.capabilities.isiOSPWA;
|
return this.capabilities.isAppWebview || this.capabilities.isiOSPWA;
|
||||||
|
@ -35,6 +35,9 @@
|
|||||||
{{/if}}
|
{{/if}}
|
||||||
<NotificationConsentBanner />
|
<NotificationConsentBanner />
|
||||||
<PwaInstallBanner />
|
<PwaInstallBanner />
|
||||||
|
{{#if this.showBootstrapModeNotice}}
|
||||||
|
<BootstrapModeNotice />
|
||||||
|
{{/if}}
|
||||||
<GlobalNotice />
|
<GlobalNotice />
|
||||||
<CreateTopicsNotice />
|
<CreateTopicsNotice />
|
||||||
<PluginOutlet @name="top-notices" @connectorTagName="div" @args={{hash currentPath=this.router._router.currentPath}} />
|
<PluginOutlet @name="top-notices" @connectorTagName="div" @args={{hash currentPath=this.router._router.currentPath}} />
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
<div class="row bootstrap-mode-notice">
|
||||||
|
<div class="alert alert-info alert-bootstrap-mode">
|
||||||
|
<div class="col-text">
|
||||||
|
{{this.message}}
|
||||||
|
</div>
|
||||||
|
<div class="col-button">
|
||||||
|
<div class="alert--button"><DButton @icon="user-plus" @href="/my/invited" @class="btn-primary bootstrap-invite-button" @label="bootstrap_invite_button_title" /></div>
|
||||||
|
{{#if this.site.wizard_required}}
|
||||||
|
<div class="alert--link"><a class="bootstrap-wizard-link" href="/wizard">{{i18n "bootstrap_wizard_link_title"}}</a></div>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
43
app/assets/javascripts/discourse/tests/acceptance/bootstrap-mode-notice-test.js
vendored
Normal file
43
app/assets/javascripts/discourse/tests/acceptance/bootstrap-mode-notice-test.js
vendored
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import { acceptance, exists } from "discourse/tests/helpers/qunit-helpers";
|
||||||
|
import { test } from "qunit";
|
||||||
|
import { click, currentURL, visit } from "@ember/test-helpers";
|
||||||
|
|
||||||
|
acceptance("Bootstrap Mode Notice", function (needs) {
|
||||||
|
needs.user();
|
||||||
|
needs.site({ wizard_required: true });
|
||||||
|
needs.settings({
|
||||||
|
bootstrap_mode_enabled: true,
|
||||||
|
bootstrap_mode_min_users: 50,
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Navigation", async function (assert) {
|
||||||
|
await visit("/");
|
||||||
|
assert.ok(
|
||||||
|
exists(".bootstrap-mode-notice"),
|
||||||
|
"has the bootstrap mode notice"
|
||||||
|
);
|
||||||
|
assert.ok(
|
||||||
|
exists(".bootstrap-invite-button"),
|
||||||
|
"bootstrap notice has invite button"
|
||||||
|
);
|
||||||
|
assert.ok(
|
||||||
|
exists(".bootstrap-wizard-link"),
|
||||||
|
"bootstrap notice has wizard link"
|
||||||
|
);
|
||||||
|
|
||||||
|
await click(".bootstrap-invite-button");
|
||||||
|
assert.strictEqual(
|
||||||
|
currentURL(),
|
||||||
|
"/u/eviltrout/invited/pending",
|
||||||
|
"it transitions to the invite page"
|
||||||
|
);
|
||||||
|
|
||||||
|
await visit("/");
|
||||||
|
await click(".bootstrap-wizard-link");
|
||||||
|
assert.strictEqual(
|
||||||
|
currentURL(),
|
||||||
|
"/wizard/steps/hello-world",
|
||||||
|
"it transitions to the wizard page"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
@ -1,4 +1,5 @@
|
|||||||
@import "admin_customize";
|
@import "admin_customize";
|
||||||
|
@import "alert";
|
||||||
@import "category-list";
|
@import "category-list";
|
||||||
@import "compose";
|
@import "compose";
|
||||||
@import "discourse";
|
@import "discourse";
|
||||||
|
23
app/assets/stylesheets/desktop/alert.scss
Normal file
23
app/assets/stylesheets/desktop/alert.scss
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
.alert-bootstrap-mode {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
.col-text {
|
||||||
|
width: 85%;
|
||||||
|
}
|
||||||
|
.col-button {
|
||||||
|
width: 15%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
.alert--button,
|
||||||
|
.alert--link {
|
||||||
|
align-self: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
.alert--link {
|
||||||
|
font-weight: bold;
|
||||||
|
padding-top: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -5,3 +5,24 @@
|
|||||||
padding: 1em;
|
padding: 1em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.alert-bootstrap-mode {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
.col-button {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
padding-top: 10px;
|
||||||
|
justify-content: center;
|
||||||
|
.alert--button,
|
||||||
|
.alert--link {
|
||||||
|
align-self: center;
|
||||||
|
}
|
||||||
|
.alert--link {
|
||||||
|
font-weight: bold;
|
||||||
|
padding-left: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -198,7 +198,6 @@ en:
|
|||||||
topic_admin_menu: "topic actions"
|
topic_admin_menu: "topic actions"
|
||||||
skip_to_main_content: "Skip to main content"
|
skip_to_main_content: "Skip to main content"
|
||||||
|
|
||||||
wizard_required: "Welcome to your new Discourse! Let’s get started with <a href='%{url}' data-auto-route='true'>the setup wizard</a> ✨"
|
|
||||||
emails_are_disabled: "All outgoing email has been globally disabled by an administrator. No email notifications of any kind will be sent."
|
emails_are_disabled: "All outgoing email has been globally disabled by an administrator. No email notifications of any kind will be sent."
|
||||||
emails_are_disabled_non_staff: "Outgoing email has been disabled for non-staff users."
|
emails_are_disabled_non_staff: "Outgoing email has been disabled for non-staff users."
|
||||||
|
|
||||||
@ -210,6 +209,8 @@ en:
|
|||||||
one: "To make launching your new site easier, you are in bootstrap mode. All new users will be granted trust level 1 and have daily email summary emails enabled. This will be automatically turned off when %{count} user has joined."
|
one: "To make launching your new site easier, you are in bootstrap mode. All new users will be granted trust level 1 and have daily email summary emails enabled. This will be automatically turned off when %{count} user has joined."
|
||||||
other: "To make launching your new site easier, you are in bootstrap mode. All new users will be granted trust level 1 and have daily email summary emails enabled. This will be automatically turned off when %{count} users have joined."
|
other: "To make launching your new site easier, you are in bootstrap mode. All new users will be granted trust level 1 and have daily email summary emails enabled. This will be automatically turned off when %{count} users have joined."
|
||||||
bootstrap_mode_disabled: "Bootstrap mode will be disabled within 24 hours."
|
bootstrap_mode_disabled: "Bootstrap mode will be disabled within 24 hours."
|
||||||
|
bootstrap_invite_button_title: "Send Invites"
|
||||||
|
bootstrap_wizard_link_title: "Finish setup wizard"
|
||||||
|
|
||||||
themes:
|
themes:
|
||||||
default_description: "Default"
|
default_description: "Default"
|
||||||
|
@ -114,13 +114,13 @@ RSpec.describe TranslationOverride do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'sanitizes values before upsert' do
|
it 'sanitizes values before upsert' do
|
||||||
xss = "<a href='%{url}' data-auto-route='true'>setup wizard</a> ✨<script>alert('TEST');</script>"
|
xss = "<a target='blank' href='%{path}'>Click here</a> <script>alert('TEST');</script>"
|
||||||
|
|
||||||
TranslationOverride.upsert!('en', 'js.wizard_required', xss)
|
TranslationOverride.upsert!('en', 'js.themes.error_caused_by', xss)
|
||||||
|
|
||||||
ovr = TranslationOverride.where(locale: 'en', translation_key: 'js.wizard_required').first
|
ovr = TranslationOverride.where(locale: 'en', translation_key: 'js.themes.error_caused_by').first
|
||||||
expect(ovr).to be_present
|
expect(ovr).to be_present
|
||||||
expect(ovr.value).to eq("<a href=\"%{url}\" data-auto-route=\"true\">setup wizard</a> ✨alert('TEST');")
|
expect(ovr.value).to eq("<a href=\"%{path}\">Click here</a> alert('TEST');")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "stores js for a message format key" do
|
it "stores js for a message format key" do
|
||||||
|
Loading…
x
Reference in New Issue
Block a user