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.
- {micro_users-1.2.0.dist-info → micro_users-1.2.3.dist-info}/METADATA +13 -10
- {micro_users-1.2.0.dist-info → micro_users-1.2.3.dist-info}/RECORD +10 -8
- users/static/css/login.css +134 -0
- users/static/img/default_profile.webp +0 -0
- users/templates/users/user_actions.html +1 -1
- users/templates/users/user_detail.html +29 -26
- users/views.py +12 -14
- {micro_users-1.2.0.dist-info → micro_users-1.2.3.dist-info}/LICENSE +0 -0
- {micro_users-1.2.0.dist-info → micro_users-1.2.3.dist-info}/WHEEL +0 -0
- {micro_users-1.2.0.dist-info → micro_users-1.2.3.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: micro-users
|
|
3
|
-
Version: 1.2.
|
|
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
|
-
|
|
113
|
-
| v1.0.
|
|
114
|
-
| v1.0.
|
|
115
|
-
| v1.0.
|
|
116
|
-
| v1.0.
|
|
117
|
-
| v1.
|
|
118
|
-
| v1.1.
|
|
119
|
-
| v1.
|
|
120
|
-
|
|
|
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=
|
|
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=
|
|
19
|
-
users/templates/users/user_detail.html,sha256=
|
|
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.
|
|
22
|
-
micro_users-1.2.
|
|
23
|
-
micro_users-1.2.
|
|
24
|
-
micro_users-1.2.
|
|
25
|
-
micro_users-1.2.
|
|
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="
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
<
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
{
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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
|
|
31
|
-
<div class="card-header
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|