mirror of
https://github.com/ConnectedHumber/Air-Quality-Web
synced 2024-11-22 06:23:01 +00:00
Implement initial tour.
This commit is contained in:
parent
bc3c631c89
commit
fa433c88b0
6 changed files with 193 additions and 7 deletions
|
@ -6,13 +6,16 @@ import 'leaflet.markercluster';
|
|||
// We're using the git repo for now until an update is released, and rollup doesn't like that apparently
|
||||
import CreateElement from '../../node_modules/dom-create-element-query-selector/src/index.js';
|
||||
import tabs from 'tabs';
|
||||
import Emitter from 'event-emitter-es6';
|
||||
|
||||
import Config from './Config.mjs';
|
||||
import DeviceReadingDisplay from './DeviceReadingDisplay.mjs';
|
||||
import GetFromUrl from './Helpers/GetFromUrl.mjs';
|
||||
|
||||
class LayerDeviceMarkers {
|
||||
class LayerDeviceMarkers extends Emitter {
|
||||
constructor(in_map, in_device_data) {
|
||||
super();
|
||||
|
||||
this.map = in_map;
|
||||
this.device_data = in_device_data;
|
||||
|
||||
|
@ -72,6 +75,8 @@ class LayerDeviceMarkers {
|
|||
delete device_info.longitude;
|
||||
|
||||
event.popup.setContent(this.render_device_info(device_info));
|
||||
|
||||
this.emit("marker-popup-opened");
|
||||
}
|
||||
|
||||
render_device_info(device_info) {
|
||||
|
|
|
@ -63,7 +63,7 @@ class MapManager {
|
|||
// .then(() => console.info("[map] Time dimension initialised."));
|
||||
|
||||
this.ui = new UI(Config, this);
|
||||
this.ui.setup().then(() => console.log("[map] Settings initialised."));
|
||||
this.ui.setup().then(() => console.log("[map] UI setup complete."));
|
||||
}
|
||||
|
||||
async setup_overlay() {
|
||||
|
|
155
client_src/js/Tour.mjs
Normal file
155
client_src/js/Tour.mjs
Normal file
|
@ -0,0 +1,155 @@
|
|||
"use strict";
|
||||
|
||||
import Sheperd from 'shepherd.js';
|
||||
import '../../node_modules/shepherd.js/dist/css/shepherd-theme-default.css';
|
||||
|
||||
class Tour {
|
||||
constructor(in_map_manager) {
|
||||
this.map_manager = in_map_manager;
|
||||
}
|
||||
|
||||
create_tour() {
|
||||
this.tour = new Sheperd.Tour({
|
||||
useModalOverlay: true,
|
||||
defaultStepOptions: {
|
||||
// Default settings for steps go here
|
||||
}
|
||||
});
|
||||
|
||||
this.tour.addStep("welcome", {
|
||||
text: "Welcome to the air quality web interface! Press next to get a short tour.",
|
||||
buttons: this.get_buttons(false, true)
|
||||
});
|
||||
|
||||
this.tour.addStep("map", {
|
||||
text: "Each device has a blue marker. The shape a marker is located in changes colour depending on the value of the measure it reported.",
|
||||
attachTo: {
|
||||
element: "#map",
|
||||
on: "bottom"
|
||||
},
|
||||
buttons: this.get_buttons()
|
||||
});
|
||||
this.tour.addStep("guage", {
|
||||
text: "This guage is a key to the colour of the shapes underneath the device markers.",
|
||||
attachTo: {
|
||||
element: document.querySelector("#canvas-guage"),
|
||||
on: "left"
|
||||
},
|
||||
buttons: this.get_buttons()
|
||||
});
|
||||
|
||||
this.tour.addStep("reading-type", {
|
||||
text: "Devices report multiple types of measurement. Change to another reading type now.",
|
||||
attachTo: {
|
||||
element: document.querySelector("select").parentNode,
|
||||
on: "top"
|
||||
},
|
||||
advanceOn: { selector: "select", event: "change" },
|
||||
buttons: this.get_buttons(true)
|
||||
});
|
||||
this.tour.addStep("reading-type-complete", {
|
||||
text: "Hey, the map changed! Some devices only report certain types of measurement, and different measurements have different colour scales.",
|
||||
attachTo: { element: "#map", on: "bottom" },
|
||||
buttons: this.get_buttons()
|
||||
});
|
||||
this.tour.addStep("layer-showhide", {
|
||||
text: "You can show and hide the device markers and the heatmap here.",
|
||||
attachTo: {
|
||||
element: ".leaflet-control-layers",
|
||||
on: "left"
|
||||
},
|
||||
buttons: this.get_buttons()
|
||||
});
|
||||
|
||||
this.tour.addStep("map-controls", {
|
||||
text: "You can control the zoom level and go fullscreen here. You can also zoom with your mouse wheel if you have one, and pan by clicking and dragging.",
|
||||
attachTo: {
|
||||
element: ".leaflet-top.leaflet-left",
|
||||
on: "right"
|
||||
},
|
||||
buttons: this.get_buttons()
|
||||
});
|
||||
|
||||
this.tour.addStep("device-graph", {
|
||||
text: "By clicking a blue marker, you can view additional information about that device. Not all device are actively reporting data. Try clicking one now.",
|
||||
attachTo: {
|
||||
element: "#map",
|
||||
on: "top"
|
||||
},
|
||||
buttons: this.get_buttons(true)
|
||||
|
||||
}).on("show", (() => {
|
||||
this.map_manager.device_markers.once("marker-popup-opened", this.tour.next.bind(this.tour));
|
||||
}).bind(this));
|
||||
|
||||
this.tour.addStep("device-graph-a", {
|
||||
text: "This is a device information popup. By default it displays recent data that the device has reported on the line graph, but you can control this with the blue buttons.",
|
||||
attachTo: {
|
||||
element: ".popup-device",
|
||||
on: "right"
|
||||
},
|
||||
buttons: this.get_buttons()
|
||||
});
|
||||
this.tour.addStep("device-graph-b", {
|
||||
text: "By clicking here, you can see the specification of the device, including its software, sensor models, exact location, more. Click this now.",
|
||||
attachTo: {
|
||||
element: ".tabs :first-child",
|
||||
on: "left"
|
||||
},
|
||||
advanceOn: { selector: ".tabs :first-child a", event: "click" },
|
||||
buttons: this.get_buttons(true)
|
||||
});
|
||||
|
||||
|
||||
this.tour.addStep("report-bug", {
|
||||
text: "If you find a bug, you can report it by clicking this button.",
|
||||
attachTo: {
|
||||
element: "button[value='Report bug']",
|
||||
on: "right"
|
||||
},
|
||||
buttons: this.get_buttons()
|
||||
});
|
||||
this.tour.addStep("changelog", {
|
||||
text: "The changelog will be automatically shown every time this web interface updates. Click the version information here to review it again at other times.",
|
||||
attachTo: {
|
||||
element: "button[value~='built']",
|
||||
on: "right"
|
||||
},
|
||||
buttons: this.get_buttons()
|
||||
});
|
||||
|
||||
|
||||
this.tour.addStep("complete", {
|
||||
text: "Tour complete!\nIf you need any additional assistance, let us know :-)",
|
||||
buttons: [{ text: "Done", action: this.tour.next }]
|
||||
});
|
||||
}
|
||||
|
||||
run_once() {
|
||||
if(!window.localStorage.has("completed_tour"))
|
||||
this.run();
|
||||
|
||||
window.localStorage.setItem("completed_tour", (new Date()).toISOString());
|
||||
}
|
||||
|
||||
run() {
|
||||
if(typeof this.tour == "undefined")
|
||||
this.create_tour();
|
||||
this.tour.start();
|
||||
}
|
||||
|
||||
get_buttons(no_continue = false, no_prev = false) {
|
||||
let next = { text: "Next", action: this.tour.next },
|
||||
prev = { text: "Previous", action: this.tour.back },
|
||||
exit = { text: "Exit", action: this.tour.cancel };
|
||||
|
||||
let result = [];
|
||||
if(!no_prev) result.push(prev);
|
||||
if(!no_continue) result.push(next);
|
||||
result.push(exit);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
export default Tour;
|
|
@ -6,6 +6,16 @@ import NanoModal from 'nanomodal';
|
|||
import Config from './Config.mjs';
|
||||
import GetFromUrl from './Helpers/GetFromUrl.mjs';
|
||||
|
||||
import Tour from './Tour.mjs';
|
||||
|
||||
function show_nanomodal(html) {
|
||||
return new Promise((resolve, _reject) => {
|
||||
let modal = NanoModal(html);
|
||||
modal.onHide(resolve);
|
||||
modal.show();
|
||||
});
|
||||
}
|
||||
|
||||
async function show_changelog(only_if_changed) {
|
||||
let current_version = `${Config.version}, built ${Config.build_date.toDateString()}`;
|
||||
console.log(`[UI] Comparing current '${current_version}' to '${localStorage.getItem("last_seen_version")}'`);
|
||||
|
@ -15,9 +25,8 @@ async function show_changelog(only_if_changed) {
|
|||
}
|
||||
|
||||
console.log("[UI] Showing changelog");
|
||||
NanoModal(
|
||||
await GetFromUrl(`${Config.api_root}?action=changelog`)
|
||||
).show();
|
||||
await show_nanomodal(await GetFromUrl(`${Config.api_root}?action=changelog`));
|
||||
|
||||
localStorage.setItem("last_seen_version", current_version);
|
||||
return true;
|
||||
}
|
||||
|
@ -29,6 +38,8 @@ class UI {
|
|||
|
||||
this.ui_panel = new SmartSettings("Settings");
|
||||
// this.ui_panel.watch((event) => console.log(event));
|
||||
|
||||
this.tour = new Tour(this.map_manager);
|
||||
}
|
||||
|
||||
async setup() {
|
||||
|
@ -64,7 +75,9 @@ class UI {
|
|||
]);
|
||||
this.ui_panel.setIndex("Reading Type", this.reading_types.findIndex((type) => type.short_descr == "PM25"));
|
||||
|
||||
|
||||
await show_changelog(true);
|
||||
await this.tour.run();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
13
package-lock.json
generated
13
package-lock.json
generated
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "air-quality-mapper",
|
||||
"version": "0.9.1",
|
||||
"version": "0.10.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
@ -48,6 +48,12 @@
|
|||
"integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/event-emitter-es6": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/event-emitter-es6/-/event-emitter-es6-1.1.0.tgz",
|
||||
"integrity": "sha512-A0010GUMSopVYUlDdzhYAD8Z2qGC2hG2H32IHy554NpGEHmsx8M6/lLZRRqxXCxLq28aYrmaZtGwDJjeNXbTDQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/geojson": {
|
||||
"version": "7946.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.7.tgz",
|
||||
|
@ -1120,6 +1126,11 @@
|
|||
"integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
|
||||
"dev": true
|
||||
},
|
||||
"event-emitter-es6": {
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/event-emitter-es6/-/event-emitter-es6-1.1.5.tgz",
|
||||
"integrity": "sha1-75UxGy4Xqjm+djsDHOSvfunLeEk="
|
||||
},
|
||||
"expand-brackets": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "air-quality-mapper",
|
||||
"version": "0.10",
|
||||
"version": "0.10.0",
|
||||
"description": "The web interface and JSON api for the ConnectedHumber Air Quality Monitoring Project.",
|
||||
"private": true,
|
||||
"main": "index.mjs",
|
||||
|
@ -22,6 +22,7 @@
|
|||
"chroma-js": "^2.0.3",
|
||||
"d3-delaunay": "^4.1.5",
|
||||
"dom-create-element-query-selector": "github:hekigan/dom-create-element-query-selector",
|
||||
"event-emitter-es6": "^1.1.5",
|
||||
"iso8601-js-period": "^0.2.1",
|
||||
"leaflet": "^1.5.1",
|
||||
"leaflet-fullscreen": "^1.0.2",
|
||||
|
@ -37,6 +38,7 @@
|
|||
"@types/chart.js": "^2.7.53",
|
||||
"@types/chroma-js": "^1.4.1",
|
||||
"@types/d3-delaunay": "^4.1.0",
|
||||
"@types/event-emitter-es6": "^1.1.0",
|
||||
"@types/leaflet": "^1.4.4",
|
||||
"@types/leaflet-fullscreen": "^1.0.4",
|
||||
"nightdocs": "^1.0.5",
|
||||
|
|
Loading…
Reference in a new issue