UX: Add Styling step to wizard (#14132)
Refactors three wizard steps (colors, fonts, homepage style) into one new step called Styling.
This commit is contained in:
parent
cfbf69848a
commit
85b8fea262
|
@ -1,6 +1,5 @@
|
|||
import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row";
|
||||
import { computed } from "@ember/object";
|
||||
import { escapeExpression } from "discourse/lib/utilities";
|
||||
import layout from "select-kit/templates/components/color-palettes/color-palettes-row";
|
||||
|
||||
export default SelectKitRowComponent.extend({
|
||||
|
@ -10,7 +9,7 @@ export default SelectKitRowComponent.extend({
|
|||
palettes: computed("item.colors.[]", function () {
|
||||
return (this.item.colors || [])
|
||||
.filter((color) => color.name !== "secondary")
|
||||
.map((color) => `#${escapeExpression(color.hex)}`)
|
||||
.map((color) => `#${escape(color.hex)}`)
|
||||
.map(
|
||||
(hex) => `<span class="palette" style="background-color:${hex}"></span>`
|
||||
)
|
||||
|
@ -22,7 +21,7 @@ export default SelectKitRowComponent.extend({
|
|||
const secondary = (this.item.colors || []).findBy("name", "secondary");
|
||||
|
||||
if (secondary && secondary.hex) {
|
||||
return `background-color:#${escapeExpression(secondary.hex)}`.htmlSafe();
|
||||
return `background-color:#${escape(secondary.hex)}`.htmlSafe();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
|
|
|
@ -3,14 +3,14 @@ import {
|
|||
createPreviewComponent,
|
||||
darkLightDiff,
|
||||
} from "wizard/lib/preview";
|
||||
import { observes } from "discourse-common/utils/decorators";
|
||||
|
||||
export default createPreviewComponent(659, 320, {
|
||||
logo: null,
|
||||
avatar: null,
|
||||
|
||||
@observes("step.fieldsById.homepage_style.value")
|
||||
styleChanged() {
|
||||
didUpdateAttrs() {
|
||||
this._super(...arguments);
|
||||
|
||||
this.triggerRepaint();
|
||||
},
|
||||
|
||||
|
@ -22,7 +22,9 @@ export default createPreviewComponent(659, 320, {
|
|||
},
|
||||
|
||||
paint({ ctx, colors, font, width, height }) {
|
||||
this.drawFullHeader(colors, font, this.logo);
|
||||
if (this.logo) {
|
||||
this.drawFullHeader(colors, font, this.logo);
|
||||
}
|
||||
|
||||
if (this.get("step.fieldsById.homepage_style.value") === "latest") {
|
||||
this.drawPills(colors, font, height * 0.15);
|
||||
|
|
|
@ -15,13 +15,66 @@ metus. Fusce in consequat augue, vel facilisis felis.`;
|
|||
export default createPreviewComponent(659, 320, {
|
||||
logo: null,
|
||||
avatar: null,
|
||||
previewTopic: true,
|
||||
draggingActive: false,
|
||||
startX: 0,
|
||||
scrollLeft: 0,
|
||||
|
||||
mouseDown(e) {
|
||||
const slider = this.element.querySelector(".previews");
|
||||
this.setProperties({
|
||||
draggingActive: true,
|
||||
startX: e.pageX - slider.offsetLeft,
|
||||
scrollLeft: slider.scrollLeft,
|
||||
});
|
||||
},
|
||||
|
||||
mouseLeave() {
|
||||
this.set("draggingActive", false);
|
||||
},
|
||||
|
||||
mouseUp() {
|
||||
this.set("draggingActive", false);
|
||||
},
|
||||
|
||||
mouseMove(e) {
|
||||
if (!this.draggingActive) {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
|
||||
const slider = this.element.querySelector(".previews"),
|
||||
x = e.pageX - slider.offsetLeft,
|
||||
walk = (x - this.startX) * 1.5;
|
||||
|
||||
slider.scrollLeft = this.scrollLeft - walk;
|
||||
|
||||
if (slider.scrollLeft < 50) {
|
||||
this.set("previewTopic", true);
|
||||
}
|
||||
if (slider.scrollLeft > slider.offsetWidth) {
|
||||
this.set("previewTopic", false);
|
||||
}
|
||||
},
|
||||
|
||||
didUpdateAttrs() {
|
||||
this._super(...arguments);
|
||||
|
||||
@observes(
|
||||
"step.fieldsById.body_font.value",
|
||||
"step.fieldsById.heading_font.value"
|
||||
)
|
||||
fontChanged() {
|
||||
this.triggerRepaint();
|
||||
|
||||
if (this.stylingDropdown?.id === "homepage_style") {
|
||||
this.set("previewTopic", false);
|
||||
}
|
||||
},
|
||||
|
||||
@observes("previewTopic")
|
||||
scrollPreviewArea() {
|
||||
const el = this.element.querySelector(".previews");
|
||||
el.scrollTo({
|
||||
top: 0,
|
||||
left: this.previewTopic ? 0 : el.scrollWidth - el.offsetWidth,
|
||||
behavior: "smooth",
|
||||
});
|
||||
},
|
||||
|
||||
images() {
|
||||
|
@ -39,14 +92,14 @@ export default createPreviewComponent(659, 320, {
|
|||
}
|
||||
|
||||
const margin = 20;
|
||||
const avatarSize = height * 0.2;
|
||||
const lineHeight = height / 11;
|
||||
const avatarSize = height * 0.15;
|
||||
const lineHeight = height / 14;
|
||||
|
||||
// Draw a fake topic
|
||||
this.scaleImage(
|
||||
this.avatar,
|
||||
margin,
|
||||
headerHeight + height * 0.11,
|
||||
headerHeight + height * 0.09,
|
||||
avatarSize,
|
||||
avatarSize
|
||||
);
|
||||
|
@ -80,7 +133,7 @@ export default createPreviewComponent(659, 320, {
|
|||
ctx.fillText(
|
||||
I18n.t("wizard.previews.share_button"),
|
||||
margin + 10,
|
||||
line + lineHeight * 1.7
|
||||
line + lineHeight * 1.9
|
||||
);
|
||||
|
||||
// Reply Button
|
||||
|
@ -100,7 +153,7 @@ export default createPreviewComponent(659, 320, {
|
|||
ctx.fillText(
|
||||
I18n.t("wizard.previews.reply_button"),
|
||||
shareButtonWidth + margin + 20,
|
||||
line + lineHeight * 1.7
|
||||
line + lineHeight * 1.9
|
||||
);
|
||||
|
||||
// Draw Timeline
|
||||
|
@ -124,4 +177,14 @@ export default createPreviewComponent(659, 320, {
|
|||
ctx.fillStyle = colors.primary;
|
||||
ctx.fillText("1 / 20", timelineX + margin, height * 0.3 + margin * 1.5);
|
||||
},
|
||||
|
||||
actions: {
|
||||
setPreviewHomepage() {
|
||||
this.set("previewTopic", false);
|
||||
},
|
||||
|
||||
setPreviewTopic() {
|
||||
this.set("previewTopic", true);
|
||||
},
|
||||
},
|
||||
});
|
|
@ -1,8 +0,0 @@
|
|||
import Component from "@ember/component";
|
||||
export default Component.extend({
|
||||
actions: {
|
||||
changed(value) {
|
||||
this.set("field.value", value);
|
||||
},
|
||||
},
|
||||
});
|
|
@ -1,7 +1,36 @@
|
|||
import Component from "@ember/component";
|
||||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
import { set } from "@ember/object";
|
||||
|
||||
export default Component.extend({
|
||||
init(...args) {
|
||||
this._super(...args);
|
||||
|
||||
if (this.field.id === "color_scheme") {
|
||||
for (let choice of this.field.choices) {
|
||||
if (choice?.data?.colors) {
|
||||
set(choice, "colors", choice.data.colors);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@discourseComputed("field.id")
|
||||
componentName(id) {
|
||||
if (id === "color_scheme") {
|
||||
return "color-palettes";
|
||||
}
|
||||
return "combo-box";
|
||||
},
|
||||
|
||||
keyPress(e) {
|
||||
e.stopPropagation();
|
||||
},
|
||||
|
||||
actions: {
|
||||
onChangeValue(value) {
|
||||
this.set("field.value", value);
|
||||
this.stylingDropdownChanged(this.field.id, value);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -3,10 +3,11 @@ import { dasherize } from "@ember/string";
|
|||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
|
||||
export default Component.extend({
|
||||
classNameBindings: [":wizard-field", "typeClass", "field.invalid"],
|
||||
classNameBindings: [":wizard-field", "typeClasses", "field.invalid"],
|
||||
|
||||
@discourseComputed("field.type")
|
||||
typeClass: (type) => `${dasherize(type)}-field`,
|
||||
@discourseComputed("field.type", "field.id")
|
||||
typeClasses: (type, id) =>
|
||||
`${dasherize(type)}-field ${dasherize(type)}-${dasherize(id)}`,
|
||||
|
||||
@discourseComputed("field.id")
|
||||
fieldClass: (id) => `field-${dasherize(id)} wizard-focusable`,
|
||||
|
|
|
@ -27,6 +27,11 @@ export default Component.extend({
|
|||
classNames: ["wizard-step"],
|
||||
saving: null,
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.set("stylingDropdown", {});
|
||||
},
|
||||
|
||||
didInsertElement() {
|
||||
this._super(...arguments);
|
||||
this.autoFocus();
|
||||
|
@ -96,6 +101,11 @@ export default Component.extend({
|
|||
return htmlSafe(`width: ${ratio * 200}px`);
|
||||
},
|
||||
|
||||
@discourseComputed("step.fields")
|
||||
includeSidebar(fields) {
|
||||
return !!fields.findBy("show_in_sidebar");
|
||||
},
|
||||
|
||||
autoFocus() {
|
||||
schedule("afterRender", () => {
|
||||
const $invalid = $(
|
||||
|
@ -130,6 +140,10 @@ export default Component.extend({
|
|||
document.location = getUrl("/");
|
||||
},
|
||||
|
||||
stylingDropdownChanged(id, value) {
|
||||
this.set("stylingDropdown", { id, value });
|
||||
},
|
||||
|
||||
exitEarly() {
|
||||
const step = this.step;
|
||||
step.validate();
|
||||
|
|
|
@ -12,7 +12,7 @@ export default Controller.extend({
|
|||
|
||||
@discourseComputed("model")
|
||||
fontClasses(model) {
|
||||
const fontsStep = model.steps.findBy("id", "fonts");
|
||||
const fontsStep = model.steps.findBy("id", "styling");
|
||||
if (!fontsStep) {
|
||||
return [];
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ import Component from "@ember/component";
|
|||
import { Promise } from "rsvp";
|
||||
/*eslint no-bitwise:0 */
|
||||
import getUrl from "discourse-common/lib/get-url";
|
||||
import { htmlSafe } from "@ember/template";
|
||||
import { scheduleOnce } from "@ember/runloop";
|
||||
|
||||
export const LOREM = `
|
||||
|
@ -41,7 +42,7 @@ export function createPreviewComponent(width, height, obj) {
|
|||
height,
|
||||
elementWidth: width * scale,
|
||||
elementHeight: height * scale,
|
||||
canvasStyle: `width:${width}px;height:${height}px`,
|
||||
canvasStyle: htmlSafe(`width:${width}px;height:${height}px`),
|
||||
ctx: null,
|
||||
loaded: false,
|
||||
|
||||
|
@ -87,11 +88,17 @@ export function createPreviewComponent(width, height, obj) {
|
|||
return false;
|
||||
}
|
||||
|
||||
const colors = this.wizard.getCurrentColors(this.colorsId);
|
||||
if (!colors) {
|
||||
const colorsArray = this.wizard.getCurrentColors(this.colorsId);
|
||||
if (!colorsArray) {
|
||||
return;
|
||||
}
|
||||
|
||||
let colors = {};
|
||||
colorsArray.forEach(function (c) {
|
||||
const name = c.name;
|
||||
colors[name] = `#${c.hex}`;
|
||||
});
|
||||
|
||||
const font = this.wizard.getCurrentFont(this.fontId);
|
||||
const headingFont = this.wizard.getCurrentFont(
|
||||
this.fontId,
|
||||
|
@ -115,12 +122,6 @@ export function createPreviewComponent(width, height, obj) {
|
|||
height: this.height,
|
||||
};
|
||||
this.paint(options);
|
||||
|
||||
// draw border
|
||||
ctx.beginPath();
|
||||
ctx.strokeStyle = "rgba(0, 0, 0, 0.2)";
|
||||
ctx.rect(0, 0, width, height);
|
||||
ctx.stroke();
|
||||
},
|
||||
|
||||
categories() {
|
||||
|
|
|
@ -26,12 +26,12 @@ const Wizard = EmberObject.extend({
|
|||
|
||||
// A bit clunky, but get the current colors from the appropriate step
|
||||
getCurrentColors(schemeId) {
|
||||
const colorStep = this.steps.findBy("id", "colors");
|
||||
const colorStep = this.steps.findBy("id", "styling");
|
||||
if (!colorStep) {
|
||||
return this.current_color_scheme;
|
||||
}
|
||||
|
||||
const themeChoice = colorStep.get("fieldsById.theme_previews");
|
||||
const themeChoice = colorStep.get("fieldsById.color_scheme");
|
||||
if (!themeChoice) {
|
||||
return;
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ const Wizard = EmberObject.extend({
|
|||
},
|
||||
|
||||
getCurrentFont(fontId, type = "body_font") {
|
||||
const fontsStep = this.steps.findBy("id", "fonts");
|
||||
const fontsStep = this.steps.findBy("id", "styling");
|
||||
if (!fontsStep) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
<div class="preview-area">
|
||||
<canvas
|
||||
width={{elementWidth}}
|
||||
height={{elementHeight}}
|
||||
style={{canvasStyle}}
|
||||
>
|
||||
</canvas>
|
||||
</div>
|
|
@ -0,0 +1,22 @@
|
|||
<div class="previews {{if draggingActive "dragging"}}">
|
||||
<div class="preview-area topic-preview">
|
||||
<canvas width={{elementWidth}} height={{elementHeight}} style={{canvasStyle}}>
|
||||
</canvas>
|
||||
</div>
|
||||
<div class="preview-area homepage-preview">
|
||||
{{homepage-preview
|
||||
wizard=wizard
|
||||
step=step
|
||||
stylingDropdown=stylingDropdown
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="preview-nav">
|
||||
<a href class="preview-nav-button {{if previewTopic "active"}}" {{action "setPreviewTopic"}}>
|
||||
{{i18n "wizard.previews.topic_preview"}}
|
||||
</a>
|
||||
<a href class="preview-nav-button {{unless previewTopic "active"}}" {{action "setPreviewHomepage"}}>
|
||||
{{i18n "wizard.previews.homepage_preview"}}
|
||||
</a>
|
||||
</div>
|
|
@ -1,14 +0,0 @@
|
|||
<ul class="grid">
|
||||
{{#each field.choices as |choice|}}
|
||||
<li>
|
||||
{{theme-preview colorsId=choice.id
|
||||
wizard=wizard
|
||||
selectedId=field.value
|
||||
onChange=(action "changed")}}
|
||||
{{radio-button radioValue=choice.id
|
||||
label=choice.id
|
||||
value=field.value
|
||||
onChange=(action "changed")}}
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
|
@ -1,9 +1,12 @@
|
|||
{{combo-box
|
||||
id=field.id
|
||||
{{component
|
||||
componentName
|
||||
class=fieldClass
|
||||
value=field.value
|
||||
content=field.choices
|
||||
nameProperty="label"
|
||||
tabindex="9"
|
||||
onChange=(action (mut field.value))
|
||||
onChange=(action "onChangeValue")
|
||||
options=(hash
|
||||
translatedNone=false
|
||||
)
|
||||
}}
|
||||
|
|
|
@ -13,7 +13,14 @@
|
|||
</label>
|
||||
|
||||
<div class="input-area">
|
||||
{{component inputComponentName field=field step=step fieldClass=fieldClass wizard=wizard}}
|
||||
{{component
|
||||
inputComponentName
|
||||
field=field step=step
|
||||
fieldClass=fieldClass
|
||||
wizard=wizard
|
||||
stylingDropdownChanged=stylingDropdownChanged
|
||||
stylingDropdown=stylingDropdown
|
||||
}}
|
||||
</div>
|
||||
|
||||
{{#if field.errorDescription}}
|
||||
|
|
|
@ -14,9 +14,32 @@
|
|||
</div>
|
||||
|
||||
{{#wizard-step-form step=step}}
|
||||
{{#each step.fields as |field|}}
|
||||
{{wizard-field field=field step=step wizard=wizard}}
|
||||
{{/each}}
|
||||
{{#if includeSidebar}}
|
||||
<div class="wizard-fields-sidebar">
|
||||
{{#each step.fields as |field|}}
|
||||
{{#if field.show_in_sidebar}}
|
||||
{{wizard-field
|
||||
field=field
|
||||
step=step
|
||||
wizard=wizard
|
||||
stylingDropdownChanged=(action "stylingDropdownChanged")
|
||||
}}
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
</div>
|
||||
{{/if}}
|
||||
<div class="wizard-fields-main">
|
||||
{{#each step.fields as |field|}}
|
||||
{{#unless field.show_in_sidebar}}
|
||||
{{wizard-field
|
||||
field=field
|
||||
step=step
|
||||
wizard=wizard
|
||||
stylingDropdown=stylingDropdown
|
||||
}}
|
||||
{{/unless}}
|
||||
{{/each}}
|
||||
</div>
|
||||
{{/wizard-step-form}}
|
||||
</div>
|
||||
|
||||
|
|
|
@ -820,66 +820,78 @@ body.wizard {
|
|||
|
||||
.wizard-step-form {
|
||||
max-height: 500px;
|
||||
}
|
||||
display: flex;
|
||||
|
||||
.wizard-step-homepage {
|
||||
.field-homepage-style {
|
||||
width: 280px;
|
||||
.wizard-fields-main {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.wizard-step-colors {
|
||||
max-height: 465px;
|
||||
overflow-y: auto;
|
||||
.grid {
|
||||
.wizard-fields-sidebar {
|
||||
width: 170px;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-around;
|
||||
padding: 0;
|
||||
margin: 0 auto;
|
||||
list-style-type: none;
|
||||
text-align: center;
|
||||
|
||||
li {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
margin: 0 5px 25px 5px;
|
||||
label:checked + div {
|
||||
display: none;
|
||||
}
|
||||
.is-selected {
|
||||
box-shadow: 0 0 0 5px var(--tertiary);
|
||||
}
|
||||
div {
|
||||
display: flex;
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
.radio-area {
|
||||
display: none;
|
||||
& > * {
|
||||
position: relative;
|
||||
right: 7px;
|
||||
}
|
||||
}
|
||||
canvas {
|
||||
transition: box-shadow 0.25s;
|
||||
&:hover {
|
||||
box-shadow: shadow("card");
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
padding: 30px 0px 15px 15px;
|
||||
background: var(--primary-very-low);
|
||||
+ .wizard-fields-main {
|
||||
padding: 15px;
|
||||
padding-top: 30px;
|
||||
background: var(--primary-very-low);
|
||||
width: calc(100% - 170px);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.wizard-step-fonts {
|
||||
.dropdown-field {
|
||||
float: left;
|
||||
margin-right: 1.5em;
|
||||
.wizard-step-styling {
|
||||
.preview-nav {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
position: relative;
|
||||
margin-top: -1px;
|
||||
padding-right: 10px;
|
||||
.preview-nav-button {
|
||||
text-align: center;
|
||||
padding: 10px 15px;
|
||||
cursor: pointer;
|
||||
margin-left: 10px;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
color: var(--primary-high);
|
||||
&.active {
|
||||
background: var(--secondary);
|
||||
border-bottom-left-radius: 10px;
|
||||
border-bottom-right-radius: 10px;
|
||||
color: var(--tertiary);
|
||||
border: 1px dashed var(--tertiary-low);
|
||||
border-top: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
.component-field {
|
||||
clear: both;
|
||||
|
||||
.previews {
|
||||
position: relative;
|
||||
height: 320px;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
background: var(--secondary);
|
||||
border: 1px dashed var(--tertiary-low);
|
||||
border-radius: 10px;
|
||||
cursor: grab;
|
||||
user-select: none;
|
||||
&.dragging {
|
||||
cursor: grabbing;
|
||||
}
|
||||
.topic-preview {
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
transform: scale(0.85) translateX(-45px);
|
||||
}
|
||||
.homepage-preview {
|
||||
position: absolute;
|
||||
left: calc(100% + 25px);
|
||||
top: 0px;
|
||||
transform: scale(0.85);
|
||||
padding-right: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -891,7 +903,7 @@ body.wizard {
|
|||
box-sizing: border-box;
|
||||
margin: 1.5em auto;
|
||||
padding: 0;
|
||||
max-width: 700px;
|
||||
max-width: 820px;
|
||||
min-width: 280px;
|
||||
width: 100%;
|
||||
border: 1px solid var(--primary-low-mid);
|
||||
|
@ -924,7 +936,7 @@ body.wizard {
|
|||
}
|
||||
.wizard-step-banner {
|
||||
margin-bottom: 2em;
|
||||
width: 620px;
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
@ -1178,6 +1190,10 @@ body.wizard {
|
|||
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
|
||||
.wizard-image-row canvas {
|
||||
border: 1px solid rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
.textarea-field {
|
||||
|
|
|
@ -133,10 +133,10 @@ class ColorScheme < ActiveRecord::Base
|
|||
LIGHT_THEME_ID = 'Light'
|
||||
|
||||
def self.base_color_scheme_colors
|
||||
base_with_hash = {}
|
||||
base_with_hash = []
|
||||
|
||||
base_colors.each do |name, color|
|
||||
base_with_hash[name] = "#{color}"
|
||||
base_with_hash << { name: name, hex: "#{color}" }
|
||||
end
|
||||
|
||||
list = [
|
||||
|
@ -144,7 +144,11 @@ class ColorScheme < ActiveRecord::Base
|
|||
]
|
||||
|
||||
CUSTOM_SCHEMES.each do |k, v|
|
||||
list.push(id: k.to_s, colors: v)
|
||||
colors = []
|
||||
v.each do |name, color|
|
||||
colors << { name: name, hex: "#{color}" }
|
||||
end
|
||||
list.push(id: k.to_s, colors: colors)
|
||||
end
|
||||
|
||||
list
|
||||
|
@ -205,7 +209,7 @@ class ColorScheme < ActiveRecord::Base
|
|||
def self.base_color_schemes
|
||||
base_color_scheme_colors.map do |hash|
|
||||
scheme = new(name: I18n.t("color_schemes.#{hash[:id].downcase.gsub(' ', '_')}"), base_scheme_id: hash[:id])
|
||||
scheme.colors = hash[:colors].map { |k, v| { name: k.to_s, hex: v.sub("#", "") } }
|
||||
scheme.colors = hash[:colors].map { |k| { name: k[:name], hex: k[:hex] } }
|
||||
scheme.is_base = true
|
||||
scheme
|
||||
end
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
class WizardFieldSerializer < ApplicationSerializer
|
||||
|
||||
attributes :id, :type, :required, :value, :label, :placeholder, :description, :extra_description
|
||||
attributes :id, :type, :required, :value, :label, :placeholder, :description, :extra_description, :show_in_sidebar
|
||||
has_many :choices, serializer: WizardFieldChoiceSerializer, embed: :objects
|
||||
|
||||
def id
|
||||
|
@ -68,4 +68,12 @@ class WizardFieldSerializer < ApplicationSerializer
|
|||
extra_description.present?
|
||||
end
|
||||
|
||||
def show_in_sidebar
|
||||
object.show_in_sidebar
|
||||
end
|
||||
|
||||
def include_show_in_sidebar?
|
||||
object.show_in_sidebar.present?
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -15,11 +15,6 @@ class WizardSerializer < ApplicationSerializer
|
|||
|
||||
def current_color_scheme
|
||||
color_scheme = Theme.where(id: SiteSetting.default_theme_id).first&.color_scheme
|
||||
colors = color_scheme ? color_scheme.colors : ColorScheme.base.colors
|
||||
|
||||
# The frontend expects the color hexs to start with '#'
|
||||
colors_with_hash = {}
|
||||
colors.each { |color| colors_with_hash[color.name] = color.hex_with_hash }
|
||||
colors_with_hash
|
||||
color_scheme ? color_scheme.colors_hashes : ColorScheme.base.colors_hashes
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5395,7 +5395,8 @@ en:
|
|||
regular: "Regular User"
|
||||
|
||||
previews:
|
||||
topic_title: "Discussion topic"
|
||||
font_title: "%{font} Font"
|
||||
topic_title: "A discussion topic heading"
|
||||
share_button: "Share"
|
||||
reply_button: "Reply"
|
||||
topic_preview: "Topic preview"
|
||||
homepage_preview: "Homepage preview"
|
||||
|
|
|
@ -4863,18 +4863,34 @@ en:
|
|||
label: "City for Disputes"
|
||||
placeholder: "San Francisco, California"
|
||||
|
||||
colors:
|
||||
title: "Colors"
|
||||
|
||||
fonts:
|
||||
title: "Fonts"
|
||||
styling:
|
||||
title: "Styling"
|
||||
fields:
|
||||
color_scheme:
|
||||
label: "Color scheme"
|
||||
body_font:
|
||||
label: "Body font"
|
||||
heading_font:
|
||||
label: "Heading font"
|
||||
font_preview:
|
||||
styling_preview:
|
||||
label: "Preview"
|
||||
homepage_style:
|
||||
label: "Homepage style"
|
||||
choices:
|
||||
latest:
|
||||
label: "Latest Topics"
|
||||
categories_only:
|
||||
label: "Categories Only"
|
||||
categories_with_featured_topics:
|
||||
label: "Categories with Featured Topics"
|
||||
categories_and_latest_topics:
|
||||
label: "Categories and Latest Topics"
|
||||
categories_and_top_topics:
|
||||
label: "Categories and Top Topics"
|
||||
categories_boxes:
|
||||
label: "Categories boxes"
|
||||
categories_boxes_with_topics:
|
||||
label: "Categories boxes with Topics"
|
||||
|
||||
logos:
|
||||
title: "Logos"
|
||||
|
@ -4896,28 +4912,6 @@ en:
|
|||
label: "Large Icon"
|
||||
description: "Icon image used to represent your site on modern devices that looks good at larger sizes. Ideally larger than 512 × 512. We'll use the square logo by default."
|
||||
|
||||
homepage:
|
||||
description: "We recommend showing the latest topics on your homepage, but you can also show categories (groups of topics) on the homepage if you prefer."
|
||||
title: "Homepage"
|
||||
|
||||
fields:
|
||||
homepage_style:
|
||||
choices:
|
||||
latest:
|
||||
label: "Latest Topics"
|
||||
categories_only:
|
||||
label: "Categories Only"
|
||||
categories_with_featured_topics:
|
||||
label: "Categories with Featured Topics"
|
||||
categories_and_latest_topics:
|
||||
label: "Categories and Latest Topics"
|
||||
categories_and_top_topics:
|
||||
label: "Categories and Top Topics"
|
||||
categories_boxes:
|
||||
label: "Categories boxes"
|
||||
categories_boxes_with_topics:
|
||||
label: "Categories boxes with Topics"
|
||||
|
||||
invites:
|
||||
title: "Invite Staff"
|
||||
description: "You’re almost done! Let’s invite some people to help <a href='https://blog.discourse.org/2014/08/building-a-discourse-community/' target='blank'>seed your discussions</a> with interesting topics and replies to get your community started."
|
||||
|
|
|
@ -141,7 +141,7 @@ class Wizard
|
|||
end
|
||||
end
|
||||
|
||||
@wizard.append_step('colors') do |step|
|
||||
@wizard.append_step('styling') do |step|
|
||||
default_theme = Theme.find_by(id: SiteSetting.default_theme_id)
|
||||
default_theme_override = SiteSetting.exists?(name: "default_theme_id")
|
||||
|
||||
|
@ -151,29 +151,60 @@ class Wizard
|
|||
scheme_id = default_theme_override ? (base_scheme || color_scheme_name) : ColorScheme::LIGHT_THEME_ID
|
||||
|
||||
themes = step.add_field(
|
||||
id: 'theme_previews',
|
||||
type: 'component',
|
||||
id: 'color_scheme',
|
||||
type: 'dropdown',
|
||||
required: !default_theme_override,
|
||||
value: scheme_id || ColorScheme::LIGHT_THEME_ID
|
||||
value: scheme_id || ColorScheme::LIGHT_THEME_ID,
|
||||
show_in_sidebar: true
|
||||
)
|
||||
|
||||
# fix for the case when base_scheme is nil
|
||||
if scheme_id && default_theme_override && base_scheme.nil?
|
||||
scheme = default_theme.color_scheme
|
||||
default_colors = scheme.colors.select(:name, :hex)
|
||||
choice_hash = default_colors.reduce({}) { |choice, color| choice[color.name] = "##{color.hex}"; choice }
|
||||
themes.add_choice(scheme_id, data: { colors: choice_hash })
|
||||
themes.add_choice(scheme_id, data: { colors: scheme.colors_hashes })
|
||||
end
|
||||
|
||||
ColorScheme.base_color_scheme_colors.each do |t|
|
||||
with_hash = t[:colors].dup
|
||||
with_hash.map { |k, v| with_hash[k] = "##{v}" }
|
||||
themes.add_choice(t[:id], data: { colors: with_hash })
|
||||
themes.add_choice(t[:id], data: { colors: t[:colors] })
|
||||
end
|
||||
|
||||
body_font = step.add_field(
|
||||
id: 'body_font',
|
||||
type: 'dropdown',
|
||||
value: SiteSetting.base_font,
|
||||
show_in_sidebar: true
|
||||
)
|
||||
|
||||
heading_font = step.add_field(
|
||||
id: 'heading_font',
|
||||
type: 'dropdown',
|
||||
value: SiteSetting.heading_font,
|
||||
show_in_sidebar: true
|
||||
)
|
||||
|
||||
DiscourseFonts.fonts.each do |font|
|
||||
body_font.add_choice(font[:key], label: font[:name])
|
||||
heading_font.add_choice(font[:key], label: font[:name])
|
||||
end
|
||||
|
||||
current = SiteSetting.top_menu.starts_with?("categories") ? SiteSetting.desktop_category_page_style : "latest"
|
||||
style = step.add_field(id: 'homepage_style', type: 'dropdown', required: true, value: current, show_in_sidebar: true)
|
||||
style.add_choice('latest')
|
||||
CategoryPageStyle.values.each do |page|
|
||||
style.add_choice(page[:value])
|
||||
end
|
||||
|
||||
step.add_field(
|
||||
id: 'styling_preview',
|
||||
type: 'component'
|
||||
)
|
||||
|
||||
step.on_update do |updater|
|
||||
updater.update_setting(:base_font, updater.fields[:body_font])
|
||||
updater.update_setting(:heading_font, updater.fields[:heading_font])
|
||||
|
||||
scheme_name = (
|
||||
(updater.fields[:theme_previews] || "") ||
|
||||
(updater.fields[:color_scheme] || "") ||
|
||||
ColorScheme::LIGHT_THEME_ID
|
||||
)
|
||||
|
||||
|
@ -189,33 +220,21 @@ class Wizard
|
|||
default_theme.save!
|
||||
else
|
||||
theme = Theme.create!(
|
||||
name: name,
|
||||
name: I18n.t("color_schemes.default_theme_name"),
|
||||
user_id: @wizard.user.id,
|
||||
color_scheme_id: scheme.id
|
||||
)
|
||||
|
||||
theme.set_default!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@wizard.append_step('fonts') do |step|
|
||||
body_font = step.add_field(id: 'body_font', type: 'dropdown', value: SiteSetting.base_font)
|
||||
heading_font = step.add_field(id: 'heading_font', type: 'dropdown', value: SiteSetting.heading_font)
|
||||
|
||||
DiscourseFonts.fonts.each do |font|
|
||||
body_font.add_choice(font[:key], label: font[:name])
|
||||
heading_font.add_choice(font[:key], label: font[:name])
|
||||
end
|
||||
|
||||
step.add_field(
|
||||
id: 'font_preview',
|
||||
type: 'component'
|
||||
)
|
||||
|
||||
step.on_update do |updater|
|
||||
updater.update_setting(:base_font, updater.fields[:body_font])
|
||||
updater.update_setting(:heading_font, updater.fields[:heading_font])
|
||||
if updater.fields[:homepage_style] == 'latest'
|
||||
top_menu = "latest|new|unread|top|categories"
|
||||
else
|
||||
top_menu = "categories|latest|new|unread|top"
|
||||
updater.update_setting(:desktop_category_page_style, updater.fields[:homepage_style])
|
||||
end
|
||||
updater.update_setting(:top_menu, top_menu)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -242,29 +261,6 @@ class Wizard
|
|||
end
|
||||
end
|
||||
|
||||
@wizard.append_step('homepage') do |step|
|
||||
|
||||
current = SiteSetting.top_menu.starts_with?("categories") ? SiteSetting.desktop_category_page_style : "latest"
|
||||
|
||||
style = step.add_field(id: 'homepage_style', type: 'dropdown', required: true, value: current)
|
||||
style.add_choice('latest')
|
||||
CategoryPageStyle.values.each do |page|
|
||||
style.add_choice(page[:value])
|
||||
end
|
||||
|
||||
step.add_field(id: 'homepage_preview', type: 'component')
|
||||
|
||||
step.on_update do |updater|
|
||||
if updater.fields[:homepage_style] == 'latest'
|
||||
top_menu = "latest|new|unread|top|categories"
|
||||
else
|
||||
top_menu = "categories|latest|new|unread|top"
|
||||
updater.update_setting(:desktop_category_page_style, updater.fields[:homepage_style])
|
||||
end
|
||||
updater.update_setting(:top_menu, top_menu)
|
||||
end
|
||||
end
|
||||
|
||||
@wizard.append_step('invites') do |step|
|
||||
if SiteSetting.enable_local_logins
|
||||
staff_count = User.staff.human_users.where('username_lower not in (?)', reserved_usernames).count
|
||||
|
|
|
@ -16,7 +16,7 @@ class Wizard
|
|||
end
|
||||
|
||||
class Field
|
||||
attr_reader :id, :type, :required, :value, :choices
|
||||
attr_reader :id, :type, :required, :value, :choices, :show_in_sidebar
|
||||
attr_accessor :step
|
||||
|
||||
def initialize(attrs)
|
||||
|
@ -27,6 +27,7 @@ class Wizard
|
|||
@required = !!attrs[:required]
|
||||
@value = attrs[:value]
|
||||
@choices = []
|
||||
@show_in_sidebar = attrs[:show_in_sidebar]
|
||||
end
|
||||
|
||||
def add_choice(id, opts = nil)
|
||||
|
|
|
@ -167,105 +167,145 @@ describe Wizard::StepUpdater do
|
|||
end
|
||||
end
|
||||
|
||||
context "fonts step" do
|
||||
context "styling step" do
|
||||
it "updates fonts" do
|
||||
updater = wizard.create_updater('fonts', body_font: 'open_sans', heading_font: 'oswald')
|
||||
updater = wizard.create_updater('styling', body_font: 'open_sans', heading_font: 'oswald')
|
||||
updater.update
|
||||
expect(updater.success?).to eq(true)
|
||||
expect(wizard.completed_steps?('fonts')).to eq(true)
|
||||
expect(wizard.completed_steps?('styling')).to eq(true)
|
||||
expect(SiteSetting.base_font).to eq('open_sans')
|
||||
expect(SiteSetting.heading_font).to eq('oswald')
|
||||
end
|
||||
end
|
||||
|
||||
context "colors step" do
|
||||
context "with an existing color scheme" do
|
||||
fab!(:color_scheme) { Fabricate(:color_scheme, name: 'existing', via_wizard: true) }
|
||||
context "colors" do
|
||||
context "with an existing color scheme" do
|
||||
fab!(:color_scheme) { Fabricate(:color_scheme, name: 'existing', via_wizard: true) }
|
||||
|
||||
it "updates the scheme" do
|
||||
updater = wizard.create_updater('colors', theme_previews: 'Dark')
|
||||
updater.update
|
||||
expect(updater.success?).to eq(true)
|
||||
expect(wizard.completed_steps?('colors')).to eq(true)
|
||||
theme = Theme.find_by(id: SiteSetting.default_theme_id)
|
||||
expect(theme.color_scheme.base_scheme_id).to eq('Dark')
|
||||
end
|
||||
end
|
||||
|
||||
context "with an existing default theme" do
|
||||
fab!(:theme) { Fabricate(:theme) }
|
||||
|
||||
before do
|
||||
theme.set_default!
|
||||
end
|
||||
|
||||
it "should not update the default theme when no option has been selected" do
|
||||
expect do
|
||||
wizard.create_updater('colors', {}).update
|
||||
end.to_not change { SiteSetting.default_theme_id }
|
||||
end
|
||||
|
||||
it "should update the color scheme of the default theme" do
|
||||
updater = wizard.create_updater('colors', theme_previews: 'Neutral')
|
||||
expect { updater.update }.not_to change { Theme.count }
|
||||
theme.reload
|
||||
expect(theme.color_scheme.base_scheme_id).to eq('Neutral')
|
||||
end
|
||||
end
|
||||
|
||||
context "without an existing theme" do
|
||||
before do
|
||||
Theme.delete_all
|
||||
end
|
||||
|
||||
context 'dark theme' do
|
||||
it "creates the theme" do
|
||||
updater = wizard.create_updater('colors', theme_previews: 'Dark')
|
||||
|
||||
expect { updater.update }.to change { Theme.count }.by(1)
|
||||
|
||||
theme = Theme.last
|
||||
|
||||
expect(theme.user_id).to eq(wizard.user.id)
|
||||
it "updates the scheme" do
|
||||
updater = wizard.create_updater('styling', color_scheme: 'Dark', body_font: 'arial', heading_font: 'arial', homepage_style: 'latest')
|
||||
updater.update
|
||||
expect(updater.success?).to eq(true)
|
||||
expect(wizard.completed_steps?('styling')).to eq(true)
|
||||
theme = Theme.find_by(id: SiteSetting.default_theme_id)
|
||||
expect(theme.color_scheme.base_scheme_id).to eq('Dark')
|
||||
end
|
||||
end
|
||||
|
||||
context 'light theme' do
|
||||
it "creates the theme" do
|
||||
updater = wizard.create_updater('colors',
|
||||
theme_previews: ColorScheme::LIGHT_THEME_ID
|
||||
context "with an existing default theme" do
|
||||
fab!(:theme) { Fabricate(:theme) }
|
||||
|
||||
before do
|
||||
theme.set_default!
|
||||
end
|
||||
|
||||
it "should update the color scheme of the default theme" do
|
||||
updater = wizard.create_updater('styling',
|
||||
color_scheme: 'Neutral',
|
||||
body_font: 'arial',
|
||||
heading_font: 'arial',
|
||||
homepage_style: 'latest'
|
||||
)
|
||||
expect { updater.update }.not_to change { Theme.count }
|
||||
theme.reload
|
||||
expect(theme.color_scheme.base_scheme_id).to eq('Neutral')
|
||||
end
|
||||
end
|
||||
|
||||
expect { updater.update }.to change { Theme.count }.by(1)
|
||||
context "without an existing theme" do
|
||||
before do
|
||||
Theme.delete_all
|
||||
end
|
||||
|
||||
theme = Theme.last
|
||||
context 'dark theme' do
|
||||
it "creates the theme" do
|
||||
updater = wizard.create_updater('styling',
|
||||
color_scheme: 'Dark',
|
||||
body_font: 'arial',
|
||||
heading_font: 'arial',
|
||||
homepage_style: 'latest'
|
||||
)
|
||||
|
||||
expect(theme.user_id).to eq(wizard.user.id)
|
||||
expect { updater.update }.to change { Theme.count }.by(1)
|
||||
|
||||
expect(theme.color_scheme).to eq(ColorScheme.find_by(name:
|
||||
ColorScheme::LIGHT_THEME_ID
|
||||
))
|
||||
theme = Theme.last
|
||||
|
||||
expect(theme.user_id).to eq(wizard.user.id)
|
||||
expect(theme.color_scheme.base_scheme_id).to eq('Dark')
|
||||
end
|
||||
end
|
||||
|
||||
context 'light theme' do
|
||||
it "creates the theme" do
|
||||
updater = wizard.create_updater('styling',
|
||||
color_scheme: ColorScheme::LIGHT_THEME_ID,
|
||||
body_font: 'arial',
|
||||
heading_font: 'arial',
|
||||
homepage_style: 'latest'
|
||||
)
|
||||
|
||||
expect { updater.update }.to change { Theme.count }.by(1)
|
||||
|
||||
theme = Theme.last
|
||||
|
||||
expect(theme.user_id).to eq(wizard.user.id)
|
||||
|
||||
expect(theme.color_scheme).to eq(ColorScheme.find_by(name:
|
||||
ColorScheme::LIGHT_THEME_ID
|
||||
))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "without an existing scheme" do
|
||||
it "creates the scheme" do
|
||||
ColorScheme.destroy_all
|
||||
updater = wizard.create_updater('styling',
|
||||
color_scheme: 'Dark',
|
||||
body_font: 'arial',
|
||||
heading_font: 'arial',
|
||||
homepage_style: 'latest'
|
||||
)
|
||||
updater.update
|
||||
expect(updater.success?).to eq(true)
|
||||
expect(wizard.completed_steps?('styling')).to eq(true)
|
||||
|
||||
color_scheme = ColorScheme.where(via_wizard: true).first
|
||||
expect(color_scheme).to be_present
|
||||
expect(color_scheme.colors).to be_present
|
||||
|
||||
theme = Theme.find_by(id: SiteSetting.default_theme_id)
|
||||
expect(theme.color_scheme_id).to eq(color_scheme.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "without an existing scheme" do
|
||||
it "creates the scheme" do
|
||||
ColorScheme.destroy_all
|
||||
updater = wizard.create_updater('colors', theme_previews: 'Dark')
|
||||
context "homepage style" do
|
||||
it "updates the fields correctly" do
|
||||
updater = wizard.create_updater('styling',
|
||||
color_scheme: 'Dark',
|
||||
body_font: 'arial',
|
||||
heading_font: 'arial',
|
||||
homepage_style: "categories_and_top_topics"
|
||||
)
|
||||
updater.update
|
||||
expect(updater.success?).to eq(true)
|
||||
expect(wizard.completed_steps?('colors')).to eq(true)
|
||||
|
||||
color_scheme = ColorScheme.where(via_wizard: true).first
|
||||
expect(color_scheme).to be_present
|
||||
expect(color_scheme.colors).to be_present
|
||||
expect(updater).to be_success
|
||||
expect(wizard.completed_steps?('styling')).to eq(true)
|
||||
expect(SiteSetting.top_menu).to eq('categories|latest|new|unread|top')
|
||||
expect(SiteSetting.desktop_category_page_style).to eq('categories_and_top_topics')
|
||||
|
||||
theme = Theme.find_by(id: SiteSetting.default_theme_id)
|
||||
expect(theme.color_scheme_id).to eq(color_scheme.id)
|
||||
updater = wizard.create_updater('styling',
|
||||
color_scheme: 'Dark',
|
||||
body_font: 'arial',
|
||||
heading_font: 'arial',
|
||||
homepage_style: "latest"
|
||||
)
|
||||
updater.update
|
||||
expect(updater).to be_success
|
||||
expect(SiteSetting.top_menu).to eq('latest|new|unread|top|categories')
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context "logos step" do
|
||||
|
@ -307,23 +347,6 @@ describe Wizard::StepUpdater do
|
|||
end
|
||||
end
|
||||
|
||||
context "homepage step" do
|
||||
it "updates the fields correctly" do
|
||||
updater = wizard.create_updater('homepage', homepage_style: "categories_and_top_topics")
|
||||
updater.update
|
||||
|
||||
expect(updater).to be_success
|
||||
expect(wizard.completed_steps?('homepage')).to eq(true)
|
||||
expect(SiteSetting.top_menu).to eq('categories|latest|new|unread|top')
|
||||
expect(SiteSetting.desktop_category_page_style).to eq('categories_and_top_topics')
|
||||
|
||||
updater = wizard.create_updater('homepage', homepage_style: "latest")
|
||||
updater.update
|
||||
expect(updater).to be_success
|
||||
expect(SiteSetting.top_menu).to eq('latest|new|unread|top|categories')
|
||||
end
|
||||
end
|
||||
|
||||
context "invites step" do
|
||||
let(:invites) {
|
||||
return [{ email: 'regular@example.com', role: 'regular' },
|
||||
|
|
|
@ -41,12 +41,64 @@ describe Wizard::Builder do
|
|||
expect(invites_step.disabled).to be_truthy
|
||||
end
|
||||
|
||||
context 'fonts step' do
|
||||
let(:fonts_step) { wizard.steps.find { |s| s.id == 'fonts' } }
|
||||
let(:field) { fonts_step.fields.first }
|
||||
context 'styling step' do
|
||||
let(:styling_step) { wizard.steps.find { |s| s.id == 'styling' } }
|
||||
let(:font_field) { styling_step.fields[1] }
|
||||
fab!(:theme) { Fabricate(:theme) }
|
||||
let(:colors_field) { styling_step.fields.first }
|
||||
|
||||
it 'should set the right font' do
|
||||
expect(field.choices.size).to eq(DiscourseFonts.fonts.size)
|
||||
it 'has the full list of available fonts' do
|
||||
expect(font_field.choices.size).to eq(DiscourseFonts.fonts.size)
|
||||
end
|
||||
|
||||
context "colors" do
|
||||
describe "when the default theme has not been override" do
|
||||
before do
|
||||
SiteSetting.find_by(name: "default_theme_id").destroy!
|
||||
end
|
||||
|
||||
it 'should set the right default values' do
|
||||
expect(colors_field.required).to eq(true)
|
||||
expect(colors_field.value).to eq(ColorScheme::LIGHT_THEME_ID)
|
||||
end
|
||||
end
|
||||
|
||||
describe "when the default theme has been override and the color scheme doesn't have a base scheme" do
|
||||
let(:color_scheme) { Fabricate(:color_scheme, base_scheme_id: nil) }
|
||||
|
||||
before do
|
||||
SiteSetting.default_theme_id = theme.id
|
||||
theme.update(color_scheme: color_scheme)
|
||||
end
|
||||
|
||||
it 'fallbacks to the color scheme name' do
|
||||
expect(colors_field.required).to eq(false)
|
||||
expect(colors_field.value).to eq(color_scheme.name)
|
||||
end
|
||||
end
|
||||
|
||||
describe "when the default theme has been overridden by a theme without a color scheme" do
|
||||
before do
|
||||
theme.set_default!
|
||||
end
|
||||
|
||||
it 'should set the right default values' do
|
||||
expect(colors_field.required).to eq(false)
|
||||
expect(colors_field.value).to eq("Light")
|
||||
end
|
||||
end
|
||||
|
||||
describe "when the default theme has been overridden by a theme with a color scheme" do
|
||||
before do
|
||||
theme.update(color_scheme_id: ColorScheme.find_by_name("Dark").id)
|
||||
theme.set_default!
|
||||
end
|
||||
|
||||
it 'should set the right default values' do
|
||||
expect(colors_field.required).to eq(false)
|
||||
expect(colors_field.value).to eq("Dark")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -155,57 +207,4 @@ describe Wizard::Builder do
|
|||
end
|
||||
end
|
||||
|
||||
context "colors step" do
|
||||
fab!(:theme) { Fabricate(:theme) }
|
||||
let(:colors_step) { wizard.steps.find { |s| s.id == 'colors' } }
|
||||
let(:field) { colors_step.fields.first }
|
||||
|
||||
describe "when the default theme has not been override" do
|
||||
before do
|
||||
SiteSetting.find_by(name: "default_theme_id").destroy!
|
||||
end
|
||||
|
||||
it 'should set the right default values' do
|
||||
expect(field.required).to eq(true)
|
||||
expect(field.value).to eq(ColorScheme::LIGHT_THEME_ID)
|
||||
end
|
||||
end
|
||||
|
||||
describe "when the default theme has been override and the color scheme doesn't have a base scheme" do
|
||||
let(:color_scheme) { Fabricate(:color_scheme, base_scheme_id: nil) }
|
||||
|
||||
before do
|
||||
SiteSetting.default_theme_id = theme.id
|
||||
theme.update(color_scheme: color_scheme)
|
||||
end
|
||||
|
||||
it 'fallbacks to the color scheme name' do
|
||||
expect(field.required).to eq(false)
|
||||
expect(field.value).to eq(color_scheme.name)
|
||||
end
|
||||
end
|
||||
|
||||
describe "when the default theme has been overridden by a theme without a color scheme" do
|
||||
before do
|
||||
theme.set_default!
|
||||
end
|
||||
|
||||
it 'should set the right default values' do
|
||||
expect(field.required).to eq(false)
|
||||
expect(field.value).to eq("Light")
|
||||
end
|
||||
end
|
||||
|
||||
describe "when the default theme has been overridden by a theme with a color scheme" do
|
||||
before do
|
||||
theme.update(color_scheme_id: ColorScheme.find_by_name("Dark").id)
|
||||
theme.set_default!
|
||||
end
|
||||
|
||||
it 'should set the right default values' do
|
||||
expect(field.required).to eq(false)
|
||||
expect(field.value).to eq("Dark")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -28,8 +28,13 @@ describe Admin::ColorSchemesController do
|
|||
get "/admin/color_schemes.json"
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
schemes = response.parsed_body.map { |scheme| scheme["name"] }
|
||||
expect(schemes).to include(scheme_name)
|
||||
scheme_names = response.parsed_body.map { |scheme| scheme["name"] }
|
||||
scheme_colors = response.parsed_body[0]["colors"]
|
||||
base_scheme_colors = ColorScheme.base.colors
|
||||
|
||||
expect(scheme_names).to include(scheme_name)
|
||||
expect(scheme_colors[0]["name"]).to eq(base_scheme_colors[0].name)
|
||||
expect(scheme_colors[0]["hex"]).to eq(base_scheme_colors[0].hex)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -18,7 +18,8 @@ describe WizardSerializer do
|
|||
json = MultiJson.load(MultiJson.dump(serializer.as_json))
|
||||
wjson = json['wizard']
|
||||
|
||||
expect(wjson['current_color_scheme']['primary']).to eq('#222222')
|
||||
expect(wjson['current_color_scheme'][0]['name']).to eq('primary')
|
||||
expect(wjson['current_color_scheme'][0]['hex']).to eq('222222')
|
||||
end
|
||||
|
||||
it "should provide custom colors correctly" do
|
||||
|
@ -34,7 +35,7 @@ describe WizardSerializer do
|
|||
json = MultiJson.load(MultiJson.dump(serializer.as_json))
|
||||
wjson = json['wizard']
|
||||
|
||||
expect(wjson['current_color_scheme']['header_background']).to eq('#00FF00')
|
||||
expect(wjson['current_color_scheme'].to_s).to include('{"name"=>"header_background", "hex"=>"00FF00"}')
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue