Fix Visual Manager empty categories: seed roots, harden tree API.
Local Build and Deploy / deploy (push) Successful in 56s
Local Build and Deploy / deploy (push) Successful in 56s
Seed root tabs from SSR, load the full tree without CLEAR_TREE races, coerce parent ids, and tolerate catalog_items page_id type mismatches so category pages actually appear. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
1 parent
385cefd0fa
commit
1d8efefce4
6 files changed
+285
-187
No files matched your search
@@ -6,6 +6,8 @@ import {
|
||||
deletePage,
|
||||
getAncestors,
|
||||
getTreeFlat,
|
||||
safeItemCounts,
|
||||
toInt,
|
||||
} from "@/lib/services/catalog-tree";
|
||||
import { rcon } from "@/lib/services/rcon";
|
||||
import type { TreeNode } from "@/types/catalog";
|
||||
@@ -87,8 +89,9 @@ async function getChildren(
|
||||
parentId: number,
|
||||
isBc: boolean,
|
||||
): Promise<TreeNode[]> {
|
||||
// Roots in Habbo DBs are usually parent_id = -1, sometimes 0.
|
||||
const parentFilter =
|
||||
parentId === -1
|
||||
parentId <= 0
|
||||
? { OR: [{ parentId: -1 }, { parentId: 0 }] }
|
||||
: { parentId };
|
||||
|
||||
@@ -97,7 +100,7 @@ async function getChildren(
|
||||
where: parentFilter,
|
||||
orderBy: { orderNum: "asc" },
|
||||
});
|
||||
const ids = pages.map((p) => p.id);
|
||||
const ids = pages.map((p) => toInt(p.id));
|
||||
const [childCounts, itemCounts] = await Promise.all([
|
||||
ids.length
|
||||
? prisma.catalogPagesBc.groupBy({
|
||||
@@ -105,56 +108,79 @@ async function getChildren(
|
||||
where: { parentId: { in: ids } },
|
||||
_count: true,
|
||||
})
|
||||
: [],
|
||||
: Promise.resolve([]),
|
||||
ids.length
|
||||
? prisma.catalogItemsBc.groupBy({
|
||||
by: ["pageId"],
|
||||
where: { pageId: { in: ids } },
|
||||
_count: true,
|
||||
})
|
||||
: [],
|
||||
? prisma.catalogItemsBc
|
||||
.groupBy({
|
||||
by: ["pageId"],
|
||||
where: { pageId: { in: ids } },
|
||||
_count: true,
|
||||
})
|
||||
.catch(() => [])
|
||||
: Promise.resolve([]),
|
||||
]);
|
||||
const childMap = Object.fromEntries(
|
||||
childCounts.map((c) => [c.parentId, c._count]),
|
||||
childCounts.map((c) => [toInt(c.parentId), c._count]),
|
||||
);
|
||||
const itemMap = Object.fromEntries(
|
||||
itemCounts.map((c) => [c.pageId, c._count]),
|
||||
);
|
||||
return pages.map((p) =>
|
||||
toTreeNode(p, childMap[p.id] ?? 0, itemMap[p.id] ?? 0),
|
||||
itemCounts.map((c) => [toInt(c.pageId), c._count]),
|
||||
);
|
||||
return pages.map((p) => {
|
||||
const id = toInt(p.id);
|
||||
return toTreeNode(
|
||||
{
|
||||
id,
|
||||
caption: p.caption,
|
||||
parentId: toInt(p.parentId, -1),
|
||||
orderNum: toInt(p.orderNum),
|
||||
enabled: String(p.enabled ?? "0"),
|
||||
visible: String(p.visible ?? "0"),
|
||||
iconImage: toInt(p.iconImage),
|
||||
iconColor: toInt(p.iconColor),
|
||||
pageLayout: p.pageLayout,
|
||||
},
|
||||
childMap[id] ?? 0,
|
||||
itemMap[id] ?? 0,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
const pages = await prisma.catalogPages.findMany({
|
||||
where: parentFilter,
|
||||
orderBy: { orderNum: "asc" },
|
||||
});
|
||||
const ids = pages.map((p) => p.id);
|
||||
const [childCounts, itemCounts] = await Promise.all([
|
||||
const ids = pages.map((p) => toInt(p.id));
|
||||
const [childCounts, itemMap] = await Promise.all([
|
||||
ids.length
|
||||
? prisma.catalogPages.groupBy({
|
||||
by: ["parentId"],
|
||||
where: { parentId: { in: ids } },
|
||||
_count: true,
|
||||
})
|
||||
: [],
|
||||
ids.length
|
||||
? prisma.catalogItems.groupBy({
|
||||
by: ["pageId"],
|
||||
where: { pageId: { in: ids } },
|
||||
_count: true,
|
||||
})
|
||||
: [],
|
||||
: Promise.resolve([]),
|
||||
safeItemCounts(ids),
|
||||
]);
|
||||
const childMap = Object.fromEntries(
|
||||
childCounts.map((c) => [c.parentId, c._count]),
|
||||
);
|
||||
const itemMap = Object.fromEntries(
|
||||
itemCounts.map((c) => [c.pageId, c._count]),
|
||||
);
|
||||
return pages.map((p) =>
|
||||
toTreeNode(p, childMap[p.id] ?? 0, itemMap[p.id] ?? 0),
|
||||
childCounts.map((c) => [toInt(c.parentId), c._count]),
|
||||
);
|
||||
return pages.map((p) => {
|
||||
const id = toInt(p.id);
|
||||
return toTreeNode(
|
||||
{
|
||||
id,
|
||||
caption: p.caption,
|
||||
parentId: toInt(p.parentId, -1),
|
||||
orderNum: toInt(p.orderNum),
|
||||
enabled: String(p.enabled ?? "0"),
|
||||
visible: String(p.visible ?? "0"),
|
||||
iconImage: toInt(p.iconImage),
|
||||
iconColor: toInt(p.iconColor),
|
||||
pageLayout: p.pageLayout,
|
||||
},
|
||||
childMap[id] ?? 0,
|
||||
itemMap.get(id) ?? 0,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
async function searchPages(q: string, isBc: boolean): Promise<TreeNode[]> {
|
||||
|
||||
Reference in new issue
Block a user