micro-users 1.2.1__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.1
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
@@ -110,12 +111,13 @@ users/
110
111
 
111
112
  | Version | Changes |
112
113
  |----------|---------|
113
- | v1.0.0 | Initial release as pip package |
114
- | v1.0.1 | Fixed a couple of new issues as a pip package |
115
- | v1.0.2 | Fixed the readme and building files |
116
- | v1.0.3 | Still getting the hang of this pip publish thing |
117
- | v1.0.4 | Honestly still messing with and trying settings and stuff out |
118
- | v1.1.0 | OK, finally a working seamless micro-users app |
119
- | v1.1.1 | Fixed a bug where a staff member can edit the admin details |
120
- | v1.2.0 | Added User Details view with specific user activity log |
121
- | v1.2.1 | Fixed a minot import bug |
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=mruC7kf0_KMiNVxOwZNMyt5pUidu7U3RyIgYHDEFJ_4,8113
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.1.dist-info/LICENSE,sha256=Fco89ULLSSxKkC2KKnx57SaT0R7WOkZfuk8IYcGiN50,1063
22
- micro_users-1.2.1.dist-info/METADATA,sha256=Q__3FA_yfJm1I4WY9gLGBeVv8-N7L4fj6tUaLRWGhLE,3421
23
- micro_users-1.2.1.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
24
- micro_users-1.2.1.dist-info/top_level.txt,sha256=tWT24ZcWau2wrlbpU_h3mP2jRukyLaVYiyHBuOezpLQ,6
25
- micro_users-1.2.1.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
@@ -141,28 +141,25 @@ class UserActivityLogView(LoginRequiredMixin, UserPassesTestMixin, SingleTableVi
141
141
  return context
142
142
 
143
143
 
144
- class UserDetailView(LoginRequiredMixin, UserPassesTestMixin, DetailView, SingleTableView):
144
+ class UserDetailView(LoginRequiredMixin, UserPassesTestMixin, DetailView):
145
145
  model = User
146
146
  template_name = "users/user_detail.html"
147
- context_object_name = "detail_user" # Keep clear naming
148
- table_class = UserActivityLogTableNoUser
149
- paginate_by = 10
150
147
 
151
148
  def test_func(self):
152
149
  # only staff can view user detail page
153
150
  return self.request.user.is_staff
154
151
 
155
- def get_queryset(self):
156
- # This is for the DetailView (only target user)
157
- return User.objects.all()
158
-
159
- def get_table_data(self):
160
- # filter log table to user in URL
161
- return UserActivityLog.objects.filter(user=self.get_object()).order_by('-timestamp')
162
-
163
152
  def get_context_data(self, **kwargs):
164
153
  context = super().get_context_data(**kwargs)
165
- 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
166
163
  return context
167
164
 
168
165