mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
UX: Tweaks to the theme/component pages when using admin sidebar
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
import Component from "@glimmer/component";
|
||||
import { action } from "@ember/object";
|
||||
import { service } from "@ember/service";
|
||||
import DPageSubheader from "discourse/components/d-page-subheader";
|
||||
import { i18n } from "discourse-i18n";
|
||||
import InstallThemeModal from "admin/components/modal/install-theme";
|
||||
import ThemesGrid from "admin/components/themes-grid";
|
||||
import { COMPONENTS } from "admin/models/theme";
|
||||
|
||||
export default class AdminConfigAreasLookAndFeelComponents extends Component {
|
||||
@service modal;
|
||||
@service router;
|
||||
@service toasts;
|
||||
|
||||
@action
|
||||
installModal() {
|
||||
this.modal.show(InstallThemeModal, {
|
||||
model: { ...this.installThemeOptions() },
|
||||
});
|
||||
}
|
||||
|
||||
// TODO (martin) These install methods may not belong here and they
|
||||
// are incomplete or have stubbed or omitted properties. We may want
|
||||
// to move this to the new config route or a dedicated component
|
||||
// that sits in the route.
|
||||
installThemeOptions() {
|
||||
return {
|
||||
selectedType: COMPONENTS,
|
||||
userId: null,
|
||||
content: [],
|
||||
installedThemes: this.args.components,
|
||||
addTheme: this.addTheme,
|
||||
updateSelectedType: () => {},
|
||||
showComponentsOnly: true,
|
||||
};
|
||||
}
|
||||
|
||||
@action
|
||||
addTheme(theme) {
|
||||
this.toasts.success({
|
||||
data: {
|
||||
message: i18n("admin.customize.theme.install_success", {
|
||||
theme: theme.name,
|
||||
}),
|
||||
},
|
||||
duration: 2000,
|
||||
});
|
||||
this.router.refresh();
|
||||
}
|
||||
|
||||
<template>
|
||||
<DPageSubheader
|
||||
@titleLabel={{i18n "admin.config_areas.look_and_feel.components.title"}}
|
||||
@descriptionLabel={{i18n "admin.customize.theme.components_intro_new"}}
|
||||
@learnMoreUrl="https://meta.discourse.org/t/93648"
|
||||
>
|
||||
<:actions as |actions|>
|
||||
<actions.Primary
|
||||
@action={{this.installModal}}
|
||||
@label="admin.customize.install"
|
||||
@icon="upload"
|
||||
class="admin-look-and-feel__install-theme"
|
||||
/>
|
||||
</:actions>
|
||||
</DPageSubheader>
|
||||
|
||||
<div class="admin-detail">
|
||||
<ThemesGrid @themes={{@components}} />
|
||||
</div>
|
||||
</template>
|
||||
}
|
@@ -5,6 +5,7 @@ import DPageSubheader from "discourse/components/d-page-subheader";
|
||||
import { i18n } from "discourse-i18n";
|
||||
import InstallThemeModal from "admin/components/modal/install-theme";
|
||||
import ThemesGrid from "admin/components/themes-grid";
|
||||
import { THEMES } from "admin/models/theme";
|
||||
|
||||
export default class AdminConfigAreasLookAndFeelThemes extends Component {
|
||||
@service modal;
|
||||
@@ -24,12 +25,13 @@ export default class AdminConfigAreasLookAndFeelThemes extends Component {
|
||||
// that sits in the route.
|
||||
installThemeOptions() {
|
||||
return {
|
||||
selectedType: "theme",
|
||||
selectedType: THEMES,
|
||||
userId: null,
|
||||
content: [],
|
||||
installedThemes: this.args.themes,
|
||||
addTheme: this.addTheme,
|
||||
updateSelectedType: () => {},
|
||||
showThemesOnly: true,
|
||||
};
|
||||
}
|
||||
|
||||
|
@@ -111,7 +111,8 @@ export default class InstallThemeModal extends Component {
|
||||
}
|
||||
|
||||
get themes() {
|
||||
return POPULAR_THEMES.map((popularTheme) => {
|
||||
const list = [];
|
||||
POPULAR_THEMES.forEach((popularTheme) => {
|
||||
if (
|
||||
this.args.model.installedThemes.some((installedTheme) =>
|
||||
this.themeHasSameUrl(installedTheme, popularTheme.value)
|
||||
@@ -119,8 +120,20 @@ export default class InstallThemeModal extends Component {
|
||||
) {
|
||||
popularTheme.installed = true;
|
||||
}
|
||||
return popularTheme;
|
||||
|
||||
if (this.args.model.showComponentsOnly) {
|
||||
if (popularTheme.component) {
|
||||
list.push(popularTheme);
|
||||
}
|
||||
} else if (this.args.model.showThemesOnly) {
|
||||
if (!popularTheme.component) {
|
||||
list.push(popularTheme);
|
||||
}
|
||||
} else {
|
||||
list.push(popularTheme);
|
||||
}
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
get installingMessage() {
|
||||
|
@@ -0,0 +1,13 @@
|
||||
import DiscourseRoute from "discourse/routes/discourse";
|
||||
import { i18n } from "discourse-i18n";
|
||||
|
||||
export default class AdminConfigLookAndFeelComponentsRoute extends DiscourseRoute {
|
||||
async model() {
|
||||
const themes = await this.store.findAll("theme");
|
||||
return themes.reject((t) => !t.component);
|
||||
}
|
||||
|
||||
titleToken() {
|
||||
return i18n("admin.config_areas.look_and_feel.components.title");
|
||||
}
|
||||
}
|
@@ -273,6 +273,7 @@ export default function () {
|
||||
});
|
||||
this.route("lookAndFeel", { path: "/look-and-feel" }, function () {
|
||||
this.route("themes");
|
||||
this.route("components");
|
||||
});
|
||||
this.route(
|
||||
"adminPermalinks",
|
||||
|
@@ -0,0 +1,6 @@
|
||||
<DBreadcrumbsItem
|
||||
@path="/admin/config/look-and-feel/components"
|
||||
@label={{i18n "admin.config_areas.look_and_feel.components.title"}}
|
||||
/>
|
||||
|
||||
<AdminConfigAreas::LookAndFeelComponents @components={{this.model}} />
|
@@ -16,6 +16,10 @@
|
||||
@route="adminConfig.lookAndFeel.themes"
|
||||
@label="admin.config_areas.look_and_feel.themes.title"
|
||||
/>
|
||||
<NavItem
|
||||
@route="adminConfig.lookAndFeel.components"
|
||||
@label="admin.config_areas.look_and_feel.components.title"
|
||||
/>
|
||||
</:tabs>
|
||||
</DPageHeader>
|
||||
|
||||
|
@@ -1,7 +1,32 @@
|
||||
{{#if this.editingThemeSetting}}
|
||||
{{outlet}}
|
||||
{{else}}
|
||||
<div class="show-current-style">
|
||||
{{#if this.currentUser.use_admin_sidebar}}
|
||||
<div class="back-to-look-and-feel">
|
||||
<LinkTo
|
||||
@route={{if
|
||||
this.model.component
|
||||
"adminConfig.lookAndFeel.components"
|
||||
"adminConfig.lookAndFeel.themes"
|
||||
}}
|
||||
>
|
||||
{{dIcon "angle-left"}}
|
||||
{{i18n
|
||||
(if
|
||||
this.model.component
|
||||
"admin.config_areas.look_and_feel.components.back"
|
||||
"admin.config_areas.look_and_feel.themes.back"
|
||||
)
|
||||
}}
|
||||
</LinkTo>
|
||||
</div>
|
||||
{{/if}}
|
||||
<div
|
||||
class={{concatClass
|
||||
"show-current-style"
|
||||
(if this.currentUser.use_admin_sidebar "show-current-style--with-sidebar")
|
||||
}}
|
||||
>
|
||||
<span>
|
||||
<PluginOutlet
|
||||
@name="admin-customize-themes-show-top"
|
||||
|
@@ -1,36 +1,38 @@
|
||||
{{#if (eq this.currentTab "themes")}}
|
||||
<DPageHeader
|
||||
@titleLabel={{i18n "admin.customize.theme.title"}}
|
||||
@descriptionLabel={{i18n "admin.customize.theme.description"}}
|
||||
@learnMoreUrl="https://meta.discourse.org/t/91966"
|
||||
@hideTabs={{true}}
|
||||
>
|
||||
<:breadcrumbs>
|
||||
<DBreadcrumbsItem @path="/admin" @label={{i18n "admin_title"}} />
|
||||
<DBreadcrumbsItem
|
||||
@path="/admin/customize/themes"
|
||||
@label={{i18n "admin.customize.theme.title"}}
|
||||
/>
|
||||
</:breadcrumbs>
|
||||
</DPageHeader>
|
||||
{{else}}
|
||||
<DPageHeader
|
||||
@titleLabel={{i18n "admin.customize.theme.components"}}
|
||||
@descriptionLabel={{i18n "admin.customize.theme.components_description"}}
|
||||
@hideTabs={{true}}
|
||||
>
|
||||
<:breadcrumbs>
|
||||
<DBreadcrumbsItem @path="/admin" @label={{i18n "admin_title"}} />
|
||||
<DBreadcrumbsItem
|
||||
@path="/admin/customize/components"
|
||||
@label={{i18n "admin.customize.theme.components"}}
|
||||
/>
|
||||
</:breadcrumbs>
|
||||
</DPageHeader>
|
||||
{{/if}}
|
||||
{{#unless this.currentUser.use_admin_sidebar}}
|
||||
{{#if (eq this.currentTab "themes")}}
|
||||
<DPageHeader
|
||||
@titleLabel={{i18n "admin.customize.theme.title"}}
|
||||
@descriptionLabel={{i18n "admin.customize.theme.description"}}
|
||||
@learnMoreUrl="https://meta.discourse.org/t/91966"
|
||||
@hideTabs={{true}}
|
||||
>
|
||||
<:breadcrumbs>
|
||||
<DBreadcrumbsItem @path="/admin" @label={{i18n "admin_title"}} />
|
||||
<DBreadcrumbsItem
|
||||
@path="/admin/customize/themes"
|
||||
@label={{i18n "admin.customize.theme.title"}}
|
||||
/>
|
||||
</:breadcrumbs>
|
||||
</DPageHeader>
|
||||
{{else}}
|
||||
<DPageHeader
|
||||
@titleLabel={{i18n "admin.customize.theme.components"}}
|
||||
@descriptionLabel={{i18n "admin.customize.theme.components_description"}}
|
||||
@hideTabs={{true}}
|
||||
>
|
||||
<:breadcrumbs>
|
||||
<DBreadcrumbsItem @path="/admin" @label={{i18n "admin_title"}} />
|
||||
<DBreadcrumbsItem
|
||||
@path="/admin/customize/components"
|
||||
@label={{i18n "admin.customize.theme.components"}}
|
||||
/>
|
||||
</:breadcrumbs>
|
||||
</DPageHeader>
|
||||
{{/if}}
|
||||
{{/unless}}
|
||||
|
||||
<PluginOutlet @name="admin-customize-themes">
|
||||
{{#unless this.editingTheme}}
|
||||
{{#unless (or this.editingTheme this.currentUser.use_admin_sidebar)}}
|
||||
<ThemesList
|
||||
@themes={{this.fullThemes}}
|
||||
@components={{this.childThemes}}
|
||||
|
@@ -133,20 +133,12 @@ export const ADMIN_NAV_MAP = [
|
||||
icon: "diagram-project",
|
||||
},
|
||||
{
|
||||
name: "admin_themes",
|
||||
route: "adminCustomizeThemes",
|
||||
routeModels: ["themes"],
|
||||
model: "themes",
|
||||
label: "admin.appearance.sidebar_link.themes",
|
||||
name: "admin_themes_and_components",
|
||||
route: "adminConfig.lookAndFeel.themes",
|
||||
label: "admin.appearance.sidebar_link.themes_and_components.title",
|
||||
icon: "paintbrush",
|
||||
},
|
||||
{
|
||||
name: "admin_components",
|
||||
route: "adminCustomizeThemes",
|
||||
routeModels: ["components"],
|
||||
label: "admin.appearance.sidebar_link.components.title",
|
||||
icon: "puzzle-piece",
|
||||
keywords: "admin.appearance.sidebar_link.components.keywords",
|
||||
keywords:
|
||||
"admin.appearance.sidebar_link.themes_and_components.keywords",
|
||||
},
|
||||
{
|
||||
name: "admin_customize_site_texts",
|
||||
|
@@ -3,6 +3,10 @@
|
||||
padding-left: 2%;
|
||||
width: 68%;
|
||||
|
||||
&--with-sidebar {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
input {
|
||||
width: 80%;
|
||||
@@ -13,4 +17,8 @@
|
||||
.themes-list {
|
||||
width: 28%;
|
||||
}
|
||||
|
||||
.back-to-look-and-feel {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
}
|
||||
|
@@ -3,4 +3,7 @@
|
||||
class Admin::Config::LookAndFeelController < Admin::AdminController
|
||||
def themes
|
||||
end
|
||||
|
||||
def components
|
||||
end
|
||||
end
|
||||
|
@@ -1925,7 +1925,7 @@ en:
|
||||
after_5_minutes: "after 5 minutes"
|
||||
after_10_minutes: "after 10 minutes"
|
||||
|
||||
notification_level_when_replying:
|
||||
notification_level_when_replying:
|
||||
label: "When posting"
|
||||
watch_topic: "Watch topic"
|
||||
track_topic: "Track topic"
|
||||
@@ -5720,10 +5720,9 @@ en:
|
||||
color_schemes: "Color palettes"
|
||||
emoji: "Emoji"
|
||||
navigation: "Navigation"
|
||||
themes: "Themes"
|
||||
components:
|
||||
title: "Components"
|
||||
keywords: "theme|extension"
|
||||
themes_and_components:
|
||||
title: "Themes and components"
|
||||
keywords: "extension"
|
||||
site_texts: "Site texts"
|
||||
|
||||
email_settings:
|
||||
@@ -5864,6 +5863,10 @@ en:
|
||||
themes_description: "Themes are expansive customizations that change multiple elements of the style of your forum design, and often also include additional front-end features."
|
||||
new_theme: "New theme"
|
||||
user_selectable: "User selectable"
|
||||
back: "Back to themes"
|
||||
components:
|
||||
title: "Components"
|
||||
back: "Back to components"
|
||||
user_fields:
|
||||
field: "Field"
|
||||
type: "Type"
|
||||
@@ -6049,6 +6052,7 @@ en:
|
||||
component_name: "Component name"
|
||||
themes_intro: "Select an existing theme or install a new one to get started"
|
||||
themes_intro_new: "Install a new theme to get started, or create your own from scratch using these resources."
|
||||
components_intro_new: "Install a new component to get started, or create your own from scratch using these resources."
|
||||
themes_intro_img_alt: "New theme placeholder"
|
||||
beginners_guide_title: "Beginner’s guide to using Discourse Themes"
|
||||
developers_guide_title: "Developer’s guide to Discourse Themes"
|
||||
|
@@ -422,7 +422,10 @@ Discourse::Application.routes.draw do
|
||||
path: "look-and-feel",
|
||||
constraints: AdminConstraint.new,
|
||||
only: %i[index] do
|
||||
collection { get "/themes" => "look_and_feel#themes" }
|
||||
collection do
|
||||
get "/themes" => "look_and_feel#themes"
|
||||
get "/components" => "look_and_feel#components"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@@ -8,6 +8,7 @@ module SvgSprite
|
||||
align-left
|
||||
anchor
|
||||
angle-down
|
||||
angle-left
|
||||
angle-right
|
||||
angle-up
|
||||
angles-down
|
||||
|
@@ -189,4 +189,32 @@ describe "Admin Customize Themes", type: :system do
|
||||
expect(theme_translations_picker.component.text).to eq("English (US)")
|
||||
end
|
||||
end
|
||||
|
||||
describe "when using the admin sidebar" do
|
||||
fab!(:group) { Fabricate(:group, users: [admin]) }
|
||||
|
||||
before { SiteSetting.admin_sidebar_enabled_groups = group.id.to_s }
|
||||
|
||||
it "hides the themes/components inner sidebar and the page header" do
|
||||
visit("/admin/customize/themes")
|
||||
expect(admin_customize_themes_page).to have_no_themes_list
|
||||
expect(admin_customize_themes_page).to have_no_page_header
|
||||
end
|
||||
|
||||
context "when visting a theme's page" do
|
||||
it "has a link to the themes 'look and feel' page" do
|
||||
visit("/admin/customize/themes/#{theme.id}")
|
||||
expect(admin_customize_themes_page).to have_back_button_to_themes_page
|
||||
end
|
||||
end
|
||||
|
||||
context "when visting a component's page" do
|
||||
before { theme.switch_to_component! }
|
||||
|
||||
it "has a link to the components 'look and feel' page" do
|
||||
visit("/admin/customize/themes/#{theme.id}")
|
||||
expect(admin_customize_themes_page).to have_back_button_to_components_page
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@@ -27,6 +27,28 @@ module PageObjects
|
||||
has_css?("#{setting_selector(setting_name)} .desc", exact_text: description)
|
||||
end
|
||||
|
||||
def has_no_themes_list?
|
||||
has_no_css?(".themes-list-header")
|
||||
end
|
||||
|
||||
def has_back_button_to_themes_page?
|
||||
has_css?(
|
||||
'.back-to-look-and-feel a[href="/admin/config/look-and-feel/themes"]',
|
||||
text: I18n.t("admin_js.admin.config_areas.look_and_feel.themes.back"),
|
||||
)
|
||||
end
|
||||
|
||||
def has_back_button_to_components_page?
|
||||
has_css?(
|
||||
'.back-to-look-and-feel a[href="/admin/config/look-and-feel/components"]',
|
||||
text: I18n.t("admin_js.admin.config_areas.look_and_feel.components.back"),
|
||||
)
|
||||
end
|
||||
|
||||
def has_no_page_header?
|
||||
has_no_css?(".d-page-header")
|
||||
end
|
||||
|
||||
def reset_overridden_setting(setting_name)
|
||||
setting_section = find("section.theme.settings .setting[data-setting=\"#{setting_name}\"]")
|
||||
setting_section.click_button(I18n.t("admin_js.admin.settings.reset"))
|
||||
|
Reference in New Issue
Block a user