first permission view page

This commit is contained in:
Thomas Weinhold 2025-12-31 18:07:01 +01:00
commit 86c18c29da
4 changed files with 106 additions and 3 deletions

22
rsc/css/league/about.css Normal file
View file

@ -0,0 +1,22 @@
table#AboutPermissionsTable {
text-align: center;
margin: 0 auto;
}
table#AboutPermissionsTable th {
background: transparent;
}
table#AboutPermissionsTable td {
background: transparent;
}
table#AboutPermissionsTable td.PermDenied {
background-color: var(--color-red);
}
table#AboutPermissionsTable td.PermGranted {
background-color: var(--color-green);
}

View file

@ -83,6 +83,7 @@ pub fn create_router(app_state: AppState) -> Router {
.route("/html/presets", routing::get(routes_html::presets::handler))
.route("/html/about/third_party", routing::get(routes_html::about::handler_third_party))
.route("/html/about/permissions", routing::get(routes_html::about::handler_permissions))
.merge(SwaggerUi::new("/api/v0/").url("/apidoc/openapi.json", api))
@ -325,7 +326,7 @@ impl HtmlTemplate {
html += " <div>";
html += " <a href=\"/html/about\">General</a>";
html += " <a href=\"/html/about/third_party\">Third Party Integrations</a>";
html += " <a href=\"/html/about/data_protection\">Data Protection</a>";
html += " <a href=\"/html/about/permissions\">Permission System</a>";
html += " <a href=\"/api/v0\">REST API v0</a>";
html += " </div>";
html += " </div>";

View file

@ -1,9 +1,12 @@
use axum::extract::State;
use axum::http::StatusCode;
use axum::response::Response;
use strum::IntoEnumIterator;
use crate::app_state::AppState;
use crate::http::HtmlTemplate;
use crate::http::http_user::HttpUserExtractor;
use crate::user_grade::Promotion;
use crate::user_permissions::PermissionContainer;
pub async fn handler_third_party(State(app_state): State<AppState>,
HttpUserExtractor(http_user): HttpUserExtractor,
@ -19,3 +22,80 @@ pub async fn handler_third_party(State(app_state): State<AppState>,
Ok(html.into_response().await)
}
pub async fn handler_permissions(State(app_state): State<AppState>,
HttpUserExtractor(http_user): HttpUserExtractor,
) -> Result<Response, StatusCode> {
let mut html = HtmlTemplate::new(http_user, app_state.clone());
html.include_css("/rsc/css/league/about.css");
// gather table data per column (not per row as usual)
let mut tbl_row_data: Vec<Vec<ColumnCache>> = Vec::new();
struct ColumnCache {
content: &'static str,
css_class: Option<&'static str>,
is_header: bool,
}
impl ColumnCache {
fn to_html(&self) -> String {
let tag = match self.is_header {true=>"th", false=>"td"};
match self.css_class {
None => format!("<{0}>{1}</{0}>", tag, self.content),
Some(css) => format!("<{0} class=\"{1}\">{2}</{0}>", tag, css, self.content)
}
}
}
// first column
let mut col_data : Vec<ColumnCache> = Vec::new();
col_data.push(ColumnCache {content: "", css_class: None, is_header:true});
tbl_row_data.push(col_data);
for perm_grp in PermissionContainer::new(Promotion::None).list_groups() {
let mut col_data : Vec<ColumnCache> = Vec::new();
col_data.push(ColumnCache {content: perm_grp.label(), css_class: None, is_header:true});
tbl_row_data.push(col_data);
for perm in perm_grp.list_permissions() {
let mut col_data : Vec<ColumnCache> = Vec::new();
col_data.push(ColumnCache {content: perm.label(), css_class: None, is_header:false});
tbl_row_data.push(col_data);
}
}
// promotion columns
for promo in Promotion::iter() {
let mut row_index = 0;
tbl_row_data[row_index].push(ColumnCache {content: promo.title_str(), css_class: None, is_header:true});
row_index += 1;
for perm_grp in PermissionContainer::new(promo).list_groups() {
tbl_row_data[row_index].push(ColumnCache {content: "", css_class: None, is_header:false});
row_index += 1;
for perm in perm_grp.list_permissions() {
let mut col_data : Vec<ColumnCache> = Vec::new();
let css_class: Option<&'static str> = Some(match perm.granted() {true=>"PermGranted", false=>"PermDenied"});
tbl_row_data[row_index].push(ColumnCache {content: " ", css_class, is_header:false});
row_index += 1;
}
}
}
// build table
html.push_body("<table id=\"AboutPermissionsTable\">");
for row in tbl_row_data {
html.push_body("<tr>");
for col in row {
html.push_body(&col.to_html());
}
html.push_body("</tr>");
}
html.push_body("</table>");
Ok(html.into_response().await)
}

View file

@ -1,13 +1,13 @@
use crate::user_grade::Promotion;
struct Permission {
pub struct Permission {
promotion_actual: Promotion,
promotion_min: Promotion,
label: &'static str,
}
impl Permission {
fn label(&self) -> &'static str { self.label }
pub fn label(&self) -> &'static str { self.label }
pub fn granted(&self) -> bool {
self.promotion_actual >= self.promotion_min