mirror of
https://github.com/olehomelchenko/astrolabe-nvc.git
synced 2025-12-21 21:22:23 +00:00
refactor: remove excessive code, move script to app.js
This commit is contained in:
107
index.html
107
index.html
@@ -28,13 +28,13 @@
|
||||
<div class="app-container">
|
||||
<!-- Toggle Button Strip -->
|
||||
<div class="toggle-strip">
|
||||
<button class="toggle-btn active" id="toggle-snippets" title="Toggle Snippets Panel">
|
||||
<button class="toggle-btn active" id="toggle-snippet-panel" title="Toggle Snippets Panel">
|
||||
📄
|
||||
</button>
|
||||
<button class="toggle-btn active" id="toggle-editor" title="Toggle Editor Panel">
|
||||
<button class="toggle-btn active" id="toggle-editor-panel" title="Toggle Editor Panel">
|
||||
✏️
|
||||
</button>
|
||||
<button class="toggle-btn active" id="toggle-preview" title="Toggle Preview Panel">
|
||||
<button class="toggle-btn active" id="toggle-preview-panel" title="Toggle Preview Panel">
|
||||
👁️
|
||||
</button>
|
||||
</div>
|
||||
@@ -130,107 +130,6 @@
|
||||
<script src="src/js/panel-manager.js"></script>
|
||||
<script src="src/js/editor.js"></script>
|
||||
<script src="src/js/app.js"></script>
|
||||
|
||||
<script>
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
// Initialize snippet storage and render list
|
||||
initializeSnippetsStorage();
|
||||
|
||||
// Initialize sort controls
|
||||
initializeSortControls();
|
||||
|
||||
// Initialize search controls
|
||||
initializeSearchControls();
|
||||
|
||||
renderSnippetList();
|
||||
|
||||
// Load saved layout
|
||||
loadLayoutFromStorage();
|
||||
|
||||
// Initialize resize functionality
|
||||
initializeResize();
|
||||
|
||||
// Initialize Monaco Editor
|
||||
require.config({ paths: { vs: 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.47.0/min/vs' } });
|
||||
require(['vs/editor/editor.main'], async function () {
|
||||
// Fetch actual Vega-Lite schema JSON for better validation
|
||||
let vegaLiteSchema;
|
||||
try {
|
||||
const response = await fetch('https://vega.github.io/schema/vega-lite/v5.json');
|
||||
vegaLiteSchema = await response.json();
|
||||
} catch (error) {
|
||||
vegaLiteSchema = null;
|
||||
}
|
||||
|
||||
// Configure JSON language with actual schema
|
||||
if (vegaLiteSchema) {
|
||||
monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
|
||||
validate: true,
|
||||
schemas: [{
|
||||
uri: "https://vega.github.io/schema/vega-lite/v5.json",
|
||||
fileMatch: ["*"], // Associate with all files
|
||||
schema: vegaLiteSchema
|
||||
}]
|
||||
});
|
||||
}
|
||||
|
||||
// Load Vega libraries before creating editor
|
||||
await loadVegaLibraries();
|
||||
|
||||
// Create the editor with improved configuration
|
||||
editor = monaco.editor.create(document.getElementById('monaco-editor'), {
|
||||
value: JSON.stringify(sampleSpec, null, 2),
|
||||
language: 'json',
|
||||
theme: 'vs-light',
|
||||
fontSize: 12,
|
||||
minimap: { enabled: false },
|
||||
scrollBeyondLastLine: false,
|
||||
automaticLayout: true,
|
||||
wordWrap: 'on',
|
||||
formatOnPaste: true,
|
||||
formatOnType: true
|
||||
});
|
||||
|
||||
// Add debounced auto-render on editor change
|
||||
editor.onDidChangeModelContent(() => {
|
||||
debouncedRender();
|
||||
});
|
||||
|
||||
// Initial render
|
||||
renderVisualization();
|
||||
|
||||
// Initialize auto-save functionality
|
||||
initializeAutoSave();
|
||||
});
|
||||
|
||||
// Enhanced toggle functionality with memory and expansion
|
||||
const toggleButtons = document.querySelectorAll('.toggle-btn');
|
||||
toggleButtons.forEach(button => {
|
||||
button.addEventListener('click', function () {
|
||||
const panelId = this.id.replace('toggle-', ''); // Remove 'toggle-' prefix
|
||||
togglePanel(panelId);
|
||||
});
|
||||
});
|
||||
|
||||
// Snippet selection is now handled by snippet-manager.js
|
||||
|
||||
// Header link handlers
|
||||
const headerLinks = document.querySelectorAll('.header-link');
|
||||
headerLinks.forEach(link => {
|
||||
link.addEventListener('click', function () {
|
||||
const linkText = this.textContent.trim();
|
||||
switch (linkText) {
|
||||
case 'Import':
|
||||
case 'Export':
|
||||
case 'Help':
|
||||
// TODO: Implement in future phases
|
||||
break;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,89 @@
|
||||
// Application initialization and event handlers
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
// Initialize snippet storage and render list
|
||||
initializeSnippetsStorage();
|
||||
|
||||
// Initialize sort controls
|
||||
initializeSortControls();
|
||||
|
||||
// Initialize search controls
|
||||
initializeSearchControls();
|
||||
|
||||
renderSnippetList();
|
||||
|
||||
// Load saved layout
|
||||
loadLayoutFromStorage();
|
||||
|
||||
// Initialize resize functionality
|
||||
initializeResize();
|
||||
|
||||
// Initialize Monaco Editor
|
||||
require.config({ paths: { vs: 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.47.0/min/vs' } });
|
||||
require(['vs/editor/editor.main'], async function () {
|
||||
// Fetch Vega-Lite schema for validation
|
||||
let vegaLiteSchema;
|
||||
try {
|
||||
const response = await fetch('https://vega.github.io/schema/vega-lite/v5.json');
|
||||
vegaLiteSchema = await response.json();
|
||||
} catch (error) {
|
||||
vegaLiteSchema = null;
|
||||
}
|
||||
|
||||
// Configure JSON language with schema
|
||||
if (vegaLiteSchema) {
|
||||
monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
|
||||
validate: true,
|
||||
schemas: [{
|
||||
uri: "https://vega.github.io/schema/vega-lite/v5.json",
|
||||
fileMatch: ["*"],
|
||||
schema: vegaLiteSchema
|
||||
}]
|
||||
});
|
||||
}
|
||||
|
||||
// Load Vega libraries before creating editor
|
||||
await loadVegaLibraries();
|
||||
|
||||
// Create the editor
|
||||
editor = monaco.editor.create(document.getElementById('monaco-editor'), {
|
||||
value: JSON.stringify(sampleSpec, null, 2),
|
||||
language: 'json',
|
||||
theme: 'vs-light',
|
||||
fontSize: 12,
|
||||
minimap: { enabled: false },
|
||||
scrollBeyondLastLine: false,
|
||||
automaticLayout: true,
|
||||
wordWrap: 'on',
|
||||
formatOnPaste: true,
|
||||
formatOnType: true
|
||||
});
|
||||
|
||||
// Add debounced auto-render on editor change
|
||||
editor.onDidChangeModelContent(() => {
|
||||
debouncedRender();
|
||||
debouncedAutoSave();
|
||||
});
|
||||
|
||||
// Initial render
|
||||
renderVisualization();
|
||||
|
||||
// Initialize auto-save functionality
|
||||
initializeAutoSave();
|
||||
});
|
||||
|
||||
// Toggle panel buttons
|
||||
document.querySelectorAll('.toggle-btn').forEach(button => {
|
||||
button.addEventListener('click', function () {
|
||||
const panelId = this.id.replace('toggle-', '');
|
||||
togglePanel(panelId);
|
||||
});
|
||||
});
|
||||
|
||||
// Header links - show placeholder
|
||||
document.querySelectorAll('.header-link').forEach(link => {
|
||||
link.addEventListener('click', function () {
|
||||
alert('Coming soon in a future phase!');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -28,14 +28,14 @@ async function renderVisualization() {
|
||||
|
||||
// Debounced render function
|
||||
function debouncedRender() {
|
||||
clearTimeout(renderTimeout);
|
||||
|
||||
// If we're updating the editor programmatically, render immediately
|
||||
// Don't debounce if we're programmatically updating - render immediately
|
||||
if (window.isUpdatingEditor) {
|
||||
renderVisualization();
|
||||
} else {
|
||||
renderTimeout = setTimeout(renderVisualization, 1500); // 1.5s delay for user edits
|
||||
return;
|
||||
}
|
||||
|
||||
clearTimeout(renderTimeout);
|
||||
renderTimeout = setTimeout(renderVisualization, 1500);
|
||||
}
|
||||
|
||||
// Load Vega libraries dynamically with UMD builds
|
||||
|
||||
@@ -18,22 +18,10 @@ function updatePanelMemory() {
|
||||
|
||||
|
||||
function togglePanel(panelId) {
|
||||
const panel = document.getElementById(panelId);
|
||||
const button = document.getElementById(`toggle-${panelId}`);
|
||||
|
||||
// Fix ID mapping - buttons use plural, panels use singular
|
||||
const panelIdMap = {
|
||||
'snippets': 'snippet-panel',
|
||||
'editor': 'editor-panel',
|
||||
'preview': 'preview-panel'
|
||||
};
|
||||
|
||||
const actualPanelId = panelIdMap[panelId];
|
||||
const panel = document.getElementById(actualPanelId);
|
||||
const button = document.getElementById('toggle-' + panelId);
|
||||
|
||||
|
||||
if (!panel || !button) {
|
||||
return;
|
||||
}
|
||||
if (!panel || !button) return;
|
||||
|
||||
if (panel.style.display === 'none') {
|
||||
// Show panel
|
||||
@@ -126,9 +114,9 @@ function loadLayoutFromStorage() {
|
||||
previewPanel.style.display = layout.previewVisible !== false ? 'flex' : 'none';
|
||||
|
||||
// Update toggle button states
|
||||
document.getElementById('toggle-snippets').classList.toggle('active', layout.snippetVisible !== false);
|
||||
document.getElementById('toggle-editor').classList.toggle('active', layout.editorVisible !== false);
|
||||
document.getElementById('toggle-preview').classList.toggle('active', layout.previewVisible !== false);
|
||||
document.getElementById('toggle-snippet-panel').classList.toggle('active', layout.snippetVisible !== false);
|
||||
document.getElementById('toggle-editor-panel').classList.toggle('active', layout.editorVisible !== false);
|
||||
document.getElementById('toggle-preview-panel').classList.toggle('active', layout.previewVisible !== false);
|
||||
|
||||
// Restore widths and redistribute
|
||||
snippetPanel.style.width = layout.snippetWidth;
|
||||
|
||||
@@ -8,14 +8,9 @@ function generateSnippetId() {
|
||||
// Generate auto-populated name with current datetime
|
||||
function generateSnippetName() {
|
||||
const now = new Date();
|
||||
const year = now.getFullYear();
|
||||
const month = String(now.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(now.getDate()).padStart(2, '0');
|
||||
const hours = String(now.getHours()).padStart(2, '0');
|
||||
const minutes = String(now.getMinutes()).padStart(2, '0');
|
||||
const seconds = String(now.getSeconds()).padStart(2, '0');
|
||||
const pad = (n) => String(n).padStart(2, '0');
|
||||
|
||||
return `${year}-${month}-${day}_${hours}-${minutes}-${seconds}`;
|
||||
return `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}_${pad(now.getHours())}-${pad(now.getMinutes())}-${pad(now.getSeconds())}`;
|
||||
}
|
||||
|
||||
// Create a new snippet using Phase 0 schema
|
||||
@@ -174,19 +169,12 @@ function initializeSnippetsStorage() {
|
||||
// Format date for display in snippet list
|
||||
function formatSnippetDate(isoString) {
|
||||
const date = new Date(isoString);
|
||||
const now = new Date();
|
||||
const diffMs = now - date;
|
||||
const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));
|
||||
const diffDays = Math.floor((new Date() - date) / (1000 * 60 * 60 * 24));
|
||||
|
||||
if (diffDays === 0) {
|
||||
return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
|
||||
} else if (diffDays === 1) {
|
||||
return 'Yesterday';
|
||||
} else if (diffDays < 7) {
|
||||
return `${diffDays} days ago`;
|
||||
} else {
|
||||
if (diffDays === 0) return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
|
||||
if (diffDays === 1) return 'Yesterday';
|
||||
if (diffDays < 7) return `${diffDays} days ago`;
|
||||
return date.toLocaleDateString();
|
||||
}
|
||||
}
|
||||
|
||||
// Format full date/time for display in meta info
|
||||
@@ -409,9 +397,7 @@ function clearSelection() {
|
||||
if (editor) {
|
||||
window.isUpdatingEditor = true;
|
||||
editor.setValue('{}');
|
||||
setTimeout(() => {
|
||||
window.isUpdatingEditor = false;
|
||||
}, 50);
|
||||
}
|
||||
|
||||
// Hide meta panel and show placeholder
|
||||
@@ -459,9 +445,7 @@ function selectSnippet(snippetId) {
|
||||
if (editor) {
|
||||
window.isUpdatingEditor = true;
|
||||
editor.setValue(JSON.stringify(snippet.draftSpec, null, 2));
|
||||
setTimeout(() => {
|
||||
window.isUpdatingEditor = false;
|
||||
}, 50); // Small delay to ensure setValue completes
|
||||
}
|
||||
|
||||
// Show and populate meta fields
|
||||
@@ -524,12 +508,6 @@ function debouncedAutoSave() {
|
||||
|
||||
// Initialize auto-save on editor changes
|
||||
function initializeAutoSave() {
|
||||
if (editor) {
|
||||
editor.onDidChangeModelContent(() => {
|
||||
debouncedAutoSave();
|
||||
});
|
||||
}
|
||||
|
||||
// Initialize meta fields auto-save
|
||||
const nameField = document.getElementById('snippet-name');
|
||||
const commentField = document.getElementById('snippet-comment');
|
||||
@@ -651,19 +629,7 @@ function deleteSnippet(snippetId) {
|
||||
|
||||
// If we deleted the currently selected snippet, clear selection
|
||||
if (window.currentSnippetId === snippetId) {
|
||||
window.currentSnippetId = null;
|
||||
if (editor) {
|
||||
window.isUpdatingEditor = true;
|
||||
editor.setValue('{}');
|
||||
setTimeout(() => {
|
||||
window.isUpdatingEditor = false;
|
||||
}, 50);
|
||||
}
|
||||
// Hide comment field and show placeholder
|
||||
const metaSection = document.getElementById('snippet-meta');
|
||||
const placeholder = document.querySelector('.placeholder');
|
||||
if (metaSection) metaSection.style.display = 'none';
|
||||
if (placeholder) placeholder.style.display = 'block';
|
||||
clearSelection();
|
||||
}
|
||||
|
||||
// Refresh the list
|
||||
|
||||
Reference in New Issue
Block a user