FEATURE: direct link to components for admin sidebar (#26644)
To add a components link to the sidebar refactoring was required to create unique URLs for themes and components. Before the query param was used. After changes, we have two URLs `/admin/customize/themes` and `/admin/customize/components`.
This commit is contained in:
parent
56c4804440
commit
df373d90fe
|
@ -77,6 +77,13 @@ export default class ThemesList extends Component {
|
||||||
@equal("filter", ACTIVE_FILTER) activeFilter;
|
@equal("filter", ACTIVE_FILTER) activeFilter;
|
||||||
@equal("filter", INACTIVE_FILTER) inactiveFilter;
|
@equal("filter", INACTIVE_FILTER) inactiveFilter;
|
||||||
|
|
||||||
|
willRender() {
|
||||||
|
super.willRender(...arguments);
|
||||||
|
if (!this.showSearchAndFilter) {
|
||||||
|
this.set("searchTerm", null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@discourseComputed("themes", "components", "currentTab")
|
@discourseComputed("themes", "components", "currentTab")
|
||||||
themesList(themes, components) {
|
themesList(themes, components) {
|
||||||
if (this.themesTabActive) {
|
if (this.themesTabActive) {
|
||||||
|
@ -208,11 +215,8 @@ export default class ThemesList extends Component {
|
||||||
changeView(newTab) {
|
changeView(newTab) {
|
||||||
if (newTab !== this.currentTab) {
|
if (newTab !== this.currentTab) {
|
||||||
this.set("selectInactiveMode", false);
|
this.set("selectInactiveMode", false);
|
||||||
this.set("currentTab", newTab);
|
|
||||||
this.set("filter", ALL_FILTER);
|
this.set("filter", ALL_FILTER);
|
||||||
if (!this.showSearchAndFilter) {
|
this.router.transitionTo("adminCustomizeThemes", newTab);
|
||||||
this.set("searchTerm", null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
import Route from "@ember/routing/route";
|
|
||||||
import { service } from "@ember/service";
|
|
||||||
import { COMPONENTS } from "admin/models/theme";
|
|
||||||
|
|
||||||
export default class AdminCustomizeThemeComponents extends Route {
|
|
||||||
@service router;
|
|
||||||
|
|
||||||
beforeModel(transition) {
|
|
||||||
transition.abort();
|
|
||||||
this.router.transitionTo("adminCustomizeThemes", {
|
|
||||||
queryParams: { tab: COMPONENTS },
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -13,23 +13,20 @@ export default class AdminCustomizeThemesRoute extends Route {
|
||||||
queryParams = {
|
queryParams = {
|
||||||
repoUrl: null,
|
repoUrl: null,
|
||||||
repoName: null,
|
repoName: null,
|
||||||
tab: null,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
model() {
|
model(params) {
|
||||||
|
this.currentTab = params.type;
|
||||||
return this.store.findAll("theme");
|
return this.store.findAll("theme");
|
||||||
}
|
}
|
||||||
|
|
||||||
setupController(controller, model) {
|
setupController(controller, model) {
|
||||||
super.setupController(controller, model);
|
super.setupController(controller, model);
|
||||||
|
|
||||||
if (controller.tab) {
|
if (this.currentTab) {
|
||||||
controller.setProperties({
|
controller.setProperties({
|
||||||
editingTheme: false,
|
editingTheme: false,
|
||||||
currentTab: controller.tab,
|
currentTab: this.currentTab,
|
||||||
|
|
||||||
// this is to get rid of the queryString since we don't want it hanging around
|
|
||||||
tab: undefined,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ export default function () {
|
||||||
|
|
||||||
this.route(
|
this.route(
|
||||||
"adminCustomizeThemes",
|
"adminCustomizeThemes",
|
||||||
{ path: "themes", resetNamespace: true },
|
{ path: "/:type", resetNamespace: true },
|
||||||
function () {
|
function () {
|
||||||
this.route("show", { path: "/:theme_id" }, function () {
|
this.route("show", { path: "/:theme_id" }, function () {
|
||||||
this.route("schema", { path: "schema/:setting_name" });
|
this.route("schema", { path: "schema/:setting_name" });
|
||||||
|
@ -64,11 +64,6 @@ export default function () {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
this.route("adminCustomizeThemeComponents", {
|
|
||||||
path: "theme-components",
|
|
||||||
resetNamespace: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
this.route(
|
this.route(
|
||||||
"adminSiteText",
|
"adminSiteText",
|
||||||
{ path: "/site_texts", resetNamespace: true },
|
{ path: "/site_texts", resetNamespace: true },
|
||||||
|
|
|
@ -25,7 +25,11 @@
|
||||||
<NavItem @route="adminEmail" @label="admin.email.title" />
|
<NavItem @route="adminEmail" @label="admin.email.title" />
|
||||||
{{/if}}
|
{{/if}}
|
||||||
<NavItem @route="adminLogs" @label="admin.logs.title" />
|
<NavItem @route="adminLogs" @label="admin.logs.title" />
|
||||||
<NavItem @route="adminCustomize" @label="admin.customize.title" />
|
<NavItem
|
||||||
|
@route="adminCustomizeThemes"
|
||||||
|
@routeParam="themes"
|
||||||
|
@label="admin.customize.title"
|
||||||
|
/>
|
||||||
{{#if this.currentUser.admin}}
|
{{#if this.currentUser.admin}}
|
||||||
<NavItem @route="adminApi" @label="admin.api.title" />
|
<NavItem @route="adminApi" @label="admin.api.title" />
|
||||||
{{#if this.siteSettings.enable_backups}}
|
{{#if this.siteSettings.enable_backups}}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
{{#if this.currentUser.admin}}
|
{{#if this.currentUser.admin}}
|
||||||
<NavItem
|
<NavItem
|
||||||
@route="adminCustomizeThemes"
|
@route="adminCustomizeThemes"
|
||||||
|
@routeParam="themes"
|
||||||
@label="admin.customize.theme.title"
|
@label="admin.customize.theme.title"
|
||||||
class="admin-customize-themes"
|
class="admin-customize-themes"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -150,10 +150,18 @@ export const ADMIN_NAV_MAP = [
|
||||||
{
|
{
|
||||||
name: "admin_themes",
|
name: "admin_themes",
|
||||||
route: "adminCustomizeThemes",
|
route: "adminCustomizeThemes",
|
||||||
query: { tab: "themes" },
|
routeModels: ["themes"],
|
||||||
|
model: "themes",
|
||||||
label: "admin.appearance.sidebar_link.themes",
|
label: "admin.appearance.sidebar_link.themes",
|
||||||
icon: "paint-brush",
|
icon: "paint-brush",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "admin_components",
|
||||||
|
route: "adminCustomizeThemes",
|
||||||
|
routeModels: ["components"],
|
||||||
|
label: "admin.appearance.sidebar_link.components",
|
||||||
|
icon: "puzzle-piece",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "admin_customize_site_texts",
|
name: "admin_customize_site_texts",
|
||||||
route: "adminSiteText",
|
route: "adminSiteText",
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { click, fillIn, render } from "@ember/test-helpers";
|
import { fillIn, render } from "@ember/test-helpers";
|
||||||
import { hbs } from "ember-cli-htmlbars";
|
import { hbs } from "ember-cli-htmlbars";
|
||||||
import { module, test } from "qunit";
|
import { module, test } from "qunit";
|
||||||
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
|
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
|
||||||
|
@ -367,86 +367,4 @@ module("Integration | Component | themes-list", function (hooks) {
|
||||||
);
|
);
|
||||||
assert.deepEqual(componentNames(), ["Component unused and disabled 1"]);
|
assert.deepEqual(componentNames(), ["Component unused and disabled 1"]);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("switching between themes and components tabs keeps the search visible only if both tabs have at least 10 items", async function (assert) {
|
|
||||||
const themes = createThemes(10, (n) => {
|
|
||||||
return { name: `Theme ${n}${n}` };
|
|
||||||
});
|
|
||||||
const components = createThemes(5, (n) => {
|
|
||||||
return {
|
|
||||||
name: `Component ${n}${n}`,
|
|
||||||
component: true,
|
|
||||||
parent_themes: [1],
|
|
||||||
parentThemes: [1],
|
|
||||||
};
|
|
||||||
});
|
|
||||||
this.setProperties({
|
|
||||||
themes,
|
|
||||||
components,
|
|
||||||
currentTab: THEMES,
|
|
||||||
});
|
|
||||||
|
|
||||||
await render(
|
|
||||||
hbs`<ThemesList @themes={{this.themes}} @components={{this.components}} @currentTab={{this.currentTab}} />`
|
|
||||||
);
|
|
||||||
|
|
||||||
await fillIn(".themes-list-search__input", "11");
|
|
||||||
assert.strictEqual(
|
|
||||||
query(".themes-list-container__item .info").textContent.trim(),
|
|
||||||
"Theme 11",
|
|
||||||
"only 1 theme is shown"
|
|
||||||
);
|
|
||||||
await click(".themes-list-header .components-tab");
|
|
||||||
assert.ok(
|
|
||||||
!exists(".themes-list-search__input"),
|
|
||||||
"search input/term do not persist when we switch to the other" +
|
|
||||||
" tab because it has fewer than 10 items"
|
|
||||||
);
|
|
||||||
assert.deepEqual(
|
|
||||||
[...queryAll(".themes-list-container__item .info .name")].map((node) =>
|
|
||||||
node.textContent.trim()
|
|
||||||
),
|
|
||||||
[
|
|
||||||
"Component 11",
|
|
||||||
"Component 22",
|
|
||||||
"Component 33",
|
|
||||||
"Component 44",
|
|
||||||
"Component 55",
|
|
||||||
],
|
|
||||||
"all components are shown"
|
|
||||||
);
|
|
||||||
|
|
||||||
this.set(
|
|
||||||
"components",
|
|
||||||
this.components.concat(
|
|
||||||
createThemes(5, (n) => {
|
|
||||||
n += 5;
|
|
||||||
return {
|
|
||||||
name: `Component ${n}${n}`,
|
|
||||||
component: true,
|
|
||||||
parent_themes: [1],
|
|
||||||
parentThemes: [1],
|
|
||||||
};
|
|
||||||
})
|
|
||||||
)
|
|
||||||
);
|
|
||||||
assert.ok(
|
|
||||||
exists(".themes-list-search__input"),
|
|
||||||
"search is now shown for the components tab"
|
|
||||||
);
|
|
||||||
|
|
||||||
await fillIn(".themes-list-search__input", "66");
|
|
||||||
assert.strictEqual(
|
|
||||||
query(".themes-list-container__item .info").textContent.trim(),
|
|
||||||
"Component 66",
|
|
||||||
"only 1 component is shown"
|
|
||||||
);
|
|
||||||
|
|
||||||
await click(".themes-list-header .themes-tab");
|
|
||||||
assert.strictEqual(
|
|
||||||
query(".themes-list-container__item .info").textContent.trim(),
|
|
||||||
"Theme 66",
|
|
||||||
"search term persisted between tabs because both have more than 10 items"
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -5337,6 +5337,7 @@ en:
|
||||||
emoji: "Emoji"
|
emoji: "Emoji"
|
||||||
navigation: "Navigation"
|
navigation: "Navigation"
|
||||||
themes: "Themes"
|
themes: "Themes"
|
||||||
|
components: "Components"
|
||||||
site_texts: "Site Texts"
|
site_texts: "Site Texts"
|
||||||
|
|
||||||
email_settings:
|
email_settings:
|
||||||
|
|
|
@ -221,6 +221,7 @@ Discourse::Application.routes.draw do
|
||||||
|
|
||||||
get "customize" => "color_schemes#index", :constraints => AdminConstraint.new
|
get "customize" => "color_schemes#index", :constraints => AdminConstraint.new
|
||||||
get "customize/themes" => "themes#index", :constraints => AdminConstraint.new
|
get "customize/themes" => "themes#index", :constraints => AdminConstraint.new
|
||||||
|
get "customize/components" => "themes#index", :constraints => AdminConstraint.new
|
||||||
get "customize/theme-components" => "themes#index", :constraints => AdminConstraint.new
|
get "customize/theme-components" => "themes#index", :constraints => AdminConstraint.new
|
||||||
get "customize/colors" => "color_schemes#index", :constraints => AdminConstraint.new
|
get "customize/colors" => "color_schemes#index", :constraints => AdminConstraint.new
|
||||||
get "customize/colors/:id" => "color_schemes#index", :constraints => AdminConstraint.new
|
get "customize/colors/:id" => "color_schemes#index", :constraints => AdminConstraint.new
|
||||||
|
@ -257,6 +258,7 @@ Discourse::Application.routes.draw do
|
||||||
|
|
||||||
get "themes/:id/:target/:field_name/edit" => "themes#index"
|
get "themes/:id/:target/:field_name/edit" => "themes#index"
|
||||||
get "themes/:id" => "themes#index"
|
get "themes/:id" => "themes#index"
|
||||||
|
get "components/:id" => "themes#index"
|
||||||
get "themes/:id/export" => "themes#export"
|
get "themes/:id/export" => "themes#export"
|
||||||
get "themes/:id/schema/:setting_name" => "themes#schema"
|
get "themes/:id/schema/:setting_name" => "themes#schema"
|
||||||
|
|
||||||
|
|
|
@ -48,9 +48,35 @@ describe "Admin Customize Themes", type: :system do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "selects the component tab when visiting the theme-components route" do
|
it "selects the component tab when visiting the theme-components route" do
|
||||||
visit("/admin/customize/theme-components")
|
visit("/admin/customize/components")
|
||||||
expect(find(".themes-list-header")).to have_css(".components-tab.active")
|
expect(find(".themes-list-header")).to have_css(".components-tab.active")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "switching between themes and components tabs keeps the search visible only if both tabs have at least 10 items" do
|
||||||
|
6.times { Fabricate(:theme) }
|
||||||
|
(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
|
end
|
||||||
|
|
||||||
describe "when visiting the page to customize a single theme" do
|
describe "when visiting the page to customize a single theme" do
|
||||||
|
|
|
@ -45,6 +45,10 @@ module PageObjects
|
||||||
has_css?(".inactive-theme input:checked", count: count)
|
has_css?(".inactive-theme input:checked", count: count)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def has_themes?(count:)
|
||||||
|
has_css?(".themes-list-container__item", count: count)
|
||||||
|
end
|
||||||
|
|
||||||
def toggle_all_inactive
|
def toggle_all_inactive
|
||||||
find(".toggle-all-inactive").click
|
find(".toggle-all-inactive").click
|
||||||
end
|
end
|
||||||
|
@ -67,6 +71,22 @@ module PageObjects
|
||||||
PageObjects::Components::AdminThemeSettingsEditor.new
|
PageObjects::Components::AdminThemeSettingsEditor.new
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def switch_to_components
|
||||||
|
find(".components-tab").click
|
||||||
|
end
|
||||||
|
|
||||||
|
def switch_to_themes
|
||||||
|
find(".themes-tab").click
|
||||||
|
end
|
||||||
|
|
||||||
|
def search(term)
|
||||||
|
find(".themes-list-search__input").fill_in with: term
|
||||||
|
end
|
||||||
|
|
||||||
|
def has_no_search?
|
||||||
|
has_no_css?(".themes-list-search__input")
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def setting_selector(setting_name, overridden: false)
|
def setting_selector(setting_name, overridden: false)
|
||||||
|
|
Loading…
Reference in New Issue