Skip to content

MILAB-6655: use disambiguated column labels for native CSV export - #1762

Merged
AStaroverov merged 3 commits into
mainfrom
MILAB-6655_csv-export-disambiguated-labels
Jul 22, 2026
Merged

MILAB-6655: use disambiguated column labels for native CSV export#1762
AStaroverov merged 3 commits into
mainfrom
MILAB-6655_csv-export-disambiguated-labels

Conversation

@AStaroverov

@AStaroverov AStaroverov commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

The native export path (exportPTable / writePTableToFs) derived header names from the raw column spec (pl7.app/label, else spec name). Since label disambiguation moved into the PlDataTable columnsMeta sidecar, those raw labels are no longer unique, so exporting a table with many columns could emit duplicate header names — which the native DataFusion-backed exportPTable rejects, breaking the export.

Carry the disambiguated labels the UI actually shows into the export call. PlAgCsvExporter reads them from the visible grid columns via effectiveLabel(spec, columnsMeta) and passes them alongside the column indices.

The driver API stays backward compatible: columnIndices is unchanged and a new optional headerNames (aligned 1:1) is added. ui-vue and the desktop-app runtime version independently, so an older runtime simply ignores headerNames and keeps deriving labels from the spec; a missing or empty name falls back to the spec-derived label.

Greptile Summary

This PR fixes a native CSV export failure that occurred when a PlDataTable contained multiple columns whose raw pl7.app/label annotations collide. The core driver (exportPTable / writePTableToFs) was deriving header names from the spec's intrinsic label, while the UI had already moved label disambiguation into the columnsMeta sidecar — causing the native DataFusion export path to reject the duplicate headers.

  • Interface change (data_types.ts): ExportPTableOptions and WritePTableToFsOptions gain an optional headerNames?: string[] aligned 1:1 with columnIndices. Additive/backward-compatible — older runtimes silently ignore the field.
  • Driver implementation (driver_impl.ts): Both writePTableToFs and exportPTable resolve headers eagerly — caller-supplied names win; a missing/empty entry falls back to getNativeColumnLabel (renamed from columnLabel to clarify its scope).
  • UI wiring (export-csv.ts, PlAgCsvExporter.vue, PlAgDataTableV2.vue): collectVisibleColumnIndices is replaced by collectVisibleColumns which returns [index, disambiguatedLabel][]; columnsMeta is threaded from PlAgDataTableV2 through PlAgCsvExporter into the export call so disambiguated labels are captured at the grid layer.

Confidence Score: 5/5

Safe to merge — additive, backward-compatible change that fixes a real export breakage without altering existing behavior.

The change is narrowly scoped: a new optional field (headerNames) threads disambiguated labels from the UI grid layer through to the CSV streaming path, with the driver resolving each name eagerly and falling back to the existing spec-derived label when the caller omits or empties an entry. The length-mismatch guard added to streamPTableRows catches the one realistic misuse. Both exportPTable and writePTableToFs paths now have symmetric test coverage for the new field. No existing call sites are broken — older runtimes that receive headerNames in the JSON simply ignore an unrecognized field.

No files require special attention.

Important Files Changed

Filename Overview
lib/model/common/src/drivers/pframe/data_types.ts Adds optional headerNames?: string[] to both WritePTableToFsOptions and ExportPTableOptions with clear JSDoc. Backward-compatible — older runtimes ignore the field.
lib/node/pf-driver/src/csv_writer.ts Adds headerNames to StreamPTableRowsOptions, enforces length == columnIndices.length guard at stream entry, and renames columnLabel → getNativeColumnLabel for clarity.
lib/node/pf-driver/src/driver_impl.ts Both writePTableToFs and exportPTable now eagerly resolve headers from options.headerNames with getNativeColumnLabel fallback. The resolved array is always length-matched to columnIndices, so the downstream guard never fires from this path.
lib/node/pf-driver/src/driver_double.test.ts Adds symmetric tests for exportPTable and writePTableToFs with explicit headerNames, verifying caller-supplied names win over spec-derived labels. Addresses the gap from the prior review cycle.
lib/node/pf-driver/src/tests/csv_writer.test.ts Adds a test asserting that mismatched headerNames / columnIndices lengths throw with a descriptive message.
sdk/ui-vue/src/components/PlAgCsvExporter/export-csv.ts Renames collectVisibleColumnIndices → collectVisibleColumns (return type [number, string][]), passes columnsMeta through, and threads headerNames into both exportPTable and writePTableToFs calls.
sdk/ui-vue/src/components/PlAgCsvExporter/PlAgCsvExporter.vue Adds optional columnsMeta prop and passes it into ExportOptions. Minimal, clean change.
sdk/ui-vue/src/components/PlAgDataTable/PlAgDataTableV2.vue Wires :columns-meta into PlAgCsvExporter and renames the internal helper from currentColumnsMeta to getColumnsMeta. No functional changes beyond the new prop pass-through.
sdk/model/src/components/PlDataTable/createPlDataTable/createPlDataTableV3.ts Removes a large dead-code block (const _ = [...] with hardcoded sample PColumn data). Pure cleanup, no functional change.
lib/node/pf-driver/src/driver_decl.ts Doc-comment update for exportPTable to mention the new optional headerNames field. No code change.

Sequence Diagram

sequenceDiagram
    participant User
    participant PlAgDataTableV2
    participant PlAgCsvExporter
    participant exportCsv
    participant collectVisibleColumns
    participant PFrameDriver

    User->>PlAgDataTableV2: click Export
    PlAgDataTableV2->>PlAgCsvExporter: api, tableHandle, columnsMeta
    PlAgCsvExporter->>exportCsv: "ExportOptions{tableHandle, columnsMeta}"
    exportCsv->>PFrameDriver: getSpec(visibleTableHandle)
    PFrameDriver-->>exportCsv: PTableColumnSpec[]
    exportCsv->>collectVisibleColumns: gridApi, specs, pframeSpec, columnsMeta
    Note over collectVisibleColumns: effectiveLabel(spec, columnsMeta) sidecar override > pl7.app/label > spec.name
    collectVisibleColumns-->>exportCsv: [index, disambiguatedLabel][]
    exportCsv->>PFrameDriver: "exportPTable(handle, {columnIndices, headerNames})"
    Note over PFrameDriver: headerNames[i] win over getNativeColumnLabel() empty/missing fallback to spec label
    PFrameDriver-->>User: CSV file with disambiguated headers
Loading

Reviews (2): Last reviewed commit: "MILAB-6655: validate headerNames length;..." | Re-trigger Greptile

Context used:

  • Context used - Terms is a types in codebase. Provide the list of ... (source)

The native export path (exportPTable / writePTableToFs) derived header
names from the raw column spec (pl7.app/label, else spec name). Since
label disambiguation moved into the PlDataTable columnsMeta sidecar,
those raw labels are no longer unique, so exporting a table with many
columns could emit duplicate header names — which the native
DataFusion-backed exportPTable rejects, breaking the export.

Carry the disambiguated labels the UI actually shows into the export
call. PlAgCsvExporter reads them from the visible grid columns via
effectiveLabel(spec, columnsMeta) and passes them alongside the column
indices.

The driver API stays backward compatible: columnIndices is unchanged and
a new optional headerNames (aligned 1:1) is added. ui-vue and the
desktop-app runtime version independently, so an older runtime simply
ignores headerNames and keeps deriving labels from the spec; a missing
or empty name falls back to the spec-derived label.
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@notion-workspace

Copy link
Copy Markdown

@changeset-bot

changeset-bot Bot commented Jul 22, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 4ec4738

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 22 packages
Name Type
@milaboratories/pl-model-common Patch
@milaboratories/pf-driver Patch
@platforma-sdk/ui-vue Patch
@milaboratories/pl-model-middle-layer Patch
@milaboratories/pf-spec-driver Patch
@milaboratories/columns-collection-driver Patch
@milaboratories/pl-client Patch
@milaboratories/pl-drivers Patch
@milaboratories/pl-middle-layer Patch
@milaboratories/pl-deployments Patch
@platforma-open/milaboratories.software-ptabler.schema Patch
@platforma-sdk/block-tools Patch
@platforma-sdk/model Patch
@milaboratories/pl-model-backend Patch
@milaboratories/pl-errors Patch
@milaboratories/pl-tree Patch
@platforma-sdk/pl-cli Patch
@platforma-sdk/test Patch
@platforma-sdk/bootstrap Patch
@milaboratories/ptabler-expression-js Patch
@milaboratories/uikit Patch
@platforma-sdk/tengo-builder Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Comment thread lib/node/pf-driver/src/csv_writer.ts
Comment thread lib/node/pf-driver/src/driver_double.test.ts
@AStaroverov

Copy link
Copy Markdown
Collaborator Author

@greptileai

@AStaroverov
AStaroverov enabled auto-merge July 22, 2026 10:35
@AStaroverov
AStaroverov added this pull request to the merge queue Jul 22, 2026
Merged via the queue into main with commit 0fa67e7 Jul 22, 2026
7 checks passed
@AStaroverov
AStaroverov deleted the MILAB-6655_csv-export-disambiguated-labels branch July 22, 2026 10:51
@codecov

codecov Bot commented Jul 22, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.75000% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 53.71%. Comparing base (edf2f7d) to head (4ec4738).
⚠️ Report is 5 commits behind head on main.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
lib/node/pf-driver/src/driver_impl.ts 87.50% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1762      +/-   ##
==========================================
+ Coverage   49.57%   53.71%   +4.13%     
==========================================
  Files          70      366     +296     
  Lines        3786    19679   +15893     
  Branches      969     4341    +3372     
==========================================
+ Hits         1877    10571    +8694     
- Misses       1640     7799    +6159     
- Partials      269     1309    +1040     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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