diff --git a/rsc/css/league/about.css b/rsc/css/league/about.css
new file mode 100644
index 0000000..e020c15
--- /dev/null
+++ b/rsc/css/league/about.css
@@ -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);
+}
\ No newline at end of file
diff --git a/sslo_league/src/http.rs b/sslo_league/src/http.rs
index 7db298a..42b6d3d 100644
--- a/sslo_league/src/http.rs
+++ b/sslo_league/src/http.rs
@@ -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 += "
";
html += " ";
diff --git a/sslo_league/src/http/routes_html/about.rs b/sslo_league/src/http/routes_html/about.rs
index f519c74..22e1090 100644
--- a/sslo_league/src/http/routes_html/about.rs
+++ b/sslo_league/src/http/routes_html/about.rs
@@ -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,
HttpUserExtractor(http_user): HttpUserExtractor,
@@ -19,3 +22,80 @@ pub async fn handler_third_party(State(app_state): State,
Ok(html.into_response().await)
}
+
+
+pub async fn handler_permissions(State(app_state): State,
+ HttpUserExtractor(http_user): HttpUserExtractor,
+) -> Result {
+ 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::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 = 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 = 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 = 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 = 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("");
+ for row in tbl_row_data {
+ html.push_body("");
+ for col in row {
+ html.push_body(&col.to_html());
+ }
+ html.push_body("
");
+ }
+ html.push_body("
");
+
+
+ Ok(html.into_response().await)
+}
\ No newline at end of file
diff --git a/sslo_league/src/user_permissions.rs b/sslo_league/src/user_permissions.rs
index f8df92f..a164b72 100644
--- a/sslo_league/src/user_permissions.rs
+++ b/sslo_league/src/user_permissions.rs
@@ -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