From 378a256f5b6ae67a2fa982c65f2fb922a593622a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antti=20M=C3=A4ki?= Date: Fri, 3 Nov 2023 12:12:09 +0200 Subject: [PATCH 1/2] @thunderstore/dapper: use unique ids in category and section objects While PackageCategory and PackageListingSection slugs are unique in a community scope, they're not globally unique. To ensure more robust behaviour, use the unique database ids internally. Refs TS-1890 --- .../components/PackageCard.stories.tsx | 4 +- packages/dapper-fake/src/fakers/utils.ts | 49 ++++++++++++------- .../dapper-ts/src/methods/communityFilters.ts | 2 + packages/dapper/src/types/community.ts | 1 + packages/dapper/src/types/package.ts | 6 +-- packages/dapper/src/types/shared.ts | 1 + 6 files changed, 40 insertions(+), 23 deletions(-) diff --git a/apps/cyberstorm-storybook/stories/components/PackageCard.stories.tsx b/apps/cyberstorm-storybook/stories/components/PackageCard.stories.tsx index 5860dce39..e7387285b 100644 --- a/apps/cyberstorm-storybook/stories/components/PackageCard.stories.tsx +++ b/apps/cyberstorm-storybook/stories/components/PackageCard.stories.tsx @@ -51,8 +51,8 @@ ReferencePackageCard.args = { isNsfw: false, isDeprecated: false, categories: [ - { name: "Misc", slug: "misc" }, - { name: "Mods", slug: "mods" }, + { id: 1, name: "Misc", slug: "misc" }, + { id: 2, name: "Mods", slug: "mods" }, ], }, }; diff --git a/packages/dapper-fake/src/fakers/utils.ts b/packages/dapper-fake/src/fakers/utils.ts index 1e9252a00..524333985 100644 --- a/packages/dapper-fake/src/fakers/utils.ts +++ b/packages/dapper-fake/src/fakers/utils.ts @@ -10,17 +10,17 @@ export const getFakeLink = () => ({ export const getFakePackageCategories = (returnAmount?: number) => { const categories = [ - { name: "Mods", slug: "mods" }, - { name: "Tools", slug: "tools" }, - { name: "Libraries", slug: "libraries" }, - { name: "Modpacks", slug: "modpacks" }, - { name: "Skins", slug: "skins" }, - { name: "Maps", slug: "maps" }, - { name: "Tweaks", slug: "tweaks" }, - { name: "Items", slug: "items" }, - { name: "Language", slug: "language" }, - { name: "Audio", slug: "audio" }, - { name: "Enemies", slug: "enemies" }, + { id: 1, name: "Mods", slug: "mods" }, + { id: 2, name: "Tools", slug: "tools" }, + { id: 3, name: "Libraries", slug: "libraries" }, + { id: 4, name: "Modpacks", slug: "modpacks" }, + { id: 5, name: "Skins", slug: "skins" }, + { id: 6, name: "Maps", slug: "maps" }, + { id: 7, name: "Tweaks", slug: "tweaks" }, + { id: 8, name: "Items", slug: "items" }, + { id: 9, name: "Language", slug: "language" }, + { id: 10, name: "Audio", slug: "audio" }, + { id: 11, name: "Enemies", slug: "enemies" }, ]; return faker.helpers.arrayElements(categories, { @@ -31,12 +31,27 @@ export const getFakePackageCategories = (returnAmount?: number) => { export const getFakeSections = (returnAmount?: number) => { const categories = [ - { name: "Mods", slug: "mods", priority: 0 }, - { name: "Modpacks", slug: "modpacks", priority: 1 }, - { name: "Maps", slug: "maps", priority: 2 }, - { name: "Custom cards", slug: "cards", priority: 3 }, - { name: "Latest update", slug: "update", priority: 4 }, - { name: "Paid DLC", slug: "dlc", priority: 5 }, + { uuid: faker.string.uuid(), name: "Mods", slug: "mods", priority: 0 }, + { + uuid: faker.string.uuid(), + name: "Modpacks", + slug: "modpacks", + priority: 1, + }, + { uuid: faker.string.uuid(), name: "Maps", slug: "maps", priority: 2 }, + { + uuid: faker.string.uuid(), + name: "Custom cards", + slug: "cards", + priority: 3, + }, + { + uuid: faker.string.uuid(), + name: "Latest update", + slug: "update", + priority: 4, + }, + { uuid: faker.string.uuid(), name: "Paid DLC", slug: "dlc", priority: 5 }, ]; return faker.helpers.arrayElements(categories, { diff --git a/packages/dapper-ts/src/methods/communityFilters.ts b/packages/dapper-ts/src/methods/communityFilters.ts index cd5479387..3d8882b2f 100644 --- a/packages/dapper-ts/src/methods/communityFilters.ts +++ b/packages/dapper-ts/src/methods/communityFilters.ts @@ -4,11 +4,13 @@ import { fetchCommunityFilters } from "@thunderstore/thunderstore-api"; import { DapperTsInterface } from "../index"; const PackageCategory = z.object({ + id: z.number().nonnegative(), name: z.string().nonempty(), slug: z.string().nonempty(), }); const Section = z.object({ + uuid: z.string().uuid(), name: z.string().nonempty(), slug: z.string().nonempty(), priority: z.number().int(), diff --git a/packages/dapper/src/types/community.ts b/packages/dapper/src/types/community.ts index 7e01780c6..e9555560a 100644 --- a/packages/dapper/src/types/community.ts +++ b/packages/dapper/src/types/community.ts @@ -15,6 +15,7 @@ export interface Community { export type Communities = PaginatedList; export interface Section { + uuid: string; name: string; slug: string; priority: number; diff --git a/packages/dapper/src/types/package.ts b/packages/dapper/src/types/package.ts index c1b2d7a94..6e6ebc7ee 100644 --- a/packages/dapper/src/types/package.ts +++ b/packages/dapper/src/types/package.ts @@ -1,3 +1,4 @@ +import { PackageCategory } from "./shared"; import { TeamMember } from "./team"; export interface PackagePreview { @@ -14,10 +15,7 @@ export interface PackagePreview { isPinned?: boolean; isNsfw?: boolean; isDeprecated?: boolean; - categories: { - name: string; - slug: string; - }[]; + categories: PackageCategory[]; } export interface Package extends PackagePreview { diff --git a/packages/dapper/src/types/shared.ts b/packages/dapper/src/types/shared.ts index 46ec33f1b..27d1af2d7 100644 --- a/packages/dapper/src/types/shared.ts +++ b/packages/dapper/src/types/shared.ts @@ -4,6 +4,7 @@ export type DynamicLink = { }; export interface PackageCategory { + id: number; name: string; slug: string; } From 084ef276173d8fb41931da920cd962b66831ba1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antti=20M=C3=A4ki?= Date: Fri, 3 Nov 2023 12:35:36 +0200 Subject: [PATCH 2/2] @thunderstore/cyberstorm: use unique category/section ids in filters When filtering a package list, the ids of categories and uuids of sections should be sent to backend, instead of the slugs, which are guaranteed to be unique only within a scope of each community. Refs TS-1890 --- .../PackageSearch/CategoryTagCloud/CategoryTagCloud.tsx | 6 +++--- .../PackageSearch/FilterMenus/CategoryMenu.tsx | 9 ++++----- .../components/PackageSearch/FilterMenus/SectionMenu.tsx | 6 +++--- .../src/components/PackageSearch/PackageSearch.tsx | 2 +- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/packages/cyberstorm/src/components/PackageSearch/CategoryTagCloud/CategoryTagCloud.tsx b/packages/cyberstorm/src/components/PackageSearch/CategoryTagCloud/CategoryTagCloud.tsx index ab7f5f975..8f3f5e14e 100644 --- a/packages/cyberstorm/src/components/PackageSearch/CategoryTagCloud/CategoryTagCloud.tsx +++ b/packages/cyberstorm/src/components/PackageSearch/CategoryTagCloud/CategoryTagCloud.tsx @@ -24,9 +24,9 @@ export const CategoryTagCloud = (props: Props) => { return null; } - const clearCategory = (slug: string) => + const clearCategory = (id: number) => setCategories( - categories.map((c) => (c.slug === slug ? { ...c, selection: OFF } : c)) + categories.map((c) => (c.id === id ? { ...c, selection: OFF } : c)) ); const clearAll = () => @@ -37,7 +37,7 @@ export const CategoryTagCloud = (props: Props) => { {visible.map((c) => ( clearCategory(c.slug)} + onClick={() => clearCategory(c.id)} colorScheme={c.selection === "exclude" ? "danger" : "default"} paddingSize="small" style={{ gap: "0.5rem" }} diff --git a/packages/cyberstorm/src/components/PackageSearch/FilterMenus/CategoryMenu.tsx b/packages/cyberstorm/src/components/PackageSearch/FilterMenus/CategoryMenu.tsx index 5bbf3d5e2..e47847d53 100644 --- a/packages/cyberstorm/src/components/PackageSearch/FilterMenus/CategoryMenu.tsx +++ b/packages/cyberstorm/src/components/PackageSearch/FilterMenus/CategoryMenu.tsx @@ -21,8 +21,7 @@ interface Props { export const CategoryMenu = (props: Props) => { const { categories, setCategories } = props; - const toggleCategory = (slug: string) => - setCategories(toggle(categories, slug)); + const toggleCategory = (id: number) => setCategories(toggle(categories, id)); return (
@@ -35,7 +34,7 @@ export const CategoryMenu = (props: Props) => {