👁️
5
fork

Configure Feed

Select the types of activity you want to include in your feed.

sort tags before types

+56 -13
+1 -1
src/components/deck/DeckSection.tsx
··· 65 65 }, [cards, cardMap, groupBy]); 66 66 67 67 const sortedGroupNames = useMemo( 68 - () => sortGroupNames(Array.from(groupedCards.keys()), groupBy), 68 + () => sortGroupNames(groupedCards, groupBy), 69 69 [groupedCards, groupBy], 70 70 ); 71 71
+30 -10
src/lib/deck-grouping.test.ts
··· 338 338 }); 339 339 340 340 describe("sortGroupNames", () => { 341 + // Helper to create a mock groups map from names 342 + const mockGroups = ( 343 + names: string[], 344 + forTag = false, 345 + ): Map<string, { cards: DeckCard[]; forTag: boolean }> => { 346 + return new Map(names.map((name) => [name, { cards: [], forTag }])); 347 + }; 348 + 341 349 it("sorts manaValue groups numerically", () => { 342 - const names = ["7+", "3", "0", "1", "5"]; 343 - const sorted = sortGroupNames(names, "manaValue"); 350 + const groups = mockGroups(["7+", "3", "0", "1", "5"]); 351 + const sorted = sortGroupNames(groups, "manaValue"); 344 352 expect(sorted).toEqual(["0", "1", "3", "5", "7+"]); 345 353 }); 346 354 347 355 it("sorts colorIdentity groups by WUBRG order", () => { 348 - const names = ["G", "Colorless", "WU", "R", "B"]; 349 - const sorted = sortGroupNames(names, "colorIdentity"); 356 + const groups = mockGroups(["G", "Colorless", "WU", "R", "B"]); 357 + const sorted = sortGroupNames(groups, "colorIdentity"); 350 358 expect(sorted).toEqual(["Colorless", "B", "R", "G", "WU"]); 351 359 }); 352 360 353 361 it("sorts colorIdentity multi-color by length then color", () => { 354 - const names = ["WUB", "WU", "UB", "W"]; 355 - const sorted = sortGroupNames(names, "colorIdentity"); 362 + const groups = mockGroups(["WUB", "WU", "UB", "W"]); 363 + const sorted = sortGroupNames(groups, "colorIdentity"); 356 364 expect(sorted).toEqual(["W", "WU", "UB", "WUB"]); 357 365 }); 358 366 359 367 it("sorts special groups to end", () => { 360 - const names = ["Zombie", "(No Tags)", "Human", "(No Subtype)"]; 361 - const sorted = sortGroupNames(names, "subtype"); 368 + const groups = mockGroups(["Zombie", "(No Tags)", "Human", "(No Subtype)"]); 369 + const sorted = sortGroupNames(groups, "subtype"); 362 370 // Special groups (starting with parentheses) come last, sorted alphabetically among themselves 363 371 expect(sorted).toEqual(["Human", "Zombie", "(No Subtype)", "(No Tags)"]); 364 372 }); 365 373 366 374 it("sorts alphabetically for type/tag/subtype", () => { 367 - const names = ["Zombie", "Human", "Wizard"]; 368 - const sorted = sortGroupNames(names, "type"); 375 + const groups = mockGroups(["Zombie", "Human", "Wizard"]); 376 + const sorted = sortGroupNames(groups, "type"); 369 377 expect(sorted).toEqual(["Human", "Wizard", "Zombie"]); 378 + }); 379 + 380 + it("sorts tags before types in typeAndTags mode", () => { 381 + const groups = new Map<string, { cards: DeckCard[]; forTag: boolean }>([ 382 + ["aggro", { cards: [], forTag: true }], 383 + ["Instant", { cards: [], forTag: false }], 384 + ["removal", { cards: [], forTag: true }], 385 + ["Creature", { cards: [], forTag: false }], 386 + ]); 387 + const sorted = sortGroupNames(groups, "typeAndTags"); 388 + // Tags (aggro, removal) come before types (Creature, Instant) 389 + expect(sorted).toEqual(["aggro", "removal", "Creature", "Instant"]); 370 390 }); 371 391 });
+25 -2
src/lib/deck-grouping.ts
··· 318 318 * Sort group names for consistent display order 319 319 */ 320 320 export function sortGroupNames( 321 - groupNames: string[], 321 + groups: Map<string, { cards: DeckCard[]; forTag: boolean }>, 322 322 groupBy: GroupBy, 323 323 ): string[] { 324 + const groupNames = Array.from(groups.keys()); 325 + 324 326 switch (groupBy) { 325 327 case "manaValue": { 326 328 // Sort numerically: 0, 1, 2, ..., 7+ ··· 348 350 }); 349 351 } 350 352 353 + case "typeAndTags": { 354 + // Sort tags before types, then alphabetically within each category 355 + return groupNames.sort((a, b) => { 356 + const aIsSpecial = a.startsWith("("); 357 + const bIsSpecial = b.startsWith("("); 358 + const aIsTag = groups.get(a)?.forTag ?? false; 359 + const bIsTag = groups.get(b)?.forTag ?? false; 360 + 361 + // Put special groups at the end 362 + if (aIsSpecial && !bIsSpecial) return 1; 363 + if (!aIsSpecial && bIsSpecial) return -1; 364 + 365 + // Tags before types 366 + if (aIsTag && !bIsTag) return -1; 367 + if (!aIsTag && bIsTag) return 1; 368 + 369 + // Both tags, both types, or both special: sort alphabetically 370 + return a.localeCompare(b); 371 + }); 372 + } 373 + 351 374 default: 352 - // Alphabetical for tag, type, subtype, etc 375 + // Alphabetical for type, subtype, etc 353 376 return groupNames.sort((a, b) => { 354 377 const aIsSpecial = a.startsWith("("); 355 378 const bIsSpecial = b.startsWith("(");