juxscript 1.1.177 → 1.1.179
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.
|
@@ -69,7 +69,7 @@ export declare class DataFrameComponent extends BaseComponent<DataFrameState> {
|
|
|
69
69
|
paginated(v: boolean): this;
|
|
70
70
|
rowsPerPage(v: number): this;
|
|
71
71
|
/**
|
|
72
|
-
* ✅
|
|
72
|
+
* ✅ FIXED: Render multiple Excel sheets as tabs
|
|
73
73
|
*/
|
|
74
74
|
private _renderMultiSheet;
|
|
75
75
|
private _updateStatus;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dataframe.d.ts","sourceRoot":"","sources":["dataframe.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"dataframe.d.ts","sourceRoot":"","sources":["dataframe.ts"],"names":[],"mappings":"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"}
|
|
@@ -86,7 +86,7 @@ export class DataFrameComponent extends BaseComponent {
|
|
|
86
86
|
this.state.loading = true;
|
|
87
87
|
this._updateStatus('⏳ Parsing ' + file.name + '...', 'loading');
|
|
88
88
|
try {
|
|
89
|
-
// ✅
|
|
89
|
+
// ✅ Check if multi-sheet Excel
|
|
90
90
|
const isExcel = file.name.toLowerCase().endsWith('.xlsx') ||
|
|
91
91
|
file.name.toLowerCase().endsWith('.xls');
|
|
92
92
|
if (isExcel) {
|
|
@@ -95,7 +95,7 @@ export class DataFrameComponent extends BaseComponent {
|
|
|
95
95
|
// Store first sheet to IndexedDB
|
|
96
96
|
await this._driver.store(file.name, sheets[sheetNames[0]], { source: file.name });
|
|
97
97
|
if (sheetNames.length > 1) {
|
|
98
|
-
// Multi-sheet: render tabs
|
|
98
|
+
// ✅ Multi-sheet: render tabs
|
|
99
99
|
this._renderMultiSheet(sheets, file.name);
|
|
100
100
|
}
|
|
101
101
|
else {
|
|
@@ -212,7 +212,7 @@ export class DataFrameComponent extends BaseComponent {
|
|
|
212
212
|
* MULTI-SHEET RENDERING
|
|
213
213
|
* ═══════════════════════════════════════════════════ */
|
|
214
214
|
/**
|
|
215
|
-
* ✅
|
|
215
|
+
* ✅ FIXED: Render multiple Excel sheets as tabs
|
|
216
216
|
*/
|
|
217
217
|
_renderMultiSheet(sheets, sourceName) {
|
|
218
218
|
this.state.loading = false;
|
|
@@ -228,25 +228,27 @@ export class DataFrameComponent extends BaseComponent {
|
|
|
228
228
|
Object.entries(sheets).forEach(([name, df]) => {
|
|
229
229
|
this._sheets.set(name, df);
|
|
230
230
|
});
|
|
231
|
-
// Create tabs
|
|
232
231
|
const sheetNames = Object.keys(sheets);
|
|
232
|
+
// ✅ FIX: Create tabs with EMPTY content first (just placeholders)
|
|
233
233
|
const tabs = new Tabs(`${this._id}-tabs`, {
|
|
234
234
|
tabs: sheetNames.map(name => ({
|
|
235
235
|
id: name,
|
|
236
236
|
label: name,
|
|
237
|
-
content: '' //
|
|
237
|
+
content: '' // Empty - we'll fill after render
|
|
238
238
|
})),
|
|
239
239
|
activeTab: sheetNames[0]
|
|
240
240
|
});
|
|
241
241
|
this._tabs = tabs;
|
|
242
|
-
// Render tabs
|
|
242
|
+
// Render tabs container
|
|
243
243
|
const tabsContainer = document.createElement('div');
|
|
244
244
|
tabsContainer.className = 'jux-dataframe-tabs';
|
|
245
245
|
wrapper.appendChild(tabsContainer);
|
|
246
|
+
// ✅ Render tabs NOW (creates all tab panels in DOM)
|
|
246
247
|
tabs.render(tabsContainer);
|
|
247
|
-
//
|
|
248
|
+
// ✅ NOW populate each tab with its DataFrame table (panels exist now)
|
|
248
249
|
sheetNames.forEach(sheetName => {
|
|
249
250
|
const df = sheets[sheetName];
|
|
251
|
+
// Create table
|
|
250
252
|
const table = new Table(`${this._id}-table-${sheetName}`, {
|
|
251
253
|
striped: this._tableOptions.striped,
|
|
252
254
|
hoverable: this._tableOptions.hoverable,
|
|
@@ -255,14 +257,20 @@ export class DataFrameComponent extends BaseComponent {
|
|
|
255
257
|
paginated: this._tableOptions.paginated,
|
|
256
258
|
rowsPerPage: this._tableOptions.rowsPerPage
|
|
257
259
|
});
|
|
258
|
-
//
|
|
260
|
+
// Convert columns to ColumnDef[]
|
|
259
261
|
const columnDefs = df.columns.map(col => ({
|
|
260
262
|
key: col,
|
|
261
263
|
label: col
|
|
262
264
|
}));
|
|
263
265
|
table.columns(columnDefs).rows(df.toRows());
|
|
264
|
-
//
|
|
265
|
-
|
|
266
|
+
// ✅ Find the tab panel (it exists now because tabs.render() was called)
|
|
267
|
+
const tabPanel = document.getElementById(`${this._id}-tabs-${sheetName}-panel`);
|
|
268
|
+
if (!tabPanel) {
|
|
269
|
+
console.error(`Tab panel not found: ${this._id}-tabs-${sheetName}-panel`);
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
// ✅ Render table directly into tab panel
|
|
273
|
+
table.render(tabPanel);
|
|
266
274
|
// Add filter if enabled
|
|
267
275
|
if (this._tableOptions.filterable) {
|
|
268
276
|
const filterContainer = document.createElement('div');
|
|
@@ -290,13 +298,10 @@ export class DataFrameComponent extends BaseComponent {
|
|
|
290
298
|
});
|
|
291
299
|
table.rows(filtered.toRows());
|
|
292
300
|
});
|
|
293
|
-
// Insert filter
|
|
294
|
-
const
|
|
295
|
-
if (
|
|
296
|
-
|
|
297
|
-
if (tableWrapper) {
|
|
298
|
-
tabPanel.insertBefore(filterContainer, tableWrapper);
|
|
299
|
-
}
|
|
301
|
+
// ✅ Insert filter BEFORE the table wrapper (which exists now)
|
|
302
|
+
const tableWrapper = tabPanel.querySelector('.jux-table-wrapper');
|
|
303
|
+
if (tableWrapper) {
|
|
304
|
+
tabPanel.insertBefore(filterContainer, tableWrapper);
|
|
300
305
|
}
|
|
301
306
|
}
|
|
302
307
|
});
|
|
@@ -305,7 +310,6 @@ export class DataFrameComponent extends BaseComponent {
|
|
|
305
310
|
this._updateStatus(`${sourceName} — ${sheetNames.length} sheets, ${totalRows} total rows`, 'success');
|
|
306
311
|
// Set first sheet as active DataFrame
|
|
307
312
|
this._df = sheets[sheetNames[0]];
|
|
308
|
-
this._table = tabs._tabsWrapper?.querySelector(`#${this._id}-table-${sheetNames[0]}`);
|
|
309
313
|
this._triggerCallback('load', this._df, null, this);
|
|
310
314
|
}
|
|
311
315
|
/* ═══════════════════════════════════════════════════
|
|
@@ -352,19 +356,19 @@ export class DataFrameComponent extends BaseComponent {
|
|
|
352
356
|
_updateTable() {
|
|
353
357
|
if (!this._table || !this._df)
|
|
354
358
|
return;
|
|
355
|
-
// ✅
|
|
359
|
+
// ✅ Convert string[] columns to ColumnDef[] with labels
|
|
356
360
|
const columnDefs = this._df.columns.map(col => ({
|
|
357
361
|
key: col,
|
|
358
|
-
label: col
|
|
362
|
+
label: col
|
|
359
363
|
}));
|
|
360
|
-
// ✅ Update
|
|
364
|
+
// ✅ Update columns and rows
|
|
361
365
|
this._table.columns(columnDefs).rows(this._df.toRows());
|
|
362
|
-
// ✅ Force table
|
|
363
|
-
const tableElement = this._table['_tableElement'];
|
|
366
|
+
// ✅ FIX: Force full table rebuild (including pagination)
|
|
367
|
+
const tableElement = this._table['_tableElement'];
|
|
364
368
|
if (tableElement) {
|
|
365
369
|
const wrapper = tableElement.closest('.jux-table-wrapper');
|
|
366
370
|
if (wrapper) {
|
|
367
|
-
// Clear
|
|
371
|
+
// Clear table content
|
|
368
372
|
tableElement.innerHTML = '';
|
|
369
373
|
// Rebuild header
|
|
370
374
|
const thead = this._table._buildTableHeader();
|
|
@@ -375,6 +379,10 @@ export class DataFrameComponent extends BaseComponent {
|
|
|
375
379
|
tableElement.appendChild(tbody);
|
|
376
380
|
// Re-wire events
|
|
377
381
|
this._table._wireTriggerEvents(tbody);
|
|
382
|
+
// ✅ FIX: Re-build pagination controls
|
|
383
|
+
if (this._tableOptions.paginated) {
|
|
384
|
+
this._table._updatePagination(wrapper, tbody);
|
|
385
|
+
}
|
|
378
386
|
}
|
|
379
387
|
}
|
|
380
388
|
}
|
|
@@ -443,6 +451,7 @@ export class DataFrameComponent extends BaseComponent {
|
|
|
443
451
|
}
|
|
444
452
|
const upload = new FileUpload(`${this._id}-upload`, uploadOpts);
|
|
445
453
|
this._uploadRef = upload;
|
|
454
|
+
// ✅ FIX: Use the SAME logic as fromUpload() to handle multi-sheet
|
|
446
455
|
this._pendingSource = async () => {
|
|
447
456
|
upload.bind('change', async (files) => {
|
|
448
457
|
if (!files || files.length === 0)
|
|
@@ -451,9 +460,29 @@ export class DataFrameComponent extends BaseComponent {
|
|
|
451
460
|
this.state.loading = true;
|
|
452
461
|
this._updateStatus('⏳ Parsing ' + file.name + '...', 'loading');
|
|
453
462
|
try {
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
463
|
+
// ✅ Check if multi-sheet Excel
|
|
464
|
+
const isExcel = file.name.toLowerCase().endsWith('.xlsx') ||
|
|
465
|
+
file.name.toLowerCase().endsWith('.xls');
|
|
466
|
+
if (isExcel) {
|
|
467
|
+
const sheets = await this._driver.streamFileMultiSheet(file);
|
|
468
|
+
const sheetNames = Object.keys(sheets);
|
|
469
|
+
// Store first sheet to IndexedDB
|
|
470
|
+
await this._driver.store(file.name, sheets[sheetNames[0]], { source: file.name });
|
|
471
|
+
if (sheetNames.length > 1) {
|
|
472
|
+
// ✅ Multi-sheet: render tabs
|
|
473
|
+
this._renderMultiSheet(sheets, file.name);
|
|
474
|
+
}
|
|
475
|
+
else {
|
|
476
|
+
// Single sheet: render normally
|
|
477
|
+
this._setDataFrame(sheets[sheetNames[0]], file.name);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
else {
|
|
481
|
+
// CSV/TSV: single sheet
|
|
482
|
+
const df = await this._driver.streamFile(file);
|
|
483
|
+
await this._driver.store(file.name, df, { source: file.name });
|
|
484
|
+
this._setDataFrame(df, file.name);
|
|
485
|
+
}
|
|
457
486
|
}
|
|
458
487
|
catch (err) {
|
|
459
488
|
this._triggerCallback('error', err.message, null, this);
|
|
@@ -124,7 +124,7 @@ export class DataFrameComponent extends BaseComponent<DataFrameState> {
|
|
|
124
124
|
this._updateStatus('⏳ Parsing ' + file.name + '...', 'loading');
|
|
125
125
|
|
|
126
126
|
try {
|
|
127
|
-
// ✅
|
|
127
|
+
// ✅ Check if multi-sheet Excel
|
|
128
128
|
const isExcel = file.name.toLowerCase().endsWith('.xlsx') ||
|
|
129
129
|
file.name.toLowerCase().endsWith('.xls');
|
|
130
130
|
|
|
@@ -136,7 +136,7 @@ export class DataFrameComponent extends BaseComponent<DataFrameState> {
|
|
|
136
136
|
await this._driver.store(file.name, sheets[sheetNames[0]], { source: file.name });
|
|
137
137
|
|
|
138
138
|
if (sheetNames.length > 1) {
|
|
139
|
-
// Multi-sheet: render tabs
|
|
139
|
+
// ✅ Multi-sheet: render tabs
|
|
140
140
|
this._renderMultiSheet(sheets, file.name);
|
|
141
141
|
} else {
|
|
142
142
|
// Single sheet: render normally
|
|
@@ -262,7 +262,7 @@ export class DataFrameComponent extends BaseComponent<DataFrameState> {
|
|
|
262
262
|
* ═══════════════════════════════════════════════════ */
|
|
263
263
|
|
|
264
264
|
/**
|
|
265
|
-
* ✅
|
|
265
|
+
* ✅ FIXED: Render multiple Excel sheets as tabs
|
|
266
266
|
*/
|
|
267
267
|
private _renderMultiSheet(sheets: Record<string, DataFrame>, sourceName: string): void {
|
|
268
268
|
this.state.loading = false;
|
|
@@ -280,28 +280,33 @@ export class DataFrameComponent extends BaseComponent<DataFrameState> {
|
|
|
280
280
|
this._sheets.set(name, df);
|
|
281
281
|
});
|
|
282
282
|
|
|
283
|
-
// Create tabs
|
|
284
283
|
const sheetNames = Object.keys(sheets);
|
|
284
|
+
|
|
285
|
+
// ✅ FIX: Create tabs with EMPTY content first (just placeholders)
|
|
285
286
|
const tabs = new Tabs(`${this._id}-tabs`, {
|
|
286
287
|
tabs: sheetNames.map(name => ({
|
|
287
288
|
id: name,
|
|
288
289
|
label: name,
|
|
289
|
-
content: '' //
|
|
290
|
+
content: '' // Empty - we'll fill after render
|
|
290
291
|
})),
|
|
291
292
|
activeTab: sheetNames[0]
|
|
292
293
|
});
|
|
293
294
|
|
|
294
295
|
this._tabs = tabs;
|
|
295
296
|
|
|
296
|
-
// Render tabs
|
|
297
|
+
// Render tabs container
|
|
297
298
|
const tabsContainer = document.createElement('div');
|
|
298
299
|
tabsContainer.className = 'jux-dataframe-tabs';
|
|
299
300
|
wrapper.appendChild(tabsContainer);
|
|
301
|
+
|
|
302
|
+
// ✅ Render tabs NOW (creates all tab panels in DOM)
|
|
300
303
|
tabs.render(tabsContainer);
|
|
301
304
|
|
|
302
|
-
//
|
|
305
|
+
// ✅ NOW populate each tab with its DataFrame table (panels exist now)
|
|
303
306
|
sheetNames.forEach(sheetName => {
|
|
304
307
|
const df = sheets[sheetName];
|
|
308
|
+
|
|
309
|
+
// Create table
|
|
305
310
|
const table = new Table(`${this._id}-table-${sheetName}`, {
|
|
306
311
|
striped: this._tableOptions.striped,
|
|
307
312
|
hoverable: this._tableOptions.hoverable,
|
|
@@ -311,7 +316,7 @@ export class DataFrameComponent extends BaseComponent<DataFrameState> {
|
|
|
311
316
|
rowsPerPage: this._tableOptions.rowsPerPage
|
|
312
317
|
});
|
|
313
318
|
|
|
314
|
-
//
|
|
319
|
+
// Convert columns to ColumnDef[]
|
|
315
320
|
const columnDefs = df.columns.map(col => ({
|
|
316
321
|
key: col,
|
|
317
322
|
label: col
|
|
@@ -319,8 +324,15 @@ export class DataFrameComponent extends BaseComponent<DataFrameState> {
|
|
|
319
324
|
|
|
320
325
|
table.columns(columnDefs).rows(df.toRows());
|
|
321
326
|
|
|
322
|
-
//
|
|
323
|
-
|
|
327
|
+
// ✅ Find the tab panel (it exists now because tabs.render() was called)
|
|
328
|
+
const tabPanel = document.getElementById(`${this._id}-tabs-${sheetName}-panel`);
|
|
329
|
+
if (!tabPanel) {
|
|
330
|
+
console.error(`Tab panel not found: ${this._id}-tabs-${sheetName}-panel`);
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// ✅ Render table directly into tab panel
|
|
335
|
+
table.render(tabPanel);
|
|
324
336
|
|
|
325
337
|
// Add filter if enabled
|
|
326
338
|
if (this._tableOptions.filterable) {
|
|
@@ -357,13 +369,10 @@ export class DataFrameComponent extends BaseComponent<DataFrameState> {
|
|
|
357
369
|
table.rows(filtered.toRows());
|
|
358
370
|
});
|
|
359
371
|
|
|
360
|
-
// Insert filter
|
|
361
|
-
const
|
|
362
|
-
if (
|
|
363
|
-
|
|
364
|
-
if (tableWrapper) {
|
|
365
|
-
tabPanel.insertBefore(filterContainer, tableWrapper);
|
|
366
|
-
}
|
|
372
|
+
// ✅ Insert filter BEFORE the table wrapper (which exists now)
|
|
373
|
+
const tableWrapper = tabPanel.querySelector('.jux-table-wrapper');
|
|
374
|
+
if (tableWrapper) {
|
|
375
|
+
tabPanel.insertBefore(filterContainer, tableWrapper);
|
|
367
376
|
}
|
|
368
377
|
}
|
|
369
378
|
});
|
|
@@ -377,7 +386,6 @@ export class DataFrameComponent extends BaseComponent<DataFrameState> {
|
|
|
377
386
|
|
|
378
387
|
// Set first sheet as active DataFrame
|
|
379
388
|
this._df = sheets[sheetNames[0]];
|
|
380
|
-
this._table = (tabs as any)._tabsWrapper?.querySelector(`#${this._id}-table-${sheetNames[0]}`);
|
|
381
389
|
|
|
382
390
|
this._triggerCallback('load', this._df, null, this);
|
|
383
391
|
}
|
|
@@ -438,21 +446,21 @@ export class DataFrameComponent extends BaseComponent<DataFrameState> {
|
|
|
438
446
|
private _updateTable(): void {
|
|
439
447
|
if (!this._table || !this._df) return;
|
|
440
448
|
|
|
441
|
-
// ✅
|
|
449
|
+
// ✅ Convert string[] columns to ColumnDef[] with labels
|
|
442
450
|
const columnDefs = this._df.columns.map(col => ({
|
|
443
451
|
key: col,
|
|
444
|
-
label: col
|
|
452
|
+
label: col
|
|
445
453
|
}));
|
|
446
454
|
|
|
447
|
-
// ✅ Update
|
|
455
|
+
// ✅ Update columns and rows
|
|
448
456
|
this._table.columns(columnDefs).rows(this._df.toRows());
|
|
449
457
|
|
|
450
|
-
// ✅ Force table
|
|
451
|
-
const tableElement = this._table['_tableElement'];
|
|
458
|
+
// ✅ FIX: Force full table rebuild (including pagination)
|
|
459
|
+
const tableElement = this._table['_tableElement'];
|
|
452
460
|
if (tableElement) {
|
|
453
|
-
const wrapper = tableElement.closest('.jux-table-wrapper');
|
|
461
|
+
const wrapper = tableElement.closest('.jux-table-wrapper') as HTMLElement;
|
|
454
462
|
if (wrapper) {
|
|
455
|
-
// Clear
|
|
463
|
+
// Clear table content
|
|
456
464
|
tableElement.innerHTML = '';
|
|
457
465
|
|
|
458
466
|
// Rebuild header
|
|
@@ -466,6 +474,11 @@ export class DataFrameComponent extends BaseComponent<DataFrameState> {
|
|
|
466
474
|
|
|
467
475
|
// Re-wire events
|
|
468
476
|
(this._table as any)._wireTriggerEvents(tbody);
|
|
477
|
+
|
|
478
|
+
// ✅ FIX: Re-build pagination controls
|
|
479
|
+
if (this._tableOptions.paginated) {
|
|
480
|
+
(this._table as any)._updatePagination(wrapper, tbody);
|
|
481
|
+
}
|
|
469
482
|
}
|
|
470
483
|
}
|
|
471
484
|
}
|
|
@@ -545,6 +558,7 @@ export class DataFrameComponent extends BaseComponent<DataFrameState> {
|
|
|
545
558
|
const upload = new FileUpload(`${this._id}-upload`, uploadOpts);
|
|
546
559
|
|
|
547
560
|
this._uploadRef = upload;
|
|
561
|
+
// ✅ FIX: Use the SAME logic as fromUpload() to handle multi-sheet
|
|
548
562
|
this._pendingSource = async () => {
|
|
549
563
|
upload.bind('change', async (files: File[]) => {
|
|
550
564
|
if (!files || files.length === 0) return;
|
|
@@ -553,9 +567,30 @@ export class DataFrameComponent extends BaseComponent<DataFrameState> {
|
|
|
553
567
|
this._updateStatus('⏳ Parsing ' + file.name + '...', 'loading');
|
|
554
568
|
|
|
555
569
|
try {
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
570
|
+
// ✅ Check if multi-sheet Excel
|
|
571
|
+
const isExcel = file.name.toLowerCase().endsWith('.xlsx') ||
|
|
572
|
+
file.name.toLowerCase().endsWith('.xls');
|
|
573
|
+
|
|
574
|
+
if (isExcel) {
|
|
575
|
+
const sheets = await this._driver.streamFileMultiSheet(file);
|
|
576
|
+
const sheetNames = Object.keys(sheets);
|
|
577
|
+
|
|
578
|
+
// Store first sheet to IndexedDB
|
|
579
|
+
await this._driver.store(file.name, sheets[sheetNames[0]], { source: file.name });
|
|
580
|
+
|
|
581
|
+
if (sheetNames.length > 1) {
|
|
582
|
+
// ✅ Multi-sheet: render tabs
|
|
583
|
+
this._renderMultiSheet(sheets, file.name);
|
|
584
|
+
} else {
|
|
585
|
+
// Single sheet: render normally
|
|
586
|
+
this._setDataFrame(sheets[sheetNames[0]], file.name);
|
|
587
|
+
}
|
|
588
|
+
} else {
|
|
589
|
+
// CSV/TSV: single sheet
|
|
590
|
+
const df = await this._driver.streamFile(file);
|
|
591
|
+
await this._driver.store(file.name, df, { source: file.name });
|
|
592
|
+
this._setDataFrame(df, file.name);
|
|
593
|
+
}
|
|
559
594
|
} catch (err: any) {
|
|
560
595
|
this._triggerCallback('error', err.message, null, this);
|
|
561
596
|
this.state.loading = false;
|