juxscript 1.1.183 → 1.1.184
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.
|
@@ -97,6 +97,9 @@ export declare class DataFrameComponent extends BaseComponent<DataFrameState> {
|
|
|
97
97
|
private _setDataFrame;
|
|
98
98
|
private _updateTable;
|
|
99
99
|
private _showFilterInput;
|
|
100
|
+
/**
|
|
101
|
+
* ✅ NEW: Show settings modal to reshape CSV data
|
|
102
|
+
*/
|
|
100
103
|
private _showReshapeModal;
|
|
101
104
|
update(prop: string, value: any): void;
|
|
102
105
|
render(targetId?: string | HTMLElement | BaseComponent<any>): this;
|
|
@@ -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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"}
|
|
@@ -481,9 +481,121 @@ export class DataFrameComponent extends BaseComponent {
|
|
|
481
481
|
this._table?.rows(filtered.toRows());
|
|
482
482
|
});
|
|
483
483
|
}
|
|
484
|
+
/**
|
|
485
|
+
* ✅ NEW: Show settings modal to reshape CSV data
|
|
486
|
+
*/
|
|
484
487
|
_showReshapeModal() {
|
|
485
|
-
|
|
486
|
-
|
|
488
|
+
if (!this._rawFileData)
|
|
489
|
+
return;
|
|
490
|
+
const modal = document.createElement('div');
|
|
491
|
+
modal.className = 'jux-modal-overlay';
|
|
492
|
+
modal.innerHTML = `
|
|
493
|
+
<div class="jux-modal" style="max-width: 800px;">
|
|
494
|
+
<div class="jux-modal-header">
|
|
495
|
+
<div class="jux-modal-header-title">Data Import Settings</div>
|
|
496
|
+
<button class="jux-modal-close" id="${this._id}-modal-close">×</button>
|
|
497
|
+
</div>
|
|
498
|
+
<div class="jux-modal-content" style="padding: 1.5rem;">
|
|
499
|
+
<div style="margin-bottom: 1rem;">
|
|
500
|
+
<label style="display: block; font-weight: 600; margin-bottom: 0.5rem;">Delimiter</label>
|
|
501
|
+
<select id="${this._id}-delimiter" class="jux-input-element" style="width: 100%;">
|
|
502
|
+
<option value=",">Comma (,)</option>
|
|
503
|
+
<option value="|">Pipe (|)</option>
|
|
504
|
+
<option value="\t">Tab (\\t)</option>
|
|
505
|
+
<option value=";">Semicolon (;)</option>
|
|
506
|
+
</select>
|
|
507
|
+
</div>
|
|
508
|
+
|
|
509
|
+
<div style="margin-bottom: 1rem;">
|
|
510
|
+
<label style="display: block; font-weight: 600; margin-bottom: 0.5rem;">Header Row (0-based)</label>
|
|
511
|
+
<input type="number" id="${this._id}-header-row" class="jux-input-element" value="0" min="0" max="50" style="width: 100%;" />
|
|
512
|
+
</div>
|
|
513
|
+
|
|
514
|
+
<div style="margin-bottom: 1rem;">
|
|
515
|
+
<label style="display: block; font-weight: 600; margin-bottom: 0.5rem;">Skip Rows Before Header</label>
|
|
516
|
+
<input type="number" id="${this._id}-skip-rows" class="jux-input-element" value="0" min="0" max="50" style="width: 100%;" />
|
|
517
|
+
</div>
|
|
518
|
+
|
|
519
|
+
<div style="border: 1px solid hsl(var(--border)); border-radius: var(--radius); padding: 1rem; background: hsl(var(--muted) / 0.3); max-height: 300px; overflow-y: auto;">
|
|
520
|
+
<div style="font-weight: 600; margin-bottom: 0.5rem; color: hsl(var(--foreground));">Preview</div>
|
|
521
|
+
<div id="${this._id}-preview" style="font-family: monospace; font-size: 0.75rem; white-space: pre; color: hsl(var(--muted-foreground));"></div>
|
|
522
|
+
</div>
|
|
523
|
+
</div>
|
|
524
|
+
<div class="jux-modal-footer">
|
|
525
|
+
<button id="${this._id}-cancel-reshape" class="jux-button jux-button-ghost">Cancel</button>
|
|
526
|
+
<button id="${this._id}-apply-reshape" class="jux-button">Apply & Re-import</button>
|
|
527
|
+
</div>
|
|
528
|
+
</div>
|
|
529
|
+
`;
|
|
530
|
+
document.body.appendChild(modal);
|
|
531
|
+
const delimiterSelect = document.getElementById(`${this._id}-delimiter`);
|
|
532
|
+
const headerRowInput = document.getElementById(`${this._id}-header-row`);
|
|
533
|
+
const skipRowsInput = document.getElementById(`${this._id}-skip-rows`);
|
|
534
|
+
const previewDiv = document.getElementById(`${this._id}-preview`);
|
|
535
|
+
// ✅ Auto-detect initial values
|
|
536
|
+
if (this._rawFileData.text) {
|
|
537
|
+
const detected = this._driver._detectDelimiter(this._rawFileData.text);
|
|
538
|
+
delimiterSelect.value = detected === '\t' ? '\\t' : detected;
|
|
539
|
+
const headerRow = this._driver._detectHeaderRow(this._rawFileData.text, detected);
|
|
540
|
+
headerRowInput.value = String(headerRow);
|
|
541
|
+
}
|
|
542
|
+
// ✅ Update preview on changes
|
|
543
|
+
const updatePreview = async () => {
|
|
544
|
+
if (!this._rawFileData?.text)
|
|
545
|
+
return;
|
|
546
|
+
const delim = delimiterSelect.value === '\\t' ? '\t' : delimiterSelect.value;
|
|
547
|
+
const headerRow = parseInt(headerRowInput.value) || 0;
|
|
548
|
+
const skipRows = parseInt(skipRowsInput.value) || 0;
|
|
549
|
+
try {
|
|
550
|
+
const df = this._driver.parseCSV(this._rawFileData.text, {
|
|
551
|
+
delimiter: delim,
|
|
552
|
+
headerRow,
|
|
553
|
+
skipRows,
|
|
554
|
+
hasHeader: true,
|
|
555
|
+
maxRows: 10 // Preview first 10 rows
|
|
556
|
+
});
|
|
557
|
+
const preview = df.toRows().map((row, i) => {
|
|
558
|
+
const cols = Object.values(row).map(v => String(v).padEnd(20)).join(' | ');
|
|
559
|
+
return `${i === 0 ? '📌 ' : ' '}${cols}`;
|
|
560
|
+
}).join('\n');
|
|
561
|
+
previewDiv.textContent = `Columns: ${df.columns.join(' | ')}\n\n${preview}`;
|
|
562
|
+
}
|
|
563
|
+
catch (err) {
|
|
564
|
+
previewDiv.textContent = `⚠️ Error: ${err.message}`;
|
|
565
|
+
}
|
|
566
|
+
};
|
|
567
|
+
delimiterSelect.addEventListener('change', updatePreview);
|
|
568
|
+
headerRowInput.addEventListener('input', updatePreview);
|
|
569
|
+
skipRowsInput.addEventListener('input', updatePreview);
|
|
570
|
+
updatePreview();
|
|
571
|
+
// ✅ Apply button
|
|
572
|
+
document.getElementById(`${this._id}-apply-reshape`).addEventListener('click', async () => {
|
|
573
|
+
if (!this._rawFileData?.text)
|
|
574
|
+
return;
|
|
575
|
+
const delim = delimiterSelect.value === '\\t' ? '\t' : delimiterSelect.value;
|
|
576
|
+
const headerRow = parseInt(headerRowInput.value) || 0;
|
|
577
|
+
const skipRows = parseInt(skipRowsInput.value) || 0;
|
|
578
|
+
this.state.loading = true;
|
|
579
|
+
this._updateStatus('⏳ Re-parsing with new settings...', 'loading');
|
|
580
|
+
try {
|
|
581
|
+
const df = this._driver.parseCSV(this._rawFileData.text, {
|
|
582
|
+
delimiter: delim,
|
|
583
|
+
headerRow,
|
|
584
|
+
skipRows,
|
|
585
|
+
hasHeader: true
|
|
586
|
+
});
|
|
587
|
+
await this._driver.store(this._rawFileData.file.name, df, { source: this._rawFileData.file.name });
|
|
588
|
+
this._setDataFrame(df, this._rawFileData.file.name);
|
|
589
|
+
modal.remove();
|
|
590
|
+
}
|
|
591
|
+
catch (err) {
|
|
592
|
+
this._updateStatus(`❌ ${err.message}`, 'error');
|
|
593
|
+
}
|
|
594
|
+
});
|
|
595
|
+
// ✅ Cancel/Close buttons
|
|
596
|
+
const closeModal = () => modal.remove();
|
|
597
|
+
document.getElementById(`${this._id}-cancel-reshape`).addEventListener('click', closeModal);
|
|
598
|
+
document.getElementById(`${this._id}-modal-close`).addEventListener('click', closeModal);
|
|
487
599
|
}
|
|
488
600
|
update(prop, value) { }
|
|
489
601
|
/* ═══════════════════════════════════════════════════
|
|
@@ -596,9 +596,135 @@ export class DataFrameComponent extends BaseComponent<DataFrameState> {
|
|
|
596
596
|
});
|
|
597
597
|
}
|
|
598
598
|
|
|
599
|
+
/**
|
|
600
|
+
* ✅ NEW: Show settings modal to reshape CSV data
|
|
601
|
+
*/
|
|
599
602
|
private _showReshapeModal(): void {
|
|
600
|
-
|
|
601
|
-
|
|
603
|
+
if (!this._rawFileData) return;
|
|
604
|
+
|
|
605
|
+
const modal = document.createElement('div');
|
|
606
|
+
modal.className = 'jux-modal-overlay';
|
|
607
|
+
modal.innerHTML = `
|
|
608
|
+
<div class="jux-modal" style="max-width: 800px;">
|
|
609
|
+
<div class="jux-modal-header">
|
|
610
|
+
<div class="jux-modal-header-title">Data Import Settings</div>
|
|
611
|
+
<button class="jux-modal-close" id="${this._id}-modal-close">×</button>
|
|
612
|
+
</div>
|
|
613
|
+
<div class="jux-modal-content" style="padding: 1.5rem;">
|
|
614
|
+
<div style="margin-bottom: 1rem;">
|
|
615
|
+
<label style="display: block; font-weight: 600; margin-bottom: 0.5rem;">Delimiter</label>
|
|
616
|
+
<select id="${this._id}-delimiter" class="jux-input-element" style="width: 100%;">
|
|
617
|
+
<option value=",">Comma (,)</option>
|
|
618
|
+
<option value="|">Pipe (|)</option>
|
|
619
|
+
<option value="\t">Tab (\\t)</option>
|
|
620
|
+
<option value=";">Semicolon (;)</option>
|
|
621
|
+
</select>
|
|
622
|
+
</div>
|
|
623
|
+
|
|
624
|
+
<div style="margin-bottom: 1rem;">
|
|
625
|
+
<label style="display: block; font-weight: 600; margin-bottom: 0.5rem;">Header Row (0-based)</label>
|
|
626
|
+
<input type="number" id="${this._id}-header-row" class="jux-input-element" value="0" min="0" max="50" style="width: 100%;" />
|
|
627
|
+
</div>
|
|
628
|
+
|
|
629
|
+
<div style="margin-bottom: 1rem;">
|
|
630
|
+
<label style="display: block; font-weight: 600; margin-bottom: 0.5rem;">Skip Rows Before Header</label>
|
|
631
|
+
<input type="number" id="${this._id}-skip-rows" class="jux-input-element" value="0" min="0" max="50" style="width: 100%;" />
|
|
632
|
+
</div>
|
|
633
|
+
|
|
634
|
+
<div style="border: 1px solid hsl(var(--border)); border-radius: var(--radius); padding: 1rem; background: hsl(var(--muted) / 0.3); max-height: 300px; overflow-y: auto;">
|
|
635
|
+
<div style="font-weight: 600; margin-bottom: 0.5rem; color: hsl(var(--foreground));">Preview</div>
|
|
636
|
+
<div id="${this._id}-preview" style="font-family: monospace; font-size: 0.75rem; white-space: pre; color: hsl(var(--muted-foreground));"></div>
|
|
637
|
+
</div>
|
|
638
|
+
</div>
|
|
639
|
+
<div class="jux-modal-footer">
|
|
640
|
+
<button id="${this._id}-cancel-reshape" class="jux-button jux-button-ghost">Cancel</button>
|
|
641
|
+
<button id="${this._id}-apply-reshape" class="jux-button">Apply & Re-import</button>
|
|
642
|
+
</div>
|
|
643
|
+
</div>
|
|
644
|
+
`;
|
|
645
|
+
|
|
646
|
+
document.body.appendChild(modal);
|
|
647
|
+
|
|
648
|
+
const delimiterSelect = document.getElementById(`${this._id}-delimiter`) as HTMLSelectElement;
|
|
649
|
+
const headerRowInput = document.getElementById(`${this._id}-header-row`) as HTMLInputElement;
|
|
650
|
+
const skipRowsInput = document.getElementById(`${this._id}-skip-rows`) as HTMLInputElement;
|
|
651
|
+
const previewDiv = document.getElementById(`${this._id}-preview`)!;
|
|
652
|
+
|
|
653
|
+
// ✅ Auto-detect initial values
|
|
654
|
+
if (this._rawFileData.text) {
|
|
655
|
+
const detected = (this._driver as any)._detectDelimiter(this._rawFileData.text);
|
|
656
|
+
delimiterSelect.value = detected === '\t' ? '\\t' : detected;
|
|
657
|
+
|
|
658
|
+
const headerRow = (this._driver as any)._detectHeaderRow(this._rawFileData.text, detected);
|
|
659
|
+
headerRowInput.value = String(headerRow);
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
// ✅ Update preview on changes
|
|
663
|
+
const updatePreview = async () => {
|
|
664
|
+
if (!this._rawFileData?.text) return;
|
|
665
|
+
|
|
666
|
+
const delim = delimiterSelect.value === '\\t' ? '\t' : delimiterSelect.value;
|
|
667
|
+
const headerRow = parseInt(headerRowInput.value) || 0;
|
|
668
|
+
const skipRows = parseInt(skipRowsInput.value) || 0;
|
|
669
|
+
|
|
670
|
+
try {
|
|
671
|
+
const df = this._driver.parseCSV(this._rawFileData.text, {
|
|
672
|
+
delimiter: delim,
|
|
673
|
+
headerRow,
|
|
674
|
+
skipRows,
|
|
675
|
+
hasHeader: true,
|
|
676
|
+
maxRows: 10 // Preview first 10 rows
|
|
677
|
+
});
|
|
678
|
+
|
|
679
|
+
const preview = df.toRows().map((row, i) => {
|
|
680
|
+
const cols = Object.values(row).map(v => String(v).padEnd(20)).join(' | ');
|
|
681
|
+
return `${i === 0 ? '📌 ' : ' '}${cols}`;
|
|
682
|
+
}).join('\n');
|
|
683
|
+
|
|
684
|
+
previewDiv.textContent = `Columns: ${df.columns.join(' | ')}\n\n${preview}`;
|
|
685
|
+
} catch (err: any) {
|
|
686
|
+
previewDiv.textContent = `⚠️ Error: ${err.message}`;
|
|
687
|
+
}
|
|
688
|
+
};
|
|
689
|
+
|
|
690
|
+
delimiterSelect.addEventListener('change', updatePreview);
|
|
691
|
+
headerRowInput.addEventListener('input', updatePreview);
|
|
692
|
+
skipRowsInput.addEventListener('input', updatePreview);
|
|
693
|
+
|
|
694
|
+
updatePreview();
|
|
695
|
+
|
|
696
|
+
// ✅ Apply button
|
|
697
|
+
document.getElementById(`${this._id}-apply-reshape`)!.addEventListener('click', async () => {
|
|
698
|
+
if (!this._rawFileData?.text) return;
|
|
699
|
+
|
|
700
|
+
const delim = delimiterSelect.value === '\\t' ? '\t' : delimiterSelect.value;
|
|
701
|
+
const headerRow = parseInt(headerRowInput.value) || 0;
|
|
702
|
+
const skipRows = parseInt(skipRowsInput.value) || 0;
|
|
703
|
+
|
|
704
|
+
this.state.loading = true;
|
|
705
|
+
this._updateStatus('⏳ Re-parsing with new settings...', 'loading');
|
|
706
|
+
|
|
707
|
+
try {
|
|
708
|
+
const df = this._driver.parseCSV(this._rawFileData.text, {
|
|
709
|
+
delimiter: delim,
|
|
710
|
+
headerRow,
|
|
711
|
+
skipRows,
|
|
712
|
+
hasHeader: true
|
|
713
|
+
});
|
|
714
|
+
|
|
715
|
+
await this._driver.store(this._rawFileData.file.name, df, { source: this._rawFileData.file.name });
|
|
716
|
+
this._setDataFrame(df, this._rawFileData.file.name);
|
|
717
|
+
|
|
718
|
+
modal.remove();
|
|
719
|
+
} catch (err: any) {
|
|
720
|
+
this._updateStatus(`❌ ${err.message}`, 'error');
|
|
721
|
+
}
|
|
722
|
+
});
|
|
723
|
+
|
|
724
|
+
// ✅ Cancel/Close buttons
|
|
725
|
+
const closeModal = () => modal.remove();
|
|
726
|
+
document.getElementById(`${this._id}-cancel-reshape`)!.addEventListener('click', closeModal);
|
|
727
|
+
document.getElementById(`${this._id}-modal-close`)!.addEventListener('click', closeModal);
|
|
602
728
|
}
|
|
603
729
|
|
|
604
730
|
update(prop: string, value: any): void { }
|