mirror of
https://github.com/discourse/discourse.git
synced 2025-03-14 10:33:43 +00:00
UX: Tweaks to the theme/component pages when using admin sidebar (#30953)
There are a number of minor changes in this commit : 1. Combine the "Themes" and "Components" links in the admin sidebar into a single tab labelled "Themes and components" 2. The combined tab links to the `/admin/config/customize/themes` page (titled as "Themes and components") 3. Add a new "Components" tab to the "Themes and components" page. There's already an existing "Themes" tab 4. Add a "back to" link at the top of individual theme/component page to navigate back to the respective tab in the "Themes and components" page 5. Remove the themes/components list/sidebar that currently serves for navigating between themes/components 6. Remove the header in the theme/component page Changes 4–6 apply only if the admin sidebar is enabled; they have no effect otherwise. Internal topic: t/146006.
This commit is contained in:
@ -0,0 +1,76 @@
|
|||||||
|
import Component from "@glimmer/component";
|
||||||
|
import DButton from "discourse/components/d-button";
|
||||||
|
import icon from "discourse/helpers/d-icon";
|
||||||
|
import { i18n } from "discourse-i18n";
|
||||||
|
import AdminConfigAreaCard from "admin/components/admin-config-area-card";
|
||||||
|
|
||||||
|
export default class InstallThemeCard extends Component {
|
||||||
|
externalResources = [
|
||||||
|
{
|
||||||
|
key: "admin.customize.theme.beginners_guide_title",
|
||||||
|
link: "https://meta.discourse.org/t/91966",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "admin.customize.theme.developers_guide_title",
|
||||||
|
link: "https://meta.discourse.org/t/93648",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "admin.customize.theme.browse_themes",
|
||||||
|
link: "https://meta.discourse.org/c/theme",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
get heading() {
|
||||||
|
if (this.args.component) {
|
||||||
|
return i18n(
|
||||||
|
"admin.config_areas.themes_and_components.components.new_component"
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return i18n("admin.config_areas.themes_and_components.themes.new_theme");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get intro() {
|
||||||
|
if (this.args.component) {
|
||||||
|
return i18n(
|
||||||
|
"admin.config_areas.themes_and_components.components.components_intro"
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return i18n(
|
||||||
|
"admin.config_areas.themes_and_components.themes.themes_intro"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<AdminConfigAreaCard
|
||||||
|
class="theme-install-card"
|
||||||
|
@translatedHeading={{this.heading}}
|
||||||
|
>
|
||||||
|
<:content>
|
||||||
|
<p>{{this.intro}}</p>
|
||||||
|
<div class="theme-install-card__external-links">
|
||||||
|
{{#each this.externalResources as |resource|}}
|
||||||
|
<a
|
||||||
|
href={{resource.link}}
|
||||||
|
class="external-link"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
{{i18n resource.key}}
|
||||||
|
{{icon "up-right-from-square"}}
|
||||||
|
</a>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
<DButton
|
||||||
|
class="btn-primary theme-install-card__install-button"
|
||||||
|
@translatedLabel={{i18n
|
||||||
|
"admin.config_areas.themes_and_components.install"
|
||||||
|
}}
|
||||||
|
@icon="upload"
|
||||||
|
@action={{@openModal}}
|
||||||
|
/>
|
||||||
|
</:content>
|
||||||
|
</AdminConfigAreaCard>
|
||||||
|
</template>
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
import Component from "@glimmer/component";
|
||||||
|
import { action } from "@ember/object";
|
||||||
|
import { service } from "@ember/service";
|
||||||
|
import { i18n } from "discourse-i18n";
|
||||||
|
import InstallThemeCard from "admin/components/admin-config-area-cards/install-theme-card";
|
||||||
|
import InstallComponentModal from "admin/components/modal/install-theme";
|
||||||
|
import ThemesGrid from "admin/components/themes-grid";
|
||||||
|
import { COMPONENTS } from "admin/models/theme";
|
||||||
|
|
||||||
|
export default class AdminConfigAreasComponents extends Component {
|
||||||
|
@service modal;
|
||||||
|
@service router;
|
||||||
|
@service toasts;
|
||||||
|
|
||||||
|
@action
|
||||||
|
installModal() {
|
||||||
|
this.modal.show(InstallComponentModal, {
|
||||||
|
model: { ...this.installOptions() },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
installOptions() {
|
||||||
|
return {
|
||||||
|
selectedType: COMPONENTS,
|
||||||
|
userId: null,
|
||||||
|
content: [],
|
||||||
|
installedThemes: this.args.components,
|
||||||
|
addTheme: this.addComponent,
|
||||||
|
updateSelectedType: () => {},
|
||||||
|
showComponentsOnly: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
addComponent(component) {
|
||||||
|
this.toasts.success({
|
||||||
|
data: {
|
||||||
|
message: i18n("admin.customize.theme.install_success", {
|
||||||
|
theme: component.name,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
duration: 2000,
|
||||||
|
});
|
||||||
|
this.router.refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="admin-detail">
|
||||||
|
<ThemesGrid @themes={{@components}}>
|
||||||
|
<:specialCard>
|
||||||
|
<InstallThemeCard
|
||||||
|
@component={{true}}
|
||||||
|
@openModal={{this.installModal}}
|
||||||
|
/>
|
||||||
|
</:specialCard>
|
||||||
|
</ThemesGrid>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
}
|
@ -1,12 +1,13 @@
|
|||||||
import Component from "@glimmer/component";
|
import Component from "@glimmer/component";
|
||||||
import { action } from "@ember/object";
|
import { action } from "@ember/object";
|
||||||
import { service } from "@ember/service";
|
import { service } from "@ember/service";
|
||||||
import DPageSubheader from "discourse/components/d-page-subheader";
|
|
||||||
import { i18n } from "discourse-i18n";
|
import { i18n } from "discourse-i18n";
|
||||||
|
import InstallThemeCard from "admin/components/admin-config-area-cards/install-theme-card";
|
||||||
import InstallThemeModal from "admin/components/modal/install-theme";
|
import InstallThemeModal from "admin/components/modal/install-theme";
|
||||||
import ThemesGrid from "admin/components/themes-grid";
|
import ThemesGrid from "admin/components/themes-grid";
|
||||||
|
import { THEMES } from "admin/models/theme";
|
||||||
|
|
||||||
export default class AdminConfigAreasLookAndFeelThemes extends Component {
|
export default class AdminConfigAreasThemes extends Component {
|
||||||
@service modal;
|
@service modal;
|
||||||
@service router;
|
@service router;
|
||||||
@service toasts;
|
@service toasts;
|
||||||
@ -24,12 +25,13 @@ export default class AdminConfigAreasLookAndFeelThemes extends Component {
|
|||||||
// that sits in the route.
|
// that sits in the route.
|
||||||
installThemeOptions() {
|
installThemeOptions() {
|
||||||
return {
|
return {
|
||||||
selectedType: "theme",
|
selectedType: THEMES,
|
||||||
userId: null,
|
userId: null,
|
||||||
content: [],
|
content: [],
|
||||||
installedThemes: this.args.themes,
|
installedThemes: this.args.themes,
|
||||||
addTheme: this.addTheme,
|
addTheme: this.addTheme,
|
||||||
updateSelectedType: () => {},
|
updateSelectedType: () => {},
|
||||||
|
showThemesOnly: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,23 +49,12 @@ export default class AdminConfigAreasLookAndFeelThemes extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<DPageSubheader
|
|
||||||
@titleLabel={{i18n "admin.config_areas.look_and_feel.themes.title"}}
|
|
||||||
@descriptionLabel={{i18n "admin.customize.theme.themes_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">
|
<div class="admin-detail">
|
||||||
<ThemesGrid @themes={{@themes}} />
|
<ThemesGrid @themes={{@themes}}>
|
||||||
|
<:specialCard>
|
||||||
|
<InstallThemeCard @openModal={{this.installModal}} />
|
||||||
|
</:specialCard>
|
||||||
|
</ThemesGrid>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
}
|
}
|
@ -111,7 +111,8 @@ export default class InstallThemeModal extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get themes() {
|
get themes() {
|
||||||
return POPULAR_THEMES.map((popularTheme) => {
|
const list = [];
|
||||||
|
POPULAR_THEMES.forEach((popularTheme) => {
|
||||||
if (
|
if (
|
||||||
this.args.model.installedThemes.some((installedTheme) =>
|
this.args.model.installedThemes.some((installedTheme) =>
|
||||||
this.themeHasSameUrl(installedTheme, popularTheme.value)
|
this.themeHasSameUrl(installedTheme, popularTheme.value)
|
||||||
@ -119,8 +120,20 @@ export default class InstallThemeModal extends Component {
|
|||||||
) {
|
) {
|
||||||
popularTheme.installed = true;
|
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() {
|
get installingMessage() {
|
||||||
|
@ -12,21 +12,6 @@ export default class ThemesGrid extends Component {
|
|||||||
|
|
||||||
sortedThemes;
|
sortedThemes;
|
||||||
|
|
||||||
externalResources = [
|
|
||||||
{
|
|
||||||
key: "admin.customize.theme.beginners_guide_title",
|
|
||||||
link: "https://meta.discourse.org/t/91966",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "admin.customize.theme.developers_guide_title",
|
|
||||||
link: "https://meta.discourse.org/t/93648",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "admin.customize.theme.browse_themes",
|
|
||||||
link: "https://meta.discourse.org/c/theme",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super(...arguments);
|
super(...arguments);
|
||||||
|
|
||||||
@ -51,6 +36,9 @@ export default class ThemesGrid extends Component {
|
|||||||
{{#each @themes as |theme|}}
|
{{#each @themes as |theme|}}
|
||||||
<ThemesGridCard @theme={{theme}} @allThemes={{@themes}} />
|
<ThemesGridCard @theme={{theme}} @allThemes={{@themes}} />
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
{{#if (has-block "specialCard")}}
|
||||||
|
{{yield to="specialCard"}}
|
||||||
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
import DiscourseRoute from "discourse/routes/discourse";
|
||||||
|
import { i18n } from "discourse-i18n";
|
||||||
|
|
||||||
|
export default class AdminConfigThemesAndComponentsComponentsRoute extends DiscourseRoute {
|
||||||
|
async model() {
|
||||||
|
const components = await this.store.findAll("theme");
|
||||||
|
return components.reject((t) => !t.component);
|
||||||
|
}
|
||||||
|
|
||||||
|
titleToken() {
|
||||||
|
return i18n("admin.config_areas.themes_and_components.components.title");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
import { service } from "@ember/service";
|
||||||
|
import DiscourseRoute from "discourse/routes/discourse";
|
||||||
|
|
||||||
|
export default class AdminConfigThemesAndComponentsIndexRoute extends DiscourseRoute {
|
||||||
|
@service router;
|
||||||
|
|
||||||
|
beforeModel() {
|
||||||
|
this.router.replaceWith("adminConfig.customize.themes");
|
||||||
|
}
|
||||||
|
}
|
@ -1,13 +1,13 @@
|
|||||||
import DiscourseRoute from "discourse/routes/discourse";
|
import DiscourseRoute from "discourse/routes/discourse";
|
||||||
import { i18n } from "discourse-i18n";
|
import { i18n } from "discourse-i18n";
|
||||||
|
|
||||||
export default class AdminConfigLookAndFeelThemesRoute extends DiscourseRoute {
|
export default class AdminConfigThemesAndComponentsThemesRoute extends DiscourseRoute {
|
||||||
async model() {
|
async model() {
|
||||||
const themes = await this.store.findAll("theme");
|
const themes = await this.store.findAll("theme");
|
||||||
return themes.reject((t) => t.component);
|
return themes.reject((t) => t.component);
|
||||||
}
|
}
|
||||||
|
|
||||||
titleToken() {
|
titleToken() {
|
||||||
return i18n("admin.config_areas.look_and_feel.themes.title");
|
return i18n("admin.config_areas.themes_and_components.themes.title");
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,10 +2,10 @@ import { service } from "@ember/service";
|
|||||||
import DiscourseRoute from "discourse/routes/discourse";
|
import DiscourseRoute from "discourse/routes/discourse";
|
||||||
import { i18n } from "discourse-i18n";
|
import { i18n } from "discourse-i18n";
|
||||||
|
|
||||||
export default class AdminConfigLookAndFeelRoute extends DiscourseRoute {
|
export default class AdminConfigThemesAndComponentsRoute extends DiscourseRoute {
|
||||||
@service router;
|
@service router;
|
||||||
|
|
||||||
titleToken() {
|
titleToken() {
|
||||||
return i18n("admin.config_areas.look_and_feel.title");
|
return i18n("admin.config_areas.themes_and_components.title");
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,10 +0,0 @@
|
|||||||
import { service } from "@ember/service";
|
|
||||||
import AdminConfigWithSettingsRoute from "./admin-config-with-settings-route";
|
|
||||||
|
|
||||||
export default class AdminConfigLookAndFeelIndexRoute extends AdminConfigWithSettingsRoute {
|
|
||||||
@service router;
|
|
||||||
|
|
||||||
beforeModel() {
|
|
||||||
this.router.replaceWith("adminConfig.lookAndFeel.themes");
|
|
||||||
}
|
|
||||||
}
|
|
@ -276,8 +276,9 @@ export default function () {
|
|||||||
path: "/",
|
path: "/",
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
this.route("lookAndFeel", { path: "/look-and-feel" }, function () {
|
this.route("customize", function () {
|
||||||
this.route("themes");
|
this.route("themes");
|
||||||
|
this.route("components");
|
||||||
});
|
});
|
||||||
this.route(
|
this.route(
|
||||||
"adminPermalinks",
|
"adminPermalinks",
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
<DBreadcrumbsItem
|
||||||
|
@path="/admin/config/customize/components"
|
||||||
|
@label={{i18n "admin.config_areas.themes_and_components.components.title"}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<AdminConfigAreas::Components @components={{this.model}} />
|
@ -0,0 +1,6 @@
|
|||||||
|
<DBreadcrumbsItem
|
||||||
|
@path="/admin/config/customize/themes"
|
||||||
|
@label={{i18n "admin.config_areas.themes_and_components.themes.title"}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<AdminConfigAreas::Themes @themes={{this.model}} />
|
@ -0,0 +1,28 @@
|
|||||||
|
<DPageHeader
|
||||||
|
@titleLabel={{i18n "admin.config_areas.themes_and_components.title"}}
|
||||||
|
@descriptionLabel={{i18n
|
||||||
|
"admin.config_areas.themes_and_components.description"
|
||||||
|
}}
|
||||||
|
@learnMoreUrl="https://meta.discourse.org/t/beginners-guide-to-using-discourse-themes/91966"
|
||||||
|
>
|
||||||
|
<:breadcrumbs>
|
||||||
|
<DBreadcrumbsItem @path="/admin" @label={{i18n "admin_title"}} />
|
||||||
|
</:breadcrumbs>
|
||||||
|
|
||||||
|
<:tabs>
|
||||||
|
<NavItem
|
||||||
|
@route="adminConfig.customize.themes"
|
||||||
|
@label="admin.config_areas.themes_and_components.themes.title"
|
||||||
|
/>
|
||||||
|
<NavItem
|
||||||
|
@route="adminConfig.customize.components"
|
||||||
|
@label="admin.config_areas.themes_and_components.components.title"
|
||||||
|
/>
|
||||||
|
</:tabs>
|
||||||
|
</DPageHeader>
|
||||||
|
|
||||||
|
<div class="admin-container admin-config-page__main-area">
|
||||||
|
<PluginOutlet @name="admin-config-customize">
|
||||||
|
{{outlet}}
|
||||||
|
</PluginOutlet>
|
||||||
|
</div>
|
@ -1,6 +0,0 @@
|
|||||||
<DBreadcrumbsItem
|
|
||||||
@path="/admin/config/look-and-feel/themes"
|
|
||||||
@label={{i18n "admin.config_areas.look_and_feel.themes.title"}}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<AdminConfigAreas::LookAndFeelThemes @themes={{this.model}} />
|
|
@ -1,24 +0,0 @@
|
|||||||
<DPageHeader
|
|
||||||
@titleLabel={{i18n "admin.config_areas.look_and_feel.title"}}
|
|
||||||
@descriptionLabel={{i18n "admin.config_areas.look_and_feel.description"}}
|
|
||||||
@learnMoreUrl="https://meta.discourse.org/t/beginners-guide-to-using-discourse-themes/91966"
|
|
||||||
>
|
|
||||||
<:breadcrumbs>
|
|
||||||
<DBreadcrumbsItem @path="/admin" @label={{i18n "admin_title"}} />
|
|
||||||
<DBreadcrumbsItem
|
|
||||||
@path="/admin/config/look-and-feel"
|
|
||||||
@label={{i18n "admin.config_areas.look_and_feel.title"}}
|
|
||||||
/>
|
|
||||||
</:breadcrumbs>
|
|
||||||
|
|
||||||
<:tabs>
|
|
||||||
<NavItem
|
|
||||||
@route="adminConfig.lookAndFeel.themes"
|
|
||||||
@label="admin.config_areas.look_and_feel.themes.title"
|
|
||||||
/>
|
|
||||||
</:tabs>
|
|
||||||
</DPageHeader>
|
|
||||||
|
|
||||||
<div class="admin-container admin-config-page__main-area">
|
|
||||||
{{outlet}}
|
|
||||||
</div>
|
|
@ -1,6 +1,24 @@
|
|||||||
{{#if this.editingThemeSetting}}
|
{{#if this.editingThemeSetting}}
|
||||||
{{outlet}}
|
{{outlet}}
|
||||||
{{else}}
|
{{else}}
|
||||||
|
<div class="back-to-themes-and-components">
|
||||||
|
<LinkTo
|
||||||
|
@route={{if
|
||||||
|
this.model.component
|
||||||
|
"adminConfig.customize.components"
|
||||||
|
"adminConfig.customize.themes"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{{dIcon "angle-left"}}
|
||||||
|
{{i18n
|
||||||
|
(if
|
||||||
|
this.model.component
|
||||||
|
"admin.config_areas.themes_and_components.components.back"
|
||||||
|
"admin.config_areas.themes_and_components.themes.back"
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
</LinkTo>
|
||||||
|
</div>
|
||||||
<div class="show-current-style">
|
<div class="show-current-style">
|
||||||
<span>
|
<span>
|
||||||
<PluginOutlet
|
<PluginOutlet
|
||||||
|
@ -1,43 +1,3 @@
|
|||||||
{{#if (eq this.currentTab "themes")}}
|
|
||||||
<DPageHeader
|
|
||||||
@titleLabel={{i18n "admin.config.themes.title"}}
|
|
||||||
@descriptionLabel={{i18n "admin.config.themes.header_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.config.themes.title"}}
|
|
||||||
/>
|
|
||||||
</:breadcrumbs>
|
|
||||||
</DPageHeader>
|
|
||||||
{{else}}
|
|
||||||
<DPageHeader
|
|
||||||
@titleLabel={{i18n "admin.config.components.title"}}
|
|
||||||
@descriptionLabel={{i18n "admin.config.components.header_description"}}
|
|
||||||
@hideTabs={{true}}
|
|
||||||
>
|
|
||||||
<:breadcrumbs>
|
|
||||||
<DBreadcrumbsItem @path="/admin" @label={{i18n "admin_title"}} />
|
|
||||||
<DBreadcrumbsItem
|
|
||||||
@path="/admin/customize/components"
|
|
||||||
@label={{i18n "admin.config.components.title"}}
|
|
||||||
/>
|
|
||||||
</:breadcrumbs>
|
|
||||||
</DPageHeader>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
<PluginOutlet @name="admin-customize-themes">
|
<PluginOutlet @name="admin-customize-themes">
|
||||||
{{#unless this.editingTheme}}
|
|
||||||
<ThemesList
|
|
||||||
@themes={{this.fullThemes}}
|
|
||||||
@components={{this.childThemes}}
|
|
||||||
@currentTab={{this.currentTab}}
|
|
||||||
@installModal={{route-action "installModal"}}
|
|
||||||
/>
|
|
||||||
{{/unless}}
|
|
||||||
|
|
||||||
{{outlet}}
|
{{outlet}}
|
||||||
</PluginOutlet>
|
</PluginOutlet>
|
@ -240,22 +240,14 @@ export const ADMIN_NAV_MAP = [
|
|||||||
settings_area: "navigation",
|
settings_area: "navigation",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "admin_themes",
|
name: "admin_themes_and_components",
|
||||||
route: "adminCustomizeThemes",
|
route: "adminConfig.customize.themes",
|
||||||
routeModels: ["themes"],
|
currentWhen:
|
||||||
model: "themes",
|
"adminConfig.customize.themes adminConfig.customize.components",
|
||||||
label: "admin.config.themes.title",
|
label: "admin.appearance.sidebar_link.themes_and_components.title",
|
||||||
description: "admin.config.themes.header_description",
|
|
||||||
icon: "paintbrush",
|
icon: "paintbrush",
|
||||||
},
|
keywords:
|
||||||
{
|
"admin.appearance.sidebar_link.themes_and_components.keywords",
|
||||||
name: "admin_components",
|
|
||||||
route: "adminCustomizeThemes",
|
|
||||||
routeModels: ["components"],
|
|
||||||
label: "admin.config.components.title",
|
|
||||||
description: "admin.config.components.header_description",
|
|
||||||
icon: "puzzle-piece",
|
|
||||||
keywords: "admin.config.components.keywords",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "admin_customize_site_texts",
|
name: "admin_customize_site_texts",
|
||||||
|
@ -93,6 +93,9 @@ class SidebarAdminSectionLink extends BaseCustomSidebarSectionLink {
|
|||||||
return this.router.currentRoute.name;
|
return this.router.currentRoute.name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (this.adminSidebarNavLink.currentWhen) {
|
||||||
|
return this.adminSidebarNavLink.currentWhen;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get keywords() {
|
get keywords() {
|
||||||
@ -352,11 +355,11 @@ export default class AdminSidebarPanel extends BaseCustomSidebarPanel {
|
|||||||
|
|
||||||
store.findAll("theme").then((themes) => {
|
store.findAll("theme").then((themes) => {
|
||||||
this.adminSidebarStateManager.setLinkKeywords(
|
this.adminSidebarStateManager.setLinkKeywords(
|
||||||
"admin_themes",
|
"admin_themes_and_components",
|
||||||
themes.content.rejectBy("component").mapBy("name")
|
themes.content.rejectBy("component").mapBy("name")
|
||||||
);
|
);
|
||||||
this.adminSidebarStateManager.setLinkKeywords(
|
this.adminSidebarStateManager.setLinkKeywords(
|
||||||
"admin_components",
|
"admin_themes_and_components",
|
||||||
themes.content.filterBy("component").mapBy("name")
|
themes.content.filterBy("component").mapBy("name")
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -175,9 +175,9 @@ acceptance("Theme", function (needs) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("can force install themes", async function (assert) {
|
test("can force install themes", async function (assert) {
|
||||||
await visit("/admin/customize/themes");
|
await visit("/admin/config/customize/themes");
|
||||||
|
|
||||||
await click(".themes-list .create-actions button");
|
await click(".theme-install-card .btn-primary");
|
||||||
await click(".install-theme-items #remote");
|
await click(".install-theme-items #remote");
|
||||||
await fillIn(
|
await fillIn(
|
||||||
".install-theme-content .repo input",
|
".install-theme-content .repo input",
|
||||||
@ -200,9 +200,9 @@ acceptance("Theme", function (needs) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("can continue installation", async function (assert) {
|
test("can continue installation", async function (assert) {
|
||||||
await visit("/admin/customize/themes");
|
await visit("/admin/config/customize/themes");
|
||||||
|
|
||||||
await click(".themes-list-container__item .info");
|
await click(".theme-card .btn-primary");
|
||||||
assert
|
assert
|
||||||
.dom(".control-unit .status-message")
|
.dom(".control-unit .status-message")
|
||||||
.includesText(
|
.includesText(
|
||||||
|
@ -853,6 +853,18 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.theme-install-card {
|
||||||
|
&__external-links {
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__install-button {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.add-upload-modal {
|
.add-upload-modal {
|
||||||
input[type="file"] {
|
input[type="file"] {
|
||||||
display: block;
|
display: block;
|
||||||
@ -1191,7 +1203,7 @@
|
|||||||
|
|
||||||
.desktop-view .admin-customize {
|
.desktop-view .admin-customize {
|
||||||
.show-current-style {
|
.show-current-style {
|
||||||
padding-left: 2%;
|
padding-left: 0;
|
||||||
width: 68%;
|
width: 68%;
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
@ -1204,6 +1216,10 @@
|
|||||||
.themes-list {
|
.themes-list {
|
||||||
width: 28%;
|
width: 28%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.back-to-themes-and-components {
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobile-view .admin-customize {
|
.mobile-view .admin-customize {
|
||||||
|
9
app/controllers/admin/config/customize_controller.rb
Normal file
9
app/controllers/admin/config/customize_controller.rb
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class Admin::Config::CustomizeController < Admin::AdminController
|
||||||
|
def themes
|
||||||
|
end
|
||||||
|
|
||||||
|
def components
|
||||||
|
end
|
||||||
|
end
|
@ -1,6 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class Admin::Config::LookAndFeelController < Admin::AdminController
|
|
||||||
def themes
|
|
||||||
end
|
|
||||||
end
|
|
@ -5958,6 +5958,72 @@ en:
|
|||||||
failed: "Failed"
|
failed: "Failed"
|
||||||
home:
|
home:
|
||||||
title: "Home"
|
title: "Home"
|
||||||
|
account:
|
||||||
|
title: "Account"
|
||||||
|
sidebar_link:
|
||||||
|
backups: "Backups"
|
||||||
|
whats_new:
|
||||||
|
title: "What's new?"
|
||||||
|
keywords: "changelog|feature|release"
|
||||||
|
|
||||||
|
community:
|
||||||
|
title: "Community"
|
||||||
|
sidebar_link:
|
||||||
|
about_your_site: "About your site"
|
||||||
|
badges: "Badges"
|
||||||
|
login_and_authentication: "Login & authentication"
|
||||||
|
notifications: "Notifications"
|
||||||
|
permalinks: "Permalinks"
|
||||||
|
trust_levels: "Trust levels"
|
||||||
|
group_permissions: "Group permissions"
|
||||||
|
users: "Users"
|
||||||
|
groups: "Groups"
|
||||||
|
user_fields: "User fields"
|
||||||
|
watched_words: "Watched words"
|
||||||
|
legal: "Legal"
|
||||||
|
moderation_flags:
|
||||||
|
title: "Moderation"
|
||||||
|
keywords: "flag|review"
|
||||||
|
|
||||||
|
appearance:
|
||||||
|
title: "Appearance"
|
||||||
|
sidebar_link:
|
||||||
|
font_style: "Font style"
|
||||||
|
site_logo: "Site logo"
|
||||||
|
color_schemes: "Color palettes"
|
||||||
|
emoji: "Emoji"
|
||||||
|
navigation: "Navigation"
|
||||||
|
themes_and_components:
|
||||||
|
title: "Themes and components"
|
||||||
|
keywords: "extension"
|
||||||
|
site_texts: "Site texts"
|
||||||
|
|
||||||
|
email_settings:
|
||||||
|
title: "Email Settings"
|
||||||
|
sidebar_link:
|
||||||
|
appearance: "Appearance"
|
||||||
|
server_setup:
|
||||||
|
title: "Server setup & logs"
|
||||||
|
keywords: "email|smtp|mailgun|sendgrid|sent|skipped|bounced|received|rejected|email logs|preview summary"
|
||||||
|
|
||||||
|
security:
|
||||||
|
title: "Security"
|
||||||
|
sidebar_link:
|
||||||
|
security: "Security settings"
|
||||||
|
spam: "Spam settings"
|
||||||
|
staff_action_logs:
|
||||||
|
title: "Logs & screening"
|
||||||
|
keywords: "error logs|staff action|screened emails|screened ips|screened urls|search logs"
|
||||||
|
|
||||||
|
section_landing_pages:
|
||||||
|
account:
|
||||||
|
title: "Account"
|
||||||
|
backups:
|
||||||
|
title: "Backups"
|
||||||
|
description: "Take a backup of your site's data"
|
||||||
|
whats_new:
|
||||||
|
title: "What's new?"
|
||||||
|
description: "Discover new releases and improvements to Discourse"
|
||||||
|
|
||||||
config_areas:
|
config_areas:
|
||||||
about:
|
about:
|
||||||
@ -6054,16 +6120,21 @@ en:
|
|||||||
delete: "Delete"
|
delete: "Delete"
|
||||||
more_options:
|
more_options:
|
||||||
title: "More options"
|
title: "More options"
|
||||||
look_and_feel:
|
themes_and_components:
|
||||||
|
title: "Themes and components"
|
||||||
|
description: "Personalize your Discourse site with themes and components to match your needs."
|
||||||
|
breadcrumb_title: "Customize"
|
||||||
|
install: "Install"
|
||||||
themes:
|
themes:
|
||||||
title: "Themes"
|
title: "Themes"
|
||||||
themes_intro: "Install a new theme to get started, or create your own from scratch using these resources."
|
themes_intro: "Install a new theme to get started, or create your own from scratch using these resources."
|
||||||
themes_intro_img_alt: "New theme placeholder"
|
|
||||||
set_default_theme: "Set default"
|
|
||||||
default_theme: "Default theme"
|
|
||||||
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"
|
new_theme: "New theme"
|
||||||
user_selectable: "User selectable"
|
back: "Back to themes"
|
||||||
|
components:
|
||||||
|
title: "Components"
|
||||||
|
components_intro: "Install a new component to get started, or create your own from scratch using these resources."
|
||||||
|
new_component: "New component"
|
||||||
|
back: "Back to components"
|
||||||
user_fields:
|
user_fields:
|
||||||
field: "Field"
|
field: "Field"
|
||||||
type: "Type"
|
type: "Type"
|
||||||
@ -6240,6 +6311,7 @@ en:
|
|||||||
component_name: "Component name"
|
component_name: "Component name"
|
||||||
themes_intro: "Select an existing theme or install a new one to get started"
|
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."
|
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"
|
themes_intro_img_alt: "New theme placeholder"
|
||||||
beginners_guide_title: "Beginner’s guide to using Discourse Themes"
|
beginners_guide_title: "Beginner’s guide to using Discourse Themes"
|
||||||
developers_guide_title: "Developer’s guide to Discourse Themes"
|
developers_guide_title: "Developer’s guide to Discourse Themes"
|
||||||
|
@ -426,11 +426,14 @@ Discourse::Application.routes.draw do
|
|||||||
collection { put "/" => "about#update" }
|
collection { put "/" => "about#update" }
|
||||||
end
|
end
|
||||||
|
|
||||||
resources :look_and_feel,
|
resources :customize,
|
||||||
path: "look-and-feel",
|
path: "customize",
|
||||||
constraints: AdminConstraint.new,
|
constraints: AdminConstraint.new,
|
||||||
only: %i[index] do
|
only: %i[index] do
|
||||||
collection { get "/themes" => "look_and_feel#themes" }
|
collection do
|
||||||
|
get "/themes" => "customize#themes"
|
||||||
|
get "/components" => "customize#components"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ module SvgSprite
|
|||||||
align-left
|
align-left
|
||||||
anchor
|
anchor
|
||||||
angle-down
|
angle-down
|
||||||
|
angle-left
|
||||||
angle-right
|
angle-right
|
||||||
angle-up
|
angle-up
|
||||||
angles-down
|
angles-down
|
||||||
|
38
spec/system/admin_customize_config_area_spec.rb
Normal file
38
spec/system/admin_customize_config_area_spec.rb
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
describe "Admin Customize Config Area Page", type: :system do
|
||||||
|
fab!(:admin)
|
||||||
|
|
||||||
|
let(:config_area) { PageObjects::Pages::AdminCustomizeConfigArea.new }
|
||||||
|
let(:install_modal) { PageObjects::Modals::InstallTheme.new }
|
||||||
|
|
||||||
|
before { sign_in(admin) }
|
||||||
|
|
||||||
|
context "when in the themes tab" do
|
||||||
|
it "has a special card for installing new themes" do
|
||||||
|
config_area.visit
|
||||||
|
|
||||||
|
expect(config_area.install_card).to have_text(
|
||||||
|
I18n.t("admin_js.admin.config_areas.themes_and_components.themes.new_theme"),
|
||||||
|
)
|
||||||
|
|
||||||
|
config_area.install_card.find(".btn-primary").click
|
||||||
|
expect(install_modal).to be_open
|
||||||
|
expect(install_modal.popular_options.first).to have_text("Air")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when in the components tab" do
|
||||||
|
it "has a special card for installing new components" do
|
||||||
|
config_area.visit_components
|
||||||
|
|
||||||
|
expect(config_area.install_card).to have_text(
|
||||||
|
I18n.t("admin_js.admin.config_areas.themes_and_components.components.new_component"),
|
||||||
|
)
|
||||||
|
|
||||||
|
config_area.install_card.find(".btn-primary").click
|
||||||
|
expect(install_modal).to be_open
|
||||||
|
expect(install_modal.popular_options.first).to have_text("Brand Header")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -9,76 +9,6 @@ describe "Admin Customize Themes", type: :system do
|
|||||||
|
|
||||||
before { sign_in(admin) }
|
before { sign_in(admin) }
|
||||||
|
|
||||||
describe "when visiting the page to customize themes" do
|
|
||||||
fab!(:theme_2) { Fabricate(:theme, name: "Cool theme 2") }
|
|
||||||
fab!(:theme_3) { Fabricate(:theme, name: "Cool theme 3") }
|
|
||||||
let(:delete_themes_confirm_modal) { PageObjects::Modals::DeleteThemesConfirm.new }
|
|
||||||
|
|
||||||
it "should allow admin to bulk delete inactive themes" do
|
|
||||||
visit("/admin/customize/themes")
|
|
||||||
|
|
||||||
expect(admin_customize_themes_page).to have_inactive_themes
|
|
||||||
|
|
||||||
admin_customize_themes_page.click_select_inactive_mode
|
|
||||||
expect(admin_customize_themes_page).to have_inactive_themes_selected(count: 0)
|
|
||||||
admin_customize_themes_page.toggle_all_inactive
|
|
||||||
expect(admin_customize_themes_page).to have_inactive_themes_selected(count: 3)
|
|
||||||
|
|
||||||
admin_customize_themes_page.cancel_select_inactive_mode
|
|
||||||
expect(admin_customize_themes_page).to have_select_inactive_mode_button
|
|
||||||
|
|
||||||
admin_customize_themes_page.click_select_inactive_mode
|
|
||||||
expect(admin_customize_themes_page).to have_disabled_delete_theme_button
|
|
||||||
|
|
||||||
admin_customize_themes_page.toggle_all_inactive
|
|
||||||
|
|
||||||
admin_customize_themes_page.click_delete_themes_button
|
|
||||||
|
|
||||||
expect(delete_themes_confirm_modal).to have_theme(theme.name)
|
|
||||||
expect(delete_themes_confirm_modal).to have_theme(theme_2.name)
|
|
||||||
expect(delete_themes_confirm_modal).to have_theme(theme_3.name)
|
|
||||||
delete_themes_confirm_modal.confirm
|
|
||||||
|
|
||||||
expect(admin_customize_themes_page).to have_no_inactive_themes
|
|
||||||
end
|
|
||||||
|
|
||||||
it "selects the themes tab by default" do
|
|
||||||
visit("/admin/customize/themes")
|
|
||||||
expect(find(".themes-list-header")).to have_css(".themes-tab.active")
|
|
||||||
end
|
|
||||||
|
|
||||||
it "selects the component tab when visiting the theme-components route" do
|
|
||||||
visit("/admin/customize/components")
|
|
||||||
expect(find(".themes-list-header")).to have_css(".components-tab.active")
|
|
||||||
end
|
|
||||||
|
|
||||||
it "switching between themes and components tabs keeps the search visible only if both tabs have at least 10 items" do
|
|
||||||
(1..6).each { |number| Fabricate(:theme, component: false, name: "Cool theme #{number}") }
|
|
||||||
(1..5).each { |number| Fabricate(:theme, component: true, name: "Cool component #{number}") }
|
|
||||||
|
|
||||||
visit("/admin/customize/themes")
|
|
||||||
expect(admin_customize_themes_page).to have_themes(count: 11)
|
|
||||||
|
|
||||||
admin_customize_themes_page.search("5")
|
|
||||||
expect(admin_customize_themes_page).to have_themes(count: 1)
|
|
||||||
|
|
||||||
admin_customize_themes_page.switch_to_components
|
|
||||||
expect(admin_customize_themes_page).to have_no_search
|
|
||||||
expect(admin_customize_themes_page).to have_themes(count: 5)
|
|
||||||
|
|
||||||
(6..11).each { |number| Fabricate(:theme, component: true, name: "Cool component #{number}") }
|
|
||||||
|
|
||||||
visit("/admin/customize/components")
|
|
||||||
expect(admin_customize_themes_page).to have_themes(count: 11)
|
|
||||||
|
|
||||||
admin_customize_themes_page.search("5")
|
|
||||||
expect(admin_customize_themes_page).to have_themes(count: 1)
|
|
||||||
|
|
||||||
admin_customize_themes_page.switch_to_themes
|
|
||||||
expect(admin_customize_themes_page).to have_themes(count: 1)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "when visiting the page to customize a single theme" do
|
describe "when visiting the page to customize a single theme" do
|
||||||
it "should allow admin to update the color scheme of the theme" do
|
it "should allow admin to update the color scheme of the theme" do
|
||||||
visit("/admin/customize/themes/#{theme.id}")
|
visit("/admin/customize/themes/#{theme.id}")
|
||||||
@ -213,4 +143,20 @@ describe "Admin Customize Themes", type: :system do
|
|||||||
expect(theme_translations_picker.component.text).to eq("English (US)")
|
expect(theme_translations_picker.component.text).to eq("English (US)")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "when visting a theme's page" do
|
||||||
|
it "has a link to the themes 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
|
||||||
|
fab!(:component) { Fabricate(:theme, component: true, name: "Cool component 493") }
|
||||||
|
|
||||||
|
it "has a link to the components page" do
|
||||||
|
visit("/admin/customize/themes/#{component.id}")
|
||||||
|
expect(admin_customize_themes_page).to have_back_button_to_components_page
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -293,12 +293,26 @@ describe "Admin | Sidebar Navigation", type: :system do
|
|||||||
filter.filter("air")
|
filter.filter("air")
|
||||||
links = page.all(".sidebar-section-link-content-text")
|
links = page.all(".sidebar-section-link-content-text")
|
||||||
expect(links.count).to eq(1)
|
expect(links.count).to eq(1)
|
||||||
expect(links.map(&:text)).to eq(["Themes"])
|
expect(links.map(&:text)).to eq(["Themes and components"])
|
||||||
|
|
||||||
filter.filter("kanban")
|
filter.filter("kanban")
|
||||||
links = page.all(".sidebar-section-link-content-text")
|
links = page.all(".sidebar-section-link-content-text")
|
||||||
expect(links.count).to eq(1)
|
expect(links.count).to eq(1)
|
||||||
expect(links.map(&:text)).to eq(["Components"])
|
expect(links.map(&:text)).to eq(["Themes and components"])
|
||||||
|
end
|
||||||
|
|
||||||
|
it "highlights the 'Themes and components' link when the themes page is visited" do
|
||||||
|
visit("/admin/config/customize/themes")
|
||||||
|
expect(page).to have_css(
|
||||||
|
'.sidebar-section-link-wrapper[data-list-item-name="admin_themes_and_components"] a.active',
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "highlights the 'Themes and components' link when the components page is visited" do
|
||||||
|
visit("/admin/config/customize/components")
|
||||||
|
expect(page).to have_css(
|
||||||
|
'.sidebar-section-link-wrapper[data-list-item-name="admin_themes_and_components"] a.active',
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does not show the button to customize sidebar sections, that is only supported in the main panel" do
|
it "does not show the button to customize sidebar sections, that is only supported in the main panel" do
|
||||||
|
15
spec/system/page_objects/modals/install_theme.rb
Normal file
15
spec/system/page_objects/modals/install_theme.rb
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module PageObjects
|
||||||
|
module Modals
|
||||||
|
class InstallTheme < PageObjects::Modals::Base
|
||||||
|
def modal
|
||||||
|
find(".admin-install-theme-modal")
|
||||||
|
end
|
||||||
|
|
||||||
|
def popular_options
|
||||||
|
all(".popular-theme-item")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,19 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module PageObjects
|
||||||
|
module Pages
|
||||||
|
class AdminCustomizeConfigArea < PageObjects::Pages::Base
|
||||||
|
def visit
|
||||||
|
page.visit("/admin/config/customize")
|
||||||
|
end
|
||||||
|
|
||||||
|
def visit_components
|
||||||
|
page.visit("/admin/config/customize/components")
|
||||||
|
end
|
||||||
|
|
||||||
|
def install_card
|
||||||
|
find(".theme-install-card")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -27,6 +27,28 @@ module PageObjects
|
|||||||
has_css?("#{setting_selector(setting_name)} .desc", exact_text: description)
|
has_css?("#{setting_selector(setting_name)} .desc", exact_text: description)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def has_no_themes_list?
|
||||||
|
has_no_css?(".themes-list-header")
|
||||||
|
end
|
||||||
|
|
||||||
|
def has_back_button_to_themes_page?
|
||||||
|
has_css?(
|
||||||
|
'.back-to-themes-and-components a[href="/admin/config/customize/themes"]',
|
||||||
|
text: I18n.t("admin_js.admin.config_areas.themes_and_components.themes.back"),
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def has_back_button_to_components_page?
|
||||||
|
has_css?(
|
||||||
|
'.back-to-themes-and-components a[href="/admin/config/customize/components"]',
|
||||||
|
text: I18n.t("admin_js.admin.config_areas.themes_and_components.components.back"),
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def has_no_page_header?
|
||||||
|
has_no_css?(".d-page-header")
|
||||||
|
end
|
||||||
|
|
||||||
def reset_overridden_setting(setting_name)
|
def reset_overridden_setting(setting_name)
|
||||||
setting_section = find("section.theme.settings .setting[data-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"))
|
setting_section.click_button(I18n.t("admin_js.admin.settings.reset"))
|
||||||
|
Reference in New Issue
Block a user