django-whiteneuron 0.2.48.2__tar.gz → 0.2.48.5__tar.gz

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.
Files changed (184) hide show
  1. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/PKG-INFO +14 -3
  2. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/README.md +13 -2
  3. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/django_whiteneuron.egg-info/PKG-INFO +14 -3
  4. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/pyproject.toml +1 -1
  5. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/admin.py +1 -0
  6. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/modeladmin.py +10 -2
  7. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/settings.py +2 -2
  8. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/utils.py +10 -2
  9. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/feedbacks/admin.py +1 -0
  10. django_whiteneuron-0.2.48.5/whiteneuron/locale/vi/LC_MESSAGES/django.mo +0 -0
  11. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/locale/vi/LC_MESSAGES/django.po +67 -30
  12. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/notification/admin.py +92 -4
  13. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/notification/models.py +11 -10
  14. django_whiteneuron-0.2.48.5/whiteneuron/static/base/css/styles.css +2 -0
  15. django_whiteneuron-0.2.48.2/whiteneuron/locale/vi/LC_MESSAGES/django.mo +0 -0
  16. django_whiteneuron-0.2.48.2/whiteneuron/static/base/css/styles.css +0 -2
  17. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/LICENSE +0 -0
  18. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/django_whiteneuron.egg-info/SOURCES.txt +0 -0
  19. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/django_whiteneuron.egg-info/dependency_links.txt +0 -0
  20. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/django_whiteneuron.egg-info/requires.txt +0 -0
  21. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/django_whiteneuron.egg-info/top_level.txt +0 -0
  22. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/setup.cfg +0 -0
  23. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/__init__.py +0 -0
  24. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/__init__.py +0 -0
  25. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/apps.py +0 -0
  26. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/asgi.py +0 -0
  27. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/ckeditor.py +0 -0
  28. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/filters.py +0 -0
  29. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/forms.py +0 -0
  30. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/management/__init__.py +0 -0
  31. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/management/commands/__init__.py +0 -0
  32. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/management/commands/init_admin.py +0 -0
  33. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/management/commands/init_groupuser.py +0 -0
  34. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/management/commands/init_guest.py +0 -0
  35. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/middleware.py +0 -0
  36. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/migrations/0001_initial.py +0 -0
  37. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/migrations/0002_imagemodel_userprofile_user_avatar_user_biography_and_more.py +0 -0
  38. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/migrations/0003_notification_obj_link.py +0 -0
  39. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/migrations/0004_delete_notification.py +0 -0
  40. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/migrations/0005_user_show_softdelete.py +0 -0
  41. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/migrations/0006_user_is_bot.py +0 -0
  42. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/migrations/0007_app.py +0 -0
  43. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/migrations/0008_app_created_at_app_created_by_app_deleted_at_and_more.py +0 -0
  44. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/migrations/0009_alter_app_table.py +0 -0
  45. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/migrations/0010_app_category.py +0 -0
  46. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/migrations/0011_alter_app_options.py +0 -0
  47. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/migrations/0012_app_permission.py +0 -0
  48. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/migrations/0013_app_thumbnail_url.py +0 -0
  49. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/migrations/0014_alter_app_created_at_alter_app_updated_at_and_more.py +0 -0
  50. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/migrations/0015_ipblacklist.py +0 -0
  51. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/migrations/0016_uablacklist.py +0 -0
  52. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/migrations/0017_alter_uablacklist_pattern.py +0 -0
  53. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/migrations/__init__.py +0 -0
  54. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/models.py +0 -0
  55. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/resources.py +0 -0
  56. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/sites.py +0 -0
  57. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/tasks.py +0 -0
  58. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/templatetags/__init__.py +0 -0
  59. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/templatetags/unfold_list_custom.py +0 -0
  60. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/templatetags/wn_filters.py +0 -0
  61. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/tests.py +0 -0
  62. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/thread_local.py +0 -0
  63. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/urls.py +0 -0
  64. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/views.py +0 -0
  65. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/base/widgets.py +0 -0
  66. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/contrib/__init__.py +0 -0
  67. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/contrib/wn_import_export/__init__.py +0 -0
  68. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/contrib/wn_import_export/admin.py +0 -0
  69. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/contrib/wn_import_export/constants.py +0 -0
  70. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/contrib/wn_import_export/mixins.py +0 -0
  71. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/contrib/wn_import_export/tasks.py +0 -0
  72. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/contrib/wn_import_export/utils.py +0 -0
  73. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/contrib/wn_modeltranslation/__init__.py +0 -0
  74. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/contrib/wn_modeltranslation/admin.py +0 -0
  75. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/contrib/wn_modeltranslation/utils.py +0 -0
  76. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/dashboard/__init__.py +0 -0
  77. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/dashboard/admin.py +0 -0
  78. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/dashboard/apps.py +0 -0
  79. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/dashboard/migrations/__init__.py +0 -0
  80. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/dashboard/models.py +0 -0
  81. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/dashboard/tests.py +0 -0
  82. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/dashboard/views.py +0 -0
  83. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/feedbacks/__init__.py +0 -0
  84. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/feedbacks/apps.py +0 -0
  85. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/feedbacks/migrations/0001_initial.py +0 -0
  86. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/feedbacks/migrations/0002_feedbackdata_created_by_feedbackdata_deleted_at_and_more.py +0 -0
  87. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/feedbacks/migrations/0003_feedbackdata_note.py +0 -0
  88. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/feedbacks/migrations/0004_alter_feedbackdata_object_id.py +0 -0
  89. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/feedbacks/migrations/0005_feedbackdata_field.py +0 -0
  90. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/feedbacks/migrations/0006_alter_feedbackdata_created_at_and_more.py +0 -0
  91. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/feedbacks/migrations/__init__.py +0 -0
  92. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/feedbacks/models.py +0 -0
  93. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/feedbacks/tests.py +0 -0
  94. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/feedbacks/urls.py +0 -0
  95. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/feedbacks/utils.py +0 -0
  96. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/feedbacks/views.py +0 -0
  97. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/file_management/__init__.py +0 -0
  98. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/file_management/admin.py +0 -0
  99. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/file_management/apps.py +0 -0
  100. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/file_management/migrations/0001_initial.py +0 -0
  101. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/file_management/migrations/0002_alter_excelfile_options_alter_pdffile_options_and_more.py +0 -0
  102. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/file_management/migrations/0003_alter_excelfile_created_at_and_more.py +0 -0
  103. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/file_management/migrations/__init__.py +0 -0
  104. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/file_management/models.py +0 -0
  105. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/file_management/tests.py +0 -0
  106. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/file_management/utils.py +0 -0
  107. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/file_management/views.py +0 -0
  108. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/manage.py +0 -0
  109. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/notification/__init__.py +0 -0
  110. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/notification/apps.py +0 -0
  111. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/notification/consumers.py +0 -0
  112. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/notification/management/__init__.py +0 -0
  113. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/notification/management/commands/__init__.py +0 -0
  114. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/notification/management/commands/call_demo_noti.py +0 -0
  115. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/notification/migrations/0001_initial.py +0 -0
  116. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/notification/migrations/0002_alter_notificationconfig_event_type.py +0 -0
  117. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/notification/migrations/0003_notification.py +0 -0
  118. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/notification/migrations/0004_alter_notification_flag.py +0 -0
  119. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/notification/migrations/0005_notification_keywords.py +0 -0
  120. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/notification/migrations/0006_remove_notification_keywords.py +0 -0
  121. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/notification/migrations/0007_notification_changed_data.py +0 -0
  122. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/notification/migrations/0008_alter_notification_changed_data.py +0 -0
  123. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/notification/migrations/0009_notification_action_by_alter_notification_user.py +0 -0
  124. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/notification/migrations/0010_alter_notification_user.py +0 -0
  125. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/notification/migrations/0011_alter_notification_user.py +0 -0
  126. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/notification/migrations/0012_alter_notification_action_and_more.py +0 -0
  127. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/notification/migrations/__init__.py +0 -0
  128. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/notification/routing.py +0 -0
  129. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/notification/tests.py +0 -0
  130. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/notification/utils.py +0 -0
  131. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/notification/views.py +0 -0
  132. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/static/base/css/btn-styles.css +0 -0
  133. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/static/base/css/ckeditor5.css +0 -0
  134. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/static/base/css/loading.css +0 -0
  135. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/static/base/forms/css/html-editor.css +0 -0
  136. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/static/base/forms/js/format.html.js +0 -0
  137. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/static/base/forms/js/trix.config.js +0 -0
  138. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/static/base/images/delete.svg +0 -0
  139. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/static/base/images/edit.svg +0 -0
  140. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/static/base/images/icon-viewlink.svg +0 -0
  141. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/static/base/images/loading.gif +0 -0
  142. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/static/base/images/login-bg.jpg +0 -0
  143. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/static/base/images/login_bg.jpg +0 -0
  144. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/static/base/images/logo/WhiteNeuron.png +0 -0
  145. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/static/base/js/chart.min.js +0 -0
  146. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/static/base/js/d3.v7.min.js +0 -0
  147. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/static/base/js/loading.js +0 -0
  148. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/static/base/js/whiteneuron.js +0 -0
  149. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/synchronization/__init__.py +0 -0
  150. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/synchronization/admin.py +0 -0
  151. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/synchronization/apps.py +0 -0
  152. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/synchronization/migrations/__init__.py +0 -0
  153. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/synchronization/models.py +0 -0
  154. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/synchronization/tests.py +0 -0
  155. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/synchronization/views.py +0 -0
  156. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/templates/400.html +0 -0
  157. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/templates/403.html +0 -0
  158. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/templates/404.html +0 -0
  159. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/templates/429.html +0 -0
  160. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/templates/500.html +0 -0
  161. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/templates/admin/auth/user/add_form.html +0 -0
  162. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/templates/admin/base/app_change_list.html +0 -0
  163. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/templates/admin/base/image_change_form.html +0 -0
  164. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/templates/admin/base/userprofile_change_form.html +0 -0
  165. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/templates/admin/base.html +0 -0
  166. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/templates/admin/change_list.html +0 -0
  167. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/templates/admin/feedbacks/feedback_change_form.html +0 -0
  168. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/templates/admin/grid_view_results.html +0 -0
  169. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/templates/admin/header.html +0 -0
  170. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/templates/admin/index.html +0 -0
  171. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/templates/admin/login.html +0 -0
  172. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/templates/admin/login_after.html +0 -0
  173. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/templates/admin/search_form.html +0 -0
  174. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/templates/admin/submit_line.html +0 -0
  175. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/templates/admin/wn_change_form.html +0 -0
  176. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/templates/admin/wn_history_panel.html +0 -0
  177. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/templates/base/forms/helpers/toolbar.html +0 -0
  178. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/templates/base/forms/wysiwyg.html +0 -0
  179. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/templates/base.html +0 -0
  180. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/templates/unfold/helpers/account_links.html +0 -0
  181. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/templates/unfold/helpers/app_list_badge.html +0 -0
  182. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/templates/unfold/helpers/field_password.html +0 -0
  183. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/templates/unfold/helpers/navigation_user.html +0 -0
  184. {django_whiteneuron-0.2.48.2 → django_whiteneuron-0.2.48.5}/whiteneuron/templates/unfold/helpers/pagination.html +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: django-whiteneuron
3
- Version: 0.2.48.2
3
+ Version: 0.2.48.5
4
4
  Summary: A modern Django Admin extension with enhanced UI/UX, dashboard, feedback, file management, rate limiting, IP blacklisting, and advanced admin integrations built on django-unfold.
5
5
  Author-email: White Neuron <anhnt@whiteneuron.ai>
6
6
  License: MIT License
@@ -96,7 +96,7 @@ A modern Django Admin extension focused on UI/UX, dashboard, feedback, file mana
96
96
 
97
97
  ## Current Version
98
98
 
99
- - 0.2.48
99
+ - 0.2.48.3
100
100
 
101
101
  ## Compatibility
102
102
 
@@ -107,7 +107,18 @@ A modern Django Admin extension focused on UI/UX, dashboard, feedback, file mana
107
107
 
108
108
  ## Changelog
109
109
 
110
- ### v0.2.48.2 (2026-04-10) — latest
110
+ ### v0.2.48.4 (2026-04-11) — latest
111
+ **Security: Nâng cấp cbor2 5.9.0 và ujson 5.12.0**
112
+ - **Security**: `cbor2` nâng từ `v5.8.0` lên `v5.9.0` — bản vá lỗi và cải thiện encoding/decoding CBOR.
113
+ - **Security**: `ujson` nâng từ `v5.11.0` lên `v5.12.0` — bản vá bảo mật và cải thiện hiệu suất JSON serialization.
114
+
115
+ ### v0.2.48.3 (2026-04-10)
116
+ **Improve: Notification list — DaisyUI badge display, search field verbose names**
117
+ - **Improved**: `NotificationAdmin.display_title` rewritten — renders `[Model][#ID][Object name][Action] by [Alias][@username]` using `ui-badge ui-badge-xs` badges with correct color mapping (`ui-badge-success/info/error/warning`).
118
+ - **Fixed**: `obj_link` parsing regex updated to handle paths without `/admin/` prefix — e.g. `/techniques/technique/58316/change/`.
119
+ - **Fixed**: `get_verbose_name_field` now traverses `__`-separated lookup paths (e.g. `user__username`) to resolve proper verbose names for all search fields in `search_help_text`.
120
+
121
+ ### v0.2.48.2 (2026-04-10)
111
122
  **Security: Nâng cấp django 5.2.13 và thêm pyOpenSSL 26.0.0**
112
123
  - **Security**: `django` lower bound nâng từ `>=5.2.12` lên `>=5.2.13` — bản vá bảo mật mới nhất của Django.
113
124
  - **Security**: `pyopenssl==26.0.0` thêm vào explicit dependencies — đảm bảo phiên bản mới nhất của pyOpenSSL được sử dụng, vá các lỗ hổng tiềm ẩn trong TLS/SSL handling.
@@ -11,7 +11,7 @@ A modern Django Admin extension focused on UI/UX, dashboard, feedback, file mana
11
11
 
12
12
  ## Current Version
13
13
 
14
- - 0.2.48
14
+ - 0.2.48.3
15
15
 
16
16
  ## Compatibility
17
17
 
@@ -22,7 +22,18 @@ A modern Django Admin extension focused on UI/UX, dashboard, feedback, file mana
22
22
 
23
23
  ## Changelog
24
24
 
25
- ### v0.2.48.2 (2026-04-10) — latest
25
+ ### v0.2.48.4 (2026-04-11) — latest
26
+ **Security: Nâng cấp cbor2 5.9.0 và ujson 5.12.0**
27
+ - **Security**: `cbor2` nâng từ `v5.8.0` lên `v5.9.0` — bản vá lỗi và cải thiện encoding/decoding CBOR.
28
+ - **Security**: `ujson` nâng từ `v5.11.0` lên `v5.12.0` — bản vá bảo mật và cải thiện hiệu suất JSON serialization.
29
+
30
+ ### v0.2.48.3 (2026-04-10)
31
+ **Improve: Notification list — DaisyUI badge display, search field verbose names**
32
+ - **Improved**: `NotificationAdmin.display_title` rewritten — renders `[Model][#ID][Object name][Action] by [Alias][@username]` using `ui-badge ui-badge-xs` badges with correct color mapping (`ui-badge-success/info/error/warning`).
33
+ - **Fixed**: `obj_link` parsing regex updated to handle paths without `/admin/` prefix — e.g. `/techniques/technique/58316/change/`.
34
+ - **Fixed**: `get_verbose_name_field` now traverses `__`-separated lookup paths (e.g. `user__username`) to resolve proper verbose names for all search fields in `search_help_text`.
35
+
36
+ ### v0.2.48.2 (2026-04-10)
26
37
  **Security: Nâng cấp django 5.2.13 và thêm pyOpenSSL 26.0.0**
27
38
  - **Security**: `django` lower bound nâng từ `>=5.2.12` lên `>=5.2.13` — bản vá bảo mật mới nhất của Django.
28
39
  - **Security**: `pyopenssl==26.0.0` thêm vào explicit dependencies — đảm bảo phiên bản mới nhất của pyOpenSSL được sử dụng, vá các lỗ hổng tiềm ẩn trong TLS/SSL handling.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: django-whiteneuron
3
- Version: 0.2.48.2
3
+ Version: 0.2.48.5
4
4
  Summary: A modern Django Admin extension with enhanced UI/UX, dashboard, feedback, file management, rate limiting, IP blacklisting, and advanced admin integrations built on django-unfold.
5
5
  Author-email: White Neuron <anhnt@whiteneuron.ai>
6
6
  License: MIT License
@@ -96,7 +96,7 @@ A modern Django Admin extension focused on UI/UX, dashboard, feedback, file mana
96
96
 
97
97
  ## Current Version
98
98
 
99
- - 0.2.48
99
+ - 0.2.48.3
100
100
 
101
101
  ## Compatibility
102
102
 
@@ -107,7 +107,18 @@ A modern Django Admin extension focused on UI/UX, dashboard, feedback, file mana
107
107
 
108
108
  ## Changelog
109
109
 
110
- ### v0.2.48.2 (2026-04-10) — latest
110
+ ### v0.2.48.4 (2026-04-11) — latest
111
+ **Security: Nâng cấp cbor2 5.9.0 và ujson 5.12.0**
112
+ - **Security**: `cbor2` nâng từ `v5.8.0` lên `v5.9.0` — bản vá lỗi và cải thiện encoding/decoding CBOR.
113
+ - **Security**: `ujson` nâng từ `v5.11.0` lên `v5.12.0` — bản vá bảo mật và cải thiện hiệu suất JSON serialization.
114
+
115
+ ### v0.2.48.3 (2026-04-10)
116
+ **Improve: Notification list — DaisyUI badge display, search field verbose names**
117
+ - **Improved**: `NotificationAdmin.display_title` rewritten — renders `[Model][#ID][Object name][Action] by [Alias][@username]` using `ui-badge ui-badge-xs` badges with correct color mapping (`ui-badge-success/info/error/warning`).
118
+ - **Fixed**: `obj_link` parsing regex updated to handle paths without `/admin/` prefix — e.g. `/techniques/technique/58316/change/`.
119
+ - **Fixed**: `get_verbose_name_field` now traverses `__`-separated lookup paths (e.g. `user__username`) to resolve proper verbose names for all search fields in `search_help_text`.
120
+
121
+ ### v0.2.48.2 (2026-04-10)
111
122
  **Security: Nâng cấp django 5.2.13 và thêm pyOpenSSL 26.0.0**
112
123
  - **Security**: `django` lower bound nâng từ `>=5.2.12` lên `>=5.2.13` — bản vá bảo mật mới nhất của Django.
113
124
  - **Security**: `pyopenssl==26.0.0` thêm vào explicit dependencies — đảm bảo phiên bản mới nhất của pyOpenSSL được sử dụng, vá các lỗ hổng tiềm ẩn trong TLS/SSL handling.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "django-whiteneuron"
3
- version = "0.2.48.2"
3
+ version = "0.2.48.5"
4
4
  description = "A modern Django Admin extension with enhanced UI/UX, dashboard, feedback, file management, rate limiting, IP blacklisting, and advanced admin integrations built on django-unfold."
5
5
  authors = [
6
6
  {name = "White Neuron", email = "anhnt@whiteneuron.ai"}
@@ -346,6 +346,7 @@ class UserActivityAdmin(ModelAdmin):
346
346
  """
347
347
 
348
348
  compressed_fields = True
349
+ using_grid_view = False
349
350
 
350
351
  list_display = [
351
352
  "user",
@@ -44,8 +44,16 @@ from unfold.paginator import InfinitePaginator
44
44
 
45
45
  def get_verbose_name_field(model, field):
46
46
  try:
47
- return str(model._meta.get_field(field).verbose_name)
48
- except:
47
+ parts = field.split('__')
48
+ current_model = model
49
+ labels = []
50
+ for part in parts:
51
+ f = current_model._meta.get_field(part)
52
+ labels.append(str(f.verbose_name))
53
+ if hasattr(f, 'related_model') and f.related_model:
54
+ current_model = f.related_model
55
+ return ' / '.join(labels)
56
+ except Exception:
49
57
  return field
50
58
 
51
59
  class ModelAdmin(UnfoldAdmin):
@@ -556,14 +556,14 @@ UNFOLD = {
556
556
  # "title": _("Dashboard"),
557
557
  # "icon": "dashboard",
558
558
  # "link": reverse_lazy("admin:index"),
559
- # "permission": "whiteneuron.base.utils.prmission_viewer_callback",
559
+ # "permission": "whiteneuron.base.utils.permission_viewer_callback",
560
560
  # },
561
561
  {
562
562
  "title": _("Dashboard"),
563
563
  "icon": "dashboard",
564
564
  "link": reverse_lazy("admin:base_app_changelist"),
565
565
  "badge": "whiteneuron.base.utils.app_badge_callback",
566
- "permission": "whiteneuron.base.utils.prmission_viewer_callback",
566
+ "permission": "whiteneuron.base.utils.permission_viewer_callback",
567
567
  },
568
568
  {
569
569
  "title": _("Notifications"),
@@ -83,6 +83,14 @@ def app_badge_callback(request):
83
83
  except Exception:
84
84
  return 0
85
85
 
86
+ def is_guest_user(user):
87
+ if not user or not user.is_authenticated:
88
+ return True
89
+ if user.username.lower() == "guest":
90
+ return True
91
+ return user.groups.filter(name__in=["Khách thăm", "Guest", "guest"]).exists()
92
+
93
+
86
94
  def permission_callback(request):
87
95
  return False
88
96
 
@@ -95,9 +103,9 @@ def permission_admin_callback(request):
95
103
  return request.user.groups.filter(name='Quản trị viên').exists()
96
104
 
97
105
  def permission_non_guest_callback(request):
98
- return not request.user.groups.filter(name='Khách thăm').exists()
106
+ return not is_guest_user(request.user)
99
107
 
100
- def prmission_viewer_callback(request):
108
+ def permission_viewer_callback(request):
101
109
  return True
102
110
 
103
111
 
@@ -13,6 +13,7 @@ from whiteneuron.notification.models import Notification
13
13
 
14
14
  @admin.register(FeedbackData, site=base_admin_site)
15
15
  class FeedbackDataAdmin(ModelAdmin):
16
+ using_grid_view = False
16
17
  date_hierarchy = 'created_at'
17
18
  change_form_template = 'admin/feedbacks/feedback_change_form.html'
18
19
  list_display = (
@@ -8,7 +8,7 @@ msgid ""
8
8
  msgstr ""
9
9
  "Project-Id-Version: PACKAGE VERSION\n"
10
10
  "Report-Msgid-Bugs-To: \n"
11
- "POT-Creation-Date: 2026-04-06 10:48+0700\n"
11
+ "POT-Creation-Date: 2026-04-10 15:12+0700\n"
12
12
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13
13
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
14
  "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -112,7 +112,7 @@ msgstr "Mục tiêu"
112
112
  msgid "Block settings"
113
113
  msgstr "Cài đặt chặn"
114
114
 
115
- #: base/admin.py:442 base/admin.py:489 base/modeladmin.py:350
115
+ #: base/admin.py:442 base/admin.py:489 base/modeladmin.py:351
116
116
  #: file_management/admin.py:21
117
117
  msgid "Meta"
118
118
  msgstr "Meta"
@@ -161,7 +161,7 @@ msgstr "Thông tin hình ảnh"
161
161
  msgid "Mail info"
162
162
  msgstr "Thông tin thư"
163
163
 
164
- #: base/admin.py:623 base/models.py:821 notification/admin.py:146
164
+ #: base/admin.py:623 base/models.py:821 notification/admin.py:148
165
165
  msgid "Content"
166
166
  msgstr "Nội dung"
167
167
 
@@ -188,48 +188,48 @@ msgstr ""
188
188
  "Cơ sở dữ liệu đang hoạt động ở chế độ chỉ đọc. Không thể lưu bất kỳ dữ liệu "
189
189
  "nào."
190
190
 
191
- #: base/modeladmin.py:90
191
+ #: base/modeladmin.py:91
192
192
  #, python-brace-format
193
193
  msgid "Search by {fields}"
194
194
  msgstr "Tìm kiếm theo {fields}"
195
195
 
196
- #: base/modeladmin.py:151 base/modeladmin.py:152 base/modeladmin.py:201
197
- #: base/modeladmin.py:202
196
+ #: base/modeladmin.py:152 base/modeladmin.py:153 base/modeladmin.py:202
197
+ #: base/modeladmin.py:203
198
198
  #, python-format
199
199
  msgid "%(name)s \"%(obj)s\" has been soft-deleted by user \"%(user)s\""
200
200
  msgstr "%(name)s \"%(obj)s\" đã được xóa mềm bởi người dùng \"%(user)s\""
201
201
 
202
- #: base/modeladmin.py:161
202
+ #: base/modeladmin.py:162
203
203
  msgid "Delete selected records"
204
204
  msgstr "Xóa các bản ghi đã chọn"
205
205
 
206
- #: base/modeladmin.py:165 base/modeladmin.py:166
206
+ #: base/modeladmin.py:166 base/modeladmin.py:167
207
207
  #, python-format
208
208
  msgid "%(name)s \"%(obj)s\" has been hard-deleted by user \"%(user)s\""
209
209
  msgstr "%(name)s \"%(obj)s\" đã được xóa cứng bởi người dùng \"%(user)s\""
210
210
 
211
- #: base/modeladmin.py:178
211
+ #: base/modeladmin.py:179
212
212
  msgid "Hard delete selected records"
213
213
  msgstr "Xóa cứng các bản ghi đã chọn"
214
214
 
215
- #: base/modeladmin.py:182 base/modeladmin.py:183
215
+ #: base/modeladmin.py:183 base/modeladmin.py:184
216
216
  #, python-format
217
217
  msgid "%(name)s \"%(obj)s\" has been restored by user \"%(user)s\""
218
218
  msgstr "%(name)s \"%(obj)s\" đã được khôi phục bởi người dùng \"%(user)s\""
219
219
 
220
- #: base/modeladmin.py:192
220
+ #: base/modeladmin.py:193
221
221
  msgid "Restore selected records"
222
222
  msgstr "Khôi phục các bản ghi đã chọn"
223
223
 
224
- #: base/modeladmin.py:370
224
+ #: base/modeladmin.py:371
225
225
  msgid "Edit"
226
226
  msgstr "Sửa"
227
227
 
228
- #: base/modeladmin.py:373
228
+ #: base/modeladmin.py:374
229
229
  msgid "View"
230
230
  msgstr "Xem"
231
231
 
232
- #: base/modeladmin.py:378 templates/admin/wn_history_panel.html:74
232
+ #: base/modeladmin.py:379 templates/admin/wn_history_panel.html:74
233
233
  msgid "Delete"
234
234
  msgstr "Xóa"
235
235
 
@@ -943,39 +943,43 @@ msgstr "Tệp Excel"
943
943
  msgid "PDF File"
944
944
  msgstr "Tệp PDF"
945
945
 
946
- #: notification/admin.py:34
946
+ #: notification/admin.py:36
947
947
  msgid "Notification Recipients"
948
948
  msgstr "Người nhận thông báo"
949
949
 
950
- #: notification/admin.py:70
950
+ #: notification/admin.py:72
951
951
  msgid "Notification information"
952
952
  msgstr "Thông tin thông báo"
953
953
 
954
- #: notification/admin.py:90
954
+ #: notification/admin.py:92
955
955
  msgid "View Linked Object"
956
956
  msgstr "Xem đối tượng được liên kết"
957
957
 
958
- #: notification/admin.py:97
958
+ #: notification/admin.py:99
959
959
  msgid "No object link available for this notification."
960
960
  msgstr "Không có liên kết đối tượng nào có sẵn cho thông báo này."
961
961
 
962
- #: notification/admin.py:150 synchronization/models.py:14
962
+ #: notification/admin.py:152 synchronization/models.py:14
963
963
  msgid "Action"
964
964
  msgstr "Hành động"
965
965
 
966
- #: notification/admin.py:154
966
+ #: notification/admin.py:156
967
967
  msgid "Flag"
968
968
  msgstr "Cờ"
969
969
 
970
- #: notification/admin.py:160
970
+ #: notification/admin.py:231
971
+ msgid "by"
972
+ msgstr "bởi"
973
+
974
+ #: notification/admin.py:243
971
975
  msgid "Title"
972
976
  msgstr "Tiêu đề"
973
977
 
974
- #: notification/admin.py:203
978
+ #: notification/admin.py:286
975
979
  msgid "No changes"
976
980
  msgstr "Không có thay đổi nào"
977
981
 
978
- #: notification/admin.py:204 notification/models.py:71
982
+ #: notification/admin.py:287 notification/models.py:71
979
983
  msgid "Changed Data"
980
984
  msgstr "Thay đổi dữ liệu"
981
985
 
@@ -1050,27 +1054,63 @@ msgstr "Đối tượng liên kết"
1050
1054
  msgid "Read"
1051
1055
  msgstr "Đã đọc"
1052
1056
 
1057
+ #: notification/models.py:73
1058
+ msgid "info"
1059
+ msgstr "thông tin"
1060
+
1061
+ #: notification/models.py:74
1062
+ msgid "success"
1063
+ msgstr "thành công"
1064
+
1065
+ #: notification/models.py:75
1066
+ msgid "warning"
1067
+ msgstr "cảnh báo"
1068
+
1069
+ #: notification/models.py:76
1070
+ msgid "error"
1071
+ msgstr "lỗi"
1072
+
1053
1073
  #: notification/models.py:77
1074
+ msgid "danger"
1075
+ msgstr "nguy hiểm"
1076
+
1077
+ #: notification/models.py:78
1054
1078
  msgid "Notification Type"
1055
1079
  msgstr "Loại thông báo"
1056
1080
 
1081
+ #: notification/models.py:79
1082
+ msgid "update"
1083
+ msgstr "cập nhật"
1084
+
1085
+ #: notification/models.py:80
1086
+ msgid "create"
1087
+ msgstr "tạo"
1088
+
1057
1089
  #: notification/models.py:81
1090
+ msgid "restore"
1091
+ msgstr "khôi phục"
1092
+
1093
+ #: notification/models.py:82
1094
+ msgid "delete"
1095
+ msgstr "xóa"
1096
+
1097
+ #: notification/models.py:82
1058
1098
  msgid "Action Type"
1059
1099
  msgstr "Loại hành động"
1060
1100
 
1061
- #: notification/models.py:82
1101
+ #: notification/models.py:83
1062
1102
  msgid "Created At"
1063
1103
  msgstr "Đã tạo lúc"
1064
1104
 
1065
- #: notification/models.py:84
1105
+ #: notification/models.py:85
1066
1106
  msgid "Action By"
1067
1107
  msgstr "Hành động bởi"
1068
1108
 
1069
- #: notification/models.py:89
1109
+ #: notification/models.py:90
1070
1110
  msgid "notification"
1071
1111
  msgstr "thông báo"
1072
1112
 
1073
- #: notification/models.py:90
1113
+ #: notification/models.py:91
1074
1114
  msgid "notifications"
1075
1115
  msgstr "thông báo"
1076
1116
 
@@ -1372,9 +1412,6 @@ msgstr "Tiếp theo"
1372
1412
  #~ msgid "Feedback marked as resolved"
1373
1413
  #~ msgstr "Phản hồi đã được đánh dấu là đã giải quyết"
1374
1414
 
1375
- #~ msgid "App info"
1376
- #~ msgstr "Thông tin ứng dụng"
1377
-
1378
1415
  #~ msgid "This app is not active."
1379
1416
  #~ msgstr "Ứng dụng này không hoạt động."
1380
1417
 
@@ -1,7 +1,9 @@
1
1
  from django.contrib import admin
2
2
  import ast
3
3
  import json
4
+ import re
4
5
  from typing import Sequence
6
+ from django.contrib.contenttypes.models import ContentType
5
7
 
6
8
  from whiteneuron.base.admin import base_admin_site
7
9
  from whiteneuron.base.admin import ModelAdmin
@@ -45,9 +47,9 @@ class NotificationAdmin(ModelAdmin):
45
47
  list_display = [
46
48
  # "user",
47
49
  "display_title",
48
- "action_by",
49
- "display_action",
50
- "display_flag",
50
+ # "action_by",
51
+ # "display_action",
52
+ # "display_flag",
51
53
  "is_read",
52
54
  "created_at",
53
55
  ]
@@ -87,6 +89,8 @@ class NotificationAdmin(ModelAdmin):
87
89
 
88
90
  actions_detail = ["view_obj_link"]
89
91
 
92
+ using_grid_view= False
93
+
90
94
  @action(description=_("View Linked Object"),
91
95
  permissions= ["view_obj_link"],
92
96
  url_path="view-obj-link")
@@ -155,8 +159,92 @@ class NotificationAdmin(ModelAdmin):
155
159
  def display_flag(self, instance: Notification):
156
160
  return instance.flag
157
161
 
162
+ def get_components(self, instance: Notification):
163
+ app_label = None
164
+ model_verbose = None
165
+ object_id = None
166
+ obj_str = None
167
+ if instance.obj_link:
168
+ m = re.search(r'/([^/]+)/([^/]+)/(\d+)/change/', instance.obj_link)
169
+ if m:
170
+ app_label = m.group(1)
171
+ raw_model = m.group(2)
172
+ object_id = m.group(3)
173
+ try:
174
+ ct = ContentType.objects.get(app_label=app_label, model=raw_model)
175
+ mc = ct.model_class()
176
+ model_verbose = mc._meta.verbose_name.title()
177
+ try:
178
+ manager = getattr(mc, 'objects_all', mc.objects)
179
+ obj = manager.get(pk=int(object_id))
180
+ obj_str = str(obj)
181
+ except Exception:
182
+ obj_str = f"#{object_id}"
183
+ except Exception:
184
+ model_verbose = raw_model.replace('_', ' ').title()
185
+ obj_str = f"#{object_id}"
186
+ return app_label, model_verbose, object_id, obj_str
187
+
158
188
  def display_title(self, instance: Notification):
159
- return mark_safe(f"{instance.title}")
189
+ # Parse obj_link → extract app_label, model_name, object_id
190
+ app_label, model_verbose, object_id, obj_str = self.get_components(instance)
191
+
192
+ _action_cls = {
193
+ 'create': 'ui-badge-success',
194
+ 'update': 'ui-badge-info',
195
+ 'delete': 'ui-badge-error',
196
+ 'restore': 'ui-badge-warning',
197
+ }
198
+ action_cls = _action_cls.get(instance.action or '', '')
199
+ action_label = _(instance.action) if instance.action else '—'
200
+
201
+ parts = []
202
+
203
+ # [Model name]
204
+ if model_verbose:
205
+ parts.append(
206
+ f'<span class="ui-badge ui-badge-xs font-mono opacity-70">'
207
+ f'<strong>{model_verbose}</strong></span>'
208
+ )
209
+
210
+ # [#ID] — clickable link
211
+ if object_id:
212
+ if instance.obj_link:
213
+ parts.append(
214
+ f'<a href="{instance.obj_link}" class="ui-badge ui-badge-xs font-mono">'
215
+ f'#{object_id}</a>'
216
+ )
217
+ else:
218
+ parts.append(
219
+ f'<span class="ui-badge ui-badge-xs font-mono">#{object_id}</span>'
220
+ )
221
+
222
+ # [Object name]
223
+ if obj_str:
224
+ parts.append(f'<span class="text-sm font-semibold">{obj_str}</span>')
225
+
226
+ # [Action]
227
+ parts.append(
228
+ f'<span class="ui-badge ui-badge-xs {action_cls}">{action_label}</span>'
229
+ )
230
+
231
+ # by [Alias] [@username]
232
+ if instance.action_by:
233
+ ab = instance.action_by
234
+ alias = getattr(ab, 'full_name', None) or ''
235
+ username = ab.username
236
+ parts.append(f'<span class="text-xs opacity-50">{_("by")}</span>')
237
+ if alias and alias != username:
238
+ parts.append(
239
+ f'<span class="ui-badge ui-badge-xs">{alias}</span>'
240
+ f'<span class="ui-badge ui-badge-xs opacity-60">@{username}</span>'
241
+ )
242
+ else:
243
+ parts.append(f'<span class="ui-badge ui-badge-xs">@{username}</span>')
244
+
245
+ return mark_safe(
246
+ '<div class="flex flex-wrap items-center gap-1">' + ''.join(parts) + '</div>'
247
+ )
160
248
  display_title.short_description = _("Title")
161
249
 
162
250
  def display_changed_data(self, instance: Notification):
@@ -70,15 +70,16 @@ class Notification(models.Model):
70
70
  content = models.TextField()
71
71
  changed_data= models.TextField(null=True, blank=True, verbose_name=_("Changed Data"))
72
72
  is_read = models.BooleanField(default=False, verbose_name=_("Read"))
73
- flag = models.CharField(max_length=25, choices=[("info", "info"),
74
- ("success", "success"),
75
- ("warning", "warning"),
76
- ("error", "error"),
77
- ("danger", "danger")], verbose_name=_("Notification Type"))
78
- action = models.CharField(max_length=25, null=True, blank=True, choices=[("update", "update"),
79
- ("create", "create"),
80
- ('restore', 'restore'),
81
- ("delete", "delete")], verbose_name=_("Action Type"))
73
+ flag = models.CharField(max_length=25, choices=[("info", _("info")),
74
+ ("success", _("success")),
75
+ ("warning", _("warning")),
76
+ ("error", _("error")),
77
+ ("danger", _("danger"))
78
+ ], verbose_name=_("Notification Type"))
79
+ action = models.CharField(max_length=25, null=True, blank=True, choices=[("update", _("update")),
80
+ ("create", _("create")),
81
+ ('restore', _('restore')),
82
+ ("delete", _("delete"))], verbose_name=_("Action Type"))
82
83
  created_at = models.DateTimeField(auto_now_add=True, verbose_name=_("Created At"))
83
84
  action_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True,
84
85
  verbose_name=_("Action By"),
@@ -90,7 +91,7 @@ class Notification(models.Model):
90
91
  verbose_name_plural = _("notifications")
91
92
 
92
93
  def __str__(self):
93
- return f"[{self.flag}] {self.title}"
94
+ return f"{self.user.username} - {self.id} - {self.action} - {self.flag}"
94
95
 
95
96
  def mark_as_read(self):
96
97
  self.is_read = True