FEATURE: Fuzzy search in site settings and raise limit to 100 matches (#21572)
We have been struggling lately finding site settings due to 30 setting limit This was introduced for performance reasons a while back but is no longer as needed given that ember is faster. Additionally searching is hard, so allow people to use fuzzy search against setting name.
This commit is contained in:
parent
b596e54a39
commit
e63e193a0a
|
@ -15,15 +15,15 @@ export default class AdminSiteSettingsController extends Controller {
|
|||
visibleSiteSettings = null;
|
||||
onlyOverridden = false;
|
||||
|
||||
filterContentNow(category) {
|
||||
// If we have no content, don't bother filtering anything
|
||||
if (isEmpty(this.allSiteSettings)) {
|
||||
return;
|
||||
}
|
||||
get maxResults() {
|
||||
return 100;
|
||||
}
|
||||
|
||||
let filter, pluginFilter;
|
||||
if (this.filter) {
|
||||
filter = this.filter
|
||||
performSearch(filter, allSiteSettings, onlyOverridden) {
|
||||
let pluginFilter;
|
||||
|
||||
if (filter) {
|
||||
filter = filter
|
||||
.toLowerCase()
|
||||
.split(" ")
|
||||
.filter((word) => {
|
||||
|
@ -42,29 +42,27 @@ export default class AdminSiteSettingsController extends Controller {
|
|||
.trim();
|
||||
}
|
||||
|
||||
if (
|
||||
(!filter || 0 === filter.length) &&
|
||||
(!pluginFilter || 0 === pluginFilter.length) &&
|
||||
!this.onlyOverridden
|
||||
) {
|
||||
this.set("visibleSiteSettings", this.allSiteSettings);
|
||||
if (this.categoryNameKey === "all_results") {
|
||||
this.transitionToRoute("adminSiteSettings");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const all = {
|
||||
nameKey: "all_results",
|
||||
name: I18n.t("admin.site_settings.categories.all_results"),
|
||||
siteSettings: [],
|
||||
};
|
||||
const matchesGroupedByCategory = [all];
|
||||
|
||||
const matchesGroupedByCategory = [all];
|
||||
const matches = [];
|
||||
this.allSiteSettings.forEach((settingsCategory) => {
|
||||
|
||||
const strippedQuery = filter.replace(/[^a-z0-9]/gi, "");
|
||||
let fuzzyRegex;
|
||||
|
||||
if (strippedQuery.length > 2) {
|
||||
fuzzyRegex = new RegExp(strippedQuery.split("").join(".*"), "i");
|
||||
}
|
||||
|
||||
allSiteSettings.forEach((settingsCategory) => {
|
||||
let fuzzyMatches = [];
|
||||
|
||||
const siteSettings = settingsCategory.siteSettings.filter((item) => {
|
||||
if (this.onlyOverridden && !item.get("overridden")) {
|
||||
if (onlyOverridden && !item.get("overridden")) {
|
||||
return false;
|
||||
}
|
||||
if (pluginFilter && item.plugin !== pluginFilter) {
|
||||
|
@ -72,16 +70,24 @@ export default class AdminSiteSettingsController extends Controller {
|
|||
}
|
||||
if (filter) {
|
||||
const setting = item.get("setting").toLowerCase();
|
||||
return (
|
||||
let filterResult =
|
||||
setting.includes(filter) ||
|
||||
setting.replace(/_/g, " ").includes(filter) ||
|
||||
item.get("description").toLowerCase().includes(filter) ||
|
||||
(item.get("value") || "").toString().toLowerCase().includes(filter)
|
||||
);
|
||||
(item.get("value") || "").toString().toLowerCase().includes(filter);
|
||||
if (!filterResult && fuzzyRegex && fuzzyRegex.test(setting)) {
|
||||
fuzzyMatches.push(item);
|
||||
}
|
||||
return filterResult;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
if (fuzzyMatches.length > 0) {
|
||||
siteSettings.pushObjects(fuzzyMatches);
|
||||
}
|
||||
|
||||
if (siteSettings.length > 0) {
|
||||
matches.pushObjects(siteSettings);
|
||||
matchesGroupedByCategory.pushObject({
|
||||
|
@ -95,14 +101,38 @@ export default class AdminSiteSettingsController extends Controller {
|
|||
}
|
||||
});
|
||||
|
||||
all.siteSettings.pushObjects(matches.slice(0, 30));
|
||||
all.hasMore = matches.length > 30;
|
||||
all.count = all.hasMore ? "30+" : matches.length;
|
||||
all.siteSettings.pushObjects(matches.slice(0, this.maxResults));
|
||||
all.hasMore = matches.length > this.maxResults;
|
||||
all.count = all.hasMore ? `${this.maxResults}+` : matches.length;
|
||||
all.maxResults = this.maxResults;
|
||||
|
||||
return matchesGroupedByCategory;
|
||||
}
|
||||
|
||||
filterContentNow(category) {
|
||||
if (isEmpty(this.allSiteSettings)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isEmpty(this.filter) && !this.onlyOverridden) {
|
||||
this.set("visibleSiteSettings", this.allSiteSettings);
|
||||
if (this.categoryNameKey === "all_results") {
|
||||
this.transitionToRoute("adminSiteSettings");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const matchesGroupedByCategory = this.performSearch(
|
||||
this.filter,
|
||||
this.allSiteSettings,
|
||||
this.onlyOverridden
|
||||
);
|
||||
|
||||
const categoryMatches = matchesGroupedByCategory.findBy(
|
||||
"nameKey",
|
||||
category
|
||||
);
|
||||
|
||||
if (!categoryMatches || categoryMatches.count === 0) {
|
||||
category = "all_results";
|
||||
}
|
||||
|
@ -124,7 +154,9 @@ export default class AdminSiteSettingsController extends Controller {
|
|||
if (this._skipBounce) {
|
||||
this.set("_skipBounce", false);
|
||||
} else {
|
||||
this.filterContentNow(this.categoryNameKey);
|
||||
if (!this.isDestroyed) {
|
||||
this.filterContentNow(this.categoryNameKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,10 @@
|
|||
/>
|
||||
{{/each}}
|
||||
{{#if this.category.hasMore}}
|
||||
<p class="warning">{{i18n "admin.site_settings.more_than_30_results"}}</p>
|
||||
<p class="warning">{{i18n
|
||||
"admin.site_settings.more_site_setting_results"
|
||||
count=this.category.maxResults
|
||||
}}</p>
|
||||
{{/if}}
|
||||
</DSection>
|
||||
{{else}}
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
import { module, test } from "qunit";
|
||||
import { setupTest } from "ember-qunit";
|
||||
import SiteSetting from "admin/models/site-setting";
|
||||
|
||||
module("Unit | Controller | admin-site-settings", function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test("can perform fuzzy search", async function (assert) {
|
||||
const controller = this.owner.lookup("controller:admin-site-settings");
|
||||
const settings = await SiteSetting.findAll();
|
||||
|
||||
let results = controller.performSearch("top_menu", settings);
|
||||
assert.deepEqual(results[0].siteSettings.length, 1);
|
||||
|
||||
results = controller.performSearch("tmenu", settings);
|
||||
assert.deepEqual(results[0].siteSettings.length, 1);
|
||||
|
||||
const settings2 = [
|
||||
{
|
||||
name: "Required",
|
||||
nameKey: "required",
|
||||
siteSettings: [
|
||||
SiteSetting.create({
|
||||
description: "",
|
||||
value: "",
|
||||
setting: "hpello world",
|
||||
}),
|
||||
SiteSetting.create({
|
||||
description: "",
|
||||
value: "",
|
||||
setting: "hello world",
|
||||
}),
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
results = controller.performSearch("hello world", settings2);
|
||||
assert.deepEqual(results[0].siteSettings.length, 2);
|
||||
// ensures hello world shows up before fuzzy hpello world
|
||||
assert.deepEqual(results[0].siteSettings[0].setting, "hello world");
|
||||
});
|
||||
});
|
|
@ -6056,7 +6056,9 @@ en:
|
|||
label: "Add Emoji"
|
||||
title: "Settings"
|
||||
no_results: "No results found."
|
||||
more_than_30_results: "There are more than 30 results. Please refine your search or select a category."
|
||||
more_site_setting_results:
|
||||
one: "There is more than %{count} result. Please refine your search or select a category."
|
||||
other: "There are more than %{count} results. Please refine your search or select a category."
|
||||
clear_filter: "Clear"
|
||||
add_url: "add URL"
|
||||
add_host: "add host"
|
||||
|
|
Loading…
Reference in New Issue