django-cfg 1.4.59__py3-none-any.whl → 1.4.60__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 (53) hide show
  1. django_cfg/__init__.py +1 -1
  2. django_cfg/apps/ipc/RPC_LOGGING.md +321 -0
  3. django_cfg/apps/ipc/TESTING.md +539 -0
  4. django_cfg/apps/ipc/__init__.py +12 -3
  5. django_cfg/apps/ipc/admin.py +212 -0
  6. django_cfg/apps/ipc/migrations/0001_initial.py +137 -0
  7. django_cfg/apps/ipc/migrations/__init__.py +0 -0
  8. django_cfg/apps/ipc/models.py +221 -0
  9. django_cfg/apps/ipc/serializers/__init__.py +10 -0
  10. django_cfg/apps/ipc/serializers/serializers.py +114 -0
  11. django_cfg/apps/ipc/services/client/client.py +83 -4
  12. django_cfg/apps/ipc/services/logging.py +239 -0
  13. django_cfg/apps/ipc/services/monitor.py +5 -3
  14. django_cfg/apps/ipc/static/django_cfg_ipc/js/dashboard/main.mjs +269 -0
  15. django_cfg/apps/ipc/static/django_cfg_ipc/js/dashboard/overview.mjs +259 -0
  16. django_cfg/apps/ipc/static/django_cfg_ipc/js/dashboard/testing.mjs +375 -0
  17. django_cfg/apps/ipc/templates/django_cfg_ipc/components/methods_content.html +22 -0
  18. django_cfg/apps/ipc/templates/django_cfg_ipc/components/notifications_content.html +9 -0
  19. django_cfg/apps/ipc/templates/django_cfg_ipc/components/overview_content.html +9 -0
  20. django_cfg/apps/ipc/templates/django_cfg_ipc/components/requests_content.html +23 -0
  21. django_cfg/apps/ipc/templates/django_cfg_ipc/components/stat_cards.html +50 -0
  22. django_cfg/apps/ipc/templates/django_cfg_ipc/components/system_status.html +47 -0
  23. django_cfg/apps/ipc/templates/django_cfg_ipc/components/tab_navigation.html +29 -0
  24. django_cfg/apps/ipc/templates/django_cfg_ipc/components/testing_tools.html +184 -0
  25. django_cfg/apps/ipc/templates/django_cfg_ipc/pages/dashboard.html +56 -0
  26. django_cfg/apps/ipc/urls.py +4 -2
  27. django_cfg/apps/ipc/views/__init__.py +7 -2
  28. django_cfg/apps/ipc/views/dashboard.py +1 -1
  29. django_cfg/apps/ipc/views/{viewsets.py → monitoring.py} +17 -11
  30. django_cfg/apps/ipc/views/testing.py +285 -0
  31. django_cfg/modules/django_client/system/generate_mjs_clients.py +1 -1
  32. django_cfg/modules/django_dashboard/sections/widgets.py +209 -0
  33. django_cfg/modules/django_unfold/callbacks/main.py +43 -18
  34. django_cfg/modules/django_unfold/dashboard.py +41 -4
  35. django_cfg/pyproject.toml +1 -1
  36. django_cfg/static/js/api/index.mjs +8 -3
  37. django_cfg/static/js/api/ipc/client.mjs +40 -0
  38. django_cfg/static/js/api/knowbase/client.mjs +309 -0
  39. django_cfg/static/js/api/knowbase/index.mjs +13 -0
  40. django_cfg/static/js/api/payments/client.mjs +46 -1215
  41. django_cfg/static/js/api/types.mjs +164 -337
  42. django_cfg/templates/admin/index.html +8 -0
  43. django_cfg/templates/admin/layouts/dashboard_with_tabs.html +13 -1
  44. django_cfg/templates/admin/sections/widgets_section.html +129 -0
  45. django_cfg/templates/admin/snippets/tabs/widgets_tab.html +38 -0
  46. {django_cfg-1.4.59.dist-info → django_cfg-1.4.60.dist-info}/METADATA +1 -1
  47. {django_cfg-1.4.59.dist-info → django_cfg-1.4.60.dist-info}/RECORD +52 -28
  48. django_cfg/apps/ipc/templates/django_cfg_ipc/dashboard.html +0 -202
  49. /django_cfg/apps/ipc/static/django_cfg_ipc/js/{dashboard.mjs → dashboard.mjs.old} +0 -0
  50. /django_cfg/apps/ipc/templates/django_cfg_ipc/{base.html → layout/base.html} +0 -0
  51. {django_cfg-1.4.59.dist-info → django_cfg-1.4.60.dist-info}/WHEEL +0 -0
  52. {django_cfg-1.4.59.dist-info → django_cfg-1.4.60.dist-info}/entry_points.txt +0 -0
  53. {django_cfg-1.4.59.dist-info → django_cfg-1.4.60.dist-info}/licenses/LICENSE +0 -0
@@ -77,4 +77,12 @@
77
77
  {% else %}
78
78
  {% include 'admin/snippets/tabs/documentation_tab.html' %}
79
79
  {% endif %}
80
+ {% endblock %}
81
+
82
+ {% block widgets_tab %}
83
+ {% if widgets_section %}
84
+ {{ widgets_section|safe }}
85
+ {% else %}
86
+ {% include 'admin/snippets/tabs/widgets_tab.html' %}
87
+ {% endif %}
80
88
  {% endblock %}
@@ -16,7 +16,7 @@
16
16
  if (!tabs.length || !contents.length) return;
17
17
 
18
18
  // Tab names for URL hash
19
- const tabNames = ['overview', 'zones', 'users', 'system', 'stats', 'app-stats', 'commands', 'documentation'];
19
+ const tabNames = ['overview', 'zones', 'users', 'system', 'stats', 'app-stats', 'commands', 'documentation', 'widgets'];
20
20
 
21
21
  // Global function for tab switching
22
22
  window.switchTab = function(idx, updateHash = true) {
@@ -509,6 +509,14 @@
509
509
  <span class="material-icons mr-2 align-middle text-sm">description</span>
510
510
  Documentation
511
511
  </button>
512
+ <button
513
+ type="button"
514
+ data-tab="8"
515
+ class="px-4 py-3 rounded-t-lg focus:outline-none"
516
+ >
517
+ <span class="material-icons mr-2 align-middle text-sm">widgets</span>
518
+ Widgets
519
+ </button>
512
520
  </div>
513
521
 
514
522
  <div class="flex flex-col gap-5">
@@ -545,6 +553,10 @@
545
553
  <div class="tab-content" data-tab="7">
546
554
  {% block documentation_tab %}{% endblock %}
547
555
  </div>
556
+
557
+ <div class="tab-content" data-tab="8">
558
+ {% block widgets_tab %}{% endblock %}
559
+ </div>
548
560
  </div>
549
561
 
550
562
  <!-- Footer Section -->
@@ -0,0 +1,129 @@
1
+ {% load unfold %}
2
+
3
+ <!-- Widgets Section -->
4
+ <div class="space-y-8">
5
+ <!-- Header -->
6
+ <div class="flex items-center justify-between mb-6">
7
+ <div>
8
+ <h1 class="text-2xl font-bold theme-text flex items-center">
9
+ <span class="material-icons mr-3 text-blue-500">widgets</span>
10
+ {{ title|default:"Dashboard Widgets" }}
11
+ </h1>
12
+ <p class="text-gray-600 dark:text-gray-300 mt-2">
13
+ {% if data.has_widgets %}
14
+ Showing {{ data.widgets_count }} widget{{ data.widgets_count|pluralize }}
15
+ {% else %}
16
+ No widgets configured
17
+ {% endif %}
18
+ </p>
19
+ </div>
20
+ </div>
21
+
22
+ {% if data.has_widgets %}
23
+ <!-- Stats Widgets -->
24
+ {% if stats_widgets %}
25
+ {% for widget in stats_widgets %}
26
+ <div class="theme-card rounded-lg shadow-sm border theme-border mb-6">
27
+ <!-- Widget Header -->
28
+ <div class="p-6 border-b theme-border">
29
+ <h2 class="text-lg font-semibold theme-text flex items-center">
30
+ <span class="material-icons text-blue-500 mr-2">dashboard</span>
31
+ {{ widget.title }}
32
+ </h2>
33
+ </div>
34
+
35
+ <!-- Widget Content: Stats Cards -->
36
+ <div class="p-6">
37
+ <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
38
+ {% for card in widget.cards %}
39
+ <div class="theme-card p-6 rounded-lg shadow-sm border theme-border">
40
+ <div class="flex items-start justify-between mb-4">
41
+ <div class="flex-1">
42
+ <p class="text-sm text-gray-600 dark:text-gray-400 mb-2">
43
+ {{ card.title }}
44
+ </p>
45
+ <p class="text-2xl font-bold theme-text">
46
+ {{ card.value_template }}
47
+ </p>
48
+ </div>
49
+ {% if card.icon %}
50
+ <span class="material-icons text-{{ card.color }}-500 text-3xl">
51
+ {{ card.icon }}
52
+ </span>
53
+ {% endif %}
54
+ </div>
55
+
56
+ {% if card.description %}
57
+ <p class="text-xs text-gray-500 dark:text-gray-400 mt-2">
58
+ {{ card.description }}
59
+ </p>
60
+ {% endif %}
61
+
62
+ {% if card.change %}
63
+ <div class="mt-3 flex items-center">
64
+ <span class="text-xs px-2 py-1 rounded
65
+ {% if card.change_type == 'positive' %}
66
+ bg-green-100 text-green-700 dark:bg-green-900/20 dark:text-green-400
67
+ {% elif card.change_type == 'negative' %}
68
+ bg-red-100 text-red-700 dark:bg-red-900/20 dark:text-red-400
69
+ {% else %}
70
+ bg-gray-100 text-gray-700 dark:bg-gray-700 dark:text-gray-400
71
+ {% endif %}
72
+ ">
73
+ {{ card.change }}
74
+ </span>
75
+ </div>
76
+ {% endif %}
77
+ </div>
78
+ {% endfor %}
79
+ </div>
80
+ </div>
81
+ </div>
82
+ {% endfor %}
83
+ {% endif %}
84
+
85
+ <!-- Chart Widgets (if any) -->
86
+ {% if chart_widgets %}
87
+ {% for widget in chart_widgets %}
88
+ <div class="theme-card rounded-lg shadow-sm border theme-border p-6 mb-6">
89
+ <h2 class="text-lg font-semibold theme-text mb-4">
90
+ {{ widget.title }}
91
+ </h2>
92
+ <!-- Chart rendering would go here -->
93
+ <div class="h-64 flex items-center justify-center text-gray-400">
94
+ Chart widget rendering (TODO)
95
+ </div>
96
+ </div>
97
+ {% endfor %}
98
+ {% endif %}
99
+
100
+ <!-- Custom Widgets (if any) -->
101
+ {% if custom_widgets %}
102
+ {% for widget in custom_widgets %}
103
+ <div class="theme-card rounded-lg shadow-sm border theme-border p-6 mb-6">
104
+ <h2 class="text-lg font-semibold theme-text mb-4">
105
+ {{ widget.title }}
106
+ </h2>
107
+ <!-- Custom widget rendering -->
108
+ <div class="text-gray-600 dark:text-gray-300">
109
+ Custom widget type: {{ widget.type }}
110
+ </div>
111
+ </div>
112
+ {% endfor %}
113
+ {% endif %}
114
+
115
+ {% else %}
116
+ <!-- No Widgets State -->
117
+ <div class="theme-card rounded-lg shadow-sm border theme-border p-12 text-center">
118
+ <span class="material-icons text-gray-300 dark:text-gray-600 text-6xl mb-4">
119
+ widgets
120
+ </span>
121
+ <h3 class="text-lg font-semibold text-gray-600 dark:text-gray-400 mb-2">
122
+ No Widgets Configured
123
+ </h3>
124
+ <p class="text-sm text-gray-500 dark:text-gray-500">
125
+ Widgets can be added in DashboardManager.get_widgets_config()
126
+ </p>
127
+ </div>
128
+ {% endif %}
129
+ </div>
@@ -0,0 +1,38 @@
1
+ {% load unfold %}
2
+
3
+ <!-- Widgets Tab Content -->
4
+ <div class="space-y-8">
5
+ <!-- Info Banner -->
6
+ <div class="bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-lg p-4">
7
+ <div class="flex items-start">
8
+ <span class="material-icons text-blue-500 mr-3">info</span>
9
+ <div>
10
+ <h4 class="text-sm font-semibold text-blue-900 dark:text-blue-300 mb-1">
11
+ About Dashboard Widgets
12
+ </h4>
13
+ <p class="text-xs text-blue-700 dark:text-blue-400">
14
+ Widgets are automatically generated from <code class="bg-blue-100 dark:bg-blue-800 px-1 rounded">DashboardManager.get_widgets_config()</code>.
15
+ Add custom widgets by extending the configuration in your project's dashboard manager.
16
+ </p>
17
+ </div>
18
+ </div>
19
+ </div>
20
+
21
+ <!-- Widgets Content (will be replaced by widgets_section if available) -->
22
+ {% if widgets_section %}
23
+ {{ widgets_section|safe }}
24
+ {% else %}
25
+ <!-- Fallback: show message if widgets_section not rendered -->
26
+ <div class="theme-card rounded-lg shadow-sm border theme-border p-12 text-center">
27
+ <span class="material-icons text-gray-300 dark:text-gray-600 text-6xl mb-4">
28
+ widgets
29
+ </span>
30
+ <h3 class="text-lg font-semibold text-gray-600 dark:text-gray-400 mb-2">
31
+ Widgets Section Not Loaded
32
+ </h3>
33
+ <p class="text-sm text-gray-500 dark:text-gray-500">
34
+ The widgets section is being initialized. Please refresh the page.
35
+ </p>
36
+ </div>
37
+ {% endif %}
38
+ </div>
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: django-cfg
3
- Version: 1.4.59
3
+ Version: 1.4.60
4
4
  Summary: Django AI framework with built-in agents, type-safe Pydantic v2 configuration, and 8 enterprise apps. Replace settings.py, validate at startup, 90% less code. Production-ready AI workflows for Django.
5
5
  Project-URL: Homepage, https://djangocfg.com
6
6
  Project-URL: Documentation, https://djangocfg.com
@@ -1,5 +1,5 @@
1
1
  django_cfg/README.md,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- django_cfg/__init__.py,sha256=TPvC_07hRzCP1DyqCw3vkCu4by78b9Kqqg-tccLGVpY,1620
2
+ django_cfg/__init__.py,sha256=fJ_0Ac-Ttb6P-1aXu8SCuaQz3nt3pb_KPKKpx7VO6To,1620
3
3
  django_cfg/apps.py,sha256=72m3uuvyqGiLx6gOfE-BD3P61jddCCERuBOYpxTX518,1605
4
4
  django_cfg/config.py,sha256=y4Z3rnYsHBE0TehpwAIPaxr---mkvyKrZGGsNwYso74,1398
5
5
  django_cfg/apps/__init__.py,sha256=JtDmEYt1OcleWM2ZaeX0LKDnRQzPOavfaXBWG4ECB5Q,26
@@ -120,24 +120,43 @@ django_cfg/apps/api/health/serializers.py,sha256=Y_kn_RIn4MBRJWbsO2_DNEG_AqxnhuD
120
120
  django_cfg/apps/api/health/urls.py,sha256=eCTzgB4rv_H2W0NrixPO6qsh0pT2oUePrYAT5D35QIY,550
121
121
  django_cfg/apps/api/health/views.py,sha256=65oA6O3gaz2ECY2SiXlT3n4JpORt0nDufa_10um0nRw,8194
122
122
  django_cfg/apps/ipc/README.md,sha256=f_t_dK-W6GXMy7kxKpa_FidkZPII4M7eI3cmTFkJRMg,8971
123
- django_cfg/apps/ipc/__init__.py,sha256=1uZR8WqNdgWs-s0NXVvNFJ5ir7k5BnMcse44flXIuyg,1489
123
+ django_cfg/apps/ipc/RPC_LOGGING.md,sha256=NmYdCM0FggMdCbAzFH1dzKEsK97merVunN3Yk9nlO_E,7919
124
+ django_cfg/apps/ipc/TESTING.md,sha256=c-AdIfEZMbr7fvwKwfRWciZzS-m4TXnNcfcLJrt0fOQ,11544
125
+ django_cfg/apps/ipc/__init__.py,sha256=C86RhKR8MeKAyaJhegWjZCKohI5TlX5dIwhIHsmNEQk,1727
126
+ django_cfg/apps/ipc/admin.py,sha256=QzaJLsMPreK1sPSkzXceRsPW7r1iOxzNLwQ_Hn__gUo,6100
124
127
  django_cfg/apps/ipc/apps.py,sha256=FJrHrcxeyk-SR8V_mv4kC6IClczffligz9K8y-WevJc,716
125
- django_cfg/apps/ipc/urls.py,sha256=EJ-xDmAD7-XhURTIGxfgwrbbEbTWMJtFE3aazqla7gI,448
128
+ django_cfg/apps/ipc/models.py,sha256=yr5PLYr8Vb639eLlNwMmK5ltoWE9UWCnmZ9BaKgDaMU,6251
129
+ django_cfg/apps/ipc/urls.py,sha256=LuqwwAKqs-nHoXae3yJiUjVhK5T8DthrAt9LCAUAYNI,568
126
130
  django_cfg/apps/ipc/urls_admin.py,sha256=YvixgQXTVFWojJeYmo0b7AF9X9g7Nmhwxv7Fm4ihTAg,399
127
- django_cfg/apps/ipc/serializers/__init__.py,sha256=F7hvptXZP-vyeQpnn5SQxbl2gYWlFfy7cFCojo4TXSU,387
128
- django_cfg/apps/ipc/serializers/serializers.py,sha256=Yb3ai5H_T2mpYKe4qNYyQEvkHnLaVTcNa2CTdgwoD_g,6577
131
+ django_cfg/apps/ipc/migrations/0001_initial.py,sha256=9fpp3bvYFZL48hRKeyxEchtnMSuQlbGIBeydZfsCMnQ,5011
132
+ django_cfg/apps/ipc/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
133
+ django_cfg/apps/ipc/serializers/__init__.py,sha256=5b9-6f0Nrrf6g7lZR1-l5xhliB8yRWSCbym8GpkmMsw,705
134
+ django_cfg/apps/ipc/serializers/serializers.py,sha256=R6e4sNp7i58bQq9gflpoEsDVhItsDnQv548bJYX1WNg,9692
129
135
  django_cfg/apps/ipc/services/__init__.py,sha256=YdHT1pd7FZbjYFaPAf3rw_t3NIHA-6TIWI7Il2ELLO4,96
130
- django_cfg/apps/ipc/services/monitor.py,sha256=NjZdNACiFggi9HgjXRwVDdj5DfloYeO5OuOe6XIAtZs,15368
136
+ django_cfg/apps/ipc/services/logging.py,sha256=FZCel-I2wcPAXoy1JethrpCB_TzqYs14Fc-h0oeIUeQ,7240
137
+ django_cfg/apps/ipc/services/monitor.py,sha256=5_ttY_D9EoZ3LUKb5S05_jwW6W6A8NyUkS1QbR6wfMw,15496
131
138
  django_cfg/apps/ipc/services/client/__init__.py,sha256=7tMogbz93FefNoT5ul5_kGwnYnL29WS-rHh1T5lVl6w,456
132
- django_cfg/apps/ipc/services/client/client.py,sha256=aSCa_wjw0XPntd2KL2tQUsu3iOXdwT2KHOwFK9vb4xo,17479
139
+ django_cfg/apps/ipc/services/client/client.py,sha256=dopna1aWTia49pEjYRHnxlmvmwofNwbUnTFK9BfyCEQ,20296
133
140
  django_cfg/apps/ipc/services/client/config.py,sha256=A6xWzRfVb03hatoHmT8saePy3zPHgm0FOwXKT8QShOY,5895
134
141
  django_cfg/apps/ipc/services/client/exceptions.py,sha256=vAnZgH4ZYnqs7HJs11Rm6oqM-aTVAdPVcQZ9NcpE6Ik,5866
135
- django_cfg/apps/ipc/static/django_cfg_ipc/js/dashboard.mjs,sha256=FTumHeB_IwfsQvgm5_teC8UAw-baTGIrrR1nXDSMocc,16187
136
- django_cfg/apps/ipc/templates/django_cfg_ipc/base.html,sha256=naTYIAlETt00FVVBmz-dB5iPWekITagkTgGgKb25N60,2405
137
- django_cfg/apps/ipc/templates/django_cfg_ipc/dashboard.html,sha256=ZVJ8xvLJIuCD0e8sCUtHKgJMKGyL5hQwU-pxhAC5LxI,10599
138
- django_cfg/apps/ipc/views/__init__.py,sha256=FI8I0bASo-Az4WmURtN6NXhouNbXr_82cNjaILojlls,164
139
- django_cfg/apps/ipc/views/dashboard.py,sha256=lou_r9b1UtUJ_DaZrL_QpLDRrVto8oL83CUCde6zMFA,401
140
- django_cfg/apps/ipc/views/viewsets.py,sha256=ALy3DRSPZDH0eAis37UR8T_U5mY7UJKFGQ67xn1Ynvw,8605
142
+ django_cfg/apps/ipc/static/django_cfg_ipc/js/dashboard.mjs.old,sha256=FTumHeB_IwfsQvgm5_teC8UAw-baTGIrrR1nXDSMocc,16187
143
+ django_cfg/apps/ipc/static/django_cfg_ipc/js/dashboard/main.mjs,sha256=v_0YQa88MX3NI5kyHl_6CREB_Mw3iDsnk4vWMVntWdk,9088
144
+ django_cfg/apps/ipc/static/django_cfg_ipc/js/dashboard/overview.mjs,sha256=j9i67T7450ILLBWcj56gynCfg8x1o4HYFWNI57z8Ppg,9483
145
+ django_cfg/apps/ipc/static/django_cfg_ipc/js/dashboard/testing.mjs,sha256=FoTlliqkuIIlb-vvNvglZFS8FPlVsVXl3Ra_JxthChU,12389
146
+ django_cfg/apps/ipc/templates/django_cfg_ipc/components/methods_content.html,sha256=svwBW8CztvEL4qjdHHYAOVgnXuutbOa15LypSJ797ok,1206
147
+ django_cfg/apps/ipc/templates/django_cfg_ipc/components/notifications_content.html,sha256=euBmWVE70rKtQl8qANdovoydN3sUfxkLU3n976ZDw3M,436
148
+ django_cfg/apps/ipc/templates/django_cfg_ipc/components/overview_content.html,sha256=3k_Na1u2eBOlZ3m0dDHlj4tQVg_EUamJKf2nDTC_6t4,434
149
+ django_cfg/apps/ipc/templates/django_cfg_ipc/components/requests_content.html,sha256=q1kQ0izzf4PIg0WLkX0bfyIJ_RquUQrLedQ_xYllLH4,1346
150
+ django_cfg/apps/ipc/templates/django_cfg_ipc/components/stat_cards.html,sha256=8CnB5Tx7BOkAuSZm6BjHuxBZkaHrXnw0kQwT4PjipFc,2695
151
+ django_cfg/apps/ipc/templates/django_cfg_ipc/components/system_status.html,sha256=qNe98FDgJGhOxSoi9xnCpd1Qzhlx3H6cPSy0Tu4A-c0,2018
152
+ django_cfg/apps/ipc/templates/django_cfg_ipc/components/tab_navigation.html,sha256=5HFvvNr-u6gIu4Km6ePjOsv65s03z_49xhX9n85_WoY,2415
153
+ django_cfg/apps/ipc/templates/django_cfg_ipc/components/testing_tools.html,sha256=g1FiEHIoaFwoecUP6qi1tPRckVZTbq5FsFinkkPuOjM,10241
154
+ django_cfg/apps/ipc/templates/django_cfg_ipc/layout/base.html,sha256=naTYIAlETt00FVVBmz-dB5iPWekITagkTgGgKb25N60,2405
155
+ django_cfg/apps/ipc/templates/django_cfg_ipc/pages/dashboard.html,sha256=DHy2a1UlESuc5nZfN8DqNjS02QDtmWWMVggjXDMh6DA,1973
156
+ django_cfg/apps/ipc/views/__init__.py,sha256=8aJAuDRg9CInvJ9CgSVC7aTIsVdziQwqTQVohsudUSo,241
157
+ django_cfg/apps/ipc/views/dashboard.py,sha256=s8JLG9FbAtER0u3D0dx1hGhLZrjp1lcnizPsk2COxm4,407
158
+ django_cfg/apps/ipc/views/monitoring.py,sha256=yqHkYvregMXVad6knYq3qSgxheDN31PawjdvK0ee-Oc,8937
159
+ django_cfg/apps/ipc/views/testing.py,sha256=BUIAaVQNbNPVccXhfbSnVyFm0PuNVOAqvlNvpKpt7ns,9603
141
160
  django_cfg/apps/knowbase/README.md,sha256=HXt_J6WCN-LsMhA7p9mdvih07_vp_r_hkPdmqHhNEeo,3965
142
161
  django_cfg/apps/knowbase/__init__.py,sha256=cfGnxDQwjajPhUoleKkgvdabJcB0LdXEglnsBojKkPo,1045
143
162
  django_cfg/apps/knowbase/apps.py,sha256=GAYw98_rQdGHoak58xN-0vjdDcRNpJuND3kV-FfM1II,3290
@@ -734,7 +753,7 @@ django_cfg/modules/django_client/spectacular/enum_naming.py,sha256=FMJyJiS7nBs-Q
734
753
  django_cfg/modules/django_client/spectacular/schema.py,sha256=6oJxoNsSsZLlM2qmKuJGU1sPPyEGr1Xit_xBfLvprHU,1639
735
754
  django_cfg/modules/django_client/system/__init__.py,sha256=uDARdYmmJ2yR0pCNaIQpsAPcErvhO7FNYX0CTbow8Y8,622
736
755
  django_cfg/modules/django_client/system/base_generator.py,sha256=skEf8_vXz3AeHZqOg_BjqsL1AToPn-RQY0211-ZXncM,4396
737
- django_cfg/modules/django_client/system/generate_mjs_clients.py,sha256=TkM1eNUOdvQNUswRBPGHcVfianThSMUpEU4_bVR1Nos,5650
756
+ django_cfg/modules/django_client/system/generate_mjs_clients.py,sha256=-EEnibUErUOJfODAqdorLw3p_IjRGln_R_-oKXrHN10,5653
738
757
  django_cfg/modules/django_client/system/mjs_generator.py,sha256=c6ktFR8Ipuju3CGPe6NUnlBwiqPrT_ik1ysRsBcd9Nw,7351
739
758
  django_cfg/modules/django_client/system/schema_parser.py,sha256=wRQ8nAIDsEIwTKBjK76ac36OWiH8hD0GKs-w9FpVBpw,6982
740
759
  django_cfg/modules/django_client/system/templates/api_client.js.j2,sha256=u3CLl4LVNgGrusuhiY8Q7btWpwkF2ijYxtZmFCsbBfk,2803
@@ -770,6 +789,7 @@ django_cfg/modules/django_dashboard/sections/documentation.py,sha256=rpBRGhawCay
770
789
  django_cfg/modules/django_dashboard/sections/overview.py,sha256=Gfgl55d9S9ohzDJ_UxxCP7ny6NbbhfZ24l1uAs0PEc0,13391
771
790
  django_cfg/modules/django_dashboard/sections/stats.py,sha256=5k2DKr_87Os0H8Wd_hU3sIcAq799OOnjApJ14hDF-gc,1282
772
791
  django_cfg/modules/django_dashboard/sections/system.py,sha256=3zAfms02qB2zSQt3BjBYKw-JlLTjaj0A6qciqYOKNMo,2026
792
+ django_cfg/modules/django_dashboard/sections/widgets.py,sha256=sFUhk8BWW-KzMw3hDjcotw1hz3LFULGhHRhx5shrYC4,7646
773
793
  django_cfg/modules/django_drf_theme/__init__.py,sha256=0D5ctzcjadbw-z7jpvVjvo8C1ufrGRk6b-mA4xSutTE,525
774
794
  django_cfg/modules/django_drf_theme/apps.py,sha256=UzcjnTQyMqExKGwhg5KhCK0eEqgGXtaYbCztHd_V2pw,428
775
795
  django_cfg/modules/django_drf_theme/renderers.py,sha256=AVlXpepI62iHcZhbGAsLwtXpnQ8NeN0zyWQbePUnN3w,1808
@@ -890,7 +910,7 @@ django_cfg/modules/django_twilio/templates/guide.md,sha256=nZfwx-sgWyK5NApm93zOe
890
910
  django_cfg/modules/django_twilio/templates/sendgrid_otp_email.html,sha256=sXR6_D9hmOFfk9CrfPizpLddVhkRirBWpZd_ioEsxVk,6671
891
911
  django_cfg/modules/django_twilio/templates/sendgrid_test_data.json,sha256=fh1VyuSiDELHsS_CIz9gp7tlsMAEjaDOoqbAPSZ3yyo,339
892
912
  django_cfg/modules/django_unfold/__init__.py,sha256=QB551Si2k-g_LoB3WdhkLBKaI2O4qiynCCCbzhqLM3c,1898
893
- django_cfg/modules/django_unfold/dashboard.py,sha256=c0R9DYFpv0LQR46NA2RPvZkp0CmjEOu5kY2zGRUHac8,15894
913
+ django_cfg/modules/django_unfold/dashboard.py,sha256=xqBpKb4o2C_mndks7fkkOD8Cp4szcc8_r8ACVj3IGwc,17342
894
914
  django_cfg/modules/django_unfold/models.py,sha256=E6NPu2lKkgXkTsqpriupoW5IER_nuvATYvoO8VzjhWE,3942
895
915
  django_cfg/modules/django_unfold/system_monitor.py,sha256=KcrTa5irstdB1pDKe3sC0zl4tz9LVjhp7xvbqUM4YVk,6781
896
916
  django_cfg/modules/django_unfold/tailwind.py,sha256=9yy50g4AQKnEKAHlcS9mJ4cX7v_d-on4Tei8m9kYA2w,10633
@@ -901,7 +921,7 @@ django_cfg/modules/django_unfold/callbacks/apizones.py,sha256=SHHlMGoCxBxijafdUp
901
921
  django_cfg/modules/django_unfold/callbacks/base.py,sha256=1qVfK7aIWs9DzFWsCjP6QBF8UD48A3G1cwvIegQXcEA,9990
902
922
  django_cfg/modules/django_unfold/callbacks/charts.py,sha256=OhqT_w7qV5XBqQaEBXKl1IkclhCcjdI2I8phYBO0W1Y,7965
903
923
  django_cfg/modules/django_unfold/callbacks/commands.py,sha256=qQ8z3oeaieyJDJHKd_VZ38jksZ1NmJM-mMptNI1IV7c,1281
904
- django_cfg/modules/django_unfold/callbacks/main.py,sha256=jxV3LwYNL58gQY7sBNtGuJJwhoWPKQyyFkNn0FVXW4A,11980
924
+ django_cfg/modules/django_unfold/callbacks/main.py,sha256=qDUiAzl0Keh1zl2s0awbPmBMUoRpSOkhpX1sjCgnJ04,13366
905
925
  django_cfg/modules/django_unfold/callbacks/statistics.py,sha256=f6yDLywGqAgDyoEv1CzWEGVsqIrT6o-bTv4CgfeTmMo,8746
906
926
  django_cfg/modules/django_unfold/callbacks/system.py,sha256=7YWC_-Db6bvDxArxMNfRoTRuRq9reF67UJn8IpWel8c,6078
907
927
  django_cfg/modules/django_unfold/callbacks/users.py,sha256=5UHPLZyG1GWTKSO6FZyWJloWJ-fnTpCYNAgyADab7aQ,2070
@@ -927,24 +947,26 @@ django_cfg/static/admin/js/commands.js,sha256=o_t5gFGsVsL3ApFFyokDNk3oUip5hPn0tu
927
947
  django_cfg/static/admin/js/dashboard.js,sha256=uCcu6mnG0HNiHI_HVyYMc5c1YGg727PzutZU8JNR9Es,4176
928
948
  django_cfg/static/js/api-loader.mjs,sha256=boGqqRGnFR-Mzo_RQOjhAzNvsb7QxZddSwMKROzkk9Q,5163
929
949
  django_cfg/static/js/api/base.mjs,sha256=Qjngf8783y47FnQ0ZOvtdFTSF6t-vYqvJaFPJmaTY40,4524
930
- django_cfg/static/js/api/index.mjs,sha256=6Hf0FJnbpW8fddWqlRnZyXLyHdG6sXIRLVjpKiISjtg,2349
931
- django_cfg/static/js/api/types.mjs,sha256=ybBPGQCb9X-jHldqO9MpcZNAdWgfDXZbHtq2-ILx8jw,77092
950
+ django_cfg/static/js/api/index.mjs,sha256=lZEWrgU1xGOgXT3O5J2u-cXq7_5CzgKwkaLyiEWvfl0,2482
951
+ django_cfg/static/js/api/types.mjs,sha256=L6tl85PfYX2kPGrIZ17kQbYOlh0MSKsBiX3HBsoamUg,61427
932
952
  django_cfg/static/js/api/accounts/client.mjs,sha256=taP5xvYSMhRdhob1WxLmdM-5SsyQv7WIs2ONVecZ5Mw,3708
933
953
  django_cfg/static/js/api/accounts/index.mjs,sha256=Inx2iGWk4K5JXMLeRCfTnTfSviTwuZQJKjn5RVyVDqE,315
934
- django_cfg/static/js/api/ipc/client.mjs,sha256=2WSGfhU4czVerVsTcWiCcp9NaXDI1kBViLq4hHrx-nU,3751
954
+ django_cfg/static/js/api/ipc/client.mjs,sha256=vGzH_HPjC_Z90EW2LslNYoAqQDEGxb_qBDSGGNgWZ6w,6445
935
955
  django_cfg/static/js/api/ipc/index.mjs,sha256=Zenfy7i2Hthq4bFBfjz2QxjWhLNaC5W1FvHeMqgLQ-o,280
956
+ django_cfg/static/js/api/knowbase/client.mjs,sha256=GsX-GF-9YGtff2RS9K97J05Ye8UP_gV7MWXTuH12vqw,24449
957
+ django_cfg/static/js/api/knowbase/index.mjs,sha256=AOJD4k_cp-dG-IwscX_YyLUBNzUrjLuZIoTyBJ2TUzs,315
936
958
  django_cfg/static/js/api/leads/client.mjs,sha256=XCOvHzST9SzBTS3PA2y2cgXc3MyrlCGGnkiu9Nge1Xg,3380
937
959
  django_cfg/static/js/api/leads/index.mjs,sha256=5jG0w5FJEWwtZ5wzp9Pfzl687DmF6NRqmXKUqMHRLdo,294
938
960
  django_cfg/static/js/api/newsletter/client.mjs,sha256=HRoovJSYfreyL798itLUlkqowVN20Smfq3UxXIUwaiA,7148
939
961
  django_cfg/static/js/api/newsletter/index.mjs,sha256=PdKy7BwCMhdUCEcjpTGEBpIYP0IlWM70pkZA1COzv8c,329
940
- django_cfg/static/js/api/payments/client.mjs,sha256=H4WXZWW0X6aT-s5lOQqwJqTjjW839DZSV563ABZh4ds,81275
962
+ django_cfg/static/js/api/payments/client.mjs,sha256=xny3OUW0kQC3Hb112uTRreNkQWaOJEoG_I4-hseGeaI,4253
941
963
  django_cfg/static/js/api/payments/index.mjs,sha256=BlPilLuoQZPFNgVPkgZbKVhFwP-NmjpejSYRHdFxnWw,315
942
964
  django_cfg/static/js/api/support/client.mjs,sha256=kqI80DkAVfn3yqEI4RFLeu01hg2mqFsVhk0O6YjKwv4,5661
943
965
  django_cfg/static/js/api/support/index.mjs,sha256=oPA3iGkUWYyKQuJlI5-tSxD3AOhwlAzXKAh4CNCNziQ,308
944
966
  django_cfg/static/js/api/tasks/client.mjs,sha256=tIy8K-finXzTUL9kOo_L4Q1kchDaHyuzjwS4VymiWPM,3579
945
967
  django_cfg/static/js/api/tasks/index.mjs,sha256=yCY1GzdD-RtFZ3pAfk1l0msgO1epyo0lsGCjH0g1Afc,294
946
968
  django_cfg/templates/__init__.py,sha256=IzLjt-a7VIJ0OutmAE1_-w0_LpL2u0MgGpnIabjZuW8,19
947
- django_cfg/templates/admin/index.html,sha256=zZAOy393_KMu9fnD1XMDG5OABg3r3tl9lY0QGLuE-rU,2170
969
+ django_cfg/templates/admin/index.html,sha256=bbGe7QgEkbmc8m01uOcZ_ytYtRPULBkp95yxVns4i6Y,2366
948
970
  django_cfg/templates/admin/index_new.html,sha256=B5nC6TMjHCvbyX-SG7kIyLbFyGUNm-86Uo694EdfUZQ,4262
949
971
  django_cfg/templates/admin/components/action_grid.html,sha256=Ol6UqHR6CQkrLzOIqIWeBk-fu3dYu2x1xxjaL6HnXRQ,2840
950
972
  django_cfg/templates/admin/components/card.html,sha256=gOW8MBvRiWPQdoSYg_MH7KQ8o_WTRC5anyefRcPtRjM,2167
@@ -969,12 +991,13 @@ django_cfg/templates/admin/import_export/change_list_export.html,sha256=oFBsnpgZ
969
991
  django_cfg/templates/admin/import_export/change_list_import.html,sha256=jL7Dhjcbx8IfzY-ltlxoWLvF97tD9B77moj8Mh6sRjY,1214
970
992
  django_cfg/templates/admin/import_export/change_list_import_export.html,sha256=KWnPbkv_kP5TlAKBRutbk_eFTqPXDt6_SmxXULE94iE,1840
971
993
  django_cfg/templates/admin/layouts/base_dashboard.html,sha256=GziX02ldpFNvnuIxUl2FrWBEs97A4DuvE_BOZaDkyLU,1935
972
- django_cfg/templates/admin/layouts/dashboard_with_tabs.html,sha256=Wu5M6mAe7hez5BBltY2_EwxRgBv5bghtgUm12DDjMAA,20162
994
+ django_cfg/templates/admin/layouts/dashboard_with_tabs.html,sha256=BrpQldcMjFm6ZnQxUwWk6U13ucb05vog9juOaDP_hAw,20589
973
995
  django_cfg/templates/admin/sections/commands_section.html,sha256=I6PsDeQtQWc9xBxbIVa39jfZ7WAu4U3Q8Cii4hsIBCE,28948
974
996
  django_cfg/templates/admin/sections/documentation_section.html,sha256=aIJ8nAd0Ifw5-Zfl-HLDx_x5KxF9InWyqrI2sJf9Dks,10451
975
997
  django_cfg/templates/admin/sections/overview_section.html,sha256=gfhjBzQBtZQAj1DnjhFE6efgXFWb4GotIgW6kyRVE-g,4726
976
998
  django_cfg/templates/admin/sections/stats_section.html,sha256=iUF-ILAkHBHMb7p2pZXsn_ILYd68mmyr7uFH4He2TKg,1524
977
999
  django_cfg/templates/admin/sections/system_section.html,sha256=jcbLoIF-EIodppWFrf8zs85zxdAfFpjdcNuiGIwmjNE,4766
1000
+ django_cfg/templates/admin/sections/widgets_section.html,sha256=xgRF-M1iuN4E4QNuiyrem1XHs7UKzdPribeWu91_J5w,6444
978
1001
  django_cfg/templates/admin/snippets/components/CHARTS_GUIDE.md,sha256=SM0gO0bchhgTZdLXfZxv7Zq0Bbt0C0cfFqceUcL4JCU,8923
979
1002
  django_cfg/templates/admin/snippets/components/activity_tracker.html,sha256=y9PsU_XKBPxiOm762UL7ZAw0Lqh5D4lUTgFnLeCso3w,4359
980
1003
  django_cfg/templates/admin/snippets/components/charts_section.html,sha256=eIJFFuy3vAz0pYRAVEgJ7Nzc3BbNGIqrEWT4SitoMrQ,9808
@@ -994,6 +1017,7 @@ django_cfg/templates/admin/snippets/tabs/documentation_tab.html,sha256=3SGpqsIsl
994
1017
  django_cfg/templates/admin/snippets/tabs/overview_tab.html,sha256=mX8C9EQmpwW-uYN5i0hjpn-q-LXtjenGWNI3BmsJsaI,3918
995
1018
  django_cfg/templates/admin/snippets/tabs/stats_tab.html,sha256=jIqSnp4WTo2jAzzMqo9As6z5PykWsO_V1VwBEpTzZ5E,5170
996
1019
  django_cfg/templates/admin/snippets/tabs/users_tab.html,sha256=04D05VSeidn2qJnQmktVI7TNlm7tNcXYXJAsk32U5hY,2813
1020
+ django_cfg/templates/admin/snippets/tabs/widgets_tab.html,sha256=1TxvLPjydcOQRVdaEzGaIq8QZD_CmGY58X9wcqNrtpM,1699
997
1021
  django_cfg/templates/admin/snippets/zones/zones_table.html,sha256=WtaI-x16LijochRy7uFj8xyUeqcCqhenF9xKRW_JQWE,11879
998
1022
  django_cfg/templates/emails/base_email.html,sha256=TWcvYa2IHShlF_E8jf1bWZStRO0v8G4L_GexPxvz6XQ,8836
999
1023
  django_cfg/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -1005,9 +1029,9 @@ django_cfg/utils/version_check.py,sha256=WO51J2m2e-wVqWCRwbultEwu3q1lQasV67Mw2aa
1005
1029
  django_cfg/CHANGELOG.md,sha256=jtT3EprqEJkqSUh7IraP73vQ8PmKUMdRtznQsEnqDZk,2052
1006
1030
  django_cfg/CONTRIBUTING.md,sha256=DU2kyQ6PU0Z24ob7O_OqKWEYHcZmJDgzw-lQCmu6uBg,3041
1007
1031
  django_cfg/LICENSE,sha256=xHuytiUkSZCRG3N11nk1X6q1_EGQtv6aL5O9cqNRhKE,1071
1008
- django_cfg/pyproject.toml,sha256=qxPPXXqPfkJp9WoFlbzjnLWaQ0N-a8YuKGMUKvQSFGI,8260
1009
- django_cfg-1.4.59.dist-info/METADATA,sha256=1y9UqOQtgYjWfqFJU3-kSUeMDwmtsP06hmGUZ5hPlEg,22589
1010
- django_cfg-1.4.59.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
1011
- django_cfg-1.4.59.dist-info/entry_points.txt,sha256=Ucmde4Z2wEzgb4AggxxZ0zaYDb9HpyE5blM3uJ0_VNg,56
1012
- django_cfg-1.4.59.dist-info/licenses/LICENSE,sha256=xHuytiUkSZCRG3N11nk1X6q1_EGQtv6aL5O9cqNRhKE,1071
1013
- django_cfg-1.4.59.dist-info/RECORD,,
1032
+ django_cfg/pyproject.toml,sha256=uRiQ0bh7I2s6i1PaZbVrLukJxc76LqNVAahy3DZ-fLU,8260
1033
+ django_cfg-1.4.60.dist-info/METADATA,sha256=JN6wZGPFqI3Aa0DcXJn77Dc-8Q2qAjEWCtfigCni29o,22589
1034
+ django_cfg-1.4.60.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
1035
+ django_cfg-1.4.60.dist-info/entry_points.txt,sha256=Ucmde4Z2wEzgb4AggxxZ0zaYDb9HpyE5blM3uJ0_VNg,56
1036
+ django_cfg-1.4.60.dist-info/licenses/LICENSE,sha256=xHuytiUkSZCRG3N11nk1X6q1_EGQtv6aL5O9cqNRhKE,1071
1037
+ django_cfg-1.4.60.dist-info/RECORD,,
@@ -1,202 +0,0 @@
1
- {% extends 'django_cfg_ipc/base.html' %}
2
- {% load static %}
3
-
4
- {% block title %}Dashboard{% endblock %}
5
-
6
- {% block content %}
7
- <!-- Overview Stats Cards -->
8
- <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
9
- <!-- Total Requests -->
10
- <div class="stat-card bg-white dark:bg-gray-800 rounded-lg p-6 border border-gray-200 dark:border-gray-700">
11
- <div class="flex items-center justify-between mb-4">
12
- <span class="material-icons text-4xl text-blue-500 dark:text-blue-400">bar_chart</span>
13
- <span class="text-xs text-gray-600 dark:text-gray-400">Today</span>
14
- </div>
15
- <h3 class="text-2xl font-bold text-gray-900 dark:text-white mb-1" id="total-requests">
16
- {{ overview_stats.total_requests_today|default:"0" }}
17
- </h3>
18
- <p class="text-sm text-gray-600 dark:text-gray-400">Total Requests</p>
19
- </div>
20
-
21
- <!-- Active Methods -->
22
- <div class="stat-card bg-white dark:bg-gray-800 rounded-lg p-6 border border-gray-200 dark:border-gray-700">
23
- <div class="flex items-center justify-between mb-4">
24
- <span class="material-icons text-4xl text-green-500 dark:text-green-400">functions</span>
25
- <span class="text-xs text-gray-600 dark:text-gray-400">Active</span>
26
- </div>
27
- <h3 class="text-2xl font-bold text-gray-900 dark:text-white mb-1" id="active-methods-count">
28
- {{ overview_stats.active_methods|length|default:"0" }}
29
- </h3>
30
- <p class="text-sm text-gray-600 dark:text-gray-400">Active Methods</p>
31
- </div>
32
-
33
- <!-- Avg Response Time -->
34
- <div class="stat-card bg-white dark:bg-gray-800 rounded-lg p-6 border border-gray-200 dark:border-gray-700">
35
- <div class="flex items-center justify-between mb-4">
36
- <span class="material-icons text-4xl text-yellow-500 dark:text-yellow-400">timer</span>
37
- <span class="text-xs text-gray-600 dark:text-gray-400">Average</span>
38
- </div>
39
- <h3 class="text-2xl font-bold text-gray-900 dark:text-white mb-1" id="avg-response-time">
40
- {{ overview_stats.avg_response_time_ms|default:"0" }}<span class="text-lg text-gray-600 dark:text-gray-400">ms</span>
41
- </h3>
42
- <p class="text-sm text-gray-600 dark:text-gray-400">Response Time</p>
43
- </div>
44
-
45
- <!-- Success Rate -->
46
- <div class="stat-card bg-white dark:bg-gray-800 rounded-lg p-6 border border-gray-200 dark:border-gray-700">
47
- <div class="flex items-center justify-between mb-4">
48
- <span class="material-icons text-4xl text-purple-500 dark:text-purple-400">check_circle</span>
49
- <span class="text-xs text-gray-600 dark:text-gray-400">Rate</span>
50
- </div>
51
- <h3 class="text-2xl font-bold text-gray-900 dark:text-white mb-1" id="success-rate">
52
- {{ overview_stats.success_rate|default:"0" }}<span class="text-lg text-gray-600 dark:text-gray-400">%</span>
53
- </h3>
54
- <p class="text-sm text-gray-600 dark:text-gray-400">Success Rate</p>
55
- </div>
56
- </div>
57
-
58
- <!-- System Status -->
59
- <div class="bg-white dark:bg-gray-800 rounded-lg p-6 border border-gray-200 dark:border-gray-700 mb-8">
60
- <h2 class="text-xl font-bold text-gray-900 dark:text-white mb-4 flex items-center">
61
- <span class="material-icons mr-2">health_and_safety</span>
62
- System Status
63
- </h2>
64
- <div id="system-status" class="grid grid-cols-1 md:grid-cols-3 gap-4">
65
- <!-- Redis Status -->
66
- <div class="flex items-start gap-3">
67
- <span class="material-icons flex-shrink-0 text-2xl {% if health.redis_connected %}text-green-500{% else %}text-red-500{% endif %}">
68
- {% if health.redis_connected %}check_circle{% else %}cancel{% endif %}
69
- </span>
70
- <div class="min-w-0">
71
- <p class="text-sm font-medium text-gray-900 dark:text-white">Redis</p>
72
- <p class="text-xs text-gray-600 dark:text-gray-400">
73
- {% if health.redis_connected %}Connected (DB 2){% else %}Disconnected{% endif %}
74
- </p>
75
- </div>
76
- </div>
77
-
78
- <!-- Stream Status -->
79
- <div class="flex items-start gap-3">
80
- <span class="material-icons flex-shrink-0 text-2xl {% if health.stream_exists %}text-green-500{% else %}text-gray-500{% endif %}">
81
- {% if health.stream_exists %}stream{% else %}stream_off{% endif %}
82
- </span>
83
- <div class="min-w-0">
84
- <p class="text-sm font-medium text-gray-900 dark:text-white">Request Stream</p>
85
- <p class="text-xs text-gray-600 dark:text-gray-400">
86
- {% if health.stream_exists %}{{ health.stream_length }} entries{% else %}Not initialized{% endif %}
87
- </p>
88
- </div>
89
- </div>
90
-
91
- <!-- Activity Status -->
92
- <div class="flex items-start gap-3">
93
- <span class="material-icons flex-shrink-0 text-2xl {% if health.recent_activity %}text-green-500{% else %}text-yellow-500{% endif %}">
94
- {% if health.recent_activity %}notifications_active{% else %}notifications_paused{% endif %}
95
- </span>
96
- <div class="min-w-0">
97
- <p class="text-sm font-medium text-gray-900 dark:text-white">Recent Activity</p>
98
- <p class="text-xs text-gray-600 dark:text-gray-400">
99
- {% if health.recent_activity %}Active (last 5 min){% else %}No recent activity{% endif %}
100
- </p>
101
- </div>
102
- </div>
103
- </div>
104
- </div>
105
-
106
- <!-- Tabs Navigation -->
107
- <div class="border-b border-gray-200 dark:border-gray-700 mb-6">
108
- <nav class="flex space-x-4">
109
- <button class="tab-button active px-4 py-2 text-blue-600 dark:text-blue-400 border-b-2 border-blue-600 dark:border-blue-400 font-medium" data-tab="overview">
110
- Overview
111
- </button>
112
- <button class="tab-button px-4 py-2 text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-300 border-b-2 border-transparent font-medium" data-tab="requests">
113
- Recent Requests
114
- </button>
115
- <button class="tab-button px-4 py-2 text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-300 border-b-2 border-transparent font-medium" data-tab="notifications">
116
- Notifications
117
- </button>
118
- <button class="tab-button px-4 py-2 text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-300 border-b-2 border-transparent font-medium" data-tab="methods">
119
- Methods
120
- </button>
121
- </nav>
122
- </div>
123
-
124
- <!-- Tab Content -->
125
- <div class="tab-content">
126
- <!-- Overview Tab (Active by default) -->
127
- <div id="overview-tab" class="tab-panel">
128
- <div class="bg-white dark:bg-gray-800 rounded-lg p-6 border border-gray-200 dark:border-gray-700">
129
- <h3 class="text-lg font-bold text-gray-900 dark:text-white mb-4">Top Method</h3>
130
- <p class="text-gray-700 dark:text-gray-300" id="top-method">
131
- {% if overview_stats.top_method %}
132
- <code class="bg-gray-100 dark:bg-gray-700 px-2 py-1 rounded text-blue-600 dark:text-blue-300">{{ overview_stats.top_method }}</code>
133
- {% else %}
134
- No data available
135
- {% endif %}
136
- </p>
137
- </div>
138
- </div>
139
-
140
- <!-- Recent Requests Tab -->
141
- <div id="requests-tab" class="tab-panel hidden">
142
- <div class="bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 overflow-hidden">
143
- <table class="w-full">
144
- <thead class="bg-gray-50 dark:bg-gray-900">
145
- <tr>
146
- <th class="px-4 py-3 text-left text-xs font-medium text-gray-700 dark:text-gray-400 uppercase">Time</th>
147
- <th class="px-4 py-3 text-left text-xs font-medium text-gray-700 dark:text-gray-400 uppercase">Method</th>
148
- <th class="px-4 py-3 text-left text-xs font-medium text-gray-700 dark:text-gray-400 uppercase">Correlation ID</th>
149
- <th class="px-4 py-3 text-left text-xs font-medium text-gray-700 dark:text-gray-400 uppercase">Params</th>
150
- </tr>
151
- </thead>
152
- <tbody id="requests-table-body" class="divide-y divide-gray-200 dark:divide-gray-700">
153
- <tr>
154
- <td colspan="4" class="px-4 py-8 text-center text-gray-600 dark:text-gray-400">
155
- Loading...
156
- </td>
157
- </tr>
158
- </tbody>
159
- </table>
160
- </div>
161
- </div>
162
-
163
- <!-- Notifications Tab -->
164
- <div id="notifications-tab" class="tab-panel hidden">
165
- <div class="bg-white dark:bg-gray-800 rounded-lg p-6 border border-gray-200 dark:border-gray-700">
166
- <h3 class="text-lg font-bold text-gray-900 dark:text-white mb-4">Notification Statistics</h3>
167
- <div id="notification-stats-content">
168
- <p class="text-gray-600 dark:text-gray-400">Loading...</p>
169
- </div>
170
- </div>
171
- </div>
172
-
173
- <!-- Methods Tab -->
174
- <div id="methods-tab" class="tab-panel hidden">
175
- <div class="bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 overflow-hidden">
176
- <table class="w-full">
177
- <thead class="bg-gray-50 dark:bg-gray-900">
178
- <tr>
179
- <th class="px-4 py-3 text-left text-xs font-medium text-gray-700 dark:text-gray-400 uppercase">Method</th>
180
- <th class="px-4 py-3 text-left text-xs font-medium text-gray-700 dark:text-gray-400 uppercase">Count</th>
181
- <th class="px-4 py-3 text-left text-xs font-medium text-gray-700 dark:text-gray-400 uppercase">Percentage</th>
182
- <th class="px-4 py-3 text-left text-xs font-medium text-gray-700 dark:text-gray-400 uppercase">Avg Time</th>
183
- </tr>
184
- </thead>
185
- <tbody id="methods-table-body" class="divide-y divide-gray-200 dark:divide-gray-700">
186
- <tr>
187
- <td colspan="4" class="px-4 py-8 text-center text-gray-600 dark:text-gray-400">
188
- Loading...
189
- </td>
190
- </tr>
191
- </tbody>
192
- </table>
193
- </div>
194
- </div>
195
- </div>
196
- {% endblock %}
197
-
198
- {% block extra_js %}
199
- {% load i18n %}
200
- {% now "U" as current_timestamp %}
201
- <script type="module" src="{% static 'django_cfg_ipc/js/dashboard.mjs' %}?v={{ current_timestamp }}"></script>
202
- {% endblock %}