webapp: Implement BasePage component for default views
This commit is contained in:
parent
93512e2e0c
commit
03066af1c4
28
webapp/src/components/BasePage.vue
Normal file
28
webapp/src/components/BasePage.vue
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<template>
|
||||||
|
<div class="container-xxl" role="main">
|
||||||
|
<div class="page-header">
|
||||||
|
<h1>{{ title }}</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="text-center" v-if="isLoading">
|
||||||
|
<div class="spinner-border" role="status">
|
||||||
|
<span class="visually-hidden">Loading...</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<template v-if="!isLoading">
|
||||||
|
<slot />
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
props: {
|
||||||
|
title: { type: String, required: true },
|
||||||
|
isLoading: { type: Boolean, required: false, default: false }
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
@ -1,10 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container-xxl" role="main">
|
<BasePage :title="'About OpenDTU'">
|
||||||
<div class="page-header">
|
|
||||||
<h1>About OpenDTU</h1>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="accordion" id="accordionExample">
|
<div class="accordion" id="accordionExample">
|
||||||
<div class="accordion-item">
|
<div class="accordion-item">
|
||||||
<h2 class="accordion-header" id="headingOne">
|
<h2 class="accordion-header" id="headingOne">
|
||||||
@ -96,12 +91,13 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</BasePage>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
import BasePage from '@/components/BasePage.vue';
|
||||||
import {
|
import {
|
||||||
BIconInfoCircle,
|
BIconInfoCircle,
|
||||||
BIconActivity,
|
BIconActivity,
|
||||||
@ -111,6 +107,7 @@ import {
|
|||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
|
BasePage,
|
||||||
BIconInfoCircle,
|
BIconInfoCircle,
|
||||||
BIconActivity,
|
BIconActivity,
|
||||||
BIconBug,
|
BIconBug,
|
||||||
|
|||||||
@ -1,121 +1,110 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container-xxl" role="main">
|
<BasePage :title="'Config Management'" :isLoading="loading">
|
||||||
<div class="page-header">
|
|
||||||
<h1>Config Management</h1>
|
|
||||||
</div>
|
|
||||||
<BootstrapAlert v-model="showAlert" dismissible :variant="alertType">
|
<BootstrapAlert v-model="showAlert" dismissible :variant="alertType">
|
||||||
{{ alertMessage }}
|
{{ alertMessage }}
|
||||||
</BootstrapAlert>
|
</BootstrapAlert>
|
||||||
|
|
||||||
<div class="text-center" v-if="loading">
|
<div class="card">
|
||||||
<div class="spinner-border" role="status">
|
<div class="card-header text-white bg-primary">Backup: Configuration File Backup</div>
|
||||||
<span class="visually-hidden">Loading...</span>
|
<div class="card-body text-center">
|
||||||
|
Backup the configuration file
|
||||||
|
<button class="btn btn-primary" @click="downloadConfig">Backup
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<template v-if="!loading">
|
<div class="card mt-5">
|
||||||
<div class="card">
|
<div class="card-header text-white bg-primary">Restore: Restore the Configuration File</div>
|
||||||
<div class="card-header text-white bg-primary">Backup: Configuration File Backup</div>
|
<div class="card-body text-center">
|
||||||
<div class="card-body text-center">
|
|
||||||
Backup the configuration file
|
<div v-if="!uploading && UploadError != ''">
|
||||||
<button class="btn btn-primary" @click="downloadConfig">Backup
|
<p class="h1 mb-2">
|
||||||
|
<BIconExclamationCircleFill />
|
||||||
|
</p>
|
||||||
|
<span style="vertical-align: middle" class="ml-2">
|
||||||
|
{{ UploadError }}
|
||||||
|
</span>
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<button class="btn btn-light" @click="clear">
|
||||||
|
<BIconArrowLeft /> Back
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card mt-5">
|
<div v-else-if="!uploading && UploadSuccess">
|
||||||
<div class="card-header text-white bg-primary">Restore: Restore the Configuration File</div>
|
<span class="h1 mb-2">
|
||||||
<div class="card-body text-center">
|
<BIconCheckCircle />
|
||||||
|
</span>
|
||||||
<div v-if="!uploading && UploadError != ''">
|
<span> Upload Success </span>
|
||||||
<p class="h1 mb-2">
|
<br />
|
||||||
<BIconExclamationCircleFill />
|
<br />
|
||||||
</p>
|
<button class="btn btn-primary" @click="clear">
|
||||||
<span style="vertical-align: middle" class="ml-2">
|
<BIconArrowLeft /> Back
|
||||||
{{ UploadError }}
|
|
||||||
</span>
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
<button class="btn btn-light" @click="clear">
|
|
||||||
<BIconArrowLeft /> Back
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div v-else-if="!uploading && UploadSuccess">
|
|
||||||
<span class="h1 mb-2">
|
|
||||||
<BIconCheckCircle />
|
|
||||||
</span>
|
|
||||||
<span> Upload Success </span>
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
<button class="btn btn-primary" @click="clear">
|
|
||||||
<BIconArrowLeft /> Back
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div v-else-if="!uploading">
|
|
||||||
<div class="form-group pt-2 mt-3">
|
|
||||||
<input class="form-control" type="file" ref="file" accept=".json" @change="uploadConfig" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div v-else-if="uploading">
|
|
||||||
<div class="progress">
|
|
||||||
<div class="progress-bar" role="progressbar" :style="{ width: progress + '%' }"
|
|
||||||
v-bind:aria-valuenow="progress" aria-valuemin="0" aria-valuemax="100">
|
|
||||||
{{ progress }}%
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="alert alert-danger mt-3" role="alert">
|
|
||||||
<b>Note:</b> This operation replaces the configuration file with the restored configuration and
|
|
||||||
restarts OpenDTU to apply all settings.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card mt-5">
|
|
||||||
<div class="card-header text-white bg-primary">Initialize: Perform Factory Reset</div>
|
|
||||||
<div class="card-body text-center">
|
|
||||||
|
|
||||||
<button class="btn btn-danger" @click="onFactoryResetModal">Restore Factory-Default Settings
|
|
||||||
</button>
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="alert alert-danger mt-3" role="alert">
|
<div v-else-if="!uploading">
|
||||||
<b>Note:</b> Click Restore Factory-Default Settings to restore and initialize the
|
<div class="form-group pt-2 mt-3">
|
||||||
factory-default settings and reboot.
|
<input class="form-control" type="file" ref="file" accept=".json" @change="uploadConfig" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<div class="modal" id="factoryReset" tabindex="-1">
|
<div v-else-if="uploading">
|
||||||
<div class="modal-dialog">
|
<div class="progress">
|
||||||
<div class="modal-content">
|
<div class="progress-bar" role="progressbar" :style="{ width: progress + '%' }"
|
||||||
<div class="modal-header">
|
v-bind:aria-valuenow="progress" aria-valuemin="0" aria-valuemax="100">
|
||||||
<h5 class="modal-title">Factory Reset</h5>
|
{{ progress }}%
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
</div>
|
||||||
</div>
|
|
||||||
<div class="modal-body">
|
|
||||||
Are you sure you want to delete the current configuration and reset all settings to their
|
|
||||||
factory defaults?
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" class="btn btn-secondary" @click="onFactoryResetCancel"
|
|
||||||
data-bs-dismiss="modal">Cancel</button>
|
|
||||||
<button type="button" class="btn btn-danger" @click="onFactoryResetPerform">Factory
|
|
||||||
Reset!</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="alert alert-danger mt-3" role="alert">
|
||||||
|
<b>Note:</b> This operation replaces the configuration file with the restored configuration and
|
||||||
|
restarts OpenDTU to apply all settings.
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="card mt-5">
|
||||||
|
<div class="card-header text-white bg-primary">Initialize: Perform Factory Reset</div>
|
||||||
|
<div class="card-body text-center">
|
||||||
|
|
||||||
|
<button class="btn btn-danger" @click="onFactoryResetModal">Restore Factory-Default Settings
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div class="alert alert-danger mt-3" role="alert">
|
||||||
|
<b>Note:</b> Click Restore Factory-Default Settings to restore and initialize the
|
||||||
|
factory-default settings and reboot.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</BasePage>
|
||||||
|
|
||||||
|
<div class="modal" id="factoryReset" tabindex="-1">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title">Factory Reset</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
Are you sure you want to delete the current configuration and reset all settings to their
|
||||||
|
factory defaults?
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" @click="onFactoryResetCancel"
|
||||||
|
data-bs-dismiss="modal">Cancel</button>
|
||||||
|
<button type="button" class="btn btn-danger" @click="onFactoryResetPerform">Factory
|
||||||
|
Reset!</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
import BasePage from '@/components/BasePage.vue';
|
||||||
import {
|
import {
|
||||||
BIconExclamationCircleFill,
|
BIconExclamationCircleFill,
|
||||||
BIconArrowLeft,
|
BIconArrowLeft,
|
||||||
@ -126,6 +115,7 @@ import BootstrapAlert from "@/components/BootstrapAlert.vue";
|
|||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
|
BasePage,
|
||||||
BIconExclamationCircleFill,
|
BIconExclamationCircleFill,
|
||||||
BIconArrowLeft,
|
BIconArrowLeft,
|
||||||
BIconCheckCircle,
|
BIconCheckCircle,
|
||||||
|
|||||||
@ -1,68 +1,59 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container-xxl" role="main">
|
<BasePage :title="'DTU Settings'" :isLoading="dataLoading">
|
||||||
<div class="page-header">
|
|
||||||
<h1>DTU Settings</h1>
|
|
||||||
</div>
|
|
||||||
<BootstrapAlert v-model="showAlert" dismissible :variant="alertType">
|
<BootstrapAlert v-model="showAlert" dismissible :variant="alertType">
|
||||||
{{ alertMessage }}
|
{{ alertMessage }}
|
||||||
</BootstrapAlert>
|
</BootstrapAlert>
|
||||||
|
|
||||||
<div class="text-center" v-if="dataLoading">
|
<form @submit="saveDtuConfig">
|
||||||
<div class="spinner-border" role="status">
|
<div class="card">
|
||||||
<span class="visually-hidden">Loading...</span>
|
<div class="card-header text-white bg-primary">DTU Configuration</div>
|
||||||
</div>
|
<div class="card-body">
|
||||||
</div>
|
<div class="row mb-3">
|
||||||
|
<label for="inputDtuSerial" class="col-sm-2 col-form-label">Serial:</label>
|
||||||
<template v-if="!dataLoading">
|
<div class="col-sm-10">
|
||||||
<form @submit="saveDtuConfig">
|
<input type="number" class="form-control" id="inputDtuSerial" min="1" max="99999999999"
|
||||||
<div class="card">
|
placeholder="DTU Serial" v-model="dtuConfigList.dtu_serial" />
|
||||||
<div class="card-header text-white bg-primary">DTU Configuration</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="row mb-3">
|
|
||||||
<label for="inputDtuSerial" class="col-sm-2 col-form-label">Serial:</label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<input type="number" class="form-control" id="inputDtuSerial" min="1" max="99999999999"
|
|
||||||
placeholder="DTU Serial" v-model="dtuConfigList.dtu_serial" />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<label for="inputPollInterval" class="col-sm-2 col-form-label">Poll Interval:</label>
|
<label for="inputPollInterval" class="col-sm-2 col-form-label">Poll Interval:</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input type="number" class="form-control" id="inputPollInterval" min="1" max="86400"
|
<input type="number" class="form-control" id="inputPollInterval" min="1" max="86400"
|
||||||
placeholder="Poll Interval in Seconds" v-model="dtuConfigList.dtu_pollinterval"
|
placeholder="Poll Interval in Seconds" v-model="dtuConfigList.dtu_pollinterval"
|
||||||
aria-describedby="pollIntervalDescription" />
|
aria-describedby="pollIntervalDescription" />
|
||||||
<span class="input-group-text" id="pollIntervalDescription">seconds</span>
|
<span class="input-group-text" id="pollIntervalDescription">seconds</span>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row mb-3">
|
|
||||||
<label for="inputTimezone" class="col-sm-2 col-form-label">PA Level:</label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<select class="form-select" v-model="dtuConfigList.dtu_palevel">
|
|
||||||
<option v-for="palevel in palevelList" :key="palevel.key" :value="palevel.key">
|
|
||||||
{{ palevel.value }}
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<label for="inputTimezone" class="col-sm-2 col-form-label">PA Level:</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<select class="form-select" v-model="dtuConfigList.dtu_palevel">
|
||||||
|
<option v-for="palevel in palevelList" :key="palevel.key" :value="palevel.key">
|
||||||
|
{{ palevel.value }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" class="btn btn-primary mb-3">Save</button>
|
</div>
|
||||||
</form>
|
<button type="submit" class="btn btn-primary mb-3">Save</button>
|
||||||
</template>
|
</form>
|
||||||
</div>
|
</BasePage>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
import BasePage from '@/components/BasePage.vue';
|
||||||
import BootstrapAlert from "@/components/BootstrapAlert.vue";
|
import BootstrapAlert from "@/components/BootstrapAlert.vue";
|
||||||
import type { DtuConfig } from "@/types/DtuConfig";
|
import type { DtuConfig } from "@/types/DtuConfig";
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
|
BasePage,
|
||||||
BootstrapAlert,
|
BootstrapAlert,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
|||||||
@ -1,9 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container-xxl" role="main">
|
<BasePage :title="'Firmware Upgrade'">
|
||||||
<div class="page-header">
|
|
||||||
<h1>Firmware Upgrade</h1>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="position-relative" v-if="loading">
|
<div class="position-relative" v-if="loading">
|
||||||
<div class="position-absolute top-50 start-50 translate-middle">
|
<div class="position-absolute top-50 start-50 translate-middle">
|
||||||
<div class="spinner-border" role="status">
|
<div class="spinner-border" role="status">
|
||||||
@ -68,11 +64,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</BasePage>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
import BasePage from '@/components/BasePage.vue';
|
||||||
import SparkMD5 from "spark-md5";
|
import SparkMD5 from "spark-md5";
|
||||||
import {
|
import {
|
||||||
BIconExclamationCircleFill,
|
BIconExclamationCircleFill,
|
||||||
@ -83,6 +80,7 @@ import {
|
|||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
|
BasePage,
|
||||||
BIconExclamationCircleFill,
|
BIconExclamationCircleFill,
|
||||||
BIconArrowLeft,
|
BIconArrowLeft,
|
||||||
BIconArrowRepeat,
|
BIconArrowRepeat,
|
||||||
|
|||||||
@ -1,9 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container-xxl" role="main">
|
<BasePage :title="'Inverter Settings'" :isLoading="dataLoading">
|
||||||
<div class="page-header">
|
|
||||||
<h1>Inverter Settings</h1>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<BootstrapAlert v-model="showAlert" dismissible :variant="alertType">
|
<BootstrapAlert v-model="showAlert" dismissible :variant="alertType">
|
||||||
{{ alertMessage }}
|
{{ alertMessage }}
|
||||||
</BootstrapAlert>
|
</BootstrapAlert>
|
||||||
@ -72,80 +68,79 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</BasePage>
|
||||||
|
|
||||||
<div class="modal" id="inverterEdit" tabindex="-1">
|
<div class="modal" id="inverterEdit" tabindex="-1">
|
||||||
<div class="modal-dialog">
|
<div class="modal-dialog">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h5 class="modal-title">Edit Inverter</h5>
|
<h5 class="modal-title">Edit Inverter</h5>
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|
||||||
<form>
|
<form>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="inverter-serial" class="col-form-label">Serial:</label>
|
<label for="inverter-serial" class="col-form-label">Serial:</label>
|
||||||
<input v-model="editInverterData.serial" type="number" id="inverter-serial"
|
<input v-model="editInverterData.serial" type="number" id="inverter-serial"
|
||||||
class="form-control" />
|
class="form-control" />
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="inverter-name" class="col-form-label">Name:</label>
|
<label for="inverter-name" class="col-form-label">Name:</label>
|
||||||
<input v-model="editInverterData.name" type="text" id="inverter-name"
|
<input v-model="editInverterData.name" type="text" id="inverter-name" class="form-control"
|
||||||
class="form-control" maxlength="31" />
|
maxlength="31" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3" v-for="(max, index) in editInverterData.max_power" :key="`${index}`">
|
||||||
|
<label :for="`inverter-max_${index}`" class="col-form-label">Max power string {{ index +
|
||||||
|
1
|
||||||
|
}}:</label>
|
||||||
|
<div class="input-group">
|
||||||
|
<input type="number" class="form-control" :id="`inverter-max_${index}`" min="0"
|
||||||
|
v-model="editInverterData.max_power[index]"
|
||||||
|
:aria-describedby="`inverter-maxDescription_${index} inverter-maxHelpText_${index}`" />
|
||||||
|
<span class="input-group-text" :id="`inverter-maxDescription_${index}`">W</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div :id="`inverter-maxHelpText_${index}`" class="form-text">This value is used to
|
||||||
|
calculate the Irradiation.</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
<div class="mb-3" v-for="(max, index) in editInverterData.max_power" :key="`${index}`">
|
</div>
|
||||||
<label :for="`inverter-max_${index}`" class="col-form-label">Max power string {{ index +
|
<div class="modal-footer">
|
||||||
1
|
<button type="button" class="btn btn-secondary" @click="onCancel"
|
||||||
}}:</label>
|
data-bs-dismiss="modal">Cancel</button>
|
||||||
<div class="input-group">
|
<button type="button" class="btn btn-primary" @click="onEditSubmit(editId)">Save
|
||||||
<input type="number" class="form-control" :id="`inverter-max_${index}`" min="0"
|
changes</button>
|
||||||
v-model="editInverterData.max_power[index]"
|
|
||||||
:aria-describedby="`inverter-maxDescription_${index} inverter-maxHelpText_${index}`" />
|
|
||||||
<span class="input-group-text" :id="`inverter-maxDescription_${index}`">W</span>
|
|
||||||
</div>
|
|
||||||
<div :id="`inverter-maxHelpText_${index}`" class="form-text">This value is used to
|
|
||||||
calculate the Irradiation.</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" class="btn btn-secondary" @click="onCancel"
|
|
||||||
data-bs-dismiss="modal">Cancel</button>
|
|
||||||
<button type="button" class="btn btn-primary" @click="onEditSubmit(editId)">Save
|
|
||||||
changes</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="modal" id="inverterDelete" tabindex="-1">
|
<div class="modal" id="inverterDelete" tabindex="-1">
|
||||||
<div class="modal-dialog">
|
<div class="modal-dialog">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h5 class="modal-title">Delete Inverter</h5>
|
<h5 class="modal-title">Delete Inverter</h5>
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
Are you sure you want to delete the inverter "{{ deleteInverterData.name }}" with serial number
|
Are you sure you want to delete the inverter "{{ deleteInverterData.name }}" with serial number
|
||||||
{{ deleteInverterData.serial }}?
|
{{ deleteInverterData.serial }}?
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" class="btn btn-secondary" @click="onDeleteCancel"
|
<button type="button" class="btn btn-secondary" @click="onDeleteCancel"
|
||||||
data-bs-dismiss="modal">Cancel</button>
|
data-bs-dismiss="modal">Cancel</button>
|
||||||
<button type="button" class="btn btn-danger"
|
<button type="button" class="btn btn-danger" @click="onDelete(deleteId.toString())">Delete</button>
|
||||||
@click="onDelete(deleteId.toString())">Delete</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
import BasePage from '@/components/BasePage.vue';
|
||||||
import {
|
import {
|
||||||
BIconTrash,
|
BIconTrash,
|
||||||
BIconPencil
|
BIconPencil
|
||||||
@ -163,6 +158,7 @@ declare interface Inverter {
|
|||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
|
BasePage,
|
||||||
BootstrapAlert,
|
BootstrapAlert,
|
||||||
BIconTrash,
|
BIconTrash,
|
||||||
BIconPencil,
|
BIconPencil,
|
||||||
@ -177,6 +173,7 @@ export default defineComponent({
|
|||||||
editInverterData: {} as Inverter,
|
editInverterData: {} as Inverter,
|
||||||
deleteInverterData: {} as Inverter,
|
deleteInverterData: {} as Inverter,
|
||||||
inverters: [] as Inverter[],
|
inverters: [] as Inverter[],
|
||||||
|
dataLoading: true,
|
||||||
alertMessage: "",
|
alertMessage: "",
|
||||||
alertType: "info",
|
alertType: "info",
|
||||||
showAlert: false,
|
showAlert: false,
|
||||||
@ -198,9 +195,13 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getInverters() {
|
getInverters() {
|
||||||
|
this.dataLoading = true;
|
||||||
fetch("/api/inverter/list")
|
fetch("/api/inverter/list")
|
||||||
.then((response) => response.json())
|
.then((response) => response.json())
|
||||||
.then((data) => (this.inverters = data.inverter));
|
.then((data) => {
|
||||||
|
this.inverters = data.inverter;
|
||||||
|
this.dataLoading = false;
|
||||||
|
});
|
||||||
},
|
},
|
||||||
onSubmit() {
|
onSubmit() {
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
|
|||||||
@ -1,237 +1,228 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container-xxl" role="main">
|
<BasePage :title="'MqTT Settings'" :isLoading="dataLoading">
|
||||||
<div class="page-header">
|
|
||||||
<h1>MqTT Settings</h1>
|
|
||||||
</div>
|
|
||||||
<BootstrapAlert v-model="showAlert" dismissible :variant="alertType">
|
<BootstrapAlert v-model="showAlert" dismissible :variant="alertType">
|
||||||
{{ alertMessage }}
|
{{ alertMessage }}
|
||||||
</BootstrapAlert>
|
</BootstrapAlert>
|
||||||
|
|
||||||
<div class="text-center" v-if="dataLoading">
|
<form @submit="saveMqttConfig">
|
||||||
<div class="spinner-border" role="status">
|
<div class="card">
|
||||||
<span class="visually-hidden">Loading...</span>
|
<div class="card-header text-white bg-primary">MqTT Configuration</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row mb-3">
|
||||||
|
<label class="col-sm-4 form-check-label" for="inputMqtt">Enable MqTT</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<div class="form-check form-switch">
|
||||||
|
<input class="form-check-input" type="checkbox" id="inputMqtt"
|
||||||
|
v-model="mqttConfigList.mqtt_enabled" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3" v-show="mqttConfigList.mqtt_enabled">
|
||||||
|
<label class="col-sm-4 form-check-label" for="inputMqttHass">Enable Home Assistant MQTT Auto
|
||||||
|
Discovery</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<div class="form-check form-switch">
|
||||||
|
<input class="form-check-input" type="checkbox" id="inputMqttHass"
|
||||||
|
v-model="mqttConfigList.mqtt_hass_enabled" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<template v-if="!dataLoading">
|
<div class="card mt-5" v-show="mqttConfigList.mqtt_enabled">
|
||||||
<form @submit="saveMqttConfig">
|
<div class="card-header text-white bg-primary">
|
||||||
<div class="card">
|
MqTT Broker Parameter
|
||||||
<div class="card-header text-white bg-primary">MqTT Configuration</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="row mb-3">
|
|
||||||
<label class="col-sm-4 form-check-label" for="inputMqtt">Enable MqTT</label>
|
|
||||||
<div class="col-sm-8">
|
|
||||||
<div class="form-check form-switch">
|
|
||||||
<input class="form-check-input" type="checkbox" id="inputMqtt"
|
|
||||||
v-model="mqttConfigList.mqtt_enabled" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row mb-3" v-show="mqttConfigList.mqtt_enabled">
|
|
||||||
<label class="col-sm-4 form-check-label" for="inputMqttHass">Enable Home Assistant MQTT Auto
|
|
||||||
Discovery</label>
|
|
||||||
<div class="col-sm-8">
|
|
||||||
<div class="form-check form-switch">
|
|
||||||
<input class="form-check-input" type="checkbox" id="inputMqttHass"
|
|
||||||
v-model="mqttConfigList.mqtt_hass_enabled" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
<div class="card mt-5" v-show="mqttConfigList.mqtt_enabled">
|
<div class="row mb-3">
|
||||||
<div class="card-header text-white bg-primary">
|
<label for="inputHostname" class="col-sm-2 col-form-label">Hostname:</label>
|
||||||
MqTT Broker Parameter
|
<div class="col-sm-10">
|
||||||
|
<input type="text" class="form-control" id="inputHostname" maxlength="128"
|
||||||
|
placeholder="Hostname or IP address" v-model="mqttConfigList.mqtt_hostname" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<label for="inputHostname" class="col-sm-2 col-form-label">Hostname:</label>
|
<label for="inputPort" class="col-sm-2 col-form-label">Port:</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<input type="text" class="form-control" id="inputHostname" maxlength="128"
|
<input type="number" class="form-control" id="inputPort" min="1" max="65535"
|
||||||
placeholder="Hostname or IP address" v-model="mqttConfigList.mqtt_hostname" />
|
placeholder="Port number" v-model="mqttConfigList.mqtt_port" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<label for="inputUsername" class="col-sm-2 col-form-label">Username:</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input type="text" class="form-control" id="inputUsername" maxlength="32"
|
||||||
|
placeholder="Username, leave empty for anonymous connection"
|
||||||
|
v-model="mqttConfigList.mqtt_username" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<label for="inputPassword" class="col-sm-2 col-form-label">Password:</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input type="password" class="form-control" id="inputPassword" maxlength="32"
|
||||||
|
placeholder="Password, leave empty for anonymous connection"
|
||||||
|
v-model="mqttConfigList.mqtt_password" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<label for="inputTopic" class="col-sm-2 col-form-label">Base Topic:</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input type="text" class="form-control" id="inputTopic" maxlength="32"
|
||||||
|
placeholder="Base topic, will be prepend to all published topics (e.g. inverter/)"
|
||||||
|
v-model="mqttConfigList.mqtt_topic" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<label for="inputPublishInterval" class="col-sm-2 col-form-label">Publish Interval:</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<div class="input-group">
|
||||||
|
<input type="number" class="form-control" id="inputPublishInterval" min="5" max="86400"
|
||||||
|
placeholder="Publish Interval in Seconds"
|
||||||
|
v-model="mqttConfigList.mqtt_publish_interval"
|
||||||
|
aria-describedby="publishIntervalDescription" />
|
||||||
|
<span class="input-group-text" id="publishIntervalDescription">seconds</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<label for="inputPort" class="col-sm-2 col-form-label">Port:</label>
|
<label class="col-sm-2 form-check-label" for="inputRetain">Enable Retain Flag</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<input type="number" class="form-control" id="inputPort" min="1" max="65535"
|
<div class="form-check form-switch">
|
||||||
placeholder="Port number" v-model="mqttConfigList.mqtt_port" />
|
<input class="form-check-input" type="checkbox" id="inputRetain"
|
||||||
|
v-model="mqttConfigList.mqtt_retain" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<label for="inputUsername" class="col-sm-2 col-form-label">Username:</label>
|
<label class="col-sm-2 form-check-label" for="inputTls">Enable TLS</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<input type="text" class="form-control" id="inputUsername" maxlength="32"
|
<div class="form-check form-switch">
|
||||||
placeholder="Username, leave empty for anonymous connection"
|
<input class="form-check-input" type="checkbox" id="inputTls"
|
||||||
v-model="mqttConfigList.mqtt_username" />
|
v-model="mqttConfigList.mqtt_tls" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="row mb-3">
|
<div class="row mb-3" v-show="mqttConfigList.mqtt_tls">
|
||||||
<label for="inputPassword" class="col-sm-2 col-form-label">Password:</label>
|
<label for="inputCert" class="col-sm-2 col-form-label">CA-Root-Certificate (default
|
||||||
<div class="col-sm-10">
|
Letsencrypt):</label>
|
||||||
<input type="password" class="form-control" id="inputPassword" maxlength="32"
|
<div class="col-sm-10">
|
||||||
placeholder="Password, leave empty for anonymous connection"
|
<textarea class="form-control" id="inputCert" maxlength="2048" rows="10"
|
||||||
v-model="mqttConfigList.mqtt_password" />
|
placeholder="Root CA Certificate from Letsencrypt"
|
||||||
</div>
|
v-model="mqttConfigList.mqtt_root_ca_cert">
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row mb-3">
|
|
||||||
<label for="inputTopic" class="col-sm-2 col-form-label">Base Topic:</label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<input type="text" class="form-control" id="inputTopic" maxlength="32"
|
|
||||||
placeholder="Base topic, will be prepend to all published topics (e.g. inverter/)"
|
|
||||||
v-model="mqttConfigList.mqtt_topic" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row mb-3">
|
|
||||||
<label for="inputPublishInterval" class="col-sm-2 col-form-label">Publish Interval:</label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<div class="input-group">
|
|
||||||
<input type="number" class="form-control" id="inputPublishInterval" min="5"
|
|
||||||
max="86400" placeholder="Publish Interval in Seconds"
|
|
||||||
v-model="mqttConfigList.mqtt_publish_interval"
|
|
||||||
aria-describedby="publishIntervalDescription" />
|
|
||||||
<span class="input-group-text" id="publishIntervalDescription">seconds</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row mb-3">
|
|
||||||
<label class="col-sm-2 form-check-label" for="inputRetain">Enable Retain Flag</label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<div class="form-check form-switch">
|
|
||||||
<input class="form-check-input" type="checkbox" id="inputRetain"
|
|
||||||
v-model="mqttConfigList.mqtt_retain" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row mb-3">
|
|
||||||
<label class="col-sm-2 form-check-label" for="inputTls">Enable TLS</label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<div class="form-check form-switch">
|
|
||||||
<input class="form-check-input" type="checkbox" id="inputTls"
|
|
||||||
v-model="mqttConfigList.mqtt_tls" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row mb-3" v-show="mqttConfigList.mqtt_tls">
|
|
||||||
<label for="inputCert" class="col-sm-2 col-form-label">CA-Root-Certificate (default
|
|
||||||
Letsencrypt):</label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<textarea class="form-control" id="inputCert" maxlength="2048" rows="10"
|
|
||||||
placeholder="Root CA Certificate from Letsencrypt"
|
|
||||||
v-model="mqttConfigList.mqtt_root_ca_cert">
|
|
||||||
</textarea>
|
</textarea>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="card mt-5" v-show="mqttConfigList.mqtt_enabled">
|
<div class="card mt-5" v-show="mqttConfigList.mqtt_enabled">
|
||||||
<div class="card-header text-white bg-primary">LWT Parameters</div>
|
<div class="card-header text-white bg-primary">LWT Parameters</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<label for="inputLwtTopic" class="col-sm-2 col-form-label">LWT Topic:</label>
|
<label for="inputLwtTopic" class="col-sm-2 col-form-label">LWT Topic:</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<span class="input-group-text" id="basic-addon3">{{
|
<span class="input-group-text" id="basic-addon3">{{
|
||||||
mqttConfigList.mqtt_topic
|
mqttConfigList.mqtt_topic
|
||||||
}}</span>
|
}}</span>
|
||||||
<input type="text" class="form-control" id="inputLwtTopic" maxlength="32"
|
<input type="text" class="form-control" id="inputLwtTopic" maxlength="32"
|
||||||
placeholder="LWT topic, will be append base topic"
|
placeholder="LWT topic, will be append base topic"
|
||||||
v-model="mqttConfigList.mqtt_lwt_topic" aria-describedby="basic-addon3" />
|
v-model="mqttConfigList.mqtt_lwt_topic" aria-describedby="basic-addon3" />
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row mb-3">
|
|
||||||
<label for="inputLwtOnline" class="col-sm-2 col-form-label">LWT Online message:</label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<input type="text" class="form-control" id="inputLwtOnline" maxlength="20"
|
|
||||||
placeholder="Message that will be published to LWT topic when online"
|
|
||||||
v-model="mqttConfigList.mqtt_lwt_online" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row mb-3">
|
|
||||||
<label for="inputLwtOffline" class="col-sm-2 col-form-label">LWT Offline message:</label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<input type="text" class="form-control" id="inputLwtOffline" maxlength="20"
|
|
||||||
placeholder="Message that will be published to LWT topic when offline"
|
|
||||||
v-model="mqttConfigList.mqtt_lwt_offline" />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card mt-5" v-show="mqttConfigList.mqtt_enabled && mqttConfigList.mqtt_hass_enabled">
|
<div class="row mb-3">
|
||||||
<div class="card-header text-white bg-primary">Home Assistant MQTT Auto Discovery Parameters</div>
|
<label for="inputLwtOnline" class="col-sm-2 col-form-label">LWT Online message:</label>
|
||||||
<div class="card-body">
|
<div class="col-sm-10">
|
||||||
<div class="row mb-3">
|
<input type="text" class="form-control" id="inputLwtOnline" maxlength="20"
|
||||||
<label for="inputHassTopic" class="col-sm-2 col-form-label">Prefix Topic:</label>
|
placeholder="Message that will be published to LWT topic when online"
|
||||||
<div class="col-sm-10">
|
v-model="mqttConfigList.mqtt_lwt_online" />
|
||||||
<input type="text" class="form-control" id="inputHassTopic" maxlength="32"
|
|
||||||
placeholder="The prefix for the discovery topic"
|
|
||||||
v-model="mqttConfigList.mqtt_hass_topic" />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<label class="col-sm-2 form-check-label" for="inputHassRetain">Enable Retain Flag</label>
|
<label for="inputLwtOffline" class="col-sm-2 col-form-label">LWT Offline message:</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<div class="form-check form-switch">
|
<input type="text" class="form-control" id="inputLwtOffline" maxlength="20"
|
||||||
<input class="form-check-input" type="checkbox" id="inputHassRetain"
|
placeholder="Message that will be published to LWT topic when offline"
|
||||||
v-model="mqttConfigList.mqtt_hass_retain" />
|
v-model="mqttConfigList.mqtt_lwt_offline" />
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row mb-3">
|
|
||||||
<label class="col-sm-2 form-check-label" for="inputHassExpire">Enable Expiration</label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<div class="form-check form-switch">
|
|
||||||
<input class="form-check-input" type="checkbox" id="inputHassExpire"
|
|
||||||
v-model="mqttConfigList.mqtt_hass_expire" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row mb-3">
|
|
||||||
<label class="col-sm-2 form-check-label" for="inputIndividualPanels">Individual
|
|
||||||
Panels:</label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<div class="form-check form-switch">
|
|
||||||
<input class="form-check-input" type="checkbox" id="inputIndividualPanels"
|
|
||||||
v-model="mqttConfigList.mqtt_hass_individualpanels" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<button type="submit" class="btn btn-primary mb-3">Save</button>
|
<div class="card mt-5" v-show="mqttConfigList.mqtt_enabled && mqttConfigList.mqtt_hass_enabled">
|
||||||
</form>
|
<div class="card-header text-white bg-primary">Home Assistant MQTT Auto Discovery Parameters</div>
|
||||||
</template>
|
<div class="card-body">
|
||||||
</div>
|
<div class="row mb-3">
|
||||||
|
<label for="inputHassTopic" class="col-sm-2 col-form-label">Prefix Topic:</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input type="text" class="form-control" id="inputHassTopic" maxlength="32"
|
||||||
|
placeholder="The prefix for the discovery topic"
|
||||||
|
v-model="mqttConfigList.mqtt_hass_topic" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<label class="col-sm-2 form-check-label" for="inputHassRetain">Enable Retain Flag</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<div class="form-check form-switch">
|
||||||
|
<input class="form-check-input" type="checkbox" id="inputHassRetain"
|
||||||
|
v-model="mqttConfigList.mqtt_hass_retain" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<label class="col-sm-2 form-check-label" for="inputHassExpire">Enable Expiration</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<div class="form-check form-switch">
|
||||||
|
<input class="form-check-input" type="checkbox" id="inputHassExpire"
|
||||||
|
v-model="mqttConfigList.mqtt_hass_expire" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<label class="col-sm-2 form-check-label" for="inputIndividualPanels">Individual
|
||||||
|
Panels:</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<div class="form-check form-switch">
|
||||||
|
<input class="form-check-input" type="checkbox" id="inputIndividualPanels"
|
||||||
|
v-model="mqttConfigList.mqtt_hass_individualpanels" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit" class="btn btn-primary mb-3">Save</button>
|
||||||
|
</form>
|
||||||
|
</BasePage>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
import BasePage from '@/components/BasePage.vue';
|
||||||
import BootstrapAlert from "@/components/BootstrapAlert.vue";
|
import BootstrapAlert from "@/components/BootstrapAlert.vue";
|
||||||
import type { MqttConfig } from "@/types/MqttConfig";
|
import type { MqttConfig } from "@/types/MqttConfig";
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
|
BasePage,
|
||||||
BootstrapAlert,
|
BootstrapAlert,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
|||||||
@ -1,168 +1,161 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container-xxl" role="main">
|
<BasePage :title="'MqTT Info'" :isLoading="dataLoading">
|
||||||
<div class="page-header">
|
<div class="card">
|
||||||
<h1>MqTT Info</h1>
|
<div class="card-header text-white bg-primary">Configuration Summary</div>
|
||||||
</div>
|
<div class="card-body">
|
||||||
|
<div class="table-responsive">
|
||||||
<div class="text-center" v-if="dataLoading">
|
<table class="table table-hover table-condensed">
|
||||||
<div class="spinner-border" role="status">
|
<tbody>
|
||||||
<span class="visually-hidden">Loading...</span>
|
<tr>
|
||||||
|
<th>Status</th>
|
||||||
|
<td class="badge" :class="{
|
||||||
|
'bg-danger': !mqttDataList.mqtt_enabled,
|
||||||
|
'bg-success': mqttDataList.mqtt_enabled,
|
||||||
|
}">
|
||||||
|
<span v-if="mqttDataList.mqtt_enabled">enabled</span>
|
||||||
|
<span v-else>disabled</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Server</th>
|
||||||
|
<td>{{ mqttDataList.mqtt_hostname }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Port</th>
|
||||||
|
<td>{{ mqttDataList.mqtt_port }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Username</th>
|
||||||
|
<td>{{ mqttDataList.mqtt_username }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Base Topic</th>
|
||||||
|
<td>{{ mqttDataList.mqtt_topic }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Publish Interval</th>
|
||||||
|
<td>{{ mqttDataList.mqtt_publish_interval }} seconds</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Retain</th>
|
||||||
|
<td class="badge" :class="{
|
||||||
|
'bg-danger': !mqttDataList.mqtt_retain,
|
||||||
|
'bg-success': mqttDataList.mqtt_retain,
|
||||||
|
}">
|
||||||
|
<span v-if="mqttDataList.mqtt_retain">enabled</span>
|
||||||
|
<span v-else>disabled</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>TLS</th>
|
||||||
|
<td class="badge" :class="{
|
||||||
|
'bg-danger': !mqttDataList.mqtt_tls,
|
||||||
|
'bg-success': mqttDataList.mqtt_tls,
|
||||||
|
}">
|
||||||
|
<span v-if="mqttDataList.mqtt_tls">enabled</span>
|
||||||
|
<span v-else>disabled</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr v-show="mqttDataList.mqtt_tls">
|
||||||
|
<th>Root CA Certifcate Info</th>
|
||||||
|
<td>{{ mqttDataList.mqtt_root_ca_cert_info }}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<template v-if="!dataLoading">
|
<div class="card mt-5">
|
||||||
<div class="card">
|
<div class="card-header text-white bg-primary">Home Assistant MQTT Auto Discovery Configuration Summary
|
||||||
<div class="card-header text-white bg-primary">Configuration Summary</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-hover table-condensed">
|
<table class="table table-hover table-condensed">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Status</th>
|
<th>Status</th>
|
||||||
<td class="badge" :class="{
|
<td class="badge" :class="{
|
||||||
'bg-danger': !mqttDataList.mqtt_enabled,
|
'bg-danger': !mqttDataList.mqtt_hass_enabled,
|
||||||
'bg-success': mqttDataList.mqtt_enabled,
|
'bg-success': mqttDataList.mqtt_hass_enabled,
|
||||||
}">
|
}">
|
||||||
<span v-if="mqttDataList.mqtt_enabled">enabled</span>
|
<span v-if="mqttDataList.mqtt_hass_enabled">enabled</span>
|
||||||
<span v-else>disabled</span>
|
<span v-else>disabled</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Server</th>
|
<th>Base Topic</th>
|
||||||
<td>{{ mqttDataList.mqtt_hostname }}</td>
|
<td>{{ mqttDataList.mqtt_hass_topic }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Port</th>
|
<th>Retain</th>
|
||||||
<td>{{ mqttDataList.mqtt_port }}</td>
|
<td class="badge" :class="{
|
||||||
</tr>
|
'bg-danger': !mqttDataList.mqtt_hass_retain,
|
||||||
<tr>
|
'bg-success': mqttDataList.mqtt_hass_retain,
|
||||||
<th>Username</th>
|
}">
|
||||||
<td>{{ mqttDataList.mqtt_username }}</td>
|
<span v-if="mqttDataList.mqtt_hass_retain">enabled</span>
|
||||||
</tr>
|
<span v-else>disabled</span>
|
||||||
<tr>
|
</td>
|
||||||
<th>Base Topic</th>
|
</tr>
|
||||||
<td>{{ mqttDataList.mqtt_topic }}</td>
|
<tr>
|
||||||
</tr>
|
<th>Expire</th>
|
||||||
<tr>
|
<td class="badge" :class="{
|
||||||
<th>Publish Interval</th>
|
'bg-danger': !mqttDataList.mqtt_hass_expire,
|
||||||
<td>{{ mqttDataList.mqtt_publish_interval }} seconds</td>
|
'bg-success': mqttDataList.mqtt_hass_expire,
|
||||||
</tr>
|
}">
|
||||||
<tr>
|
<span v-if="mqttDataList.mqtt_hass_expire">enabled</span>
|
||||||
<th>Retain</th>
|
<span v-else>disabled</span>
|
||||||
<td class="badge" :class="{
|
</td>
|
||||||
'bg-danger': !mqttDataList.mqtt_retain,
|
</tr>
|
||||||
'bg-success': mqttDataList.mqtt_retain,
|
<tr>
|
||||||
}">
|
<th>Individual Panels</th>
|
||||||
<span v-if="mqttDataList.mqtt_retain">enabled</span>
|
<td class="badge" :class="{
|
||||||
<span v-else>disabled</span>
|
'bg-danger': !mqttDataList.mqtt_hass_individualpanels,
|
||||||
</td>
|
'bg-success': mqttDataList.mqtt_hass_individualpanels,
|
||||||
</tr>
|
}">
|
||||||
<tr>
|
<span v-if="mqttDataList.mqtt_hass_individualpanels">enabled</span>
|
||||||
<th>TLS</th>
|
<span v-else>disabled</span>
|
||||||
<td class="badge" :class="{
|
</td>
|
||||||
'bg-danger': !mqttDataList.mqtt_tls,
|
</tr>
|
||||||
'bg-success': mqttDataList.mqtt_tls,
|
</tbody>
|
||||||
}">
|
</table>
|
||||||
<span v-if="mqttDataList.mqtt_tls">enabled</span>
|
|
||||||
<span v-else>disabled</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr v-show="mqttDataList.mqtt_tls">
|
|
||||||
<th>Root CA Certifcate Info</th>
|
|
||||||
<td>{{ mqttDataList.mqtt_root_ca_cert_info }}</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="card mt-5">
|
<div class="card mt-5">
|
||||||
<div class="card-header text-white bg-primary">Home Assistant MQTT Auto Discovery Configuration Summary</div>
|
<div class="card-header text-white bg-primary">Runtime Summary</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-hover table-condensed">
|
<table class="table table-hover table-condensed">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Status</th>
|
<th>Connection Status</th>
|
||||||
<td class="badge" :class="{
|
<td class="badge" :class="{
|
||||||
'bg-danger': !mqttDataList.mqtt_hass_enabled,
|
'bg-danger': !mqttDataList.mqtt_connected,
|
||||||
'bg-success': mqttDataList.mqtt_hass_enabled,
|
'bg-success': mqttDataList.mqtt_connected,
|
||||||
}">
|
}">
|
||||||
<span v-if="mqttDataList.mqtt_hass_enabled">enabled</span>
|
<span v-if="mqttDataList.mqtt_connected">connected</span>
|
||||||
<span v-else>disabled</span>
|
<span v-else>disconnected</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
</tbody>
|
||||||
<th>Base Topic</th>
|
</table>
|
||||||
<td>{{ mqttDataList.mqtt_hass_topic }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>Retain</th>
|
|
||||||
<td class="badge" :class="{
|
|
||||||
'bg-danger': !mqttDataList.mqtt_hass_retain,
|
|
||||||
'bg-success': mqttDataList.mqtt_hass_retain,
|
|
||||||
}">
|
|
||||||
<span v-if="mqttDataList.mqtt_hass_retain">enabled</span>
|
|
||||||
<span v-else>disabled</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>Expire</th>
|
|
||||||
<td class="badge" :class="{
|
|
||||||
'bg-danger': !mqttDataList.mqtt_hass_expire,
|
|
||||||
'bg-success': mqttDataList.mqtt_hass_expire,
|
|
||||||
}">
|
|
||||||
<span v-if="mqttDataList.mqtt_hass_expire">enabled</span>
|
|
||||||
<span v-else>disabled</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>Individual Panels</th>
|
|
||||||
<td class="badge" :class="{
|
|
||||||
'bg-danger': !mqttDataList.mqtt_hass_individualpanels,
|
|
||||||
'bg-success': mqttDataList.mqtt_hass_individualpanels,
|
|
||||||
}">
|
|
||||||
<span v-if="mqttDataList.mqtt_hass_individualpanels">enabled</span>
|
|
||||||
<span v-else>disabled</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<div class="card mt-5">
|
</BasePage>
|
||||||
<div class="card-header text-white bg-primary">Runtime Summary</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="table-responsive">
|
|
||||||
<table class="table table-hover table-condensed">
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<th>Connection Status</th>
|
|
||||||
<td class="badge" :class="{
|
|
||||||
'bg-danger': !mqttDataList.mqtt_connected,
|
|
||||||
'bg-success': mqttDataList.mqtt_connected,
|
|
||||||
}">
|
|
||||||
<span v-if="mqttDataList.mqtt_connected">connected</span>
|
|
||||||
<span v-else>disconnected</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { MqttStatus } from '@/types/MqttStatus';
|
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
import BasePage from '@/components/BasePage.vue';
|
||||||
|
import type { MqttStatus } from '@/types/MqttStatus';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
|
components: {
|
||||||
|
BasePage,
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
dataLoading: true,
|
dataLoading: true,
|
||||||
|
|||||||
@ -1,123 +1,114 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container-xxl" role="main">
|
<BasePage :title="'Network Settings'" :isLoading="dataLoading">
|
||||||
<div class="page-header">
|
|
||||||
<h1>Network Settings</h1>
|
|
||||||
</div>
|
|
||||||
<BootstrapAlert v-model="showAlert" dismissible :variant="alertType">
|
<BootstrapAlert v-model="showAlert" dismissible :variant="alertType">
|
||||||
{{ alertMessage }}
|
{{ alertMessage }}
|
||||||
</BootstrapAlert>
|
</BootstrapAlert>
|
||||||
|
|
||||||
<div class="text-center" v-if="dataLoading">
|
<form @submit="saveNetworkConfig">
|
||||||
<div class="spinner-border" role="status">
|
<div class="card">
|
||||||
<span class="visually-hidden">Loading...</span>
|
<div class="card-header text-white bg-primary">WiFi Configuration</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row mb-3">
|
||||||
|
<label for="inputSSID" class="col-sm-2 col-form-label">WiFi SSID:</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input type="text" class="form-control" id="inputSSID" maxlength="32" placeholder="SSID"
|
||||||
|
v-model="networkConfigList.ssid" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<label for="inputPassword" class="col-sm-2 col-form-label">WiFi Password:</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input type="password" class="form-control" id="inputPassword" maxlength="64"
|
||||||
|
placeholder="PSK" v-model="networkConfigList.password" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<label for="inputHostname" class="col-sm-2 col-form-label">Hostname:</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input type="text" class="form-control" id="inputHostname" maxlength="32"
|
||||||
|
placeholder="Hostname" v-model="networkConfigList.hostname" />
|
||||||
|
|
||||||
|
<div class="alert alert-secondary" role="alert">
|
||||||
|
<b>Hint:</b> The text <span class="font-monospace">%06X</span> will be replaced
|
||||||
|
with the last 6 digits of the ESP ChipID in hex format.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<label class="col-sm-2 form-check-label" for="inputDHCP">Enable DHCP</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<div class="form-check form-switch">
|
||||||
|
<input class="form-check-input" type="checkbox" id="inputDHCP"
|
||||||
|
v-model="networkConfigList.dhcp" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<template v-if="!dataLoading">
|
<div class="card" v-show="!networkConfigList.dhcp">
|
||||||
<form @submit="saveNetworkConfig">
|
<div class="card-header text-white bg-primary">
|
||||||
<div class="card">
|
Static IP Configuration
|
||||||
<div class="card-header text-white bg-primary">WiFi Configuration</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<label for="inputSSID" class="col-sm-2 col-form-label">WiFi SSID:</label>
|
<label for="inputIP" class="col-sm-2 col-form-label">IP Address:</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<input type="text" class="form-control" id="inputSSID" maxlength="32" placeholder="SSID"
|
<input type="text" class="form-control" id="inputIP" maxlength="32" placeholder="IP address"
|
||||||
v-model="networkConfigList.ssid" />
|
v-model="networkConfigList.ipaddress" />
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<label for="inputPassword" class="col-sm-2 col-form-label">WiFi Password:</label>
|
<label for="inputNetmask" class="col-sm-2 col-form-label">Netmask:</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<input type="password" class="form-control" id="inputPassword" maxlength="64"
|
<input type="text" class="form-control" id="inputNetmask" maxlength="32"
|
||||||
placeholder="PSK" v-model="networkConfigList.password" />
|
placeholder="Netmask" v-model="networkConfigList.netmask" />
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<label for="inputHostname" class="col-sm-2 col-form-label">Hostname:</label>
|
<label for="inputGateway" class="col-sm-2 col-form-label">Default Gateway:</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<input type="text" class="form-control" id="inputHostname" maxlength="32"
|
<input type="text" class="form-control" id="inputGateway" maxlength="32"
|
||||||
placeholder="Hostname" v-model="networkConfigList.hostname" />
|
placeholder="Default Gateway" v-model="networkConfigList.gateway" />
|
||||||
|
|
||||||
<div class="alert alert-secondary" role="alert">
|
|
||||||
<b>Hint:</b> The text <span class="font-monospace">%06X</span> will be replaced
|
|
||||||
with the last 6 digits of the ESP ChipID in hex format.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<label class="col-sm-2 form-check-label" for="inputDHCP">Enable DHCP</label>
|
<label for="inputDNS1" class="col-sm-2 col-form-label">DNS Server 1:</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<div class="form-check form-switch">
|
<input type="text" class="form-control" id="inputDNS1" maxlength="32"
|
||||||
<input class="form-check-input" type="checkbox" id="inputDHCP"
|
placeholder="DNS Server 1" v-model="networkConfigList.dns1" />
|
||||||
v-model="networkConfigList.dhcp" />
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<label for="inputDNS2" class="col-sm-2 col-form-label">DNS Server 2:</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input type="text" class="form-control" id="inputDNS2" maxlength="32"
|
||||||
|
placeholder="DNS Server 2" v-model="networkConfigList.dns2" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<div class="card" v-show="!networkConfigList.dhcp">
|
<button type="submit" class="btn btn-primary mb-3">Save</button>
|
||||||
<div class="card-header text-white bg-primary">
|
</form>
|
||||||
Static IP Configuration
|
</BasePage>
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="row mb-3">
|
|
||||||
<label for="inputIP" class="col-sm-2 col-form-label">IP Address:</label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<input type="text" class="form-control" id="inputIP" maxlength="32"
|
|
||||||
placeholder="IP address" v-model="networkConfigList.ipaddress" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row mb-3">
|
|
||||||
<label for="inputNetmask" class="col-sm-2 col-form-label">Netmask:</label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<input type="text" class="form-control" id="inputNetmask" maxlength="32"
|
|
||||||
placeholder="Netmask" v-model="networkConfigList.netmask" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row mb-3">
|
|
||||||
<label for="inputGateway" class="col-sm-2 col-form-label">Default Gateway:</label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<input type="text" class="form-control" id="inputGateway" maxlength="32"
|
|
||||||
placeholder="Default Gateway" v-model="networkConfigList.gateway" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row mb-3">
|
|
||||||
<label for="inputDNS1" class="col-sm-2 col-form-label">DNS Server 1:</label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<input type="text" class="form-control" id="inputDNS1" maxlength="32"
|
|
||||||
placeholder="DNS Server 1" v-model="networkConfigList.dns1" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row mb-3">
|
|
||||||
<label for="inputDNS2" class="col-sm-2 col-form-label">DNS Server 2:</label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<input type="text" class="form-control" id="inputDNS2" maxlength="32"
|
|
||||||
placeholder="DNS Server 2" v-model="networkConfigList.dns2" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<button type="submit" class="btn btn-primary mb-3">Save</button>
|
|
||||||
</form>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
import BasePage from '@/components/BasePage.vue';
|
||||||
import BootstrapAlert from "@/components/BootstrapAlert.vue";
|
import BootstrapAlert from "@/components/BootstrapAlert.vue";
|
||||||
import type { NetworkConfig } from "@/types/NetworkkConfig";
|
import type { NetworkConfig } from "@/types/NetworkkConfig";
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
|
BasePage,
|
||||||
BootstrapAlert,
|
BootstrapAlert,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
|||||||
@ -1,29 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container-xxl" role="main">
|
<BasePage :title="'Network Info'" :isLoading="dataLoading">
|
||||||
<div class="page-header">
|
<WifiStationInfo :networkStatus="networkDataList" />
|
||||||
<h1>Network Info</h1>
|
<div class="mt-5"></div>
|
||||||
</div>
|
<WifiApInfo :networkStatus="networkDataList" />
|
||||||
<div class="text-center" v-if="dataLoading">
|
<div class="mt-5"></div>
|
||||||
<div class="spinner-border" role="status">
|
<InterfaceNetworkInfo :networkStatus="networkDataList" />
|
||||||
<span class="visually-hidden">Loading...</span>
|
<div class="mt-5"></div>
|
||||||
</div>
|
<InterfaceApInfo :networkStatus="networkDataList" />
|
||||||
</div>
|
<div class="mt-5"></div>
|
||||||
|
</BasePage>
|
||||||
<template v-if="!dataLoading">
|
|
||||||
<WifiStationInfo :networkStatus="networkDataList" />
|
|
||||||
<div class="mt-5"></div>
|
|
||||||
<WifiApInfo :networkStatus="networkDataList" />
|
|
||||||
<div class="mt-5"></div>
|
|
||||||
<InterfaceNetworkInfo :networkStatus="networkDataList" />
|
|
||||||
<div class="mt-5"></div>
|
|
||||||
<InterfaceApInfo :networkStatus="networkDataList" />
|
|
||||||
<div class="mt-5"></div>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
import BasePage from '@/components/BasePage.vue';
|
||||||
import WifiStationInfo from "@/components/WifiStationInfo.vue";
|
import WifiStationInfo from "@/components/WifiStationInfo.vue";
|
||||||
import WifiApInfo from "@/components/WifiApInfo.vue";
|
import WifiApInfo from "@/components/WifiApInfo.vue";
|
||||||
import InterfaceNetworkInfo from "@/components/InterfaceNetworkInfo.vue";
|
import InterfaceNetworkInfo from "@/components/InterfaceNetworkInfo.vue";
|
||||||
@ -32,6 +22,7 @@ import type { NetworkStatus } from '@/types/NetworkStatus';
|
|||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
|
BasePage,
|
||||||
WifiStationInfo,
|
WifiStationInfo,
|
||||||
WifiApInfo,
|
WifiApInfo,
|
||||||
InterfaceNetworkInfo,
|
InterfaceNetworkInfo,
|
||||||
|
|||||||
@ -1,97 +1,85 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container-xxl" role="main">
|
<BasePage :title="'NTP Settings'" :isLoading="dataLoading || timezoneLoading">
|
||||||
<div class="page-header">
|
|
||||||
<h1>NTP Settings</h1>
|
|
||||||
</div>
|
|
||||||
<BootstrapAlert v-model="showAlert" dismissible :variant="alertType">
|
<BootstrapAlert v-model="showAlert" dismissible :variant="alertType">
|
||||||
{{ alertMessage }}
|
{{ alertMessage }}
|
||||||
</BootstrapAlert>
|
</BootstrapAlert>
|
||||||
|
|
||||||
<div class="text-center" v-if="dataLoading || timezoneLoading">
|
<form @submit="saveNtpConfig">
|
||||||
<div class="spinner-border" role="status">
|
|
||||||
<span class="visually-hidden">Loading...</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<template v-if="!dataLoading && !timezoneLoading">
|
|
||||||
<form @submit="saveNtpConfig">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-header text-white bg-primary">NTP Configuration</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="row mb-3">
|
|
||||||
<label for="inputNtpServer" class="col-sm-2 col-form-label">Time Server:</label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<input type="text" class="form-control" id="inputNtpServer" maxlength="32"
|
|
||||||
placeholder="Time Server" v-model="ntpConfigList.ntp_server" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row mb-3">
|
|
||||||
<label for="inputTimezone" class="col-sm-2 col-form-label">Timezone:</label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<select class="form-select" v-model="timezoneSelect">
|
|
||||||
<option v-for="(config, name) in timezoneList" :key="name + '---' + config"
|
|
||||||
:value="name + '---' + config">
|
|
||||||
{{ name }}
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row mb-3">
|
|
||||||
<label for="inputTimezoneConfig" class="col-sm-2 col-form-label">Timezone Config:</label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<input type="text" class="form-control" id="inputTimezoneConfig" maxlength="32"
|
|
||||||
placeholder="Timezone" v-model="ntpConfigList.ntp_timezone" disabled />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<button type="submit" class="btn btn-primary mb-3">Save</button>
|
|
||||||
</form>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template v-if="!dataLoading && !timezoneLoading">
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header text-white bg-primary">Manual Time Synchronization</div>
|
<div class="card-header text-white 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="currentMcuTime" class="col-sm-2 col-form-label">Current OpenDTU Time:</label>
|
<label for="inputNtpServer" class="col-sm-2 col-form-label">Time Server:</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<input type="text" class="form-control" id="currentMcuTime" v-model="mcuTime" disabled />
|
<input type="text" class="form-control" id="inputNtpServer" maxlength="32"
|
||||||
|
placeholder="Time Server" v-model="ntpConfigList.ntp_server" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-3">
|
|
||||||
<label for="currentLocalTime" class="col-sm-2 col-form-label">Current Local Time:</label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<input type="text" class="form-control" id="currentLocalTime" v-model="localTime"
|
|
||||||
disabled />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="text-center mb-3">
|
|
||||||
<button type="button" class="btn btn-danger" @click="setCurrentTime()"
|
|
||||||
title="Synchronize Time">Synchronize Time
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="alert alert-secondary" role="alert">
|
|
||||||
<b>Hint:</b> You can use the manual time synchronization to set the current time of OpenDTU if
|
|
||||||
no NTP server is available. But be aware, that in case of power cycle the time gets lost. Also
|
|
||||||
the time accurancy can be very bad as it is not resynchronised regularly.
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<label for="inputTimezone" class="col-sm-2 col-form-label">Timezone:</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<select class="form-select" v-model="timezoneSelect">
|
||||||
|
<option v-for="(config, name) in timezoneList" :key="name + '---' + config"
|
||||||
|
:value="name + '---' + config">
|
||||||
|
{{ name }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<label for="inputTimezoneConfig" class="col-sm-2 col-form-label">Timezone Config:</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input type="text" class="form-control" id="inputTimezoneConfig" maxlength="32"
|
||||||
|
placeholder="Timezone" v-model="ntpConfigList.ntp_timezone" disabled />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
<button type="submit" class="btn btn-primary mb-3">Save</button>
|
||||||
</div>
|
</form>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header text-white bg-primary">Manual Time Synchronization</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row mb-3">
|
||||||
|
<label for="currentMcuTime" class="col-sm-2 col-form-label">Current OpenDTU Time:</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input type="text" class="form-control" id="currentMcuTime" v-model="mcuTime" disabled />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-3">
|
||||||
|
<label for="currentLocalTime" class="col-sm-2 col-form-label">Current Local Time:</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input type="text" class="form-control" id="currentLocalTime" v-model="localTime" disabled />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="text-center mb-3">
|
||||||
|
<button type="button" class="btn btn-danger" @click="setCurrentTime()"
|
||||||
|
title="Synchronize Time">Synchronize Time
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="alert alert-secondary" role="alert">
|
||||||
|
<b>Hint:</b> You can use the manual time synchronization to set the current time of OpenDTU if
|
||||||
|
no NTP server is available. But be aware, that in case of power cycle the time gets lost. Also
|
||||||
|
the time accurancy can be very bad as it is not resynchronised regularly.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</BasePage>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
import BasePage from '@/components/BasePage.vue';
|
||||||
import BootstrapAlert from "@/components/BootstrapAlert.vue";
|
import BootstrapAlert from "@/components/BootstrapAlert.vue";
|
||||||
import type { NtpConfig } from "@/types/NtpConfig";
|
import type { NtpConfig } from "@/types/NtpConfig";
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
|
BasePage,
|
||||||
BootstrapAlert,
|
BootstrapAlert,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
|||||||
@ -1,75 +1,66 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container-xxl" role="main">
|
<BasePage :title="'NTP Info'" :isLoading="dataLoading">
|
||||||
<div class="page-header">
|
<div class="card">
|
||||||
<h1>NTP Info</h1>
|
<div class="card-header text-white bg-primary">Configuration Summary</div>
|
||||||
</div>
|
<div class="card-body">
|
||||||
|
<div class="table-responsive">
|
||||||
<div class="text-center" v-if="dataLoading">
|
<table class="table table-hover table-condensed">
|
||||||
<div class="spinner-border" role="status">
|
<tbody>
|
||||||
<span class="visually-hidden">Loading...</span>
|
<tr>
|
||||||
|
<th>Server</th>
|
||||||
|
<td>{{ ntpDataList.ntp_server }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Timezone</th>
|
||||||
|
<td>{{ ntpDataList.ntp_timezone }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Timezone Description</th>
|
||||||
|
<td>{{ ntpDataList.ntp_timezone_descr }}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<template v-if="!dataLoading">
|
<div class="card mt-5">
|
||||||
<div class="card">
|
<div class="card-header text-white bg-primary">Current Time</div>
|
||||||
<div class="card-header text-white bg-primary">Configuration Summary</div>
|
<div class="card-body">
|
||||||
<div class="card-body">
|
<div class="table-responsive">
|
||||||
<div class="table-responsive">
|
<table class="table table-hover table-condensed">
|
||||||
<table class="table table-hover table-condensed">
|
<tbody>
|
||||||
<tbody>
|
<tr>
|
||||||
<tr>
|
<th>Status</th>
|
||||||
<th>Server</th>
|
<td class="badge" :class="{
|
||||||
<td>{{ ntpDataList.ntp_server }}</td>
|
'bg-danger': !ntpDataList.ntp_status,
|
||||||
</tr>
|
'bg-success': ntpDataList.ntp_status,
|
||||||
<tr>
|
}">
|
||||||
<th>Timezone</th>
|
<span v-if="ntpDataList.ntp_status">synced</span>
|
||||||
<td>{{ ntpDataList.ntp_timezone }}</td>
|
<span v-else>not synced</span>
|
||||||
</tr>
|
</td>
|
||||||
<tr>
|
</tr>
|
||||||
<th>Timezone Description</th>
|
<tr>
|
||||||
<td>{{ ntpDataList.ntp_timezone_descr }}</td>
|
<th>Local Time</th>
|
||||||
</tr>
|
<td>{{ ntpDataList.ntp_localtime }}</td>
|
||||||
</tbody>
|
</tr>
|
||||||
</table>
|
</tbody>
|
||||||
</div>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<div class="card mt-5">
|
</BasePage>
|
||||||
<div class="card-header text-white bg-primary">Current Time</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="table-responsive">
|
|
||||||
<table class="table table-hover table-condensed">
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<th>Status</th>
|
|
||||||
<td class="badge" :class="{
|
|
||||||
'bg-danger': !ntpDataList.ntp_status,
|
|
||||||
'bg-success': ntpDataList.ntp_status,
|
|
||||||
}">
|
|
||||||
<span v-if="ntpDataList.ntp_status">synced</span>
|
|
||||||
<span v-else>not synced</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>Local Time</th>
|
|
||||||
<td>{{ ntpDataList.ntp_localtime }}</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
import BasePage from '@/components/BasePage.vue';
|
||||||
import type { NtpStatus } from "@/types/NtpStatus";
|
import type { NtpStatus } from "@/types/NtpStatus";
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
|
components: {
|
||||||
|
BasePage,
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
dataLoading: true,
|
dataLoading: true,
|
||||||
|
|||||||
@ -1,60 +1,51 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container-xxl" role="main">
|
<BasePage :title="'Security Settings'" :isLoading="dataLoading">
|
||||||
<div class="page-header">
|
|
||||||
<h1>Security Settings</h1>
|
|
||||||
</div>
|
|
||||||
<BootstrapAlert v-model="showAlert" dismissible :variant="alertType">
|
<BootstrapAlert v-model="showAlert" dismissible :variant="alertType">
|
||||||
{{ alertMessage }}
|
{{ alertMessage }}
|
||||||
</BootstrapAlert>
|
</BootstrapAlert>
|
||||||
|
|
||||||
<div class="text-center" v-if="dataLoading">
|
<form @submit="savePasswordConfig">
|
||||||
<div class="spinner-border" role="status">
|
<div class="card">
|
||||||
<span class="visually-hidden">Loading...</span>
|
<div class="card-header text-white bg-primary">Admin password</div>
|
||||||
</div>
|
<div class="card-body">
|
||||||
</div>
|
<div class="row mb-3">
|
||||||
|
<label for="inputPassword" class="col-sm-2 col-form-label">Password:</label>
|
||||||
<template v-if="!dataLoading">
|
<div class="col-sm-10">
|
||||||
<form @submit="savePasswordConfig">
|
<input type="password" class="form-control" id="inputPassword" maxlength="64"
|
||||||
<div class="card">
|
placeholder="Password" v-model="securityConfigList.password" />
|
||||||
<div class="card-header text-white bg-primary">Admin password</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="row mb-3">
|
|
||||||
<label for="inputPassword" class="col-sm-2 col-form-label">Password:</label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<input type="password" class="form-control" id="inputPassword" maxlength="64"
|
|
||||||
placeholder="Password" v-model="securityConfigList.password" />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row mb-3">
|
|
||||||
<label for="inputPasswordRepeat" class="col-sm-2 col-form-label">Repeat Password:</label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<input type="password" class="form-control" id="inputPasswordRepeat" maxlength="64"
|
|
||||||
placeholder="Password" v-model="passwordRepeat" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="alert alert-secondary" role="alert">
|
|
||||||
<b>Hint:</b>
|
|
||||||
The administrator password is used to connect to the device when in AP mode.
|
|
||||||
It must be 8..64 characters.
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<label for="inputPasswordRepeat" class="col-sm-2 col-form-label">Repeat Password:</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input type="password" class="form-control" id="inputPasswordRepeat" maxlength="64"
|
||||||
|
placeholder="Password" v-model="passwordRepeat" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="alert alert-secondary" role="alert">
|
||||||
|
<b>Hint:</b>
|
||||||
|
The administrator password is used to connect to the device when in AP mode.
|
||||||
|
It must be 8..64 characters.
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" class="btn btn-primary mb-3">Save</button>
|
</div>
|
||||||
</form>
|
<button type="submit" class="btn btn-primary mb-3">Save</button>
|
||||||
</template>
|
</form>
|
||||||
</div>
|
</BasePage>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
import BasePage from '@/components/BasePage.vue';
|
||||||
import BootstrapAlert from "@/components/BootstrapAlert.vue";
|
import BootstrapAlert from "@/components/BootstrapAlert.vue";
|
||||||
import type { SecurityConfig } from '@/types/SecurityConfig';
|
import type { SecurityConfig } from '@/types/SecurityConfig';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
|
BasePage,
|
||||||
BootstrapAlert,
|
BootstrapAlert,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
|||||||
@ -1,30 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container-xxl" role="main">
|
<BasePage :title="'System Info'" :isLoading="dataLoading">
|
||||||
<div class="page-header">
|
<FirmwareInfo :systemStatus="systemDataList" />
|
||||||
<h1>System Info</h1>
|
<div class="mt-5"></div>
|
||||||
</div>
|
<HardwareInfo :systemStatus="systemDataList" />
|
||||||
|
<div class="mt-5"></div>
|
||||||
<div class="text-center" v-if="dataLoading">
|
<MemoryInfo :systemStatus="systemDataList" />
|
||||||
<div class="spinner-border" role="status">
|
<div class="mt-5"></div>
|
||||||
<span class="visually-hidden">Loading...</span>
|
<RadioInfo :systemStatus="systemDataList" />
|
||||||
</div>
|
<div class="mt-5"></div>
|
||||||
</div>
|
</BasePage>
|
||||||
|
|
||||||
<template v-if="!dataLoading">
|
|
||||||
<FirmwareInfo :systemStatus="systemDataList" />
|
|
||||||
<div class="mt-5"></div>
|
|
||||||
<HardwareInfo :systemStatus="systemDataList" />
|
|
||||||
<div class="mt-5"></div>
|
|
||||||
<MemoryInfo :systemStatus="systemDataList" />
|
|
||||||
<div class="mt-5"></div>
|
|
||||||
<RadioInfo :systemStatus="systemDataList" />
|
|
||||||
<div class="mt-5"></div>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
import BasePage from '@/components/BasePage.vue';
|
||||||
import HardwareInfo from "@/components/HardwareInfo.vue";
|
import HardwareInfo from "@/components/HardwareInfo.vue";
|
||||||
import FirmwareInfo from "@/components/FirmwareInfo.vue";
|
import FirmwareInfo from "@/components/FirmwareInfo.vue";
|
||||||
import MemoryInfo from "@/components/MemoryInfo.vue";
|
import MemoryInfo from "@/components/MemoryInfo.vue";
|
||||||
@ -33,6 +22,7 @@ import type { SystemStatus } from '@/types/SystemStatus';
|
|||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
|
BasePage,
|
||||||
HardwareInfo,
|
HardwareInfo,
|
||||||
FirmwareInfo,
|
FirmwareInfo,
|
||||||
MemoryInfo,
|
MemoryInfo,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user