Skip to content

fix: correct table column alignment and non-millisecond timestamp formatting#27

Merged
HTHou merged 1 commit into
apache:mainfrom
CritasWang:fix/table-column-alignment-and-timestamp-precision
Jul 2, 2026
Merged

fix: correct table column alignment and non-millisecond timestamp formatting#27
HTHou merged 1 commit into
apache:mainfrom
CritasWang:fix/table-column-alignment-and-timestamp-precision

Conversation

@CritasWang

Copy link
Copy Markdown
Contributor

Summary

Fixes two defects in the Data Preview of table-model TsFiles, plus a related atob regression.

1. Header/body column misalignment

On table-model files, measurements also contains the tag columns (e.g. plant, device). The fixed device column used key/dataIndex = "device", colliding with a tag column also named device. Since antdv Table distinguishes columns by key, the header desynced from the body, and flatRow.device was overwritten by the measurement value.

Fix: the fixed identity column now uses a reserved key __device__, fully isolated from tag columns. Tree-model files are unaffected.

2. Timestamps rendered as NaN-NaN-NaN NaN:NaN:NaN.NaN

Source timestamps can be nanoseconds (19 digits, e.g. 1692611833503000000), which overflow JS DateInvalid DateNaN.

Fix:

  • Added normalizeToMs() (in utils/timestamp.ts) to auto-scale seconds / milliseconds / microseconds / nanoseconds to milliseconds.
  • Display stays at millisecond precision. The exact original value is preserved without a backend change via a scoped transformResponse hook that captures the raw timestamp digit string before JSON.parse (avoiding lossy double conversion), exposed on hover, with an info banner explaining the behavior.
  • CSV export timestamps now use normalizeToMs too.

3. atob regression fix

After fileIds became URL-safe base64, atob() failed on -/_ characters (and never handled UTF-8 for non-ASCII paths). Extracted encodeFileId/decodeFileId into utils/fileId.ts and replaced all six call sites (file tree, data-preview, chart, metadata).

Testing

  • pnpm build (vue-tsc + vite) passes.
  • Verified end-to-end in the browser on a real nanosecond table-model file: columns align, timestamp displays as 2023-08-21 17:57:13.503, hover shows the exact raw value, and sub-millisecond precision is preserved losslessly (raw string ...123456 kept exact, vs ...123500 under naive String(double)).

Notes

timestampRaw is currently preserved only on the data-preview endpoint. The chart endpoint could get the same treatment if full nanosecond fidelity is needed there.

…matting

Data preview had two defects on table-model TsFiles:

1. Header/body column misalignment: the fixed "device" column shared the
   same key/dataIndex ("device") with a tag column also named "device",
   which collided in antdv Table and desynced header from body. The fixed
   identity column now uses a reserved key "__device__" isolated from tag
   columns.

2. Timestamps rendered as "NaN-NaN-NaN": nanosecond (19-digit) timestamps
   overflow JS Date. Added normalizeToMs() to auto-scale sec/ms/us/ns to
   milliseconds. Display stays at millisecond precision; the exact original
   value is preserved via a transformResponse hook that captures the raw
   digit string before JSON.parse (avoiding lossy double conversion) and is
   shown on hover, with an info banner explaining the precision behavior.

Also fixes an atob() regression: after fileIds became URL-safe base64,
atob() failed on "_"/"-" chars. Extracted encode/decodeFileId into
utils/fileId.ts and replaced all six call sites (file tree, data-preview,
chart, metadata). CSV export timestamps now use normalizeToMs too.
@HTHou
HTHou merged commit 1a14814 into apache:main Jul 2, 2026
HTHou pushed a commit that referenced this pull request Jul 2, 2026
The data preview table hardcoded the virtual-scroll viewport height
(scroll.y = 480). After #27 added the timestamp-precision info banner
above the table, the fixed height no longer matched the actual space
left in the flex layout, so the table body overflowed onto the bottom
pagination bar.

Replace the hardcoded height with a measured one: wrap the table in a
flex-1 container and use a ResizeObserver to compute scroll.y from the
container's real client height, subtracting the measured header height
plus a scrollbar/border reserve. Re-measure after loading/data changes
(nextTick) since the column toolbar, info banner and pagination toggle
visibility. This adapts automatically to any future elements added
above or below the table instead of relying on a magic constant.

Also make .ant-card-body a flex column so the wrapper's flex-1 receives
the real remaining height, and drop an unused Spin import.
HTHou pushed a commit that referenced this pull request Jul 2, 2026
The data preview table hardcoded the virtual-scroll viewport height
(scroll.y = 480). After #27 added the timestamp-precision info banner
above the table, the fixed height no longer matched the actual space
left in the flex layout, so the table body overflowed onto the bottom
pagination bar.

Replace the hardcoded height with a measured one: wrap the table in a
flex-1 container and use a ResizeObserver to compute scroll.y from the
container's real client height, subtracting the measured header height
plus a scrollbar/border reserve. Re-measure after loading/data changes
(nextTick) since the column toolbar, info banner and pagination toggle
visibility. This adapts automatically to any future elements added
above or below the table instead of relying on a magic constant.

Also make .ant-card-body a flex column so the wrapper's flex-1 receives
the real remaining height, and drop an unused Spin import.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants