diff --git a/public/index.html b/public/index.html
index 8a9eacc..0dffe3c 100644
--- a/public/index.html
+++ b/public/index.html
@@ -143,6 +143,7 @@
+
diff --git a/public/scripts/constants.js b/public/scripts/constants.js
new file mode 100644
index 0000000..0f577c9
--- /dev/null
+++ b/public/scripts/constants.js
@@ -0,0 +1,27 @@
+(function(){
+ const TIMING = {
+ NAV_COOLDOWN_MS: 300,
+ VIEW_FADE_OUT_MS: 150,
+ VIEW_FADE_IN_MS: 200,
+ VIEW_FADE_DELAY_MS: 50,
+ AUTO_REFRESH_MS: 30000,
+ PRIMARY_NODE_REFRESH_MS: 10000,
+ LOAD_GUARD_MS: 10000
+ };
+
+ const SELECTORS = {
+ NAV_TAB: '.nav-tab',
+ VIEW_CONTENT: '.view-content',
+ CLUSTER_STATUS: '.cluster-status'
+ };
+
+ const CLASSES = {
+ CLUSTER_STATUS_ONLINE: 'cluster-status-online',
+ CLUSTER_STATUS_OFFLINE: 'cluster-status-offline',
+ CLUSTER_STATUS_CONNECTING: 'cluster-status-connecting',
+ CLUSTER_STATUS_ERROR: 'cluster-status-error',
+ CLUSTER_STATUS_DISCOVERING: 'cluster-status-discovering'
+ };
+
+ window.CONSTANTS = window.CONSTANTS || { TIMING, SELECTORS, CLASSES };
+})();
\ No newline at end of file
diff --git a/public/scripts/framework.js b/public/scripts/framework.js
index ada9fb0..43ba9e8 100644
--- a/public/scripts/framework.js
+++ b/public/scripts/framework.js
@@ -614,7 +614,7 @@ class App {
this.navigationInProgress = false;
this.navigationQueue = [];
this.lastNavigationTime = 0;
- this.navigationCooldown = 300; // 300ms cooldown between navigations
+ this.navigationCooldown = (window.CONSTANTS && window.CONSTANTS.TIMING.NAV_COOLDOWN_MS) || 300; // cooldown between navigations
// Component cache to keep components alive
this.componentCache = new Map();
@@ -750,11 +750,11 @@ class App {
// Fade out the container
if (this.currentView.container) {
this.currentView.container.style.opacity = '0';
- this.currentView.container.style.transition = 'opacity 0.15s ease-out';
+ this.currentView.container.style.transition = `opacity ${(window.CONSTANTS && window.CONSTANTS.TIMING.VIEW_FADE_OUT_MS) || 150}ms ease-out`;
}
// Wait for fade out to complete
- await new Promise(resolve => setTimeout(resolve, 150));
+ await new Promise(resolve => setTimeout(resolve, (window.CONSTANTS && window.CONSTANTS.TIMING.VIEW_FADE_OUT_MS) || 150));
}
// Show view smoothly
@@ -772,10 +772,10 @@ class App {
// Fade in the container
container.style.opacity = '0';
- container.style.transition = 'opacity 0.2s ease-in';
+ container.style.transition = `opacity ${(window.CONSTANTS && window.CONSTANTS.TIMING.VIEW_FADE_IN_MS) || 200}ms ease-in`;
// Small delay to ensure smooth transition
- await new Promise(resolve => setTimeout(resolve, 50));
+ await new Promise(resolve => setTimeout(resolve, (window.CONSTANTS && window.CONSTANTS.TIMING.VIEW_FADE_DELAY_MS) || 50));
// Fade in
container.style.opacity = '1';
@@ -784,7 +784,7 @@ class App {
// Update navigation state
updateNavigation(activeRoute) {
// Remove active class from all nav tabs
- document.querySelectorAll('.nav-tab').forEach(tab => {
+ document.querySelectorAll((window.CONSTANTS && window.CONSTANTS.SELECTORS.NAV_TAB) || '.nav-tab').forEach(tab => {
tab.classList.remove('active');
});
@@ -795,7 +795,7 @@ class App {
}
// Hide all view contents with smooth transition
- document.querySelectorAll('.view-content').forEach(view => {
+ document.querySelectorAll((window.CONSTANTS && window.CONSTANTS.SELECTORS.VIEW_CONTENT) || '.view-content').forEach(view => {
view.classList.remove('active');
view.style.opacity = '0';
view.style.transition = 'opacity 0.15s ease-out';
@@ -838,7 +838,7 @@ class App {
// Setup navigation
setupNavigation() {
- document.querySelectorAll('.nav-tab').forEach(tab => {
+ document.querySelectorAll((window.CONSTANTS && window.CONSTANTS.SELECTORS.NAV_TAB) || '.nav-tab').forEach(tab => {
tab.addEventListener('click', () => {
const routeName = tab.dataset.view;
this.navigateTo(routeName);