(a: DbRow, b: DbRow, field: DbField)
| 84 | // --------------------------------------------------------------------------- |
| 85 | |
| 86 | function compareByField(a: DbRow, b: DbRow, field: DbField): number { |
| 87 | const av = cell(a, field.id).trim() |
| 88 | const bv = cell(b, field.id).trim() |
| 89 | // Empty values always sort last (regardless of direction is applied by caller). |
| 90 | if (av === '' && bv === '') return 0 |
| 91 | if (av === '') return 1 |
| 92 | if (bv === '') return -1 |
| 93 | switch (field.type) { |
| 94 | case 'number': { |
| 95 | const na = Number(av) |
| 96 | const nb = Number(bv) |
| 97 | if (Number.isNaN(na) || Number.isNaN(nb)) return av.localeCompare(bv) |
| 98 | return na - nb |
| 99 | } |
| 100 | case 'checkbox': |
| 101 | return Number(isCheckboxTrue(av)) - Number(isCheckboxTrue(bv)) |
| 102 | case 'date': |
| 103 | // ISO YYYY-MM-DD sorts correctly lexically. |
| 104 | return av < bv ? -1 : av > bv ? 1 : 0 |
| 105 | default: |
| 106 | return av.localeCompare(bv, undefined, { numeric: true, sensitivity: 'base' }) |
| 107 | } |
| 108 | } |
| 109 | |
| 110 | export function sortRows( |
| 111 | rows: DbRow[], |
no test coverage detected