refactor: Modularize UI components and utilities
- Extract UI components into separate JS files - Centralize configuration values in config.js - Introduce a dedicated logger module - Improve file tree drag-and-drop and undo functionality - Refactor modal handling to a single manager - Add URL routing support for SPA navigation - Implement view mode for read-only access
This commit is contained in:
126
static/js/event-bus.js
Normal file
126
static/js/event-bus.js
Normal file
@@ -0,0 +1,126 @@
|
||||
/**
|
||||
* Event Bus Module
|
||||
* Provides a centralized event system for application-wide communication
|
||||
* Allows components to communicate without tight coupling
|
||||
*/
|
||||
|
||||
class EventBus {
|
||||
constructor() {
|
||||
/**
|
||||
* Map of event names to arrays of listener functions
|
||||
* @type {Object.<string, Function[]>}
|
||||
*/
|
||||
this.listeners = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an event listener
|
||||
* @param {string} event - The event name to listen for
|
||||
* @param {Function} callback - The function to call when the event is dispatched
|
||||
* @returns {Function} A function to unregister this listener
|
||||
*/
|
||||
on(event, callback) {
|
||||
if (!this.listeners[event]) {
|
||||
this.listeners[event] = [];
|
||||
}
|
||||
this.listeners[event].push(callback);
|
||||
|
||||
// Return unsubscribe function
|
||||
return () => this.off(event, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a one-time event listener
|
||||
* The listener will be automatically removed after being called once
|
||||
* @param {string} event - The event name to listen for
|
||||
* @param {Function} callback - The function to call when the event is dispatched
|
||||
* @returns {Function} A function to unregister this listener
|
||||
*/
|
||||
once(event, callback) {
|
||||
const onceWrapper = (data) => {
|
||||
callback(data);
|
||||
this.off(event, onceWrapper);
|
||||
};
|
||||
return this.on(event, onceWrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister an event listener
|
||||
* @param {string} event - The event name
|
||||
* @param {Function} callback - The callback function to remove
|
||||
*/
|
||||
off(event, callback) {
|
||||
if (!this.listeners[event]) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.listeners[event] = this.listeners[event].filter(
|
||||
listener => listener !== callback
|
||||
);
|
||||
|
||||
// Clean up empty listener arrays
|
||||
if (this.listeners[event].length === 0) {
|
||||
delete this.listeners[event];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch an event to all registered listeners
|
||||
* @param {string} event - The event name to dispatch
|
||||
* @param {any} data - The data to pass to the listeners
|
||||
*/
|
||||
dispatch(event, data) {
|
||||
if (!this.listeners[event]) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a copy of the listeners array to avoid issues if listeners are added/removed during dispatch
|
||||
const listeners = [...this.listeners[event]];
|
||||
|
||||
listeners.forEach(callback => {
|
||||
try {
|
||||
callback(data);
|
||||
} catch (error) {
|
||||
Logger.error(`Error in event listener for "${event}":`, error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all listeners for a specific event
|
||||
* If no event is specified, removes all listeners for all events
|
||||
* @param {string} [event] - The event name (optional)
|
||||
*/
|
||||
clear(event) {
|
||||
if (event) {
|
||||
delete this.listeners[event];
|
||||
} else {
|
||||
this.listeners = {};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of listeners for an event
|
||||
* @param {string} event - The event name
|
||||
* @returns {number} The number of listeners
|
||||
*/
|
||||
listenerCount(event) {
|
||||
return this.listeners[event] ? this.listeners[event].length : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all event names that have listeners
|
||||
* @returns {string[]} Array of event names
|
||||
*/
|
||||
eventNames() {
|
||||
return Object.keys(this.listeners);
|
||||
}
|
||||
}
|
||||
|
||||
// Create and export the global event bus instance
|
||||
const eventBus = new EventBus();
|
||||
|
||||
// Make it globally available
|
||||
window.eventBus = eventBus;
|
||||
window.EventBus = EventBus;
|
||||
|
||||
Reference in New Issue
Block a user