micro-users 1.2.0__py3-none-any.whl → 1.2.3__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 micro-users might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: micro-users
3
- Version: 1.2.0
3
+ Version: 1.2.3
4
4
  Summary: Arabic Django user management app with abstract user, permissions, and activity logging
5
5
  Home-page: https://github.com/debeski/micro-users
6
6
  Author: DeBeski
@@ -51,6 +51,7 @@ Requires-Dist: babel (>=2.1)
51
51
  - Custom AbstractUser model
52
52
  - User permissions system
53
53
  - Activity logging (login/logout, CRUD tracking)
54
+ - Specific User detail and log view *new*
54
55
  - Localization support
55
56
  - Admin interface integration
56
57
  - CRUD views and templates
@@ -109,12 +110,14 @@ users/
109
110
  ## Version History
110
111
 
111
112
  | Version | Changes |
112
- | v1.0.0 | Initial release as pip package |
113
- | v1.0.1 | Fixed a couple of new issues as a pip package |
114
- | v1.0.2 | Fixed the readme and building files |
115
- | v1.0.3 | Still getting the hang of this pip publish thing |
116
- | v1.0.4 | Honestly still messing with and trying settings and stuff out |
117
- | v1.1.0 | OK, finally a working seamless micro-users app |
118
- | v1.1.1 | Fixed a bug where a staff member can edit the admin details |
119
- | v1.2.0 | Added User Details view with specific user activity log |
120
- | v
113
+ |----------|---------|
114
+ | v1.0.0 | Initial release as pip package |
115
+ | v1.0.1 | Fixed a couple of new issues as a pip package |
116
+ | v1.0.2 | Fixed the readme and building files |
117
+ | v1.0.3 | Still getting the hang of this pip publish thing |
118
+ | v1.0.4 | Honestly still messing with and trying settings and stuff out |
119
+ | v1.1.0 | OK, finally a working seamless micro-users app |
120
+ | v1.1.1 | Fixed a bug where a staff member can edit the admin details |
121
+ | v1.2.0 | • Added User Details view with specific user activity log |
122
+ | v1.2.1 | • Fixed a minor import bug |
123
+ | v1.2.3 | • Separated user detail view from table for consistency<br> • Optimized the new detail + log view for optimal compatibiliyy with users |
@@ -7,19 +7,21 @@ users/models.py,sha256=KX_6LoiNJN6PCTFOuuGp5so4CNn5pAh1Vpaigv4fKk4,2060
7
7
  users/signals.py,sha256=5Kd3KyfPT6740rvwZj4vy1yXsmjVhmaQ__RB8p5R5aE,1336
8
8
  users/tables.py,sha256=ZW8_TR6Y3DwchS7Q8DGVdJX01fjIDZfaqoZo0XpZnyU,1920
9
9
  users/urls.py,sha256=FwQ9GVOBRQ4iXQ9UyLFI0aEAga0d5qL_miPNpmFPA-Q,1022
10
- users/views.py,sha256=HOl3pHr3M28s3pHkyGjCgRbiOwqSSRkbkazzpcMBofw,8074
10
+ users/views.py,sha256=FdMY49IKgU0clowCJ3_XRqqLLja7N7fs9GhavmJE0mw,7979
11
11
  users/migrations/0001_initial.py,sha256=lx9sSKS-lxHhI6gelVH52NOkwqEMJ32TvOJUn9zaOXM,4709
12
12
  users/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
+ users/static/css/login.css,sha256=SiJ6jBbWQAP2Nxt7DOTZbTcFYP9JEp557AuQZ9Eirb0,2120
14
+ users/static/img/default_profile.webp,sha256=BKUoQHo4z_fZnmc6z6I-KFvLEHahDr98U9LnDQKHLAM,3018
13
15
  users/templates/user_activity_log.html,sha256=S_FDN6vVLz_mB826yjeU9vtVGtzk7E_LKBmQIeYtdkQ,611
14
16
  users/templates/registration/login.html,sha256=owbzO_XjqMeSncwWxkTzsvbkhjEZd7LdbblC3HBnld0,4091
15
17
  users/templates/users/manage_users.html,sha256=ZusUTrJcp-xeORBnOcBObi9q1zlQE9yVRurMEvQVeWQ,2940
16
18
  users/templates/users/profile.html,sha256=9ahVF6YZUR-6-c8SKc0rN2pVdis2lI9gbcOQZeMaFnY,2909
17
19
  users/templates/users/profile_edit.html,sha256=sgO3h9ffVK1vnDNl4E6l5x3xfam3FTQl6Lqkrw5gmlw,4215
18
- users/templates/users/user_actions.html,sha256=oJedI5NElf-bXFBdeuQVNgx2enbwRsJSowBv5i6PFUE,1625
19
- users/templates/users/user_detail.html,sha256=jU6GIKlXEwnASDL_yosc6V46SjSwIDAgaRn0_iDK50U,1688
20
+ users/templates/users/user_actions.html,sha256=TfA1DUvPyuSTPvVn7JgAL1cbqQyT9d8vnVB6j6308LU,1625
21
+ users/templates/users/user_detail.html,sha256=QkJ-6jdtUdi8mM-V_MzqYcdoEkzXEsIeFMliNjgIOsc,2053
20
22
  users/templates/users/user_form.html,sha256=jcyI7OQZOY4ue4DajPtfjAt2SmAYO5ZgHNOqTp2-FO0,1352
21
- micro_users-1.2.0.dist-info/LICENSE,sha256=Fco89ULLSSxKkC2KKnx57SaT0R7WOkZfuk8IYcGiN50,1063
22
- micro_users-1.2.0.dist-info/METADATA,sha256=FjI3CzRhLRwETEGtpsxs56AN3M5KSAXbI9EMrvY5ho0,3362
23
- micro_users-1.2.0.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
24
- micro_users-1.2.0.dist-info/top_level.txt,sha256=tWT24ZcWau2wrlbpU_h3mP2jRukyLaVYiyHBuOezpLQ,6
25
- micro_users-1.2.0.dist-info/RECORD,,
23
+ micro_users-1.2.3.dist-info/LICENSE,sha256=Fco89ULLSSxKkC2KKnx57SaT0R7WOkZfuk8IYcGiN50,1063
24
+ micro_users-1.2.3.dist-info/METADATA,sha256=dApOQwELdXHFYZaiDIPqzK6uuz24dN9R3RjriOEqRtQ,3653
25
+ micro_users-1.2.3.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
26
+ micro_users-1.2.3.dist-info/top_level.txt,sha256=tWT24ZcWau2wrlbpU_h3mP2jRukyLaVYiyHBuOezpLQ,6
27
+ micro_users-1.2.3.dist-info/RECORD,,
@@ -0,0 +1,134 @@
1
+ ::selection {
2
+ background: #d4c591;
3
+ }
4
+ ::-webkit-selection {
5
+ background: #d4c591;
6
+ }
7
+ ::-moz-selection {
8
+ background: #c9aa5e;
9
+ }
10
+
11
+ .page {
12
+ display: flex;
13
+ flex-direction: column;
14
+ height: calc(100% - 15vh);
15
+ position: absolute;
16
+ place-content: center;
17
+ width: calc(100% - 40px);
18
+ }
19
+ @media (max-width: 767px) {
20
+ .page {
21
+ height: auto;
22
+ margin-bottom: 20px;
23
+ padding-bottom: 20px;
24
+ }
25
+ }
26
+ .container {
27
+ height: 320px;
28
+ margin: 0 auto;
29
+ width: 640px;
30
+ }
31
+ @media (max-width: 767px) {
32
+ .container {
33
+ flex-direction: column;
34
+ height: 630px;
35
+ width: 320px;
36
+ }
37
+ }
38
+ .left {
39
+ background: white;
40
+ height: calc(100% - 40px);
41
+ top: 20px;
42
+ position: relative;
43
+ width: 60%;
44
+ box-shadow: 0px 0px 10px 4px rgba(0,0,0,0.03);
45
+
46
+ }
47
+ @media (max-width: 767px) {
48
+ .left {
49
+ height: 100%;
50
+ left: 5%;
51
+ width: 110%;
52
+ max-height: 270px;
53
+ }
54
+ }
55
+ /* .login {
56
+ font-size: 38px;
57
+ font-weight: 600;
58
+ }
59
+ .eula {
60
+ color: #adadad;
61
+ font-size: 14px;
62
+ line-height: 1.5;
63
+ margin: 40px;
64
+ } */
65
+ .right {
66
+ background: #cb9447;
67
+ box-shadow: 0px 0px 20px 8px rgba(0,0,0,0.07);
68
+ color: #F1F1F2;
69
+ position: relative;
70
+ width: 58%;
71
+ }
72
+ @media (max-width: 767px) {
73
+ .right {
74
+ flex-shrink: 0;
75
+ height: 100%;
76
+ width: 100%;
77
+ max-height: 350px;
78
+ }
79
+ }
80
+ svg {
81
+ position: absolute;
82
+ width: 320px;
83
+ }
84
+ path {
85
+ fill: none;
86
+ stroke: url(#linearGradient);;
87
+ stroke-width: 3;
88
+ stroke-dasharray: 240 1386;
89
+ }
90
+ .form {
91
+ margin: 35px 35px 35px 20px;
92
+ position: absolute;
93
+ }
94
+ label {
95
+ color: #c2c2c5;
96
+ display: block;
97
+ font-size: 14px;
98
+ height: 16px;
99
+ margin-top: 20px;
100
+ margin-bottom: 5px;
101
+ }
102
+ input {
103
+ background: transparent;
104
+ border: 0;
105
+ color: #2d0202;
106
+ font-size: 20px;
107
+ height: 30px;
108
+ line-height: 30px;
109
+ outline: none !important;
110
+ width: 100%;
111
+ margin-top: 30px;
112
+ margin-bottom: 10px;
113
+ }
114
+ input::-moz-focus-inner {
115
+ border: 0;
116
+ }
117
+ #submit {
118
+ color: #707075;
119
+ margin-top: 40px;
120
+ transition: color 300ms;
121
+ }
122
+ #submit:focus {
123
+ color: #575757;
124
+ }
125
+ #submit:active {
126
+ color: #4d4d4d;
127
+ }
128
+
129
+ .titlebar {
130
+ background-color: var(--title);
131
+ flex-direction: row;
132
+ height: 7vh;
133
+ justify-content: center !important
134
+ }
Binary file
@@ -9,12 +9,12 @@
9
9
  <i class="bi bi-person-lines-fill text-dark me-1 h5"> </i> عرض
10
10
  </a>
11
11
  </li> {% endcomment %}
12
- {% if not record.is_superuser %}
13
12
  <li>
14
13
  <a class="dropdown-item" href="{% url 'user_detail' record.pk %}" title="عرض">
15
14
  <i class="bi bi-person-dash-fill text-dark me-1 h5"> </i> عرض
16
15
  </a>
17
16
  </li>
17
+ {% if not record.is_superuser %}
18
18
  <li>
19
19
  <a class="dropdown-item" href="{% url 'edit_user' record.pk %}" title="تعديل">
20
20
  <i class="bi bi-person-dash-fill text-dark me-1 h5"> </i> تعديل
@@ -1,49 +1,52 @@
1
1
  {% extends "base.html" %}
2
2
  {% load crispy_forms_tags %}
3
3
  {% load django_tables2 %}
4
+ {% load static %}
4
5
 
5
6
  {% block content %}
6
- <div class="container mt-4">
7
- <!-- USER INFO CARD -->
8
- <div class="card mb-4 shadow-sm">
9
- <div class="card-header bg-primary text-white">
10
- تفاصيل المستخدم
11
- </div>
12
- <div class="card-body">
13
- <h5>{{ detail_user.get_full_name }} ({{ detail_user.username }})</h5>
14
- <p class="mb-1"><strong>البريد:</strong> {{ detail_user.email }}</p>
15
- <p class="mb-1"><strong>تاريخ الإنشاء:</strong> {{ detail_user.date_joined|date:"Y-m-d" }}</p>
16
- <p class="mb-1"><strong>آخر دخول:</strong> {{ detail_user.last_login|date:"Y-m-d H:i" }}</p>
17
- <p class="mb-1"><strong>الصلاحيات:</strong>
18
- {% if detail_user.is_superuser %}
19
- مدير النظام
20
- {% elif detail_user.is_staff %}
21
- مستخدم اداري
22
- {% else %}
23
- مستخدم عادي
24
- {% endif %}
25
- </p>
7
+ <div class="card border-light shadow">
8
+ <div class="card-header h3">تفاصيل المستخدم</div>
9
+ <div class="card-body mt-2 row">
10
+ <div class="col-md-6 h4">
11
+ <p><strong>اسم الـمستخدم:</strong> {{ object.username }}</p>
12
+ <p><strong>الاســــــــــــــــــم:</strong> {{ object.get_full_name }}</p>
13
+ <p><strong>رقـــــم الـــهاتف:</strong> {{ object.phone }}</p>
14
+ <p><strong>جهـــــة الـــعمل:</strong> {{ object.occupation }}</p>
15
+ </div>
16
+ <div class="col-md-6 h4">
17
+ <p><strong>البريد الالكتروني:</strong> {{ object.email }}</p>
18
+ <p><strong>تاريخ الإنشاء:</strong> {{ object.date_joined|date:"Y-m-d" }}</p>
19
+ <p><strong>آخر دخول:</strong> {{ object.last_login|date:"Y-m-d H:i" }}</p>
20
+ <p><strong>الصلاحيات:</strong>
21
+ {% if object.is_superuser %}
22
+ مدير النظام
23
+ {% elif object.is_staff %}
24
+ مستخدم اداري
25
+ {% else %}
26
+ مستخدم عادي
27
+ {% endif %}
28
+ </p>
29
+ </div>
26
30
  </div>
27
31
  </div>
28
32
 
29
33
  <!-- ACTIVITY LOG TABLE -->
30
- <div class="card shadow-sm">
31
- <div class="card-header bg-secondary text-white">
32
- سجل نشاط المستخدم
34
+ <div class="card mt-2 border-light shadow">
35
+ <div class="card-header h3">
36
+ سجل النشاط
33
37
  </div>
34
- <div class="card-body">
38
+ <div class="mt-2 card-body p-1 table-responsive-lg">
35
39
  {% render_table table %}
36
40
  </div>
37
41
  </div>
38
42
 
39
43
  <!-- BACK BUTTON -->
40
- <div class="mb-3">
44
+ <div class="mb-3 mt-3">
41
45
  <a href="{% url 'manage_users' %}" class="btn btn-outline-secondary">
42
46
  <i class="bi bi-arrow-right me-2"></i> العودة إلى إدارة المستخدمين
43
47
  </a>
44
48
  </div>
45
49
 
46
- </div>
47
50
 
48
51
 
49
52
  {% endblock %}
users/views.py CHANGED
@@ -7,8 +7,9 @@ from django.contrib.auth.decorators import login_required, user_passes_test
7
7
  from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
8
8
  from django.http import JsonResponse
9
9
  from django.shortcuts import render, redirect, get_object_or_404
10
- from django_tables2 import RequestConfig, SingleTableView, DetailView
10
+ from django_tables2 import RequestConfig, SingleTableView
11
11
  from django_filters.views import FilterView
12
+ from django.views.generic.detail import DetailView
12
13
 
13
14
  # Project imports
14
15
  #################
@@ -140,28 +141,25 @@ class UserActivityLogView(LoginRequiredMixin, UserPassesTestMixin, SingleTableVi
140
141
  return context
141
142
 
142
143
 
143
- class UserDetailView(LoginRequiredMixin, UserPassesTestMixin, DetailView, SingleTableView):
144
+ class UserDetailView(LoginRequiredMixin, UserPassesTestMixin, DetailView):
144
145
  model = User
145
146
  template_name = "users/user_detail.html"
146
- context_object_name = "detail_user" # Keep clear naming
147
- table_class = UserActivityLogTableNoUser
148
- paginate_by = 10
149
147
 
150
148
  def test_func(self):
151
149
  # only staff can view user detail page
152
150
  return self.request.user.is_staff
153
151
 
154
- def get_queryset(self):
155
- # This is for the DetailView (only target user)
156
- return User.objects.all()
157
-
158
- def get_table_data(self):
159
- # filter log table to user in URL
160
- return UserActivityLog.objects.filter(user=self.get_object()).order_by('-timestamp')
161
-
162
152
  def get_context_data(self, **kwargs):
163
153
  context = super().get_context_data(**kwargs)
164
- context['table'] = self.get_table() # table instance
154
+
155
+ # self.object is the User instance
156
+ logs_qs = UserActivityLog.objects.filter(user=self.object).order_by('-timestamp')
157
+
158
+ # Create table manually
159
+ table = UserActivityLogTableNoUser(logs_qs)
160
+ RequestConfig(self.request, paginate={'per_page': 10}).configure(table)
161
+
162
+ context['table'] = table
165
163
  return context
166
164
 
167
165