plain.admin 0.56.0__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 (83) hide show
  1. plain_admin-0.56.0/.gitignore +21 -0
  2. plain_admin-0.56.0/LICENSE +28 -0
  3. plain_admin-0.56.0/PKG-INFO +193 -0
  4. plain_admin-0.56.0/README.md +1 -0
  5. plain_admin-0.56.0/plain/admin/CHANGELOG.md +464 -0
  6. plain_admin-0.56.0/plain/admin/README.md +179 -0
  7. plain_admin-0.56.0/plain/admin/__init__.py +5 -0
  8. plain_admin-0.56.0/plain/admin/assets/admin/admin.css +237 -0
  9. plain_admin-0.56.0/plain/admin/assets/admin/admin.js +212 -0
  10. plain_admin-0.56.0/plain/admin/assets/admin/bootstrap-icons.svg +1 -0
  11. plain_admin-0.56.0/plain/admin/assets/admin/list.js +94 -0
  12. plain_admin-0.56.0/plain/admin/assets/admin/vendor/chart.js +19 -0
  13. plain_admin-0.56.0/plain/admin/assets/admin/vendor/jquery-3.7.1.min.js +2 -0
  14. plain_admin-0.56.0/plain/admin/assets/admin/vendor/popper.min.js +5 -0
  15. plain_admin-0.56.0/plain/admin/assets/admin/vendor/tippy.css +1 -0
  16. plain_admin-0.56.0/plain/admin/assets/admin/vendor/tippy.umd.min.js +2 -0
  17. plain_admin-0.56.0/plain/admin/cards/__init__.py +10 -0
  18. plain_admin-0.56.0/plain/admin/cards/base.py +91 -0
  19. plain_admin-0.56.0/plain/admin/cards/charts.py +117 -0
  20. plain_admin-0.56.0/plain/admin/cards/tables.py +28 -0
  21. plain_admin-0.56.0/plain/admin/config.py +10 -0
  22. plain_admin-0.56.0/plain/admin/dates.py +268 -0
  23. plain_admin-0.56.0/plain/admin/impersonate/__init__.py +7 -0
  24. plain_admin-0.56.0/plain/admin/impersonate/constants.py +1 -0
  25. plain_admin-0.56.0/plain/admin/impersonate/middleware.py +44 -0
  26. plain_admin-0.56.0/plain/admin/impersonate/permissions.py +18 -0
  27. plain_admin-0.56.0/plain/admin/impersonate/requests.py +19 -0
  28. plain_admin-0.56.0/plain/admin/impersonate/settings.py +10 -0
  29. plain_admin-0.56.0/plain/admin/impersonate/urls.py +11 -0
  30. plain_admin-0.56.0/plain/admin/impersonate/views.py +24 -0
  31. plain_admin-0.56.0/plain/admin/middleware.py +10 -0
  32. plain_admin-0.56.0/plain/admin/templates/admin/base.html +262 -0
  33. plain_admin-0.56.0/plain/admin/templates/admin/cards/base.html +41 -0
  34. plain_admin-0.56.0/plain/admin/templates/admin/cards/card.html +17 -0
  35. plain_admin-0.56.0/plain/admin/templates/admin/cards/chart.html +31 -0
  36. plain_admin-0.56.0/plain/admin/templates/admin/cards/table.html +35 -0
  37. plain_admin-0.56.0/plain/admin/templates/admin/delete.html +16 -0
  38. plain_admin-0.56.0/plain/admin/templates/admin/detail.html +16 -0
  39. plain_admin-0.56.0/plain/admin/templates/admin/index.html +5 -0
  40. plain_admin-0.56.0/plain/admin/templates/admin/list.html +190 -0
  41. plain_admin-0.56.0/plain/admin/templates/admin/page.html +3 -0
  42. plain_admin-0.56.0/plain/admin/templates/admin/search.html +49 -0
  43. plain_admin-0.56.0/plain/admin/templates/admin/toolbar/button.html +21 -0
  44. plain_admin-0.56.0/plain/admin/templates/admin/values/UUID.html +1 -0
  45. plain_admin-0.56.0/plain/admin/templates/admin/values/bool.html +9 -0
  46. plain_admin-0.56.0/plain/admin/templates/admin/values/datetime.html +1 -0
  47. plain_admin-0.56.0/plain/admin/templates/admin/values/default.html +5 -0
  48. plain_admin-0.56.0/plain/admin/templates/admin/values/dict.html +1 -0
  49. plain_admin-0.56.0/plain/admin/templates/admin/values/img.html +4 -0
  50. plain_admin-0.56.0/plain/admin/templates/admin/values/list.html +1 -0
  51. plain_admin-0.56.0/plain/admin/templates/admin/values/model.html +15 -0
  52. plain_admin-0.56.0/plain/admin/templates/admin/values/queryset.html +7 -0
  53. plain_admin-0.56.0/plain/admin/templates/elements/admin/Checkbox.html +8 -0
  54. plain_admin-0.56.0/plain/admin/templates/elements/admin/CheckboxField.html +10 -0
  55. plain_admin-0.56.0/plain/admin/templates/elements/admin/FieldErrors.html +5 -0
  56. plain_admin-0.56.0/plain/admin/templates/elements/admin/Help.html +1 -0
  57. plain_admin-0.56.0/plain/admin/templates/elements/admin/Icon.html +3 -0
  58. plain_admin-0.56.0/plain/admin/templates/elements/admin/Input.html +8 -0
  59. plain_admin-0.56.0/plain/admin/templates/elements/admin/InputField.html +8 -0
  60. plain_admin-0.56.0/plain/admin/templates/elements/admin/Label.html +4 -0
  61. plain_admin-0.56.0/plain/admin/templates/elements/admin/Select.html +10 -0
  62. plain_admin-0.56.0/plain/admin/templates/elements/admin/SelectField.html +8 -0
  63. plain_admin-0.56.0/plain/admin/templates/elements/admin/Submit.html +6 -0
  64. plain_admin-0.56.0/plain/admin/templates/elements/admin/Textarea.html +7 -0
  65. plain_admin-0.56.0/plain/admin/templates/elements/admin/TextareaField.html +8 -0
  66. plain_admin-0.56.0/plain/admin/templates.py +20 -0
  67. plain_admin-0.56.0/plain/admin/toolbar.py +24 -0
  68. plain_admin-0.56.0/plain/admin/urls.py +42 -0
  69. plain_admin-0.56.0/plain/admin/utils.py +14 -0
  70. plain_admin-0.56.0/plain/admin/views/__init__.py +41 -0
  71. plain_admin-0.56.0/plain/admin/views/base.py +128 -0
  72. plain_admin-0.56.0/plain/admin/views/models.py +251 -0
  73. plain_admin-0.56.0/plain/admin/views/objects.py +398 -0
  74. plain_admin-0.56.0/plain/admin/views/registry.py +192 -0
  75. plain_admin-0.56.0/plain/admin/views/types.py +13 -0
  76. plain_admin-0.56.0/plain/admin/views/viewsets.py +54 -0
  77. plain_admin-0.56.0/pyproject.toml +26 -0
  78. plain_admin-0.56.0/tests/app/settings.py +18 -0
  79. plain_admin-0.56.0/tests/app/urls.py +24 -0
  80. plain_admin-0.56.0/tests/app/users/migrations/0001_initial.py +21 -0
  81. plain_admin-0.56.0/tests/app/users/migrations/__init__.py +0 -0
  82. plain_admin-0.56.0/tests/app/users/models.py +12 -0
  83. plain_admin-0.56.0/tests/test_admin.py +24 -0
@@ -0,0 +1,21 @@
1
+ .venv
2
+ /.env
3
+ *.egg-info
4
+ *.py[co]
5
+ __pycache__
6
+ *.DS_Store
7
+
8
+ /*.code-workspace
9
+
10
+ # Test apps
11
+ plain*/tests/.plain
12
+
13
+ # Agent scratch files
14
+ /scratch
15
+
16
+ # Plain temp dirs
17
+ .plain
18
+
19
+ .vscode
20
+ /.claude
21
+ /.benchmarks
@@ -0,0 +1,28 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2023, Dropseed, LLC
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ 3. Neither the name of the copyright holder nor the names of its
16
+ contributors may be used to endorse or promote products derived from
17
+ this software without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,193 @@
1
+ Metadata-Version: 2.4
2
+ Name: plain.admin
3
+ Version: 0.56.0
4
+ Summary: Manage your app with a backend interface.
5
+ Author-email: Dave Gaeddert <dave.gaeddert@dropseed.dev>
6
+ License-Expression: BSD-3-Clause
7
+ License-File: LICENSE
8
+ Requires-Python: >=3.13
9
+ Requires-Dist: plain-auth<1.0.0
10
+ Requires-Dist: plain-htmx<1.0.0
11
+ Requires-Dist: plain-tailwind<1.0.0
12
+ Requires-Dist: plain<1.0.0
13
+ Description-Content-Type: text/markdown
14
+
15
+ # plain.admin
16
+
17
+ **Manage your app with a backend interface.**
18
+
19
+ - [Overview](#overview)
20
+ - [Admin viewsets](#admin-viewsets)
21
+ - [Admin cards](#admin-cards)
22
+ - [Admin forms](#admin-forms)
23
+ - [List presets](#list-presets)
24
+ - [Toolbar](#toolbar)
25
+ - [Impersonate](#impersonate)
26
+ - [Installation](#installation)
27
+
28
+ ## Overview
29
+
30
+ The Plain Admin provides a combination of built-in views and the flexibility to create your own. You can use it to quickly get visibility into your app's data and to manage it.
31
+
32
+ ![Plain Admin user example](https://assets.plainframework.com/docs/plain-pageviews-user.png)
33
+
34
+ The most common use of the admin is to manage your `plain.models`. To do this, create a [viewset](./views/viewsets.py#AdminViewset) with inner/nested views:
35
+
36
+ ```python
37
+ # app/users/admin.py
38
+ from plain.admin.views import (
39
+ AdminModelDetailView,
40
+ AdminModelListView,
41
+ AdminModelUpdateView,
42
+ AdminViewset,
43
+ register_viewset,
44
+ )
45
+ from plain.models.forms import ModelForm
46
+
47
+ from .models import User
48
+
49
+
50
+ class UserForm(ModelForm):
51
+ class Meta:
52
+ model = User
53
+ fields = ["email"]
54
+
55
+
56
+ @register_viewset
57
+ class UserAdmin(AdminViewset):
58
+ class ListView(AdminModelListView):
59
+ model = User
60
+ fields = [
61
+ "id",
62
+ "email",
63
+ "created_at__date",
64
+ ]
65
+ queryset_order = ["-created_at"]
66
+ search_fields = [
67
+ "email",
68
+ ]
69
+
70
+ class DetailView(AdminModelDetailView):
71
+ model = User
72
+
73
+ class UpdateView(AdminModelUpdateView):
74
+ template_name = "admin/users/user_form.html"
75
+ model = User
76
+ form_class = UserForm
77
+ ```
78
+
79
+ ## Admin viewsets
80
+
81
+ The [`AdminViewset`](./views/viewsets.py#AdminViewset) will automatically recognize inner views named `ListView`, `CreateView`, `DetailView`, `UpdateView`, and `DeleteView`. It will interlink these views automatically in the UI and form success URLs. You can define additional views too, but you will need to implement a couple methods to hook them up.
82
+
83
+ ## Admin cards
84
+
85
+ TODO
86
+
87
+ ## Admin forms
88
+
89
+ TODO
90
+
91
+ ## List presets
92
+
93
+ On [`AdminListView`](./views/objects.py#AdminListView) and [`AdminModelListView`](./views/models.py#AdminModelListView), you can define different `presets` to build predefined views of your data. The preset choices will be shown in the UI, and you can use the current `self.preset` in your view logic.
94
+
95
+ ```python
96
+ # app/users/admin.py
97
+ from plain.admin.views import AdminModelListView, register_viewset
98
+
99
+ from .models import User
100
+
101
+
102
+ @register_viewset
103
+ class UserAdmin(AdminViewset):
104
+ class ListView(AdminModelListView):
105
+ model = User
106
+ fields = [
107
+ "id",
108
+ "email",
109
+ "created_at__date",
110
+ ]
111
+ presets = ["Users without email"]
112
+
113
+ def get_objects(self):
114
+ objects = super().get_objects()
115
+
116
+ if self.preset == "Users without email":
117
+ objects = objects.filter(email="")
118
+
119
+ return objects
120
+ ```
121
+
122
+ ## Toolbar
123
+
124
+ TODO
125
+
126
+ ## Impersonate
127
+
128
+ TODO
129
+
130
+ ## Installation
131
+
132
+ Install the `plain.admin` package from [PyPI](https://pypi.org/project/plain.admin/):
133
+
134
+ ```bash
135
+ uv add plain.admin
136
+ ```
137
+
138
+ The admin uses a combination of other Plain packages, most of which you will already have installed. Ultimately, your settings will look something like this:
139
+
140
+ ```python
141
+ # app/settings.py
142
+ INSTALLED_PACKAGES = [
143
+ "plain.models",
144
+ "plain.tailwind",
145
+ "plain.auth",
146
+ "plain.sessions",
147
+ "plain.htmx",
148
+ "plain.admin",
149
+ "plain.elements",
150
+ # other packages...
151
+ ]
152
+
153
+ AUTH_USER_MODEL = "users.User"
154
+ AUTH_LOGIN_URL = "login"
155
+
156
+ MIDDLEWARE = [
157
+ "plain.sessions.middleware.SessionMiddleware",
158
+ "plain.admin.AdminMiddleware",
159
+ ]
160
+ ```
161
+
162
+ Your User model is expected to have an `is_admin` field (or attribute) for checking who has permission to access the admin.
163
+
164
+ ```python
165
+ # app/users/models.py
166
+ from plain import models
167
+
168
+
169
+ @models.register_model
170
+ class User(models.Model):
171
+ is_admin = models.BooleanField(default=False)
172
+ # other fields...
173
+ ```
174
+
175
+ To make the admin accessible, add the [`AdminRouter`](./urls.py#AdminRouter) to your root URLs.
176
+
177
+ ```python
178
+ # app/urls.py
179
+ from plain.admin.urls import AdminRouter
180
+ from plain.urls import Router, include, path
181
+
182
+ from . import views
183
+
184
+
185
+ class AppRouter(Router):
186
+ namespace = ""
187
+ urls = [
188
+ include("admin/", AdminRouter),
189
+ path("login/", views.LoginView, name="login"),
190
+ path("logout/", LogoutView, name="logout"),
191
+ # other urls...
192
+ ]
193
+ ```
@@ -0,0 +1 @@
1
+ plain/admin/README.md