From 574ee62092072e6caa3669678ef32961d0d812d4 Mon Sep 17 00:00:00 2001 From: Philippe Loctaux Date: Thu, 30 Mar 2023 00:55:45 +0200 Subject: [PATCH] ezidam: added admin/apps listing --- crates/ezidam/src/menu/icons.rs | 1 + crates/ezidam/src/menu/items/admin.rs | 9 ++ crates/ezidam/src/page.rs | 5 + crates/ezidam/src/routes/admin.rs | 12 ++ crates/ezidam/src/routes/admin/apps.rs | 13 ++ crates/ezidam/static/libs/list.js/list.min.js | 2 + .../templates/pages/admin/apps/list.html.tera | 124 ++++++++++++++++++ 7 files changed, 166 insertions(+) create mode 100644 crates/ezidam/src/routes/admin/apps.rs create mode 100644 crates/ezidam/static/libs/list.js/list.min.js create mode 100644 crates/ezidam/templates/pages/admin/apps/list.html.tera diff --git a/crates/ezidam/src/menu/icons.rs b/crates/ezidam/src/menu/icons.rs index cd129f1..897ff83 100644 --- a/crates/ezidam/src/menu/icons.rs +++ b/crates/ezidam/src/menu/icons.rs @@ -2,3 +2,4 @@ pub const HOME: &str = r#""#; pub const LOGOUT: &str = r#""#; pub const SETTINGS: &str = r#""#; +pub const APPS: &str = r#"svg>"#; diff --git a/crates/ezidam/src/menu/items/admin.rs b/crates/ezidam/src/menu/items/admin.rs index f0311b2..47c9be8 100644 --- a/crates/ezidam/src/menu/items/admin.rs +++ b/crates/ezidam/src/menu/items/admin.rs @@ -5,6 +5,7 @@ use rocket::uri; pub enum AdminMenu { Exit, Dashboard, + Apps, Settings, } @@ -13,6 +14,7 @@ impl AdminMenu { match self { AdminMenu::Exit => "exit", AdminMenu::Dashboard => "dashboard", + AdminMenu::Apps => "apps", AdminMenu::Settings => "settings", } } @@ -32,6 +34,13 @@ impl AdminMenu { icon: icons::HOME, sub: None, }, + MainItem { + id: AdminMenu::Apps.id(), + label: "Applications", + link: uri!(routes::admin::apps::admin_apps).to_string(), + icon: icons::APPS, + sub: None, + }, MainItem { id: AdminMenu::Settings.id(), label: "Server settings", diff --git a/crates/ezidam/src/page.rs b/crates/ezidam/src/page.rs index 6a24aaf..8a57a09 100644 --- a/crates/ezidam/src/page.rs +++ b/crates/ezidam/src/page.rs @@ -17,6 +17,7 @@ pub enum Page { AdminDashboard(AdminDashboard), AdminSettingsBranding(AdminSettingsBranding), AdminSettingsSecurity(AdminSettingsSecurity), + AdminApps(AdminApps), } impl Page { @@ -31,6 +32,7 @@ impl Page { Page::AdminDashboard(_) => "pages/admin/dashboard", Page::AdminSettingsBranding(_) => "pages/admin/settings/branding", Page::AdminSettingsSecurity(_) => "pages/admin/settings/security", + Page::AdminApps(_) => "pages/admin/apps/list", } } @@ -45,6 +47,7 @@ impl Page { Page::AdminDashboard(_) => "Admin dashboard", Page::AdminSettingsBranding(_) => "Server branding", Page::AdminSettingsSecurity(_) => "Server security", + Page::AdminApps(_) => "Applications", } } @@ -61,6 +64,7 @@ impl Page { Page::AdminDashboard(_) => Some(AdminMenu::Dashboard.into()), Page::AdminSettingsBranding(_) => Some(AdminMenu::Settings.into()), Page::AdminSettingsSecurity(_) => Some(AdminMenu::Settings.into()), + Page::AdminApps(_) => Some(AdminMenu::Apps.into()), } } @@ -75,6 +79,7 @@ impl Page { Page::AdminDashboard(dashboard) => Box::new(dashboard), Page::AdminSettingsBranding(branding) => Box::new(branding), Page::AdminSettingsSecurity(security) => Box::new(security), + Page::AdminApps(apps) => Box::new(apps), } } } diff --git a/crates/ezidam/src/routes/admin.rs b/crates/ezidam/src/routes/admin.rs index 25c9c5f..5575e9a 100644 --- a/crates/ezidam/src/routes/admin.rs +++ b/crates/ezidam/src/routes/admin.rs @@ -1,7 +1,9 @@ +use self::apps::*; use self::settings::*; use dashboard::*; use rocket::{routes, Route}; +pub mod apps; pub mod dashboard; pub mod settings; @@ -12,10 +14,12 @@ pub fn routes() -> Vec { settings_update_branding, settings_security, settings_security_form, + admin_apps, ] } pub mod content { + use apps::App; use jwt::JwtClaims; use rocket::serde::Serialize; @@ -40,4 +44,12 @@ pub mod content { pub struct AdminSettingsSecurity { pub user: JwtClaims, } + + #[derive(Serialize)] + #[serde(crate = "rocket::serde")] + #[derive(Clone)] + pub struct AdminApps { + pub user: JwtClaims, + pub apps: Vec, + } } diff --git a/crates/ezidam/src/routes/admin/apps.rs b/crates/ezidam/src/routes/admin/apps.rs new file mode 100644 index 0000000..e6c8484 --- /dev/null +++ b/crates/ezidam/src/routes/admin/apps.rs @@ -0,0 +1,13 @@ +use crate::routes::prelude::*; +use apps::App; +use rocket::get; + +#[get("/admin/apps")] +pub async fn admin_apps(mut db: Connection, admin: JwtAdmin) -> Result { + let list = App::get_all(&mut *db, None).await?; + + Ok(Page::AdminApps(super::content::AdminApps { + user: admin.0, + apps: list, + })) +} diff --git a/crates/ezidam/static/libs/list.js/list.min.js b/crates/ezidam/static/libs/list.js/list.min.js new file mode 100644 index 0000000..8131881 --- /dev/null +++ b/crates/ezidam/static/libs/list.js/list.min.js @@ -0,0 +1,2 @@ +var List;List=function(){var t={"./src/add-async.js":function(t){t.exports=function(t){return function e(r,n,s){var i=r.splice(0,50);s=(s=s||[]).concat(t.add(i)),r.length>0?setTimeout((function(){e(r,n,s)}),1):(t.update(),n(s))}}},"./src/filter.js":function(t){t.exports=function(t){return t.handlers.filterStart=t.handlers.filterStart||[],t.handlers.filterComplete=t.handlers.filterComplete||[],function(e){if(t.trigger("filterStart"),t.i=1,t.reset.filter(),void 0===e)t.filtered=!1;else{t.filtered=!0;for(var r=t.items,n=0,s=r.length;nv.page,a=new g(t[s],void 0,n),v.items.push(a),r.push(a)}return v.update(),r}m(t.slice(0),e)}},this.show=function(t,e){return this.i=t,this.page=e,v.update(),v},this.remove=function(t,e,r){for(var n=0,s=0,i=v.items.length;s-1&&r.splice(n,1),v},this.trigger=function(t){for(var e=v.handlers[t].length;e--;)v.handlers[t][e](v);return v},this.reset={filter:function(){for(var t=v.items,e=t.length;e--;)t[e].filtered=!1;return v},search:function(){for(var t=v.items,e=t.length;e--;)t[e].found=!1;return v}},this.update=function(){var t=v.items,e=t.length;v.visibleItems=[],v.matchingItems=[],v.templater.clear();for(var r=0;r=v.i&&v.visibleItems.lengthe},innerWindow:function(t,e,r){return t>=e-r&&t<=e+r},dotted:function(t,e,r,n,s,i,a){return this.dottedLeft(t,e,r,n,s,i)||this.dottedRight(t,e,r,n,s,i,a)},dottedLeft:function(t,e,r,n,s,i){return e==r+1&&!this.innerWindow(e,s,i)&&!this.right(e,n)},dottedRight:function(t,e,r,n,s,i,a){return!t.items[a-1].values().dotted&&(e==n&&!this.innerWindow(e,s,i)&&!this.right(e,n))}};return function(e){var n=new i(t.listContainer.id,{listClass:e.paginationClass||"pagination",item:e.item||"
  • ",valueNames:["page","dotted"],searchClass:"pagination-search-that-is-not-supposed-to-exist",sortClass:"pagination-sort-that-is-not-supposed-to-exist"});s.bind(n.listContainer,"click",(function(e){var r=e.target||e.srcElement,n=t.utils.getAttribute(r,"data-page"),s=t.utils.getAttribute(r,"data-i");s&&t.show((s-1)*n+1,n)})),t.on("updated",(function(){r(n,e)})),r(n,e)}}},"./src/parse.js":function(t,e,r){t.exports=function(t){var e=r("./src/item.js")(t),n=function(r,n){for(var s=0,i=r.length;s0?setTimeout((function(){e(r,s)}),1):(t.update(),t.trigger("parseComplete"))};return t.handlers.parseComplete=t.handlers.parseComplete||[],function(){var e=function(t){for(var e=t.childNodes,r=[],n=0,s=e.length;n]/g.exec(t)){var e=document.createElement("tbody");return e.innerHTML=t,e.firstElementChild}if(-1!==t.indexOf("<")){var r=document.createElement("div");return r.innerHTML=t,r.firstElementChild}}},a=function(e,r,n){var s=void 0,i=function(e){for(var r=0,n=t.valueNames.length;r=1;)t.list.removeChild(t.list.firstChild)},function(){var r;if("function"!=typeof t.item){if(!(r="string"==typeof t.item?-1===t.item.indexOf("<")?document.getElementById(t.item):i(t.item):s()))throw new Error("The list needs to have at least one item on init otherwise you'll have to add a template.");r=n(r,t.valueNames),e=function(){return r.cloneNode(!0)}}else e=function(e){var r=t.item(e);return i(r)}}()};t.exports=function(t){return new e(t)}},"./src/utils/classes.js":function(t,e,r){var n=r("./src/utils/index-of.js"),s=/\s+/;Object.prototype.toString;function i(t){if(!t||!t.nodeType)throw new Error("A DOM element reference is required");this.el=t,this.list=t.classList}t.exports=function(t){return new i(t)},i.prototype.add=function(t){if(this.list)return this.list.add(t),this;var e=this.array();return~n(e,t)||e.push(t),this.el.className=e.join(" "),this},i.prototype.remove=function(t){if(this.list)return this.list.remove(t),this;var e=this.array(),r=n(e,t);return~r&&e.splice(r,1),this.el.className=e.join(" "),this},i.prototype.toggle=function(t,e){return this.list?(void 0!==e?e!==this.list.toggle(t,e)&&this.list.toggle(t):this.list.toggle(t),this):(void 0!==e?e?this.add(t):this.remove(t):this.has(t)?this.remove(t):this.add(t),this)},i.prototype.array=function(){var t=(this.el.getAttribute("class")||"").replace(/^\s+|\s+$/g,"").split(s);return""===t[0]&&t.shift(),t},i.prototype.has=i.prototype.contains=function(t){return this.list?this.list.contains(t):!!~n(this.array(),t)}},"./src/utils/events.js":function(t,e,r){var n=window.addEventListener?"addEventListener":"attachEvent",s=window.removeEventListener?"removeEventListener":"detachEvent",i="addEventListener"!==n?"on":"",a=r("./src/utils/to-array.js");e.bind=function(t,e,r,s){for(var o=0,l=(t=a(t)).length;o32)return!1;var a=n,o=function(){var t,r={};for(t=0;t=p;b--){var j=o[t.charAt(b-1)];if(C[b]=0===m?(C[b+1]<<1|1)&j:(C[b+1]<<1|1)&j|(v[b+1]|v[b])<<1|1|v[b+1],C[b]&d){var x=l(m,b-1);if(x<=u){if(u=x,!((c=b-1)>a))break;p=Math.max(1,2*a-c)}}}if(l(m+1,a)>u)break;v=C}return!(c<0)}},"./src/utils/get-attribute.js":function(t){t.exports=function(t,e){var r=t.getAttribute&&t.getAttribute(e)||null;if(!r)for(var n=t.attributes,s=n.length,i=0;i=48&&t<=57}function i(t,e){for(var i=(t+="").length,a=(e+="").length,o=0,l=0;o=i&&l=a?-1:l>=a&&o=i?1:i-a}i.caseInsensitive=i.i=function(t,e){return i((""+t).toLowerCase(),(""+e).toLowerCase())},Object.defineProperties(i,{alphabet:{get:function(){return e},set:function(t){r=[];var s=0;if(e=t)for(;s +
    +
    +
    +
    + Admin dashboard +
    +

    + Applications +

    +
    +
    +
    + {% set primary_action = "New application" %} + + + + + + + + {{ primary_action }} + + + + + + + + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + {% for app in apps %} + + + + + + + + + {% endfor %} + + +
    + + + + + + + + + + + Actions +
    {{ app.label }} + {% if app.is_archived == true %} + Archived + {% else %} + Active + {% endif %} + + {{ app.created_at | date() }} + {{ app.id }}{{ app.redirect_uri }} + Details +
    +
    +
    +
    +
    +{% endblock content %} + +{% block libs_js %} + +{% endblock lib_js %} + +{% block additional_js %} + +{% endblock additional_js %}