mirror of
https://github.com/discourse/discourse.git
synced 2025-10-03 17:21:20 +08:00
UX: fixes and improvements for color palettes (#34359)
Various fixes and improvements for the color palettes admin page... * Live previews stopped working because we were never running `_captureInitialState()` so we had no comparison to see if we could live preview * `canPreviewColorScheme` also needed to check against "theme default" user preference (-1) * Refactors warning messages if admin user preferences differ from defaults <img width="2036" height="260" alt="image" src="https://github.com/user-attachments/assets/30b6957a-6009-42e7-9cb7-01610536fd1c" /> We now warn on: * Theme is different from the default (overrides color difference warnings) * Light and/or dark palette are different from the default * Added specs for toasts on palette change, which is a light way to check if live preview is working (when the conditions are met for the live preview, we don't show the toast) * If a color palette isn't editable, make the button say "view" and not "edit" — we can improve this some more, but this is a simple iterative step
This commit is contained in:
parent
4c094224b1
commit
b60d9bcc8c
7 changed files with 184 additions and 21 deletions
|
@ -25,6 +25,16 @@ export default class ColorPaletteListItem extends Component {
|
|||
return !this.isBuiltInDefault && this.args.scheme?.id;
|
||||
}
|
||||
|
||||
get isThemePalette() {
|
||||
return this.args.scheme?.theme_id;
|
||||
}
|
||||
|
||||
get editButtonLabel() {
|
||||
return this.isThemePalette && !this.isBuiltInDefault
|
||||
? "admin.customize.colors.view"
|
||||
: "admin.customize.colors.edit";
|
||||
}
|
||||
|
||||
get canDelete() {
|
||||
return !this.isBuiltInDefault && !this.args.scheme?.theme_id;
|
||||
}
|
||||
|
@ -157,7 +167,7 @@ export default class ColorPaletteListItem extends Component {
|
|||
<DButton
|
||||
@route="adminCustomize.colors-show"
|
||||
@routeModels={{array @scheme.id}}
|
||||
@label="admin.customize.colors.edit"
|
||||
@label={{this.editButtonLabel}}
|
||||
class="btn-secondary"
|
||||
@disabled={{not this.canEdit}}
|
||||
/>
|
||||
|
|
|
@ -16,6 +16,7 @@ export default class AdminCustomizeColorsController extends Controller {
|
|||
@service session;
|
||||
@service site;
|
||||
@service siteSettings;
|
||||
@service interfaceColor;
|
||||
|
||||
@tracked defaultTheme = null;
|
||||
|
||||
|
@ -36,12 +37,16 @@ export default class AdminCustomizeColorsController extends Controller {
|
|||
|
||||
canPreviewColorScheme(mode) {
|
||||
const usingDefaultTheme = currentThemeId() === this.defaultTheme?.id;
|
||||
|
||||
// -1 means they're using the theme default scheme
|
||||
const usingDefaultLightScheme =
|
||||
this._initialUserLightColorSchemeId === -1 ||
|
||||
this._initialUserLightColorSchemeId ===
|
||||
this._initialDefaultThemeLightColorSchemeId;
|
||||
this._initialDefaultThemeLightColorSchemeId;
|
||||
const usingDefaultDarkScheme =
|
||||
this._initialUserDarkColorSchemeId === -1 ||
|
||||
this._initialUserDarkColorSchemeId ===
|
||||
this._initialDefaultThemeDarkColorSchemeId;
|
||||
this._initialDefaultThemeDarkColorSchemeId;
|
||||
|
||||
return (
|
||||
usingDefaultTheme &&
|
||||
|
@ -63,18 +68,86 @@ export default class AdminCustomizeColorsController extends Controller {
|
|||
this.defaultTheme?.dark_color_scheme_id;
|
||||
}
|
||||
|
||||
get changedThemePreferences() {
|
||||
const changedTheme = this.defaultTheme?.id !== currentThemeId(this.site);
|
||||
get userColorSchemeDifferences() {
|
||||
const userLightDiffersFromDefault =
|
||||
this._initialUserLightColorSchemeId !== -1 &&
|
||||
this._initialUserLightColorSchemeId !==
|
||||
this._initialDefaultThemeLightColorSchemeId;
|
||||
|
||||
return changedTheme;
|
||||
const userDarkDiffersFromDefault =
|
||||
this._initialUserDarkColorSchemeId !== -1 &&
|
||||
this._initialUserDarkColorSchemeId !==
|
||||
this._initialDefaultThemeDarkColorSchemeId;
|
||||
|
||||
return { userLightDiffersFromDefault, userDarkDiffersFromDefault };
|
||||
}
|
||||
|
||||
get userPreferencesDifferFromDefaults() {
|
||||
if (!this.defaultTheme) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const usingDefaultTheme = currentThemeId() === this.defaultTheme.id;
|
||||
if (!usingDefaultTheme) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// only check color scheme preferences if using the default theme
|
||||
// because if they're not using the default theme, that's the higher priority warning
|
||||
const { userLightDiffersFromDefault, userDarkDiffersFromDefault } =
|
||||
this.userColorSchemeDifferences;
|
||||
|
||||
return userLightDiffersFromDefault || userDarkDiffersFromDefault;
|
||||
}
|
||||
|
||||
get preferencesWarningMessage() {
|
||||
if (!this.userPreferencesDifferFromDefaults) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const themeName = this.defaultTheme?.name || "default theme";
|
||||
const usingNonDefaultTheme = currentThemeId() !== this.defaultTheme?.id;
|
||||
|
||||
if (usingNonDefaultTheme) {
|
||||
return {
|
||||
themeName,
|
||||
usingNonDefaultTheme: true,
|
||||
};
|
||||
}
|
||||
|
||||
const { userLightDiffersFromDefault, userDarkDiffersFromDefault } =
|
||||
this.userColorSchemeDifferences;
|
||||
|
||||
const affectedModes = [];
|
||||
if (userLightDiffersFromDefault) {
|
||||
affectedModes.push("light");
|
||||
}
|
||||
if (userDarkDiffersFromDefault) {
|
||||
affectedModes.push("dark");
|
||||
}
|
||||
|
||||
let colorModesText;
|
||||
if (affectedModes.length === 2) {
|
||||
colorModesText = ""; // intentionally left empty
|
||||
} else if (affectedModes[0] === "light") {
|
||||
colorModesText = i18n("admin.customize.colors.light");
|
||||
} else {
|
||||
colorModesText = i18n("admin.customize.colors.dark");
|
||||
}
|
||||
|
||||
return {
|
||||
themeName,
|
||||
colorModes: colorModesText,
|
||||
usingNonDefaultTheme: false,
|
||||
};
|
||||
}
|
||||
|
||||
get isUsingDarkMode() {
|
||||
// check if user has dark mode available and is using it
|
||||
return (
|
||||
this.session.darkModeAvailable &&
|
||||
this.session.userDarkSchemeId !== -1 &&
|
||||
window.matchMedia("(prefers-color-scheme: dark)").matches
|
||||
this.interfaceColor.darkModeForced ||
|
||||
(this.interfaceColor.colorModeIsAuto &&
|
||||
window.matchMedia("(prefers-color-scheme: dark)").matches) ||
|
||||
this.session.defaultColorSchemeIsDark
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,13 @@ export default class AdminCustomizeColorsRoute extends Route {
|
|||
setupController(controller, model) {
|
||||
super.setupController(controller, model);
|
||||
controller.set("model", model.colorSchemes);
|
||||
controller.set("defaultTheme", model.themes.findBy("default", true));
|
||||
|
||||
const themes = model.themes || [];
|
||||
const defaultTheme = themes.find((theme) => theme.default === true);
|
||||
controller.set("defaultTheme", defaultTheme);
|
||||
|
||||
if (defaultTheme) {
|
||||
controller._captureInitialState();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,15 +45,26 @@ export default RouteTemplate(
|
|||
</:actions>
|
||||
</DPageSubheader>
|
||||
|
||||
{{#if @controller.changedThemePreferences}}
|
||||
<div class="alert alert-info">
|
||||
{{htmlSafe
|
||||
(i18n
|
||||
"admin.customize.colors.preference_warning"
|
||||
link=(getUrl "/my/preferences/interface")
|
||||
)
|
||||
}}
|
||||
</div>
|
||||
{{#if @controller.preferencesWarningMessage}}
|
||||
<p class="color-palette__warning">
|
||||
{{#if @controller.preferencesWarningMessage.usingNonDefaultTheme}}
|
||||
{{htmlSafe
|
||||
(i18n
|
||||
"admin.customize.colors.non_default_theme_warning"
|
||||
themeName=@controller.preferencesWarningMessage.themeName
|
||||
link=(getUrl "/my/preferences/interface")
|
||||
)
|
||||
}}
|
||||
{{else}}
|
||||
{{htmlSafe
|
||||
(i18n
|
||||
"admin.customize.colors.custom_schemes_warning"
|
||||
colorModes=@controller.preferencesWarningMessage.colorModes
|
||||
link=(getUrl "/my/preferences/interface")
|
||||
)
|
||||
}}
|
||||
{{/if}}
|
||||
</p>
|
||||
{{/if}}
|
||||
|
||||
<AdminFilterControls
|
||||
|
|
|
@ -79,3 +79,7 @@
|
|||
margin-bottom: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
.color-palette__warning {
|
||||
font-style: italic;
|
||||
}
|
||||
|
|
|
@ -7119,9 +7119,13 @@ en:
|
|||
select_base:
|
||||
title: "Select base color palette"
|
||||
description: "Base palette:"
|
||||
preference_warning: "You've changed <a href='%{link}'>your personal theme settings</a>, so palette changes may not be visible to you. Visitors that haven't changed their defaults will still see the changes you make here."
|
||||
non_default_theme_warning: "Your <a href='%{link}'>personal preferences</a> for theme are different than the default. Changes you make here may not apply to you, but will apply to everyone using the default (%{themeName})."
|
||||
custom_schemes_warning: "Your <a href='%{link}'>personal preferences</a> for %{colorModes} color palette are different than the default. Changes to the %{colorModes} palette may not apply to you, but will apply to everyone using the default."
|
||||
light: "light"
|
||||
dark: "dark"
|
||||
title: "Colors"
|
||||
edit: "Edit"
|
||||
view: "View"
|
||||
set_default_light: "Set as light palette on default theme (%{theme})"
|
||||
set_default_dark: "Set as dark palette on default theme (%{theme})"
|
||||
set_default_success: "%{schemeName} set as default palette for %{themeName}"
|
||||
|
|
|
@ -196,6 +196,60 @@ describe "Admin Color Palettes Features", type: :system do
|
|||
end
|
||||
end
|
||||
|
||||
describe "live preview functionality" do
|
||||
it "does not show toast when live preview is available" do
|
||||
admin.user_option.update!(
|
||||
theme_ids: [Theme.find_default.id],
|
||||
color_scheme_id: -1,
|
||||
dark_scheme_id: -1,
|
||||
)
|
||||
|
||||
visit("/admin/customize/colors")
|
||||
|
||||
within("[data-palette-id='#{regular_palette.id}']") { find(".btn-flat").click }
|
||||
|
||||
expect(page).to have_css(".dropdown-menu")
|
||||
|
||||
click_button(
|
||||
I18n.t(
|
||||
"admin_js.admin.customize.colors.set_default_light",
|
||||
{ theme: Theme.find_default.name },
|
||||
),
|
||||
)
|
||||
|
||||
expect(page).to have_no_css(".fk-d-default-toast.-success")
|
||||
end
|
||||
|
||||
it "shows toast when admin cannot see live preview" do
|
||||
custom_scheme = Fabricate(:color_scheme, name: "Custom Scheme")
|
||||
admin.user_option.update!(
|
||||
theme_ids: [Theme.find_default.id],
|
||||
color_scheme_id: custom_scheme.id,
|
||||
)
|
||||
|
||||
visit("/admin/customize/colors")
|
||||
|
||||
within("[data-palette-id='#{regular_palette.id}']") { find(".btn-flat").click }
|
||||
|
||||
expect(page).to have_css(".dropdown-menu")
|
||||
|
||||
click_button(
|
||||
I18n.t(
|
||||
"admin_js.admin.customize.colors.set_default_light",
|
||||
{ theme: Theme.find_default.name },
|
||||
),
|
||||
)
|
||||
|
||||
expected_message =
|
||||
I18n.t(
|
||||
"admin_js.admin.customize.colors.set_default_success",
|
||||
schemeName: regular_palette.name,
|
||||
themeName: Theme.find_default.name,
|
||||
)
|
||||
expect(toasts).to have_success(expected_message)
|
||||
end
|
||||
end
|
||||
|
||||
describe "sort" do
|
||||
before do
|
||||
ColorScheme.delete_all
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue