mirror of
https://github.com/olehomelchenko/astrolabe-nvc.git
synced 2025-12-21 21:22:23 +00:00
refactor: add edit dataset button and enhance dataset form handling with schema warnings
This commit is contained in:
@@ -67,3 +67,4 @@ When implementing changes:
|
|||||||
- Pay attention to the existing code base style and approaches and try to adhere to the existing style instead of bringing your own vision.
|
- Pay attention to the existing code base style and approaches and try to adhere to the existing style instead of bringing your own vision.
|
||||||
- When updating documentation, do not record intermediate changes - write them always as a matter-of-fact information.
|
- When updating documentation, do not record intermediate changes - write them always as a matter-of-fact information.
|
||||||
- When working on the code, if you notice any opportunities to better bring the project to the state above - bring this to user's attention and ask for approval to implement the suggested changes.
|
- When working on the code, if you notice any opportunities to better bring the project to the state above - bring this to user's attention and ask for approval to implement the suggested changes.
|
||||||
|
- Testing: The user always tests changes manually. Do not start local servers or attempt to run the application.
|
||||||
|
|||||||
@@ -200,6 +200,7 @@
|
|||||||
<div class="dataset-details" id="dataset-details" style="display: none;">
|
<div class="dataset-details" id="dataset-details" style="display: none;">
|
||||||
<div class="dataset-detail-section">
|
<div class="dataset-detail-section">
|
||||||
<div class="dataset-actions">
|
<div class="dataset-actions">
|
||||||
|
<button class="btn btn-modal primary" id="edit-dataset-btn" title="Edit this dataset">Edit</button>
|
||||||
<button class="btn btn-modal primary" id="new-snippet-btn" title="Create a new snippet using this dataset">New Snippet</button>
|
<button class="btn btn-modal primary" id="new-snippet-btn" title="Create a new snippet using this dataset">New Snippet</button>
|
||||||
<button class="btn btn-modal" id="export-dataset-btn" title="Export this dataset to file">Export</button>
|
<button class="btn btn-modal" id="export-dataset-btn" title="Export this dataset to file">Export</button>
|
||||||
<button class="btn btn-modal" id="copy-reference-btn" title="Copy dataset reference to clipboard">Copy Reference</button>
|
<button class="btn btn-modal" id="copy-reference-btn" title="Copy dataset reference to clipboard">Copy Reference</button>
|
||||||
|
|||||||
@@ -216,6 +216,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
const datasetsLink = document.getElementById('datasets-link');
|
const datasetsLink = document.getElementById('datasets-link');
|
||||||
const toggleDatasetsBtn = document.getElementById('toggle-datasets');
|
const toggleDatasetsBtn = document.getElementById('toggle-datasets');
|
||||||
const newDatasetBtn = document.getElementById('new-dataset-btn');
|
const newDatasetBtn = document.getElementById('new-dataset-btn');
|
||||||
|
const editDatasetBtn = document.getElementById('edit-dataset-btn');
|
||||||
const cancelDatasetBtn = document.getElementById('cancel-dataset-btn');
|
const cancelDatasetBtn = document.getElementById('cancel-dataset-btn');
|
||||||
const saveDatasetBtn = document.getElementById('save-dataset-btn');
|
const saveDatasetBtn = document.getElementById('save-dataset-btn');
|
||||||
const deleteDatasetBtn = document.getElementById('delete-dataset-btn');
|
const deleteDatasetBtn = document.getElementById('delete-dataset-btn');
|
||||||
@@ -234,6 +235,15 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
newDatasetBtn.addEventListener('click', showNewDatasetForm);
|
newDatasetBtn.addEventListener('click', showNewDatasetForm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Edit dataset button
|
||||||
|
if (editDatasetBtn) {
|
||||||
|
editDatasetBtn.addEventListener('click', async function() {
|
||||||
|
if (window.currentDatasetId) {
|
||||||
|
await showEditDatasetForm(window.currentDatasetId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Import dataset button and file input
|
// Import dataset button and file input
|
||||||
const importDatasetBtn = document.getElementById('import-dataset-btn');
|
const importDatasetBtn = document.getElementById('import-dataset-btn');
|
||||||
const importDatasetFile = document.getElementById('import-dataset-file');
|
const importDatasetFile = document.getElementById('import-dataset-file');
|
||||||
@@ -375,10 +385,18 @@ function handleURLStateChange() {
|
|||||||
if (state.datasetId === 'new') {
|
if (state.datasetId === 'new') {
|
||||||
// Show new dataset form
|
// Show new dataset form
|
||||||
showNewDatasetForm(false);
|
showNewDatasetForm(false);
|
||||||
|
} else if (state.datasetId && state.datasetId.startsWith('edit-')) {
|
||||||
|
// Show edit dataset form - extract numeric ID from "edit-123456"
|
||||||
|
const numericId = parseFloat(state.datasetId.replace('edit-', ''));
|
||||||
|
if (!isNaN(numericId)) {
|
||||||
|
showEditDatasetForm(numericId, false);
|
||||||
|
}
|
||||||
} else if (state.datasetId) {
|
} else if (state.datasetId) {
|
||||||
// Extract numeric ID from "dataset-123456"
|
// Extract numeric ID from "dataset-123456"
|
||||||
const numericId = parseFloat(state.datasetId.replace('dataset-', ''));
|
const numericId = parseFloat(state.datasetId.replace('dataset-', ''));
|
||||||
selectDataset(numericId, false);
|
if (!isNaN(numericId)) {
|
||||||
|
selectDataset(numericId, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (state.snippetId) {
|
} else if (state.snippetId) {
|
||||||
// Close dataset modal if open
|
// Close dataset modal if open
|
||||||
|
|||||||
@@ -997,10 +997,31 @@ function showDetectionConfirmation(detection, originalInput) {
|
|||||||
detectedConfidenceEl.className = `detected-confidence ${confidenceClass}`;
|
detectedConfidenceEl.className = `detected-confidence ${confidenceClass}`;
|
||||||
detectedConfidenceEl.textContent = `${detection.confidence} confidence`;
|
detectedConfidenceEl.textContent = `${detection.confidence} confidence`;
|
||||||
|
|
||||||
// Show preview
|
// Calculate metadata for the detected data
|
||||||
|
let metadata = null;
|
||||||
|
if (detection.source === 'url' && detection.content) {
|
||||||
|
metadata = calculateDatasetStats(
|
||||||
|
detection.parsed || detection.content,
|
||||||
|
detection.format,
|
||||||
|
'inline'
|
||||||
|
);
|
||||||
|
} else if (detection.source === 'inline') {
|
||||||
|
metadata = calculateDatasetStats(
|
||||||
|
detection.parsed || originalInput,
|
||||||
|
detection.format,
|
||||||
|
'inline'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show preview with metadata
|
||||||
let previewText = '';
|
let previewText = '';
|
||||||
|
|
||||||
if (detection.source === 'url') {
|
if (detection.source === 'url') {
|
||||||
previewText = `URL: ${originalInput}\n\n`;
|
previewText = `URL: ${originalInput}\n\n`;
|
||||||
|
if (metadata && metadata.columns && metadata.columns.length > 0) {
|
||||||
|
previewText += `Columns (${metadata.columnCount}): ${metadata.columns.join(', ')}\n`;
|
||||||
|
previewText += `Rows: ${metadata.rowCount}\n\n`;
|
||||||
|
}
|
||||||
if (detection.content) {
|
if (detection.content) {
|
||||||
const lines = detection.content.split('\n');
|
const lines = detection.content.split('\n');
|
||||||
previewText += `Preview (first 10 lines):\n${lines.slice(0, 10).join('\n')}`;
|
previewText += `Preview (first 10 lines):\n${lines.slice(0, 10).join('\n')}`;
|
||||||
@@ -1009,8 +1030,12 @@ function showDetectionConfirmation(detection, originalInput) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (metadata && metadata.columns && metadata.columns.length > 0) {
|
||||||
|
previewText = `Columns (${metadata.columnCount}): ${metadata.columns.join(', ')}\n`;
|
||||||
|
previewText += `Rows: ${metadata.rowCount}\n\n`;
|
||||||
|
}
|
||||||
const lines = originalInput.split('\n');
|
const lines = originalInput.split('\n');
|
||||||
previewText = lines.slice(0, 15).join('\n');
|
previewText += lines.slice(0, 15).join('\n');
|
||||||
if (lines.length > 15) {
|
if (lines.length > 15) {
|
||||||
previewText += `\n... (${lines.length - 15} more lines)`;
|
previewText += `\n... (${lines.length - 15} more lines)`;
|
||||||
}
|
}
|
||||||
@@ -1020,7 +1045,8 @@ function showDetectionConfirmation(detection, originalInput) {
|
|||||||
// Store detection data for later use
|
// Store detection data for later use
|
||||||
window.currentDetection = {
|
window.currentDetection = {
|
||||||
...detection,
|
...detection,
|
||||||
originalInput
|
originalInput,
|
||||||
|
metadata
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1031,8 +1057,80 @@ function hideDetectionConfirmation() {
|
|||||||
window.currentDetection = null;
|
window.currentDetection = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Setup input handler for dataset form (handles both create and edit)
|
||||||
|
function setupDatasetInputHandler() {
|
||||||
|
const inputEl = document.getElementById('dataset-form-input');
|
||||||
|
|
||||||
|
// Remove existing listener if any
|
||||||
|
if (inputEl._datasetInputHandler) {
|
||||||
|
inputEl.removeEventListener('input', inputEl._datasetInputHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create new handler
|
||||||
|
const handler = async function () {
|
||||||
|
const text = this.value.trim();
|
||||||
|
if (!text) {
|
||||||
|
hideDetectionConfirmation();
|
||||||
|
hideSchemaWarning();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const errorEl = document.getElementById('dataset-form-error');
|
||||||
|
errorEl.textContent = '';
|
||||||
|
|
||||||
|
// Check if it's a URL
|
||||||
|
if (isURL(text)) {
|
||||||
|
errorEl.textContent = 'Fetching and analyzing URL...';
|
||||||
|
|
||||||
|
try {
|
||||||
|
const detection = await fetchAndDetectURL(text);
|
||||||
|
errorEl.textContent = '';
|
||||||
|
|
||||||
|
if (detection.format) {
|
||||||
|
showDetectionConfirmation(detection, text);
|
||||||
|
checkSchemaChanges();
|
||||||
|
} else {
|
||||||
|
errorEl.textContent = 'Could not detect data format from URL. Please check the URL or try pasting the data directly.';
|
||||||
|
hideDetectionConfirmation();
|
||||||
|
hideSchemaWarning();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
errorEl.textContent = error.message;
|
||||||
|
hideDetectionConfirmation();
|
||||||
|
hideSchemaWarning();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Inline data - detect format
|
||||||
|
const detection = detectDataFormat(text);
|
||||||
|
|
||||||
|
if (detection.format) {
|
||||||
|
showDetectionConfirmation({
|
||||||
|
...detection,
|
||||||
|
source: 'inline'
|
||||||
|
}, text);
|
||||||
|
checkSchemaChanges();
|
||||||
|
} else {
|
||||||
|
errorEl.textContent = 'Could not detect data format. Please ensure your data is valid JSON, CSV, or TSV.';
|
||||||
|
hideDetectionConfirmation();
|
||||||
|
hideSchemaWarning();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Store reference to handler for cleanup
|
||||||
|
inputEl._datasetInputHandler = handler;
|
||||||
|
|
||||||
|
// Attach listener
|
||||||
|
inputEl.addEventListener('input', handler);
|
||||||
|
}
|
||||||
|
|
||||||
// Show new dataset form
|
// Show new dataset form
|
||||||
function showNewDatasetForm(updateURL = true) {
|
function showNewDatasetForm(updateURL = true) {
|
||||||
|
// Set mode to create
|
||||||
|
window.datasetFormMode = 'create';
|
||||||
|
window.editingDatasetId = null;
|
||||||
|
window.originalSchema = null;
|
||||||
|
|
||||||
document.getElementById('dataset-list-view').style.display = 'none';
|
document.getElementById('dataset-list-view').style.display = 'none';
|
||||||
document.getElementById('dataset-form-view').style.display = 'block';
|
document.getElementById('dataset-form-view').style.display = 'block';
|
||||||
document.getElementById('dataset-form-name').value = '';
|
document.getElementById('dataset-form-name').value = '';
|
||||||
@@ -1040,6 +1138,12 @@ function showNewDatasetForm(updateURL = true) {
|
|||||||
document.getElementById('dataset-form-comment').value = '';
|
document.getElementById('dataset-form-comment').value = '';
|
||||||
document.getElementById('dataset-form-error').textContent = '';
|
document.getElementById('dataset-form-error').textContent = '';
|
||||||
|
|
||||||
|
// Update form header
|
||||||
|
document.querySelector('.dataset-form-header').textContent = 'Create New Dataset';
|
||||||
|
|
||||||
|
// Hide schema warning
|
||||||
|
hideSchemaWarning();
|
||||||
|
|
||||||
// Hide detection confirmation
|
// Hide detection confirmation
|
||||||
hideDetectionConfirmation();
|
hideDetectionConfirmation();
|
||||||
|
|
||||||
@@ -1048,56 +1152,156 @@ function showNewDatasetForm(updateURL = true) {
|
|||||||
URLState.update({ view: 'datasets', snippetId: null, datasetId: 'new' });
|
URLState.update({ view: 'datasets', snippetId: null, datasetId: 'new' });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add paste handler if not already added
|
// Setup input handler for detection
|
||||||
if (!window.datasetListenersAdded) {
|
setupDatasetInputHandler();
|
||||||
const inputEl = document.getElementById('dataset-form-input');
|
}
|
||||||
|
|
||||||
// Handle paste/input with auto-detection
|
// Show edit dataset form
|
||||||
inputEl.addEventListener('input', async function () {
|
async function showEditDatasetForm(datasetId, updateURL = true) {
|
||||||
const text = this.value.trim();
|
const dataset = await DatasetStorage.getDataset(datasetId);
|
||||||
if (!text) {
|
if (!dataset) return;
|
||||||
hideDetectionConfirmation();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const errorEl = document.getElementById('dataset-form-error');
|
// Set mode to edit
|
||||||
errorEl.textContent = '';
|
window.datasetFormMode = 'edit';
|
||||||
|
window.editingDatasetId = datasetId;
|
||||||
|
|
||||||
// Check if it's a URL
|
// Store original schema for comparison
|
||||||
if (isURL(text)) {
|
window.originalSchema = dataset.columns ? [...dataset.columns] : [];
|
||||||
errorEl.textContent = 'Fetching and analyzing URL...';
|
|
||||||
|
|
||||||
try {
|
document.getElementById('dataset-list-view').style.display = 'none';
|
||||||
const detection = await fetchAndDetectURL(text);
|
document.getElementById('dataset-form-view').style.display = 'block';
|
||||||
errorEl.textContent = '';
|
|
||||||
|
|
||||||
if (detection.format) {
|
// Populate form with current values
|
||||||
showDetectionConfirmation(detection, text);
|
document.getElementById('dataset-form-name').value = dataset.name;
|
||||||
} else {
|
document.getElementById('dataset-form-comment').value = dataset.comment || '';
|
||||||
errorEl.textContent = 'Could not detect data format from URL. Please check the URL or try pasting the data directly.';
|
|
||||||
hideDetectionConfirmation();
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
errorEl.textContent = error.message;
|
|
||||||
hideDetectionConfirmation();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Inline data - detect format
|
|
||||||
const detection = detectDataFormat(text);
|
|
||||||
|
|
||||||
if (detection.format) {
|
// Populate data input based on source
|
||||||
showDetectionConfirmation({
|
let inputValue;
|
||||||
...detection,
|
if (dataset.source === 'url') {
|
||||||
source: 'inline'
|
inputValue = dataset.data; // The URL string
|
||||||
}, text);
|
} else if (dataset.format === 'json' || dataset.format === 'topojson') {
|
||||||
} else {
|
inputValue = JSON.stringify(dataset.data, null, 2);
|
||||||
errorEl.textContent = 'Could not detect data format. Please ensure your data is valid JSON, CSV, or TSV.';
|
} else if (dataset.format === 'csv' || dataset.format === 'tsv') {
|
||||||
hideDetectionConfirmation();
|
inputValue = dataset.data;
|
||||||
}
|
}
|
||||||
}
|
document.getElementById('dataset-form-input').value = inputValue;
|
||||||
});
|
|
||||||
|
|
||||||
window.datasetListenersAdded = true;
|
// Trigger detection to show current state
|
||||||
|
const inputEl = document.getElementById('dataset-form-input');
|
||||||
|
// Use setTimeout to ensure the value is set before triggering
|
||||||
|
setTimeout(() => {
|
||||||
|
inputEl.dispatchEvent(new Event('input', { bubbles: true }));
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
document.getElementById('dataset-form-error').textContent = '';
|
||||||
|
|
||||||
|
// Update form header
|
||||||
|
document.querySelector('.dataset-form-header').textContent = 'Edit Dataset';
|
||||||
|
|
||||||
|
// Hide schema warning initially
|
||||||
|
hideSchemaWarning();
|
||||||
|
|
||||||
|
// Update URL state
|
||||||
|
if (updateURL) {
|
||||||
|
URLState.update({ view: 'datasets', snippetId: null, datasetId: `edit-${datasetId}` });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup input handler for detection
|
||||||
|
setupDatasetInputHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hide schema warning
|
||||||
|
function hideSchemaWarning() {
|
||||||
|
const warningEl = document.getElementById('dataset-schema-warning');
|
||||||
|
if (warningEl) {
|
||||||
|
warningEl.style.display = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show schema warning with details
|
||||||
|
function showSchemaWarning(oldSchema, newSchema) {
|
||||||
|
let warningEl = document.getElementById('dataset-schema-warning');
|
||||||
|
|
||||||
|
// Create warning element if it doesn't exist
|
||||||
|
if (!warningEl) {
|
||||||
|
const confirmEl = document.getElementById('dataset-detection-confirm');
|
||||||
|
warningEl = document.createElement('div');
|
||||||
|
warningEl.id = 'dataset-schema-warning';
|
||||||
|
warningEl.className = 'dataset-schema-warning';
|
||||||
|
confirmEl.parentNode.insertBefore(warningEl, confirmEl.nextSibling);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine what changed
|
||||||
|
const added = newSchema.filter(col => !oldSchema.includes(col));
|
||||||
|
const removed = oldSchema.filter(col => !newSchema.includes(col));
|
||||||
|
|
||||||
|
let message = '⚠️ Schema Change Detected<br/>';
|
||||||
|
|
||||||
|
if (removed.length > 0) {
|
||||||
|
message += `<strong>Removed columns:</strong> ${removed.join(', ')}<br/>`;
|
||||||
|
}
|
||||||
|
if (added.length > 0) {
|
||||||
|
message += `<strong>Added columns:</strong> ${added.join(', ')}<br/>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
message += '<em>Saving will update the dataset schema. Linked snippets may be affected.</em>';
|
||||||
|
|
||||||
|
warningEl.innerHTML = message;
|
||||||
|
warningEl.style.display = 'block';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for schema changes
|
||||||
|
function checkSchemaChanges() {
|
||||||
|
// Only check in edit mode
|
||||||
|
if (window.datasetFormMode !== 'edit' || !window.originalSchema) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get current detection
|
||||||
|
const detection = window.currentDetection;
|
||||||
|
if (!detection || !detection.format) {
|
||||||
|
hideSchemaWarning();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract new schema from detected data
|
||||||
|
let newSchema = [];
|
||||||
|
|
||||||
|
if (detection.source === 'url' && detection.content) {
|
||||||
|
// Parse content to get schema
|
||||||
|
const tempStats = calculateDatasetStats(
|
||||||
|
detection.parsed || detection.content,
|
||||||
|
detection.format,
|
||||||
|
'inline'
|
||||||
|
);
|
||||||
|
newSchema = tempStats.columns || [];
|
||||||
|
} else if (detection.source === 'inline') {
|
||||||
|
const tempStats = calculateDatasetStats(
|
||||||
|
detection.parsed || detection.originalInput,
|
||||||
|
detection.format,
|
||||||
|
'inline'
|
||||||
|
);
|
||||||
|
newSchema = tempStats.columns || [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compare schemas
|
||||||
|
const originalSchema = window.originalSchema || [];
|
||||||
|
|
||||||
|
if (newSchema.length === 0 && originalSchema.length === 0) {
|
||||||
|
hideSchemaWarning();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if schemas are different
|
||||||
|
const schemaChanged =
|
||||||
|
originalSchema.length !== newSchema.length ||
|
||||||
|
!originalSchema.every(col => newSchema.includes(col)) ||
|
||||||
|
!newSchema.every(col => originalSchema.includes(col));
|
||||||
|
|
||||||
|
if (schemaChanged) {
|
||||||
|
showSchemaWarning(originalSchema, newSchema);
|
||||||
|
} else {
|
||||||
|
hideSchemaWarning();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1105,9 +1309,13 @@ function showNewDatasetForm(updateURL = true) {
|
|||||||
function hideNewDatasetForm() {
|
function hideNewDatasetForm() {
|
||||||
document.getElementById('dataset-list-view').style.display = 'block';
|
document.getElementById('dataset-list-view').style.display = 'block';
|
||||||
document.getElementById('dataset-form-view').style.display = 'none';
|
document.getElementById('dataset-form-view').style.display = 'none';
|
||||||
|
window.datasetFormMode = null;
|
||||||
|
window.editingDatasetId = null;
|
||||||
|
window.originalSchema = null;
|
||||||
|
hideSchemaWarning();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save new dataset
|
// Save new dataset (handles both create and edit modes)
|
||||||
async function saveNewDataset() {
|
async function saveNewDataset() {
|
||||||
const name = document.getElementById('dataset-form-name').value.trim();
|
const name = document.getElementById('dataset-form-name').value.trim();
|
||||||
const comment = document.getElementById('dataset-form-comment').value.trim();
|
const comment = document.getElementById('dataset-form-comment').value.trim();
|
||||||
@@ -1173,29 +1381,65 @@ async function saveNewDataset() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if name already exists
|
|
||||||
if (await DatasetStorage.nameExists(name)) {
|
|
||||||
errorEl.textContent = 'A dataset with this name already exists';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create dataset
|
|
||||||
try {
|
try {
|
||||||
const dataset = await DatasetStorage.createDataset(name, data, format, source, comment);
|
if (window.datasetFormMode === 'edit') {
|
||||||
|
// Edit mode - update existing dataset
|
||||||
|
const datasetId = window.editingDatasetId;
|
||||||
|
|
||||||
// If we have metadata from URL fetch, update the dataset
|
// Check if name already exists (excluding current dataset)
|
||||||
if (metadata) {
|
if (await DatasetStorage.nameExists(name, datasetId)) {
|
||||||
await DatasetStorage.updateDataset(dataset.id, {
|
errorEl.textContent = 'A dataset with this name already exists';
|
||||||
data: data,
|
return;
|
||||||
...metadata
|
}
|
||||||
});
|
|
||||||
|
// Update dataset
|
||||||
|
const updates = {
|
||||||
|
name,
|
||||||
|
data,
|
||||||
|
format,
|
||||||
|
source,
|
||||||
|
comment
|
||||||
|
};
|
||||||
|
|
||||||
|
// Add metadata if available (for URL sources)
|
||||||
|
if (metadata) {
|
||||||
|
Object.assign(updates, metadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
await DatasetStorage.updateDataset(datasetId, updates);
|
||||||
|
|
||||||
|
hideNewDatasetForm();
|
||||||
|
await renderDatasetList();
|
||||||
|
await selectDataset(datasetId);
|
||||||
|
|
||||||
|
Toast.success('Dataset updated successfully');
|
||||||
|
|
||||||
|
// Track event
|
||||||
|
Analytics.track('dataset-update', `Update dataset (${source})`);
|
||||||
|
} else {
|
||||||
|
// Create mode - create new dataset
|
||||||
|
// Check if name already exists
|
||||||
|
if (await DatasetStorage.nameExists(name)) {
|
||||||
|
errorEl.textContent = 'A dataset with this name already exists';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const dataset = await DatasetStorage.createDataset(name, data, format, source, comment);
|
||||||
|
|
||||||
|
// If we have metadata from URL fetch, update the dataset
|
||||||
|
if (metadata) {
|
||||||
|
await DatasetStorage.updateDataset(dataset.id, {
|
||||||
|
data: data,
|
||||||
|
...metadata
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
hideNewDatasetForm();
|
||||||
|
await renderDatasetList();
|
||||||
|
|
||||||
|
// Track event
|
||||||
|
Analytics.track('dataset-create', `Create dataset (${source})`);
|
||||||
}
|
}
|
||||||
|
|
||||||
hideNewDatasetForm();
|
|
||||||
await renderDatasetList();
|
|
||||||
|
|
||||||
// Track event
|
|
||||||
Analytics.track('dataset-create', `Create dataset (${source})`);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
errorEl.textContent = `Failed to save dataset: ${error.message}`;
|
errorEl.textContent = `Failed to save dataset: ${error.message}`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -374,6 +374,12 @@ body { font-family: var(--font-main); height: 100vh; overflow: hidden; backgroun
|
|||||||
.detection-badges { display: flex; gap: 6px; align-items: center; }
|
.detection-badges { display: flex; gap: 6px; align-items: center; }
|
||||||
.detection-badge { background: var(--win-blue); color: var(--bg-white); padding: 2px 8px; font-size: 10px; font-weight: bold; border: 1px solid var(--win-blue-dark); border-radius: 2px; }
|
.detection-badge { background: var(--win-blue); color: var(--bg-white); padding: 2px 8px; font-size: 10px; font-weight: bold; border: 1px solid var(--win-blue-dark); border-radius: 2px; }
|
||||||
.detected-confidence { font-size: 9px; padding: 2px 6px; border-radius: 2px; }
|
.detected-confidence { font-size: 9px; padding: 2px 6px; border-radius: 2px; }
|
||||||
|
|
||||||
|
/* Schema Warning */
|
||||||
|
.dataset-schema-warning { margin: 12px 0; padding: 12px; background: #fff8dc; border: 2px solid #ffa500; border-radius: 4px; font-size: 11px; line-height: 1.6; color: #000; }
|
||||||
|
:root[data-theme="experimental"] .dataset-schema-warning { background: #3a3020; border-color: #cc8800; color: #ffd966; }
|
||||||
|
.dataset-schema-warning strong { font-weight: 600; }
|
||||||
|
.dataset-schema-warning em { font-style: italic; opacity: 0.9; }
|
||||||
.detected-confidence.high { background: #90ee90; border: 1px solid #60c060; }
|
.detected-confidence.high { background: #90ee90; border: 1px solid #60c060; }
|
||||||
:root[data-theme="experimental"] .detected-confidence.high { background: #3a6a3a; color: #88ff88; border-color: #66dd66; }
|
:root[data-theme="experimental"] .detected-confidence.high { background: #3a6a3a; color: #88ff88; border-color: #66dd66; }
|
||||||
.detected-confidence.medium { background: #ffff90; border: 1px solid #d0d060; }
|
.detected-confidence.medium { background: #ffff90; border: 1px solid #d0d060; }
|
||||||
|
|||||||
Reference in New Issue
Block a user