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.

Files changed (177) hide show
  1. django_cfg/__init__.py +1 -1
  2. django_cfg/apps/centrifugo/views/__init__.py +0 -2
  3. django_cfg/apps/dashboard/permissions.py +48 -0
  4. django_cfg/apps/dashboard/serializers/__init__.py +8 -1
  5. django_cfg/apps/dashboard/serializers/commands.py +29 -0
  6. django_cfg/apps/dashboard/services/__init__.py +2 -0
  7. django_cfg/{modules/django_unfold/callbacks/base.py → apps/dashboard/services/commands_security.py} +28 -90
  8. django_cfg/apps/dashboard/services/commands_service.py +208 -9
  9. django_cfg/apps/dashboard/services/overview_service.py +205 -0
  10. django_cfg/apps/dashboard/views/commands_views.py +92 -4
  11. django_cfg/apps/frontend/test_routing.py +134 -0
  12. django_cfg/apps/frontend/views.py +73 -28
  13. django_cfg/apps/urls.py +0 -1
  14. django_cfg/core/builders/apps_builder.py +0 -58
  15. django_cfg/modules/django_unfold/__init__.py +5 -24
  16. django_cfg/modules/django_unfold/models/__init__.py +0 -23
  17. django_cfg/modules/django_unfold/models/config.py +11 -65
  18. django_cfg/modules/django_unfold/{dashboard.py → navigation.py} +21 -152
  19. django_cfg/modules/django_unfold/tailwind.py +2 -4
  20. django_cfg/pyproject.toml +1 -1
  21. django_cfg/registry/third_party.py +0 -9
  22. django_cfg/routing/callbacks.py +1 -43
  23. django_cfg/static/frontend/admin/404/index.html +1 -1
  24. django_cfg/static/frontend/admin/404.html +1 -1
  25. django_cfg/static/frontend/admin/500/index.html +1 -1
  26. django_cfg/static/frontend/admin/_next/static/{ZJZBgOL9mO1koHrgaaLEV → 0sN9ktsgXH48ygtGSrhfu}/_buildManifest.js +1 -1
  27. django_cfg/static/frontend/admin/_next/static/chunks/{19430.fe7bff7372f8a256.js → 19430.c4c95603c23c17fe.js} +1 -1
  28. django_cfg/static/frontend/admin/_next/static/chunks/50314-9443faa6df24aebf.js +1 -0
  29. django_cfg/static/frontend/admin/_next/static/chunks/94141-bc6d47f419b26b21.js +1 -0
  30. django_cfg/static/frontend/admin/_next/static/chunks/pages/{_app-c336f254967dd101.js → _app-c7dcd3aa616fab68.js} +6 -6
  31. django_cfg/static/frontend/admin/_next/static/chunks/pages/legal/{cookies-b39c7f22c066e2c6.js → cookies-97d279800f12aab4.js} +1 -1
  32. django_cfg/static/frontend/admin/_next/static/chunks/pages/legal/{privacy-5aedad0cf3a4f80f.js → privacy-1d5e6cd94689247e.js} +1 -1
  33. django_cfg/static/frontend/admin/_next/static/chunks/pages/legal/{security-dbd854d0d5d483e2.js → security-55e49700e7a01f5a.js} +1 -1
  34. django_cfg/static/frontend/admin/_next/static/chunks/pages/legal/{terms-f3e1d2b9e5edf12f.js → terms-14c02bb2d3198352.js} +1 -1
  35. django_cfg/static/frontend/admin/_next/static/chunks/pages/private/{centrifugo-22532c65971225eb.js → centrifugo-f9ecbc3ae0052a03.js} +1 -1
  36. django_cfg/static/frontend/admin/_next/static/chunks/pages/private-d4ccbe1265cbd853.js +1 -0
  37. django_cfg/static/frontend/admin/_next/static/chunks/{webpack-da114020a6b940f5.js → webpack-5a92f81363b62aa7.js} +1 -1
  38. django_cfg/static/frontend/admin/_next/static/css/3063068f0d5a8a00.css +3 -0
  39. django_cfg/static/frontend/admin/_next/static/media/19cfc7226ec3afaa-s.woff2 +0 -0
  40. django_cfg/static/frontend/admin/_next/static/media/21350d82a1f187e9-s.p.woff2 +0 -0
  41. django_cfg/static/frontend/admin/_next/static/media/8e9860b6e62d6359-s.woff2 +0 -0
  42. django_cfg/static/frontend/admin/_next/static/media/ba9851c3c22cd980-s.woff2 +0 -0
  43. django_cfg/static/frontend/admin/_next/static/media/c5fe6dc8356a8c31-s.woff2 +0 -0
  44. django_cfg/static/frontend/admin/_next/static/media/df0a9ae256c0569c-s.woff2 +0 -0
  45. django_cfg/static/frontend/admin/_next/static/media/e4af272ccee01ff0-s.p.woff2 +0 -0
  46. django_cfg/static/frontend/admin/auth/index.html +1 -1
  47. django_cfg/static/frontend/admin/index.html +1 -1
  48. django_cfg/static/frontend/admin/legal/cookies/index.html +1 -1
  49. django_cfg/static/frontend/admin/legal/privacy/index.html +1 -1
  50. django_cfg/static/frontend/admin/legal/security/index.html +1 -1
  51. django_cfg/static/frontend/admin/legal/terms/index.html +1 -1
  52. django_cfg/static/frontend/admin/private/centrifugo/index.html +1 -1
  53. django_cfg/static/frontend/admin/private/index.html +1 -1
  54. django_cfg/static/frontend/admin/private/profile/index.html +1 -1
  55. django_cfg/static/frontend/admin/private/ui/index.html +2 -2
  56. django_cfg/templates/admin/index.html +1 -1
  57. {django_cfg-1.4.87.dist-info → django_cfg-1.4.89.dist-info}/METADATA +1 -1
  58. {django_cfg-1.4.87.dist-info → django_cfg-1.4.89.dist-info}/RECORD +62 -163
  59. django_cfg/apps/centrifugo/static/django_cfg_centrifugo/css/dashboard.css +0 -260
  60. django_cfg/apps/centrifugo/static/django_cfg_centrifugo/js/dashboard/live_channels.mjs +0 -313
  61. django_cfg/apps/centrifugo/static/django_cfg_centrifugo/js/dashboard/live_testing.mjs +0 -803
  62. django_cfg/apps/centrifugo/static/django_cfg_centrifugo/js/dashboard/main.mjs +0 -341
  63. django_cfg/apps/centrifugo/static/django_cfg_centrifugo/js/dashboard/overview.mjs +0 -432
  64. django_cfg/apps/centrifugo/static/django_cfg_centrifugo/js/dashboard/testing.mjs +0 -33
  65. django_cfg/apps/centrifugo/static/django_cfg_centrifugo/js/dashboard/websocket.mjs +0 -210
  66. django_cfg/apps/centrifugo/templates/django_cfg_centrifugo/components/channels_content.html +0 -46
  67. django_cfg/apps/centrifugo/templates/django_cfg_centrifugo/components/live_channels_content.html +0 -123
  68. django_cfg/apps/centrifugo/templates/django_cfg_centrifugo/components/overview_content.html +0 -45
  69. django_cfg/apps/centrifugo/templates/django_cfg_centrifugo/components/publishes_content.html +0 -84
  70. django_cfg/apps/centrifugo/templates/django_cfg_centrifugo/components/stat_cards.html +0 -53
  71. django_cfg/apps/centrifugo/templates/django_cfg_centrifugo/components/system_status.html +0 -91
  72. django_cfg/apps/centrifugo/templates/django_cfg_centrifugo/components/tab_navigation.html +0 -29
  73. django_cfg/apps/centrifugo/templates/django_cfg_centrifugo/components/testing_tools.html +0 -415
  74. django_cfg/apps/centrifugo/templates/django_cfg_centrifugo/layout/base.html +0 -61
  75. django_cfg/apps/centrifugo/templates/django_cfg_centrifugo/pages/dashboard.html +0 -58
  76. django_cfg/apps/centrifugo/templates/django_cfg_centrifugo/tags/connection_script.html +0 -48
  77. django_cfg/apps/centrifugo/templatetags/__init__.py +0 -1
  78. django_cfg/apps/centrifugo/templatetags/centrifugo_tags.py +0 -81
  79. django_cfg/apps/centrifugo/urls_admin.py +0 -20
  80. django_cfg/apps/centrifugo/views/dashboard.py +0 -28
  81. django_cfg/modules/django_dashboard/__init__.py +0 -23
  82. django_cfg/modules/django_dashboard/components.py +0 -312
  83. django_cfg/modules/django_dashboard/debug.py +0 -174
  84. django_cfg/modules/django_dashboard/management/__init__.py +0 -0
  85. django_cfg/modules/django_dashboard/management/commands/__init__.py +0 -0
  86. django_cfg/modules/django_dashboard/management/commands/debug_dashboard.py +0 -109
  87. django_cfg/modules/django_dashboard/sections/__init__.py +0 -1
  88. django_cfg/modules/django_dashboard/sections/base.py +0 -129
  89. django_cfg/modules/django_dashboard/sections/commands.py +0 -33
  90. django_cfg/modules/django_dashboard/sections/documentation.py +0 -393
  91. django_cfg/modules/django_dashboard/sections/overview.py +0 -398
  92. django_cfg/modules/django_dashboard/sections/stats.py +0 -48
  93. django_cfg/modules/django_dashboard/sections/system.py +0 -74
  94. django_cfg/modules/django_dashboard/sections/widgets.py +0 -222
  95. django_cfg/modules/django_unfold/callbacks/__init__.py +0 -9
  96. django_cfg/modules/django_unfold/callbacks/actions.py +0 -51
  97. django_cfg/modules/django_unfold/callbacks/apizones.py +0 -122
  98. django_cfg/modules/django_unfold/callbacks/charts.py +0 -223
  99. django_cfg/modules/django_unfold/callbacks/commands.py +0 -40
  100. django_cfg/modules/django_unfold/callbacks/main.py +0 -322
  101. django_cfg/modules/django_unfold/callbacks/statistics.py +0 -240
  102. django_cfg/modules/django_unfold/callbacks/system.py +0 -180
  103. django_cfg/modules/django_unfold/callbacks/users.py +0 -65
  104. django_cfg/modules/django_unfold/models/dashboard.py +0 -207
  105. django_cfg/modules/django_unfold/models/tabs.py +0 -26
  106. django_cfg/modules/django_unfold/models.py +0 -98
  107. django_cfg/modules/django_unfold/templates/unfold/helpers/app_list.html +0 -102
  108. django_cfg/static/frontend/admin/_next/static/chunks/23004-faae121bbfecc163.js +0 -1
  109. django_cfg/static/frontend/admin/_next/static/chunks/50314-48bd5701f62faf27.js +0 -1
  110. django_cfg/static/frontend/admin/_next/static/chunks/pages/private-fe9faa86ecdb0ce6.js +0 -1
  111. django_cfg/static/frontend/admin/_next/static/css/5f9a37b6e6a72303.css +0 -3
  112. django_cfg/static/frontend/admin/_next/static/media/438aa629764e75f3-s.woff2 +0 -0
  113. django_cfg/static/frontend/admin/_next/static/media/4c9affa5bc8f420e-s.p.woff2 +0 -0
  114. django_cfg/static/frontend/admin/_next/static/media/51251f8b9793cdb3-s.woff2 +0 -0
  115. django_cfg/static/frontend/admin/_next/static/media/875ae681bfde4580-s.p.woff2 +0 -0
  116. django_cfg/static/frontend/admin/_next/static/media/cc978ac5ee68c2b6-s.woff2 +0 -0
  117. django_cfg/static/frontend/admin/_next/static/media/e857b654a2caa584-s.woff2 +0 -0
  118. django_cfg/templates/admin/sections/commands_section.html +0 -5
  119. django_cfg/templates/admin/sections/documentation_section.html +0 -5
  120. django_cfg/templates/admin/sections/overview_section.html +0 -5
  121. django_cfg/templates/admin/sections/stats_section.html +0 -5
  122. django_cfg/templates/admin/sections/system_section.html +0 -5
  123. django_cfg/templates/admin/sections/widgets_section.html +0 -11
  124. django_cfg/templates/admin_old/components/action_grid.html +0 -49
  125. django_cfg/templates/admin_old/components/card.html +0 -50
  126. django_cfg/templates/admin_old/components/data_table.html +0 -67
  127. django_cfg/templates/admin_old/components/metric_card.html +0 -39
  128. django_cfg/templates/admin_old/components/modal.html +0 -58
  129. django_cfg/templates/admin_old/components/progress_bar.html +0 -20
  130. django_cfg/templates/admin_old/components/section_header.html +0 -26
  131. django_cfg/templates/admin_old/components/stat_item.html +0 -32
  132. django_cfg/templates/admin_old/components/stats_grid.html +0 -72
  133. django_cfg/templates/admin_old/components/status_badge.html +0 -28
  134. django_cfg/templates/admin_old/components/user_avatar.html +0 -27
  135. django_cfg/templates/admin_old/constance/change_list.html +0 -74
  136. django_cfg/templates/admin_old/constance/includes/default_value.html +0 -24
  137. django_cfg/templates/admin_old/constance/includes/fieldset_header.html +0 -15
  138. django_cfg/templates/admin_old/constance/includes/results_list.html +0 -16
  139. django_cfg/templates/admin_old/constance/includes/setting_row.html +0 -50
  140. django_cfg/templates/admin_old/constance/includes/table_headers.html +0 -10
  141. django_cfg/templates/admin_old/examples/component_class_example.html +0 -156
  142. django_cfg/templates/admin_old/import_export/change_list_export.html +0 -24
  143. django_cfg/templates/admin_old/import_export/change_list_import.html +0 -24
  144. django_cfg/templates/admin_old/import_export/change_list_import_export.html +0 -34
  145. django_cfg/templates/admin_old/index.html +0 -80
  146. django_cfg/templates/admin_old/index_new.html +0 -119
  147. django_cfg/templates/admin_old/layouts/base_dashboard.html +0 -62
  148. django_cfg/templates/admin_old/layouts/dashboard_with_tabs.html +0 -176
  149. django_cfg/templates/admin_old/sections/commands_section.html +0 -549
  150. django_cfg/templates/admin_old/sections/documentation_section.html +0 -152
  151. django_cfg/templates/admin_old/sections/overview_section.html +0 -112
  152. django_cfg/templates/admin_old/sections/stats_section.html +0 -35
  153. django_cfg/templates/admin_old/sections/system_section.html +0 -99
  154. django_cfg/templates/admin_old/sections/widgets_section.html +0 -129
  155. django_cfg/templates/admin_old/snippets/components/activity_tracker.html +0 -70
  156. django_cfg/templates/admin_old/snippets/components/charts_section.html +0 -113
  157. django_cfg/templates/admin_old/snippets/components/django_commands.html +0 -270
  158. django_cfg/templates/admin_old/snippets/components/quick_actions.html +0 -66
  159. django_cfg/templates/admin_old/snippets/components/recent_activity_improved.html +0 -25
  160. django_cfg/templates/admin_old/snippets/components/recent_users_table.html +0 -102
  161. django_cfg/templates/admin_old/snippets/components/stats_cards.html +0 -4
  162. django_cfg/templates/admin_old/snippets/components/stats_tiles.html +0 -92
  163. django_cfg/templates/admin_old/snippets/components/system_health.html +0 -22
  164. django_cfg/templates/admin_old/snippets/components/system_metrics.html +0 -199
  165. django_cfg/templates/admin_old/snippets/components/user_permissions.html +0 -57
  166. django_cfg/templates/admin_old/snippets/tabs/app_stats_tab.html +0 -201
  167. django_cfg/templates/admin_old/snippets/tabs/commands_tab.html +0 -114
  168. django_cfg/templates/admin_old/snippets/tabs/documentation_tab.html +0 -42
  169. django_cfg/templates/admin_old/snippets/tabs/overview_tab.html +0 -116
  170. django_cfg/templates/admin_old/snippets/tabs/stats_tab.html +0 -89
  171. django_cfg/templates/admin_old/snippets/tabs/users_tab.html +0 -51
  172. django_cfg/templates/admin_old/snippets/tabs/widgets_tab.html +0 -38
  173. django_cfg/templates/admin_old/snippets/zones/zones_table.html +0 -176
  174. /django_cfg/static/frontend/admin/_next/static/{ZJZBgOL9mO1koHrgaaLEV → 0sN9ktsgXH48ygtGSrhfu}/_ssgManifest.js +0 -0
  175. {django_cfg-1.4.87.dist-info → django_cfg-1.4.89.dist-info}/WHEEL +0 -0
  176. {django_cfg-1.4.87.dist-info → django_cfg-1.4.89.dist-info}/entry_points.txt +0 -0
  177. {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;