-# this config is used by a page linked in the navbar
-# this pages will use the same configuration from config.yml, but will overwrite fields present here
+---
+# Additionnal page configuration
-# this overwrites title and subtitle:
-title: "Page2"
-subtitle: "this is the second page"
+# Additionnal configurations are loaded using its file name, minus the extension, as an anchor (https://<mydashboad>#<config>).
+# `config.yml` is still used as a base configuration, and all values here will overwrite it, so you don't have to re-defined everything
-# this overwrites message config. Setting it to empty to remove message from this page and keep it only in the main one:
-message:
+
+subtitle: "this is another dashboard page"
+
+# This overwrites message config. Setting it to empty to remove message from this page and keep it only in the main one:
+message: ~
# as we want to include a differente link here (so we can get back to home page), we need to replicate all links or they will be revome when overwriting the links field:
links:
- name: "Home"
icon: "fas fa-home"
- url: "/"
+ url: "#"
- name: "Contribute"
icon: "fab fa-github"
url: "https://github.com/bastienwirtz/homer"
icon: "fas fa-book"
url: "https://www.wikipedia.org/"
-# we keep the first group from the main page, but remove the second group. We need to replicate that first group or it will be removed:
services:
- - name: "NEW"
+ - name: "More applications on another page!"
icon: "fas fa-cloud"
items:
- name: "Awesome app on a second page!"
- name: "Wiki"
icon: "fas fa-book"
url: "https://www.wikipedia.org/"
+ # this will link to a second homer page that will load config from additionnal-page.yml and keep default config values as in config.yml file
+ # see url field and assets/additionnal-page.yml.dist used in this example:
+ - name: "another page!"
+ icon: "fas fa-file-alt"
+ url: "#additionnal-page"
# Services
# First level array represent a group.
<section v-if="config.header" class="first-line">
<div v-cloak class="container">
<div class="logo">
- <a href="#"><img v-if="config.logo" :src="config.logo" alt="dashboard logo" /></a>
+ <a href="#">
+ <img v-if="config.logo" :src="config.logo" alt="dashboard logo" />
+ </a>
<i v-if="config.icon" :class="config.icon"></i>
</div>
<div class="dashboard-title">
};
},
created: async function () {
- const defaults = jsyaml.load(defaultConfig);
- let config;
- window.onhashchange = function() { location.reload(); };
- try {
- config = await this.getConfig();
- const path = (window.location.hash.substring(1) != '') ? window.location.hash.substring(1) : null;
- if (path) {
- let pathConfig = await this.getConfig(`assets/${path}.yml`); // the slash (/) is included in the pathname
- for (const prop in pathConfig) config[prop] = pathConfig[prop];
- }
- // config = await this.getConfig(path ? `assets/${path}.yml` : null);
- //config = await (path ? this.getConfig(`assets/${path}.yml`) : this.getConfig())
- } catch (error) {
- console.log(error);
- config = this.handleErrors("⚠️ Error loading configuration", error);
- }
- this.config = merge(defaults, config);
- this.services = this.config.services;
- document.title =
- this.config.documentTitle ||
- `${this.config.title} | ${this.config.subtitle}`;
- if (this.config.stylesheet) {
- let stylesheet = "";
- for (const file of this.config.stylesheet) {
- stylesheet += `@import "${file}";`;
- }
- this.createStylesheet(stylesheet);
- }
+ this.buildDashboard();
+ window.onhashchange = this.buildDashboard;
},
methods: {
+ buildDashboard: async function () {
+ const defaults = jsyaml.load(defaultConfig);
+ let config;
+ try {
+ config = await this.getConfig();
+ const path =
+ window.location.hash.substring(1) != ""
+ ? window.location.hash.substring(1)
+ : null;
+
+ if (path) {
+ let pathConfig = await this.getConfig(`assets/${path}.yml`); // the slash (/) is included in the pathname
+ config = Object.assign(config, pathConfig);
+ }
+ } catch (error) {
+ console.log(error);
+ config = this.handleErrors("⚠️ Error loading configuration", error);
+ }
+ this.config = merge(defaults, config);
+ this.services = this.config.services;
+ document.title =
+ this.config.documentTitle ||
+ `${this.config.title} | ${this.config.subtitle}`;
+ if (this.config.stylesheet) {
+ let stylesheet = "";
+ for (const file of this.config.stylesheet) {
+ stylesheet += `@import "${file}";`;
+ }
+ this.createStylesheet(stylesheet);
+ }
+ },
getConfig: function (path = "assets/config.yml") {
return fetch(path).then((response) => {
if (response.redirected) {
},
data: function () {
return {
- show: false,
message: {},
};
},
// Look for a new message if an endpoint is provided.
this.message = Object.assign({}, this.item);
await this.getMessage();
- this.show = this.message.title || this.message.content;
},
-
+ computed: {
+ show: function () {
+ return this.message.title || this.message.content;
+ },
+ },
+ watch: {
+ item: function (item) {
+ this.message = Object.assign({}, item);
+ },
+ },
methods: {
- getMessage: async function() {
+ getMessage: async function () {
if (this.item && this.item.url) {
let fetchedMessage = await this.downloadMessage(this.item.url);
- if (this.item.mapping) fetchedMessage = this.mapRemoteMessage(fetchedMessage);
+ if (this.item.mapping)
+ fetchedMessage = this.mapRemoteMessage(fetchedMessage);
// keep the original config value if no value is provided by the endpoint
for (const prop of ["title", "style", "content"]) {
if (prop in fetchedMessage && fetchedMessage[prop] !== null) {
}
}
}
- if (this.item.refreshInterval) setTimeout(this.getMessage, this.item.refreshInterval);
+ if (this.item.refreshInterval)
+ setTimeout(this.getMessage, this.item.refreshInterval);
},
downloadMessage: function (url) {
mapRemoteMessage: function (message) {
let mapped = {};
// map property from message into mapped according to mapping config (only if field has a value):
- for (const prop in this.item.mapping) if (message[this.item.mapping[prop]]) mapped[prop] = message[this.item.mapping[prop]];
+ for (const prop in this.item.mapping)
+ if (message[this.item.mapping[prop]])
+ mapped[prop] = message[this.item.mapping[prop]];
return mapped;
},
},