webapp: introduced CardElement and replace cards with it

This commit is contained in:
Thomas Basler 2022-12-24 20:20:22 +01:00
parent 20083ecba5
commit 1677f7dd03
22 changed files with 850 additions and 895 deletions

View File

@ -0,0 +1,20 @@
<template>
<div :class="['card', addSpace ? 'mt-5' : '' ]">
<div :class="['card-header', textVariant]">{{ text }}</div>
<div :class="['card-body', centerContent ? 'text-center' : '']">
<slot />
</div>
</div>
</template>
<script lang="ts">
import {defineComponent} from 'vue';
export default defineComponent({
props: {
'text': String,
'textVariant': String,
'addSpace': Boolean,
'centerContent': Boolean,
},
});
</script>

View File

@ -1,69 +1,68 @@
<template>
<div class="card">
<div class="card-header text-bg-primary">
{{ $t('firmwareinfo.FirmwareInformation') }}
<CardElement :text="$t('firmwareinfo.FirmwareInformation')" textVariant="text-bg-primary">
<div class="table-responsive">
<table class="table table-hover table-condensed">
<tbody>
<tr>
<th>{{ $t('firmwareinfo.Hostname') }}</th>
<td>{{ systemStatus.hostname }}</td>
</tr>
<tr>
<th>{{ $t('firmwareinfo.SdkVersion') }}</th>
<td>{{ systemStatus.sdkversion }}</td>
</tr>
<tr>
<th>{{ $t('firmwareinfo.ConfigVersion') }}</th>
<td>{{ systemStatus.config_version }}</td>
</tr>
<tr>
<th>{{ $t('firmwareinfo.FirmwareVersion') }}</th>
<td><a :href="'https://github.com/tbnobody/OpenDTU/commits/' + systemStatus.git_hash?.substring(1)"
target="_blank" v-tooltip :title="$t('firmwareinfo.FirmwareVersionHint')">
{{ systemStatus.git_hash?.substring(1) }}
</a></td>
</tr>
<tr>
<th>{{ $t('firmwareinfo.FirmwareUpdate') }}</th>
<td><a :href="systemStatus.update_url" target="_blank" v-tooltip
:title="$t('firmwareinfo.FirmwareUpdateHint')">
<span class="badge" :class="systemStatus.update_status">
{{ systemStatus.update_text }}
</span>
</a></td>
</tr>
<tr>
<th>{{ $t('firmwareinfo.ResetReason0') }}</th>
<td>{{ systemStatus.resetreason_0 }}</td>
</tr>
<tr>
<th>{{ $t('firmwareinfo.ResetReason1') }}</th>
<td>{{ systemStatus.resetreason_1 }}</td>
</tr>
<tr>
<th>{{ $t('firmwareinfo.ConfigSaveCount') }}</th>
<td>{{ systemStatus.cfgsavecount }}</td>
</tr>
<tr>
<th>{{ $t('firmwareinfo.Uptime') }}</th>
<td>{{ timeInHours(systemStatus.uptime) }}</td>
</tr>
</tbody>
</table>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover table-condensed">
<tbody>
<tr>
<th>{{ $t('firmwareinfo.Hostname') }}</th>
<td>{{ systemStatus.hostname }}</td>
</tr>
<tr>
<th>{{ $t('firmwareinfo.SdkVersion') }}</th>
<td>{{ systemStatus.sdkversion }}</td>
</tr>
<tr>
<th>{{ $t('firmwareinfo.ConfigVersion') }}</th>
<td>{{ systemStatus.config_version }}</td>
</tr>
<tr>
<th>{{ $t('firmwareinfo.FirmwareVersion') }}</th>
<td><a :href="'https://github.com/tbnobody/OpenDTU/commits/' + systemStatus.git_hash?.substring(1)"
target="_blank" v-tooltip :title="$t('firmwareinfo.FirmwareVersionHint')">
{{ systemStatus.git_hash?.substring(1) }}
</a></td>
</tr>
<tr>
<th>{{ $t('firmwareinfo.FirmwareUpdate') }}</th>
<td><a :href="systemStatus.update_url" target="_blank" v-tooltip
:title="$t('firmwareinfo.FirmwareUpdateHint')">
<span class="badge" :class="systemStatus.update_status">
{{ systemStatus.update_text }}
</span>
</a></td>
</tr>
<tr>
<th>{{ $t('firmwareinfo.ResetReason0') }}</th>
<td>{{ systemStatus.resetreason_0 }}</td>
</tr>
<tr>
<th>{{ $t('firmwareinfo.ResetReason1') }}</th>
<td>{{ systemStatus.resetreason_1 }}</td>
</tr>
<tr>
<th>{{ $t('firmwareinfo.ConfigSaveCount') }}</th>
<td>{{ systemStatus.cfgsavecount }}</td>
</tr>
<tr>
<th>{{ $t('firmwareinfo.Uptime') }}</th>
<td>{{ timeInHours(systemStatus.uptime) }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</CardElement>
</template>
<script lang="ts">
import { defineComponent, type PropType } from 'vue';
import type { SystemStatus } from '@/types/SystemStatus';
import { timestampToString } from '@/utils';
import CardElement from '@/components/CardElement.vue';
export default defineComponent({
components: {
CardElement,
},
props: {
systemStatus: { type: Object as PropType<SystemStatus>, required: true },
},

View File

@ -1,40 +1,39 @@
<template>
<div class="card">
<div class="card-header text-bg-primary">
{{ $t('hardwareinfo.HardwareInformation') }}
<CardElement :text="$t('hardwareinfo.HardwareInformation')" textVariant="text-bg-primary">
<div class="table-responsive">
<table class="table table-hover table-condensed">
<tbody>
<tr>
<th>{{ $t('hardwareinfo.ChipModel') }}</th>
<td>{{ systemStatus.chipmodel }}</td>
</tr>
<tr>
<th>{{ $t('hardwareinfo.ChipRevision') }}</th>
<td>{{ systemStatus.chiprevision }}</td>
</tr>
<tr>
<th>{{ $t('hardwareinfo.ChipCores') }}</th>
<td>{{ systemStatus.chipcores }}</td>
</tr>
<tr>
<th>{{ $t('hardwareinfo.CpuFrequency') }}</th>
<td>{{ systemStatus.cpufreq }} {{ $t('hardwareinfo.Mhz') }}</td>
</tr>
</tbody>
</table>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover table-condensed">
<tbody>
<tr>
<th>{{ $t('hardwareinfo.ChipModel') }}</th>
<td>{{ systemStatus.chipmodel }}</td>
</tr>
<tr>
<th>{{ $t('hardwareinfo.ChipRevision') }}</th>
<td>{{ systemStatus.chiprevision }}</td>
</tr>
<tr>
<th>{{ $t('hardwareinfo.ChipCores') }}</th>
<td>{{ systemStatus.chipcores }}</td>
</tr>
<tr>
<th>{{ $t('hardwareinfo.CpuFrequency') }}</th>
<td>{{ systemStatus.cpufreq }} {{ $t('hardwareinfo.Mhz') }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</CardElement>
</template>
<script lang="ts">
import type { SystemStatus } from '@/types/SystemStatus';
import { defineComponent, type PropType } from 'vue';
import CardElement from '@/components/CardElement.vue';
export default defineComponent({
components: {
CardElement,
},
props: {
systemStatus: { type: Object as PropType<SystemStatus>, required: true },
},

View File

@ -1,32 +1,31 @@
<template>
<div class="card">
<div class="card-header text-bg-primary">
{{ $t('interfaceapinfo.NetworkInterface') }}
<CardElement :text="$t('interfaceapinfo.NetworkInterface')" textVariant="text-bg-primary">
<div class="table-responsive">
<table class="table table-hover table-condensed">
<tbody>
<tr>
<th>{{ $t('interfaceapinfo.IpAddress') }}</th>
<td>{{ networkStatus.ap_ip }}</td>
</tr>
<tr>
<th>{{ $t('interfaceapinfo.MacAddress') }}</th>
<td>{{ networkStatus.ap_mac }}</td>
</tr>
</tbody>
</table>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover table-condensed">
<tbody>
<tr>
<th>{{ $t('interfaceapinfo.IpAddress') }}</th>
<td>{{ networkStatus.ap_ip }}</td>
</tr>
<tr>
<th>{{ $t('interfaceapinfo.MacAddress') }}</th>
<td>{{ networkStatus.ap_mac }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</CardElement>
</template>
<script lang="ts">
import type { NetworkStatus } from '@/types/NetworkStatus';
import { defineComponent, type PropType } from 'vue';
import CardElement from '@/components/CardElement.vue';
export default defineComponent({
components: {
CardElement,
},
props: {
networkStatus: { type: Object as PropType<NetworkStatus>, required: true },
},

View File

@ -1,52 +1,53 @@
<template>
<div class="card">
<div class="card-header text-bg-primary">
{{ $t('interfacenetworkinfo.NetworkInterface', { iface: networkStatus.network_mode }) }}
<CardElement :text="$t('interfacenetworkinfo.NetworkInterface', { iface: networkStatus.network_mode })"
textVariant="text-bg-primary"
>
<div class="table-responsive">
<table class="table table-hover table-condensed">
<tbody>
<tr>
<th>{{ $t('interfacenetworkinfo.Hostname') }}</th>
<td>{{ networkStatus.network_hostname }}</td>
</tr>
<tr>
<th>{{ $t('interfacenetworkinfo.IpAddress') }}</th>
<td>{{ networkStatus.network_ip }}</td>
</tr>
<tr>
<th>{{ $t('interfacenetworkinfo.Netmask') }}</th>
<td>{{ networkStatus.network_netmask }}</td>
</tr>
<tr>
<th>{{ $t('interfacenetworkinfo.DefaultGateway') }}</th>
<td>{{ networkStatus.network_gateway }}</td>
</tr>
<tr>
<th>{{ $t('interfacenetworkinfo.Dns', { num: 1 }) }}</th>
<td>{{ networkStatus.network_dns1 }}</td>
</tr>
<tr>
<th>{{ $t('interfacenetworkinfo.Dns', { num: 2 }) }}</th>
<td>{{ networkStatus.network_dns2 }}</td>
</tr>
<tr>
<th>{{ $t('interfacenetworkinfo.MacAddress') }}</th>
<td>{{ networkStatus.network_mac }}</td>
</tr>
</tbody>
</table>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover table-condensed">
<tbody>
<tr>
<th>{{ $t('interfacenetworkinfo.Hostname') }}</th>
<td>{{ networkStatus.network_hostname }}</td>
</tr>
<tr>
<th>{{ $t('interfacenetworkinfo.IpAddress') }}</th>
<td>{{ networkStatus.network_ip }}</td>
</tr>
<tr>
<th>{{ $t('interfacenetworkinfo.Netmask') }}</th>
<td>{{ networkStatus.network_netmask }}</td>
</tr>
<tr>
<th>{{ $t('interfacenetworkinfo.DefaultGateway') }}</th>
<td>{{ networkStatus.network_gateway }}</td>
</tr>
<tr>
<th>{{ $t('interfacenetworkinfo.Dns', { num: 1 }) }}</th>
<td>{{ networkStatus.network_dns1 }}</td>
</tr>
<tr>
<th>{{ $t('interfacenetworkinfo.Dns', { num: 2 }) }}</th>
<td>{{ networkStatus.network_dns2 }}</td>
</tr>
<tr>
<th>{{ $t('interfacenetworkinfo.MacAddress') }}</th>
<td>{{ networkStatus.network_mac }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</CardElement>
</template>
<script lang="ts">
import type { NetworkStatus } from '@/types/NetworkStatus';
import { defineComponent, type PropType } from 'vue';
import CardElement from '@/components/CardElement.vue';
export default defineComponent({
components: {
CardElement,
},
props: {
networkStatus: { type: Object as PropType<NetworkStatus>, required: true },
},

View File

@ -1,39 +1,38 @@
<template>
<div class="card">
<div class="card-header text-bg-primary">{{ $t('memoryinfo.MemoryInformation') }}</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover table-condensed">
<thead>
<tr>
<th>{{ $t('memoryinfo.Type') }}</th>
<th>{{ $t('memoryinfo.Usage') }}</th>
<th class="rightCell">{{ $t('memoryinfo.Free') }}</th>
<th class="rightCell">{{ $t('memoryinfo.Used') }}</th>
<th class="rightCell">{{ $t('memoryinfo.Size') }}</th>
</tr>
</thead>
<tbody>
<FsInfo :name="$t('memoryinfo.Heap')" :total="systemStatus.heap_total"
:used="systemStatus.heap_used" />
<FsInfo :name="$t('memoryinfo.LittleFs')" :total="systemStatus.littlefs_total"
:used="systemStatus.littlefs_used" />
<FsInfo :name="$t('memoryinfo.Sketch')" :total="systemStatus.sketch_total"
:used="systemStatus.sketch_used" />
</tbody>
</table>
</div>
<CardElement :text="$t('memoryinfo.MemoryInformation')" textVariant="text-bg-primary">
<div class="table-responsive">
<table class="table table-hover table-condensed">
<thead>
<tr>
<th>{{ $t('memoryinfo.Type') }}</th>
<th>{{ $t('memoryinfo.Usage') }}</th>
<th class="rightCell">{{ $t('memoryinfo.Free') }}</th>
<th class="rightCell">{{ $t('memoryinfo.Used') }}</th>
<th class="rightCell">{{ $t('memoryinfo.Size') }}</th>
</tr>
</thead>
<tbody>
<FsInfo :name="$t('memoryinfo.Heap')" :total="systemStatus.heap_total"
:used="systemStatus.heap_used" />
<FsInfo :name="$t('memoryinfo.LittleFs')" :total="systemStatus.littlefs_total"
:used="systemStatus.littlefs_used" />
<FsInfo :name="$t('memoryinfo.Sketch')" :total="systemStatus.sketch_total"
:used="systemStatus.sketch_used" />
</tbody>
</table>
</div>
</div>
</CardElement>
</template>
<script lang="ts">
import { defineComponent, type PropType } from 'vue';
import type { SystemStatus } from '@/types/SystemStatus';
import CardElement from '@/components/CardElement.vue';
import FsInfo from "@/components/FsInfo.vue";
export default defineComponent({
components: {
CardElement,
FsInfo,
},
props: {

View File

@ -1,48 +1,47 @@
<template>
<div class="card">
<div class="card-header text-bg-primary">
{{ $t('radioinfo.RadioInformation') }}
<CardElement :text="$t('radioinfo.RadioInformation')" textVariant="text-bg-primary">
<div class="table-responsive">
<table class="table table-hover table-condensed">
<tbody>
<tr>
<th>{{ $t('radioinfo.ChipStatus') }}</th>
<td class="badge" :class="{
'text-bg-danger': !systemStatus.radio_connected,
'text-bg-success': systemStatus.radio_connected,
}">
<span v-if="systemStatus.radio_connected">{{ $t('radioinfo.Connected') }}</span>
<span v-else>{{ $t('radioinfo.NotConnected') }}</span>
</td>
</tr>
<tr>
<th>{{ $t('radioinfo.ChipType') }}</th>
<td class="badge" :class="{
'text-bg-danger': systemStatus.radio_connected && !systemStatus.radio_pvariant,
'text-bg-success': systemStatus.radio_connected && systemStatus.radio_pvariant,
'text-bg-secondary': !systemStatus.radio_connected,
}">
<span
v-if="systemStatus.radio_connected && systemStatus.radio_pvariant">nRF24L01+</span>
<span
v-else-if="systemStatus.radio_connected && !systemStatus.radio_pvariant">nRF24L01</span>
<span v-else>{{ $t('radioinfo.Unknown') }}</span>
</td>
</tr>
</tbody>
</table>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover table-condensed">
<tbody>
<tr>
<th>{{ $t('radioinfo.ChipStatus') }}</th>
<td class="badge" :class="{
'text-bg-danger': !systemStatus.radio_connected,
'text-bg-success': systemStatus.radio_connected,
}">
<span v-if="systemStatus.radio_connected">{{ $t('radioinfo.Connected') }}</span>
<span v-else>{{ $t('radioinfo.NotConnected') }}</span>
</td>
</tr>
<tr>
<th>{{ $t('radioinfo.ChipType') }}</th>
<td class="badge" :class="{
'text-bg-danger': systemStatus.radio_connected && !systemStatus.radio_pvariant,
'text-bg-success': systemStatus.radio_connected && systemStatus.radio_pvariant,
'text-bg-secondary': !systemStatus.radio_connected,
}">
<span
v-if="systemStatus.radio_connected && systemStatus.radio_pvariant">nRF24L01+</span>
<span
v-else-if="systemStatus.radio_connected && !systemStatus.radio_pvariant">nRF24L01</span>
<span v-else>{{ $t('radioinfo.Unknown') }}</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</CardElement>
</template>
<script lang="ts">
import { defineComponent, type PropType } from 'vue';
import type { SystemStatus } from '@/types/SystemStatus';
import CardElement from '@/components/CardElement.vue';
export default defineComponent({
components: {
CardElement,
},
props: {
systemStatus: { type: Object as PropType<SystemStatus>, required: true },
},

View File

@ -1,42 +1,41 @@
<template>
<div class="card">
<div class="card-header text-bg-primary">
{{ $t('wifiapinfo.WifiApInfo') }}
<CardElement :text="$t('wifiapinfo.WifiApInfo')" textVariant="text-bg-primary">
<div class="table-responsive">
<table class="table table-hover table-condensed">
<tbody>
<tr>
<th>{{ $t('wifiapinfo.Status') }}</th>
<td class="badge" :class="{
'text-bg-danger': !networkStatus.ap_status,
'text-bg-success': networkStatus.ap_status,
}">
<span v-if="networkStatus.ap_status">{{ $t('wifiapinfo.Enabled') }}</span>
<span v-else>{{ $t('wifiapinfo.Disabled') }}</span>
</td>
</tr>
<tr>
<th>{{ $t('wifiapinfo.Ssid') }}</th>
<td>{{ networkStatus.ap_ssid }}</td>
</tr>
<tr>
<th>{{ $t('wifiapinfo.Stations') }}</th>
<td>{{ networkStatus.ap_stationnum }}</td>
</tr>
</tbody>
</table>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover table-condensed">
<tbody>
<tr>
<th>{{ $t('wifiapinfo.Status') }}</th>
<td class="badge" :class="{
'text-bg-danger': !networkStatus.ap_status,
'text-bg-success': networkStatus.ap_status,
}">
<span v-if="networkStatus.ap_status">{{ $t('wifiapinfo.Enabled') }}</span>
<span v-else>{{ $t('wifiapinfo.Disabled') }}</span>
</td>
</tr>
<tr>
<th>{{ $t('wifiapinfo.Ssid') }}</th>
<td>{{ networkStatus.ap_ssid }}</td>
</tr>
<tr>
<th>{{ $t('wifiapinfo.Stations') }}</th>
<td>{{ networkStatus.ap_stationnum }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</CardElement>
</template>
<script lang="ts">
import type { NetworkStatus } from '@/types/NetworkStatus';
import { defineComponent, type PropType } from 'vue';
import CardElement from '@/components/CardElement.vue';
export default defineComponent({
components: {
CardElement,
},
props: {
networkStatus: { type: Object as PropType<NetworkStatus>, required: true },
},

View File

@ -1,46 +1,45 @@
<template>
<div class="card">
<div class="card-header text-bg-primary">
{{ $t('wifistationinfo.WifiStationInfo') }}
<CardElement :text="$t('wifistationinfo.WifiStationInfo')" textVariant="text-bg-primary">
<div class="table-responsive">
<table class="table table-hover table-condensed">
<tbody>
<tr>
<th>{{ $t('wifistationinfo.Status') }}</th>
<td class="badge" :class="{
'text-bg-danger': !networkStatus.sta_status,
'text-bg-success': networkStatus.sta_status,
}">
<span v-if="networkStatus.sta_status">{{ $t('wifistationinfo.Enabled') }}</span>
<span v-else>{{ $t('wifistationinfo.Disabled') }}</span>
</td>
</tr>
<tr>
<th>{{ $t('wifistationinfo.Ssid') }}</th>
<td>{{ networkStatus.sta_ssid }}</td>
</tr>
<tr>
<th>{{ $t('wifistationinfo.Quality') }}</th>
<td>{{ getRSSIasQuality(networkStatus.sta_rssi) }} %</td>
</tr>
<tr>
<th>{{ $t('wifistationinfo.Rssi') }}</th>
<td>{{ networkStatus.sta_rssi }}</td>
</tr>
</tbody>
</table>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover table-condensed">
<tbody>
<tr>
<th>{{ $t('wifistationinfo.Status') }}</th>
<td class="badge" :class="{
'text-bg-danger': !networkStatus.sta_status,
'text-bg-success': networkStatus.sta_status,
}">
<span v-if="networkStatus.sta_status">{{ $t('wifistationinfo.Enabled') }}</span>
<span v-else>{{ $t('wifistationinfo.Disabled') }}</span>
</td>
</tr>
<tr>
<th>{{ $t('wifistationinfo.Ssid') }}</th>
<td>{{ networkStatus.sta_ssid }}</td>
</tr>
<tr>
<th>{{ $t('wifistationinfo.Quality') }}</th>
<td>{{ getRSSIasQuality(networkStatus.sta_rssi) }} %</td>
</tr>
<tr>
<th>{{ $t('wifistationinfo.Rssi') }}</th>
<td>{{ networkStatus.sta_rssi }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</CardElement>
</template>
<script lang="ts">
import type { NetworkStatus } from '@/types/NetworkStatus';
import { defineComponent, type PropType } from 'vue';
import CardElement from '@/components/CardElement.vue';
export default defineComponent({
components: {
CardElement,
},
props: {
networkStatus: { type: Object as PropType<NetworkStatus>, required: true },
},

View File

@ -4,74 +4,63 @@
{{ alertMessage }}
</BootstrapAlert>
<div class="card">
<div class="card-header text-bg-primary">{{ $t('configadmin.BackupHeader') }}</div>
<div class="card-body text-center">
{{ $t('configadmin.BackupConfig') }}
<button class="btn btn-primary" @click="downloadConfig">{{ $t('configadmin.Backup') }}
<CardElement :text="$t('configadmin.BackupHeader')" textVariant="text-bg-primary" center-content>
{{ $t('configadmin.BackupConfig') }}
<button class="btn btn-primary" @click="downloadConfig">{{ $t('configadmin.Backup') }}
</button>
</CardElement>
<CardElement :text="$t('configadmin.RestoreHeader')" textVariant="text-bg-primary" center-content add-space>
<div v-if="!uploading && UploadError != ''">
<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 /> {{ $t('configadmin.Back') }}
</button>
</div>
</div>
<div class="card mt-5">
<div class="card-header text-bg-primary">{{ $t('configadmin.RestoreHeader') }}</div>
<div class="card-body text-center">
<div v-if="!uploading && UploadError != ''">
<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 /> {{ $t('configadmin.Back') }}
</button>
</div>
<div v-else-if="!uploading && UploadSuccess">
<span class="h1 mb-2">
<BIconCheckCircle />
</span>
<span> {{ $t('configadmin.UploadSuccess') }} </span>
<br />
<br />
<button class="btn btn-primary" @click="clear">
<BIconArrowLeft /> {{ $t('configadmin.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" v-html="$t('configadmin.RestoreHint')"></div>
</div>
</div>
<div class="card mt-5">
<div class="card-header text-bg-primary">{{ $t('configadmin.ResetHeader') }}</div>
<div class="card-body text-center">
<button class="btn btn-danger" @click="onFactoryResetModal">{{ $t('configadmin.FactoryResetButton') }}
<div v-else-if="!uploading && UploadSuccess">
<span class="h1 mb-2">
<BIconCheckCircle />
</span>
<span> {{ $t('configadmin.UploadSuccess') }} </span>
<br />
<br />
<button class="btn btn-primary" @click="clear">
<BIconArrowLeft /> {{ $t('configadmin.Back') }}
</button>
<div class="alert alert-danger mt-3" role="alert" v-html="$t('configadmin.ResetHint')"></div>
</div>
</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" v-html="$t('configadmin.RestoreHint')"></div>
</CardElement>
<CardElement :text="$t('configadmin.ResetHeader')" textVariant="text-bg-primary" center-content add-space>
<button class="btn btn-danger" @click="onFactoryResetModal">{{ $t('configadmin.FactoryResetButton') }}
</button>
<div class="alert alert-danger mt-3" role="alert" v-html="$t('configadmin.ResetHint')"></div>
</CardElement>
</BasePage>
<div class="modal" id="factoryReset" tabindex="-1">
@ -106,6 +95,7 @@ import {
} from 'bootstrap-icons-vue';
import * as bootstrap from 'bootstrap';
import BootstrapAlert from "@/components/BootstrapAlert.vue";
import CardElement from '@/components/CardElement.vue';
import { handleResponse, authHeader, isLoggedIn } from '@/utils/authentication';
export default defineComponent({
@ -115,6 +105,7 @@ export default defineComponent({
BIconArrowLeft,
BIconCheckCircle,
BootstrapAlert,
CardElement,
},
data() {
return {

View File

@ -1,41 +1,40 @@
<template>
<BasePage :title="$t('console.Console')" :isLoading="dataLoading">
<div class="card">
<div class="card-header text-bg-primary">{{ $t('console.VirtualDebugConsole') }}</div>
<div class="card-body">
<div class="row g-3 align-items-center">
<div class="col">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" id="autoScroll"
v-model="isAutoScroll">
<label class="form-check-label" for="autoScroll">
{{ $t('console.EnableAutoScroll') }}
</label>
</div>
</div>
<div class="col text-end">
<div class="btn-group" role="group">
<button type="button" class="btn btn-primary" :onClick="clearConsole">
{{ $t('console.ClearConsole') }}</button>
<button type="button" class="btn btn-secondary" :onClick="copyConsole">
{{ $t('console.CopyToClipboard') }}</button>
</div>
<CardElement :text="$t('console.VirtualDebugConsole')" textVariant="text-bg-primary">
<div class="row g-3 align-items-center">
<div class="col">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" id="autoScroll"
v-model="isAutoScroll">
<label class="form-check-label" for="autoScroll">
{{ $t('console.EnableAutoScroll') }}
</label>
</div>
</div>
<div class="col text-end">
<div class="btn-group" role="group">
<button type="button" class="btn btn-primary" :onClick="clearConsole">
{{ $t('console.ClearConsole') }}</button>
<button type="button" class="btn btn-secondary" :onClick="copyConsole">
{{ $t('console.CopyToClipboard') }}</button>
</div>
</div>
<textarea id="console" class="form-control" rows="24" v-model="consoleBuffer" readonly></textarea>
</div>
</div>
<textarea id="console" class="form-control" rows="24" v-model="consoleBuffer" readonly></textarea>
</CardElement>
</BasePage>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import BasePage from '@/components/BasePage.vue';
import CardElement from '@/components/CardElement.vue';
import { authUrl } from '@/utils/authentication';
export default defineComponent({
components: {
BasePage,
CardElement,
},
data() {
return {

View File

@ -5,35 +5,31 @@
</BootstrapAlert>
<form @submit="saveDtuConfig">
<div class="card">
<div class="card-header text-bg-primary">{{ $t('dtuadmin.DtuConfiguration') }}</div>
<div class="card-body">
<CardElement :text="$t('dtuadmin.DtuConfiguration')" textVariant="text-bg-primary">
<InputElement :label="$t('dtuadmin.Serial')"
v-model="dtuConfigList.dtu_serial"
type="number" min="1" max="199999999999"
:tooltip="$t('dtuadmin.SerialHint')"/>
<InputElement :label="$t('dtuadmin.Serial')"
v-model="dtuConfigList.dtu_serial"
type="number" min="1" max="199999999999"
:tooltip="$t('dtuadmin.SerialHint')"/>
<InputElement :label="$t('dtuadmin.PollInterval')"
v-model="dtuConfigList.dtu_pollinterval"
type="number" min="1" max="86400"
:postfix="$t('dtuadmin.Seconds')"/>
<InputElement :label="$t('dtuadmin.PollInterval')"
v-model="dtuConfigList.dtu_pollinterval"
type="number" min="1" max="86400"
:postfix="$t('dtuadmin.Seconds')"/>
<div class="row mb-3">
<label for="inputTimezone" class="col-sm-2 col-form-label">
{{ $t('dtuadmin.PaLevel') }}
<BIconInfoCircle v-tooltip :title="$t('dtuadmin.PaLevelHint')" />
</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 class="row mb-3">
<label for="inputTimezone" class="col-sm-2 col-form-label">
{{ $t('dtuadmin.PaLevel') }}
<BIconInfoCircle v-tooltip :title="$t('dtuadmin.PaLevelHint')" />
</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>
</CardElement>
<button type="submit" class="btn btn-primary mb-3">{{ $t('dtuadmin.Save') }}</button>
</form>
</BasePage>
@ -44,6 +40,7 @@ import { defineComponent } from 'vue';
import BasePage from '@/components/BasePage.vue';
import BootstrapAlert from "@/components/BootstrapAlert.vue";
import InputElement from '@/components/InputElement.vue';
import CardElement from '@/components/CardElement.vue';
import { handleResponse, authHeader } from '@/utils/authentication';
import type { DtuConfig } from "@/types/DtuConfig";
import {
@ -56,6 +53,7 @@ export default defineComponent({
BootstrapAlert,
BIconInfoCircle,
InputElement,
CardElement,
},
data() {
return {

View File

@ -8,68 +8,66 @@
</div>
</div>
<div v-if="!loading && !uploading && OTAError != ''" class="card">
<div class="card-header text-bg-danger">{{ $t('firmwareupgrade.OtaError') }}</div>
<div class="card-body text-center">
<p class="h1 mb-2">
<BIconExclamationCircleFill />
</p>
<CardElement :text="$t('firmwareupgrade.OtaError')" textVariant="text-bg-danger" center-content
v-if="!loading && !uploading && OTAError != ''"
>
<p class="h1 mb-2">
<BIconExclamationCircleFill />
</p>
<span style="vertical-align: middle" class="ml-2">
{{ OTAError }}
</span>
<br />
<br />
<button class="btn btn-light" @click="clear">
<BIconArrowLeft /> {{ $t('firmwareupgrade.Back') }}
</button>
<button class="btn btn-primary" @click="retryOTA">
<BIconArrowRepeat /> {{ $t('firmwareupgrade.Retry') }}
</button>
<span style="vertical-align: middle" class="ml-2">
{{ OTAError }}
</span>
<br />
<br />
<button class="btn btn-light" @click="clear">
<BIconArrowLeft /> {{ $t('firmwareupgrade.Back') }}
</button>
<button class="btn btn-primary" @click="retryOTA">
<BIconArrowRepeat /> {{ $t('firmwareupgrade.Retry') }}
</button>
</CardElement>
<CardElement :text="$t('firmwareupgrade.OtaStatus')" textVariant="text-bg-success" center-content
v-else-if="!loading && !uploading && OTASuccess"
>
<span class="h1 mb-2">
<BIconCheckCircle />
</span>
<span> {{ $t('firmwareupgrade.OtaSuccess') }} </span>
<br />
<br />
<button class="btn btn-primary" @click="clear">
<BIconArrowLeft /> {{ $t('firmwareupgrade.Back') }}
</button>
</CardElement>
<CardElement :text="$t('firmwareupgrade.FirmwareUpload')" textVariant="text-bg-primary" center-content
v-else-if="!loading && !uploading"
>
<div class="form-group pt-2 mt-3">
<input class="form-control" type="file" ref="file" accept=".bin,.bin.gz" @change="uploadOTA" />
</div>
</div>
</CardElement>
<div v-else-if="!loading && !uploading && OTASuccess" class="card">
<div class="card-header text-bg-success">{{ $t('firmwareupgrade.OtaStatus') }}</div>
<div class="card-body text-center">
<span class="h1 mb-2">
<BIconCheckCircle />
</span>
<span> {{ $t('firmwareupgrade.OtaSuccess') }} </span>
<br />
<br />
<button class="btn btn-primary" @click="clear">
<BIconArrowLeft /> {{ $t('firmwareupgrade.Back') }}
</button>
</div>
</div>
<div v-else-if="!loading && !uploading" class="card">
<div class="card-header text-bg-primary">{{ $t('firmwareupgrade.FirmwareUpload') }}</div>
<div class="card-body text-center">
<div class="form-group pt-2 mt-3">
<input class="form-control" type="file" ref="file" accept=".bin,.bin.gz" @change="uploadOTA" />
<CardElement :text="$t('firmwareupgrade.UploadProgress')" textVariant="text-bg-primary" center-content
v-else-if="!loading && 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>
</CardElement>
<div v-else-if="!loading && uploading" class="card">
<div class="card-header text-bg-primary">{{ $t('firmwareupgrade.UploadProgress') }}</div>
<div class="card-body text-center">
<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>
</BasePage>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import BasePage from '@/components/BasePage.vue';
import CardElement from '@/components/CardElement.vue';
import SparkMD5 from "spark-md5";
import {
BIconExclamationCircleFill,
@ -82,6 +80,7 @@ import { authHeader, isLoggedIn } from '@/utils/authentication';
export default defineComponent({
components: {
BasePage,
CardElement,
BIconExclamationCircleFill,
BIconArrowLeft,
BIconArrowRepeat,

View File

@ -4,60 +4,54 @@
{{ alert.message }}
</BootstrapAlert>
<div class="card">
<div class="card-header text-bg-primary">{{ $t('inverteradmin.AddInverter') }}</div>
<div class="card-body">
<form class="form-inline" v-on:submit.prevent="onSubmit">
<div class="form-group">
<label>{{ $t('inverteradmin.Serial') }}</label>
<input v-model="newInverterData.serial" type="number" class="form-control ml-sm-2 mr-sm-4 my-2"
required />
</div>
<div class="form-group">
<label>{{ $t('inverteradmin.Name') }}</label>
<input v-model="newInverterData.name" type="text" class="form-control ml-sm-2 mr-sm-4 my-2"
maxlength="31" required />
</div>
<div class="ml-auto text-right">
<button type="submit" class="btn btn-primary my-2">{{ $t('inverteradmin.Add') }}</button>
</div>
<div class="alert alert-secondary" role="alert" v-html="$t('inverteradmin.AddHint')"></div>
</form>
</div>
</div>
<div class="card mt-5">
<div class="card-header text-bg-primary">{{ $t('inverteradmin.InverterList') }}</div>
<div class="card-body">
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th scope="col">{{ $t('inverteradmin.Serial') }}</th>
<th>{{ $t('inverteradmin.Name') }}</th>
<th>{{ $t('inverteradmin.Type') }}</th>
<th>{{ $t('inverteradmin.Action') }}</th>
</tr>
</thead>
<tbody>
<tr v-for="inverter in sortedInverters" v-bind:key="inverter.id">
<td>{{ inverter.serial }}</td>
<td>{{ inverter.name }}</td>
<td>{{ inverter.type }}</td>
<td>
<a href="#" class="icon text-danger" :title="$t('inverteradmin.DeleteInverter')">
<BIconTrash v-on:click="onOpenModal(modalDelete, inverter)" />
</a>&nbsp;
<a href="#" class="icon" :title="$t('inverteradmin.EditInverter')">
<BIconPencil v-on:click="onOpenModal(modal, inverter)" />
</a>
</td>
</tr>
</tbody>
</table>
<CardElement :text="$t('inverteradmin.AddInverter')" textVariant="text-bg-primary">
<form class="form-inline" v-on:submit.prevent="onSubmit">
<div class="form-group">
<label>{{ $t('inverteradmin.Serial') }}</label>
<input v-model="newInverterData.serial" type="number" class="form-control ml-sm-2 mr-sm-4 my-2"
required />
</div>
<div class="form-group">
<label>{{ $t('inverteradmin.Name') }}</label>
<input v-model="newInverterData.name" type="text" class="form-control ml-sm-2 mr-sm-4 my-2"
maxlength="31" required />
</div>
<div class="ml-auto text-right">
<button type="submit" class="btn btn-primary my-2">{{ $t('inverteradmin.Add') }}</button>
</div>
<div class="alert alert-secondary" role="alert" v-html="$t('inverteradmin.AddHint')"></div>
</form>
</CardElement>
<CardElement :text="$t('inverteradmin.InverterList')" textVariant="text-bg-primary" add-space>
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th scope="col">{{ $t('inverteradmin.Serial') }}</th>
<th>{{ $t('inverteradmin.Name') }}</th>
<th>{{ $t('inverteradmin.Type') }}</th>
<th>{{ $t('inverteradmin.Action') }}</th>
</tr>
</thead>
<tbody>
<tr v-for="inverter in sortedInverters" v-bind:key="inverter.id">
<td>{{ inverter.serial }}</td>
<td>{{ inverter.name }}</td>
<td>{{ inverter.type }}</td>
<td>
<a href="#" class="icon text-danger" :title="$t('inverteradmin.DeleteInverter')">
<BIconTrash v-on:click="onOpenModal(modalDelete, inverter)" />
</a>&nbsp;
<a href="#" class="icon" :title="$t('inverteradmin.EditInverter')">
<BIconPencil v-on:click="onOpenModal(modal, inverter)" />
</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</CardElement>
</BasePage>
<div class="modal" id="inverterEdit" tabindex="-1">
@ -163,6 +157,7 @@ import {
} from 'bootstrap-icons-vue';
import * as bootstrap from 'bootstrap';
import BootstrapAlert from "@/components/BootstrapAlert.vue";
import CardElement from '@/components/CardElement.vue';
import { handleResponse, authHeader } from '@/utils/authentication';
declare interface Channel {
@ -189,6 +184,7 @@ export default defineComponent({
components: {
BasePage,
BootstrapAlert,
CardElement,
BIconTrash,
BIconPencil,
BIconInfoCircle,

View File

@ -4,31 +4,27 @@
{{ alertMessage }}
</BootstrapAlert>
<div class="card">
<div class="card-header text-bg-danger">{{ $t('login.SystemLogin') }}</div>
<div class="card-body">
<form @submit.prevent="handleSubmit">
<div class="form-group">
<label for="username">{{ $t('login.Username') }}</label>
<input type="text" v-model="username" name="username" class="form-control"
:class="{ 'is-invalid': submitted && !username }" />
<div v-show="submitted && !username" class="invalid-feedback">{{ $t('login.UsernameRequired') }}
</div>
<CardElement :text="$t('login.SystemLogin')" textVariant="text-bg-danger">
<form @submit.prevent="handleSubmit">
<div class="form-group">
<label for="username">{{ $t('login.Username') }}</label>
<input type="text" v-model="username" name="username" class="form-control"
:class="{ 'is-invalid': submitted && !username }" />
<div v-show="submitted && !username" class="invalid-feedback">{{ $t('login.UsernameRequired') }}
</div>
<div class="form-group">
<label htmlFor="password">{{ $t('login.Password') }}</label>
<input type="password" v-model="password" name="password" class="form-control"
:class="{ 'is-invalid': submitted && !password }" />
<div v-show="submitted && !password" class="invalid-feedback">
{{ $t('login.PasswordRequired') }}</div>
</div>
<div class="form-group">
<button class="btn btn-primary" :disabled="dataLoading">{{ $t('login.LoginButton') }}</button>
</div>
</form>
</div>
</div>
</div>
<div class="form-group">
<label htmlFor="password">{{ $t('login.Password') }}</label>
<input type="password" v-model="password" name="password" class="form-control"
:class="{ 'is-invalid': submitted && !password }" />
<div v-show="submitted && !password" class="invalid-feedback">
{{ $t('login.PasswordRequired') }}</div>
</div>
<div class="form-group">
<button class="btn btn-primary" :disabled="dataLoading">{{ $t('login.LoginButton') }}</button>
</div>
</form>
</CardElement>
</BasePage>
</template>
@ -37,12 +33,14 @@ import { defineComponent } from 'vue';
import router from '@/router';
import { login } from '@/utils';
import BasePage from '@/components/BasePage.vue';
import CardElement from '@/components/CardElement.vue';
import BootstrapAlert from "@/components/BootstrapAlert.vue";
export default defineComponent({
components: {
BasePage,
BootstrapAlert,
CardElement,
},
data() {
return {

View File

@ -4,16 +4,12 @@
{{ alertMessage }}
</BootstrapAlert>
<div class="card mt-5">
<div class="card-header text-bg-primary">{{ $t('maintenancereboot.PerformReboot') }}</div>
<div class="card-body text-center">
<CardElement :text="$t('maintenancereboot.PerformReboot')" textVariant="text-bg-primary" center-content>
<button class="btn btn-danger" @click="onOpenModal(performReboot)">{{ $t('maintenancereboot.Reboot') }}
</button>
<button class="btn btn-danger" @click="onOpenModal(performReboot)">{{ $t('maintenancereboot.Reboot') }}
</button>
<div class="alert alert-danger mt-3" role="alert" v-html="$t('maintenancereboot.RebootHint')"></div>
</div>
</div>
<div class="alert alert-danger mt-3" role="alert" v-html="$t('maintenancereboot.RebootHint')"></div>
</CardElement>
</BasePage>
<div class="modal" id="performReboot" tabindex="-1">
@ -42,12 +38,14 @@ import { defineComponent } from 'vue';
import * as bootstrap from 'bootstrap';
import BasePage from '@/components/BasePage.vue';
import BootstrapAlert from "@/components/BootstrapAlert.vue";
import CardElement from '@/components/CardElement.vue';
import { handleResponse, authHeader, isLoggedIn } from '@/utils/authentication';
export default defineComponent({
components: {
BasePage,
BootstrapAlert,
CardElement,
},
data() {
return {

View File

@ -5,114 +5,102 @@
</BootstrapAlert>
<form @submit="saveMqttConfig">
<div class="card">
<div class="card-header text-bg-primary">{{ $t('mqttadmin.MqttConfiguration') }}</div>
<div class="card-body">
<CardElement :text="$t('mqttadmin.MqttConfiguration')" textVariant="text-bg-primary">
<InputElement :label="$t('mqttadmin.EnableMqtt')"
v-model="mqttConfigList.mqtt_enabled"
type="checkbox" wide/>
<InputElement :label="$t('mqttadmin.EnableMqtt')"
v-model="mqttConfigList.mqtt_enabled"
type="checkbox" wide/>
<InputElement v-show="mqttConfigList.mqtt_enabled"
:label="$t('mqttadmin.EnableHass')"
v-model="mqttConfigList.mqtt_hass_enabled"
type="checkbox" wide/>
</CardElement>
<InputElement v-show="mqttConfigList.mqtt_enabled"
:label="$t('mqttadmin.EnableHass')"
v-model="mqttConfigList.mqtt_hass_enabled"
type="checkbox" wide/>
</div>
</div>
<CardElement :text="$t('mqttadmin.MqttBrokerParameter')" textVariant="text-bg-primary" add-space
v-show="mqttConfigList.mqtt_enabled"
>
<InputElement :label="$t('mqttadmin.Hostname')"
v-model="mqttConfigList.mqtt_hostname"
type="text" maxlength="128"
:placeholder="$t('mqttadmin.HostnameHint')"/>
<div class="card mt-5" v-show="mqttConfigList.mqtt_enabled">
<div class="card-header text-bg-primary">
{{ $t('mqttadmin.MqttBrokerParameter') }}
</div>
<div class="card-body">
<InputElement :label="$t('mqttadmin.Port')"
v-model="mqttConfigList.mqtt_port"
type="number" min="1" max="65535"/>
<InputElement :label="$t('mqttadmin.Hostname')"
v-model="mqttConfigList.mqtt_hostname"
type="text" maxlength="128"
:placeholder="$t('mqttadmin.HostnameHint')"/>
<InputElement :label="$t('mqttadmin.Username')"
v-model="mqttConfigList.mqtt_username"
type="text" maxlength="64"
:placeholder="$t('mqttadmin.UsernameHint')"/>
<InputElement :label="$t('mqttadmin.Port')"
v-model="mqttConfigList.mqtt_port"
type="number" min="1" max="65535"/>
<InputElement :label="$t('mqttadmin.Password')"
v-model="mqttConfigList.mqtt_password"
type="password" maxlength="64"
:placeholder="$t('mqttadmin.PasswordHint')"/>
<InputElement :label="$t('mqttadmin.Username')"
v-model="mqttConfigList.mqtt_username"
type="text" maxlength="64"
:placeholder="$t('mqttadmin.UsernameHint')"/>
<InputElement :label="$t('mqttadmin.BaseTopic')"
v-model="mqttConfigList.mqtt_topic"
type="text" maxlength="32"
:placeholder="$t('mqttadmin.BaseTopicHint')"/>
<InputElement :label="$t('mqttadmin.Password')"
v-model="mqttConfigList.mqtt_password"
type="password" maxlength="64"
:placeholder="$t('mqttadmin.PasswordHint')"/>
<InputElement :label="$t('mqttadmin.PublishInterval')"
v-model="mqttConfigList.mqtt_publish_interval"
type="number" min="5" max="86400"
:postfix="$t('mqttadmin.Seconds')"/>
<InputElement :label="$t('mqttadmin.BaseTopic')"
v-model="mqttConfigList.mqtt_topic"
type="text" maxlength="32"
:placeholder="$t('mqttadmin.BaseTopicHint')"/>
<InputElement :label="$t('mqttadmin.EnableRetain')"
v-model="mqttConfigList.mqtt_retain"
type="checkbox"/>
<InputElement :label="$t('mqttadmin.PublishInterval')"
v-model="mqttConfigList.mqtt_publish_interval"
type="number" min="5" max="86400"
:postfix="$t('mqttadmin.Seconds')"/>
<InputElement :label="$t('mqttadmin.EnableTls')"
v-model="mqttConfigList.mqtt_tls"
type="checkbox"/>
<InputElement :label="$t('mqttadmin.EnableRetain')"
v-model="mqttConfigList.mqtt_retain"
type="checkbox"/>
<InputElement v-show="mqttConfigList.mqtt_tls"
:label="$t('mqttadmin.RootCa')"
v-model="mqttConfigList.mqtt_root_ca_cert"
type="textarea" maxlength="2048" rows="10"/>
</CardElement>
<InputElement :label="$t('mqttadmin.EnableTls')"
v-model="mqttConfigList.mqtt_tls"
type="checkbox"/>
<CardElement :text="$t('mqttadmin.LwtParameters')" textVariant="text-bg-primary" add-space
v-show="mqttConfigList.mqtt_enabled"
>
<InputElement :label="$t('mqttadmin.LwtTopic')"
v-model="mqttConfigList.mqtt_lwt_topic"
type="text" maxlength="32" :prefix="mqttConfigList.mqtt_topic"
:placeholder="$t('mqttadmin.LwtTopicHint')"/>
<InputElement v-show="mqttConfigList.mqtt_tls"
:label="$t('mqttadmin.RootCa')"
v-model="mqttConfigList.mqtt_root_ca_cert"
type="textarea" maxlength="2048" rows="10"/>
</div>
</div>
<InputElement :label="$t('mqttadmin.LwtOnline')"
v-model="mqttConfigList.mqtt_lwt_online"
type="text" maxlength="20"
:placeholder="$t('mqttadmin.LwtOnlineHint')"/>
<div class="card mt-5" v-show="mqttConfigList.mqtt_enabled">
<div class="card-header text-bg-primary">{{ $t('mqttadmin.LwtParameters') }}</div>
<div class="card-body">
<InputElement :label="$t('mqttadmin.LwtOffline')"
v-model="mqttConfigList.mqtt_lwt_offline"
type="text" maxlength="20"
:placeholder="$t('mqttadmin.LwtOfflineHint')"/>
</CardElement>
<InputElement :label="$t('mqttadmin.LwtTopic')"
v-model="mqttConfigList.mqtt_lwt_topic"
type="text" maxlength="32" :prefix="mqttConfigList.mqtt_topic"
:placeholder="$t('mqttadmin.LwtTopicHint')"/>
<CardElement :text="$t('mqttadmin.HassParameters')" textVariant="text-bg-primary" add-space
v-show="mqttConfigList.mqtt_enabled && mqttConfigList.mqtt_hass_enabled"
>
<InputElement :label="$t('mqttadmin.HassPrefixTopic')"
v-model="mqttConfigList.mqtt_hass_topic"
type="text" maxlength="32"
:placeholder="$t('mqttadmin.HassPrefixTopicHint')"/>
<InputElement :label="$t('mqttadmin.LwtOnline')"
v-model="mqttConfigList.mqtt_lwt_online"
type="text" maxlength="20"
:placeholder="$t('mqttadmin.LwtOnlineHint')"/>
<InputElement :label="$t('mqttadmin.HassRetain')"
v-model="mqttConfigList.mqtt_hass_retain"
type="checkbox"/>
<InputElement :label="$t('mqttadmin.LwtOffline')"
v-model="mqttConfigList.mqtt_lwt_offline"
type="text" maxlength="20"
:placeholder="$t('mqttadmin.LwtOfflineHint')"/>
</div>
</div>
<InputElement :label="$t('mqttadmin.HassExpire')"
v-model="mqttConfigList.mqtt_hass_expire"
type="checkbox"/>
<div class="card mt-5" v-show="mqttConfigList.mqtt_enabled && mqttConfigList.mqtt_hass_enabled">
<div class="card-header text-bg-primary">{{ $t('mqttadmin.HassParameters') }}</div>
<div class="card-body">
<InputElement :label="$t('mqttadmin.HassPrefixTopic')"
v-model="mqttConfigList.mqtt_hass_topic"
type="text" maxlength="32"
:placeholder="$t('mqttadmin.HassPrefixTopicHint')"/>
<InputElement :label="$t('mqttadmin.HassRetain')"
v-model="mqttConfigList.mqtt_hass_retain"
type="checkbox"/>
<InputElement :label="$t('mqttadmin.HassExpire')"
v-model="mqttConfigList.mqtt_hass_expire"
type="checkbox"/>
<InputElement :label="$t('mqttadmin.HassIndividual')"
v-model="mqttConfigList.mqtt_hass_individualpanels"
type="checkbox"/>
</div>
</div>
<InputElement :label="$t('mqttadmin.HassIndividual')"
v-model="mqttConfigList.mqtt_hass_individualpanels"
type="checkbox"/>
</CardElement>
<button type="submit" class="btn btn-primary mb-3">{{ $t('mqttadmin.Save') }}</button>
</form>
@ -124,6 +112,7 @@ import { defineComponent } from 'vue';
import BasePage from '@/components/BasePage.vue';
import BootstrapAlert from "@/components/BootstrapAlert.vue";
import InputElement from '@/components/InputElement.vue';
import CardElement from '@/components/CardElement.vue';
import { handleResponse, authHeader } from '@/utils/authentication';
import type { MqttConfig } from "@/types/MqttConfig";
@ -132,6 +121,7 @@ export default defineComponent({
BasePage,
BootstrapAlert,
InputElement,
CardElement,
},
data() {
return {

View File

@ -1,149 +1,140 @@
<template>
<BasePage :title="$t('mqttinfo.MqttInformation')" :isLoading="dataLoading">
<div class="card">
<div class="card-header text-bg-primary">{{ $t('mqttinfo.ConfigurationSummary') }}</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover table-condensed">
<tbody>
<tr>
<th>{{ $t('mqttinfo.Status') }}</th>
<td class="badge" :class="{
'text-bg-danger': !mqttDataList.mqtt_enabled,
'text-bg-success': mqttDataList.mqtt_enabled,
}">
<span v-if="mqttDataList.mqtt_enabled">{{ $t('mqttinfo.Enabled') }}</span>
<span v-else>{{ $t('mqttinfo.Disabled') }}</span>
</td>
</tr>
<tr>
<th>{{ $t('mqttinfo.Server') }}</th>
<td>{{ mqttDataList.mqtt_hostname }}</td>
</tr>
<tr>
<th>{{ $t('mqttinfo.Port') }}</th>
<td>{{ mqttDataList.mqtt_port }}</td>
</tr>
<tr>
<th>{{ $t('mqttinfo.Username') }}</th>
<td>{{ mqttDataList.mqtt_username }}</td>
</tr>
<tr>
<th>{{ $t('mqttinfo.BaseTopic') }}</th>
<td>{{ mqttDataList.mqtt_topic }}</td>
</tr>
<tr>
<th>{{ $t('mqttinfo.PublishInterval') }}</th>
<td>{{ $t('mqttinfo.Seconds', { sec: mqttDataList.mqtt_publish_interval }) }}</td>
</tr>
<tr>
<th>{{ $t('mqttinfo.Retain') }}</th>
<td class="badge" :class="{
'text-bg-danger': !mqttDataList.mqtt_retain,
'text-bg-success': mqttDataList.mqtt_retain,
}">
<span v-if="mqttDataList.mqtt_retain">{{ $t('mqttinfo.Enabled') }}</span>
<span v-else>{{ $t('mqttinfo.Disabled') }}</span>
</td>
</tr>
<tr>
<th>{{ $t('mqttinfo.Tls') }}</th>
<td class="badge" :class="{
'text-bg-danger': !mqttDataList.mqtt_tls,
'text-bg-success': mqttDataList.mqtt_tls,
}">
<span v-if="mqttDataList.mqtt_tls">{{ $t('mqttinfo.Enabled') }}</span>
<span v-else>{{ $t('mqttinfo.Disabled') }}</span>
</td>
</tr>
<tr v-show="mqttDataList.mqtt_tls">
<th>{{ $t('mqttinfo.RootCertifcateInfo') }}</th>
<td>{{ mqttDataList.mqtt_root_ca_cert_info }}</td>
</tr>
</tbody>
</table>
</div>
<CardElement :text="$t('mqttinfo.ConfigurationSummary')" textVariant="text-bg-primary">
<div class="table-responsive">
<table class="table table-hover table-condensed">
<tbody>
<tr>
<th>{{ $t('mqttinfo.Status') }}</th>
<td class="badge" :class="{
'text-bg-danger': !mqttDataList.mqtt_enabled,
'text-bg-success': mqttDataList.mqtt_enabled,
}">
<span v-if="mqttDataList.mqtt_enabled">{{ $t('mqttinfo.Enabled') }}</span>
<span v-else>{{ $t('mqttinfo.Disabled') }}</span>
</td>
</tr>
<tr>
<th>{{ $t('mqttinfo.Server') }}</th>
<td>{{ mqttDataList.mqtt_hostname }}</td>
</tr>
<tr>
<th>{{ $t('mqttinfo.Port') }}</th>
<td>{{ mqttDataList.mqtt_port }}</td>
</tr>
<tr>
<th>{{ $t('mqttinfo.Username') }}</th>
<td>{{ mqttDataList.mqtt_username }}</td>
</tr>
<tr>
<th>{{ $t('mqttinfo.BaseTopic') }}</th>
<td>{{ mqttDataList.mqtt_topic }}</td>
</tr>
<tr>
<th>{{ $t('mqttinfo.PublishInterval') }}</th>
<td>{{ $t('mqttinfo.Seconds', { sec: mqttDataList.mqtt_publish_interval }) }}</td>
</tr>
<tr>
<th>{{ $t('mqttinfo.Retain') }}</th>
<td class="badge" :class="{
'text-bg-danger': !mqttDataList.mqtt_retain,
'text-bg-success': mqttDataList.mqtt_retain,
}">
<span v-if="mqttDataList.mqtt_retain">{{ $t('mqttinfo.Enabled') }}</span>
<span v-else>{{ $t('mqttinfo.Disabled') }}</span>
</td>
</tr>
<tr>
<th>{{ $t('mqttinfo.Tls') }}</th>
<td class="badge" :class="{
'text-bg-danger': !mqttDataList.mqtt_tls,
'text-bg-success': mqttDataList.mqtt_tls,
}">
<span v-if="mqttDataList.mqtt_tls">{{ $t('mqttinfo.Enabled') }}</span>
<span v-else>{{ $t('mqttinfo.Disabled') }}</span>
</td>
</tr>
<tr v-show="mqttDataList.mqtt_tls">
<th>{{ $t('mqttinfo.RootCertifcateInfo') }}</th>
<td>{{ mqttDataList.mqtt_root_ca_cert_info }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</CardElement>
<div class="card mt-5">
<div class="card-header text-bg-primary">{{ $t('mqttinfo.HassSummary') }}</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover table-condensed">
<tbody>
<tr>
<th>{{ $t('mqttinfo.Status') }}</th>
<td class="badge" :class="{
'text-bg-danger': !mqttDataList.mqtt_hass_enabled,
'text-bg-success': mqttDataList.mqtt_hass_enabled,
}">
<span v-if="mqttDataList.mqtt_hass_enabled">{{ $t('mqttinfo.Enabled') }}</span>
<span v-else>{{ $t('mqttinfo.Disabled') }}</span>
</td>
</tr>
<tr>
<th>{{ $t('mqttinfo.BaseTopic') }}</th>
<td>{{ mqttDataList.mqtt_hass_topic }}</td>
</tr>
<tr>
<th>{{ $t('mqttinfo.Retain') }}</th>
<td class="badge" :class="{
'text-bg-danger': !mqttDataList.mqtt_hass_retain,
'text-bg-success': mqttDataList.mqtt_hass_retain,
}">
<span v-if="mqttDataList.mqtt_hass_retain">{{ $t('mqttinfo.Enabled') }}</span>
<span v-else>{{ $t('mqttinfo.Disabled') }}</span>
</td>
</tr>
<tr>
<th>{{ $t('mqttinfo.Expire') }}</th>
<td class="badge" :class="{
'text-bg-danger': !mqttDataList.mqtt_hass_expire,
'text-bg-success': mqttDataList.mqtt_hass_expire,
}">
<span v-if="mqttDataList.mqtt_hass_expire">{{ $t('mqttinfo.Enabled') }}</span>
<span v-else>{{ $t('mqttinfo.Disabled') }}</span>
</td>
</tr>
<tr>
<th>{{ $t('mqttinfo.IndividualPanels') }}</th>
<td class="badge" :class="{
'text-bg-danger': !mqttDataList.mqtt_hass_individualpanels,
'text-bg-success': mqttDataList.mqtt_hass_individualpanels,
}">
<span v-if="mqttDataList.mqtt_hass_individualpanels">{{ $t('mqttinfo.Enabled')
}}</span>
<span v-else>{{ $t('mqttinfo.Disabled') }}</span>
</td>
</tr>
</tbody>
</table>
</div>
<CardElement :text="$t('mqttinfo.HassSummary')" textVariant="text-bg-primary" add-space>
<div class="table-responsive">
<table class="table table-hover table-condensed">
<tbody>
<tr>
<th>{{ $t('mqttinfo.Status') }}</th>
<td class="badge" :class="{
'text-bg-danger': !mqttDataList.mqtt_hass_enabled,
'text-bg-success': mqttDataList.mqtt_hass_enabled,
}">
<span v-if="mqttDataList.mqtt_hass_enabled">{{ $t('mqttinfo.Enabled') }}</span>
<span v-else>{{ $t('mqttinfo.Disabled') }}</span>
</td>
</tr>
<tr>
<th>{{ $t('mqttinfo.BaseTopic') }}</th>
<td>{{ mqttDataList.mqtt_hass_topic }}</td>
</tr>
<tr>
<th>{{ $t('mqttinfo.Retain') }}</th>
<td class="badge" :class="{
'text-bg-danger': !mqttDataList.mqtt_hass_retain,
'text-bg-success': mqttDataList.mqtt_hass_retain,
}">
<span v-if="mqttDataList.mqtt_hass_retain">{{ $t('mqttinfo.Enabled') }}</span>
<span v-else>{{ $t('mqttinfo.Disabled') }}</span>
</td>
</tr>
<tr>
<th>{{ $t('mqttinfo.Expire') }}</th>
<td class="badge" :class="{
'text-bg-danger': !mqttDataList.mqtt_hass_expire,
'text-bg-success': mqttDataList.mqtt_hass_expire,
}">
<span v-if="mqttDataList.mqtt_hass_expire">{{ $t('mqttinfo.Enabled') }}</span>
<span v-else>{{ $t('mqttinfo.Disabled') }}</span>
</td>
</tr>
<tr>
<th>{{ $t('mqttinfo.IndividualPanels') }}</th>
<td class="badge" :class="{
'text-bg-danger': !mqttDataList.mqtt_hass_individualpanels,
'text-bg-success': mqttDataList.mqtt_hass_individualpanels,
}">
<span v-if="mqttDataList.mqtt_hass_individualpanels">{{ $t('mqttinfo.Enabled')
}}</span>
<span v-else>{{ $t('mqttinfo.Disabled') }}</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</CardElement>
<div class="card mt-5">
<div class="card-header text-bg-primary">{{ $t('mqttinfo.RuntimeSummary') }}</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover table-condensed">
<tbody>
<tr>
<th>{{ $t('mqttinfo.ConnectionStatus') }}</th>
<td class="badge" :class="{
'text-bg-danger': !mqttDataList.mqtt_connected,
'text-bg-success': mqttDataList.mqtt_connected,
}">
<span v-if="mqttDataList.mqtt_connected">{{ $t('mqttinfo.Connected') }}</span>
<span v-else>{{ $t('mqttinfo.Disconnected') }}</span>
</td>
</tr>
</tbody>
</table>
</div>
<CardElement :text="$t('mqttinfo.RuntimeSummary')" textVariant="text-bg-primary" add-space>
<div class="table-responsive">
<table class="table table-hover table-condensed">
<tbody>
<tr>
<th>{{ $t('mqttinfo.ConnectionStatus') }}</th>
<td class="badge" :class="{
'text-bg-danger': !mqttDataList.mqtt_connected,
'text-bg-success': mqttDataList.mqtt_connected,
}">
<span v-if="mqttDataList.mqtt_connected">{{ $t('mqttinfo.Connected') }}</span>
<span v-else>{{ $t('mqttinfo.Disconnected') }}</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</CardElement>
</BasePage>
</template>
@ -151,11 +142,13 @@
import { defineComponent } from 'vue';
import { handleResponse, authHeader } from '@/utils/authentication';
import BasePage from '@/components/BasePage.vue';
import CardElement from '@/components/CardElement.vue';
import type { MqttStatus } from '@/types/MqttStatus';
export default defineComponent({
components: {
BasePage,
CardElement,
},
data() {
return {

View File

@ -5,58 +5,51 @@
</BootstrapAlert>
<form @submit="saveNetworkConfig">
<div class="card">
<div class="card-header text-bg-primary">{{ $t('networkadmin.WifiConfiguration') }}</div>
<div class="card-body">
<CardElement :text="$t('networkadmin.WifiConfiguration')" textVariant="text-bg-primary">
<InputElement :label="$t('networkadmin.WifiSsid')"
v-model="networkConfigList.ssid"
type="text" maxlength="32"/>
<InputElement :label="$t('networkadmin.WifiSsid')"
v-model="networkConfigList.ssid"
type="text" maxlength="32"/>
<InputElement :label="$t('networkadmin.WifiPassword')"
v-model="networkConfigList.password"
type="password" maxlength="64"/>
<InputElement :label="$t('networkadmin.WifiPassword')"
v-model="networkConfigList.password"
type="password" maxlength="64"/>
<InputElement :label="$t('networkadmin.Hostname')"
v-model="networkConfigList.hostname"
type="text" maxlength="32"
>
<div class="alert alert-secondary" role="alert" v-html="$t('networkadmin.HostnameHint')"></div>
</InputElement>
<InputElement :label="$t('networkadmin.Hostname')"
v-model="networkConfigList.hostname"
type="text" maxlength="32"
>
<div class="alert alert-secondary" role="alert" v-html="$t('networkadmin.HostnameHint')"></div>
</InputElement>
<InputElement :label="$t('networkadmin.EnableDhcp')"
v-model="networkConfigList.dhcp"
type="checkbox"/>
</CardElement>
<InputElement :label="$t('networkadmin.EnableDhcp')"
v-model="networkConfigList.dhcp"
type="checkbox"/>
</div>
</div>
<CardElement :text="$t('networkadmin.StaticIpConfiguration')" textVariant="text-bg-primary" add-space
v-show="!networkConfigList.dhcp"
>
<InputElement :label="$t('networkadmin.IpAddress')"
v-model="networkConfigList.ipaddress"
type="text" maxlength="32"/>
<div class="card" v-show="!networkConfigList.dhcp">
<div class="card-header text-bg-primary">
{{ $t('networkadmin.StaticIpConfiguration') }}
</div>
<div class="card-body">
<InputElement :label="$t('networkadmin.Netmask')"
v-model="networkConfigList.netmask"
type="text" maxlength="32"/>
<InputElement :label="$t('networkadmin.IpAddress')"
v-model="networkConfigList.ipaddress"
type="text" maxlength="32"/>
<InputElement :label="$t('networkadmin.DefaultGateway')"
v-model="networkConfigList.gateway"
type="text" maxlength="32"/>
<InputElement :label="$t('networkadmin.Netmask')"
v-model="networkConfigList.netmask"
type="text" maxlength="32"/>
<InputElement :label="$t('networkadmin.Dns', { num: 1 })"
v-model="networkConfigList.dns1"
type="text" maxlength="32"/>
<InputElement :label="$t('networkadmin.DefaultGateway')"
v-model="networkConfigList.gateway"
type="text" maxlength="32"/>
<InputElement :label="$t('networkadmin.Dns', { num: 2 })"
v-model="networkConfigList.dns2"
type="text" maxlength="32"/>
</CardElement>
<InputElement :label="$t('networkadmin.Dns', { num: 1 })"
v-model="networkConfigList.dns1"
type="text" maxlength="32"/>
<InputElement :label="$t('networkadmin.Dns', { num: 2 })"
v-model="networkConfigList.dns2"
type="text" maxlength="32"/>
</div>
</div>
<button type="submit" class="btn btn-primary mb-3">{{ $t('networkadmin.Save') }}</button>
</form>
</BasePage>
@ -67,6 +60,7 @@ import { defineComponent } from 'vue';
import BasePage from '@/components/BasePage.vue';
import BootstrapAlert from "@/components/BootstrapAlert.vue";
import InputElement from '@/components/InputElement.vue';
import CardElement from '@/components/CardElement.vue';
import { handleResponse, authHeader } from '@/utils/authentication';
import type { NetworkConfig } from "@/types/NetworkkConfig";
@ -75,6 +69,7 @@ export default defineComponent({
BasePage,
BootstrapAlert,
InputElement,
CardElement,
},
data() {
return {

View File

@ -5,55 +5,47 @@
</BootstrapAlert>
<form @submit="saveNtpConfig">
<div class="card">
<div class="card-header text-bg-primary">{{ $t('ntpadmin.NtpConfiguration') }}</div>
<div class="card-body">
<CardElement :text="$t('ntpadmin.NtpConfiguration')" textVariant="text-bg-primary">
<InputElement :label="$t('ntpadmin.TimeServer')"
v-model="ntpConfigList.ntp_server"
type="text" maxlength="32"
:tooltip="$t('ntpadmin.TimeServerHint')"/>
<InputElement :label="$t('ntpadmin.TimeServer')"
v-model="ntpConfigList.ntp_server"
type="text" maxlength="32"
:tooltip="$t('ntpadmin.TimeServerHint')"/>
<div class="row mb-3">
<label for="inputTimezone" class="col-sm-2 col-form-label">{{ $t('ntpadmin.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 class="row mb-3">
<label for="inputTimezone" class="col-sm-2 col-form-label">{{ $t('ntpadmin.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>
<InputElement :label="$t('ntpadmin.TimezoneConfig')"
v-model="ntpConfigList.ntp_timezone"
type="text" maxlength="32" disabled/>
</div>
</div>
<InputElement :label="$t('ntpadmin.TimezoneConfig')"
v-model="ntpConfigList.ntp_timezone"
type="text" maxlength="32" disabled/>
</CardElement>
<button type="submit" class="btn btn-primary mb-3">{{ $t('ntpadmin.Save') }}</button>
</form>
<div class="card">
<div class="card-header text-bg-primary">{{ $t('ntpadmin.ManualTimeSynchronization') }}</div>
<div class="card-body">
<CardElement :text="$t('ntpadmin.ManualTimeSynchronization')" textVariant="text-bg-primary" add-space>
<InputElement :label="$t('ntpadmin.CurrentOpenDtuTime')"
v-model="mcuTime"
type="text" disabled/>
<InputElement :label="$t('ntpadmin.CurrentOpenDtuTime')"
v-model="mcuTime"
type="text" disabled/>
<InputElement :label="$t('ntpadmin.CurrentLocalTime')"
v-model="localTime"
type="text" disabled/>
<InputElement :label="$t('ntpadmin.CurrentLocalTime')"
v-model="localTime"
type="text" disabled/>
<div class="text-center mb-3">
<button type="button" class="btn btn-danger" @click="setCurrentTime()">
{{ $t('ntpadmin.SynchronizeTime') }}
</button>
</div>
<div class="alert alert-secondary" role="alert" v-html="$t('ntpadmin.SynchronizeTimeHint')"></div>
<div class="text-center mb-3">
<button type="button" class="btn btn-danger" @click="setCurrentTime()">
{{ $t('ntpadmin.SynchronizeTime') }}
</button>
</div>
</div>
<div class="alert alert-secondary" role="alert" v-html="$t('ntpadmin.SynchronizeTimeHint')"></div>
</CardElement>
</BasePage>
</template>
@ -62,6 +54,7 @@ import { defineComponent } from 'vue';
import BasePage from '@/components/BasePage.vue';
import BootstrapAlert from "@/components/BootstrapAlert.vue";
import InputElement from '@/components/InputElement.vue';
import CardElement from '@/components/CardElement.vue';
import { handleResponse, authHeader } from '@/utils/authentication';
import type { NtpConfig } from "@/types/NtpConfig";
import {
@ -74,6 +67,7 @@ export default defineComponent({
BootstrapAlert,
BIconInfoCircle,
InputElement,
CardElement,
},
data() {
return {

View File

@ -1,54 +1,48 @@
<template>
<BasePage :title="$t('ntpinfo.NtpInformation')" :isLoading="dataLoading">
<div class="card">
<div class="card-header text-bg-primary">{{ $t('ntpinfo.ConfigurationSummary') }}</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover table-condensed">
<tbody>
<tr>
<th>{{ $t('ntpinfo.Server') }}</th>
<td>{{ ntpDataList.ntp_server }}</td>
</tr>
<tr>
<th>{{ $t('ntpinfo.Timezone') }}</th>
<td>{{ ntpDataList.ntp_timezone }}</td>
</tr>
<tr>
<th>{{ $t('ntpinfo.TimezoneDescription') }}</th>
<td>{{ ntpDataList.ntp_timezone_descr }}</td>
</tr>
</tbody>
</table>
</div>
<CardElement :text="$t('ntpinfo.ConfigurationSummary')" textVariant="text-bg-primary">
<div class="table-responsive">
<table class="table table-hover table-condensed">
<tbody>
<tr>
<th>{{ $t('ntpinfo.Server') }}</th>
<td>{{ ntpDataList.ntp_server }}</td>
</tr>
<tr>
<th>{{ $t('ntpinfo.Timezone') }}</th>
<td>{{ ntpDataList.ntp_timezone }}</td>
</tr>
<tr>
<th>{{ $t('ntpinfo.TimezoneDescription') }}</th>
<td>{{ ntpDataList.ntp_timezone_descr }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</CardElement>
<div class="card mt-5">
<div class="card-header text-bg-primary">{{ $t('ntpinfo.CurrentTime') }}</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover table-condensed">
<tbody>
<tr>
<th>{{ $t('ntpinfo.Status') }}</th>
<td class="badge" :class="{
'text-bg-danger': !ntpDataList.ntp_status,
'text-bg-success': ntpDataList.ntp_status,
}">
<span v-if="ntpDataList.ntp_status">{{ $t('ntpinfo.Synced') }}</span>
<span v-else>{{ $t('ntpinfo.NotSynced') }}</span>
</td>
</tr>
<tr>
<th>{{ $t('ntpinfo.LocalTime') }}</th>
<td>{{ ntpDataList.ntp_localtime }}</td>
</tr>
</tbody>
</table>
</div>
<CardElement :text="$t('ntpinfo.CurrentTime')" textVariant="text-bg-primary" add-space>
<div class="table-responsive">
<table class="table table-hover table-condensed">
<tbody>
<tr>
<th>{{ $t('ntpinfo.Status') }}</th>
<td class="badge" :class="{
'text-bg-danger': !ntpDataList.ntp_status,
'text-bg-success': ntpDataList.ntp_status,
}">
<span v-if="ntpDataList.ntp_status">{{ $t('ntpinfo.Synced') }}</span>
<span v-else>{{ $t('ntpinfo.NotSynced') }}</span>
</td>
</tr>
<tr>
<th>{{ $t('ntpinfo.LocalTime') }}</th>
<td>{{ ntpDataList.ntp_localtime }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</CardElement>
</BasePage>
</template>
@ -56,11 +50,13 @@
import { defineComponent } from 'vue';
import { handleResponse, authHeader } from '@/utils/authentication';
import BasePage from '@/components/BasePage.vue';
import CardElement from '@/components/CardElement.vue';
import type { NtpStatus } from "@/types/NtpStatus";
export default defineComponent({
components: {
BasePage,
CardElement,
},
data() {
return {

View File

@ -5,31 +5,23 @@
</BootstrapAlert>
<form @submit="savePasswordConfig">
<div class="card">
<div class="card-header text-bg-primary">{{ $t('securityadmin.AdminPassword') }}</div>
<div class="card-body">
<CardElement :text="$t('securityadmin.AdminPassword')" textVariant="text-bg-primary">
<InputElement :label="$t('securityadmin.Password')"
v-model="securityConfigList.password"
type="password" maxlength="64"/>
<InputElement :label="$t('securityadmin.Password')"
v-model="securityConfigList.password"
type="password" maxlength="64"/>
<InputElement :label="$t('securityadmin.RepeatPassword')"
v-model="passwordRepeat"
type="password" maxlength="64"/>
<InputElement :label="$t('securityadmin.RepeatPassword')"
v-model="passwordRepeat"
type="password" maxlength="64"/>
<div class="alert alert-secondary" role="alert" v-html="$t('securityadmin.PasswordHint')"></div>
</CardElement>
<div class="alert alert-secondary" role="alert" v-html="$t('securityadmin.PasswordHint')"></div>
</div>
</div>
<div class="card mt-5">
<div class="card-header text-bg-primary">{{ $t('securityadmin.Permissions') }}</div>
<div class="card-body">
<InputElement :label="$t('securityadmin.ReadOnly')"
v-model="securityConfigList.allow_readonly"
type="checkbox" wide/>
</div>
</div>
<CardElement :text="$t('securityadmin.Permissions')" textVariant="text-bg-primary" add-space>
<InputElement :label="$t('securityadmin.ReadOnly')"
v-model="securityConfigList.allow_readonly"
type="checkbox" wide/>
</CardElement>
<button type="submit" class="btn btn-primary mb-3">{{ $t('securityadmin.Save') }}</button>
</form>
@ -41,6 +33,7 @@ import { defineComponent } from 'vue';
import BasePage from '@/components/BasePage.vue';
import BootstrapAlert from "@/components/BootstrapAlert.vue";
import InputElement from '@/components/InputElement.vue';
import CardElement from '@/components/CardElement.vue';
import { handleResponse, authHeader } from '@/utils/authentication';
import type { SecurityConfig } from '@/types/SecurityConfig';
@ -49,6 +42,7 @@ export default defineComponent({
BasePage,
BootstrapAlert,
InputElement,
CardElement,
},
data() {
return {