wip: full editing support and login of user achieved, updated minijinja to v2, htmx, hyperscript
This commit is contained in:
parent
402585f968
commit
a26e17a064
16
Cargo.lock
generated
16
Cargo.lock
generated
@ -1839,9 +1839,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "minijinja"
|
name = "minijinja"
|
||||||
version = "1.0.11"
|
version = "2.0.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "431d72874542d43aba1ca605870eacab134fdeb0c8fe27666ecf4b2662239df2"
|
checksum = "933ee10775d58fca8238a84fe165dfe4bde8b07d7574f24d76ffea91170f3ac6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memo-map",
|
"memo-map",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
@ -1851,9 +1851,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "minijinja-autoreload"
|
name = "minijinja-autoreload"
|
||||||
version = "1.0.8"
|
version = "2.0.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dbe548b8e2b0590e25f0baf95f76c1d7ea73ca264f1f90fe1bf6e00cc6612d19"
|
checksum = "bfe3362301b5f450f0f07175cc8cacdd9edb352c7d0375af72646dfb5769fc2a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"minijinja",
|
"minijinja",
|
||||||
"notify",
|
"notify",
|
||||||
@ -2388,9 +2388,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pulldown-cmark"
|
name = "pulldown-cmark"
|
||||||
version = "0.10.0"
|
version = "0.11.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dce76ce678ffc8e5675b22aa1405de0b7037e2fdf8913fea40d1926c6fe1e6e7"
|
checksum = "8746739f11d39ce5ad5c2520a9b75285310dbfe78c541ccf832d38615765aec0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.4.0",
|
"bitflags 2.4.0",
|
||||||
"getopts",
|
"getopts",
|
||||||
@ -2401,9 +2401,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pulldown-cmark-escape"
|
name = "pulldown-cmark-escape"
|
||||||
version = "0.10.0"
|
version = "0.11.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d5d8f9aa0e3cbcfaf8bf00300004ee3b72f74770f9cbac93f6928771f613276b"
|
checksum = "007d8adb5ddab6f8e3f491ac63566a7d5002cc7ed73901f72057943fa71ae1ae"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
|
@ -33,13 +33,13 @@ axum-messages = "0.6.1"
|
|||||||
barrel = { version = "0.7.0", optional = true, features = ["pg"] }
|
barrel = { version = "0.7.0", optional = true, features = ["pg"] }
|
||||||
dotenvy = "0.15.7"
|
dotenvy = "0.15.7"
|
||||||
mime_guess = "2.0.4"
|
mime_guess = "2.0.4"
|
||||||
minijinja = { version = "1.0.11", features = [
|
minijinja = { version = "2.0.3", features = [
|
||||||
"loader",
|
"loader",
|
||||||
"builtins",
|
"builtins",
|
||||||
"urlencode",
|
"urlencode",
|
||||||
"deserialization",
|
"deserialization",
|
||||||
] }
|
] }
|
||||||
minijinja-autoreload = "1.0.8"
|
minijinja-autoreload = "2.0.3"
|
||||||
once_cell = "1.18.0"
|
once_cell = "1.18.0"
|
||||||
rust-embed = { version = "8.0.0", features = [
|
rust-embed = { version = "8.0.0", features = [
|
||||||
"axum",
|
"axum",
|
||||||
|
4
TODOS.md
4
TODOS.md
@ -66,3 +66,7 @@ These errors should encompass:
|
|||||||
|
|
||||||
Repository functions also need to be redesigned to be Results.
|
Repository functions also need to be redesigned to be Results.
|
||||||
|
|
||||||
|
Finally, RepositoryResponse might require us to add abilities to
|
||||||
|
- render your own html ?
|
||||||
|
- at least influence HX Response Headers for htmx support
|
||||||
|
|
@ -11,14 +11,14 @@ path = "src/lib.rs"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0.75"
|
anyhow = "1.0.75"
|
||||||
axum = "0.7"
|
axum = "0.7"
|
||||||
minijinja = { version = "1.0.11", features = [
|
minijinja = { version = "2.0.3", features = [
|
||||||
"loader",
|
"loader",
|
||||||
"builtins",
|
"builtins",
|
||||||
"urlencode",
|
"urlencode",
|
||||||
"deserialization",
|
"deserialization",
|
||||||
] }
|
] }
|
||||||
minijinja-autoreload = "1.0.8"
|
minijinja-autoreload = "2.0.3"
|
||||||
pulldown-cmark = "0.10"
|
pulldown-cmark = "0.11"
|
||||||
serde = { version = "1.0.188", features = ["derive"] }
|
serde = { version = "1.0.188", features = ["derive"] }
|
||||||
tokio = { version = "1.32.0", features = ["full"] }
|
tokio = { version = "1.32.0", features = ["full"] }
|
||||||
log = "0.4.20"
|
log = "0.4.20"
|
||||||
|
@ -121,6 +121,10 @@ pub mod repository {
|
|||||||
Self::widget("/admin/widgets/input_textarea.jinja")
|
Self::widget("/admin/widgets/input_textarea.jinja")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn checkbox() -> Self {
|
||||||
|
Self::widget("/admin/widgets/checkbox_toggle.jinja")
|
||||||
|
}
|
||||||
|
|
||||||
pub fn required(mut self) -> Self {
|
pub fn required(mut self) -> Self {
|
||||||
self.required = true;
|
self.required = true;
|
||||||
self
|
self
|
||||||
|
@ -329,7 +329,8 @@ pub async fn update_item<S: AdminState + Clone + Send + Sync + 'static>(
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
templates.render_html("admin/items/item_change.jinja", context)
|
let response = templates.render_html("admin/items/item_change.jinja", context);
|
||||||
|
response
|
||||||
}
|
}
|
||||||
|
|
||||||
// Item Action allows running an action on one single dataset.
|
// Item Action allows running an action on one single dataset.
|
||||||
|
@ -37,7 +37,13 @@ impl AdminRepository for UserRepository {
|
|||||||
// fields_readonly: &["last_login", "date_joined"]
|
// fields_readonly: &["last_login", "date_joined"]
|
||||||
}
|
}
|
||||||
.build()
|
.build()
|
||||||
.set_widget("password", Widget::default().as_password())
|
.set_widget(
|
||||||
|
"password",
|
||||||
|
Widget::widget("/admin/widgets/password_change.jinja").as_password(),
|
||||||
|
)
|
||||||
|
.set_widget("is_staff", Widget::checkbox())
|
||||||
|
.set_widget("is_active", Widget::checkbox())
|
||||||
|
.set_widget("is_superuser", Widget::checkbox())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get(&self, model: &RepositoryContext, id: &Self::Key) -> Option<RepositoryItem> {
|
async fn get(&self, model: &RepositoryContext, id: &Self::Key) -> Option<RepositoryItem> {
|
||||||
@ -133,15 +139,34 @@ impl AdminRepository for UserRepository {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
let mut user: entity::user::ActiveModel = user.unwrap().into();
|
let mut user: entity::user::ActiveModel = user.unwrap().into();
|
||||||
|
|
||||||
// change values
|
// should we really allow username change?
|
||||||
if let Some(value) = data.get("username") {
|
if let Some(value) = data.get("username") {
|
||||||
if let Some(value) = value.as_str() {
|
if let Some(value) = value.as_str() {
|
||||||
user.username = Set(value.to_owned());
|
user.username = Set(value.to_owned());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(value) = data.get("password") {
|
let keys = [
|
||||||
user.password = Set(value.as_str().unwrap().to_owned());
|
"first_name",
|
||||||
|
"last_name",
|
||||||
|
"email",
|
||||||
|
"is_staff",
|
||||||
|
"is_active",
|
||||||
|
"is_superuser",
|
||||||
|
];
|
||||||
|
|
||||||
|
for key in &keys {
|
||||||
|
if let Some(value) = data.get(*key) {
|
||||||
|
match *key {
|
||||||
|
"first_name" => user.first_name = Set(value.as_str().map(|s| s.to_owned())),
|
||||||
|
"last_name" => user.last_name = Set(value.as_str().map(|s| s.to_owned())),
|
||||||
|
"email" => user.email = Set(value.as_str().map(|s| s.to_owned())),
|
||||||
|
"is_staff" => user.is_staff = Set(value.as_bool().unwrap_or(false)),
|
||||||
|
"is_active" => user.is_active = Set(value.as_bool().unwrap_or(true)),
|
||||||
|
"is_superuser" => user.is_superuser = Set(value.as_bool().unwrap_or(false)),
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// update
|
// update
|
||||||
|
2
static/htmx/htmx.min.js
vendored
2
static/htmx/htmx.min.js
vendored
File diff suppressed because one or more lines are too long
2
static/hyperscript/hyperscript.min.js
vendored
2
static/hyperscript/hyperscript.min.js
vendored
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
|||||||
https://unpkg.com/hyperscript.org@0.9.11/dist/_hyperscript.min.js
|
https://unpkg.com/hyperscript.org@0.9.12/dist/_hyperscript.min.js
|
@ -139,6 +139,9 @@
|
|||||||
{% endblock body %}
|
{% endblock body %}
|
||||||
{% block bodyjs %}
|
{% block bodyjs %}
|
||||||
<script src="/static/htmx/htmx.min.js"></script>
|
<script src="/static/htmx/htmx.min.js"></script>
|
||||||
|
<script src="/static/hyperscript/hyperscript.min.js"></script>
|
||||||
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
$('#main_sidemenu').sidebar({
|
$('#main_sidemenu').sidebar({
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
{% extends base|none("admin/base.jinja") %}
|
{% extends base|none("admin/base.jinja") %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
<div id="message-box-area" class="ui message" _="init wait 3s then transition opacity to 0 then remove me">
|
||||||
|
Hi there.
|
||||||
|
</div>
|
||||||
<div class="ui container">
|
<div class="ui container">
|
||||||
<h1>Update {{item_model.name}} in {{item_info.name}}</h1>
|
<h1>Update {{item_model.name}} in {{item_info.name}}</h1>
|
||||||
{% set fields = item_info.fields %}
|
{% set fields = item_info.fields %}
|
||||||
|
@ -1,5 +1,18 @@
|
|||||||
<form action="{{form.action}}" method="{{form.method|default('POST')}}" class="ui form">
|
<!--noformat-->
|
||||||
<!--noformat-->
|
<form class="ui form"
|
||||||
|
hx-target="main"
|
||||||
|
{% if form.method|upper == 'POST' or not form.method %}
|
||||||
|
hx-post="{{form.action}}"
|
||||||
|
{% elif form.method|upper == 'GET' %}
|
||||||
|
hx-get="{{form.action}}"
|
||||||
|
{% elif form.method|upper == 'PATCH' %}
|
||||||
|
hx-patch="{{form.action}}"
|
||||||
|
{% elif form.method|upper == 'PUT' %}
|
||||||
|
hx-put="{{form.action}}"
|
||||||
|
{% else %}
|
||||||
|
unknown-form-method={{form.method}}
|
||||||
|
{% endif %}>
|
||||||
|
|
||||||
{% from "/admin/items/items.jinja" import field_widget %}
|
{% from "/admin/items/items.jinja" import field_widget %}
|
||||||
{% for field_name, field_defs in fields %}
|
{% for field_name, field_defs in fields %}
|
||||||
{% if item %}
|
{% if item %}
|
||||||
@ -11,6 +24,6 @@
|
|||||||
{{ field_widget(field_name, field_defs, field_value) }}
|
{{ field_widget(field_name, field_defs, field_value) }}
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<!--noformat-->
|
|
||||||
<button class="ui button" type="submit">Create</button>
|
<button class="ui button" type="submit">Create</button>
|
||||||
</form>
|
</form>
|
||||||
|
<!--noformat-->
|
8
templates/admin/widgets/checkbox_toggle.jinja
Normal file
8
templates/admin/widgets/checkbox_toggle.jinja
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<div class="ui toggle checkbox">
|
||||||
|
<!--noformat-->
|
||||||
|
<input type="checkbox"
|
||||||
|
name="{{ field.name }}"
|
||||||
|
{% if field.value %}checked="checked" {% endif %}>
|
||||||
|
<label>{{field.label or field.name|capitalize}}</label>
|
||||||
|
<!--noformat-->
|
||||||
|
</div>
|
8
templates/admin/widgets/password_change.jinja
Normal file
8
templates/admin/widgets/password_change.jinja
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<div class="ui action input inline field">
|
||||||
|
<label>{{field.label or field.name|capitalize}}</label>
|
||||||
|
<input type="text" value="{{field.value}}" readonly="readonly">
|
||||||
|
<button class="ui teal right labeled icon button" hx-disable>
|
||||||
|
<i class="key icon"></i>
|
||||||
|
Set Password...
|
||||||
|
</button>
|
||||||
|
</div>
|
Loading…
Reference in New Issue
Block a user