mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-11 08:07:15 +00:00
fix(frontend): respect forced column order for numeric column names (#9463)
This commit is contained in:
@@ -410,6 +410,23 @@
|
||||
return json
|
||||
}
|
||||
|
||||
// The explicit column order from a leading header row (see
|
||||
// handleArrayOfObjectsHeaders). Returned as an array so the order survives:
|
||||
// baking it into object keys loses integer-like names like "1234", which JS
|
||||
// enumerates first in ascending numeric order.
|
||||
function getForcedColumnOrder(json: any): string[] | undefined {
|
||||
if (
|
||||
Array.isArray(json) &&
|
||||
json.length > 0 &&
|
||||
Array.isArray(json[0]) &&
|
||||
json[0].length > 0 &&
|
||||
json[0].every((item) => typeof item === 'string')
|
||||
) {
|
||||
return json[0]
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
|
||||
type InputObject = { [key: string]: number[] }
|
||||
|
||||
function objectOfArraysToObjects(input: InputObject): any[] {
|
||||
@@ -643,6 +660,7 @@
|
||||
? 'absolute inset-0 [&>div]:h-full [&>div]:min-h-[10rem]'
|
||||
: ''}
|
||||
objects={handleArrayOfObjectsHeaders(data)}
|
||||
headerOrder={getForcedColumnOrder(data)}
|
||||
/>
|
||||
{:else if !forceJson && resultKind === 'html'}
|
||||
<div class="h-full">
|
||||
|
||||
@@ -21,10 +21,11 @@
|
||||
import DownloadCsv from './DownloadCsv.svelte'
|
||||
interface Props {
|
||||
objects?: Array<Record<string, any>>
|
||||
headerOrder?: string[]
|
||||
class?: string
|
||||
}
|
||||
|
||||
let { objects = [], class: className }: Props = $props()
|
||||
let { objects = [], headerOrder, class: className }: Props = $props()
|
||||
|
||||
let currentPage = $state(1)
|
||||
let perPage = $state(25)
|
||||
@@ -37,7 +38,7 @@
|
||||
let headers: string[] = $state([])
|
||||
|
||||
function recomputeObjectsAndHeaders(objects: Array<Record<string, any>>) {
|
||||
;[headers, structuredObjects] = computeStructuredObjectsAndHeaders(objects)
|
||||
;[headers, structuredObjects] = computeStructuredObjectsAndHeaders(objects, headerOrder)
|
||||
}
|
||||
|
||||
function adjustCurrentPage() {
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import { computeStructuredObjectsAndHeaders } from './tableUtils'
|
||||
|
||||
describe('computeStructuredObjectsAndHeaders', () => {
|
||||
it('respects an explicit headerOrder when a column name is integer-like (#9183)', () => {
|
||||
// "1234" must keep its specified position instead of jumping to the front,
|
||||
// the way Object.keys() orders integer-like keys.
|
||||
const headerOrder = ['Pokemon name', 'Type', '1234', 'Main strength']
|
||||
const rows = [
|
||||
{ 'Pokemon name': 'Pikachu', Type: 'Electric', '1234': 'nil', 'Main strength': 'Speed' }
|
||||
]
|
||||
const [headers] = computeStructuredObjectsAndHeaders(rows, headerOrder)
|
||||
expect(headers).toEqual(['Pokemon name', 'Type', '1234', 'Main strength'])
|
||||
})
|
||||
|
||||
it('appends keys not present in headerOrder, after the explicit ones', () => {
|
||||
const [headers] = computeStructuredObjectsAndHeaders([{ a: 1, b: 2, c: 3 }], ['a', 'b'])
|
||||
expect(headers).toEqual(['a', 'b', 'c'])
|
||||
})
|
||||
|
||||
it('keeps the existing object-key behavior when no headerOrder is given', () => {
|
||||
const [headers] = computeStructuredObjectsAndHeaders([{ x: 1, y: 2 }])
|
||||
expect(headers).toEqual(['x', 'y'])
|
||||
})
|
||||
})
|
||||
@@ -8,7 +8,10 @@ export function isEmail(value: string) {
|
||||
return value?.includes('@')
|
||||
}
|
||||
|
||||
export function computeStructuredObjectsAndHeaders(objects: Array<Record<string, any>>): [
|
||||
export function computeStructuredObjectsAndHeaders(
|
||||
objects: Array<Record<string, any>>,
|
||||
headerOrder?: string[]
|
||||
): [
|
||||
string[],
|
||||
{
|
||||
_id: number
|
||||
@@ -18,7 +21,10 @@ export function computeStructuredObjectsAndHeaders(objects: Array<Record<string,
|
||||
if (Array.isArray(objects)) {
|
||||
let nextId = 1
|
||||
|
||||
let hds: string[] = []
|
||||
// Seed headers from the explicit order when provided. Object key order
|
||||
// can't be trusted here: integer-like keys (e.g. "1234") are enumerated
|
||||
// first in ascending numeric order regardless of insertion order.
|
||||
let hds: string[] = headerOrder ? [...headerOrder] : []
|
||||
let objs = objects.map((obj) => {
|
||||
let rowData = obj && typeof obj == 'object' ? obj : {}
|
||||
if (Array.isArray(rowData)) {
|
||||
|
||||
Reference in New Issue
Block a user