1use actix_session::Session;
8use actix_web::{
9 error,
10 http::{header::ContentType, StatusCode},
11 HttpResponse,
12};
13use async_trait::async_trait;
14use derive_more::{Display, Error};
15use sea_orm::DatabaseConnection;
16use serde_derive::Serialize;
17use std::{collections::HashMap, fmt};
18use tera::Tera;
19
20pub mod builder;
21pub mod model;
22pub mod routes;
23pub mod tera_templates;
24pub mod view_model;
25
26pub mod prelude {
27 pub use crate::builder::{ActixAdminBuilder, ActixAdminBuilderTrait};
28 pub use crate::model::{
29 ActixAdminModel, ActixAdminModelFilter, ActixAdminModelFilterTrait,
30 ActixAdminModelFilterType, ActixAdminModelTrait, ActixAdminModelValidationTrait,
31 };
32 pub use crate::routes::{create_or_edit_post, get_admin_ctx, SortOrder};
33 pub use crate::view_model::{
34 ActixAdminViewModel, ActixAdminViewModelField, ActixAdminViewModelFieldType,
35 ActixAdminViewModelFilter, ActixAdminViewModelParams, ActixAdminViewModelSerializable,
36 ActixAdminViewModelTrait,
37 };
38 pub use crate::{hashmap, ActixAdminSelectListTrait};
39 pub use crate::{ActixAdmin, ActixAdminConfiguration, ActixAdminError, ActixAdminErrorType};
40 pub use actix_admin_macros::{
41 DeriveActixAdmin, DeriveActixAdminEnumSelectList, DeriveActixAdminModel,
42 DeriveActixAdminModelSelectList, DeriveActixAdminViewModel,
43 };
44 pub use actix_session::Session;
45 pub use async_trait::async_trait;
46 pub use lazy_static::lazy_static;
47}
48
49use crate::prelude::*;
50
51#[macro_export]
52macro_rules! hashmap {
53 ($( $key: expr => $val: expr ),*) => {{
54 let mut map = ::std::collections::HashMap::new();
55 $( map.insert($key.to_string(), $val); )*
56 map
57 }}
58}
59
60#[async_trait]
62pub trait ActixAdminSelectListTrait {
63 async fn get_key_value(
64 db: &DatabaseConnection,
65 tenant_ref: Option<i32>
66 ) -> core::result::Result<Vec<(String, String)>, ActixAdminError>;
67}
68
69#[derive(Clone)]
70pub struct ActixAdminConfiguration {
71 pub enable_auth: bool,
72 pub user_is_logged_in: Option<for<'a> fn(&'a Session) -> bool>,
73 pub user_tenant_ref: Option<for<'a> fn(&'a Session) -> Option<i32>>,
74 pub login_link: Option<String>,
75 pub logout_link: Option<String>,
76 pub file_upload_directory: &'static str,
77 pub navbar_title: &'static str,
78 pub base_path: &'static str,
79 pub custom_css_paths: Option<Vec<String>>,
80 pub custom_js_paths: Option<Vec<String>>
81}
82
83#[derive(Clone)]
84pub struct ActixAdmin {
85 pub entity_names: HashMap<String, Vec<ActixAdminMenuElement>>,
86 pub view_models: HashMap<String, ActixAdminViewModel>,
87 pub card_grids: HashMap<String, Vec<Vec<String>>>,
88 pub configuration: ActixAdminConfiguration,
89 pub tera: Tera,
90 pub support_path: Option<String>
91}
92
93#[derive(PartialEq, Eq, Clone, Serialize)]
94pub struct ActixAdminMenuElement {
95 pub name: String,
96 pub link: String,
97 pub is_custom_handler: bool,
98}
99
100#[derive(Debug, Error)]
101pub struct ActixAdminError {
102 pub ty: ActixAdminErrorType,
103 pub msg: String,
104}
105
106impl Display for ActixAdminError {
107 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
108 match &*self {
109 _ => write!(formatter, "{}: {}", &self.ty, &self.msg),
110 }
111 }
112}
113
114#[derive(Debug, Display, Error)]
116pub enum ActixAdminErrorType {
117 #[display("Internal error")]
118 InternalError,
119
120 #[display("Form has validation errors")]
121 ValidationErrors,
122
123 #[display("Could not list entities")]
124 ListError,
125
126 #[display("Could not create entity")]
127 CreateError,
128
129 #[display("Could not delete entity")]
130 DeleteError,
131
132 #[display("Could not edit entity")]
133 EditError,
134
135 #[display("Database error")]
136 DatabaseError,
137
138 #[display("Entity does not exist")]
139 EntityDoesNotExistError,
140}
141
142impl error::ResponseError for ActixAdminError {
143 fn error_response(&self) -> HttpResponse {
144 HttpResponse::build(self.status_code())
145 .insert_header(ContentType::html())
146 .body(self.to_string())
147 }
148
149 fn status_code(&self) -> StatusCode {
150 match *self {
151 _ => StatusCode::INTERNAL_SERVER_ERROR,
152 }
153 }
154}
155
156impl std::convert::From<sea_orm::DbErr> for ActixAdminError {
157 fn from(err: sea_orm::DbErr) -> ActixAdminError {
158 ActixAdminError {
159 ty: ActixAdminErrorType::DatabaseError,
160 msg: err.to_string(),
161 }
162 }
163}
164
165#[derive(Debug, Display, Serialize)]
167pub enum ActixAdminNotificationType {
168 #[display("is-danger")]
169 Danger,
170}
171
172#[derive(Debug, Serialize)]
173pub struct ActixAdminNotification {
174 css_class: String,
175 message: String,
176}
177
178impl std::convert::From<ActixAdminError> for ActixAdminNotification {
179 fn from(e: ActixAdminError) -> ActixAdminNotification {
180 ActixAdminNotification {
181 css_class: ActixAdminNotificationType::Danger.to_string(),
182 message: e.to_string(),
183 }
184 }
185}