Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | 1x 1x 6287x 1990x 1990x 4297x 4297x 1x 1400x 881x 881x 1x 1401x 507x 507x 894x 894x 1x 380x 380x 234x 234x 146x 353x 380x 380x 380x 58x 380x 11x 11x 135x 135x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 377x 376x 377x 374x 377x 126x 81x 126x 126x 248x 377x 377x 377x 1x 31x 31x 31x 87x 87x 81x 3x 3x 1x 116x 1x 1x 116x 116x 165x 165x 165x 35x 32x 32x 165x 12x 12x 118x 118x 165x 87x 87x 31x 116x 116x | // Utility helpers for CommonsTable (extracted to satisfy react-refresh rule)
export function formatPlain(value) {
if (value === null || value === undefined || value === "") {
return "—";
}
return `${value}`;
}
export function formatDate(value) {
if (!value) return "—";
return String(value).slice(0, 10);
}
export function formatBoolean(value) {
if (value === null || value === undefined || value === "") {
return "—";
}
return String(value);
}
export function computeEffectiveCapacity(commonsPlus) {
const { effectiveCapacity, commons: commonsData, totalUsers } = commonsPlus;
if (effectiveCapacity !== null && effectiveCapacity !== undefined) {
return effectiveCapacity;
}
if (
commonsData &&
commonsData.capacityPerUser !== null &&
commonsData.capacityPerUser !== undefined &&
totalUsers !== null &&
totalUsers !== undefined
) {
return commonsData.capacityPerUser * totalUsers;
}
return null;
}
const NUMERIC_SORT_KEYS = new Set([
"commons.cowPrice",
"commons.milkPrice",
"commons.startingBalance",
"commons.degradationRate",
"totalCows",
"commons.capacityPerUser",
"commons.carryingCapacity",
"effectiveCapacity",
]);
const STRING_DEFAULT_EMPTY_KEYS = new Set([
"commons.name",
"commons.startingDate",
"commons.lastDate",
]);
const sortableValueResolvers = {
"commons.id": (commonsPlus) => commonsPlus.commons?.id,
"commons.name": (commonsPlus) => commonsPlus.commons?.name,
"commons.cowPrice": (commonsPlus) => commonsPlus.commons?.cowPrice,
"commons.milkPrice": (commonsPlus) => commonsPlus.commons?.milkPrice,
"commons.startingBalance": (commonsPlus) =>
commonsPlus.commons?.startingBalance,
"commons.startingDate": (commonsPlus) => commonsPlus.commons?.startingDate,
"commons.lastDate": (commonsPlus) => commonsPlus.commons?.lastDate,
"commons.degradationRate": (commonsPlus) =>
commonsPlus.commons?.degradationRate,
"commons.showLeaderboard": (commonsPlus) =>
commonsPlus.commons?.showLeaderboard,
"commons.showChat": (commonsPlus) => commonsPlus.commons?.showChat,
totalCows: (commonsPlus) => commonsPlus.totalCows,
"commons.capacityPerUser": (commonsPlus) =>
commonsPlus.commons?.capacityPerUser,
"commons.carryingCapacity": (commonsPlus) =>
commonsPlus.commons?.carryingCapacity,
effectiveCapacity: computeEffectiveCapacity,
};
export function getSortableValue(commonsPlus, key) {
if (!commonsPlus) return null;
const resolver = sortableValueResolvers[key];
if (!resolver) return null;
const val = resolver(commonsPlus);
if (NUMERIC_SORT_KEYS.has(key)) {
if (val == null || val === "") return null;
const n = Number(val);
return Number.isFinite(n) ? n : null;
}
// For string/date/boolean fields, return as-is (or empty string for missing names/dates)
if (STRING_DEFAULT_EMPTY_KEYS.has(key)) return val ?? "";
return val ?? null;
}
export function compareAsStrings(aVal, bVal, directionMultiplier) {
const cmp = String(aVal).localeCompare(String(bVal));
return directionMultiplier === -1 ? -cmp : cmp;
}
function compareAsNumbers(aNum, bNum, directionMultiplier) {
if (aNum > bNum) return directionMultiplier;
if (aNum < bNum) return -directionMultiplier;
return 0;
}
export function createCommonsComparator(sortKey, sortDirection = "asc") {
if (sortDirection !== "asc" && sortDirection !== "desc") {
throw new Error("Invalid sort direction; expected 'asc' or 'desc'");
}
const directionMultiplier = sortDirection === "desc" ? -1 : 1;
return (a, b) => {
const aVal = getSortableValue(a, sortKey);
const bVal = getSortableValue(b, sortKey);
if (aVal == null) {
if (bVal == null) return 0;
return 1;
}
if (bVal == null) {
return -1;
}
const aNum = Number(aVal);
const bNum = Number(bVal);
if (Number.isFinite(aNum) && Number.isFinite(bNum)) {
return compareAsNumbers(aNum, bNum, directionMultiplier);
}
return compareAsStrings(aVal, bVal, directionMultiplier);
};
}
|