jupyterlab_tabular_data_viewer_extension 1.2.14 → 1.2.19
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.
- package/README.md +4 -4
- package/lib/index.js +3 -1
- package/lib/widget.js +24 -3
- package/package.json +1 -1
- package/src/index.ts +3 -1
- package/src/widget.ts +27 -3
- package/style/base.css +12 -0
package/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# jupyterlab_tabular_data_viewer_extension
|
|
2
2
|
|
|
3
|
-

|
|
4
|
-
[](https://github.com/stellarshenson/jupyterlab_tabular_data_viewer_extension/actions/workflows/build.yml)
|
|
4
|
+
[](https://www.npmjs.com/package/jupyterlab_tabular_data_viewer_extension)
|
|
5
|
+
[](https://pypi.org/project/jupyterlab-tabular-data-viewer-extension/)
|
|
6
6
|
[](https://pepy.tech/project/jupyterlab-tabular-data-viewer-extension)
|
|
7
|
-
](https://jupyterlab.readthedocs.io/en/stable/)
|
|
8
8
|
|
|
9
9
|
View and browse Parquet, Excel, CSV, and TSV files directly in JupyterLab. Double-click any .parquet, .xlsx, .csv, or .tsv file to open it in a simple, spreadsheet-like table view - no code required. Navigate through your data, inspect values, and explore the structure of your tabular data files with interactive column resizing and advanced filtering capabilities.
|
|
10
10
|
|
package/lib/index.js
CHANGED
|
@@ -73,7 +73,9 @@ const plugin = {
|
|
|
73
73
|
},
|
|
74
74
|
execute: async () => {
|
|
75
75
|
if (lastContextMenuRow) {
|
|
76
|
-
|
|
76
|
+
// Filter out internal metadata fields before copying
|
|
77
|
+
const { __row_index__, ...rowData } = lastContextMenuRow;
|
|
78
|
+
const jsonString = JSON.stringify(rowData, null, 2);
|
|
77
79
|
await navigator.clipboard.writeText(jsonString);
|
|
78
80
|
// console.log('Row copied to clipboard as JSON');
|
|
79
81
|
// Clean up highlight after copy
|
package/lib/widget.js
CHANGED
|
@@ -277,6 +277,22 @@ export class TabularDataViewer extends Widget {
|
|
|
277
277
|
_renderHeaders() {
|
|
278
278
|
this._filterRow.innerHTML = '';
|
|
279
279
|
this._headerRow.innerHTML = '';
|
|
280
|
+
// Add row number column header
|
|
281
|
+
const rowNumFilterCell = document.createElement('th');
|
|
282
|
+
rowNumFilterCell.className = 'jp-TabularDataViewer-filterCell jp-TabularDataViewer-rowNumberCell';
|
|
283
|
+
this._filterRow.appendChild(rowNumFilterCell);
|
|
284
|
+
const rowNumHeaderCell = document.createElement('th');
|
|
285
|
+
rowNumHeaderCell.className = 'jp-TabularDataViewer-headerCell jp-TabularDataViewer-rowNumberCell';
|
|
286
|
+
const rowNumContent = document.createElement('div');
|
|
287
|
+
rowNumContent.className = 'jp-TabularDataViewer-headerContent';
|
|
288
|
+
const rowNumName = document.createElement('div');
|
|
289
|
+
rowNumName.className = 'jp-TabularDataViewer-columnName';
|
|
290
|
+
rowNumName.textContent = '';
|
|
291
|
+
rowNumContent.appendChild(rowNumName);
|
|
292
|
+
rowNumHeaderCell.appendChild(rowNumContent);
|
|
293
|
+
rowNumHeaderCell.style.width = '60px';
|
|
294
|
+
rowNumFilterCell.style.width = '60px';
|
|
295
|
+
this._headerRow.appendChild(rowNumHeaderCell);
|
|
280
296
|
this._columns.forEach(col => {
|
|
281
297
|
// Create filter cell
|
|
282
298
|
const filterCell = document.createElement('th');
|
|
@@ -352,17 +368,22 @@ export class TabularDataViewer extends Widget {
|
|
|
352
368
|
filterCell.style.width = `${columnWidth}px`;
|
|
353
369
|
this._headerRow.appendChild(headerCell);
|
|
354
370
|
});
|
|
355
|
-
// Set table width to sum of all column widths
|
|
356
|
-
const totalWidth = Array.from(this._columnWidths.values()).reduce((sum, w) => sum + w, 0);
|
|
371
|
+
// Set table width to sum of all column widths plus row number column (60px)
|
|
372
|
+
const totalWidth = Array.from(this._columnWidths.values()).reduce((sum, w) => sum + w, 0) + 60;
|
|
357
373
|
this._table.style.width = `${totalWidth}px`;
|
|
358
374
|
}
|
|
359
375
|
/**
|
|
360
376
|
* Render data rows
|
|
361
377
|
*/
|
|
362
378
|
_renderData(rows) {
|
|
363
|
-
rows.forEach(row => {
|
|
379
|
+
rows.forEach((row) => {
|
|
364
380
|
const tr = document.createElement('tr');
|
|
365
381
|
tr.className = 'jp-TabularDataViewer-row';
|
|
382
|
+
// Add row number cell using original row index from backend
|
|
383
|
+
const rowNumCell = document.createElement('td');
|
|
384
|
+
rowNumCell.className = 'jp-TabularDataViewer-cell jp-TabularDataViewer-rowNumberCell';
|
|
385
|
+
rowNumCell.textContent = String(row['__row_index__'] || '');
|
|
386
|
+
tr.appendChild(rowNumCell);
|
|
366
387
|
this._columns.forEach(col => {
|
|
367
388
|
const td = document.createElement('td');
|
|
368
389
|
td.className = 'jp-TabularDataViewer-cell';
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -120,7 +120,9 @@ const plugin: JupyterFrontEndPlugin<void> = {
|
|
|
120
120
|
},
|
|
121
121
|
execute: async () => {
|
|
122
122
|
if (lastContextMenuRow) {
|
|
123
|
-
|
|
123
|
+
// Filter out internal metadata fields before copying
|
|
124
|
+
const { __row_index__, ...rowData } = lastContextMenuRow;
|
|
125
|
+
const jsonString = JSON.stringify(rowData, null, 2);
|
|
124
126
|
await navigator.clipboard.writeText(jsonString);
|
|
125
127
|
// console.log('Row copied to clipboard as JSON');
|
|
126
128
|
|
package/src/widget.ts
CHANGED
|
@@ -308,6 +308,24 @@ export class TabularDataViewer extends Widget {
|
|
|
308
308
|
this._filterRow.innerHTML = '';
|
|
309
309
|
this._headerRow.innerHTML = '';
|
|
310
310
|
|
|
311
|
+
// Add row number column header
|
|
312
|
+
const rowNumFilterCell = document.createElement('th');
|
|
313
|
+
rowNumFilterCell.className = 'jp-TabularDataViewer-filterCell jp-TabularDataViewer-rowNumberCell';
|
|
314
|
+
this._filterRow.appendChild(rowNumFilterCell);
|
|
315
|
+
|
|
316
|
+
const rowNumHeaderCell = document.createElement('th');
|
|
317
|
+
rowNumHeaderCell.className = 'jp-TabularDataViewer-headerCell jp-TabularDataViewer-rowNumberCell';
|
|
318
|
+
const rowNumContent = document.createElement('div');
|
|
319
|
+
rowNumContent.className = 'jp-TabularDataViewer-headerContent';
|
|
320
|
+
const rowNumName = document.createElement('div');
|
|
321
|
+
rowNumName.className = 'jp-TabularDataViewer-columnName';
|
|
322
|
+
rowNumName.textContent = '';
|
|
323
|
+
rowNumContent.appendChild(rowNumName);
|
|
324
|
+
rowNumHeaderCell.appendChild(rowNumContent);
|
|
325
|
+
rowNumHeaderCell.style.width = '60px';
|
|
326
|
+
rowNumFilterCell.style.width = '60px';
|
|
327
|
+
this._headerRow.appendChild(rowNumHeaderCell);
|
|
328
|
+
|
|
311
329
|
this._columns.forEach(col => {
|
|
312
330
|
// Create filter cell
|
|
313
331
|
const filterCell = document.createElement('th');
|
|
@@ -398,8 +416,8 @@ export class TabularDataViewer extends Widget {
|
|
|
398
416
|
this._headerRow.appendChild(headerCell);
|
|
399
417
|
});
|
|
400
418
|
|
|
401
|
-
// Set table width to sum of all column widths
|
|
402
|
-
const totalWidth = Array.from(this._columnWidths.values()).reduce((sum, w) => sum + w, 0);
|
|
419
|
+
// Set table width to sum of all column widths plus row number column (60px)
|
|
420
|
+
const totalWidth = Array.from(this._columnWidths.values()).reduce((sum, w) => sum + w, 0) + 60;
|
|
403
421
|
this._table.style.width = `${totalWidth}px`;
|
|
404
422
|
}
|
|
405
423
|
|
|
@@ -407,10 +425,16 @@ export class TabularDataViewer extends Widget {
|
|
|
407
425
|
* Render data rows
|
|
408
426
|
*/
|
|
409
427
|
private _renderData(rows: any[]): void {
|
|
410
|
-
rows.forEach(row => {
|
|
428
|
+
rows.forEach((row) => {
|
|
411
429
|
const tr = document.createElement('tr');
|
|
412
430
|
tr.className = 'jp-TabularDataViewer-row';
|
|
413
431
|
|
|
432
|
+
// Add row number cell using original row index from backend
|
|
433
|
+
const rowNumCell = document.createElement('td');
|
|
434
|
+
rowNumCell.className = 'jp-TabularDataViewer-cell jp-TabularDataViewer-rowNumberCell';
|
|
435
|
+
rowNumCell.textContent = String(row['__row_index__'] || '');
|
|
436
|
+
tr.appendChild(rowNumCell);
|
|
437
|
+
|
|
414
438
|
this._columns.forEach(col => {
|
|
415
439
|
const td = document.createElement('td');
|
|
416
440
|
td.className = 'jp-TabularDataViewer-cell';
|
package/style/base.css
CHANGED
|
@@ -168,6 +168,18 @@
|
|
|
168
168
|
box-sizing: border-box;
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
+
/* Row Number Cell */
|
|
172
|
+
.jp-TabularDataViewer-rowNumberCell {
|
|
173
|
+
text-align: center;
|
|
174
|
+
background-color: var(--jp-layout-color2);
|
|
175
|
+
color: var(--jp-ui-font-color2);
|
|
176
|
+
font-weight: 500;
|
|
177
|
+
user-select: none;
|
|
178
|
+
min-width: 60px;
|
|
179
|
+
max-width: 60px;
|
|
180
|
+
width: 60px;
|
|
181
|
+
}
|
|
182
|
+
|
|
171
183
|
.jp-TabularDataViewer-cell:last-child {
|
|
172
184
|
border-right: none;
|
|
173
185
|
}
|