Files
astrolabe/src/SnippetManager.js

170 lines
6.6 KiB
JavaScript

import { StorageManager } from './StorageManager.js';
import { UIManager } from './UIManager.js';
import { VisualizationManager } from './VisualizationManager.js';
import { EditorManager } from './EditorManager.js';
export class SnippetManager {
constructor() {
this.storageManager = new StorageManager();
this.uiManager = new UIManager(this);
this.visualizationManager = new VisualizationManager();
this.editorManager = new EditorManager(this);
this.currentSnippetId = null;
this.hasUnsavedChanges = false;
this.isDraftVersion = false;
this.readOnlyMode = false;
this.snippets = this.storageManager.loadSnippets();
this.uiManager.renderSnippetList(this.snippets, this.currentSnippetId);
}
setEditor(editor) {
this.editorManager.setEditor(editor);
if (this.snippets.length > 0) {
this.loadSnippet(this.snippets[0].id);
}
}
hasDraftChanges(id) {
const snippet = this.snippets.find(s => s.id === id);
return snippet && snippet.draft !== undefined;
}
loadSnippet(id, forceDraft = null) {
const snippet = this.snippets.find(s => s.id === id);
if (snippet) {
this.currentSnippetId = id;
const hasChanges = this.hasDraftChanges(id);
this.isDraftVersion = forceDraft !== null ? forceDraft : hasChanges;
const content = this.isDraftVersion && snippet.draft ?
snippet.draft :
snippet.content;
this.editorManager.setValue(content);
// Set hasUnsavedChanges to true if we're viewing a draft version
this.hasUnsavedChanges = this.isDraftVersion;
this.updateReadOnlyState();
this.uiManager.updateSaveButton(this.hasUnsavedChanges);
this.uiManager.updateVersionSwitch(this.currentSnippetId, this.isDraftVersion, hasChanges);
this.uiManager.renderSnippetList(this.snippets, this.currentSnippetId);
this.visualizationManager.updateVisualization(content);
}
}
createNewSnippet() {
const existingNames = this.snippets
.filter(s => s.name.startsWith('Snippet #'))
.map(s => parseInt(s.name.replace('Snippet #', '')))
.filter(n => !isNaN(n));
const nextNumber = existingNames.length > 0 ? Math.max(...existingNames) + 1 : 1;
const name = `Snippet #${nextNumber}`;
const id = 'snippet-' + Date.now();
const newSnippet = {
id,
name,
content: {
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"description": "New visualization",
"mark": "bar"
}
};
this.snippets.push(newSnippet);
this.storageManager.saveSnippets(this.snippets);
this.loadSnippet(id);
}
saveDraft() {
if (!this.currentSnippetId) return;
try {
const content = JSON.parse(this.editorManager.getValue());
const snippetIndex = this.snippets.findIndex(s => s.id === this.currentSnippetId);
if (snippetIndex !== -1) {
const currentSnippet = this.snippets[snippetIndex];
if (JSON.stringify(content) !== JSON.stringify(currentSnippet.content)) {
this.snippets[snippetIndex].draft = content;
this.isDraftVersion = true;
this.storageManager.saveSnippets(this.snippets);
this.uiManager.renderSnippetList(this.snippets, this.currentSnippetId);
this.uiManager.updateVersionSwitch(this.currentSnippetId, this.isDraftVersion, this.hasDraftChanges(this.currentSnippetId));
this.visualizationManager.updateVisualization(content);
}
}
} catch (e) {
console.error('Invalid JSON in editor');
}
}
saveCurrentSnippet() {
if (!this.currentSnippetId) return;
try {
const content = JSON.parse(this.editorManager.getValue());
const snippetIndex = this.snippets.findIndex(s => s.id === this.currentSnippetId);
if (snippetIndex !== -1) {
this.snippets[snippetIndex].content = content;
delete this.snippets[snippetIndex].draft; // Remove draft after saving
this.storageManager.saveSnippets(this.snippets);
this.hasUnsavedChanges = false;
this.isDraftVersion = false;
this.uiManager.updateSaveButton(this.hasUnsavedChanges);
this.uiManager.updateVersionSwitch(this.currentSnippetId, this.isDraftVersion, this.hasDraftChanges(this.currentSnippetId));
this.uiManager.renderSnippetList(this.snippets, this.currentSnippetId);
}
} catch (e) {
alert('Invalid JSON in editor');
}
}
handleReadOnlyOverride() {
this.readOnlyMode = false;
this.isDraftVersion = true;
delete this.snippets.find(s => s.id === this.currentSnippetId).draft;
this.storageManager.saveSnippets(this.snippets);
this.uiManager.updateVersionSwitch(this.currentSnippetId, this.isDraftVersion, this.hasDraftChanges(this.currentSnippetId));
this.uiManager.renderSnippetList(this.snippets, this.currentSnippetId);
}
// Remove these methods as they're now in UIManager
updateSaveButton() {
this.uiManager.updateSaveButton(this.hasUnsavedChanges);
}
updateVersionSwitch() {
this.uiManager.updateVersionSwitch(
this.currentSnippetId,
this.isDraftVersion,
this.hasDraftChanges(this.currentSnippetId)
);
}
updateReadOnlyState() {
const hasChanges = this.hasDraftChanges(this.currentSnippetId);
this.readOnlyMode = hasChanges && !this.isDraftVersion;
this.editorManager.updateReadOnlyState(this.readOnlyMode);
}
deleteSnippet(id) {
if (confirm('Are you sure you want to delete this snippet?')) {
this.snippets = this.snippets.filter(s => s.id !== id);
this.storageManager.saveSnippets(this.snippets);
if (this.currentSnippetId === id) {
this.currentSnippetId = null;
if (this.snippets.length > 0) {
this.loadSnippet(this.snippets[0].id);
} else {
this.editorManager.setValue('');
}
}
this.uiManager.renderSnippetList(this.snippets, this.currentSnippetId);
}
}
}