ezidam: added admin/apps listing
This commit is contained in:
parent
e2a7d7625e
commit
574ee62092
7 changed files with 166 additions and 0 deletions
|
|
@ -2,3 +2,4 @@
|
||||||
pub const HOME: &str = r#"<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-home" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M5 12l-2 0l9 -9l9 9l-2 0"></path><path d="M5 12v7a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-7"></path><path d="M9 21v-6a2 2 0 0 1 2 -2h2a2 2 0 0 1 2 2v6"></path></svg>"#;
|
pub const HOME: &str = r#"<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-home" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M5 12l-2 0l9 -9l9 9l-2 0"></path><path d="M5 12v7a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-7"></path><path d="M9 21v-6a2 2 0 0 1 2 -2h2a2 2 0 0 1 2 2v6"></path></svg>"#;
|
||||||
pub const LOGOUT: &str = r#"<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-logout" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M14 8v-2a2 2 0 0 0 -2 -2h-7a2 2 0 0 0 -2 2v12a2 2 0 0 0 2 2h7a2 2 0 0 0 2 -2v-2"></path><path d="M7 12h14l-3 -3m0 6l3 -3"></path></svg>"#;
|
pub const LOGOUT: &str = r#"<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-logout" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M14 8v-2a2 2 0 0 0 -2 -2h-7a2 2 0 0 0 -2 2v12a2 2 0 0 0 2 2h7a2 2 0 0 0 2 -2v-2"></path><path d="M7 12h14l-3 -3m0 6l3 -3"></path></svg>"#;
|
||||||
pub const SETTINGS: &str = r#"<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-settings" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M10.325 4.317c.426 -1.756 2.924 -1.756 3.35 0a1.724 1.724 0 0 0 2.573 1.066c1.543 -.94 3.31 .826 2.37 2.37a1.724 1.724 0 0 0 1.065 2.572c1.756 .426 1.756 2.924 0 3.35a1.724 1.724 0 0 0 -1.066 2.573c.94 1.543 -.826 3.31 -2.37 2.37a1.724 1.724 0 0 0 -2.572 1.065c-.426 1.756 -2.924 1.756 -3.35 0a1.724 1.724 0 0 0 -2.573 -1.066c-1.543 .94 -3.31 -.826 -2.37 -2.37a1.724 1.724 0 0 0 -1.065 -2.572c-1.756 -.426 -1.756 -2.924 0 -3.35a1.724 1.724 0 0 0 1.066 -2.573c-.94 -1.543 .826 -3.31 2.37 -2.37c1 .608 2.296 .07 2.572 -1.065z"></path><path d="M9 12a3 3 0 1 0 6 0a3 3 0 0 0 -6 0"></path></svg>"#;
|
pub const SETTINGS: &str = r#"<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-settings" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M10.325 4.317c.426 -1.756 2.924 -1.756 3.35 0a1.724 1.724 0 0 0 2.573 1.066c1.543 -.94 3.31 .826 2.37 2.37a1.724 1.724 0 0 0 1.065 2.572c1.756 .426 1.756 2.924 0 3.35a1.724 1.724 0 0 0 -1.066 2.573c.94 1.543 -.826 3.31 -2.37 2.37a1.724 1.724 0 0 0 -2.572 1.065c-.426 1.756 -2.924 1.756 -3.35 0a1.724 1.724 0 0 0 -2.573 -1.066c-1.543 .94 -3.31 -.826 -2.37 -2.37a1.724 1.724 0 0 0 -1.065 -2.572c-1.756 -.426 -1.756 -2.924 0 -3.35a1.724 1.724 0 0 0 1.066 -2.573c-.94 -1.543 .826 -3.31 2.37 -2.37c1 .608 2.296 .07 2.572 -1.065z"></path><path d="M9 12a3 3 0 1 0 6 0a3 3 0 0 0 -6 0"></path></svg>"#;
|
||||||
|
pub const APPS: &str = r#"<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-apps" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M4 4m0 1a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1z"></path><path d="M4 14m0 1a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1z"></path><path d="M14 14m0 1a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1z"></path><path d="M14 7l6 0"></path><path d="M17 4l0 6"></path>svg>"#;
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ use rocket::uri;
|
||||||
pub enum AdminMenu {
|
pub enum AdminMenu {
|
||||||
Exit,
|
Exit,
|
||||||
Dashboard,
|
Dashboard,
|
||||||
|
Apps,
|
||||||
Settings,
|
Settings,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -13,6 +14,7 @@ impl AdminMenu {
|
||||||
match self {
|
match self {
|
||||||
AdminMenu::Exit => "exit",
|
AdminMenu::Exit => "exit",
|
||||||
AdminMenu::Dashboard => "dashboard",
|
AdminMenu::Dashboard => "dashboard",
|
||||||
|
AdminMenu::Apps => "apps",
|
||||||
AdminMenu::Settings => "settings",
|
AdminMenu::Settings => "settings",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -32,6 +34,13 @@ impl AdminMenu {
|
||||||
icon: icons::HOME,
|
icon: icons::HOME,
|
||||||
sub: None,
|
sub: None,
|
||||||
},
|
},
|
||||||
|
MainItem {
|
||||||
|
id: AdminMenu::Apps.id(),
|
||||||
|
label: "Applications",
|
||||||
|
link: uri!(routes::admin::apps::admin_apps).to_string(),
|
||||||
|
icon: icons::APPS,
|
||||||
|
sub: None,
|
||||||
|
},
|
||||||
MainItem {
|
MainItem {
|
||||||
id: AdminMenu::Settings.id(),
|
id: AdminMenu::Settings.id(),
|
||||||
label: "Server settings",
|
label: "Server settings",
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ pub enum Page {
|
||||||
AdminDashboard(AdminDashboard),
|
AdminDashboard(AdminDashboard),
|
||||||
AdminSettingsBranding(AdminSettingsBranding),
|
AdminSettingsBranding(AdminSettingsBranding),
|
||||||
AdminSettingsSecurity(AdminSettingsSecurity),
|
AdminSettingsSecurity(AdminSettingsSecurity),
|
||||||
|
AdminApps(AdminApps),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Page {
|
impl Page {
|
||||||
|
|
@ -31,6 +32,7 @@ impl Page {
|
||||||
Page::AdminDashboard(_) => "pages/admin/dashboard",
|
Page::AdminDashboard(_) => "pages/admin/dashboard",
|
||||||
Page::AdminSettingsBranding(_) => "pages/admin/settings/branding",
|
Page::AdminSettingsBranding(_) => "pages/admin/settings/branding",
|
||||||
Page::AdminSettingsSecurity(_) => "pages/admin/settings/security",
|
Page::AdminSettingsSecurity(_) => "pages/admin/settings/security",
|
||||||
|
Page::AdminApps(_) => "pages/admin/apps/list",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -45,6 +47,7 @@ impl Page {
|
||||||
Page::AdminDashboard(_) => "Admin dashboard",
|
Page::AdminDashboard(_) => "Admin dashboard",
|
||||||
Page::AdminSettingsBranding(_) => "Server branding",
|
Page::AdminSettingsBranding(_) => "Server branding",
|
||||||
Page::AdminSettingsSecurity(_) => "Server security",
|
Page::AdminSettingsSecurity(_) => "Server security",
|
||||||
|
Page::AdminApps(_) => "Applications",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -61,6 +64,7 @@ impl Page {
|
||||||
Page::AdminDashboard(_) => Some(AdminMenu::Dashboard.into()),
|
Page::AdminDashboard(_) => Some(AdminMenu::Dashboard.into()),
|
||||||
Page::AdminSettingsBranding(_) => Some(AdminMenu::Settings.into()),
|
Page::AdminSettingsBranding(_) => Some(AdminMenu::Settings.into()),
|
||||||
Page::AdminSettingsSecurity(_) => 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::AdminDashboard(dashboard) => Box::new(dashboard),
|
||||||
Page::AdminSettingsBranding(branding) => Box::new(branding),
|
Page::AdminSettingsBranding(branding) => Box::new(branding),
|
||||||
Page::AdminSettingsSecurity(security) => Box::new(security),
|
Page::AdminSettingsSecurity(security) => Box::new(security),
|
||||||
|
Page::AdminApps(apps) => Box::new(apps),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
|
use self::apps::*;
|
||||||
use self::settings::*;
|
use self::settings::*;
|
||||||
use dashboard::*;
|
use dashboard::*;
|
||||||
use rocket::{routes, Route};
|
use rocket::{routes, Route};
|
||||||
|
|
||||||
|
pub mod apps;
|
||||||
pub mod dashboard;
|
pub mod dashboard;
|
||||||
pub mod settings;
|
pub mod settings;
|
||||||
|
|
||||||
|
|
@ -12,10 +14,12 @@ pub fn routes() -> Vec<Route> {
|
||||||
settings_update_branding,
|
settings_update_branding,
|
||||||
settings_security,
|
settings_security,
|
||||||
settings_security_form,
|
settings_security_form,
|
||||||
|
admin_apps,
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod content {
|
pub mod content {
|
||||||
|
use apps::App;
|
||||||
use jwt::JwtClaims;
|
use jwt::JwtClaims;
|
||||||
use rocket::serde::Serialize;
|
use rocket::serde::Serialize;
|
||||||
|
|
||||||
|
|
@ -40,4 +44,12 @@ pub mod content {
|
||||||
pub struct AdminSettingsSecurity {
|
pub struct AdminSettingsSecurity {
|
||||||
pub user: JwtClaims,
|
pub user: JwtClaims,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
#[serde(crate = "rocket::serde")]
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct AdminApps {
|
||||||
|
pub user: JwtClaims,
|
||||||
|
pub apps: Vec<App>,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
13
crates/ezidam/src/routes/admin/apps.rs
Normal file
13
crates/ezidam/src/routes/admin/apps.rs
Normal file
|
|
@ -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<Database>, admin: JwtAdmin) -> Result<Page> {
|
||||||
|
let list = App::get_all(&mut *db, None).await?;
|
||||||
|
|
||||||
|
Ok(Page::AdminApps(super::content::AdminApps {
|
||||||
|
user: admin.0,
|
||||||
|
apps: list,
|
||||||
|
}))
|
||||||
|
}
|
||||||
2
crates/ezidam/static/libs/list.js/list.min.js
vendored
Normal file
2
crates/ezidam/static/libs/list.js/list.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
124
crates/ezidam/templates/pages/admin/apps/list.html.tera
Normal file
124
crates/ezidam/templates/pages/admin/apps/list.html.tera
Normal file
|
|
@ -0,0 +1,124 @@
|
||||||
|
{% extends "shell" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="page-header d-print-none">
|
||||||
|
<div class="container-xl">
|
||||||
|
<div class="row align-items-center">
|
||||||
|
<div class="col">
|
||||||
|
<div class="page-pretitle">
|
||||||
|
Admin dashboard
|
||||||
|
</div>
|
||||||
|
<h2 class="page-title">
|
||||||
|
Applications
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<div class="col-auto ms-auto">
|
||||||
|
<div class="btn-list">
|
||||||
|
{% set primary_action = "New application" %}
|
||||||
|
<a href="#" class="btn btn-primary d-none d-sm-inline-block" data-bs-toggle="modal"
|
||||||
|
data-bs-target="#modal-report">
|
||||||
|
<!-- Download SVG icon from http://tabler-icons.io/i/plus -->
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24"
|
||||||
|
stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round"
|
||||||
|
stroke-linejoin="round">
|
||||||
|
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
|
||||||
|
<path d="M12 5l0 14"/>
|
||||||
|
<path d="M5 12l14 0"/>
|
||||||
|
</svg>
|
||||||
|
{{ primary_action }}
|
||||||
|
</a>
|
||||||
|
<a href="#" class="btn btn-primary d-sm-none btn-icon" data-bs-toggle="modal"
|
||||||
|
data-bs-target="#modal-report" aria-label="{{ primary_action }}">
|
||||||
|
<!-- Download SVG icon from http://tabler-icons.io/i/plus -->
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24"
|
||||||
|
stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round"
|
||||||
|
stroke-linejoin="round">
|
||||||
|
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
|
||||||
|
<path d="M12 5l0 14"/>
|
||||||
|
<path d="M5 12l14 0"/>
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Page body -->
|
||||||
|
<div class="page-body">
|
||||||
|
<div class="container-xl">
|
||||||
|
<div class="card">
|
||||||
|
<div id="table-default" class="table-responsive">
|
||||||
|
<table class="table table-hover">
|
||||||
|
<!-- Table header -->
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
<button class="table-sort" data-sort="sort-name">Name</button>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<button class="table-sort" data-sort="sort-status">Status</button>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<button class="table-sort" data-sort="sort-creation-date">Creation Date</button>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<button class="table-sort" data-sort="sort-id">ID</button>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<button class="table-sort" data-sort="sort-redirect-uri">Redirect URI</button>
|
||||||
|
</th>
|
||||||
|
<th class="w-1">
|
||||||
|
Actions
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="table-tbody">
|
||||||
|
|
||||||
|
<!-- Table content -->
|
||||||
|
{% for app in apps %}
|
||||||
|
<tr>
|
||||||
|
<td class="sort-name">{{ app.label }}</td>
|
||||||
|
<td class="sort-status">
|
||||||
|
{% if app.is_archived == true %}
|
||||||
|
<span class="badge bg-danger me-1"></span> Archived
|
||||||
|
{% else %}
|
||||||
|
<span class="badge bg-success me-1"></span> Active
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td class="sort-creation-date" data-date="{{ app.created_at | date(timestamp=true) }}">
|
||||||
|
{{ app.created_at | date() }}
|
||||||
|
</td>
|
||||||
|
<td class="sort-id">{{ app.id }}</td>
|
||||||
|
<td class="sort-redirect-uri">{{ app.redirect_uri }}</td>
|
||||||
|
<td>
|
||||||
|
<a class="btn btn-sm btn-outline-secondary" href="#">Details</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock content %}
|
||||||
|
|
||||||
|
{% block libs_js %}
|
||||||
|
<script src="/libs/list.js/list.min.js" defer></script>
|
||||||
|
{% endblock lib_js %}
|
||||||
|
|
||||||
|
{% block additional_js %}
|
||||||
|
<script>
|
||||||
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
const list = new List('table-default', {
|
||||||
|
sortClass: 'table-sort',
|
||||||
|
listClass: 'table-tbody',
|
||||||
|
valueNames: ['sort-name', 'sort-status',
|
||||||
|
{attr: 'data-date', name: 'sort-date'},
|
||||||
|
'sort-id', 'sort-redirect-uri',
|
||||||
|
]
|
||||||
|
});
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
{% endblock additional_js %}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue