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:
Sam 2023-05-16 18:23:05 +10:00 committed by GitHub
parent b596e54a39
commit e63e193a0a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 111 additions and 32 deletions

View File

@ -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);
}
}
}

View File

@ -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}}

View File

@ -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");
});
});

View File

@ -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"