juxscript 1.1.223 → 1.1.225
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.
|
@@ -172,9 +172,10 @@ export declare class DataFrameComponent extends BaseComponent<DataFrameState> {
|
|
|
172
172
|
private _updateStatus;
|
|
173
173
|
private _setDataFrame;
|
|
174
174
|
/**
|
|
175
|
-
* Update the collapsible summary text
|
|
175
|
+
* Update the collapsible summary text and add settings button
|
|
176
176
|
*/
|
|
177
177
|
private _updateSummary;
|
|
178
|
+
private _appendSettingsButton;
|
|
178
179
|
private _detectMalformedData;
|
|
179
180
|
private _showReshapeModal;
|
|
180
181
|
private _cleanupReshapeModal;
|
|
@@ -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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"}
|
|
@@ -253,8 +253,18 @@ export class DataFrameComponent extends BaseComponent {
|
|
|
253
253
|
if (existingTabs)
|
|
254
254
|
existingTabs.remove();
|
|
255
255
|
}
|
|
256
|
-
//
|
|
257
|
-
this.
|
|
256
|
+
// ✅ Hide details element when cleared
|
|
257
|
+
if (this._collapsible && this._detailsElement) {
|
|
258
|
+
this._detailsElement.style.display = 'none';
|
|
259
|
+
}
|
|
260
|
+
// ✅ Hide status when cleared (for inline upload mode)
|
|
261
|
+
const statusEl = document.getElementById(`${this._id}-status`);
|
|
262
|
+
if (statusEl && this._inlineUpload) {
|
|
263
|
+
statusEl.style.display = 'none';
|
|
264
|
+
}
|
|
265
|
+
else if (statusEl) {
|
|
266
|
+
this._updateStatus('No data loaded.', 'empty');
|
|
267
|
+
}
|
|
258
268
|
return this;
|
|
259
269
|
}
|
|
260
270
|
/* ═══════════════════════════════════════════════════
|
|
@@ -533,11 +543,7 @@ export class DataFrameComponent extends BaseComponent {
|
|
|
533
543
|
const el = document.getElementById(`${this._id}-status`);
|
|
534
544
|
if (!el)
|
|
535
545
|
return;
|
|
536
|
-
//
|
|
537
|
-
if (this._collapsible) {
|
|
538
|
-
el.style.display = 'none';
|
|
539
|
-
return;
|
|
540
|
-
}
|
|
546
|
+
// Always show status (inline with upload button)
|
|
541
547
|
el.style.display = '';
|
|
542
548
|
el.className = 'jux-dataframe-status';
|
|
543
549
|
if (type)
|
|
@@ -583,66 +589,112 @@ export class DataFrameComponent extends BaseComponent {
|
|
|
583
589
|
const columnDefs = this._df.columns.map(col => ({ key: col, label: col }));
|
|
584
590
|
this._table.columns(columnDefs).rows(this._df.toRows());
|
|
585
591
|
}
|
|
586
|
-
// ✅ Update summary if collapsible
|
|
587
|
-
this._updateSummary();
|
|
588
592
|
const isMalformed = this._detectMalformedData(this._df);
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
593
|
+
// ✅ Show the details element now that data is loaded
|
|
594
|
+
if (this._collapsible && this._detailsElement) {
|
|
595
|
+
this._detailsElement.style.display = '';
|
|
596
|
+
this._updateSummary(isMalformed);
|
|
597
|
+
}
|
|
598
|
+
// ✅ Update status (for non-collapsible mode)
|
|
599
|
+
if (!this._collapsible) {
|
|
600
|
+
if (isMalformed && this._rawFileData) {
|
|
601
|
+
this._updateStatus(`${sourceName} — ${this._df.height} rows × ${this._df.width} cols`, 'warning');
|
|
602
|
+
this._appendSettingsButton('Fix Import Settings', 'warning');
|
|
603
|
+
}
|
|
604
|
+
else {
|
|
605
|
+
this._updateStatus(`${sourceName} — ${this._df.height} rows × ${this._df.width} cols`, 'success');
|
|
606
|
+
if (this._rawFileData) {
|
|
607
|
+
this._appendSettingsButton('Import Settings', 'ghost');
|
|
600
608
|
}
|
|
601
|
-
}
|
|
609
|
+
}
|
|
602
610
|
}
|
|
603
611
|
else {
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
if (statusEl) {
|
|
609
|
-
const settingsBtn = document.createElement('button');
|
|
610
|
-
settingsBtn.textContent = 'Import Settings';
|
|
611
|
-
settingsBtn.className = 'jux-button jux-button-sm jux-button-ghost';
|
|
612
|
-
settingsBtn.style.marginLeft = '0.5rem';
|
|
613
|
-
settingsBtn.addEventListener('click', () => this._showReshapeModal());
|
|
614
|
-
statusEl.appendChild(settingsBtn);
|
|
615
|
-
}
|
|
616
|
-
});
|
|
612
|
+
// ✅ For collapsible mode, hide the status bar
|
|
613
|
+
const statusEl = document.getElementById(`${this._id}-status`);
|
|
614
|
+
if (statusEl) {
|
|
615
|
+
statusEl.style.display = 'none';
|
|
617
616
|
}
|
|
618
617
|
}
|
|
619
618
|
this._triggerCallback('load', this._df, null, this);
|
|
620
619
|
}
|
|
621
620
|
/**
|
|
622
|
-
* Update the collapsible summary text
|
|
621
|
+
* Update the collapsible summary text and add settings button
|
|
623
622
|
*/
|
|
624
|
-
_updateSummary() {
|
|
623
|
+
_updateSummary(isMalformed) {
|
|
625
624
|
if (!this._collapsible || !this._detailsElement)
|
|
626
625
|
return;
|
|
627
|
-
const
|
|
628
|
-
if (!
|
|
629
|
-
return;
|
|
630
|
-
if (!this._df) {
|
|
631
|
-
summaryTextEl.textContent = 'No data loaded';
|
|
626
|
+
const summaryEl = this._detailsElement.querySelector('.jux-dataframe-summary');
|
|
627
|
+
if (!summaryEl)
|
|
632
628
|
return;
|
|
629
|
+
// Get or detect malformed status
|
|
630
|
+
const malformed = isMalformed ?? (this._df ? this._detectMalformedData(this._df) : false);
|
|
631
|
+
// Update text
|
|
632
|
+
const summaryTextEl = summaryEl.querySelector('.jux-dataframe-summary-text');
|
|
633
|
+
if (summaryTextEl) {
|
|
634
|
+
if (!this._df) {
|
|
635
|
+
summaryTextEl.textContent = 'No data loaded';
|
|
636
|
+
}
|
|
637
|
+
else if (this._summaryTemplate) {
|
|
638
|
+
summaryTextEl.textContent = this._summaryTemplate(this._df);
|
|
639
|
+
}
|
|
640
|
+
else {
|
|
641
|
+
const suffix = malformed ? ' ⚠️' : '';
|
|
642
|
+
summaryTextEl.textContent = `${this.state.sourceName || 'Data'} — ${this._df.height} rows × ${this._df.width} cols${suffix}`;
|
|
643
|
+
}
|
|
633
644
|
}
|
|
634
|
-
if
|
|
635
|
-
|
|
645
|
+
// ✅ Add settings button to summary if we have raw file data
|
|
646
|
+
let settingsBtn = summaryEl.querySelector('.jux-dataframe-summary-settings');
|
|
647
|
+
if (this._rawFileData && this._df) {
|
|
648
|
+
if (!settingsBtn) {
|
|
649
|
+
settingsBtn = document.createElement('button');
|
|
650
|
+
settingsBtn.className = 'jux-dataframe-summary-settings';
|
|
651
|
+
settingsBtn.type = 'button';
|
|
652
|
+
settingsBtn.addEventListener('click', (e) => {
|
|
653
|
+
e.stopPropagation(); // Don't toggle the details
|
|
654
|
+
this._showReshapeModal();
|
|
655
|
+
});
|
|
656
|
+
summaryEl.appendChild(settingsBtn);
|
|
657
|
+
}
|
|
658
|
+
// Update button text/style based on malformed status
|
|
659
|
+
if (malformed) {
|
|
660
|
+
settingsBtn.textContent = '⚙️ Fix Settings';
|
|
661
|
+
settingsBtn.className = 'jux-dataframe-summary-settings jux-dataframe-summary-settings-warning';
|
|
662
|
+
}
|
|
663
|
+
else {
|
|
664
|
+
settingsBtn.textContent = '⚙️ Settings';
|
|
665
|
+
settingsBtn.className = 'jux-dataframe-summary-settings';
|
|
666
|
+
}
|
|
636
667
|
}
|
|
637
|
-
else {
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
summaryTextEl.textContent = `${this.state.sourceName || 'Data'} — ${this._df.height} rows × ${this._df.width} cols${suffix}`;
|
|
668
|
+
else if (settingsBtn) {
|
|
669
|
+
// Remove settings button if no raw file data
|
|
670
|
+
settingsBtn.remove();
|
|
641
671
|
}
|
|
642
672
|
}
|
|
643
673
|
/* ═══════════════════════════════════════════════════
|
|
644
674
|
* MALFORMED DATA DETECTION
|
|
645
675
|
* ═══════════════════════════════════════════════════ */
|
|
676
|
+
_appendSettingsButton(label, variant) {
|
|
677
|
+
const statusEl = document.getElementById(`${this._id}-status`);
|
|
678
|
+
if (!statusEl)
|
|
679
|
+
return;
|
|
680
|
+
// Remove existing settings button if any
|
|
681
|
+
const existing = statusEl.querySelector('.jux-dataframe-settings-btn');
|
|
682
|
+
if (existing)
|
|
683
|
+
existing.remove();
|
|
684
|
+
const btn = document.createElement('button');
|
|
685
|
+
btn.className = `jux-dataframe-settings-btn jux-dataframe-settings-btn-${variant}`;
|
|
686
|
+
btn.type = 'button';
|
|
687
|
+
btn.textContent = `⚙️ ${label}`;
|
|
688
|
+
btn.style.marginLeft = '8px';
|
|
689
|
+
btn.style.cursor = 'pointer';
|
|
690
|
+
btn.style.fontSize = '0.8rem';
|
|
691
|
+
btn.style.padding = '2px 8px';
|
|
692
|
+
btn.style.borderRadius = 'var(--radius, 4px)';
|
|
693
|
+
btn.style.border = '1px solid hsl(var(--border))';
|
|
694
|
+
btn.style.background = variant === 'warning' ? 'hsl(38 92% 50% / 0.15)' : 'transparent';
|
|
695
|
+
btn.addEventListener('click', () => this._showReshapeModal());
|
|
696
|
+
statusEl.appendChild(btn);
|
|
697
|
+
}
|
|
646
698
|
_detectMalformedData(df) {
|
|
647
699
|
const columns = df.columns;
|
|
648
700
|
const rows = df.toRows();
|
|
@@ -1065,11 +1117,21 @@ export class DataFrameComponent extends BaseComponent {
|
|
|
1065
1117
|
await this._handleFile(files[0]);
|
|
1066
1118
|
});
|
|
1067
1119
|
};
|
|
1120
|
+
const uploadRow = document.createElement('div');
|
|
1121
|
+
uploadRow.className = 'jux-dataframe-upload-row';
|
|
1068
1122
|
const uploadContainer = document.createElement('div');
|
|
1069
1123
|
uploadContainer.className = 'jux-dataframe-upload';
|
|
1070
1124
|
uploadContainer.id = `${this._id}-upload-container`;
|
|
1071
|
-
|
|
1072
|
-
// ✅
|
|
1125
|
+
uploadRow.appendChild(uploadContainer);
|
|
1126
|
+
// ✅ Status bar INLINE in the same row
|
|
1127
|
+
if (this._showStatus) {
|
|
1128
|
+
const statusBar = document.createElement('div');
|
|
1129
|
+
statusBar.className = 'jux-dataframe-status jux-dataframe-status-inline';
|
|
1130
|
+
statusBar.id = `${this._id}-status`;
|
|
1131
|
+
statusBar.style.display = 'none'; // Hidden until needed
|
|
1132
|
+
uploadRow.appendChild(statusBar);
|
|
1133
|
+
}
|
|
1134
|
+
uploadArea.appendChild(uploadRow);
|
|
1073
1135
|
if (this._uploadDescription) {
|
|
1074
1136
|
const descEl = document.createElement('div');
|
|
1075
1137
|
descEl.className = 'jux-dataframe-upload-description';
|
|
@@ -1082,30 +1144,22 @@ export class DataFrameComponent extends BaseComponent {
|
|
|
1082
1144
|
}
|
|
1083
1145
|
else {
|
|
1084
1146
|
container.appendChild(wrapper);
|
|
1147
|
+
// Status bar for non-upload mode
|
|
1148
|
+
if (this._showStatus) {
|
|
1149
|
+
const statusBar = document.createElement('div');
|
|
1150
|
+
statusBar.className = 'jux-dataframe-status jux-dataframe-status-empty';
|
|
1151
|
+
statusBar.id = `${this._id}-status`;
|
|
1152
|
+
statusBar.textContent = 'No data loaded.';
|
|
1153
|
+
wrapper.appendChild(statusBar);
|
|
1154
|
+
}
|
|
1085
1155
|
}
|
|
1086
|
-
// ✅
|
|
1087
|
-
if (this._showStatus && !this._collapsible) {
|
|
1088
|
-
const statusBar = document.createElement('div');
|
|
1089
|
-
statusBar.className = 'jux-dataframe-status jux-dataframe-status-empty';
|
|
1090
|
-
statusBar.id = `${this._id}-status`;
|
|
1091
|
-
statusBar.textContent = 'No data loaded.';
|
|
1092
|
-
wrapper.appendChild(statusBar);
|
|
1093
|
-
}
|
|
1094
|
-
else if (this._showStatus && this._collapsible) {
|
|
1095
|
-
// ✅ Hidden status bar still exists so _updateStatus() calls don't throw,
|
|
1096
|
-
// but it's invisible — summary handles display instead.
|
|
1097
|
-
const statusBar = document.createElement('div');
|
|
1098
|
-
statusBar.className = 'jux-dataframe-status jux-dataframe-status-empty';
|
|
1099
|
-
statusBar.id = `${this._id}-status`;
|
|
1100
|
-
statusBar.style.display = 'none';
|
|
1101
|
-
wrapper.appendChild(statusBar);
|
|
1102
|
-
}
|
|
1103
|
-
// ✅ Collapsible details wrapper
|
|
1156
|
+
// ✅ Collapsible details wrapper - HIDDEN until data loads
|
|
1104
1157
|
let tableContainer;
|
|
1105
1158
|
if (this._collapsible) {
|
|
1106
1159
|
const details = document.createElement('details');
|
|
1107
1160
|
details.className = 'jux-dataframe-details';
|
|
1108
1161
|
details.open = !this._collapsed;
|
|
1162
|
+
details.style.display = 'none'; // Hidden until data loads
|
|
1109
1163
|
this._detailsElement = details;
|
|
1110
1164
|
const summary = document.createElement('summary');
|
|
1111
1165
|
summary.className = 'jux-dataframe-summary';
|
|
@@ -1115,7 +1169,6 @@ export class DataFrameComponent extends BaseComponent {
|
|
|
1115
1169
|
summary.appendChild(chevron);
|
|
1116
1170
|
const textSpan = document.createElement('span');
|
|
1117
1171
|
textSpan.className = 'jux-dataframe-summary-text';
|
|
1118
|
-
textSpan.textContent = 'No data loaded';
|
|
1119
1172
|
summary.appendChild(textSpan);
|
|
1120
1173
|
details.appendChild(summary);
|
|
1121
1174
|
const content = document.createElement('div');
|
|
@@ -1123,7 +1176,6 @@ export class DataFrameComponent extends BaseComponent {
|
|
|
1123
1176
|
details.appendChild(content);
|
|
1124
1177
|
wrapper.appendChild(details);
|
|
1125
1178
|
tableContainer = content;
|
|
1126
|
-
// Track toggle state
|
|
1127
1179
|
details.addEventListener('toggle', () => {
|
|
1128
1180
|
this._collapsed = !details.open;
|
|
1129
1181
|
});
|
|
@@ -310,8 +310,18 @@ export class DataFrameComponent extends BaseComponent<DataFrameState> {
|
|
|
310
310
|
if (existingTabs) existingTabs.remove();
|
|
311
311
|
}
|
|
312
312
|
|
|
313
|
-
//
|
|
314
|
-
this.
|
|
313
|
+
// ✅ Hide details element when cleared
|
|
314
|
+
if (this._collapsible && this._detailsElement) {
|
|
315
|
+
this._detailsElement.style.display = 'none';
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// ✅ Hide status when cleared (for inline upload mode)
|
|
319
|
+
const statusEl = document.getElementById(`${this._id}-status`);
|
|
320
|
+
if (statusEl && this._inlineUpload) {
|
|
321
|
+
statusEl.style.display = 'none';
|
|
322
|
+
} else if (statusEl) {
|
|
323
|
+
this._updateStatus('No data loaded.', 'empty');
|
|
324
|
+
}
|
|
315
325
|
|
|
316
326
|
return this;
|
|
317
327
|
}
|
|
@@ -648,12 +658,7 @@ export class DataFrameComponent extends BaseComponent<DataFrameState> {
|
|
|
648
658
|
const el = document.getElementById(`${this._id}-status`);
|
|
649
659
|
if (!el) return;
|
|
650
660
|
|
|
651
|
-
//
|
|
652
|
-
if (this._collapsible) {
|
|
653
|
-
el.style.display = 'none';
|
|
654
|
-
return;
|
|
655
|
-
}
|
|
656
|
-
|
|
661
|
+
// Always show status (inline with upload button)
|
|
657
662
|
el.style.display = '';
|
|
658
663
|
el.className = 'jux-dataframe-status';
|
|
659
664
|
if (type) el.classList.add(`jux-dataframe-status-${type}`);
|
|
@@ -705,44 +710,36 @@ export class DataFrameComponent extends BaseComponent<DataFrameState> {
|
|
|
705
710
|
this._table.columns(columnDefs).rows(this._df.toRows());
|
|
706
711
|
}
|
|
707
712
|
|
|
708
|
-
// ✅ Update summary if collapsible
|
|
709
|
-
this._updateSummary();
|
|
710
|
-
|
|
711
713
|
const isMalformed = this._detectMalformedData(this._df!);
|
|
712
714
|
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
715
|
+
// ✅ Show the details element now that data is loaded
|
|
716
|
+
if (this._collapsible && this._detailsElement) {
|
|
717
|
+
this._detailsElement.style.display = '';
|
|
718
|
+
this._updateSummary(isMalformed);
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
// ✅ Update status (for non-collapsible mode)
|
|
722
|
+
if (!this._collapsible) {
|
|
723
|
+
if (isMalformed && this._rawFileData) {
|
|
724
|
+
this._updateStatus(
|
|
725
|
+
`${sourceName} — ${this._df!.height} rows × ${this._df!.width} cols`,
|
|
726
|
+
'warning'
|
|
727
|
+
);
|
|
728
|
+
this._appendSettingsButton('Fix Import Settings', 'warning');
|
|
729
|
+
} else {
|
|
730
|
+
this._updateStatus(
|
|
731
|
+
`${sourceName} — ${this._df!.height} rows × ${this._df!.width} cols`,
|
|
732
|
+
'success'
|
|
733
|
+
);
|
|
734
|
+
if (this._rawFileData) {
|
|
735
|
+
this._appendSettingsButton('Import Settings', 'ghost');
|
|
727
736
|
}
|
|
728
|
-
}
|
|
737
|
+
}
|
|
729
738
|
} else {
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
if (this._rawFileData) {
|
|
735
|
-
requestAnimationFrame(() => {
|
|
736
|
-
const statusEl = document.getElementById(`${this._id}-status`);
|
|
737
|
-
if (statusEl) {
|
|
738
|
-
const settingsBtn = document.createElement('button');
|
|
739
|
-
settingsBtn.textContent = 'Import Settings';
|
|
740
|
-
settingsBtn.className = 'jux-button jux-button-sm jux-button-ghost';
|
|
741
|
-
settingsBtn.style.marginLeft = '0.5rem';
|
|
742
|
-
settingsBtn.addEventListener('click', () => this._showReshapeModal());
|
|
743
|
-
statusEl.appendChild(settingsBtn);
|
|
744
|
-
}
|
|
745
|
-
});
|
|
739
|
+
// ✅ For collapsible mode, hide the status bar
|
|
740
|
+
const statusEl = document.getElementById(`${this._id}-status`);
|
|
741
|
+
if (statusEl) {
|
|
742
|
+
statusEl.style.display = 'none';
|
|
746
743
|
}
|
|
747
744
|
}
|
|
748
745
|
|
|
@@ -750,25 +747,56 @@ export class DataFrameComponent extends BaseComponent<DataFrameState> {
|
|
|
750
747
|
}
|
|
751
748
|
|
|
752
749
|
/**
|
|
753
|
-
* Update the collapsible summary text
|
|
750
|
+
* Update the collapsible summary text and add settings button
|
|
754
751
|
*/
|
|
755
|
-
private _updateSummary(): void {
|
|
752
|
+
private _updateSummary(isMalformed?: boolean): void {
|
|
756
753
|
if (!this._collapsible || !this._detailsElement) return;
|
|
757
754
|
|
|
758
|
-
const
|
|
759
|
-
if (!
|
|
755
|
+
const summaryEl = this._detailsElement.querySelector('.jux-dataframe-summary');
|
|
756
|
+
if (!summaryEl) return;
|
|
760
757
|
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
758
|
+
// Get or detect malformed status
|
|
759
|
+
const malformed = isMalformed ?? (this._df ? this._detectMalformedData(this._df) : false);
|
|
760
|
+
|
|
761
|
+
// Update text
|
|
762
|
+
const summaryTextEl = summaryEl.querySelector('.jux-dataframe-summary-text');
|
|
763
|
+
if (summaryTextEl) {
|
|
764
|
+
if (!this._df) {
|
|
765
|
+
summaryTextEl.textContent = 'No data loaded';
|
|
766
|
+
} else if (this._summaryTemplate) {
|
|
767
|
+
summaryTextEl.textContent = this._summaryTemplate(this._df);
|
|
768
|
+
} else {
|
|
769
|
+
const suffix = malformed ? ' ⚠️' : '';
|
|
770
|
+
summaryTextEl.textContent = `${this.state.sourceName || 'Data'} — ${this._df.height} rows × ${this._df.width} cols${suffix}`;
|
|
771
|
+
}
|
|
764
772
|
}
|
|
765
773
|
|
|
766
|
-
if
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
774
|
+
// ✅ Add settings button to summary if we have raw file data
|
|
775
|
+
let settingsBtn = summaryEl.querySelector('.jux-dataframe-summary-settings') as HTMLButtonElement;
|
|
776
|
+
|
|
777
|
+
if (this._rawFileData && this._df) {
|
|
778
|
+
if (!settingsBtn) {
|
|
779
|
+
settingsBtn = document.createElement('button');
|
|
780
|
+
settingsBtn.className = 'jux-dataframe-summary-settings';
|
|
781
|
+
settingsBtn.type = 'button';
|
|
782
|
+
settingsBtn.addEventListener('click', (e) => {
|
|
783
|
+
e.stopPropagation(); // Don't toggle the details
|
|
784
|
+
this._showReshapeModal();
|
|
785
|
+
});
|
|
786
|
+
summaryEl.appendChild(settingsBtn);
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
// Update button text/style based on malformed status
|
|
790
|
+
if (malformed) {
|
|
791
|
+
settingsBtn.textContent = '⚙️ Fix Settings';
|
|
792
|
+
settingsBtn.className = 'jux-dataframe-summary-settings jux-dataframe-summary-settings-warning';
|
|
793
|
+
} else {
|
|
794
|
+
settingsBtn.textContent = '⚙️ Settings';
|
|
795
|
+
settingsBtn.className = 'jux-dataframe-summary-settings';
|
|
796
|
+
}
|
|
797
|
+
} else if (settingsBtn) {
|
|
798
|
+
// Remove settings button if no raw file data
|
|
799
|
+
settingsBtn.remove();
|
|
772
800
|
}
|
|
773
801
|
}
|
|
774
802
|
|
|
@@ -776,6 +804,29 @@ export class DataFrameComponent extends BaseComponent<DataFrameState> {
|
|
|
776
804
|
* MALFORMED DATA DETECTION
|
|
777
805
|
* ═══════════════════════════════════════════════════ */
|
|
778
806
|
|
|
807
|
+
private _appendSettingsButton(label: string, variant: string): void {
|
|
808
|
+
const statusEl = document.getElementById(`${this._id}-status`);
|
|
809
|
+
if (!statusEl) return;
|
|
810
|
+
|
|
811
|
+
// Remove existing settings button if any
|
|
812
|
+
const existing = statusEl.querySelector('.jux-dataframe-settings-btn');
|
|
813
|
+
if (existing) existing.remove();
|
|
814
|
+
|
|
815
|
+
const btn = document.createElement('button');
|
|
816
|
+
btn.className = `jux-dataframe-settings-btn jux-dataframe-settings-btn-${variant}`;
|
|
817
|
+
btn.type = 'button';
|
|
818
|
+
btn.textContent = `⚙️ ${label}`;
|
|
819
|
+
btn.style.marginLeft = '8px';
|
|
820
|
+
btn.style.cursor = 'pointer';
|
|
821
|
+
btn.style.fontSize = '0.8rem';
|
|
822
|
+
btn.style.padding = '2px 8px';
|
|
823
|
+
btn.style.borderRadius = 'var(--radius, 4px)';
|
|
824
|
+
btn.style.border = '1px solid hsl(var(--border))';
|
|
825
|
+
btn.style.background = variant === 'warning' ? 'hsl(38 92% 50% / 0.15)' : 'transparent';
|
|
826
|
+
btn.addEventListener('click', () => this._showReshapeModal());
|
|
827
|
+
statusEl.appendChild(btn);
|
|
828
|
+
}
|
|
829
|
+
|
|
779
830
|
private _detectMalformedData(df: DataFrame): boolean {
|
|
780
831
|
const columns = df.columns;
|
|
781
832
|
const rows = df.toRows();
|
|
@@ -1253,12 +1304,25 @@ export class DataFrameComponent extends BaseComponent<DataFrameState> {
|
|
|
1253
1304
|
});
|
|
1254
1305
|
};
|
|
1255
1306
|
|
|
1307
|
+
const uploadRow = document.createElement('div');
|
|
1308
|
+
uploadRow.className = 'jux-dataframe-upload-row';
|
|
1309
|
+
|
|
1256
1310
|
const uploadContainer = document.createElement('div');
|
|
1257
1311
|
uploadContainer.className = 'jux-dataframe-upload';
|
|
1258
1312
|
uploadContainer.id = `${this._id}-upload-container`;
|
|
1259
|
-
|
|
1313
|
+
uploadRow.appendChild(uploadContainer);
|
|
1314
|
+
|
|
1315
|
+
// ✅ Status bar INLINE in the same row
|
|
1316
|
+
if (this._showStatus) {
|
|
1317
|
+
const statusBar = document.createElement('div');
|
|
1318
|
+
statusBar.className = 'jux-dataframe-status jux-dataframe-status-inline';
|
|
1319
|
+
statusBar.id = `${this._id}-status`;
|
|
1320
|
+
statusBar.style.display = 'none'; // Hidden until needed
|
|
1321
|
+
uploadRow.appendChild(statusBar);
|
|
1322
|
+
}
|
|
1323
|
+
|
|
1324
|
+
uploadArea.appendChild(uploadRow);
|
|
1260
1325
|
|
|
1261
|
-
// ✅ Optional description text
|
|
1262
1326
|
if (this._uploadDescription) {
|
|
1263
1327
|
const descEl = document.createElement('div');
|
|
1264
1328
|
descEl.className = 'jux-dataframe-upload-description';
|
|
@@ -1271,32 +1335,25 @@ export class DataFrameComponent extends BaseComponent<DataFrameState> {
|
|
|
1271
1335
|
upload.render(uploadContainer);
|
|
1272
1336
|
} else {
|
|
1273
1337
|
container.appendChild(wrapper);
|
|
1274
|
-
}
|
|
1275
1338
|
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
// ✅ Hidden status bar still exists so _updateStatus() calls don't throw,
|
|
1285
|
-
// but it's invisible — summary handles display instead.
|
|
1286
|
-
const statusBar = document.createElement('div');
|
|
1287
|
-
statusBar.className = 'jux-dataframe-status jux-dataframe-status-empty';
|
|
1288
|
-
statusBar.id = `${this._id}-status`;
|
|
1289
|
-
statusBar.style.display = 'none';
|
|
1290
|
-
wrapper.appendChild(statusBar);
|
|
1339
|
+
// Status bar for non-upload mode
|
|
1340
|
+
if (this._showStatus) {
|
|
1341
|
+
const statusBar = document.createElement('div');
|
|
1342
|
+
statusBar.className = 'jux-dataframe-status jux-dataframe-status-empty';
|
|
1343
|
+
statusBar.id = `${this._id}-status`;
|
|
1344
|
+
statusBar.textContent = 'No data loaded.';
|
|
1345
|
+
wrapper.appendChild(statusBar);
|
|
1346
|
+
}
|
|
1291
1347
|
}
|
|
1292
1348
|
|
|
1293
|
-
// ✅ Collapsible details wrapper
|
|
1349
|
+
// ✅ Collapsible details wrapper - HIDDEN until data loads
|
|
1294
1350
|
let tableContainer: HTMLElement;
|
|
1295
1351
|
|
|
1296
1352
|
if (this._collapsible) {
|
|
1297
1353
|
const details = document.createElement('details');
|
|
1298
1354
|
details.className = 'jux-dataframe-details';
|
|
1299
1355
|
details.open = !this._collapsed;
|
|
1356
|
+
details.style.display = 'none'; // Hidden until data loads
|
|
1300
1357
|
this._detailsElement = details;
|
|
1301
1358
|
|
|
1302
1359
|
const summary = document.createElement('summary');
|
|
@@ -1309,7 +1366,6 @@ export class DataFrameComponent extends BaseComponent<DataFrameState> {
|
|
|
1309
1366
|
|
|
1310
1367
|
const textSpan = document.createElement('span');
|
|
1311
1368
|
textSpan.className = 'jux-dataframe-summary-text';
|
|
1312
|
-
textSpan.textContent = 'No data loaded';
|
|
1313
1369
|
summary.appendChild(textSpan);
|
|
1314
1370
|
|
|
1315
1371
|
details.appendChild(summary);
|
|
@@ -1321,7 +1377,6 @@ export class DataFrameComponent extends BaseComponent<DataFrameState> {
|
|
|
1321
1377
|
wrapper.appendChild(details);
|
|
1322
1378
|
tableContainer = content;
|
|
1323
1379
|
|
|
1324
|
-
// Track toggle state
|
|
1325
1380
|
details.addEventListener('toggle', () => {
|
|
1326
1381
|
this._collapsed = !details.open;
|
|
1327
1382
|
});
|
package/lib/styles/shadcn.css
CHANGED
|
@@ -916,6 +916,36 @@ code {
|
|
|
916
916
|
flex: 1;
|
|
917
917
|
}
|
|
918
918
|
|
|
919
|
+
/* ✅ Settings button in summary */
|
|
920
|
+
.jux-dataframe-summary-settings {
|
|
921
|
+
padding: 0.25rem 0.5rem;
|
|
922
|
+
font-size: 0.75rem;
|
|
923
|
+
font-weight: 500;
|
|
924
|
+
border: 1px solid hsl(var(--border));
|
|
925
|
+
border-radius: calc(var(--radius) - 2px);
|
|
926
|
+
background: hsl(var(--background));
|
|
927
|
+
color: hsl(var(--muted-foreground));
|
|
928
|
+
cursor: pointer;
|
|
929
|
+
transition: all 0.15s;
|
|
930
|
+
margin-left: auto;
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
.jux-dataframe-summary-settings:hover {
|
|
934
|
+
background: hsl(var(--accent));
|
|
935
|
+
color: hsl(var(--foreground));
|
|
936
|
+
border-color: hsl(var(--muted-foreground) / 0.3);
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
.jux-dataframe-summary-settings-warning {
|
|
940
|
+
background: hsl(var(--warning) / 0.1);
|
|
941
|
+
border-color: hsl(var(--warning) / 0.3);
|
|
942
|
+
color: hsl(var(--warning-foreground));
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
.jux-dataframe-summary-settings-warning:hover {
|
|
946
|
+
background: hsl(var(--warning) / 0.2);
|
|
947
|
+
}
|
|
948
|
+
|
|
919
949
|
.jux-dataframe-details-content {
|
|
920
950
|
padding: 0;
|
|
921
951
|
}
|