@platforma-sdk/ui-vue 1.80.9 → 1.80.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. package/.turbo/turbo-build.log +14 -14
  2. package/.turbo/turbo-formatter$colon$check.log +2 -2
  3. package/.turbo/turbo-linter$colon$check.log +2 -2
  4. package/.turbo/turbo-types$colon$check.log +1 -1
  5. package/CHANGELOG.md +15 -0
  6. package/dist/components/PlAgCsvExporter/PlAgCsvExporter.js.map +1 -1
  7. package/dist/components/PlAgCsvExporter/PlAgCsvExporter.vue.d.ts +2 -1
  8. package/dist/components/PlAgCsvExporter/PlAgCsvExporter.vue.d.ts.map +1 -1
  9. package/dist/components/PlAgCsvExporter/PlAgCsvExporter.vue2.js +6 -2
  10. package/dist/components/PlAgCsvExporter/PlAgCsvExporter.vue2.js.map +1 -1
  11. package/dist/components/PlAgCsvExporter/export-csv.d.ts +16 -5
  12. package/dist/components/PlAgCsvExporter/export-csv.d.ts.map +1 -1
  13. package/dist/components/PlAgCsvExporter/export-csv.js +48 -39
  14. package/dist/components/PlAgCsvExporter/export-csv.js.map +1 -1
  15. package/dist/components/PlAgDataTable/PlAgDataTableV2.js.map +1 -1
  16. package/dist/components/PlAgDataTable/PlAgDataTableV2.style.js.map +1 -1
  17. package/dist/components/PlAgDataTable/PlAgDataTableV2.vue.d.ts.map +1 -1
  18. package/dist/components/PlAgDataTable/PlAgDataTableV2.vue2.js +22 -17
  19. package/dist/components/PlAgDataTable/PlAgDataTableV2.vue2.js.map +1 -1
  20. package/dist/components/PlAgDataTable/sources/table-source-v2.js +1 -1
  21. package/dist/components/PlAnnotations/components/PlAnnotations.vue2.js.map +1 -1
  22. package/dist/index.js +8 -8
  23. package/dist/lib.js +4 -4
  24. package/package.json +9 -9
  25. package/src/components/PlAgCsvExporter/PlAgCsvExporter.vue +3 -2
  26. package/src/components/PlAgCsvExporter/export-csv.ts +40 -9
  27. package/src/components/PlAgDataTable/PlAgDataTableV2.vue +4 -3
@@ -4,6 +4,7 @@ import type {
4
4
  PTableHandle,
5
5
  PTableColumnSpec,
6
6
  PFrameSpecDriver,
7
+ PlDataTableColumnsMeta,
7
8
  WritePTableToFsResult,
8
9
  } from "@platforma-sdk/model";
9
10
  import { getPTableColumnId, XLSX_MAX_ROWS_PER_SHEET } from "@platforma-sdk/model";
@@ -11,11 +12,18 @@ import { isNil } from "es-toolkit";
11
12
  import { Nil } from "@milaboratories/helpers";
12
13
  import { getServices } from "../../internal/getServices";
13
14
  import { PlAgDataTableRowNumberColId } from "../PlAgDataTable";
15
+ import { effectiveLabel } from "../PlAgDataTable/sources/table-source-v2";
14
16
 
15
17
  /** Options for the native table export. */
16
18
  export interface ExportOptions {
17
19
  tableHandle: PTableHandle;
18
20
  defaultFileName?: string;
21
+ /**
22
+ * Sidecar display metadata for the visible table. Supplies the disambiguated
23
+ * header labels the UI shows — the ones the spec's intrinsic `pl7.app/label`
24
+ * may not carry — so the export reproduces exactly what the user sees.
25
+ */
26
+ columnsMeta?: PlDataTableColumnsMeta;
19
27
  }
20
28
 
21
29
  /** Save-dialog file-type filters for the native `exportPTable` path. */
@@ -80,10 +88,20 @@ export async function exportCsv(
80
88
  }
81
89
 
82
90
  const specs = await pframe.getSpec(nativeOptions.tableHandle);
83
- const columnIndices = collectVisibleColumnIndices(gridApi, specs, pframeSpec);
84
- if (isNil(columnIndices)) {
91
+ const visibleColumns = collectVisibleColumns(
92
+ gridApi,
93
+ specs,
94
+ pframeSpec,
95
+ nativeOptions.columnsMeta,
96
+ );
97
+ if (isNil(visibleColumns)) {
85
98
  return undefined;
86
99
  }
100
+ // `columnIndices` is the long-standing field every runtime understands;
101
+ // `headerNames` is additive so a newer UI still works against an older
102
+ // desktop-app runtime (which ignores it and derives labels from the spec).
103
+ const columnIndices = visibleColumns.map(([index]) => index);
104
+ const headerNames = visibleColumns.map(([, name]) => name);
87
105
 
88
106
  const baseFileName = nativeOptions.defaultFileName ?? `table_${formatTimestamp(new Date())}`;
89
107
 
@@ -102,7 +120,7 @@ export async function exportCsv(
102
120
  return undefined;
103
121
  }
104
122
 
105
- await pframe.exportPTable(nativeOptions.tableHandle, { path, columnIndices });
123
+ await pframe.exportPTable(nativeOptions.tableHandle, { path, columnIndices, headerNames });
106
124
  return undefined;
107
125
  }
108
126
 
@@ -123,6 +141,7 @@ export async function exportCsv(
123
141
  path,
124
142
  format,
125
143
  columnIndices,
144
+ headerNames,
126
145
  ...(path.toLowerCase().endsWith(".gz") && { compression: { type: "gzip" } }),
127
146
  });
128
147
  }
@@ -150,16 +169,22 @@ export function isCsvExportAvailable(): boolean {
150
169
  }
151
170
 
152
171
  /**
153
- * Collect unified column indices for visible (non-hidden) columns from the
154
- * ag-grid column defs, remapped onto the provided PTable spec array so the
155
- * indices match the current table handle (ColDef.field indices may be stale
172
+ * Collect `[unified index, header name]` pairs for visible (non-hidden) columns
173
+ * from the ag-grid column defs, remapped onto the provided PTable spec array so
174
+ * the indices match the current table handle (ColDef.field indices may be stale
156
175
  * or diverge from the spec order).
176
+ *
177
+ * The header name is the disambiguated label the UI shows — sidecar override
178
+ * (`columnsMeta`) wins over the spec's intrinsic `pl7.app/label`, falling back
179
+ * to the spec name — so the export reproduces exactly the visible headers and
180
+ * avoids the duplicate-label collisions that break the native export path.
157
181
  */
158
- export function collectVisibleColumnIndices(
182
+ export function collectVisibleColumns(
159
183
  gridApi: GridApi,
160
184
  specs: PTableColumnSpec[],
161
185
  pframeSpec: PFrameSpecDriver,
162
- ): Nil | number[] {
186
+ columnsMeta: PlDataTableColumnsMeta | undefined,
187
+ ): Nil | [number, string][] {
163
188
  const columnDefs = gridApi.getColumnDefs();
164
189
  if (isNil(columnDefs)) {
165
190
  return;
@@ -176,5 +201,11 @@ export function collectVisibleColumnIndices(
176
201
  return [def.context as PTableColumnSpec];
177
202
  };
178
203
 
179
- return [...new Set(columnDefs.flatMap(specsForDef).map(findIndex))].filter((idx) => idx !== -1);
204
+ const byIndex = new Map<number, string>();
205
+ for (const spec of columnDefs.flatMap(specsForDef)) {
206
+ const index = findIndex(spec);
207
+ if (index === -1 || byIndex.has(index)) continue;
208
+ byIndex.set(index, effectiveLabel(spec, columnsMeta)?.trim() ?? spec.spec.name);
209
+ }
210
+ return [...byIndex];
180
211
  }
@@ -133,7 +133,7 @@ gridOptions.value.onGridPreDestroyed = (event) => {
133
133
  makePartialState(event.api.getState()),
134
134
  gridState.value,
135
135
  event.api,
136
- currentColumnsMeta(),
136
+ getColumnsMeta(),
137
137
  );
138
138
  }
139
139
  gridApi.value = null;
@@ -146,7 +146,7 @@ gridOptions.value.onStateUpdated = (event) => {
146
146
  makePartialState(event.state),
147
147
  gridState.value,
148
148
  event.api,
149
- currentColumnsMeta(),
149
+ getColumnsMeta(),
150
150
  );
151
151
  // We have to keep initialState synchronized with gridState for gridState recovery after key updating.
152
152
  gridOptions.value.initialState = gridState.value = partialState;
@@ -241,7 +241,7 @@ function normalizeColumnVisibility(
241
241
  }
242
242
 
243
243
  /** Sidecar display meta is only on the `model` branch of the settings union. */
244
- function currentColumnsMeta(): PlDataTableColumnsMeta | undefined {
244
+ function getColumnsMeta(): PlDataTableColumnsMeta | undefined {
245
245
  return "model" in props.settings ? props.settings.model?.columnsMeta : undefined;
246
246
  }
247
247
 
@@ -576,6 +576,7 @@ watchEffect(() => {
576
576
  v-if="gridApi && showExportButton"
577
577
  :api="gridApi"
578
578
  :table-handle="'model' in settings ? settings?.model?.visibleTableHandle : undefined"
579
+ :columns-meta="getColumnsMeta()"
579
580
  />
580
581
  <PlAgDataTableSheets v-model="sheetsState" :settings="sheetsSettings">
581
582
  <template v-if="$slots['before-sheets']" #before>