mirror of
https://github.com/discourse/discourse.git
synced 2025-02-24 02:44:00 +08:00
FIX: Limit displayed groups in <GroupChooser />
to 100 groups (#31288)
Follow-up to https://github.com/discourse/discourse/pull/31271 In the linked PR, we made `<GroupChooser />` use the site's preloaded list of groups instead of fetching the list from the servers every time the component is triggered. However, when a site has thousands of groups, the performance issue has shifted from the server to the browser — `<GroupChooser />` takes several seconds to render in the browser for a site with thousands of groups and the sites becomes completely unresponsive while the component is rendering. This PR changes the `<GroupChooser />` so it limits the displayed groups to 100, with ability to filter the list to show more groups when there are more than 100 groups.
This commit is contained in:
parent
cf6bab3d85
commit
d0498c9e1d
@ -0,0 +1,88 @@
|
||||
import { hash } from "@ember/helper";
|
||||
import { render } from "@ember/test-helpers";
|
||||
import { module, test } from "qunit";
|
||||
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
|
||||
import selectKit from "discourse/tests/helpers/select-kit-helper";
|
||||
import GroupChooser from "select-kit/components/group-chooser";
|
||||
|
||||
module("Integration | Component | select-kit/group-chooser", function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
hooks.beforeEach(function () {
|
||||
this.subject = selectKit();
|
||||
});
|
||||
|
||||
test("limiting the displayed groups", async function (assert) {
|
||||
const content = [
|
||||
{
|
||||
id: 1,
|
||||
name: "A",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "AB",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "ABC",
|
||||
},
|
||||
];
|
||||
await render(<template>
|
||||
<GroupChooser
|
||||
@content={{content}}
|
||||
@options={{hash displayedGroupsLimit=1}}
|
||||
/>
|
||||
</template>);
|
||||
|
||||
await this.subject.expand();
|
||||
|
||||
assert.strictEqual(
|
||||
this.subject.rows().length,
|
||||
1,
|
||||
"only 1 group is displayed"
|
||||
);
|
||||
assert.strictEqual(
|
||||
this.subject.rowByIndex(0).name(),
|
||||
"A",
|
||||
"the first group in the list is displayed"
|
||||
);
|
||||
|
||||
assert
|
||||
.dom(this.subject.el().querySelector(".filter-for-more"))
|
||||
.exists("has indicator that there are more groups");
|
||||
|
||||
await this.subject.fillInFilter("AB");
|
||||
|
||||
assert.strictEqual(
|
||||
this.subject.rows().length,
|
||||
1,
|
||||
"only 1 group is displayed"
|
||||
);
|
||||
assert.strictEqual(
|
||||
this.subject.rowByIndex(0).name(),
|
||||
"AB",
|
||||
"the first group that matches the filter in the list is displayed"
|
||||
);
|
||||
assert
|
||||
.dom(this.subject.el().querySelector(".filter-for-more"))
|
||||
.exists("has indicator that there are more groups matching the filter");
|
||||
|
||||
await this.subject.fillInFilter("C");
|
||||
|
||||
assert.strictEqual(
|
||||
this.subject.rows().length,
|
||||
1,
|
||||
"only 1 group is displayed"
|
||||
);
|
||||
assert.strictEqual(
|
||||
this.subject.rowByIndex(0).name(),
|
||||
"ABC",
|
||||
"the first group that matches the filter in the list is displayed"
|
||||
);
|
||||
assert
|
||||
.dom(this.subject.el().querySelector(".filter-for-more"))
|
||||
.doesNotExist(
|
||||
"doesn't have an indicator when there are no more matching elements"
|
||||
);
|
||||
});
|
||||
});
|
@ -1,13 +1,52 @@
|
||||
import { classNames } from "@ember-decorators/component";
|
||||
import FilterForMore from "select-kit/components/filter-for-more";
|
||||
import MultiSelectComponent from "select-kit/components/multi-select";
|
||||
import {
|
||||
MAIN_COLLECTION,
|
||||
pluginApiIdentifiers,
|
||||
selectKitOptions,
|
||||
} from "select-kit/components/select-kit";
|
||||
|
||||
const FILTER_FOR_MORE_GROUPS_COLLECTION = "MORE_GROUPS_COLLECTION";
|
||||
|
||||
@classNames("group-chooser")
|
||||
@selectKitOptions({
|
||||
allowAny: false,
|
||||
displayedGroupsLimit: 100,
|
||||
})
|
||||
@pluginApiIdentifiers("group-chooser")
|
||||
export default class GroupChooser extends MultiSelectComponent {}
|
||||
export default class GroupChooser extends MultiSelectComponent {
|
||||
init() {
|
||||
super.init(...arguments);
|
||||
|
||||
this.insertAfterCollection(
|
||||
MAIN_COLLECTION,
|
||||
FILTER_FOR_MORE_GROUPS_COLLECTION
|
||||
);
|
||||
}
|
||||
|
||||
modifyComponentForCollection(identifier) {
|
||||
if (identifier === FILTER_FOR_MORE_GROUPS_COLLECTION) {
|
||||
return FilterForMore;
|
||||
}
|
||||
}
|
||||
|
||||
modifyContent(content) {
|
||||
const limit = this.selectKit.options.displayedGroupsLimit;
|
||||
if (content.length > limit) {
|
||||
this.showFilterForMore = true;
|
||||
content = content.slice(0, limit);
|
||||
} else {
|
||||
this.showFilterForMore = false;
|
||||
}
|
||||
return content;
|
||||
}
|
||||
|
||||
modifyContentForCollection(identifier) {
|
||||
if (identifier === FILTER_FOR_MORE_GROUPS_COLLECTION) {
|
||||
return {
|
||||
shouldShowMoreTip: this.showFilterForMore,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user