django-cfg 1.4.87__py3-none-any.whl → 1.4.89__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of django-cfg might be problematic. Click here for more details.
- django_cfg/__init__.py +1 -1
- django_cfg/apps/centrifugo/views/__init__.py +0 -2
- django_cfg/apps/dashboard/permissions.py +48 -0
- django_cfg/apps/dashboard/serializers/__init__.py +8 -1
- django_cfg/apps/dashboard/serializers/commands.py +29 -0
- django_cfg/apps/dashboard/services/__init__.py +2 -0
- django_cfg/{modules/django_unfold/callbacks/base.py → apps/dashboard/services/commands_security.py} +28 -90
- django_cfg/apps/dashboard/services/commands_service.py +208 -9
- django_cfg/apps/dashboard/services/overview_service.py +205 -0
- django_cfg/apps/dashboard/views/commands_views.py +92 -4
- django_cfg/apps/frontend/test_routing.py +134 -0
- django_cfg/apps/frontend/views.py +73 -28
- django_cfg/apps/urls.py +0 -1
- django_cfg/core/builders/apps_builder.py +0 -58
- django_cfg/modules/django_unfold/__init__.py +5 -24
- django_cfg/modules/django_unfold/models/__init__.py +0 -23
- django_cfg/modules/django_unfold/models/config.py +11 -65
- django_cfg/modules/django_unfold/{dashboard.py → navigation.py} +21 -152
- django_cfg/modules/django_unfold/tailwind.py +2 -4
- django_cfg/pyproject.toml +1 -1
- django_cfg/registry/third_party.py +0 -9
- django_cfg/routing/callbacks.py +1 -43
- django_cfg/static/frontend/admin/404/index.html +1 -1
- django_cfg/static/frontend/admin/404.html +1 -1
- django_cfg/static/frontend/admin/500/index.html +1 -1
- django_cfg/static/frontend/admin/_next/static/{ZJZBgOL9mO1koHrgaaLEV → 0sN9ktsgXH48ygtGSrhfu}/_buildManifest.js +1 -1
- django_cfg/static/frontend/admin/_next/static/chunks/{19430.fe7bff7372f8a256.js → 19430.c4c95603c23c17fe.js} +1 -1
- django_cfg/static/frontend/admin/_next/static/chunks/50314-9443faa6df24aebf.js +1 -0
- django_cfg/static/frontend/admin/_next/static/chunks/94141-bc6d47f419b26b21.js +1 -0
- django_cfg/static/frontend/admin/_next/static/chunks/pages/{_app-c336f254967dd101.js → _app-c7dcd3aa616fab68.js} +6 -6
- django_cfg/static/frontend/admin/_next/static/chunks/pages/legal/{cookies-b39c7f22c066e2c6.js → cookies-97d279800f12aab4.js} +1 -1
- django_cfg/static/frontend/admin/_next/static/chunks/pages/legal/{privacy-5aedad0cf3a4f80f.js → privacy-1d5e6cd94689247e.js} +1 -1
- django_cfg/static/frontend/admin/_next/static/chunks/pages/legal/{security-dbd854d0d5d483e2.js → security-55e49700e7a01f5a.js} +1 -1
- django_cfg/static/frontend/admin/_next/static/chunks/pages/legal/{terms-f3e1d2b9e5edf12f.js → terms-14c02bb2d3198352.js} +1 -1
- django_cfg/static/frontend/admin/_next/static/chunks/pages/private/{centrifugo-22532c65971225eb.js → centrifugo-f9ecbc3ae0052a03.js} +1 -1
- django_cfg/static/frontend/admin/_next/static/chunks/pages/private-d4ccbe1265cbd853.js +1 -0
- django_cfg/static/frontend/admin/_next/static/chunks/{webpack-da114020a6b940f5.js → webpack-5a92f81363b62aa7.js} +1 -1
- django_cfg/static/frontend/admin/_next/static/css/3063068f0d5a8a00.css +3 -0
- django_cfg/static/frontend/admin/_next/static/media/19cfc7226ec3afaa-s.woff2 +0 -0
- django_cfg/static/frontend/admin/_next/static/media/21350d82a1f187e9-s.p.woff2 +0 -0
- django_cfg/static/frontend/admin/_next/static/media/8e9860b6e62d6359-s.woff2 +0 -0
- django_cfg/static/frontend/admin/_next/static/media/ba9851c3c22cd980-s.woff2 +0 -0
- django_cfg/static/frontend/admin/_next/static/media/c5fe6dc8356a8c31-s.woff2 +0 -0
- django_cfg/static/frontend/admin/_next/static/media/df0a9ae256c0569c-s.woff2 +0 -0
- django_cfg/static/frontend/admin/_next/static/media/e4af272ccee01ff0-s.p.woff2 +0 -0
- django_cfg/static/frontend/admin/auth/index.html +1 -1
- django_cfg/static/frontend/admin/index.html +1 -1
- django_cfg/static/frontend/admin/legal/cookies/index.html +1 -1
- django_cfg/static/frontend/admin/legal/privacy/index.html +1 -1
- django_cfg/static/frontend/admin/legal/security/index.html +1 -1
- django_cfg/static/frontend/admin/legal/terms/index.html +1 -1
- django_cfg/static/frontend/admin/private/centrifugo/index.html +1 -1
- django_cfg/static/frontend/admin/private/index.html +1 -1
- django_cfg/static/frontend/admin/private/profile/index.html +1 -1
- django_cfg/static/frontend/admin/private/ui/index.html +2 -2
- django_cfg/templates/admin/index.html +1 -1
- {django_cfg-1.4.87.dist-info → django_cfg-1.4.89.dist-info}/METADATA +1 -1
- {django_cfg-1.4.87.dist-info → django_cfg-1.4.89.dist-info}/RECORD +62 -163
- django_cfg/apps/centrifugo/static/django_cfg_centrifugo/css/dashboard.css +0 -260
- django_cfg/apps/centrifugo/static/django_cfg_centrifugo/js/dashboard/live_channels.mjs +0 -313
- django_cfg/apps/centrifugo/static/django_cfg_centrifugo/js/dashboard/live_testing.mjs +0 -803
- django_cfg/apps/centrifugo/static/django_cfg_centrifugo/js/dashboard/main.mjs +0 -341
- django_cfg/apps/centrifugo/static/django_cfg_centrifugo/js/dashboard/overview.mjs +0 -432
- django_cfg/apps/centrifugo/static/django_cfg_centrifugo/js/dashboard/testing.mjs +0 -33
- django_cfg/apps/centrifugo/static/django_cfg_centrifugo/js/dashboard/websocket.mjs +0 -210
- django_cfg/apps/centrifugo/templates/django_cfg_centrifugo/components/channels_content.html +0 -46
- django_cfg/apps/centrifugo/templates/django_cfg_centrifugo/components/live_channels_content.html +0 -123
- django_cfg/apps/centrifugo/templates/django_cfg_centrifugo/components/overview_content.html +0 -45
- django_cfg/apps/centrifugo/templates/django_cfg_centrifugo/components/publishes_content.html +0 -84
- django_cfg/apps/centrifugo/templates/django_cfg_centrifugo/components/stat_cards.html +0 -53
- django_cfg/apps/centrifugo/templates/django_cfg_centrifugo/components/system_status.html +0 -91
- django_cfg/apps/centrifugo/templates/django_cfg_centrifugo/components/tab_navigation.html +0 -29
- django_cfg/apps/centrifugo/templates/django_cfg_centrifugo/components/testing_tools.html +0 -415
- django_cfg/apps/centrifugo/templates/django_cfg_centrifugo/layout/base.html +0 -61
- django_cfg/apps/centrifugo/templates/django_cfg_centrifugo/pages/dashboard.html +0 -58
- django_cfg/apps/centrifugo/templates/django_cfg_centrifugo/tags/connection_script.html +0 -48
- django_cfg/apps/centrifugo/templatetags/__init__.py +0 -1
- django_cfg/apps/centrifugo/templatetags/centrifugo_tags.py +0 -81
- django_cfg/apps/centrifugo/urls_admin.py +0 -20
- django_cfg/apps/centrifugo/views/dashboard.py +0 -28
- django_cfg/modules/django_dashboard/__init__.py +0 -23
- django_cfg/modules/django_dashboard/components.py +0 -312
- django_cfg/modules/django_dashboard/debug.py +0 -174
- django_cfg/modules/django_dashboard/management/__init__.py +0 -0
- django_cfg/modules/django_dashboard/management/commands/__init__.py +0 -0
- django_cfg/modules/django_dashboard/management/commands/debug_dashboard.py +0 -109
- django_cfg/modules/django_dashboard/sections/__init__.py +0 -1
- django_cfg/modules/django_dashboard/sections/base.py +0 -129
- django_cfg/modules/django_dashboard/sections/commands.py +0 -33
- django_cfg/modules/django_dashboard/sections/documentation.py +0 -393
- django_cfg/modules/django_dashboard/sections/overview.py +0 -398
- django_cfg/modules/django_dashboard/sections/stats.py +0 -48
- django_cfg/modules/django_dashboard/sections/system.py +0 -74
- django_cfg/modules/django_dashboard/sections/widgets.py +0 -222
- django_cfg/modules/django_unfold/callbacks/__init__.py +0 -9
- django_cfg/modules/django_unfold/callbacks/actions.py +0 -51
- django_cfg/modules/django_unfold/callbacks/apizones.py +0 -122
- django_cfg/modules/django_unfold/callbacks/charts.py +0 -223
- django_cfg/modules/django_unfold/callbacks/commands.py +0 -40
- django_cfg/modules/django_unfold/callbacks/main.py +0 -322
- django_cfg/modules/django_unfold/callbacks/statistics.py +0 -240
- django_cfg/modules/django_unfold/callbacks/system.py +0 -180
- django_cfg/modules/django_unfold/callbacks/users.py +0 -65
- django_cfg/modules/django_unfold/models/dashboard.py +0 -207
- django_cfg/modules/django_unfold/models/tabs.py +0 -26
- django_cfg/modules/django_unfold/models.py +0 -98
- django_cfg/modules/django_unfold/templates/unfold/helpers/app_list.html +0 -102
- django_cfg/static/frontend/admin/_next/static/chunks/23004-faae121bbfecc163.js +0 -1
- django_cfg/static/frontend/admin/_next/static/chunks/50314-48bd5701f62faf27.js +0 -1
- django_cfg/static/frontend/admin/_next/static/chunks/pages/private-fe9faa86ecdb0ce6.js +0 -1
- django_cfg/static/frontend/admin/_next/static/css/5f9a37b6e6a72303.css +0 -3
- django_cfg/static/frontend/admin/_next/static/media/438aa629764e75f3-s.woff2 +0 -0
- django_cfg/static/frontend/admin/_next/static/media/4c9affa5bc8f420e-s.p.woff2 +0 -0
- django_cfg/static/frontend/admin/_next/static/media/51251f8b9793cdb3-s.woff2 +0 -0
- django_cfg/static/frontend/admin/_next/static/media/875ae681bfde4580-s.p.woff2 +0 -0
- django_cfg/static/frontend/admin/_next/static/media/cc978ac5ee68c2b6-s.woff2 +0 -0
- django_cfg/static/frontend/admin/_next/static/media/e857b654a2caa584-s.woff2 +0 -0
- django_cfg/templates/admin/sections/commands_section.html +0 -5
- django_cfg/templates/admin/sections/documentation_section.html +0 -5
- django_cfg/templates/admin/sections/overview_section.html +0 -5
- django_cfg/templates/admin/sections/stats_section.html +0 -5
- django_cfg/templates/admin/sections/system_section.html +0 -5
- django_cfg/templates/admin/sections/widgets_section.html +0 -11
- django_cfg/templates/admin_old/components/action_grid.html +0 -49
- django_cfg/templates/admin_old/components/card.html +0 -50
- django_cfg/templates/admin_old/components/data_table.html +0 -67
- django_cfg/templates/admin_old/components/metric_card.html +0 -39
- django_cfg/templates/admin_old/components/modal.html +0 -58
- django_cfg/templates/admin_old/components/progress_bar.html +0 -20
- django_cfg/templates/admin_old/components/section_header.html +0 -26
- django_cfg/templates/admin_old/components/stat_item.html +0 -32
- django_cfg/templates/admin_old/components/stats_grid.html +0 -72
- django_cfg/templates/admin_old/components/status_badge.html +0 -28
- django_cfg/templates/admin_old/components/user_avatar.html +0 -27
- django_cfg/templates/admin_old/constance/change_list.html +0 -74
- django_cfg/templates/admin_old/constance/includes/default_value.html +0 -24
- django_cfg/templates/admin_old/constance/includes/fieldset_header.html +0 -15
- django_cfg/templates/admin_old/constance/includes/results_list.html +0 -16
- django_cfg/templates/admin_old/constance/includes/setting_row.html +0 -50
- django_cfg/templates/admin_old/constance/includes/table_headers.html +0 -10
- django_cfg/templates/admin_old/examples/component_class_example.html +0 -156
- django_cfg/templates/admin_old/import_export/change_list_export.html +0 -24
- django_cfg/templates/admin_old/import_export/change_list_import.html +0 -24
- django_cfg/templates/admin_old/import_export/change_list_import_export.html +0 -34
- django_cfg/templates/admin_old/index.html +0 -80
- django_cfg/templates/admin_old/index_new.html +0 -119
- django_cfg/templates/admin_old/layouts/base_dashboard.html +0 -62
- django_cfg/templates/admin_old/layouts/dashboard_with_tabs.html +0 -176
- django_cfg/templates/admin_old/sections/commands_section.html +0 -549
- django_cfg/templates/admin_old/sections/documentation_section.html +0 -152
- django_cfg/templates/admin_old/sections/overview_section.html +0 -112
- django_cfg/templates/admin_old/sections/stats_section.html +0 -35
- django_cfg/templates/admin_old/sections/system_section.html +0 -99
- django_cfg/templates/admin_old/sections/widgets_section.html +0 -129
- django_cfg/templates/admin_old/snippets/components/activity_tracker.html +0 -70
- django_cfg/templates/admin_old/snippets/components/charts_section.html +0 -113
- django_cfg/templates/admin_old/snippets/components/django_commands.html +0 -270
- django_cfg/templates/admin_old/snippets/components/quick_actions.html +0 -66
- django_cfg/templates/admin_old/snippets/components/recent_activity_improved.html +0 -25
- django_cfg/templates/admin_old/snippets/components/recent_users_table.html +0 -102
- django_cfg/templates/admin_old/snippets/components/stats_cards.html +0 -4
- django_cfg/templates/admin_old/snippets/components/stats_tiles.html +0 -92
- django_cfg/templates/admin_old/snippets/components/system_health.html +0 -22
- django_cfg/templates/admin_old/snippets/components/system_metrics.html +0 -199
- django_cfg/templates/admin_old/snippets/components/user_permissions.html +0 -57
- django_cfg/templates/admin_old/snippets/tabs/app_stats_tab.html +0 -201
- django_cfg/templates/admin_old/snippets/tabs/commands_tab.html +0 -114
- django_cfg/templates/admin_old/snippets/tabs/documentation_tab.html +0 -42
- django_cfg/templates/admin_old/snippets/tabs/overview_tab.html +0 -116
- django_cfg/templates/admin_old/snippets/tabs/stats_tab.html +0 -89
- django_cfg/templates/admin_old/snippets/tabs/users_tab.html +0 -51
- django_cfg/templates/admin_old/snippets/tabs/widgets_tab.html +0 -38
- django_cfg/templates/admin_old/snippets/zones/zones_table.html +0 -176
- /django_cfg/static/frontend/admin/_next/static/{ZJZBgOL9mO1koHrgaaLEV → 0sN9ktsgXH48ygtGSrhfu}/_ssgManifest.js +0 -0
- {django_cfg-1.4.87.dist-info → django_cfg-1.4.89.dist-info}/WHEEL +0 -0
- {django_cfg-1.4.87.dist-info → django_cfg-1.4.89.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.4.87.dist-info → django_cfg-1.4.89.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,341 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Main Centrifugo Dashboard Controller
|
|
3
|
-
* Orchestrates all dashboard modules and handles tab navigation
|
|
4
|
-
*/
|
|
5
|
-
import { OverviewModule } from './overview.mjs';
|
|
6
|
-
import { UsageGuideModule } from './testing.mjs';
|
|
7
|
-
import { LiveChannelsModule } from './live_channels.mjs';
|
|
8
|
-
import { LiveTestingModule } from './live_testing.mjs';
|
|
9
|
-
import { WebSocketModule } from './websocket.mjs';
|
|
10
|
-
|
|
11
|
-
class CentrifugoDashboard {
|
|
12
|
-
constructor() {
|
|
13
|
-
this.api = window.centrifugoAPI;
|
|
14
|
-
this.currentTab = 'overview';
|
|
15
|
-
this.autoRefresh = true;
|
|
16
|
-
this.refreshInterval = null;
|
|
17
|
-
this.refreshRate = 5000; // 5 seconds
|
|
18
|
-
|
|
19
|
-
// Initialize modules
|
|
20
|
-
this.overviewModule = new OverviewModule(this.api, this);
|
|
21
|
-
this.usageGuideModule = new UsageGuideModule(this.api, this);
|
|
22
|
-
this.liveChannelsModule = new LiveChannelsModule(this.api, this);
|
|
23
|
-
this.liveTestingModule = new LiveTestingModule(this.api, this);
|
|
24
|
-
this.websocketModule = new WebSocketModule(this);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
init() {
|
|
28
|
-
console.log('=� Centrifugo Dashboard initializing...');
|
|
29
|
-
this.setupEventListeners();
|
|
30
|
-
this.usageGuideModule.init();
|
|
31
|
-
this.loadInitialData();
|
|
32
|
-
this.startAutoRefresh();
|
|
33
|
-
|
|
34
|
-
// Initialize WebSocket for real-time updates
|
|
35
|
-
this.websocketModule.init();
|
|
36
|
-
console.log(' Centrifugo Dashboard initialized');
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
isValidTab(tabName) {
|
|
40
|
-
const validTabs = ['overview', 'usage-guide', 'live-channels'];
|
|
41
|
-
return validTabs.includes(tabName);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
setupEventListeners() {
|
|
45
|
-
// Check URL hash on page load
|
|
46
|
-
const hash = window.location.hash.slice(1); // Remove #
|
|
47
|
-
if (hash && this.isValidTab(hash)) {
|
|
48
|
-
this.currentTab = hash;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const tabButtons = document.querySelectorAll('.tab-button');
|
|
52
|
-
tabButtons.forEach(button => {
|
|
53
|
-
button.addEventListener('click', (e) => {
|
|
54
|
-
const tabName = e.currentTarget.dataset.tab;
|
|
55
|
-
this.switchTab(tabName);
|
|
56
|
-
});
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
// Handle browser back/forward buttons
|
|
60
|
-
window.addEventListener('hashchange', () => {
|
|
61
|
-
const hash = window.location.hash.slice(1);
|
|
62
|
-
if (hash && this.isValidTab(hash)) {
|
|
63
|
-
this.switchTab(hash, false); // Don't update hash again
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
const autoRefreshToggle = document.getElementById('auto-refresh-toggle');
|
|
68
|
-
if (autoRefreshToggle) {
|
|
69
|
-
autoRefreshToggle.checked = this.autoRefresh;
|
|
70
|
-
autoRefreshToggle.addEventListener('change', (e) => {
|
|
71
|
-
this.autoRefresh = e.target.checked;
|
|
72
|
-
if (this.autoRefresh) {
|
|
73
|
-
this.startAutoRefresh();
|
|
74
|
-
} else {
|
|
75
|
-
this.stopAutoRefresh();
|
|
76
|
-
}
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
switchTab(tabName, updateHash = true) {
|
|
82
|
-
console.log('Switching to tab:', tabName);
|
|
83
|
-
|
|
84
|
-
// Update URL hash
|
|
85
|
-
if (updateHash) {
|
|
86
|
-
window.history.pushState(null, '', `#${tabName}`);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
document.querySelectorAll('.tab-button').forEach(btn => {
|
|
90
|
-
if (btn.dataset.tab === tabName) {
|
|
91
|
-
btn.classList.add('active', 'text-purple-600', 'dark:text-purple-400', 'border-purple-600', 'dark:border-purple-400');
|
|
92
|
-
btn.classList.remove('text-gray-600', 'dark:text-gray-400', 'border-transparent');
|
|
93
|
-
} else {
|
|
94
|
-
btn.classList.remove('active', 'text-purple-600', 'dark:text-purple-400', 'border-purple-600', 'dark:border-purple-400');
|
|
95
|
-
btn.classList.add('text-gray-600', 'dark:text-gray-400', 'border-transparent');
|
|
96
|
-
}
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
document.querySelectorAll('.tab-panel').forEach(panel => {
|
|
100
|
-
panel.classList.add('hidden');
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
const activePanel = document.getElementById(tabName + '-tab');
|
|
104
|
-
if (activePanel) {
|
|
105
|
-
activePanel.classList.remove('hidden');
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
this.currentTab = tabName;
|
|
109
|
-
|
|
110
|
-
// Update connection status when switching to usage-guide tab
|
|
111
|
-
if (tabName === 'usage-guide' && this.liveTestingModule) {
|
|
112
|
-
this.liveTestingModule.updateConnectionStatus(
|
|
113
|
-
this.liveTestingModule.centrifuge !== null
|
|
114
|
-
);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
this.loadTabData(tabName);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
async loadInitialData() {
|
|
121
|
-
console.log('Loading initial data...');
|
|
122
|
-
|
|
123
|
-
// If tab was set from hash, switch to it
|
|
124
|
-
if (this.currentTab !== 'overview') {
|
|
125
|
-
this.switchTab(this.currentTab, false);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
await this.loadHealthStatus();
|
|
129
|
-
await this.loadTabData(this.currentTab);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
async loadTabData(tabName) {
|
|
133
|
-
console.log('Loading data for tab:', tabName);
|
|
134
|
-
|
|
135
|
-
try {
|
|
136
|
-
// Always update overview stats (for stat cards at top)
|
|
137
|
-
await this.overviewModule.loadOverviewStats();
|
|
138
|
-
|
|
139
|
-
if (tabName === 'usage-guide') {
|
|
140
|
-
// Usage guide tab doesn't need data loading (static content)
|
|
141
|
-
return;
|
|
142
|
-
} else if (tabName === 'live-channels') {
|
|
143
|
-
// Load live channels from Centrifugo server
|
|
144
|
-
await this.liveChannelsModule.loadLiveChannels();
|
|
145
|
-
} else {
|
|
146
|
-
await this.overviewModule.loadData(tabName);
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
this.updateLastUpdate();
|
|
150
|
-
} catch (error) {
|
|
151
|
-
console.error('Error loading tab data:', error);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
async loadHealthStatus() {
|
|
156
|
-
try {
|
|
157
|
-
const health = await this.api.centrifugoAdminApiMonitorHealthRetrieve();
|
|
158
|
-
|
|
159
|
-
if (health) {
|
|
160
|
-
const indicator = document.getElementById('health-indicator');
|
|
161
|
-
if (indicator) {
|
|
162
|
-
// Health status is based on whether wrapper_url is configured
|
|
163
|
-
const isHealthy = health.status === 'healthy' && health.wrapper_url;
|
|
164
|
-
const statusColor = isHealthy ? 'bg-green-500' : 'bg-red-500';
|
|
165
|
-
const statusText = isHealthy ? 'Configured' : 'Not Configured';
|
|
166
|
-
const html = '<span class="pulse-dot w-2 h-2 ' + statusColor + ' rounded-full"></span>' +
|
|
167
|
-
'<span class="text-xs font-medium text-gray-600 dark:text-gray-400">' + statusText + '</span>';
|
|
168
|
-
indicator.innerHTML = html;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
this.updateSystemStatus(health);
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// Also load live server info
|
|
175
|
-
await this.loadServerInfo();
|
|
176
|
-
} catch (error) {
|
|
177
|
-
console.error('Error loading health status:', error);
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
async loadServerInfo() {
|
|
182
|
-
try {
|
|
183
|
-
console.log('Loading Centrifugo server info...');
|
|
184
|
-
|
|
185
|
-
// Call Server API to get live stats
|
|
186
|
-
const response = await this.api.centrifugoAdminApiServerInfoCreate();
|
|
187
|
-
|
|
188
|
-
if (response && response.result && response.result.nodes && response.result.nodes.length > 0) {
|
|
189
|
-
const node = response.result.nodes[0]; // First node
|
|
190
|
-
|
|
191
|
-
// Update server version and uptime
|
|
192
|
-
this.updateElement('server-version-text', `${node.name} v${node.version}`);
|
|
193
|
-
this.updateElement('server-uptime-text', `Uptime: ${this.formatUptime(node.uptime)}`);
|
|
194
|
-
|
|
195
|
-
// Update live connection stats
|
|
196
|
-
this.updateElement('live-clients-count', node.num_clients.toLocaleString());
|
|
197
|
-
this.updateElement('live-users-count', node.num_users.toLocaleString());
|
|
198
|
-
this.updateElement('live-channels-count', node.num_channels.toLocaleString());
|
|
199
|
-
this.updateElement('live-subs-count', node.num_subs.toLocaleString());
|
|
200
|
-
|
|
201
|
-
// Update server status icon
|
|
202
|
-
const serverIcon = document.getElementById('server-status-icon');
|
|
203
|
-
if (serverIcon) {
|
|
204
|
-
serverIcon.className = 'material-icons flex-shrink-0 text-2xl text-green-500';
|
|
205
|
-
serverIcon.textContent = 'check_circle';
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
console.log('Server info loaded:', node);
|
|
209
|
-
} else if (response && response.error) {
|
|
210
|
-
console.error('Server API error:', response.error);
|
|
211
|
-
this.showServerError(response.error.message);
|
|
212
|
-
}
|
|
213
|
-
} catch (error) {
|
|
214
|
-
console.error('Failed to load server info:', error);
|
|
215
|
-
this.showServerError('Failed to connect to Centrifugo server');
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
formatUptime(seconds) {
|
|
220
|
-
const days = Math.floor(seconds / 86400);
|
|
221
|
-
const hours = Math.floor((seconds % 86400) / 3600);
|
|
222
|
-
const minutes = Math.floor((seconds % 3600) / 60);
|
|
223
|
-
|
|
224
|
-
if (days > 0) {
|
|
225
|
-
return `${days}d ${hours}h ${minutes}m`;
|
|
226
|
-
} else if (hours > 0) {
|
|
227
|
-
return `${hours}h ${minutes}m`;
|
|
228
|
-
} else {
|
|
229
|
-
return `${minutes}m`;
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
showServerError(message) {
|
|
234
|
-
this.updateElement('server-version-text', 'Offline');
|
|
235
|
-
this.updateElement('server-uptime-text', message);
|
|
236
|
-
this.updateElement('live-clients-count', '?');
|
|
237
|
-
this.updateElement('live-users-count', '?');
|
|
238
|
-
this.updateElement('live-channels-count', '?');
|
|
239
|
-
this.updateElement('live-subs-count', '?');
|
|
240
|
-
|
|
241
|
-
const serverIcon = document.getElementById('server-status-icon');
|
|
242
|
-
if (serverIcon) {
|
|
243
|
-
serverIcon.className = 'material-icons flex-shrink-0 text-2xl text-red-500';
|
|
244
|
-
serverIcon.textContent = 'error';
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
updateSystemStatus(health) {
|
|
249
|
-
const statusContainer = document.getElementById('system-status');
|
|
250
|
-
if (!statusContainer) return;
|
|
251
|
-
|
|
252
|
-
// Wrapper status
|
|
253
|
-
const wrapperColor = health.wrapper_url ? 'text-green-500' : 'text-gray-500';
|
|
254
|
-
const wrapperIcon = health.wrapper_url ? 'link' : 'link_off';
|
|
255
|
-
|
|
256
|
-
// Configuration status (API key)
|
|
257
|
-
const configColor = health.has_api_key ? 'text-green-500' : 'text-yellow-500';
|
|
258
|
-
const configIcon = health.has_api_key ? 'vpn_key' : 'warning';
|
|
259
|
-
const configStatus = health.has_api_key ? 'API Key Configured' : 'No API Key';
|
|
260
|
-
|
|
261
|
-
let html = '<div class="flex items-start gap-3">';
|
|
262
|
-
html += '<span class="material-icons flex-shrink-0 text-2xl ' + wrapperColor + '">' + wrapperIcon + '</span>';
|
|
263
|
-
html += '<div class="min-w-0">';
|
|
264
|
-
html += '<p class="text-sm font-medium text-gray-900 dark:text-white">Centrifugo Wrapper</p>';
|
|
265
|
-
html += '<p class="text-xs text-gray-600 dark:text-gray-400 break-all">' + (health.wrapper_url || 'Not configured') + '</p>';
|
|
266
|
-
html += '</div></div>';
|
|
267
|
-
|
|
268
|
-
html += '<div class="flex items-start gap-3">';
|
|
269
|
-
html += '<span class="material-icons flex-shrink-0 text-2xl ' + configColor + '">' + configIcon + '</span>';
|
|
270
|
-
html += '<div class="min-w-0">';
|
|
271
|
-
html += '<p class="text-sm font-medium text-gray-900 dark:text-white">Configuration</p>';
|
|
272
|
-
html += '<p class="text-xs text-gray-600 dark:text-gray-400">' + configStatus + '</p>';
|
|
273
|
-
html += '</div></div>';
|
|
274
|
-
|
|
275
|
-
statusContainer.innerHTML = html;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
updateLastUpdate() {
|
|
279
|
-
const element = document.getElementById('last-update');
|
|
280
|
-
if (element) {
|
|
281
|
-
const now = new Date();
|
|
282
|
-
element.textContent = 'Last updated: ' + now.toLocaleTimeString();
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
startAutoRefresh() {
|
|
287
|
-
if (this.refreshInterval) {
|
|
288
|
-
clearInterval(this.refreshInterval);
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
this.refreshInterval = setInterval(() => {
|
|
292
|
-
if (this.autoRefresh) {
|
|
293
|
-
this.loadHealthStatus();
|
|
294
|
-
|
|
295
|
-
// Don't refresh static tabs (usage-guide)
|
|
296
|
-
if (this.currentTab !== 'usage-guide') {
|
|
297
|
-
this.loadTabData(this.currentTab);
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
}, this.refreshRate);
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
stopAutoRefresh() {
|
|
304
|
-
if (this.refreshInterval) {
|
|
305
|
-
clearInterval(this.refreshInterval);
|
|
306
|
-
this.refreshInterval = null;
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
updateElement(id, value) {
|
|
311
|
-
const element = document.getElementById(id);
|
|
312
|
-
if (element) {
|
|
313
|
-
element.textContent = value;
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
async function initializeDashboard() {
|
|
319
|
-
console.log('DOM loaded, waiting for CentrifugoAPI...');
|
|
320
|
-
|
|
321
|
-
let attempts = 0;
|
|
322
|
-
const maxAttempts = 100;
|
|
323
|
-
|
|
324
|
-
while (!window.centrifugoAPI && attempts < maxAttempts) {
|
|
325
|
-
await new Promise(resolve => setTimeout(resolve, 50));
|
|
326
|
-
attempts++;
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
if (!window.centrifugoAPI) {
|
|
330
|
-
console.error('L CentrifugoAPI failed to load after 5 seconds');
|
|
331
|
-
return;
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
console.log(' CentrifugoAPI ready, initializing dashboard...');
|
|
335
|
-
window.centrifugoDashboard = new CentrifugoDashboard();
|
|
336
|
-
window.centrifugoDashboard.init();
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
document.addEventListener('DOMContentLoaded', initializeDashboard);
|
|
340
|
-
|
|
341
|
-
export default CentrifugoDashboard;
|