fix(guides) : make ordering predictable
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
WITH ranked_guides AS (
|
||||
SELECT "id", (row_number() OVER (ORDER BY "created_at", "id") * 10)::integer AS "sort_order"
|
||||
FROM "guides"."guide"
|
||||
)
|
||||
UPDATE "guides"."guide" AS "guide"
|
||||
SET "sort_order" = ranked_guides."sort_order"
|
||||
FROM ranked_guides
|
||||
WHERE "guide"."id" = ranked_guides."id";
|
||||
@@ -281,6 +281,13 @@
|
||||
"when": 1788794054894,
|
||||
"tag": "0039_flowery_smiling_tiger",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 40,
|
||||
"version": "7",
|
||||
"when": 1788915600000,
|
||||
"tag": "0040_ordered_guides",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,12 +77,17 @@ export async function createGuide(input: unknown) {
|
||||
const slug = slugCollision ? `${baseSlug}-${character.key.toLowerCase()}` : baseSlug;
|
||||
|
||||
return db.transaction(async (tx) => {
|
||||
await tx.execute(sql`select pg_advisory_xact_lock(hashtext('guides-sort-order'))`);
|
||||
const [order] = await tx
|
||||
.select({ maximum: sql<number>`coalesce(max(${guides.sortOrder}), 0)` })
|
||||
.from(guides);
|
||||
const [guide] = await tx.insert(guides).values({
|
||||
characterKey: character.key,
|
||||
slug,
|
||||
name: character.name,
|
||||
overview: parsed.overview,
|
||||
coverMediaId: parsed.coverMediaId,
|
||||
sortOrder: order.maximum + 10,
|
||||
}).returning();
|
||||
await tx.insert(guideSections).values(DEFAULT_SECTIONS.map((section) => ({ ...section, guideId: guide.id })));
|
||||
await tx.insert(artifactGroups).values([
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import "server-only";
|
||||
|
||||
import { and, asc, eq, inArray, isNotNull, isNull, ne } from "drizzle-orm";
|
||||
import { and, asc, desc, eq, inArray, isNotNull, isNull, ne } from "drizzle-orm";
|
||||
import * as z from "zod";
|
||||
|
||||
import { getDb } from "@/db";
|
||||
@@ -127,7 +127,7 @@ export async function listGuideCards(includeTrash = false) {
|
||||
.from(guides)
|
||||
.innerJoin(media, eq(media.id, guides.coverMediaId))
|
||||
.where(includeTrash ? isNotNull(guides.trashedAt) : isNull(guides.trashedAt))
|
||||
.orderBy(asc(guides.sortOrder), asc(guides.name));
|
||||
.orderBy(desc(guides.sortOrder), desc(guides.createdAt), asc(guides.name));
|
||||
return rows.map(({ coverObjectKey, ...guide }) => ({
|
||||
...guide,
|
||||
coverUrl: publicMediaUrl(coverObjectKey),
|
||||
@@ -146,7 +146,7 @@ export async function listAdminTeamImportGuides(excludeGuideId: string) {
|
||||
.from(guides)
|
||||
.innerJoin(media, eq(media.id, guides.coverMediaId))
|
||||
.where(and(isNull(guides.trashedAt), ne(guides.id, excludeGuideId)))
|
||||
.orderBy(asc(guides.sortOrder), asc(guides.name));
|
||||
.orderBy(desc(guides.sortOrder), desc(guides.createdAt), asc(guides.name));
|
||||
|
||||
return rows.map(({ coverObjectKey, ...guide }) => ({
|
||||
...guide,
|
||||
@@ -221,7 +221,7 @@ export async function listPublicGuideCards() {
|
||||
.from(guides)
|
||||
.innerJoin(media, eq(media.id, guides.coverMediaId))
|
||||
.where(and(eq(guides.isPublic, true), isNull(guides.trashedAt)))
|
||||
.orderBy(asc(guides.sortOrder), asc(guides.name)), getDb().select().from(glossaryAliases)]);
|
||||
.orderBy(desc(guides.sortOrder), desc(guides.createdAt), asc(guides.name)), getDb().select().from(glossaryAliases)]);
|
||||
const grouped = aliasesByItem(aliases);
|
||||
return rows.map(({ coverObjectKey, ...guide }) => ({
|
||||
...guide,
|
||||
|
||||
Reference in New Issue
Block a user