actix-admin 0.8.0

An admin interface for actix-web
Documentation
use actix_web::{error, web, Error, HttpRequest, HttpResponse};
use sea_orm::DatabaseConnection;
use tera::Context;
use actix_session::Session;
use crate::ActixAdminError;
use crate::ActixAdminNotification;
use crate::prelude::*;

use super::helpers::add_default_context;
use super::helpers::SearchParams;
use super::Params;
use super::{ add_auth_context, user_can_access_page, render_unauthorized};

pub async fn create_get<E: ActixAdminViewModelTrait>(
    session: Session,
    req: HttpRequest,
    data: web::Data<ActixAdmin>,
    db: web::Data<DatabaseConnection>,
    _body: web::Payload,
    _text: String,
) -> Result<HttpResponse, Error> {
    let db = db.get_ref();
    let model = ActixAdminModel::create_empty();
    
    create_or_edit_get::<E>(&session, req, &data, db, Ok(model), false).await
}

pub async fn edit_get<E: ActixAdminViewModelTrait>(
    session: Session,
    req: HttpRequest,
    data: web::Data<ActixAdmin>,
    db: web::Data<DatabaseConnection>,
    _text: String,
    id: web::Path<i32>
) -> Result<HttpResponse, Error> {
    let db = db.get_ref();
    let actix_admin = &data.get_ref();
    let tenant_ref = actix_admin
        .configuration
        .user_tenant_ref
        .map_or(None, |f| f(&session));

    let model = E::get_entity(db, id.into_inner(), tenant_ref).await;
    let entity_name = E::get_entity_name();
    let view_model = actix_admin.view_models.get(&entity_name).unwrap();

    create_or_edit_get::<E>(&session, req, &data, db, model, view_model.inline_edit).await
}

async fn create_or_edit_get<E: ActixAdminViewModelTrait>(session: &Session, req: HttpRequest, data: &web::Data<ActixAdmin>, db: &sea_orm::DatabaseConnection, model_result: Result<ActixAdminModel, ActixAdminError>, is_inline: bool) -> Result<HttpResponse, Error>{
    let actix_admin = &data.get_ref();
    let mut ctx = Context::new();
    add_auth_context(&session, actix_admin, &mut ctx);
    let entity_name = E::get_entity_name();
    let mut errors: Vec<crate::ActixAdminError> = Vec::new();

    let view_model = actix_admin.view_models.get(&entity_name).unwrap();

    if !user_can_access_page(&session, actix_admin, view_model) {
        return render_unauthorized(&ctx, &actix_admin);
    }

    let model;
    match model_result {
        Ok(res) => {
            model = res;
        },
        Err(e) => {
            errors.push(e);
            model = ActixAdminModel::create_empty();
        }
    }

    let mut http_response_code = match errors.is_empty() {
        true => HttpResponse::Ok(),
        false => HttpResponse::InternalServerError(),
    };    
    let notifications: Vec<ActixAdminNotification> = errors.into_iter()
        .map(|err| ActixAdminNotification::from(err))
        .collect();

    let params = web::Query::<Params>::from_query(req.query_string()).unwrap();

    let search_params = SearchParams::from_params(&params, view_model);
    add_default_context(&mut ctx, req, view_model, entity_name, actix_admin, notifications, &search_params);

    let tenant_ref = actix_admin
        .configuration
        .user_tenant_ref
        .map_or(None, |f| f(&session));

    ctx.insert("view_model", &ActixAdminViewModelSerializable::from(view_model.clone()));
    ctx.insert("select_lists", &E::get_select_lists(db, tenant_ref).await?);
    ctx.insert("model", &model);
    
    let template_path = match is_inline {
        true => "create_or_edit/inline.html",
        false => "create_or_edit.html",
    };
    let body = actix_admin.tera
        .render(template_path, &ctx)
        .map_err(|err| error::ErrorInternalServerError(err))?;
    Ok(http_response_code.content_type("text/html").body(body))
}