UX: Wizard Step Enhancements (#19487)
* UX: Wizard Step Enhancements - Remove illustrations - Add Emoji graphic to top of steps - Add description below step title - Move point of contact to last step * Move step count to header, plus some button navigation tweaks * add remaining emoji to step headers * fix button logic on steps * Update Point of Contact * remove automated messages field * adjust styling for counter, title, and emoji * Update wording for logos * Fix tests * fix prettier * fix specs * set same with for steps except for styling screen * use sentence case; remove duplicate copy under your organization fields * fix missing buttons on small screens * add spacing to buttons; adjust font weight to labels * adjust styling for community logo step; use sentence case for button * update copy for point of contact text helper * use sentence case for field labels * fix ui tests * use btn-back class to fix ui tests * reduce bottom margin for toggle fields * clean up Co-authored-by: Ella <ella.estigoy@gmail.com>
This commit is contained in:
parent
c31113c257
commit
ae2153b330
|
@ -39,7 +39,7 @@ acceptance("Wizard", function (needs) {
|
|||
!exists(".invalid #full_name"),
|
||||
"don't show it as invalid until the user does something"
|
||||
);
|
||||
assert.ok(!exists(".wizard-container__button.back"));
|
||||
assert.ok(!exists(".wizard-container__button.btn-back"));
|
||||
assert.ok(!exists(".wizard-container__field .error"));
|
||||
|
||||
// invalid data
|
||||
|
@ -71,7 +71,7 @@ acceptance("Wizard", function (needs) {
|
|||
|
||||
await visit("/wizard/steps/styling");
|
||||
|
||||
await click(".wizard-container__button.next");
|
||||
await click(".wizard-container__button.primary.next");
|
||||
assert.ok(
|
||||
exists(".wizard-container__text-input#company_name"),
|
||||
"went to the next step"
|
||||
|
@ -84,7 +84,10 @@ acceptance("Wizard", function (needs) {
|
|||
exists(".wizard-container__button.jump-in"),
|
||||
"last step shows a jump in button"
|
||||
);
|
||||
assert.ok(exists(".wizard-container__link.back"), "shows the back button");
|
||||
assert.ok(
|
||||
exists(".wizard-container__button.btn-back"),
|
||||
"shows the back button"
|
||||
);
|
||||
assert.ok(!exists(".wizard-container__step-title"));
|
||||
assert.ok(
|
||||
!exists(".wizard-container__button.next"),
|
||||
|
@ -95,7 +98,7 @@ acceptance("Wizard", function (needs) {
|
|||
"cannot finish on last step"
|
||||
);
|
||||
|
||||
await click(".wizard-container__link.back");
|
||||
await click(".wizard-container__button.btn-back");
|
||||
assert.ok(exists(".wizard-container__step-title"), "shows the step title");
|
||||
assert.ok(
|
||||
exists(".wizard-container__button.next"),
|
||||
|
|
|
@ -26,6 +26,9 @@ export default Component.extend({
|
|||
|
||||
@discourseComputed("step.displayIndex", "wizard.totalSteps")
|
||||
showNextButton(current, total) {
|
||||
if (this.showConfigureMore === true) {
|
||||
return false;
|
||||
}
|
||||
return current < total;
|
||||
},
|
||||
|
||||
|
@ -39,6 +42,11 @@ export default Component.extend({
|
|||
return step === "ready" ? "configure-more" : "next";
|
||||
},
|
||||
|
||||
@discourseComputed("step.id")
|
||||
showConfigureMore(step) {
|
||||
return step === "ready";
|
||||
},
|
||||
|
||||
@discourseComputed("step.id")
|
||||
showJumpInButton(step) {
|
||||
return ["ready", "styling", "branding"].includes(step);
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
{{#if this.field.value}}
|
||||
{{component this.previewComponent field=this.field fieldClass=this.fieldClass wizard=this.wizard}}
|
||||
{{/if}}
|
||||
|
||||
<label class="wizard-container__button wizard-container__button-upload {{if this.uploading "disabled"}}">
|
||||
{{#if this.uploading}}
|
||||
{{i18n "wizard.uploading"}}
|
||||
{{else}}
|
||||
{{i18n "wizard.upload"}}
|
||||
{{d-icon "far-image"}}
|
||||
{{/if}}
|
||||
|
||||
<input class="wizard-hidden-upload-field" disabled={{this.uploading}} type="file" accept="image/*">
|
||||
</label>
|
||||
|
||||
{{#if this.field.value}}
|
||||
{{component this.previewComponent field=this.field fieldClass=this.fieldClass wizard=this.wizard}}
|
||||
{{/if}}
|
||||
|
|
|
@ -1,80 +1,83 @@
|
|||
<div class="wizard-container__step-contents">
|
||||
{{#if this.step.title}}
|
||||
<h1 class="wizard-container__step-title">{{this.step.title}}</h1>
|
||||
{{/if}}
|
||||
<div class="wizard-container__step-counter">
|
||||
<span class="wizard-container__step-text">{{bound-i18n "wizard.step-text"}}</span>
|
||||
<span class="wizard-container__step-count">{{bound-i18n "wizard.step" current=this.step.displayIndex total=this.wizard.totalSteps}}</span>
|
||||
</div>
|
||||
|
||||
<div class="wizard-container__step-container">
|
||||
{{#if this.step.fields}}
|
||||
<WizardStepForm @step={{this.step}}>
|
||||
{{#if this.includeSidebar}}
|
||||
<div class="wizard-container__sidebar">
|
||||
{{#each this.step.fields as |field|}}
|
||||
{{#if field.show_in_sidebar}}
|
||||
<WizardField @field={{field}} @step={{this.step}} @wizard={{this.wizard}} />
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
</div>
|
||||
{{/if}}
|
||||
<div class="wizard-container__fields">
|
||||
{{#each this.step.fields as |field|}}
|
||||
{{#unless field.show_in_sidebar}}
|
||||
<WizardField @field={{field}} @step={{this.step}} @wizard={{this.wizard}} />
|
||||
{{/unless}}
|
||||
{{/each}}
|
||||
<div class="wizard-container">
|
||||
<div class="wizard-container__step-contents">
|
||||
<div class="wizard-container__step-header">
|
||||
{{#if this.step.emoji}}
|
||||
<div class="wizard-container__step-header--emoji">
|
||||
{{emoji this.step.emoji}}
|
||||
</div>
|
||||
</WizardStepForm>
|
||||
{{/if}}
|
||||
{{#if (or this.bannerImage this.step.description)}}
|
||||
<div class={{this.bannerAndDescriptionClass}}>
|
||||
{{/if}}
|
||||
{{#if this.step.title}}
|
||||
<h1 class="wizard-container__step-title">{{this.step.title}}</h1>
|
||||
{{#if this.step.description}}
|
||||
<p class="wizard-container__step-description">{{html-safe this.step.description}}</p>
|
||||
{{/if}}
|
||||
{{#if this.bannerImage}}
|
||||
<div class="wizard-container__step-banner-image">
|
||||
{{#if (eq this.bannerImage "welcome-illustration")}}
|
||||
<IllustrationWelcome />
|
||||
{{else if (eq this.bannerImage "members-illustration")}}
|
||||
<IllustrationMembers />
|
||||
{{else if (eq this.bannerImage "finished-illustration")}}
|
||||
<IllustrationFinished />
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
<div class="wizard-container__step-container">
|
||||
{{#if this.step.fields}}
|
||||
<WizardStepForm @step={{this.step}}>
|
||||
{{#if this.includeSidebar}}
|
||||
<div class="wizard-container__sidebar">
|
||||
{{#each this.step.fields as |field|}}
|
||||
{{#if field.show_in_sidebar}}
|
||||
<WizardField @field={{field}} @step={{this.step}} @wizard={{this.wizard}} />
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
</div>
|
||||
{{/if}}
|
||||
<div class="wizard-container__fields">
|
||||
{{#each this.step.fields as |field|}}
|
||||
{{#unless field.show_in_sidebar}}
|
||||
<WizardField @field={{field}} @step={{this.step}} @wizard={{this.wizard}} />
|
||||
{{/unless}}
|
||||
{{/each}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</WizardStepForm>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="wizard-container__step-footer">
|
||||
<div class="wizard-container__buttons">
|
||||
{{#if this.showBackButton}}
|
||||
<button {{on "click" this.backStep}} disabled={{this.saving}} type="button" class="wizard-container__button btn-back">
|
||||
{{i18n "wizard.back"}}
|
||||
</button>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
<div class="wizard-container__step-progress">
|
||||
{{#if this.showFinishButton}}
|
||||
<button {{on "click" this.exitEarly}} disabled={{this.saving}} type="button" class="wizard-container__button jump-in">
|
||||
{{i18n "wizard.jump_in"}}
|
||||
</button>
|
||||
{{/if}}
|
||||
|
||||
{{#if this.showConfigureMore}}
|
||||
<button {{on "click" this.nextStep}} disabled={{this.saving}} type="button" class="wizard-container__button primary {{this.nextButtonClass}}">
|
||||
{{i18n this.nextButtonLabel}}
|
||||
</button>
|
||||
{{/if}}
|
||||
|
||||
{{#if this.showJumpInButton}}
|
||||
<button {{on "click" this.quit}} disabled={{this.saving}} type="button" class="wizard-container__button {{this.jumpInButtonClass}}">
|
||||
{{i18n this.jumpInButtonLabel}}
|
||||
</button>
|
||||
{{/if}}
|
||||
|
||||
{{#if this.showNextButton}}
|
||||
<button {{on "click" this.nextStep}} disabled={{this.saving}} type="button" class="wizard-container__button primary {{this.nextButtonClass}}">
|
||||
{{i18n this.nextButtonLabel}}
|
||||
</button>
|
||||
{{/if}}
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="wizard-container__step-footer">
|
||||
<div class="wizard-container__buttons">
|
||||
|
||||
{{#if this.showNextButton}}
|
||||
<button {{on "click" this.nextStep}} disabled={{this.saving}} type="button" class="wizard-container__button primary {{this.nextButtonClass}}">
|
||||
{{i18n this.nextButtonLabel}}
|
||||
</button>
|
||||
{{/if}}
|
||||
|
||||
{{#if this.showFinishButton}}
|
||||
<button {{on "click" this.exitEarly}} disabled={{this.saving}} type="button" class="wizard-container__button jump-in">
|
||||
{{i18n "wizard.jump_in"}}
|
||||
</button>
|
||||
{{/if}}
|
||||
|
||||
{{#if this.showJumpInButton}}
|
||||
<button {{on "click" this.quit}} disabled={{this.saving}} type="button" class="wizard-container__button {{this.jumpInButtonClass}}">
|
||||
{{i18n this.jumpInButtonLabel}}
|
||||
</button>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
<div class="wizard-container__step-progress">
|
||||
<a href {{on "click" this.backStep}} class="wizard-container__link back {{unless this.showBackButton "inactive"}}">{{d-icon "chevron-left"}}</a>
|
||||
|
||||
<span class="wizard-container__step-text">{{bound-i18n "wizard.step-text"}}</span>
|
||||
<span class="wizard-container__step-count">{{bound-i18n "wizard.step" current=this.step.displayIndex total=this.wizard.totalSteps}}</span>
|
||||
|
||||
<a href {{on "click" this.nextStep}} class="wizard-container__link {{unless this.showNextButton "inactive"}}">{{d-icon "chevron-right"}}</a>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
|
@ -7,7 +7,5 @@
|
|||
<DiscourseLogo />
|
||||
</div>
|
||||
|
||||
<div class="wizard-container">
|
||||
{{outlet}}
|
||||
</div>
|
||||
{{outlet}}
|
||||
</div>
|
||||
|
|
|
@ -67,33 +67,37 @@ body.wizard {
|
|||
background-color: var(--secondary);
|
||||
box-shadow: 0 4px 19px 6px rgba(0, 0, 0, 0.05);
|
||||
box-sizing: border-box;
|
||||
margin: 3em auto 1.5em auto;
|
||||
margin: 1em auto;
|
||||
padding: 0;
|
||||
max-width: 85%;
|
||||
min-width: 35%;
|
||||
width: 100%;
|
||||
border: 1px solid var(--primary-low);
|
||||
border-radius: 8px;
|
||||
padding: 2em 3em;
|
||||
|
||||
@media screen and (max-height: 800px) {
|
||||
.desktop-view & {
|
||||
margin: 1em auto;
|
||||
}
|
||||
}
|
||||
|
||||
@include breakpoint("mobile-extra-large") {
|
||||
padding: 2em 1.5em;
|
||||
max-width: 99%;
|
||||
margin: 1.5em auto;
|
||||
}
|
||||
|
||||
&__step {
|
||||
margin-top: 1em;
|
||||
max-width: 50%;
|
||||
min-width: 35%;
|
||||
width: 100%;
|
||||
|
||||
&.styling {
|
||||
max-width: 85%;
|
||||
}
|
||||
}
|
||||
|
||||
&__fields {
|
||||
width: 100%;
|
||||
padding-right: 20%;
|
||||
@include breakpoint("large") {
|
||||
padding-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&__step-counter {
|
||||
text-align: center;
|
||||
font-weight: 700;
|
||||
color: var(--primary-medium);
|
||||
}
|
||||
|
||||
&__step-banner {
|
||||
|
@ -102,6 +106,14 @@ body.wizard {
|
|||
}
|
||||
}
|
||||
|
||||
&__step-description {
|
||||
font-size: var(--font-up-2);
|
||||
flex: 1 0 40%;
|
||||
@include breakpoint("tablet") {
|
||||
font-size: var(--font-up-2);
|
||||
}
|
||||
}
|
||||
|
||||
&__step.branding .wizard-container__fields {
|
||||
padding-right: 0;
|
||||
display: flex;
|
||||
|
@ -122,11 +134,11 @@ body.wizard {
|
|||
}
|
||||
}
|
||||
|
||||
&__step.branding .wizard-container__description {
|
||||
max-width: 25em;
|
||||
@include breakpoint("mobile-extra-large") {
|
||||
display: none;
|
||||
}
|
||||
&__step.branding .wizard-container__preview {
|
||||
background-color: var(--primary-very-low);
|
||||
border-radius: 0.5em;
|
||||
padding: 1em;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
&__step.branding .wizard-container__preview canvas {
|
||||
|
@ -136,27 +148,12 @@ body.wizard {
|
|||
}
|
||||
}
|
||||
|
||||
&__step.corporate .wizard-container__fields {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, calc(50% - 1em));
|
||||
grid-column-gap: 2em;
|
||||
grid-template-rows: repeat(3, auto);
|
||||
padding-right: 0;
|
||||
@media only screen and (max-device-width: 568px) {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
}
|
||||
|
||||
&__field {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
&__field.checkbox-field {
|
||||
margin-bottom: 3.5em;
|
||||
@media only screen and (max-device-width: 568px) {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
margin-bottom: 1.5em;
|
||||
}
|
||||
|
||||
&__field.invalid input {
|
||||
|
@ -249,11 +246,22 @@ body.wizard {
|
|||
}
|
||||
}
|
||||
|
||||
&__step-header {
|
||||
text-align: center;
|
||||
margin-bottom: 3em;
|
||||
|
||||
&--emoji img {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
&__step-title {
|
||||
font-size: 2.75em;
|
||||
color: var(--primary);
|
||||
line-height: var(--line-height-medium);
|
||||
margin: 0 0 1.5em 0;
|
||||
margin: 0 0 0.5em 0;
|
||||
@include breakpoint("medium") {
|
||||
font-size: var(--font-up-5);
|
||||
}
|
||||
|
@ -299,13 +307,6 @@ body.wizard {
|
|||
flex: 1 0 100%;
|
||||
gap: 2em;
|
||||
}
|
||||
.wizard-container__step-description {
|
||||
font-size: var(--font-up-3);
|
||||
flex: 1 0 40%;
|
||||
@include breakpoint("tablet") {
|
||||
font-size: var(--font-up-2);
|
||||
}
|
||||
}
|
||||
.wizard-container__step-banner-image {
|
||||
padding-top: 2em;
|
||||
flex: 0 1 40%;
|
||||
|
@ -329,9 +330,6 @@ body.wizard {
|
|||
align-items: center;
|
||||
font-weight: bold;
|
||||
margin-right: -1.5em;
|
||||
@media screen and (max-width: 767px) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@include breakpoint("mobile-extra-large") {
|
||||
margin-bottom: 1em;
|
||||
|
@ -407,15 +405,6 @@ body.wizard {
|
|||
background-color: var(--primary-medium);
|
||||
}
|
||||
|
||||
&__button .d-icon-chevron-right {
|
||||
margin-left: 0.25em;
|
||||
font-size: 0.8em;
|
||||
}
|
||||
&__button .d-icon-chevron-left {
|
||||
margin-right: 0.25em;
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
&__button.primary {
|
||||
background-color: var(--tertiary);
|
||||
color: var(--secondary);
|
||||
|
@ -434,26 +423,27 @@ body.wizard {
|
|||
}
|
||||
|
||||
&__button.configure-more {
|
||||
background-color: var(--primary-200);
|
||||
color: var(--primary);
|
||||
//background-color: var(--primary-200);
|
||||
background-color: transparent;
|
||||
color: var(--tertiary);
|
||||
}
|
||||
|
||||
&__button.configure-more:hover {
|
||||
background-color: var(--primary-300);
|
||||
background-color: transparent;
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
&__button.jump-in {
|
||||
background-color: var(--success);
|
||||
background-color: var(--tertiary);
|
||||
color: var(--secondary);
|
||||
margin-left: 1em;
|
||||
&:hover {
|
||||
background-color: var(--success-hover);
|
||||
background-color: var(--primary-300);
|
||||
}
|
||||
}
|
||||
|
||||
&__button.finish {
|
||||
color: var(--tertiary);
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
&__button.finish:hover {
|
||||
|
@ -467,6 +457,7 @@ body.wizard {
|
|||
|
||||
&__button.next {
|
||||
min-width: 70px;
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
&__button.danger {
|
||||
|
@ -488,12 +479,18 @@ body.wizard {
|
|||
}
|
||||
|
||||
&__button-upload {
|
||||
background-color: var(--primary-low);
|
||||
display: block;
|
||||
background-color: transparent;
|
||||
margin-top: 1em;
|
||||
border: 1px solid var(--tertiary-high);
|
||||
text-align: center;
|
||||
color: var(--tertiary-high);
|
||||
}
|
||||
|
||||
&__button-upload:hover {
|
||||
background-color: var(--primary-low-mid);
|
||||
background-color: transparent;
|
||||
border-color: var(--tertiary-hover);
|
||||
color: var(--tertiary-hover);
|
||||
}
|
||||
|
||||
&__button-upload svg {
|
||||
|
@ -526,19 +523,9 @@ body.wizard {
|
|||
align-items: center;
|
||||
}
|
||||
|
||||
&__image-upload {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
align-items: baseline;
|
||||
}
|
||||
|
||||
&__label {
|
||||
font-weight: bold;
|
||||
font-size: var(--font-up-2);
|
||||
@media only screen and (max-device-width: 568px) {
|
||||
font-size: var(--font-up-1);
|
||||
}
|
||||
font-size: var(--font-up-1);
|
||||
}
|
||||
|
||||
&__step.styling .wizard-container__label {
|
||||
|
@ -568,7 +555,6 @@ body.wizard {
|
|||
color: var(--primary-high);
|
||||
font-size: var(--font-up-1);
|
||||
margin: 0.25em 0 0.5em 0;
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
&__text-input {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
class WizardStepSerializer < ApplicationSerializer
|
||||
|
||||
attributes :id, :next, :previous, :description, :title, :index, :banner
|
||||
attributes :id, :next, :previous, :description, :title, :index, :banner, :emoji
|
||||
has_many :fields, serializer: WizardFieldSerializer, embed: :objects
|
||||
|
||||
def id
|
||||
|
@ -65,4 +65,8 @@ class WizardStepSerializer < ApplicationSerializer
|
|||
object.banner.present?
|
||||
end
|
||||
|
||||
def emoji
|
||||
object.emoji
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -6074,10 +6074,10 @@ en:
|
|||
finish: "Exit setup"
|
||||
back: "Back"
|
||||
next: "Next"
|
||||
configure_more: "Configure More..."
|
||||
configure_more: "Configure more..."
|
||||
step-text: "Step"
|
||||
step: "%{current} of %{total}"
|
||||
upload: "Upload"
|
||||
upload: "Upload file"
|
||||
uploading: "Uploading..."
|
||||
upload_error: "Sorry, there was an error uploading that file. Please try again."
|
||||
|
||||
|
|
|
@ -4930,6 +4930,7 @@ en:
|
|||
step:
|
||||
introduction:
|
||||
title: "Tell us about your community"
|
||||
description: "These will be shown on your login and any public pages. You can always change them later."
|
||||
|
||||
fields:
|
||||
title:
|
||||
|
@ -4938,39 +4939,35 @@ en:
|
|||
site_description:
|
||||
label: "Describe your community in a sentence"
|
||||
placeholder: "A place for Jane and her friends to discuss cool stuff"
|
||||
contact_email:
|
||||
label: "Point of contact"
|
||||
placeholder: "example@user.com"
|
||||
description: "Person or group responsible for this community. Used for critical updates, and listed on <a href='%{base_path}/about' target='_blank'>your about page</a> for urgent contact."
|
||||
default_locale:
|
||||
label: "Language"
|
||||
|
||||
privacy:
|
||||
title: "Member Experience"
|
||||
title: "Member experience"
|
||||
|
||||
fields:
|
||||
login_required:
|
||||
placeholder: "Private"
|
||||
extra_description: "Only logged in users can access this community"
|
||||
invite_only:
|
||||
placeholder: "Invite Only"
|
||||
placeholder: "Invite only"
|
||||
extra_description: "Users must be invited by trusted users or staff, otherwise users can sign up on their own"
|
||||
must_approve_users:
|
||||
placeholder: "Require Approval"
|
||||
placeholder: "Require approval"
|
||||
extra_description: "Users must be approved by staff"
|
||||
chat_enabled:
|
||||
placeholder: "Enable Chat"
|
||||
placeholder: "Enable chat"
|
||||
extra_description: "Engage with your members in real time"
|
||||
enable_sidebar:
|
||||
placeholder: "Enable Sidebar"
|
||||
placeholder: "Enable sidebar"
|
||||
extra_description: "Access your favorite spaces with ease"
|
||||
|
||||
ready:
|
||||
title: "Your Discourse is Ready!"
|
||||
title: "Your site is ready!"
|
||||
description: "That's it! You've done the basics to setup your community. Now you can jump in and have a look around, write a welcome topic, and send invites!<br><br>Have fun!"
|
||||
|
||||
styling:
|
||||
title: "Look & Feel"
|
||||
title: "Look and feel"
|
||||
fields:
|
||||
color_scheme:
|
||||
label: "Color scheme"
|
||||
|
@ -5003,38 +5000,39 @@ en:
|
|||
label: "Subcategories with Featured Topics"
|
||||
|
||||
branding:
|
||||
title: "Customize Logos"
|
||||
title: "Community logo"
|
||||
fields:
|
||||
logo:
|
||||
label: "Primary Logo"
|
||||
description: "The logo at the top left of your site. Use a wide rectangular image with a height of 120 and an aspect ratio greater than 3:1"
|
||||
label: "Primary logo"
|
||||
description: "Recommended size: 600 x 200"
|
||||
logo_small:
|
||||
label: "Square Logo"
|
||||
description: "A square version of your logo. Shown at the top left when scrolling down, and when sharing on social platforms. Ideally at least 512x512."
|
||||
label: "Square logo"
|
||||
description: "Recommended size: 512 x 512. Also used as the favicon and mobile home screen app icon."
|
||||
|
||||
corporate:
|
||||
title: "Your Organization"
|
||||
title: "Your organization"
|
||||
description: "The following information will be used in your Terms of Service and About pages. Feel free to skip if no company exists."
|
||||
|
||||
fields:
|
||||
company_name:
|
||||
label: "Company Name"
|
||||
placeholder: "Example Organization"
|
||||
description: "Entered in your Terms of Service page. Feel free to skip if no company exists."
|
||||
label: "Company name"
|
||||
placeholder: "Acme Organization"
|
||||
governing_law:
|
||||
label: "Governing Law"
|
||||
label: "Governing law"
|
||||
placeholder: "California law"
|
||||
description: "Entered in your Terms of Service page. Feel free to skip if no company exists."
|
||||
contact_url:
|
||||
label: "Web Page"
|
||||
label: "Web page"
|
||||
placeholder: "https://www.example.com/contact-us"
|
||||
description: "General contact web page for you or your organization. Will be displayed on <a href='%{base_path}/about' target='_blank'>your about page</a>."
|
||||
city_for_disputes:
|
||||
label: "City for Disputes"
|
||||
label: "City for disputes"
|
||||
placeholder: "San Francisco, California"
|
||||
description: "Entered in your Terms of Service page. Feel free to skip if no company exists."
|
||||
site_contact:
|
||||
label: "Automated Messages"
|
||||
label: "Automated messages"
|
||||
description: "All automated Discourse personal messages will be sent from this user, such as flag warnings and backup completion notices."
|
||||
contact_email:
|
||||
label: "Point of contact"
|
||||
placeholder: "example@user.com"
|
||||
description: "Email address of key contact responsible for this site. Used for critical notifications, and listed on your <a href='%{base_path}/about' target='_blank'>your about page</a> for urgent matters."
|
||||
|
||||
invites:
|
||||
title: "Invite Staff"
|
||||
|
|
|
@ -12,10 +12,11 @@ class Wizard
|
|||
|
||||
@wizard.append_step('introduction') do |step|
|
||||
step.banner = "welcome-illustration"
|
||||
step.emoji = "wave"
|
||||
step.description_vars = { base_path: Discourse.base_path }
|
||||
|
||||
step.add_field(id: 'title', type: 'text', required: true, value: SiteSetting.title == SiteSetting.defaults[:title] ? "" : SiteSetting.title)
|
||||
step.add_field(id: 'site_description', type: 'text', required: false, value: SiteSetting.site_description)
|
||||
step.add_field(id: 'contact_email', type: 'text', required: true, value: SiteSetting.contact_email)
|
||||
|
||||
languages = step.add_field(id: 'default_locale',
|
||||
type: 'dropdown',
|
||||
|
@ -30,7 +31,7 @@ class Wizard
|
|||
updater.ensure_changed(:title)
|
||||
|
||||
if updater.errors.blank?
|
||||
updater.apply_settings(:title, :site_description, :contact_email)
|
||||
updater.apply_settings(:title, :site_description)
|
||||
end
|
||||
|
||||
old_locale = SiteSetting.default_locale
|
||||
|
@ -49,6 +50,7 @@ class Wizard
|
|||
|
||||
@wizard.append_step('privacy') do |step|
|
||||
step.banner = "members-illustration"
|
||||
step.emoji = "hugs"
|
||||
step.add_field(
|
||||
id: 'login_required',
|
||||
type: 'checkbox',
|
||||
|
@ -98,9 +100,25 @@ class Wizard
|
|||
@wizard.append_step('ready') do |step|
|
||||
# no form on this page, just info.
|
||||
step.banner = "finished-illustration"
|
||||
step.emoji = "rocket"
|
||||
end
|
||||
|
||||
@wizard.append_step('branding') do |step|
|
||||
step.emoji = "framed_picture"
|
||||
step.add_field(id: 'logo', type: 'image', value: SiteSetting.site_logo_url)
|
||||
step.add_field(id: 'logo_small', type: 'image', value: SiteSetting.site_logo_small_url)
|
||||
|
||||
step.on_update do |updater|
|
||||
if SiteSetting.site_logo_url != updater.fields[:logo] ||
|
||||
SiteSetting.site_logo_small_url != updater.fields[:logo_small]
|
||||
updater.apply_settings(:logo, :logo_small)
|
||||
updater.refresh_required = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@wizard.append_step('styling') do |step|
|
||||
step.emoji = "art"
|
||||
default_theme = Theme.find_by(id: SiteSetting.default_theme_id)
|
||||
default_theme_override = SiteSetting.exists?(name: "default_theme_id")
|
||||
|
||||
|
@ -205,34 +223,14 @@ class Wizard
|
|||
end
|
||||
end
|
||||
|
||||
@wizard.append_step('branding') do |step|
|
||||
step.add_field(id: 'logo', type: 'image', value: SiteSetting.site_logo_url)
|
||||
step.add_field(id: 'logo_small', type: 'image', value: SiteSetting.site_logo_small_url)
|
||||
|
||||
step.on_update do |updater|
|
||||
if SiteSetting.site_logo_url != updater.fields[:logo] ||
|
||||
SiteSetting.site_logo_small_url != updater.fields[:logo_small]
|
||||
updater.apply_settings(:logo, :logo_small)
|
||||
updater.refresh_required = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@wizard.append_step('corporate') do |step|
|
||||
step.emoji = "briefcase"
|
||||
step.description_vars = { base_path: Discourse.base_path }
|
||||
step.add_field(id: 'company_name', type: 'text', value: SiteSetting.company_name)
|
||||
step.add_field(id: 'governing_law', type: 'text', value: SiteSetting.governing_law)
|
||||
step.add_field(id: 'contact_url', type: 'text', value: SiteSetting.contact_url)
|
||||
step.add_field(id: 'city_for_disputes', type: 'text', value: SiteSetting.city_for_disputes)
|
||||
|
||||
username = SiteSetting.site_contact_username
|
||||
username = Discourse.system_user.username if username.blank?
|
||||
contact = step.add_field(id: 'site_contact', type: 'dropdown', value: username)
|
||||
|
||||
User.human_users.where(admin: true).pluck(:username).each do |c|
|
||||
contact.add_choice(c) unless reserved_usernames.include?(c.downcase)
|
||||
end
|
||||
contact.add_choice(Discourse.system_user.username)
|
||||
step.add_field(id: 'contact_email', type: 'text', value: SiteSetting.contact_email)
|
||||
|
||||
step.on_update do |updater|
|
||||
update_tos do |raw|
|
||||
|
@ -241,8 +239,9 @@ class Wizard
|
|||
replace_setting_value(updater, raw, 'city_for_disputes')
|
||||
end
|
||||
|
||||
updater.apply_settings(:company_name, :governing_law, :city_for_disputes, :contact_url)
|
||||
updater.update_setting(:site_contact_username, updater.fields[:site_contact])
|
||||
if updater.errors.blank?
|
||||
updater.apply_settings(:company_name, :governing_law, :city_for_disputes, :contact_url, :contact_email)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
class Wizard
|
||||
class Step
|
||||
attr_reader :id, :updater
|
||||
attr_accessor :index, :fields, :next, :previous, :banner, :disabled, :description_vars
|
||||
attr_accessor :index, :fields, :next, :previous, :banner, :disabled, :description_vars, :emoji
|
||||
|
||||
def initialize(id)
|
||||
@id = id
|
||||
|
|
|
@ -14,14 +14,12 @@ RSpec.describe Wizard::StepUpdater do
|
|||
updater = wizard.create_updater('introduction',
|
||||
title: 'new forum title',
|
||||
site_description: 'neat place',
|
||||
default_locale: locale,
|
||||
contact_email: 'eviltrout@example.com')
|
||||
default_locale: locale)
|
||||
updater.update
|
||||
|
||||
expect(updater.success?).to eq(true)
|
||||
expect(SiteSetting.title).to eq("new forum title")
|
||||
expect(SiteSetting.site_description).to eq("neat place")
|
||||
expect(SiteSetting.contact_email).to eq("eviltrout@example.com")
|
||||
expect(updater.refresh_required?).to eq(false)
|
||||
expect(wizard.completed_steps?('introduction')).to eq(true)
|
||||
end
|
||||
|
@ -331,13 +329,15 @@ RSpec.describe Wizard::StepUpdater do
|
|||
company_name: 'ACME, Inc.',
|
||||
governing_law: 'New Jersey law',
|
||||
contact_url: 'http://example.com/custom-contact-url',
|
||||
city_for_disputes: 'Fairfield, New Jersey')
|
||||
city_for_disputes: 'Fairfield, New Jersey',
|
||||
contact_email: 'eviltrout@example.com')
|
||||
updater.update
|
||||
expect(updater).to be_success
|
||||
expect(SiteSetting.company_name).to eq("ACME, Inc.")
|
||||
expect(SiteSetting.governing_law).to eq("New Jersey law")
|
||||
expect(SiteSetting.contact_url).to eq("http://example.com/custom-contact-url")
|
||||
expect(SiteSetting.city_for_disputes).to eq("Fairfield, New Jersey")
|
||||
expect(SiteSetting.contact_email).to eq("eviltrout@example.com")
|
||||
|
||||
# Should update the TOS topic
|
||||
raw = Post.where(topic_id: SiteSetting.tos_topic_id, post_number: 1).pluck_first(:raw)
|
||||
|
|
|
@ -39,14 +39,11 @@ RSpec.describe Wizard::Builder do
|
|||
fields = introduction_step.fields
|
||||
title_field = fields.first
|
||||
description_field = fields.second
|
||||
contact_email_field = fields.third
|
||||
|
||||
expect(title_field.id).to eq('title')
|
||||
expect(title_field.value).to eq("")
|
||||
expect(description_field.id).to eq('site_description')
|
||||
expect(description_field.value).to eq("")
|
||||
expect(contact_email_field.id).to eq('contact_email')
|
||||
expect(contact_email_field.value).to eq("")
|
||||
end
|
||||
|
||||
it 'should prefill overridden site setting values' do
|
||||
|
@ -57,14 +54,11 @@ RSpec.describe Wizard::Builder do
|
|||
fields = introduction_step.fields
|
||||
title_field = fields.first
|
||||
description_field = fields.second
|
||||
contact_email_field = fields.third
|
||||
|
||||
expect(title_field.id).to eq('title')
|
||||
expect(title_field.value).to eq("foobar")
|
||||
expect(description_field.id).to eq('site_description')
|
||||
expect(description_field.value).to eq("lorem ipsum")
|
||||
expect(contact_email_field.id).to eq('contact_email')
|
||||
expect(contact_email_field.value).to eq("foobar@example.com")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -37,16 +37,15 @@ RSpec.describe StepsController do
|
|||
|
||||
it "updates properly if you are staff" do
|
||||
put "/wizard/steps/introduction.json", params: {
|
||||
fields: { title: "FooBar", default_locale: SiteSetting.default_locale, contact_email: "eviltrout@example.com" }
|
||||
fields: { title: "FooBar", default_locale: SiteSetting.default_locale }
|
||||
}
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(SiteSetting.contact_email).to eq("eviltrout@example.com")
|
||||
end
|
||||
|
||||
it "returns errors if the field has them" do
|
||||
put "/wizard/steps/introduction.json", params: {
|
||||
fields: { contact_email: "not-an-email" }
|
||||
fields: { title: "" }
|
||||
}
|
||||
|
||||
expect(response.status).to eq(422)
|
||||
|
|
Loading…
Reference in New Issue