render_partial if hx-target header detected in req
This commit is contained in:
parent
e61b683baa
commit
88b11b6f89
@ -1,21 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "actix-admin-example"
|
|
||||||
description = "An admin interface for actix-web"
|
|
||||||
version = "0.4.0"
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
[[bin]]
|
|
||||||
name = "actix-admin-example"
|
|
||||||
path = "main.rs"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
actix-web = "^4.2.1"
|
|
||||||
actix-rt = "2.7.0"
|
|
||||||
actix-multipart = "^0.4.0"
|
|
||||||
sea-orm = { version = "^0.11.1", features = [ "sqlx-sqlite", "runtime-actix-native-tls", "macros" ], default-features = true }
|
|
||||||
chrono = "0.4.23"
|
|
||||||
tera = "^1.17.1"
|
|
||||||
serde = "^1.0.152"
|
|
||||||
serde_derive = "^1.0.152"
|
|
||||||
actix-admin = { version = "0.4.0", path = "../../" }
|
|
||||||
regex = "1.7.1"
|
|
@ -1,52 +0,0 @@
|
|||||||
use sea_orm::entity::prelude::*;
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use actix_admin::prelude::*;
|
|
||||||
use super::Post;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Deserialize, Serialize, DeriveActixAdmin, DeriveActixAdminModel, DeriveActixAdminViewModel)]
|
|
||||||
#[sea_orm(table_name = "comment")]
|
|
||||||
pub struct Model {
|
|
||||||
#[sea_orm(primary_key)]
|
|
||||||
#[serde(skip_deserializing)]
|
|
||||||
#[actix_admin(primary_key)]
|
|
||||||
pub id: i32,
|
|
||||||
pub comment: String,
|
|
||||||
#[sea_orm(column_type = "Text")]
|
|
||||||
#[actix_admin(html_input_type = "email", list_regex_mask= "^([a-zA-Z]*)")]
|
|
||||||
pub user: String,
|
|
||||||
#[sea_orm(column_type = "DateTime")]
|
|
||||||
pub insert_date: DateTime,
|
|
||||||
pub is_visible: bool,
|
|
||||||
#[actix_admin(select_list="Post")]
|
|
||||||
pub post_id: Option<i32>,
|
|
||||||
pub my_decimal: Decimal
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
|
||||||
pub enum Relation {
|
|
||||||
#[sea_orm(
|
|
||||||
belongs_to = "super::post::Entity",
|
|
||||||
from = "Column::PostId",
|
|
||||||
to = "super::post::Column::Id"
|
|
||||||
)]
|
|
||||||
Post,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Related<super::post::Entity> for Entity {
|
|
||||||
fn to() -> RelationDef {
|
|
||||||
Relation::Post.def()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ActiveModelBehavior for ActiveModel {}
|
|
||||||
|
|
||||||
impl ActixAdminModelValidationTrait<ActiveModel> for Entity {
|
|
||||||
fn validate(model: &ActiveModel) -> HashMap<String, String> {
|
|
||||||
let mut errors = HashMap::new();
|
|
||||||
if model.my_decimal.clone().unwrap() < Decimal::from(100 as i16) {
|
|
||||||
errors.insert("my_decimal".to_string(), "Must be larger than 100".to_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
errors
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,91 +0,0 @@
|
|||||||
// setup
|
|
||||||
use sea_orm::sea_query::{ForeignKeyCreateStatement, ColumnDef, TableCreateStatement};
|
|
||||||
use sea_orm::{Set, EntityTrait, error::*, sea_query, ConnectionTrait, DbConn, ExecResult};
|
|
||||||
pub mod comment;
|
|
||||||
pub mod post;
|
|
||||||
pub use comment::Entity as Comment;
|
|
||||||
pub use post::Entity as Post;
|
|
||||||
use chrono::{Local, Duration, DurationRound};
|
|
||||||
use sea_orm::prelude::Decimal;
|
|
||||||
|
|
||||||
// setup
|
|
||||||
async fn create_table(db: &DbConn, stmt: &TableCreateStatement) -> Result<ExecResult, DbErr> {
|
|
||||||
let builder = db.get_database_backend();
|
|
||||||
db.execute(builder.build(stmt)).await
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn create_post_table(db: &DbConn) -> Result<ExecResult, DbErr> {
|
|
||||||
let stmt = sea_query::Table::create()
|
|
||||||
.table(post::Entity)
|
|
||||||
.if_not_exists()
|
|
||||||
.col(
|
|
||||||
ColumnDef::new(post::Column::Id)
|
|
||||||
.integer()
|
|
||||||
.not_null()
|
|
||||||
.auto_increment()
|
|
||||||
.primary_key(),
|
|
||||||
)
|
|
||||||
.col(ColumnDef::new(post::Column::Title).string().not_null())
|
|
||||||
.col(ColumnDef::new(post::Column::Text).string().not_null())
|
|
||||||
.col(ColumnDef::new(post::Column::TeaMandatory).string().not_null())
|
|
||||||
.col(ColumnDef::new(post::Column::TeaOptional).string())
|
|
||||||
.col(ColumnDef::new(post::Column::InsertDate).date().not_null())
|
|
||||||
.col(ColumnDef::new(post::Column::Attachment).string())
|
|
||||||
.to_owned();
|
|
||||||
|
|
||||||
let _result = create_table(db, &stmt).await;
|
|
||||||
|
|
||||||
let stmt = sea_query::Table::create()
|
|
||||||
.table(comment::Entity)
|
|
||||||
.if_not_exists()
|
|
||||||
.col(
|
|
||||||
ColumnDef::new(post::Column::Id)
|
|
||||||
.integer()
|
|
||||||
.not_null()
|
|
||||||
.auto_increment()
|
|
||||||
.primary_key(),
|
|
||||||
)
|
|
||||||
.col(ColumnDef::new(comment::Column::Comment).string().not_null())
|
|
||||||
.col(ColumnDef::new(comment::Column::User).string().not_null())
|
|
||||||
.col(ColumnDef::new(comment::Column::InsertDate).date_time().not_null())
|
|
||||||
.col(ColumnDef::new(comment::Column::IsVisible).boolean().not_null())
|
|
||||||
.col(ColumnDef::new(comment::Column::MyDecimal).decimal().not_null())
|
|
||||||
.col(ColumnDef::new(comment::Column::PostId).integer())
|
|
||||||
.foreign_key(
|
|
||||||
ForeignKeyCreateStatement::new()
|
|
||||||
.name("fk-comment-post")
|
|
||||||
.from_tbl(Comment)
|
|
||||||
.from_col(comment::Column::PostId)
|
|
||||||
.to_tbl(Post)
|
|
||||||
.to_col(post::Column::Id),
|
|
||||||
)
|
|
||||||
.to_owned();
|
|
||||||
|
|
||||||
let res = create_table(db, &stmt).await;
|
|
||||||
|
|
||||||
for i in 1..1000 {
|
|
||||||
let row = post::ActiveModel {
|
|
||||||
title: Set(format!("Test {}", i)),
|
|
||||||
text: Set("some content".to_string()),
|
|
||||||
tea_mandatory: Set(post::Tea::EverydayTea),
|
|
||||||
tea_optional: Set(None),
|
|
||||||
insert_date: Set(Local::now().date_naive()),
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
let _res = Post::insert(row).exec(db).await;
|
|
||||||
}
|
|
||||||
|
|
||||||
for i in 1..1000 {
|
|
||||||
let row = comment::ActiveModel {
|
|
||||||
comment: Set(format!("Test {}", i)),
|
|
||||||
user: Set("me@home.com".to_string()),
|
|
||||||
my_decimal: Set(Decimal::new(105, 0)),
|
|
||||||
insert_date: Set(Local::now().naive_utc().duration_round(Duration::minutes(1)).unwrap()),
|
|
||||||
is_visible: Set(i%2 == 0),
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
let _res = Comment::insert(row).exec(db).await;
|
|
||||||
}
|
|
||||||
|
|
||||||
res
|
|
||||||
}
|
|
@ -1,74 +0,0 @@
|
|||||||
use sea_orm::entity::prelude::*;
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use actix_admin::prelude::*;
|
|
||||||
use std::fmt;
|
|
||||||
use std::fmt::Display;
|
|
||||||
use std::str::FromStr;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Deserialize, Serialize, DeriveActixAdmin, DeriveActixAdminViewModel, DeriveActixAdminModel, DeriveActixAdminModelSelectList)]
|
|
||||||
#[sea_orm(table_name = "post")]
|
|
||||||
pub struct Model {
|
|
||||||
#[sea_orm(primary_key)]
|
|
||||||
#[serde(skip_deserializing)]
|
|
||||||
#[actix_admin(primary_key)]
|
|
||||||
pub id: i32,
|
|
||||||
#[actix_admin(searchable, not_empty)]
|
|
||||||
pub title: String,
|
|
||||||
#[sea_orm(column_type = "Text")]
|
|
||||||
#[actix_admin(searchable, textarea, list_hide_column)]
|
|
||||||
pub text: String,
|
|
||||||
#[actix_admin(select_list="Tea")]
|
|
||||||
pub tea_mandatory: Tea,
|
|
||||||
#[actix_admin(select_list="Tea")]
|
|
||||||
pub tea_optional: Option<Tea>,
|
|
||||||
#[sea_orm(column_type = "Date")]
|
|
||||||
#[actix_admin(list_sort_position="1")]
|
|
||||||
pub insert_date: Date,
|
|
||||||
#[actix_admin(file_upload)]
|
|
||||||
pub attachment: Option<String>
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for Model {
|
|
||||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
match &*self {
|
|
||||||
_ => write!(formatter, "{} {}", &self.title, ""/* &self.insert_date*/),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
|
||||||
pub enum Relation {
|
|
||||||
#[sea_orm(has_many = "super::comment::Entity")]
|
|
||||||
Comment,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Related<super::comment::Entity> for Entity {
|
|
||||||
fn to() -> RelationDef {
|
|
||||||
Relation::Comment.def()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ActiveModelBehavior for ActiveModel {}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, EnumIter, DeriveActiveEnum, Deserialize, Serialize, DeriveActixAdminEnumSelectList)]
|
|
||||||
#[sea_orm(rs_type = "String", db_type = "Enum", enum_name = "tea")]
|
|
||||||
pub enum Tea {
|
|
||||||
#[sea_orm(string_value = "EverydayTea")]
|
|
||||||
EverydayTea,
|
|
||||||
#[sea_orm(string_value = "BreakfastTea")]
|
|
||||||
BreakfastTea,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FromStr for Tea {
|
|
||||||
type Err = ();
|
|
||||||
|
|
||||||
fn from_str(input: &str) -> Result<Tea, Self::Err> {
|
|
||||||
match input {
|
|
||||||
"EverydayTea" => Ok(Tea::EverydayTea),
|
|
||||||
"BreakfastTea" => Ok(Tea::BreakfastTea),
|
|
||||||
_ => Err(()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ActixAdminModelValidationTrait<ActiveModel> for Entity {}
|
|
@ -1,87 +0,0 @@
|
|||||||
extern crate serde_derive;
|
|
||||||
|
|
||||||
use actix_admin::prelude::*;
|
|
||||||
use actix_web::{web, App, HttpServer, middleware};
|
|
||||||
use sea_orm::{ConnectOptions, DatabaseConnection};
|
|
||||||
use std::time::Duration;
|
|
||||||
mod entity;
|
|
||||||
use entity::{Post, Comment};
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct AppState {
|
|
||||||
pub db: DatabaseConnection,
|
|
||||||
pub actix_admin: ActixAdmin,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ActixAdminAppDataTrait for AppState {
|
|
||||||
fn get_db(&self) -> &DatabaseConnection {
|
|
||||||
&self.db
|
|
||||||
}
|
|
||||||
fn get_actix_admin(&self) -> &ActixAdmin {
|
|
||||||
&self.actix_admin
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn create_actix_admin_builder() -> ActixAdminBuilder {
|
|
||||||
let configuration = ActixAdminConfiguration {
|
|
||||||
enable_auth: false,
|
|
||||||
user_is_logged_in: None,
|
|
||||||
login_link: None,
|
|
||||||
logout_link: None,
|
|
||||||
file_upload_directory: "./file_uploads"
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut admin_builder = ActixAdminBuilder::new(configuration);
|
|
||||||
|
|
||||||
|
|
||||||
let post_view_model = ActixAdminViewModel::from(Post);
|
|
||||||
admin_builder.add_entity::<AppState, Post>(&post_view_model);
|
|
||||||
|
|
||||||
let some_category = "Groupings";
|
|
||||||
let comment_view_model = ActixAdminViewModel::from(Comment);
|
|
||||||
admin_builder.add_entity_to_category::<AppState, Comment>(&comment_view_model, some_category);
|
|
||||||
|
|
||||||
admin_builder
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_db_options() -> ConnectOptions {
|
|
||||||
let db_url = "sqlite::memory:".to_string();
|
|
||||||
let mut opt = ConnectOptions::new(db_url);
|
|
||||||
opt.max_connections(100)
|
|
||||||
.min_connections(5)
|
|
||||||
.connect_timeout(Duration::from_secs(8))
|
|
||||||
.idle_timeout(Duration::from_secs(8))
|
|
||||||
.sqlx_logging(true);
|
|
||||||
opt
|
|
||||||
}
|
|
||||||
|
|
||||||
#[actix_rt::main]
|
|
||||||
async fn main() {
|
|
||||||
let opt = get_db_options();
|
|
||||||
let conn = sea_orm::Database::connect(opt).await.unwrap();
|
|
||||||
let _ = entity::create_post_table(&conn).await;
|
|
||||||
|
|
||||||
println!("The admin interface is available at http://localhost:5000/admin/");
|
|
||||||
|
|
||||||
HttpServer::new(move || {
|
|
||||||
|
|
||||||
let actix_admin_builder = create_actix_admin_builder();
|
|
||||||
|
|
||||||
let app_state = AppState {
|
|
||||||
db: conn.clone(),
|
|
||||||
actix_admin: actix_admin_builder.get_actix_admin(),
|
|
||||||
};
|
|
||||||
|
|
||||||
App::new()
|
|
||||||
.app_data(web::Data::new(app_state))
|
|
||||||
.service(
|
|
||||||
actix_admin_builder.get_scope::<AppState>()
|
|
||||||
)
|
|
||||||
.wrap(middleware::Logger::default())
|
|
||||||
})
|
|
||||||
.bind("127.0.0.1:5000")
|
|
||||||
.expect("Can not bind to port 5000")
|
|
||||||
.run()
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
@ -155,9 +155,6 @@ async fn main() {
|
|||||||
.expect("Invalid redirect URL"),
|
.expect("Invalid redirect URL"),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut tera = Tera::parse(concat!(env!("CARGO_MANIFEST_DIR"), "/templates/**/*")).unwrap();
|
|
||||||
tera.extend(&TERA).unwrap();
|
|
||||||
let _tera_res = tera.build_inheritance_chains();
|
|
||||||
|
|
||||||
let db_url = "sqlite::memory:".to_string();
|
let db_url = "sqlite::memory:".to_string();
|
||||||
let mut opt = ConnectOptions::new(db_url);
|
let mut opt = ConnectOptions::new(db_url);
|
||||||
@ -173,12 +170,17 @@ async fn main() {
|
|||||||
let cookie_secret_key = Key::generate();
|
let cookie_secret_key = Key::generate();
|
||||||
HttpServer::new(move || {
|
HttpServer::new(move || {
|
||||||
let actix_admin_builder = create_actix_admin_builder();
|
let actix_admin_builder = create_actix_admin_builder();
|
||||||
|
|
||||||
|
let actix_admin = actix_admin_builder.get_actix_admin();
|
||||||
|
let mut tera = Tera::parse(concat!(env!("CARGO_MANIFEST_DIR"), "/templates/**/*")).unwrap();
|
||||||
|
tera.extend(&actix_admin.tera).unwrap();
|
||||||
|
let _tera_res = tera.build_inheritance_chains();
|
||||||
|
|
||||||
let app_state = AppState {
|
let app_state = AppState {
|
||||||
oauth: client.clone(),
|
oauth: client.clone(),
|
||||||
tmpl: tera.clone(),
|
tmpl: tera.clone(),
|
||||||
db: conn.clone(),
|
db: conn.clone(),
|
||||||
actix_admin: actix_admin_builder.get_actix_admin(),
|
actix_admin: actix_admin,
|
||||||
};
|
};
|
||||||
|
|
||||||
App::new()
|
App::new()
|
||||||
|
@ -75,7 +75,7 @@ async fn create_or_edit_get<T: ActixAdminAppDataTrait, E: ActixAdminViewModelTra
|
|||||||
let entities_per_page = params
|
let entities_per_page = params
|
||||||
.entities_per_page
|
.entities_per_page
|
||||||
.unwrap_or(DEFAULT_ENTITIES_PER_PAGE);
|
.unwrap_or(DEFAULT_ENTITIES_PER_PAGE);
|
||||||
let render_partial = params.render_partial.unwrap_or(false);
|
let render_partial = req.headers().contains_key("HX-Target");
|
||||||
let search = params.search.clone().unwrap_or(String::new());
|
let search = params.search.clone().unwrap_or(String::new());
|
||||||
let sort_by = params.sort_by.clone().unwrap_or(view_model.primary_key.to_string());
|
let sort_by = params.sort_by.clone().unwrap_or(view_model.primary_key.to_string());
|
||||||
let sort_order = params.sort_order.as_ref().unwrap_or(&SortOrder::Asc);
|
let sort_order = params.sort_order.as_ref().unwrap_or(&SortOrder::Asc);
|
||||||
|
@ -107,7 +107,6 @@ pub async fn create_or_edit_post<T: ActixAdminAppDataTrait, E: ActixAdminViewMod
|
|||||||
let entities_per_page = params
|
let entities_per_page = params
|
||||||
.entities_per_page
|
.entities_per_page
|
||||||
.unwrap_or(DEFAULT_ENTITIES_PER_PAGE);
|
.unwrap_or(DEFAULT_ENTITIES_PER_PAGE);
|
||||||
let _render_partial = params.render_partial.unwrap_or(false);
|
|
||||||
let search = params.search.clone().unwrap_or(String::new());
|
let search = params.search.clone().unwrap_or(String::new());
|
||||||
let sort_by = params
|
let sort_by = params
|
||||||
.sort_by
|
.sort_by
|
||||||
@ -156,7 +155,7 @@ async fn render_form<E: ActixAdminViewModelTrait>(
|
|||||||
let entities_per_page = params
|
let entities_per_page = params
|
||||||
.entities_per_page
|
.entities_per_page
|
||||||
.unwrap_or(DEFAULT_ENTITIES_PER_PAGE);
|
.unwrap_or(DEFAULT_ENTITIES_PER_PAGE);
|
||||||
let render_partial = params.render_partial.unwrap_or(false);
|
let render_partial = req.headers().contains_key("HX-Target");
|
||||||
let search = params.search.clone().unwrap_or(String::new());
|
let search = params.search.clone().unwrap_or(String::new());
|
||||||
let sort_by = params
|
let sort_by = params
|
||||||
.sort_by
|
.sort_by
|
||||||
|
@ -129,7 +129,7 @@ pub async fn delete_many<T: ActixAdminAppDataTrait, E: ActixAdminViewModelTrait>
|
|||||||
true => Ok(HttpResponse::SeeOther()
|
true => Ok(HttpResponse::SeeOther()
|
||||||
.append_header((
|
.append_header((
|
||||||
header::LOCATION,
|
header::LOCATION,
|
||||||
format!("/admin/{}/list?render_partial=true&entities_per_page={}&search={}&sort_by={}&sort_order={}&page={}", entity_name, entities_per_page, search, sort_by, sort_order, page),
|
format!("/admin/{}/list?entities_per_page={}&search={}&sort_by={}&sort_order={}&page={}", entity_name, entities_per_page, search, sort_by, sort_order, page),
|
||||||
))
|
))
|
||||||
.finish()),
|
.finish()),
|
||||||
false => Ok(HttpResponse::InternalServerError().finish()),
|
false => Ok(HttpResponse::InternalServerError().finish()),
|
||||||
|
@ -71,7 +71,7 @@ pub async fn list<T: ActixAdminAppDataTrait, E: ActixAdminViewModelTrait>(
|
|||||||
let entities_per_page = params
|
let entities_per_page = params
|
||||||
.entities_per_page
|
.entities_per_page
|
||||||
.unwrap_or(DEFAULT_ENTITIES_PER_PAGE);
|
.unwrap_or(DEFAULT_ENTITIES_PER_PAGE);
|
||||||
let render_partial = params.render_partial.unwrap_or(false);
|
let render_partial = req.headers().contains_key("HX-Target");
|
||||||
let search = params.search.clone().unwrap_or(String::new());
|
let search = params.search.clone().unwrap_or(String::new());
|
||||||
|
|
||||||
let db = data.get_db();
|
let db = data.get_db();
|
||||||
|
@ -27,7 +27,6 @@ use serde::{Deserialize};
|
|||||||
pub struct Params {
|
pub struct Params {
|
||||||
page: Option<u64>,
|
page: Option<u64>,
|
||||||
entities_per_page: Option<u64>,
|
entities_per_page: Option<u64>,
|
||||||
render_partial: Option<bool>,
|
|
||||||
search: Option<String>,
|
search: Option<String>,
|
||||||
sort_by: Option<String>,
|
sort_by: Option<String>,
|
||||||
sort_order: Option<SortOrder>
|
sort_order: Option<SortOrder>
|
||||||
|
@ -47,7 +47,7 @@ pub async fn show<T: ActixAdminAppDataTrait, E: ActixAdminViewModelTrait>(sessio
|
|||||||
let entities_per_page = params
|
let entities_per_page = params
|
||||||
.entities_per_page
|
.entities_per_page
|
||||||
.unwrap_or(DEFAULT_ENTITIES_PER_PAGE);
|
.unwrap_or(DEFAULT_ENTITIES_PER_PAGE);
|
||||||
let render_partial = params.render_partial.unwrap_or(false);
|
let render_partial = req.headers().contains_key("HX-Target");
|
||||||
let search = params.search.clone().unwrap_or(String::new());
|
let search = params.search.clone().unwrap_or(String::new());
|
||||||
let sort_by = params.sort_by.clone().unwrap_or(view_model.primary_key.to_string());
|
let sort_by = params.sort_by.clone().unwrap_or(view_model.primary_key.to_string());
|
||||||
let sort_order = params.sort_order.as_ref().unwrap_or(&SortOrder::Asc);
|
let sort_order = params.sort_order.as_ref().unwrap_or(&SortOrder::Asc);
|
||||||
|
@ -38,8 +38,7 @@
|
|||||||
"entities_per_page" : "{{ entities_per_page }}",
|
"entities_per_page" : "{{ entities_per_page }}",
|
||||||
"search" : "{{ search }}",
|
"search" : "{{ search }}",
|
||||||
"sort_by" : "{{ sort_by }}",
|
"sort_by" : "{{ sort_by }}",
|
||||||
"sort_order" : "{{ sort_order }}",
|
"sort_order" : "{{ sort_order }}"
|
||||||
"render_partial" : "false",
|
|
||||||
"page" : "{{ page }}"
|
"page" : "{{ page }}"
|
||||||
}' hx-boost="true" hx-push-url="true" hx-indicator="#loading"
|
}' hx-boost="true" hx-push-url="true" hx-indicator="#loading"
|
||||||
class="button is-link is-light" href="{{ base_path }}/list">
|
class="button is-link is-light" href="{{ base_path }}/list">
|
||||||
|
@ -29,8 +29,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<form id="search_form" action="/admin/{{ entity_name }}/list" hx-boost="true" hx-indicator="#loading"
|
<form id="search_form" action="/admin/{{ entity_name }}/list" hx-boost="true" hx-indicator="#loading"
|
||||||
hx-target="#{{ entity_name }}table" hx-trigger="reload_table from:#entities_per_page"
|
hx-target="#{{ entity_name }}table" hx-trigger="reload_table from:#entities_per_page">
|
||||||
hx-vals='{ "render_partial" : "true" }'>
|
|
||||||
<input type="hidden" id="sort_by" name="sort_by" value="{{ sort_by }}">
|
<input type="hidden" id="sort_by" name="sort_by" value="{{ sort_by }}">
|
||||||
<input type="hidden" id="sort_order" name="sort_order" value="{{ sort_order }}">
|
<input type="hidden" id="sort_order" name="sort_order" value="{{ sort_order }}">
|
||||||
<div class="column is-narrow">
|
<div class="column is-narrow">
|
||||||
@ -66,7 +65,7 @@
|
|||||||
<div class="is-relative">
|
<div class="is-relative">
|
||||||
{% include "loader.html" %}
|
{% include "loader.html" %}
|
||||||
<form id="table_form" hx-indicator="#loading" hx-get="/admin/{{ entity_name }}/list"
|
<form id="table_form" hx-indicator="#loading" hx-get="/admin/{{ entity_name }}/list"
|
||||||
hx-vals='{ "render_partial" : "true" }' hx-target="#{{ entity_name }}table">
|
hx-target="#{{ entity_name }}table">
|
||||||
<input type="hidden" id="sort_by" name="sort_by" value="{{ sort_by }}">
|
<input type="hidden" id="sort_by" name="sort_by" value="{{ sort_by }}">
|
||||||
<input type="hidden" id="sort_order" name="sort_order" value="{{ sort_order }}">
|
<input type="hidden" id="sort_order" name="sort_order" value="{{ sort_order }}">
|
||||||
<input type="hidden" name="entities_per_page" value="{{ entities_per_page }}">
|
<input type="hidden" name="entities_per_page" value="{{ entities_per_page }}">
|
||||||
@ -118,8 +117,7 @@
|
|||||||
"entities_per_page" : "{{ entities_per_page }}",
|
"entities_per_page" : "{{ entities_per_page }}",
|
||||||
"search" : "{{ search }}",
|
"search" : "{{ search }}",
|
||||||
"sort_by" : "{{ sort_by }}",
|
"sort_by" : "{{ sort_by }}",
|
||||||
"sort_order" : "{{ sort_order }}",
|
"sort_order" : "{{ sort_order }}"
|
||||||
"render_partial" : "true"
|
|
||||||
}' hx-target="#content">
|
}' hx-target="#content">
|
||||||
<i class="fa-solid fa-magnifying-glass"></i> {{ entity.primary_key }}
|
<i class="fa-solid fa-magnifying-glass"></i> {{ entity.primary_key }}
|
||||||
</a>
|
</a>
|
||||||
@ -142,8 +140,7 @@
|
|||||||
"entities_per_page" : "{{ entities_per_page }}",
|
"entities_per_page" : "{{ entities_per_page }}",
|
||||||
"search" : "{{ search }}",
|
"search" : "{{ search }}",
|
||||||
"sort_by" : "{{ sort_by }}",
|
"sort_by" : "{{ sort_by }}",
|
||||||
"sort_order" : "{{ sort_order }}",
|
"sort_order" : "{{ sort_order }}"
|
||||||
"render_partial" : "false"
|
|
||||||
}'>
|
}'>
|
||||||
<i class="fa-solid fa-pen-to-square"></i>
|
<i class="fa-solid fa-pen-to-square"></i>
|
||||||
</a>
|
</a>
|
||||||
@ -167,8 +164,7 @@
|
|||||||
"entities_per_page" : "{{ entities_per_page }}",
|
"entities_per_page" : "{{ entities_per_page }}",
|
||||||
"search" : "{{ search }}",
|
"search" : "{{ search }}",
|
||||||
"sort_by" : "{{ sort_by }}",
|
"sort_by" : "{{ sort_by }}",
|
||||||
"sort_order" : "{{ sort_order }}",
|
"sort_order" : "{{ sort_order }}"
|
||||||
"render_partial" : "true"
|
|
||||||
}' hx-indicator="#loading" class="pagination is-rounded is-centered" role="pagination" aria-label="pagination">
|
}' hx-indicator="#loading" class="pagination is-rounded is-centered" role="pagination" aria-label="pagination">
|
||||||
{% if page > 1 %}
|
{% if page > 1 %}
|
||||||
<a href="?&page={{ page - 1 }}" class="pagination-previous left-arrow-click"><i
|
<a href="?&page={{ page - 1 }}" class="pagination-previous left-arrow-click"><i
|
||||||
@ -204,8 +200,4 @@
|
|||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if not render_partial or render_partial == false %}
|
|
||||||
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% endblock content %}
|
{% endblock content %}
|
@ -26,8 +26,7 @@
|
|||||||
"entities_per_page" : "{{ entities_per_page }}",
|
"entities_per_page" : "{{ entities_per_page }}",
|
||||||
"search" : "{{ search }}",
|
"search" : "{{ search }}",
|
||||||
"sort_by" : "{{ sort_by }}",
|
"sort_by" : "{{ sort_by }}",
|
||||||
"sort_order" : "{{ sort_order }}",
|
"sort_order" : "{{ sort_order }}"
|
||||||
"render_partial" : "false",
|
|
||||||
"page" : "{{ page }}"
|
"page" : "{{ page }}"
|
||||||
}' hx-boost="true" hx-push-url="true" hx-indicator="#loading"
|
}' hx-boost="true" hx-push-url="true" hx-indicator="#loading"
|
||||||
class="button is-link is-light" href="{{ base_path }}/list">Back</a>
|
class="button is-link is-light" href="{{ base_path }}/list">Back</a>
|
||||||
|
Loading…
Reference in New Issue
Block a user