Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 15 additions & 5 deletions src/components/sponsors/reports/ByItemView.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,20 @@ export const groupLinesBySponsorItem = (rows = []) => {
purchasedCount: items.filter((it) => it.qty > 0).length
};
});
groups.sort(
(a, b) =>
b.totalQty - a.totalQty || a.sponsorName.localeCompare(b.sponsorName)
);
// Nothing sorts the sponsor accordions explicitly (the column headers reorder
// items WITHIN a group), so they default to alphabetical, unknown bucket last.
// That test keys on the NAME, not sponsorId, because the card title renders as
// `sponsorName || "Unknown sponsor"` — sorting on what the card displays keeps
// every "Unknown sponsor" card together at the end. (The pivot tree keys on
// the id instead, which splits them: a blank-named sponsor shows the unknown
// label but sorts first.) This also decides which sponsors land on which
// client-side page.
groups.sort((a, b) => {
if (!a.sponsorName !== !b.sponsorName) return a.sponsorName ? -1 : 1;
return a.sponsorName
.toLowerCase()
.localeCompare(b.sponsorName.toLowerCase());
});
Comment thread
caseylocker marked this conversation as resolved.
return groups;
};

Expand Down Expand Up @@ -639,7 +649,7 @@ const ByItemView = ({
>
<ItemTable
// Sorting reorders items WITHIN each sponsor; the sponsor
// accordions keep their own fixed totalQty order.
// accordions stay alphabetical.
items={sortItems(group.items, order, orderDir)}
keyFor={(item) => itemKey(group, item)}
expandedItems={expandedItems}
Expand Down
22 changes: 19 additions & 3 deletions src/components/sponsors/reports/__tests__/ByItemView.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ describe("groupLinesBySponsorItem", () => {
expect(group.items.find((i) => i.itemCode === "B").totalCents).toBe(100);
});

it("sorts items qty desc then orders desc, sponsors by totalQty desc", () => {
it("sorts items qty desc then orders desc", () => {
const rows = [
line({ sponsor: { id: 1, name: "Small" }, item_code: "A", quantity: 1 }),
line({
Expand All @@ -124,9 +124,25 @@ describe("groupLinesBySponsorItem", () => {
})
];
const groups = groupLinesBySponsorItem(rows);
expect(groups.map((g) => g.sponsorName)).toEqual(["Big", "Small"]);
const big = groups.find((g) => g.sponsorName === "Big");
// C: qty 9, orders 2 beats B: qty 9, orders 1
expect(groups[0].items.map((i) => i.itemCode)).toEqual(["C", "B"]);
expect(big.items.map((i) => i.itemCode)).toEqual(["C", "B"]);
});

it("sorts sponsor groups alphabetically, not by qty, with unknown last", () => {
const rows = [
line({ sponsor: { id: 1, name: "zeta" }, quantity: 1 }),
line({ sponsor: null, quantity: 1 }),
// Biggest qty by far — it still sorts on name, not units.
line({ sponsor: { id: 2, name: "Nokia" }, quantity: 99 }),
line({ sponsor: { id: 3, name: "acme" }, quantity: 1 })
];
expect(groupLinesBySponsorItem(rows).map((g) => g.sponsorName)).toEqual([
"acme",
"Nokia",
"zeta",
""
]);
});

it("passes canceled lines through as contributors with isCanceled", () => {
Expand Down
Loading