webapp: Added helpfull tooltips to the web interface

This commit is contained in:
Thomas Basler 2022-12-20 20:39:59 +01:00
parent 0a38103d54
commit de61ab3694
7 changed files with 69 additions and 23 deletions

View File

@ -22,13 +22,16 @@
<tr> <tr>
<th>Firmware Version / Git Hash</th> <th>Firmware Version / Git Hash</th>
<td><a :href="'https://github.com/tbnobody/OpenDTU/commits/' + systemStatus.git_hash?.substring(1)" <td><a :href="'https://github.com/tbnobody/OpenDTU/commits/' + systemStatus.git_hash?.substring(1)"
target="_blank">{{ systemStatus.git_hash?.substring(1) }}</a></td> target="_blank" v-tooltip title="Click here to show information about your current version">{{
systemStatus.git_hash?.substring(1)
}}</a></td>
</tr> </tr>
<tr> <tr>
<th>Firmware Update</th> <th>Firmware Update</th>
<td><a :href="systemStatus.update_url" target="_blank"><span class="badge" <td><a :href="systemStatus.update_url" target="_blank" v-tooltip title="Click here to view the changes between your version
:class="systemStatus.update_status">{{ and the latest version"><span class="badge" :class="systemStatus.update_status">{{
systemStatus.update_text }}</span></a></td> systemStatus.update_text
}}</span></a></td>
</tr> </tr>
<tr> <tr>
<th>Reset Reason CPU 0</th> <th>Reset Reason CPU 0</th>

View File

@ -2,6 +2,7 @@ import { createApp } from 'vue'
import App from './App.vue' import App from './App.vue'
import router from './router' import router from './router'
import mitt from 'mitt'; import mitt from 'mitt';
import { tooltip } from './plugins/bootstrap'
import './scss/styles.scss' import './scss/styles.scss'
import "bootstrap" import "bootstrap"
@ -11,6 +12,8 @@ const app = createApp(App)
const emitter = mitt(); const emitter = mitt();
app.config.globalProperties.$emitter = emitter; app.config.globalProperties.$emitter = emitter;
app.directive('tooltip', tooltip)
app.use(router) app.use(router)
app.mount('#app') app.mount('#app')

View File

@ -0,0 +1,7 @@
import { Tooltip } from 'bootstrap'
export const tooltip = {
mounted(el: HTMLElement) {
const tooltip = new Tooltip(el)
}
}

View File

@ -9,7 +9,12 @@
<div class="card-header text-bg-primary">DTU Configuration</div> <div class="card-header text-bg-primary">DTU Configuration</div>
<div class="card-body"> <div class="card-body">
<div class="row mb-3"> <div class="row mb-3">
<label for="inputDtuSerial" class="col-sm-2 col-form-label">Serial:</label> <label for="inputDtuSerial" class="col-sm-2 col-form-label">Serial:
<BIconInfoCircle v-tooltip title="Both the inverter and the DTU have a serial number.
The DTU serial number is randomly generated at the first start and does not
normally need to be changed." />
</label>
<div class="col-sm-10"> <div class="col-sm-10">
<input type="number" class="form-control" id="inputDtuSerial" min="1" max="199999999999" <input type="number" class="form-control" id="inputDtuSerial" min="1" max="199999999999"
placeholder="DTU Serial" v-model="dtuConfigList.dtu_serial" /> placeholder="DTU Serial" v-model="dtuConfigList.dtu_serial" />
@ -29,7 +34,10 @@
</div> </div>
<div class="row mb-3"> <div class="row mb-3">
<label for="inputTimezone" class="col-sm-2 col-form-label">PA Level:</label> <label for="inputTimezone" class="col-sm-2 col-form-label">PA Level:
<BIconInfoCircle v-tooltip
title="Make sure your power supply is stable enough before increasing the transmit power." />
</label>
<div class="col-sm-10"> <div class="col-sm-10">
<select class="form-select" v-model="dtuConfigList.dtu_palevel"> <select class="form-select" v-model="dtuConfigList.dtu_palevel">
<option v-for="palevel in palevelList" :key="palevel.key" :value="palevel.key"> <option v-for="palevel in palevelList" :key="palevel.key" :value="palevel.key">
@ -51,11 +59,15 @@ import BasePage from '@/components/BasePage.vue';
import BootstrapAlert from "@/components/BootstrapAlert.vue"; import BootstrapAlert from "@/components/BootstrapAlert.vue";
import { handleResponse, authHeader } from '@/utils/authentication'; import { handleResponse, authHeader } from '@/utils/authentication';
import type { DtuConfig } from "@/types/DtuConfig"; import type { DtuConfig } from "@/types/DtuConfig";
import {
BIconInfoCircle,
} from 'bootstrap-icons-vue';
export default defineComponent({ export default defineComponent({
components: { components: {
BasePage, BasePage,
BootstrapAlert, BootstrapAlert,
BIconInfoCircle,
}, },
data() { data() {
return { return {

View File

@ -55,7 +55,7 @@
<div class="btn-toolbar p-2" role="toolbar"> <div class="btn-toolbar p-2" role="toolbar">
<div class="btn-group me-2" role="group"> <div class="btn-group me-2" role="group">
<button :disabled="!isLogged" type="button" class="btn btn-sm btn-danger" <button :disabled="!isLogged" type="button" class="btn btn-sm btn-danger"
@click="onShowLimitSettings(inverter.serial)" title="Show / Set Inverter Limit"> @click="onShowLimitSettings(inverter.serial)" v-tooltip title="Show / Set Inverter Limit">
<BIconSpeedometer style="font-size:24px;" /> <BIconSpeedometer style="font-size:24px;" />
</button> </button>
@ -63,7 +63,7 @@
<div class="btn-group me-2" role="group"> <div class="btn-group me-2" role="group">
<button :disabled="!isLogged" type="button" class="btn btn-sm btn-danger" <button :disabled="!isLogged" type="button" class="btn btn-sm btn-danger"
@click="onShowPowerSettings(inverter.serial)" title="Turn Inverter on/off"> @click="onShowPowerSettings(inverter.serial)" v-tooltip title="Turn Inverter on/off">
<BIconPower style="font-size:24px;" /> <BIconPower style="font-size:24px;" />
</button> </button>
@ -71,7 +71,7 @@
<div class="btn-group me-2" role="group"> <div class="btn-group me-2" role="group">
<button type="button" class="btn btn-sm btn-info" <button type="button" class="btn btn-sm btn-info"
@click="onShowDevInfo(inverter.serial)" title="Show Inverter Info"> @click="onShowDevInfo(inverter.serial)" v-tooltip title="Show Inverter Info">
<BIconCpu style="font-size:24px;" /> <BIconCpu style="font-size:24px;" />
</button> </button>
@ -80,7 +80,7 @@
<div class="btn-group" role="group"> <div class="btn-group" role="group">
<button v-if="inverter.events >= 0" type="button" <button v-if="inverter.events >= 0" type="button"
class="btn btn-sm btn-secondary position-relative" class="btn btn-sm btn-secondary position-relative"
@click="onShowEventlog(inverter.serial)" title="Show Eventlog"> @click="onShowEventlog(inverter.serial)" v-tooltip title="Show Eventlog">
<BIconJournalText style="font-size:24px;" /> <BIconJournalText style="font-size:24px;" />
<span <span
class="position-absolute top-0 start-100 translate-middle badge rounded-pill text-bg-danger"> class="position-absolute top-0 start-100 translate-middle badge rounded-pill text-bg-danger">

View File

@ -75,37 +75,49 @@
<div class="mb-3"> <div class="mb-3">
<label for="inverter-serial" class="col-form-label">Inverter Serial:</label> <label for="inverter-serial" class="col-form-label">Inverter Serial:</label>
<input v-model="selectedInverterData.serial" type="number" id="inverter-serial" <input v-model="selectedInverterData.serial" type="number" id="inverter-serial"
class="form-control" /> class="form-control" />
<label for="inverter-name" class="col-form-label">Inverter Name:</label> <label for="inverter-name" class="col-form-label">Inverter Name:
<BIconInfoCircle v-tooltip
title="Here you can specify a custom name for your inverter." />
</label>
<input v-model="selectedInverterData.name" type="text" id="inverter-name" <input v-model="selectedInverterData.name" type="text" id="inverter-name"
class="form-control" maxlength="31" /> class="form-control" maxlength="31" />
</div> </div>
<div v-for="(max, index) in selectedInverterData.channel" :key="`${index}`"> <div v-for="(max, index) in selectedInverterData.channel" :key="`${index}`">
<div class="row g-2"> <div class="row g-2">
<div class="col-md"> <div class="col-md">
<label :for="`inverter-name_${index}`" class="col-form-label">Name string {{ index +1 }}:</label> <label :for="`inverter-name_${index}`" class="col-form-label">Name string {{ index
+ 1
}}:
<BIconInfoCircle v-tooltip
title="Here you can specify a custom name for the respective port of your inverter." />
</label>
<div class="d-flex mb-2"> <div class="d-flex mb-2">
<div class="input-group"> <div class="input-group">
<input type="text" class="form-control" :id="`inverter-name_${index}`" maxlength="31" <input type="text" class="form-control" :id="`inverter-name_${index}`"
v-model="selectedInverterData.channel[index].name" /> maxlength="31" v-model="selectedInverterData.channel[index].name" />
</div> </div>
</div> </div>
</div> </div>
<div class="col-md-5"> <div class="col-md-5">
<label :for="`inverter-max_${index}`" class="col-form-label">Max power string {{ index +1 }}:</label> <label :for="`inverter-max_${index}`" class="col-form-label">Max power string {{
index + 1
}}: <BIconInfoCircle v-tooltip
title="Enter the max power of the connected solar panels." /></label>
<div class="d-flex mb-2"> <div class="d-flex mb-2">
<div class="input-group"> <div class="input-group">
<input type="number" class="form-control" :id="`inverter-max_${index}`" min="0" <input type="number" class="form-control" :id="`inverter-max_${index}`"
v-model="selectedInverterData.channel[index].max_power" min="0" v-model="selectedInverterData.channel[index].max_power"
:aria-describedby="`inverter-maxDescription_${index} inverter-customizer`" /> :aria-describedby="`inverter-maxDescription_${index} inverter-customizer`" />
<span class="input-group-text" :id="`inverter-maxDescription_${index}`">W<sub>p</sub><sup>*</sup></span> <span class="input-group-text"
:id="`inverter-maxDescription_${index}`">W<sub>p</sub><sup>*</sup></span>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div :id="`inverter-customizer`" class="form-text">*) Input the W<sub>p</sub> of the channel to <div :id="`inverter-customizer`" class="form-text">*) Enter the W<sub>p</sub> of the channel to
calculate irradiation.</div> calculate irradiation.</div>
</form> </form>
@ -146,7 +158,8 @@ import { defineComponent } from 'vue';
import BasePage from '@/components/BasePage.vue'; import BasePage from '@/components/BasePage.vue';
import { import {
BIconTrash, BIconTrash,
BIconPencil BIconPencil,
BIconInfoCircle,
} from 'bootstrap-icons-vue'; } from 'bootstrap-icons-vue';
import * as bootstrap from 'bootstrap'; import * as bootstrap from 'bootstrap';
import BootstrapAlert from "@/components/BootstrapAlert.vue"; import BootstrapAlert from "@/components/BootstrapAlert.vue";
@ -177,6 +190,7 @@ export default defineComponent({
BootstrapAlert, BootstrapAlert,
BIconTrash, BIconTrash,
BIconPencil, BIconPencil,
BIconInfoCircle,
}, },
data() { data() {
return { return {

View File

@ -9,7 +9,10 @@
<div class="card-header text-bg-primary">NTP Configuration</div> <div class="card-header text-bg-primary">NTP Configuration</div>
<div class="card-body"> <div class="card-body">
<div class="row mb-3"> <div class="row mb-3">
<label for="inputNtpServer" class="col-sm-2 col-form-label">Time Server:</label> <label for="inputNtpServer" class="col-sm-2 col-form-label">Time Server:
<BIconInfoCircle v-tooltip
title="The default value is fine as long as OpenDTU has direct access to the internet." />
</label>
<div class="col-sm-10"> <div class="col-sm-10">
<input type="text" class="form-control" id="inputNtpServer" maxlength="32" <input type="text" class="form-control" id="inputNtpServer" maxlength="32"
placeholder="Time Server" v-model="ntpConfigList.ntp_server" /> placeholder="Time Server" v-model="ntpConfigList.ntp_server" />
@ -78,11 +81,15 @@ import BasePage from '@/components/BasePage.vue';
import BootstrapAlert from "@/components/BootstrapAlert.vue"; import BootstrapAlert from "@/components/BootstrapAlert.vue";
import { handleResponse, authHeader } from '@/utils/authentication'; import { handleResponse, authHeader } from '@/utils/authentication';
import type { NtpConfig } from "@/types/NtpConfig"; import type { NtpConfig } from "@/types/NtpConfig";
import {
BIconInfoCircle,
} from 'bootstrap-icons-vue';
export default defineComponent({ export default defineComponent({
components: { components: {
BasePage, BasePage,
BootstrapAlert, BootstrapAlert,
BIconInfoCircle,
}, },
data() { data() {
return { return {