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,549 +0,0 @@
1
- {% load unfold %}
2
-
3
- <!-- Commands Section -->
4
- <div class="space-y-8" x-data="commandsSection({{ data.commands|length }})">
5
- <div class="flex items-center justify-between mb-6">
6
- <div>
7
- <h1 class="text-2xl font-bold text-font-important-light dark:text-font-important-dark">{{ title|default:"Management Commands" }}</h1>
8
- <p class="text-font-default-light dark:text-font-default-dark mt-2">
9
- Execute Django management commands directly from the dashboard
10
- </p>
11
- </div>
12
- <div class="text-sm text-font-subtle-light dark:text-font-subtle-dark">
13
- Total: <span x-text="visibleCommands" class="font-mono font-semibold text-font-important-light dark:text-font-important-dark"></span> commands
14
- </div>
15
- </div>
16
-
17
- <!-- Search Box -->
18
- <div class="flex items-center gap-3 mb-6">
19
- <div class="relative flex-1 max-w-md">
20
- <span class="material-symbols-outlined absolute left-3 top-1/2 -translate-y-1/2 text-base-400 dark:text-base-500">search</span>
21
- <input
22
- type="text"
23
- x-model="searchQuery"
24
- @input="search()"
25
- placeholder="Search commands..."
26
- class="w-full pl-10 pr-10 py-2 border border-base-200 dark:border-base-700 rounded-default bg-white dark:bg-base-800 text-font-important-light dark:text-font-important-dark placeholder-font-subtle-light dark:placeholder-font-subtle-dark focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-transparent"
27
- />
28
- <button
29
- x-show="showClearButton"
30
- @click="clearSearch()"
31
- class="absolute right-3 top-1/2 -translate-y-1/2 text-base-400 dark:text-base-500 hover:text-base-600 dark:hover:text-base-300"
32
- >
33
- <span class="material-symbols-outlined text-lg">close</span>
34
- </button>
35
- </div>
36
- </div>
37
-
38
- <!-- Commands by Category -->
39
- {% if data.categories %}
40
- <div class="flex flex-col gap-6">
41
- {% for category, category_commands in data.categories.items %}
42
- {% if category_commands %}
43
- <div class="category-block bg-gradient-to-br from-white to-base-50 dark:from-base-800 dark:to-base-900 rounded-default shadow-md border border-base-200 dark:border-base-700 overflow-hidden">
44
- <div class="p-6 border-b border-base-200 dark:border-base-700 category-toggle cursor-pointer hover:bg-base-100/50 dark:hover:bg-base-900/30 transition-all duration-200"
45
- @click="toggleCategory('{{ category }}')"
46
- data-category="{{ category }}">
47
- <div class="w-full flex items-center justify-between">
48
- <h3 class="text-lg font-semibold text-font-important-light dark:text-font-important-dark flex items-center">
49
- <div class="w-10 h-10 rounded-lg bg-primary-100 dark:bg-primary-900/30 flex items-center justify-center mr-3">
50
- <span class="material-symbols-outlined text-primary-600 dark:text-primary-400">
51
- {% if category == 'django_cfg' %}settings
52
- {% elif category == 'django_core' %}apps
53
- {% elif category == 'third_party' %}extension
54
- {% else %}folder{% endif %}
55
- </span>
56
- </div>
57
- <div>
58
- <div class="flex items-center gap-2">
59
- {{ category|title }} Commands
60
- <span class="px-2 py-0.5 text-xs font-medium rounded-full bg-base-200 dark:bg-base-700 text-font-default-light dark:text-font-default-dark category-count">
61
- {{ category_commands|length }}
62
- </span>
63
- </div>
64
- </div>
65
- </h3>
66
- <span
67
- class="material-symbols-outlined text-base-400 dark:text-base-500 transition-transform duration-200 select-none"
68
- x-text="isCategoryExpanded('{{ category }}') ? 'expand_less' : 'expand_more'"
69
- ></span>
70
- </div>
71
- </div>
72
- <div class="p-6 category-content bg-base-50/30 dark:bg-base-900/30"
73
- data-category="{{ category }}"
74
- x-show="isCategoryExpanded('{{ category }}')"
75
- x-cloak>
76
- <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
77
- {% for cmd in category_commands %}
78
- <button type="button"
79
- @click="confirmCommand('{{ cmd.name }}', '{{ cmd.app }}', '{{ cmd.description|escapejs|default:'-' }}')"
80
- class="command-btn command-item text-left p-4 rounded-default border border-base-200/60 dark:border-base-700/60 bg-white dark:bg-base-800 hover:border-base-300 dark:hover:border-base-600 hover:bg-white/80 dark:hover:bg-base-800/80 transition-all duration-200 group"
81
- data-command="{{ cmd.name }}"
82
- data-app="{{ cmd.app }}"
83
- data-description="{{ cmd.description|escapejs|default:'-' }}">
84
- <div class="flex items-center gap-3">
85
- <div class="flex-shrink-0">
86
- <span class="material-symbols-outlined text-primary-500 dark:text-primary-400 text-xl group-hover:text-primary-600 dark:group-hover:text-primary-300 transition-colors">terminal</span>
87
- </div>
88
- <div class="flex-1 grow min-w-0">
89
- <p class="font-mono text-sm text-font-important-light dark:text-font-important-dark font-semibold command-name truncate">{{ cmd.name }}</p>
90
- {% if cmd.description %}
91
- <p class="text-xs text-font-default-light dark:text-font-default-dark mt-1 line-clamp-2">{{ cmd.description }}</p>
92
- {% endif %}
93
- {% if cmd.app %}
94
- <p class="text-xs text-font-subtle-light dark:text-font-subtle-dark mt-1 truncate">
95
- <span class="opacity-60">from</span> {{ cmd.app }}
96
- </p>
97
- {% endif %}
98
- </div>
99
- <div class="flex-shrink-0">
100
- <span class="material-symbols-outlined text-base-400 dark:text-base-600 group-hover:text-primary-500 dark:group-hover:text-primary-400 transition-colors text-2xl">chevron_right</span>
101
- </div>
102
- </div>
103
- </button>
104
- {% endfor %}
105
- </div>
106
- </div>
107
- </div>
108
- {% endif %}
109
- {% endfor %}
110
- </div>
111
- {% else %}
112
- <!-- Fallback: All Commands List -->
113
- <div class="bg-white dark:bg-base-800 rounded-default shadow-sm border border-base-200 dark:border-base-700">
114
- <div class="p-6 border-b border-base-200 dark:border-base-700">
115
- <h3 class="text-lg font-semibold text-font-important-light dark:text-font-important-dark flex items-center">
116
- <span class="material-symbols-outlined text-primary-500 mr-2">list</span>
117
- All Commands
118
- </h3>
119
- </div>
120
- <div class="p-6">
121
- <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
122
- {% for cmd in data.commands %}
123
- <button type="button"
124
- class="command-btn text-left p-4 rounded-default border border-base-200 dark:border-base-700 bg-white dark:bg-base-800 hover:bg-base-100 dark:hover:bg-white/[.04] transition-colors"
125
- data-command="{{ cmd.name }}">
126
- <div class="flex items-center justify-between">
127
- <div>
128
- <p class="font-mono text-sm text-font-important-light dark:text-font-important-dark font-semibold">{{ cmd.name }}</p>
129
- {% if cmd.app %}
130
- <p class="text-xs text-font-subtle-light dark:text-font-subtle-dark mt-1">{{ cmd.app }}</p>
131
- {% endif %}
132
- </div>
133
- <span class="material-symbols-outlined text-primary-500">play_arrow</span>
134
- </div>
135
- </button>
136
- {% endfor %}
137
- </div>
138
- </div>
139
- </div>
140
- {% endif %}
141
-
142
- <!-- Confirm Modal -->
143
- <div x-show="showConfirmModal"
144
- @click.self="showConfirmModal = false"
145
- x-cloak
146
- x-data="{ modalTab: 'confirm' }"
147
- class="backdrop-blur-xs bg-base-900/80 fixed inset-0 p-4 lg:p-32 z-[1000]">
148
- <div class="bg-white dark:bg-base-800 rounded-default shadow-lg border border-base-200 dark:border-base-700 max-w-3xl mx-auto w-full max-h-[80vh] flex flex-col">
149
- <div class="px-4 py-3 border-b border-base-200 dark:border-base-700">
150
- <h3 class="text-lg font-semibold text-font-important-light dark:text-font-important-dark flex items-center gap-2">
151
- <span class="material-symbols-outlined text-amber-500 dark:text-amber-400">warning</span>
152
- Confirm Command Execution
153
- </h3>
154
-
155
- <!-- Tabs -->
156
- <div class="flex gap-2 mt-4 border-b border-base-200 dark:border-base-700">
157
- <button type="button"
158
- @click="modalTab = 'confirm'"
159
- :class="modalTab === 'confirm' ? 'border-b-2 border-primary-600 text-primary-600' : 'text-font-subtle-light dark:text-font-subtle-dark'"
160
- class="px-4 py-2 font-medium transition-colors">
161
- Confirm
162
- </button>
163
- <button type="button"
164
- @click="modalTab = 'help'"
165
- :class="modalTab === 'help' ? 'border-b-2 border-primary-600 text-primary-600' : 'text-font-subtle-light dark:text-font-subtle-dark'"
166
- class="px-4 py-2 font-medium transition-colors flex items-center gap-1">
167
- <span class="material-icons text-sm">help_outline</span>
168
- Help
169
- </button>
170
- </div>
171
- </div>
172
-
173
- <div class="flex-1 overflow-y-auto">
174
- <!-- Confirm Tab -->
175
- <div x-show="modalTab === 'confirm'" class="p-6">
176
- <p class="text-font-default-light dark:text-font-default-dark mb-4">
177
- Are you sure you want to execute the following command?
178
- </p>
179
- <div class="bg-base-100 dark:bg-base-900 rounded-default p-4 border border-base-200 dark:border-base-700">
180
- <div class="flex items-start gap-3">
181
- <span class="material-symbols-outlined text-primary-600 dark:text-primary-400 text-xl">terminal</span>
182
- <div class="flex-1 min-w-0">
183
- <p class="font-mono text-sm font-semibold text-font-important-light dark:text-font-important-dark" x-text="currentCommand"></p>
184
- <p class="text-xs text-font-subtle-light dark:text-font-subtle-dark mt-2" x-show="currentCommandApp" x-text="'from ' + currentCommandApp"></p>
185
- <p class="text-xs text-font-default-light dark:text-font-default-dark mt-1" x-show="currentCommandDescription" x-text="currentCommandDescription"></p>
186
- </div>
187
- </div>
188
- </div>
189
- </div>
190
-
191
- <!-- Help Tab -->
192
- <div x-show="modalTab === 'help'" class="p-6">
193
- <div class="mb-4">
194
- <h4 class="text-lg font-semibold text-font-important-light dark:text-font-important-dark mb-2">Command Help</h4>
195
- <p class="text-sm text-font-subtle-light dark:text-font-subtle-dark mb-4">
196
- Get detailed information about this command
197
- </p>
198
- </div>
199
-
200
- <div class="bg-base-100 dark:bg-base-900 rounded-default p-4 border border-base-200 dark:border-base-700 mb-4">
201
- <div class="flex items-start gap-3">
202
- <span class="material-icons text-primary-600 dark:text-primary-400">info</span>
203
- <div class="flex-1">
204
- <p class="font-semibold text-font-important-light dark:text-font-important-dark mb-2">Description</p>
205
- <p class="text-sm text-font-default-light dark:text-font-default-dark" x-text="currentCommandDescription || 'No description available'"></p>
206
- </div>
207
- </div>
208
- </div>
209
-
210
- <div class="bg-base-100 dark:bg-base-900 rounded-default p-4 border border-base-200 dark:border-base-700">
211
- <div class="flex items-start gap-3">
212
- <span class="material-icons text-blue-600 dark:text-blue-400">terminal</span>
213
- <div class="flex-1">
214
- <p class="font-semibold text-font-important-light dark:text-font-important-dark mb-2">Usage</p>
215
- <div class="bg-base-900 dark:bg-black text-green-400 p-3 rounded-default font-mono text-xs">
216
- <span>python manage.py <span x-text="currentCommand"></span> [options]</span>
217
- </div>
218
- <p class="text-xs text-font-subtle-light dark:text-font-subtle-dark mt-2">
219
- For detailed help, run: <code class="bg-base-200 dark:bg-base-700 px-2 py-1 rounded">python manage.py help <span x-text="currentCommand"></span></code>
220
- </p>
221
- </div>
222
- </div>
223
- </div>
224
- </div>
225
- </div>
226
-
227
- <div class="px-4 py-3 border-t border-base-200 dark:border-base-800 flex items-center justify-end gap-3">
228
- <button type="button" @click="cancelExecution()" class="px-4 py-2 text-font-default-light dark:text-font-default-dark hover:bg-base-100 dark:hover:bg-base-700 rounded-default transition-colors">
229
- Cancel
230
- </button>
231
- <button type="button" @click="executeCommand()" class="px-4 py-2 bg-primary-600 text-white rounded-default hover:bg-primary-700 transition-colors font-medium">
232
- Execute Command
233
- </button>
234
- </div>
235
- </div>
236
- </div>
237
-
238
- <!-- Command Output Modal -->
239
- <div x-show="showOutputModal"
240
- @click.self="closeOutputModal()"
241
- x-cloak
242
- class="backdrop-blur-xs bg-base-900/80 flex flex-col fixed inset-0 p-4 lg:p-32 z-[1000]">
243
- <div class="bg-white dark:bg-base-800 flex flex-col max-w-3xl min-h-0 mx-auto overflow-hidden rounded-default shadow-lg w-full">
244
- <div class="flex items-center justify-between px-4 py-3 border-b border-base-200 dark:border-base-700">
245
- <h3 class="text-lg font-semibold text-font-important-light dark:text-font-important-dark flex items-center gap-2">
246
- <span class="material-symbols-outlined text-primary-600 dark:text-primary-400">terminal</span>
247
- <span class="font-mono" x-text="currentCommand"></span>
248
- </h3>
249
- <button type="button" @click="closeOutputModal()" class="text-base-400 dark:text-base-500 hover:text-base-600 dark:hover:text-base-300 transition-colors">
250
- <span class="material-symbols-outlined">close</span>
251
- </button>
252
- </div>
253
- <div class="grow overflow-y-auto overflow-x-hidden w-full" x-ref="commandOutput">
254
- <div class="p-4">
255
- <pre x-text="commandOutput" class="bg-base-900 dark:bg-black text-green-400 p-4 rounded-default font-mono text-xs leading-relaxed whitespace-pre overflow-x-auto"></pre>
256
- </div>
257
- </div>
258
- <div class="px-4 py-3 border-t border-base-200 dark:border-base-700">
259
- <div class="flex items-center justify-between">
260
- <div class="flex items-center gap-2">
261
- <div :class="statusClass" class="w-3 h-3 rounded-full"></div>
262
- <span class="text-sm font-medium" x-text="statusText"></span>
263
- </div>
264
- <button type="button" @click="copyOutput()" class="px-4 py-2 bg-primary-600 text-white rounded-default hover:bg-primary-700 transition-colors flex items-center gap-2 font-medium">
265
- <span class="material-symbols-outlined text-base">content_copy</span>
266
- Copy Output
267
- </button>
268
- </div>
269
- </div>
270
- </div>
271
- </div>
272
-
273
- <!-- Load Alpine component -->
274
- {% load static %}
275
- <script src="{% static 'admin/js/alpine/commands-section.js' %}"></script>
276
-
277
- <!-- Documentation Section (Collapsible) -->
278
- <div class="mt-12" x-data="{ docsExpanded: false }">
279
- <div class="bg-gradient-to-br from-white to-base-50 dark:from-base-800 dark:to-base-900 rounded-lg shadow-md border border-base-200 dark:border-base-700 overflow-hidden">
280
- <!-- Header (Clickable) -->
281
- <div class="p-6 cursor-pointer hover:bg-base-100/50 dark:hover:bg-base-900/30 transition-all duration-200"
282
- @click="docsExpanded = !docsExpanded">
283
- <div class="flex items-center justify-between">
284
- <div class="flex items-center">
285
- <div class="w-10 h-10 rounded-lg bg-blue-100 dark:bg-blue-900/30 flex items-center justify-center mr-3">
286
- <span class="material-icons text-blue-600 dark:text-blue-400">menu_book</span>
287
- </div>
288
- <div>
289
- <h2 class="text-xl font-bold text-font-important-light dark:text-font-important-dark">
290
- Commands Documentation
291
- </h2>
292
- <p class="text-sm text-font-subtle-light dark:text-font-subtle-dark mt-1">
293
- Complete guide to Django management commands
294
- </p>
295
- </div>
296
- </div>
297
- <span class="material-icons text-base-400 dark:text-base-500 transition-transform duration-200"
298
- x-text="docsExpanded ? 'expand_less' : 'expand_more'"></span>
299
- </div>
300
- </div>
301
-
302
- <!-- Content (Collapsible) -->
303
- <div class="border-t border-base-200 dark:border-base-700"
304
- x-show="docsExpanded"
305
- x-collapse>
306
- <div class="p-6 bg-base-50/30 dark:bg-base-900/30">
307
- {% if documentation_content %}
308
- <!-- Rendered Markdown Content with Collapsible Sections -->
309
- <div class="documentation-content" x-data="documentationCollapse()">
310
- {{ documentation_content|safe }}
311
- </div>
312
- {% else %}
313
- <!-- Fallback: Basic documentation -->
314
- <div class="documentation-content">
315
- <h2>Django Management Commands</h2>
316
- <p>Django management commands provide a command-line interface for administrative tasks.</p>
317
-
318
- <h3>Common Commands</h3>
319
- <ul>
320
- <li><code>migrate</code> - Apply database migrations</li>
321
- <li><code>makemigrations</code> - Create new migrations</li>
322
- <li><code>runserver</code> - Start development server</li>
323
- <li><code>createsuperuser</code> - Create admin user</li>
324
- <li><code>collectstatic</code> - Collect static files</li>
325
- </ul>
326
-
327
- <h3>Getting Help</h3>
328
- <p>To get help for any command, use:</p>
329
- <pre><code>python manage.py help &lt;command_name&gt;</code></pre>
330
-
331
- <h3>Custom Commands</h3>
332
- <p>You can create custom management commands by adding them to <code>management/commands/</code> directory in your Django app.</p>
333
- </div>
334
- {% endif %}
335
- </div>
336
- </div>
337
- </div>
338
- </div>
339
-
340
- <!-- Documentation Collapse Script -->
341
- <script>
342
- function documentationCollapse() {
343
- return {
344
- sections: {},
345
- init() {
346
- // Find all h2 elements and make them collapsible
347
- this.$nextTick(() => {
348
- const h2Elements = this.$el.querySelectorAll('h2');
349
- h2Elements.forEach((h2, index) => {
350
- const sectionId = `section-${index}`;
351
- this.sections[sectionId] = false; // collapsed by default
352
-
353
- // Wrap h2 in clickable div
354
- const wrapper = document.createElement('div');
355
- wrapper.className = 'doc-section-header';
356
- wrapper.setAttribute('x-on:click', `sections['${sectionId}'] = !sections['${sectionId}']`);
357
-
358
- const icon = document.createElement('span');
359
- icon.className = 'material-icons doc-section-icon';
360
- icon.setAttribute('x-text', `sections['${sectionId}'] ? 'expand_less' : 'expand_more'`);
361
-
362
- h2.parentNode.insertBefore(wrapper, h2);
363
- wrapper.appendChild(icon);
364
- wrapper.appendChild(h2);
365
-
366
- // Wrap content until next h2
367
- const contentWrapper = document.createElement('div');
368
- contentWrapper.className = 'doc-section-content';
369
- contentWrapper.setAttribute('x-show', `sections['${sectionId}']`);
370
- contentWrapper.setAttribute('x-collapse', '');
371
-
372
- let nextElement = wrapper.nextElementSibling;
373
- const elementsToMove = [];
374
-
375
- while (nextElement && nextElement.tagName !== 'H2') {
376
- elementsToMove.push(nextElement);
377
- nextElement = nextElement.nextElementSibling;
378
- }
379
-
380
- wrapper.parentNode.insertBefore(contentWrapper, wrapper.nextElementSibling);
381
- elementsToMove.forEach(el => contentWrapper.appendChild(el));
382
- });
383
- });
384
- }
385
- };
386
- }
387
- </script>
388
-
389
- <!-- Documentation Styles -->
390
- <style>
391
- .documentation-content {
392
- color: #374151;
393
- line-height: 1.75;
394
- }
395
- html.dark .documentation-content {
396
- color: #d1d5db;
397
- }
398
- .documentation-content h1 {
399
- font-size: 2em;
400
- font-weight: 700;
401
- margin-top: 1.5em;
402
- margin-bottom: 0.75em;
403
- color: #111827;
404
- }
405
- html.dark .documentation-content h1 {
406
- color: #f9fafb;
407
- }
408
- .doc-section-header {
409
- display: flex;
410
- align-items: center;
411
- cursor: pointer;
412
- padding: 0.75em 0;
413
- margin-top: 1.25em;
414
- border-bottom: 1px solid #e5e7eb;
415
- transition: all 0.2s ease;
416
- }
417
- .doc-section-header:hover {
418
- background-color: rgba(0, 0, 0, 0.02);
419
- padding-left: 0.5em;
420
- margin-left: -0.5em;
421
- padding-right: 0.5em;
422
- margin-right: -0.5em;
423
- border-radius: 0.5em;
424
- }
425
- html.dark .doc-section-header {
426
- border-bottom-color: #374151;
427
- }
428
- html.dark .doc-section-header:hover {
429
- background-color: rgba(255, 255, 255, 0.05);
430
- }
431
- .doc-section-icon {
432
- color: #6b7280;
433
- font-size: 1.25em;
434
- margin-right: 0.5em;
435
- transition: transform 0.2s ease;
436
- }
437
- html.dark .doc-section-icon {
438
- color: #9ca3af;
439
- }
440
- .doc-section-header h2 {
441
- font-size: 1.5em;
442
- font-weight: 600;
443
- margin: 0;
444
- color: #1f2937;
445
- border: none;
446
- padding: 0;
447
- }
448
- html.dark .doc-section-header h2 {
449
- color: #e5e7eb;
450
- }
451
- .doc-section-content {
452
- padding-left: 2.25em;
453
- margin-bottom: 1em;
454
- }
455
- .documentation-content h3 {
456
- font-size: 1.25em;
457
- font-weight: 600;
458
- margin-top: 1em;
459
- margin-bottom: 0.5em;
460
- color: #374151;
461
- }
462
- html.dark .documentation-content h3 {
463
- color: #d1d5db;
464
- }
465
- .documentation-content h4 {
466
- font-size: 1.1em;
467
- font-weight: 600;
468
- margin-top: 0.875em;
469
- margin-bottom: 0.5em;
470
- color: #4b5563;
471
- }
472
- html.dark .documentation-content h4 {
473
- color: #9ca3af;
474
- }
475
- .documentation-content p {
476
- margin-bottom: 1em;
477
- }
478
- .documentation-content ul, .documentation-content ol {
479
- margin-bottom: 1em;
480
- padding-left: 1.5em;
481
- }
482
- .documentation-content li {
483
- margin-bottom: 0.5em;
484
- }
485
- .documentation-content code {
486
- background-color: #f3f4f6;
487
- color: #dc2626;
488
- padding: 0.125em 0.375em;
489
- border-radius: 0.25em;
490
- font-family: 'Courier New', monospace;
491
- font-size: 0.875em;
492
- }
493
- html.dark .documentation-content code {
494
- background-color: #1f2937;
495
- color: #f87171;
496
- }
497
- .documentation-content pre {
498
- background-color: #1f2937;
499
- color: #e5e7eb;
500
- padding: 1em;
501
- border-radius: 0.5em;
502
- overflow-x: auto;
503
- margin-bottom: 1em;
504
- }
505
- html.dark .documentation-content pre {
506
- background-color: #111827;
507
- }
508
- .documentation-content pre code {
509
- background-color: transparent;
510
- color: #10b981;
511
- padding: 0;
512
- }
513
- .documentation-content a {
514
- color: #2563eb;
515
- text-decoration: underline;
516
- }
517
- html.dark .documentation-content a {
518
- color: #60a5fa;
519
- }
520
- .documentation-content strong {
521
- font-weight: 600;
522
- color: #111827;
523
- }
524
- html.dark .documentation-content strong {
525
- color: #f9fafb;
526
- }
527
- .documentation-content table {
528
- width: 100%;
529
- border-collapse: collapse;
530
- margin-bottom: 1em;
531
- }
532
- .documentation-content th, .documentation-content td {
533
- border: 1px solid #e5e7eb;
534
- padding: 0.5em;
535
- text-align: left;
536
- }
537
- html.dark .documentation-content th, html.dark .documentation-content td {
538
- border-color: #374151;
539
- }
540
- .documentation-content th {
541
- background-color: #f3f4f6;
542
- font-weight: 600;
543
- }
544
- html.dark .documentation-content th {
545
- background-color: #1f2937;
546
- }
547
- </style>
548
- </div>
549
-