commit bfd93e5b1389b7b885bf0654b29c57d7a23f7a66
parent a79745956025de9d3c859f6eec9eb329f2717c24
Author: Daniel GarcĂa <dani-garcia@users.noreply.github.com>
Date: Sun, 20 Jan 2019 17:43:56 +0100
Show organizations in admin panel, implement reload templates option
Diffstat:
5 files changed, 56 insertions(+), 9 deletions(-)
diff --git a/.env.template b/.env.template
@@ -13,6 +13,8 @@
## Templates data folder, by default uses embedded templates
## Check source code to see the format
# TEMPLATES_FOLDER=/path/to/templates
+## Automatically reload the templates for every request, slow, use only for development
+# RELOAD_TEMPLATES=false
## Cache time-to-live for successfully obtained icons, in seconds (0 is "forever")
# ICON_CACHE_TTL=2592000
diff --git a/src/api/admin.rs b/src/api/admin.rs
@@ -49,7 +49,7 @@ impl AdminTemplateData {
}
fn render(self) -> Result<String, Error> {
- CONFIG.templates.render("admin/base", &self).map_err(Into::into)
+ CONFIG.render_template("admin/base", &self)
}
}
@@ -72,6 +72,7 @@ struct LoginForm {
fn post_admin_login(data: Form<LoginForm>, mut cookies: Cookies, ip: ClientIp) -> Result<Redirect, Flash<Redirect>> {
let data = data.into_inner();
+ // If the token is invalid, redirect to login page
if !_validate_token(&data.token) {
error!("Invalid admin token. IP: {}", ip.ip);
Err(Flash::error(
diff --git a/src/mail.rs b/src/mail.rs
@@ -36,7 +36,7 @@ fn mailer(config: &MailConfig) -> SmtpTransport {
}
fn get_text(template_name: &'static str, data: serde_json::Value) -> Result<(String, String), Error> {
- let text = CONFIG.templates.render(template_name, &data)?;
+ let text = CONFIG.render_template(template_name, &data)?;
let mut text_split = text.split("<!---------------->");
let subject = match text_split.next() {
diff --git a/src/main.rs b/src/main.rs
@@ -331,9 +331,11 @@ pub struct Config {
mail: Option<MailConfig>,
templates: Handlebars,
+ templates_folder: String,
+ reload_templates: bool,
}
-fn load_templates(path: String) -> Handlebars {
+fn load_templates(path: &str) -> Handlebars {
let mut hb = Handlebars::new();
// Error on missing params
hb.set_strict_mode(true);
@@ -365,6 +367,21 @@ fn load_templates(path: String) -> Handlebars {
}
impl Config {
+ pub fn render_template<T: serde::ser::Serialize>(&self, name: &str, data: &T) -> Result<String, error::Error> {
+ // We add this to signal the compiler not to drop the result of 'load_templates'
+ let hb_owned;
+
+ let hb = if CONFIG.reload_templates {
+ warn!("RELOADING TEMPLATES");
+ hb_owned = load_templates(&self.templates_folder);
+ &hb_owned
+ } else {
+ &self.templates
+ };
+
+ hb.render(name, data).map_err(Into::into)
+ }
+
fn load() -> Self {
use crate::util::{get_env, get_env_or};
dotenv::dotenv().ok();
@@ -377,11 +394,15 @@ impl Config {
let yubico_client_id = get_env("YUBICO_CLIENT_ID");
let yubico_secret_key = get_env("YUBICO_SECRET_KEY");
+ let templates_folder = get_env_or("TEMPLATES_FOLDER", format!("{}/{}", &df, "templates"));
+
Config {
database_url: get_env_or("DATABASE_URL", format!("{}/{}", &df, "db.sqlite3")),
icon_cache_folder: get_env_or("ICON_CACHE_FOLDER", format!("{}/{}", &df, "icon_cache")),
attachments_folder: get_env_or("ATTACHMENTS_FOLDER", format!("{}/{}", &df, "attachments")),
- templates: load_templates(get_env_or("TEMPLATES_FOLDER", format!("{}/{}", &df, "templates"))),
+ templates: load_templates(&templates_folder),
+ templates_folder,
+ reload_templates: get_env_or("RELOAD_TEMPLATES", false),
// icon_cache_ttl defaults to 30 days (30 * 24 * 60 * 60 seconds)
icon_cache_ttl: get_env_or("ICON_CACHE_TTL", 2_592_000),
diff --git a/src/static/templates/admin/page.hbs b/src/static/templates/admin/page.hbs
@@ -7,11 +7,23 @@
<div class="media pt-3">
<img class="mr-2 rounded identicon" data-src="{{Email}}">
<div class="media-body pb-3 mb-0 small border-bottom">
- <div class="d-flex justify-content-between">
- <strong>{{Name}}</strong>
- <a class="tmp-del mr-3" href="" onclick='deleteUser("{{Id}}", "{{Email}}");'>Delete User</a>
+ <div class="row justify-content-between">
+ <div class="col">
+ <strong>{{Name}}</strong>
+ <span class="d-block">{{Email}}</span>
+ </div>
+ <div class="col">
+ <strong> Organizations:</strong>
+ <span class="d-block">
+ {{#each Organizations}}
+ <span class="badge badge-primary" data-orgtype="{{Type}}">{{Name}}</span>
+ {{/each}}
+ </span>
+ </div>
+ <div style="flex: 0 0 100px;">
+ <a class="mr-3" href="" onclick='deleteUser("{{Id}}", "{{Email}}");'>Delete User</a>
+ </div>
</div>
- <span class="d-block">{{Email}}</span>
</div>
</div>
{{/each}}
@@ -73,11 +85,22 @@
"Error inviting user", data);
}
+ let OrgTypes = {
+ "0": { "name": "Owner", "color": "orange" },
+ "1": { "name": "Admin", "color": "blueviolet" },
+ "2": { "name": "User", "color": "blue" },
+ "3": { "name": "Manager", "color": "green" },
+ };
+
$(window).on('load', function () {
- //$("#reload-btn").click(reload);
$("#invite-form").submit(inviteUser);
$("img.identicon").each(function (i, e) {
e.src = identicon(e.dataset.src);
});
+ $('[data-orgtype]').each(function (i, e) {
+ let orgtype = OrgTypes[e.dataset.orgtype];
+ e.style.backgroundColor = orgtype.color;
+ e.title = orgtype.name;
+ });
});
</script>
\ No newline at end of file