django-cfg 1.4.88__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/services/__init__.py +2 -0
- django_cfg/apps/dashboard/services/overview_service.py +205 -0
- django_cfg/apps/frontend/test_routing.py +134 -0
- django_cfg/apps/frontend/views.py +69 -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/{D_d9HRw5Yn7BRHAX5q89_ → 0sN9ktsgXH48ygtGSrhfu}/_buildManifest.js +1 -1
- django_cfg/static/frontend/admin/_next/static/chunks/50314-9443faa6df24aebf.js +1 -0
- django_cfg/static/frontend/admin/_next/static/chunks/pages/{_app-1c0fff0f59a6d683.js → _app-c7dcd3aa616fab68.js} +1 -1
- django_cfg/static/frontend/admin/_next/static/chunks/pages/private/{centrifugo-44a8313fa040e9ad.js → centrifugo-f9ecbc3ae0052a03.js} +1 -1
- 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-1.4.88.dist-info → django_cfg-1.4.89.dist-info}/METADATA +1 -1
- {django_cfg-1.4.88.dist-info → django_cfg-1.4.89.dist-info}/RECORD +39 -143
- 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/base.py +0 -290
- 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/50314-5ec79b293c2283dd.js +0 -1
- 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/{D_d9HRw5Yn7BRHAX5q89_ → 0sN9ktsgXH48ygtGSrhfu}/_ssgManifest.js +0 -0
- {django_cfg-1.4.88.dist-info → django_cfg-1.4.89.dist-info}/WHEEL +0 -0
- {django_cfg-1.4.88.dist-info → django_cfg-1.4.89.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.4.88.dist-info → django_cfg-1.4.89.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,313 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Live Channels Module
|
|
3
|
-
* Handles real-time channel monitoring from Centrifugo server
|
|
4
|
-
*/
|
|
5
|
-
export class LiveChannelsModule {
|
|
6
|
-
constructor(api, dashboard) {
|
|
7
|
-
this.api = api;
|
|
8
|
-
this.dashboard = dashboard;
|
|
9
|
-
this.currentChannel = null;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
async loadLiveChannels() {
|
|
13
|
-
try {
|
|
14
|
-
console.log('Loading live channels from Centrifugo server...');
|
|
15
|
-
|
|
16
|
-
const patternInput = document.getElementById('live-channel-pattern');
|
|
17
|
-
const pattern = patternInput ? patternInput.value.trim() : '';
|
|
18
|
-
|
|
19
|
-
// Call Centrifugo channels API
|
|
20
|
-
const data = { pattern: pattern || '' };
|
|
21
|
-
const response = await this.api.centrifugoAdminApiServerChannelsCreate(data);
|
|
22
|
-
|
|
23
|
-
if (response && response.result) {
|
|
24
|
-
const channels = response.result.channels || {};
|
|
25
|
-
this.renderChannelsGrid(channels);
|
|
26
|
-
this.updateLiveChannelsBadge(Object.keys(channels).length);
|
|
27
|
-
} else if (response && response.error) {
|
|
28
|
-
console.error('Centrifugo API error:', response.error);
|
|
29
|
-
this.showError('Failed to load channels: ' + response.error.message);
|
|
30
|
-
}
|
|
31
|
-
} catch (error) {
|
|
32
|
-
console.error('Error loading live channels:', error);
|
|
33
|
-
this.showError('Failed to connect to Centrifugo server');
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
renderChannelsGrid(channels) {
|
|
38
|
-
const grid = document.getElementById('live-channels-grid');
|
|
39
|
-
const emptyState = document.getElementById('live-channels-empty');
|
|
40
|
-
|
|
41
|
-
if (!grid) return;
|
|
42
|
-
|
|
43
|
-
const channelEntries = Object.entries(channels);
|
|
44
|
-
|
|
45
|
-
if (channelEntries.length === 0) {
|
|
46
|
-
grid.innerHTML = '';
|
|
47
|
-
if (emptyState) emptyState.classList.remove('hidden');
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
if (emptyState) emptyState.classList.add('hidden');
|
|
52
|
-
|
|
53
|
-
let html = '';
|
|
54
|
-
channelEntries.forEach(([channelName, info]) => {
|
|
55
|
-
const numClients = info.num_clients || 0;
|
|
56
|
-
const statusColor = numClients > 0 ? 'text-green-500' : 'text-gray-400';
|
|
57
|
-
const statusIcon = numClients > 0 ? 'radio_button_checked' : 'radio_button_unchecked';
|
|
58
|
-
|
|
59
|
-
html += `
|
|
60
|
-
<div class="bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 p-4 hover:border-purple-500 dark:hover:border-purple-400 transition-colors">
|
|
61
|
-
<!-- Channel Header -->
|
|
62
|
-
<div class="flex items-start justify-between mb-3">
|
|
63
|
-
<div class="flex items-center gap-2 min-w-0 flex-1">
|
|
64
|
-
<span class="material-icons ${statusColor}">${statusIcon}</span>
|
|
65
|
-
<code class="text-sm font-mono text-gray-900 dark:text-white truncate">${this.escapeHtml(channelName)}</code>
|
|
66
|
-
</div>
|
|
67
|
-
</div>
|
|
68
|
-
|
|
69
|
-
<!-- Stats -->
|
|
70
|
-
<div class="grid grid-cols-2 gap-3 mb-3">
|
|
71
|
-
<div>
|
|
72
|
-
<p class="text-xs text-gray-600 dark:text-gray-400">Clients</p>
|
|
73
|
-
<p class="text-xl font-bold text-purple-600 dark:text-purple-400">${numClients}</p>
|
|
74
|
-
</div>
|
|
75
|
-
<div>
|
|
76
|
-
<p class="text-xs text-gray-600 dark:text-gray-400">Status</p>
|
|
77
|
-
<p class="text-sm font-medium ${numClients > 0 ? 'text-green-600 dark:text-green-400' : 'text-gray-500 dark:text-gray-400'}">
|
|
78
|
-
${numClients > 0 ? 'Active' : 'Idle'}
|
|
79
|
-
</p>
|
|
80
|
-
</div>
|
|
81
|
-
</div>
|
|
82
|
-
|
|
83
|
-
<!-- Actions -->
|
|
84
|
-
<div class="flex gap-2">
|
|
85
|
-
<button onclick="window.centrifugoDashboard.liveChannelsModule.viewChannelDetails('${this.escapeHtml(channelName)}')"
|
|
86
|
-
class="flex-1 px-3 py-2 bg-purple-600 hover:bg-purple-700 text-white rounded text-sm font-medium flex items-center justify-center gap-1">
|
|
87
|
-
<span class="material-icons text-base">visibility</span>
|
|
88
|
-
View Details
|
|
89
|
-
</button>
|
|
90
|
-
</div>
|
|
91
|
-
</div>
|
|
92
|
-
`;
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
grid.innerHTML = html;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
async viewChannelDetails(channel) {
|
|
99
|
-
this.currentChannel = channel;
|
|
100
|
-
const modal = document.getElementById('channel-details-modal');
|
|
101
|
-
if (!modal) return;
|
|
102
|
-
|
|
103
|
-
// Show modal
|
|
104
|
-
modal.classList.remove('hidden');
|
|
105
|
-
|
|
106
|
-
// Set channel name
|
|
107
|
-
const modalTitle = document.getElementById('modal-channel-name');
|
|
108
|
-
if (modalTitle) {
|
|
109
|
-
modalTitle.textContent = channel;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// Load presence and history
|
|
113
|
-
await this.loadChannelPresence(channel);
|
|
114
|
-
await this.loadChannelHistory(channel);
|
|
115
|
-
await this.loadPresenceStats(channel);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
async loadPresenceStats(channel) {
|
|
119
|
-
try {
|
|
120
|
-
const data = { channel };
|
|
121
|
-
const response = await this.api.centrifugoAdminApiServerPresenceStatsCreate(data);
|
|
122
|
-
|
|
123
|
-
if (response && response.error) {
|
|
124
|
-
// Feature not available (e.g., code 108)
|
|
125
|
-
console.warn('Presence stats not available:', response.error.message);
|
|
126
|
-
this.updateElement('modal-clients-count', 'N/A');
|
|
127
|
-
this.updateElement('modal-users-count', 'N/A');
|
|
128
|
-
} else if (response && response.result) {
|
|
129
|
-
const stats = response.result;
|
|
130
|
-
this.updateElement('modal-clients-count', stats.num_clients || 0);
|
|
131
|
-
this.updateElement('modal-users-count', stats.num_users || 0);
|
|
132
|
-
}
|
|
133
|
-
} catch (error) {
|
|
134
|
-
console.error('Error loading presence stats:', error);
|
|
135
|
-
this.updateElement('modal-clients-count', 'Error');
|
|
136
|
-
this.updateElement('modal-users-count', 'Error');
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
async loadChannelPresence(channel) {
|
|
141
|
-
try {
|
|
142
|
-
const data = { channel };
|
|
143
|
-
const response = await this.api.centrifugoAdminApiServerPresenceCreate(data);
|
|
144
|
-
|
|
145
|
-
if (response && response.error) {
|
|
146
|
-
// Feature not available (e.g., code 108)
|
|
147
|
-
console.warn('Presence not available:', response.error.message);
|
|
148
|
-
this.renderPresenceList({}, 'Presence tracking not enabled for this channel');
|
|
149
|
-
} else if (response && response.result) {
|
|
150
|
-
const presence = response.result.presence || {};
|
|
151
|
-
this.renderPresenceList(presence);
|
|
152
|
-
}
|
|
153
|
-
} catch (error) {
|
|
154
|
-
console.error('Error loading channel presence:', error);
|
|
155
|
-
this.renderPresenceList({}, 'Error loading presence data');
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
renderPresenceList(presence, errorMessage = null) {
|
|
160
|
-
const tbody = document.getElementById('modal-presence-list');
|
|
161
|
-
if (!tbody) return;
|
|
162
|
-
|
|
163
|
-
if (errorMessage) {
|
|
164
|
-
tbody.innerHTML = `
|
|
165
|
-
<tr>
|
|
166
|
-
<td colspan="3" class="px-4 py-8 text-center text-yellow-600 dark:text-yellow-400">
|
|
167
|
-
<span class="material-icons text-2xl mb-2">info</span>
|
|
168
|
-
<p>${errorMessage}</p>
|
|
169
|
-
</td>
|
|
170
|
-
</tr>
|
|
171
|
-
`;
|
|
172
|
-
return;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
const clients = Object.values(presence);
|
|
176
|
-
|
|
177
|
-
if (clients.length === 0) {
|
|
178
|
-
tbody.innerHTML = `
|
|
179
|
-
<tr>
|
|
180
|
-
<td colspan="3" class="px-4 py-8 text-center text-gray-500 dark:text-gray-400">
|
|
181
|
-
No clients connected to this channel
|
|
182
|
-
</td>
|
|
183
|
-
</tr>
|
|
184
|
-
`;
|
|
185
|
-
return;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
let html = '';
|
|
189
|
-
clients.forEach(client => {
|
|
190
|
-
const userId = client.user || 'anonymous';
|
|
191
|
-
const clientId = (client.client || '').substring(0, 12) + '...';
|
|
192
|
-
const connInfo = client.conn_info ? JSON.stringify(client.conn_info) : '-';
|
|
193
|
-
|
|
194
|
-
html += `
|
|
195
|
-
<tr class="hover:bg-gray-50 dark:hover:bg-gray-700">
|
|
196
|
-
<td class="px-4 py-3 text-sm font-medium text-gray-900 dark:text-white">${this.escapeHtml(userId)}</td>
|
|
197
|
-
<td class="px-4 py-3 text-xs font-mono text-gray-600 dark:text-gray-400">${this.escapeHtml(clientId)}</td>
|
|
198
|
-
<td class="px-4 py-3 text-xs text-gray-600 dark:text-gray-400">${this.escapeHtml(connInfo)}</td>
|
|
199
|
-
</tr>
|
|
200
|
-
`;
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
tbody.innerHTML = html;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
async loadChannelHistory(channel) {
|
|
207
|
-
try {
|
|
208
|
-
const data = { channel, limit: 10 };
|
|
209
|
-
const response = await this.api.centrifugoAdminApiServerHistoryCreate(data);
|
|
210
|
-
|
|
211
|
-
if (response && response.error) {
|
|
212
|
-
// Feature not available (e.g., code 108)
|
|
213
|
-
console.warn('History not available:', response.error.message);
|
|
214
|
-
this.renderHistoryList([], 'History not enabled for this channel');
|
|
215
|
-
this.updateElement('modal-history-count', 'N/A');
|
|
216
|
-
} else if (response && response.result) {
|
|
217
|
-
const publications = response.result.publications || [];
|
|
218
|
-
this.renderHistoryList(publications);
|
|
219
|
-
this.updateElement('modal-history-count', publications.length);
|
|
220
|
-
}
|
|
221
|
-
} catch (error) {
|
|
222
|
-
console.error('Error loading channel history:', error);
|
|
223
|
-
this.renderHistoryList([], 'Error loading history');
|
|
224
|
-
this.updateElement('modal-history-count', 'Error');
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
renderHistoryList(publications, errorMessage = null) {
|
|
229
|
-
const container = document.getElementById('modal-history-list');
|
|
230
|
-
if (!container) return;
|
|
231
|
-
|
|
232
|
-
if (errorMessage) {
|
|
233
|
-
container.innerHTML = `
|
|
234
|
-
<p class="text-sm text-yellow-600 dark:text-yellow-400 text-center py-4">
|
|
235
|
-
<span class="material-icons text-xl">info</span><br>
|
|
236
|
-
${errorMessage}
|
|
237
|
-
</p>
|
|
238
|
-
`;
|
|
239
|
-
return;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
if (publications.length === 0) {
|
|
243
|
-
container.innerHTML = `
|
|
244
|
-
<p class="text-sm text-gray-500 dark:text-gray-400 text-center py-4">
|
|
245
|
-
No recent messages in this channel
|
|
246
|
-
</p>
|
|
247
|
-
`;
|
|
248
|
-
return;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
let html = '';
|
|
252
|
-
publications.forEach((pub, index) => {
|
|
253
|
-
const data = pub.data || {};
|
|
254
|
-
const offset = pub.offset || '-';
|
|
255
|
-
const dataStr = JSON.stringify(data, null, 2);
|
|
256
|
-
|
|
257
|
-
html += `
|
|
258
|
-
<div class="bg-gray-50 dark:bg-gray-700 rounded-lg p-4">
|
|
259
|
-
<div class="flex items-center justify-between mb-2">
|
|
260
|
-
<span class="text-xs font-medium text-gray-600 dark:text-gray-400">Message #${index + 1}</span>
|
|
261
|
-
<span class="text-xs text-gray-500 dark:text-gray-400">Offset: ${offset}</span>
|
|
262
|
-
</div>
|
|
263
|
-
<pre class="text-xs text-gray-900 dark:text-white overflow-x-auto"><code>${this.escapeHtml(dataStr)}</code></pre>
|
|
264
|
-
</div>
|
|
265
|
-
`;
|
|
266
|
-
});
|
|
267
|
-
|
|
268
|
-
container.innerHTML = html;
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
closeModal() {
|
|
272
|
-
const modal = document.getElementById('channel-details-modal');
|
|
273
|
-
if (modal) {
|
|
274
|
-
modal.classList.add('hidden');
|
|
275
|
-
}
|
|
276
|
-
this.currentChannel = null;
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
updateLiveChannelsBadge(count) {
|
|
280
|
-
const badge = document.getElementById('live-channels-count-badge');
|
|
281
|
-
if (badge) {
|
|
282
|
-
badge.textContent = count;
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
showError(message) {
|
|
287
|
-
const grid = document.getElementById('live-channels-grid');
|
|
288
|
-
if (grid) {
|
|
289
|
-
grid.innerHTML = `
|
|
290
|
-
<div class="col-span-full bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg p-4">
|
|
291
|
-
<div class="flex items-center gap-3">
|
|
292
|
-
<span class="material-icons text-red-500">error</span>
|
|
293
|
-
<p class="text-sm text-red-700 dark:text-red-400">${this.escapeHtml(message)}</p>
|
|
294
|
-
</div>
|
|
295
|
-
</div>
|
|
296
|
-
`;
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
updateElement(id, value) {
|
|
301
|
-
const element = document.getElementById(id);
|
|
302
|
-
if (element) {
|
|
303
|
-
element.textContent = value;
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
escapeHtml(unsafe) {
|
|
308
|
-
if (typeof unsafe !== 'string') return unsafe;
|
|
309
|
-
const div = document.createElement('div');
|
|
310
|
-
div.textContent = unsafe;
|
|
311
|
-
return div.innerHTML;
|
|
312
|
-
}
|
|
313
|
-
}
|