diff --git a/bundle.js b/bundle.js index c3b6d74..9662729 100755 --- a/bundle.js +++ b/bundle.js @@ -106,6 +106,7 @@ async function bundleJS(inputDir, outputDir, watch) { carts: `${inputDir}/carts.js`, cart: `${inputDir}/cart.js`, changes: `${inputDir}/changes.js`, + settings: `${inputDir}/settings.js`, index: `${inputDir}/index.js`, }, bundle: true, diff --git a/server.js b/server.js index cf09f8e..e28a6f0 100644 --- a/server.js +++ b/server.js @@ -8,6 +8,10 @@ const express = require("express"); const compression = require("compression"); function copyItemsToSite(dataDir) { + fs.copyFileSync( + `${dataDir}/latest-canonical.json.${analysis.FILE_COMPRESSOR}`, + `site/output/data/latest-canonical.json.${analysis.FILE_COMPRESSOR}` + ); const items = analysis.readJSON(`${dataDir}/latest-canonical.json.${analysis.FILE_COMPRESSOR}`); analysis.writeJSON(`site/output/data/latest-canonical.json`, items); for (const store of analysis.STORE_KEYS) { diff --git a/site/_templates/_footer.html b/site/_templates/_footer.html index da1bc58..d6190a3 100644 --- a/site/_templates/_footer.html +++ b/site/_templates/_footer.html @@ -1,5 +1,6 @@
+ Einstellungen Impressum diff --git a/site/model/index.js b/site/model/index.js index 647943e..aef465b 100644 --- a/site/model/index.js +++ b/site/model/index.js @@ -1,10 +1,12 @@ const { Carts } = require("./carts"); const { Items } = require("./items"); +const { Settings } = require("./settings"); exports.stores = require("./stores"); exports.categories = require("./categories"); exports.carts = new Carts(); exports.items = new Items(); +exports.settings = new Settings(); exports.load = async () => { await exports.items.load(); diff --git a/site/model/settings.js b/site/model/settings.js new file mode 100644 index 0000000..28716c4 --- /dev/null +++ b/site/model/settings.js @@ -0,0 +1,32 @@ +const { STORE_KEYS, stores } = require("./stores"); +const { Model } = require("./model"); + +export class Settings extends Model { + constructor() { + super(); + this.startDate = "2017-01-01"; + this.chartType = "stepped"; + STORE_KEYS.forEach((store) => { + this[store] = stores[store].defaultChecked; + }); + + let settings = localStorage.getItem("settings"); + if (settings) { + settings = JSON.parse(settings); + for (const prop of Object.getOwnPropertyNames(settings)) { + this[prop] = settings[prop]; + } + } + } + + save() { + const settings = {}; + + for (const prop of Object.getOwnPropertyNames(this)) { + if (prop.startsWith("_")) continue; + settings[prop] = this[prop]; + } + + localStorage.setItem("settings", JSON.stringify(settings)); + } +} diff --git a/site/settings.html b/site/settings.html new file mode 100644 index 0000000..2821573 --- /dev/null +++ b/site/settings.html @@ -0,0 +1,9 @@ +%%_templates/_header.html%% %%_templates/_menu.html%% + +
+

Einstellungen

+ +
+ + +%%_templates/_footer.html%% diff --git a/site/settings.js b/site/settings.js new file mode 100644 index 0000000..b57bfe1 --- /dev/null +++ b/site/settings.js @@ -0,0 +1,59 @@ +const { STORE_KEYS, stores } = require("./model/stores"); +const { View } = require("./views/view"); +const { Settings } = require("./model/settings"); +require("./js/misc"); +require("./views/custom-checkbox"); + +class SettingsView extends View { + constructor() { + super(); + this.innerHTML = /*html*/ ` +
+
Vorselektierte Ketten
+
+ ${STORE_KEYS.map( + (store) => /*html*/ ` + ` + ).join("")} +
+ + +
+ `; + this.setupEventHandlers(); + } +} +customElements.define("settings-view", SettingsView); + +(async () => { + const settings = new Settings(); + const settingsView = document.querySelector("settings-view"); + settingsView.state = settings; + + document.body.addEventListener("x-change", () => { + const state = settingsView.state; + for (const prop of Object.getOwnPropertyNames(state)) { + settings[prop] = state[prop]; + } + settings.save(); + }); +})(); diff --git a/site/views/items-chart.js b/site/views/items-chart.js index 745cbdc..5da14e8 100644 --- a/site/views/items-chart.js +++ b/site/views/items-chart.js @@ -1,4 +1,5 @@ const { STORE_KEYS } = require("../model/stores"); +const { settings } = require("../model"); const { today, log, deltaTime } = require("../js/misc"); const { View } = require("./view"); require("./custom-checkbox"); @@ -30,6 +31,7 @@ class ItemsChart extends View {
`; + this.elements.startDate.value = settings.startDate; this.setupEventHandlers(); this.addEventListener("x-change", () => { this.render(); @@ -147,14 +149,16 @@ class ItemsChart extends View { const dataset = { label: (item.store ? item.store + " " : "") + item.name, - data: dedupPrices.map((price, index) => { + data: dedupPrices.map((price) => { return { x: moment(price.date), y: price.price, }; }), - stepped: "before", }; + if (settings.chartType == "stepped") { + dataset.stepped = "before"; + } return dataset; }); diff --git a/site/views/items-filter.js b/site/views/items-filter.js index 6fe9149..aa49632 100644 --- a/site/views/items-filter.js +++ b/site/views/items-filter.js @@ -1,5 +1,6 @@ const { today, parseNumber, dom, getBooleanAttribute, queryItems, log, deltaTime } = require("../js/misc"); const { stores, STORE_KEYS, BUDGET_BRANDS } = require("../model/stores"); +const { settings } = require("../model"); const { View } = require("./view"); class ItemsFilter extends View { @@ -32,7 +33,7 @@ class ItemsFilter extends View { x-id="${store}" x-state x-change label="${stores[store].name}" class="${stores[store].color}" - ${stores[store].defaultChecked ? "checked" : ""} + ${settings[store] ? "checked" : ""} >` ).join("")}