FIX: Include all categories in sortedCategories (#14979)

Fixes the issue where categories over two levels deep were missing.
This commit is contained in:
Jarek Radosz 2021-11-17 00:12:04 +01:00 committed by GitHub
parent 7e39910de6
commit bf33d2cd4b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 58 additions and 38 deletions

View File

@ -57,30 +57,21 @@ const Site = RestModel.extend({
// Sort subcategories under parents
@discourseComputed("categoriesByCount", "categories.[]")
sortedCategories(cats) {
const result = [],
remaining = {};
sortedCategories(categories) {
const children = new Map();
cats.forEach((c) => {
const parentCategoryId = parseInt(c.get("parent_category_id"), 10);
if (!parentCategoryId) {
result.pushObject(c);
} else {
remaining[parentCategoryId] = remaining[parentCategoryId] || [];
remaining[parentCategoryId].pushObject(c);
}
categories.forEach((category) => {
const parentId = parseInt(category.parent_category_id, 10) || -1;
const group = children.get(parentId) || [];
group.pushObject(category);
children.set(parentId, group);
});
Object.keys(remaining).forEach((parentCategoryId) => {
const category = result.findBy("id", parseInt(parentCategoryId, 10)),
index = result.indexOf(category);
const reduce = (values) =>
values.flatMap((c) => [c, reduce(children.get(c.id) || [])]).flat();
if (index !== -1) {
result.replace(index + 1, 0, remaining[parentCategoryId]);
}
});
return result;
return reduce(children.get(-1));
},
// Returns it in the correct order, by setting

View File

@ -29,45 +29,74 @@ module("Unit | Model | site", function () {
const store = createStore();
const site = store.createRecord("site", {
categories: [
{ id: 1234, name: "Test" },
{ id: 3456, name: "Test Subcategory", parent_category_id: 1234 },
{ id: 1234, name: "Test" },
{ id: 3458, name: "Invalid Subcategory", parent_category_id: 6666 },
],
});
const categories = site.get("categories");
site.get("sortedCategories");
assert.present(site.categories, "The categories are present");
assert.deepEqual(site.categories.mapBy("name"), [
"Test Subcategory",
"Test",
"Invalid Subcategory",
]);
assert.present(categories, "The categories are present");
assert.strictEqual(categories.length, 3, "it loaded all three categories");
assert.deepEqual(site.sortedCategories.mapBy("name"), [
"Test",
"Test Subcategory",
]);
const parent = categories.findBy("id", 1234);
const parent = site.categories.findBy("id", 1234);
assert.present(parent, "it loaded the parent category");
assert.blank(parent.get("parentCategory"), "it has no parent category");
assert.blank(parent.parentCategory, "it has no parent category");
assert.strictEqual(parent.get("subcategories").length, 1);
assert.strictEqual(parent.subcategories.length, 1);
const subcategory = categories.findBy("id", 3456);
const subcategory = site.categories.findBy("id", 3456);
assert.present(subcategory, "it loaded the subcategory");
assert.strictEqual(
subcategory.get("parentCategory"),
subcategory.parentCategory,
parent,
"it has associated the child with the parent"
);
// remove invalid category and child
categories.removeObject(categories[2]);
categories.removeObject(categories[1]);
site.categories.removeObject(site.categories[2]);
site.categories.removeObject(site.categories[0]);
assert.strictEqual(
categories.length,
site.get("categoriesByCount").length,
"categories by count should change on removal"
site.categoriesByCount.length,
site.categories.length,
"categoriesByCount should change on removal"
);
assert.strictEqual(
categories.length,
site.get("sortedCategories").length,
"sorted categories should change on removal"
site.sortedCategories.length,
site.categories.length,
"sortedCategories should change on removal"
);
});
test("deeply nested categories", function (assert) {
const store = createStore();
const site = store.createRecord("site", {
categories: [
{ id: 1003, name: "Test Sub Sub", parent_category_id: 1002 },
{ id: 1001, name: "Test" },
{ id: 1004, name: "Test Sub Sub Sub", parent_category_id: 1003 },
{ id: 1002, name: "Test Sub", parent_category_id: 1001 },
{ id: 1005, name: "Test Sub Sub Sub2", parent_category_id: 1003 },
{ id: 1006, name: "Test2" },
],
});
assert.deepEqual(site.sortedCategories.mapBy("name"), [
"Test",
"Test Sub",
"Test Sub Sub",
"Test Sub Sub Sub",
"Test Sub Sub Sub2",
"Test2",
]);
});
});