mirror of
https://github.com/donaldzou/WGDashboard
synced 2025-02-26 05:58:47 +00:00
Refactoring configuration list
This commit is contained in:
parent
ccfc1ad166
commit
cd9d17ab18
@ -563,7 +563,6 @@ class WireguardConfiguration:
|
||||
return False, err
|
||||
return True, None
|
||||
|
||||
|
||||
def __parseConfigurationFile(self):
|
||||
with open(self.configPath, 'r') as f:
|
||||
original = [l.rstrip("\n") for l in f.readlines()]
|
||||
@ -1094,8 +1093,7 @@ class WireguardConfiguration:
|
||||
"filename": f'{self.Name}_{time}.conf',
|
||||
"backupDate": datetime.now().strftime("%Y%m%d%H%M%S")
|
||||
}
|
||||
|
||||
|
||||
|
||||
def getBackups(self, databaseContent: bool = False) -> list[dict[str: str, str: str, str: str]]:
|
||||
backups = []
|
||||
|
||||
@ -1171,9 +1169,6 @@ class WireguardConfiguration:
|
||||
|
||||
return True, zip
|
||||
|
||||
|
||||
|
||||
|
||||
def updateConfigurationSettings(self, newData: dict) -> tuple[bool, str]:
|
||||
if self.Status:
|
||||
self.toggleConfiguration()
|
||||
@ -1208,6 +1203,11 @@ class WireguardConfiguration:
|
||||
status, msg = self.toggleConfiguration()
|
||||
if not status:
|
||||
return False, msg
|
||||
for i in allowEdit:
|
||||
if isinstance(getattr(self, i), bool):
|
||||
setattr(self, i, _strToBool(newData[i]))
|
||||
else:
|
||||
setattr(self, i, str(newData[i]))
|
||||
return True, ""
|
||||
|
||||
def deleteConfiguration(self):
|
||||
@ -1274,6 +1274,29 @@ class WireguardConfiguration:
|
||||
break
|
||||
return True, availableAddress
|
||||
|
||||
def getRealtimeTrafficUsage(self):
|
||||
stats = psutil.net_io_counters(pernic=True, nowrap=True)
|
||||
if self.Name in stats.keys():
|
||||
stat = stats[self.Name]
|
||||
recv1 = stat.bytes_recv
|
||||
sent1 = stat.bytes_sent
|
||||
time.sleep(1)
|
||||
stats = psutil.net_io_counters(pernic=True, nowrap=True)
|
||||
if self.Name in stats.keys():
|
||||
stat = stats[self.Name]
|
||||
recv2 = stat.bytes_recv
|
||||
sent2 = stat.bytes_sent
|
||||
net_in = round((recv2 - recv1) / 1024 / 1024, 3)
|
||||
net_out = round((sent2 - sent1) / 1024 / 1024, 3)
|
||||
return {
|
||||
"sent": net_out,
|
||||
"recv": net_in
|
||||
}
|
||||
else:
|
||||
return { "sent": 0, "recv": 0 }
|
||||
else:
|
||||
return { "sent": 0, "recv": 0 }
|
||||
|
||||
"""
|
||||
AmneziaWG Configuration
|
||||
"""
|
||||
@ -2039,7 +2062,6 @@ def sqlSelect(statement: str, paramters: tuple = ()) -> sqlite3.Cursor:
|
||||
result = []
|
||||
with sqldb:
|
||||
try:
|
||||
print("[WGDashboard] SQLite Select" + " | Statement: " + statement)
|
||||
cursor = sqldb.cursor()
|
||||
result = cursor.execute(statement, paramters)
|
||||
except Exception as error:
|
||||
@ -2327,6 +2349,13 @@ def API_renameWireguardConfiguration():
|
||||
WireguardConfigurations[data.get("NewConfigurationName")] = WireguardConfiguration(data.get("NewConfigurationName"))
|
||||
return ResponseObject(status, message)
|
||||
|
||||
@app.get(f'{APP_PREFIX}/api/getWireguardConfigurationRealtimeTraffic')
|
||||
def API_getWireguardConfigurationRealtimeTraffic():
|
||||
configurationName = request.args.get('configurationName')
|
||||
if configurationName is None or configurationName not in WireguardConfigurations.keys():
|
||||
return ResponseObject(False, "Configuration does not exist")
|
||||
return ResponseObject(data=WireguardConfigurations[configurationName].getRealtimeTrafficUsage())
|
||||
|
||||
@app.get(f'{APP_PREFIX}/api/getWireguardConfigurationBackup')
|
||||
def API_getWireguardConfigurationBackup():
|
||||
configurationName = request.args.get('configurationName')
|
||||
|
@ -24,12 +24,7 @@ onBeforeUnmount(() =>{
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="text-center">
|
||||
<small v-if="peerListLength < showPeersCount" class="text-muted">
|
||||
That's it, no more peers
|
||||
</small>
|
||||
<div style="margin-bottom: 20px; height: 1px" id="loadMore"></div>
|
||||
</div>
|
||||
<div style="margin-bottom: 20px; height: 1px" id="loadMore"></div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
@ -79,7 +79,7 @@ export default {
|
||||
Line,
|
||||
Bar
|
||||
},
|
||||
setup(){
|
||||
async setup(){
|
||||
const dashboardConfigurationStore = DashboardConfigurationStore();
|
||||
const wireguardConfigurationStore = WireguardConfigurationsStore();
|
||||
const interval = ref(undefined)
|
||||
@ -284,9 +284,6 @@ export default {
|
||||
this.getPeers()
|
||||
}, parseInt(this.dashboardConfigurationStore.Configuration.Server.dashboard_refresh_interval))
|
||||
},
|
||||
disableMutationObserver(){
|
||||
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
configurationSummary(){
|
||||
|
@ -0,0 +1,263 @@
|
||||
<script setup>
|
||||
import {computed, defineComponent, onBeforeUnmount, onMounted, reactive, ref, useTemplateRef, watch} from "vue";
|
||||
import {fetchGet} from "@/utilities/fetch.js";
|
||||
import { Line, Bar } from 'vue-chartjs'
|
||||
import {
|
||||
Chart,
|
||||
LineElement,
|
||||
BarElement,
|
||||
BarController,
|
||||
LineController,
|
||||
LinearScale,
|
||||
Legend,
|
||||
Title,
|
||||
Tooltip,
|
||||
CategoryScale,
|
||||
PointElement
|
||||
} from 'chart.js';
|
||||
Chart.register(
|
||||
LineElement,
|
||||
BarElement,
|
||||
BarController,
|
||||
LineController,
|
||||
LinearScale,
|
||||
Legend,
|
||||
Title,
|
||||
Tooltip,
|
||||
CategoryScale,
|
||||
PointElement
|
||||
);
|
||||
|
||||
import LocaleText from "@/components/text/localeText.vue";
|
||||
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
|
||||
import dayjs from "dayjs";
|
||||
const props = defineProps({
|
||||
configurationPeers: Array,
|
||||
configurationInfo: Object
|
||||
})
|
||||
|
||||
const historySentData = ref({
|
||||
timestamp: [],
|
||||
data: []
|
||||
})
|
||||
|
||||
const historyReceivedData = ref({
|
||||
timestamp: [],
|
||||
data: []
|
||||
})
|
||||
|
||||
const dashboardStore = DashboardConfigurationStore()
|
||||
const fetchRealtimeTrafficInterval = ref(undefined)
|
||||
const fetchRealtimeTraffic = async () => {
|
||||
await fetchGet("/api/getWireguardConfigurationRealtimeTraffic", {
|
||||
configurationName: "wg1"
|
||||
}, (res) => {
|
||||
let timestamp = dayjs().format("hh:mm:ss A")
|
||||
|
||||
historySentData.value.timestamp.push(timestamp)
|
||||
historySentData.value.data.push(res.data.sent)
|
||||
|
||||
historyReceivedData.value.timestamp.push(timestamp)
|
||||
historyReceivedData.value.data.push(res.data.recv)
|
||||
|
||||
})
|
||||
}
|
||||
const toggleFetchRealtimeTraffic = () => {
|
||||
clearInterval(fetchRealtimeTrafficInterval.value)
|
||||
fetchRealtimeTrafficInterval.value = undefined;
|
||||
if (props.configurationInfo.Status){
|
||||
fetchRealtimeTrafficInterval.value = setInterval(() => {
|
||||
fetchRealtimeTraffic()
|
||||
}, parseInt(dashboardStore.Configuration.Server.dashboard_refresh_interval))
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
toggleFetchRealtimeTraffic()
|
||||
})
|
||||
|
||||
watch(() => props.configurationInfo.Status, () => {
|
||||
toggleFetchRealtimeTraffic()
|
||||
})
|
||||
|
||||
watch(() => dashboardStore.Configuration.Server.dashboard_refresh_interval, () => {
|
||||
toggleFetchRealtimeTraffic()
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
clearInterval(fetchRealtimeTrafficInterval.value)
|
||||
fetchRealtimeTrafficInterval.value = undefined;
|
||||
})
|
||||
const peersDataUsageChartData = computed(() => {
|
||||
return {
|
||||
labels: props.configurationPeers.map(x => {
|
||||
if (x.name) return x.name
|
||||
return `Untitled Peer - ${x.id}`
|
||||
}),
|
||||
datasets: [{
|
||||
label: 'Total Data Usage',
|
||||
data: props.configurationPeers.map(x => x.cumu_data + x.total_data),
|
||||
backgroundColor: props.configurationPeers.map(x => `#ffc107`),
|
||||
barThickness: 50,
|
||||
tooltip: {
|
||||
callbacks: {
|
||||
label: (tooltipItem) => {
|
||||
return `${tooltipItem.formattedValue} GB`
|
||||
}
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
})
|
||||
const peersRealtimeSentData = computed(() => {
|
||||
return {
|
||||
labels: [...historySentData.value.timestamp],
|
||||
datasets: [
|
||||
{
|
||||
label: 'Data Sent',
|
||||
data: [...historySentData.value.data],
|
||||
fill: false,
|
||||
borderColor: '#198754',
|
||||
backgroundColor: '#198754',
|
||||
tension: 0
|
||||
},
|
||||
],
|
||||
}
|
||||
})
|
||||
const peersRealtimeReceivedData = computed(() => {
|
||||
return {
|
||||
labels: [...historyReceivedData.value.timestamp],
|
||||
datasets: [
|
||||
{
|
||||
label: 'Data Received',
|
||||
data: [...historyReceivedData.value.data],
|
||||
fill: false,
|
||||
borderColor: '#0d6efd',
|
||||
tension: 0
|
||||
},
|
||||
],
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
const peersDataUsageChartOption = computed(() => {
|
||||
return {
|
||||
responsive: true,
|
||||
plugins: {
|
||||
legend: {
|
||||
display: false
|
||||
}
|
||||
},
|
||||
scales: {
|
||||
x: {
|
||||
ticks: {
|
||||
display: false,
|
||||
},
|
||||
grid: {
|
||||
display: false
|
||||
},
|
||||
},
|
||||
y:{
|
||||
ticks: {
|
||||
callback: (val, index) => {
|
||||
return `${val} GB`
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
display: false
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
const realtimePeersChartOption = computed(() => {
|
||||
return {
|
||||
responsive: true,
|
||||
plugins: {
|
||||
legend: {
|
||||
display: false
|
||||
},
|
||||
tooltip: {
|
||||
callbacks: {
|
||||
label: (tooltipItem) => {
|
||||
return `${tooltipItem.formattedValue} MB/s`
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
scales: {
|
||||
x: {
|
||||
ticks: {
|
||||
display: false,
|
||||
},
|
||||
grid: {
|
||||
display: false
|
||||
},
|
||||
},
|
||||
y:{
|
||||
ticks: {
|
||||
callback: (val, index) => {
|
||||
return `${Math.round((val + Number.EPSILON) * 1000) / 1000
|
||||
} MB/s`
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
display: false
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="row gx-2 gy-2 mb-3">
|
||||
<div class="col-12">
|
||||
<div class="card rounded-3 bg-transparent " style="height: 270px">
|
||||
<div class="card-header bg-transparent border-0">
|
||||
<small class="text-muted">
|
||||
<LocaleText t="Peers Data Usage"></LocaleText>
|
||||
</small></div>
|
||||
<div class="card-body pt-1">
|
||||
<Bar
|
||||
:data="peersDataUsageChartData"
|
||||
:options="peersDataUsageChartOption"
|
||||
style="width: 100%; height: 200px; max-height: 200px"></Bar>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm col-lg-6">
|
||||
<div class="card rounded-3 bg-transparent " style="height: 270px">
|
||||
<div class="card-header bg-transparent border-0"><small class="text-muted">
|
||||
<LocaleText t="Real Time Received Data Usage"></LocaleText>
|
||||
</small></div>
|
||||
<div class="card-body pt-1">
|
||||
<Line
|
||||
:options="realtimePeersChartOption"
|
||||
:data="peersRealtimeReceivedData"
|
||||
style="width: 100%; height: 200px; max-height: 200px"
|
||||
></Line>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm col-lg-6">
|
||||
<div class="card rounded-3 bg-transparent " style="height: 270px">
|
||||
<div class="card-header bg-transparent border-0"><small class="text-muted">
|
||||
<LocaleText t="Real Time Sent Data Usage"></LocaleText>
|
||||
</small></div>
|
||||
<div class="card-body pt-1">
|
||||
<Line
|
||||
:options="realtimePeersChartOption"
|
||||
:data="peersRealtimeSentData"
|
||||
|
||||
style="width: 100%; height: 200px; max-height: 200px"
|
||||
></Line>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@ -0,0 +1,23 @@
|
||||
<script setup>
|
||||
import {defineAsyncComponent} from "vue";
|
||||
import LocaleText from "@/components/text/localeText.vue";
|
||||
const DeleteConfigurationModal = defineAsyncComponent(() => import("@/components/configurationComponents/deleteConfiguration.vue"))
|
||||
const ConfigurationBackupRestoreModal = defineAsyncComponent(() => import("@/components/configurationComponents/configurationBackupRestore.vue"))
|
||||
const SelectPeersModal = defineAsyncComponent(() => import("@/components/configurationComponents/selectPeers.vue"))
|
||||
const EditConfigurationModal = defineAsyncComponent(() => import("@/components/configurationComponents/editConfiguration.vue"))
|
||||
const PeerShareLinkModal = defineAsyncComponent(() => import("@/components/configurationComponents/peerShareLinkModal.vue"))
|
||||
const PeerJobsLogsModal = defineAsyncComponent(() => import("@/components/configurationComponents/peerJobsLogsModal.vue"))
|
||||
const PeerJobsAllModal = defineAsyncComponent(() => import("@/components/configurationComponents/peerJobsAllModal.vue"))
|
||||
const PeerJobsModal = defineAsyncComponent(() => import("@/components/configurationComponents/peerJobs.vue"))
|
||||
const PeerQRCodeModal = defineAsyncComponent(() => import("@/components/configurationComponents/peerQRCode.vue"))
|
||||
const PeerConfigurationFileModal = defineAsyncComponent(() => import("@/components/configurationComponents/peerConfigurationFile.vue"))
|
||||
const PeerSettingsModal = defineAsyncComponent(() => import("@/components/configurationComponents/peerSettings.vue"))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@ -0,0 +1,287 @@
|
||||
<script setup async>
|
||||
import {computed, onBeforeUnmount, ref, watch} from "vue";
|
||||
import {useRoute} from "vue-router";
|
||||
import {fetchGet} from "@/utilities/fetch.js";
|
||||
import ProtocolBadge from "@/components/protocolBadge.vue";
|
||||
import LocaleText from "@/components/text/localeText.vue";
|
||||
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
|
||||
import {WireguardConfigurationsStore} from "@/stores/WireguardConfigurationsStore.js";
|
||||
import PeerDataUsageCharts from "@/components/configurationComponents/peerListComponents/peerDataUsageCharts.vue";
|
||||
const dashboardStore = DashboardConfigurationStore()
|
||||
const wireguardConfigurationStore = WireguardConfigurationsStore()
|
||||
const route = useRoute()
|
||||
const configurationInfo = ref({})
|
||||
const configurationPeers = ref([])
|
||||
const configurationToggling = ref(false)
|
||||
const configurationModals = ref({
|
||||
peerSetting: {
|
||||
modalOpen: false,
|
||||
},
|
||||
peerScheduleJobs:{
|
||||
modalOpen: false,
|
||||
},
|
||||
peerQRCode: {
|
||||
modalOpen: false,
|
||||
},
|
||||
peerConfigurationFile: {
|
||||
modalOpen: false,
|
||||
},
|
||||
peerCreate: {
|
||||
modalOpen: false
|
||||
},
|
||||
peerScheduleJobsAll: {
|
||||
modalOpen: false
|
||||
},
|
||||
peerScheduleJobsLogs: {
|
||||
modalOpen: false
|
||||
},
|
||||
peerShare:{
|
||||
modalOpen: false,
|
||||
},
|
||||
editConfiguration: {
|
||||
modalOpen: false
|
||||
},
|
||||
selectPeers: {
|
||||
modalOpen: false
|
||||
},
|
||||
backupRestore: {
|
||||
modalOpen: false
|
||||
},
|
||||
deleteConfiguration: {
|
||||
modalOpen: false
|
||||
},
|
||||
editRawConfigurationFile: {
|
||||
modalOpen: false
|
||||
}
|
||||
})
|
||||
|
||||
// Fetch Peer =====================================
|
||||
const fetchPeerList = async () => {
|
||||
await fetchGet("/api/getWireguardConfigurationInfo", {
|
||||
configurationName: route.params.id
|
||||
}, (res) => {
|
||||
if (res.status){
|
||||
configurationInfo.value = res.data.configurationInfo;
|
||||
configurationPeers.value = res.data.configurationPeers;
|
||||
|
||||
configurationPeers.value.forEach(p => {
|
||||
p.restricted = false
|
||||
})
|
||||
res.data.configurationRestrictedPeers.forEach(x => {
|
||||
x.restricted = true;
|
||||
configurationPeers.value.push(x)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
await fetchPeerList()
|
||||
|
||||
// Fetch Peer Interval =====================================
|
||||
const fetchPeerListInterval = ref(undefined)
|
||||
const setFetchPeerListInterval = () => {
|
||||
clearInterval(fetchPeerListInterval.value)
|
||||
fetchPeerListInterval.value = setInterval(async () => {
|
||||
await fetchPeerList()
|
||||
}, parseInt(dashboardStore.Configuration.Server.dashboard_refresh_interval))
|
||||
}
|
||||
setFetchPeerListInterval()
|
||||
onBeforeUnmount(() => {
|
||||
clearInterval(fetchPeerListInterval.value);
|
||||
fetchPeerListInterval.value = undefined;
|
||||
})
|
||||
|
||||
watch(() => {
|
||||
return dashboardStore.Configuration.Server.dashboard_refresh_interval
|
||||
}, () => {
|
||||
setFetchPeerListInterval()
|
||||
})
|
||||
|
||||
// Toggle Configuration Method =====================================
|
||||
const toggleConfiguration = async () => {
|
||||
configurationToggling.value = true;
|
||||
await fetchGet("/api/toggleWireguardConfiguration/", {
|
||||
configurationName: configurationInfo.value.Name
|
||||
}, (res) => {
|
||||
if (res.status){
|
||||
dashboardStore.newMessage("Server",
|
||||
`${configurationInfo.value.Name} ${res.data ? 'is on':'is off'}`, "success")
|
||||
}else{
|
||||
dashboardStore.newMessage("Server", res.message, 'danger')
|
||||
}
|
||||
wireguardConfigurationStore.Configurations
|
||||
.find(x => x.Name === configurationInfo.value.Name).Status = res.data
|
||||
configurationInfo.value.Status = res.data
|
||||
configurationToggling.value = false;
|
||||
})
|
||||
}
|
||||
|
||||
// Configuration Summary =====================================
|
||||
const configurationSummary = computed(() => {
|
||||
return {
|
||||
connectedPeers: configurationPeers.value.filter(x => x.status === "running").length,
|
||||
totalUsage: configurationPeers.value.length > 0 ?
|
||||
configurationPeers.value.filter(x => !x.restricted)
|
||||
.map(x => x.total_data + x.cumu_data).reduce((a, b) => a + b, 0).toFixed(4) : 0,
|
||||
totalReceive: configurationPeers.value.length > 0 ?
|
||||
configurationPeers.value.filter(x => !x.restricted)
|
||||
.map(x => x.total_receive + x.cumu_receive).reduce((a, b) => a + b, 0).toFixed(4) : 0,
|
||||
totalSent: configurationPeers.value.length > 0 ?
|
||||
configurationPeers.value.filter(x => !x.restricted)
|
||||
.map(x => x.total_sent + x.cumu_sent).reduce((a, b) => a + b, 0).toFixed(4) : 0
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="container-md" >
|
||||
<div class="d-flex align-items-sm-center flex-column flex-sm-row gap-3">
|
||||
<div>
|
||||
<div class="text-muted d-flex align-items-center gap-2">
|
||||
<h5 class="mb-0">
|
||||
<ProtocolBadge :protocol="configurationInfo.Protocol"></ProtocolBadge>
|
||||
</h5>
|
||||
</div>
|
||||
<div class="d-flex align-items-center gap-3">
|
||||
<h1 class="mb-0 display-4"><samp>{{configurationInfo.Name}}</samp></h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ms-sm-auto d-flex gap-2 flex-column">
|
||||
<div class="card rounded-3 bg-transparent ">
|
||||
<div class="card-body py-2 d-flex align-items-center">
|
||||
<small class="text-muted">
|
||||
<LocaleText t="Status"></LocaleText>
|
||||
</small>
|
||||
<div class="dot ms-2" :class="{active: configurationInfo.Status}"></div>
|
||||
<div class="form-check form-switch mb-0 ms-auto pe-0 me-0">
|
||||
<label class="form-check-label" style="cursor: pointer" :for="'switch' + configurationInfo.id">
|
||||
<LocaleText t="On" v-if="configurationInfo.Status && !configurationToggling"></LocaleText>
|
||||
<LocaleText t="Off" v-else-if="!configurationInfo.Status && !configurationToggling"></LocaleText>
|
||||
<span v-if="configurationToggling"
|
||||
class="spinner-border spinner-border-sm ms-2" aria-hidden="true">
|
||||
</span>
|
||||
</label>
|
||||
<input class="form-check-input"
|
||||
style="cursor: pointer"
|
||||
:disabled="configurationToggling"
|
||||
type="checkbox" role="switch" :id="'switch' + configurationInfo.id"
|
||||
@change="toggleConfiguration()"
|
||||
v-model="configurationInfo.Status">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex gap-2">
|
||||
<RouterLink
|
||||
to="create"
|
||||
class="titleBtn py-2 text-decoration-none btn text-primary-emphasis bg-primary-subtle rounded-3 border-1 border-primary-subtle ">
|
||||
<i class="bi bi-plus-lg me-2"></i>
|
||||
<LocaleText t="Peer"></LocaleText>
|
||||
</RouterLink>
|
||||
<button class="titleBtn py-2 text-decoration-none btn text-primary-emphasis bg-primary-subtle rounded-3 border-1 border-primary-subtle "
|
||||
@click="configurationModals.editConfiguration.modalOpen = true"
|
||||
type="button" aria-expanded="false">
|
||||
<i class="bi bi-gear-fill me-2"></i>
|
||||
<LocaleText t="Configuration Settings"></LocaleText>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="row mt-3 gy-2 gx-2 mb-2">
|
||||
<div class="col-12 col-lg-3">
|
||||
<div class="card rounded-3 bg-transparent h-100">
|
||||
<div class="card-body py-2 d-flex flex-column justify-content-center">
|
||||
<p class="mb-0 text-muted"><small>
|
||||
<LocaleText t="Address"></LocaleText>
|
||||
</small></p>
|
||||
{{configurationInfo.Address}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-3">
|
||||
<div class="card rounded-3 bg-transparent h-100">
|
||||
<div class="card-body py-2 d-flex flex-column justify-content-center">
|
||||
<p class="mb-0 text-muted"><small>
|
||||
<LocaleText t="Listen Port"></LocaleText>
|
||||
</small></p>
|
||||
{{configurationInfo.ListenPort}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="word-break: break-all" class="col-12 col-lg-6">
|
||||
<div class="card rounded-3 bg-transparent h-100">
|
||||
<div class="card-body py-2 d-flex flex-column justify-content-center">
|
||||
<p class="mb-0 text-muted"><small>
|
||||
<LocaleText t="Public Key"></LocaleText>
|
||||
</small></p>
|
||||
<samp>{{configurationInfo.PublicKey}}</samp>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row gx-2 gy-2 mb-2">
|
||||
<div class="col-12 col-lg-3">
|
||||
<div class="card rounded-3 bg-transparent h-100">
|
||||
<div class="card-body d-flex">
|
||||
<div>
|
||||
<p class="mb-0 text-muted"><small>
|
||||
<LocaleText t="Connected Peers"></LocaleText>
|
||||
</small></p>
|
||||
<strong class="h4">
|
||||
{{configurationSummary.connectedPeers}} / {{configurationPeers.length}}
|
||||
</strong>
|
||||
</div>
|
||||
<i class="bi bi-ethernet ms-auto h2 text-muted"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-3">
|
||||
<div class="card rounded-3 bg-transparent h-100">
|
||||
<div class="card-body d-flex">
|
||||
<div>
|
||||
<p class="mb-0 text-muted"><small>
|
||||
<LocaleText t="Total Usage"></LocaleText>
|
||||
</small></p>
|
||||
<strong class="h4">{{configurationSummary.totalUsage}} GB</strong>
|
||||
</div>
|
||||
<i class="bi bi-arrow-down-up ms-auto h2 text-muted"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-3">
|
||||
<div class="card rounded-3 bg-transparent h-100">
|
||||
<div class="card-body d-flex">
|
||||
<div>
|
||||
<p class="mb-0 text-muted"><small>
|
||||
<LocaleText t="Total Received"></LocaleText>
|
||||
</small></p>
|
||||
<strong class="h4 text-primary">{{configurationSummary.totalReceive}} GB</strong>
|
||||
</div>
|
||||
<i class="bi bi-arrow-down ms-auto h2 text-muted"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-3">
|
||||
<div class="card rounded-3 bg-transparent h-100">
|
||||
<div class="card-body d-flex">
|
||||
<div>
|
||||
<p class="mb-0 text-muted"><small>
|
||||
<LocaleText t="Total Sent"></LocaleText>
|
||||
</small></p>
|
||||
<strong class="h4 text-success">{{configurationSummary.totalSent}} GB</strong>
|
||||
</div>
|
||||
<i class="bi bi-arrow-up ms-auto h2 text-muted"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<PeerDataUsageCharts
|
||||
:configurationPeers="configurationPeers"
|
||||
:configurationInfo="configurationInfo"
|
||||
></PeerDataUsageCharts>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@ -1,11 +1,14 @@
|
||||
<script setup>
|
||||
import {onBeforeUnmount, onMounted, ref} from "vue";
|
||||
import {computed, onBeforeUnmount, onMounted, ref} from "vue";
|
||||
import {fetchGet} from "@/utilities/fetch.js";
|
||||
import LocaleText from "@/components/text/localeText.vue";
|
||||
import CpuCore from "@/components/systemStatusComponents/cpuCore.vue";
|
||||
import StorageMount from "@/components/systemStatusComponents/storageMount.vue";
|
||||
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
|
||||
|
||||
const data = ref(undefined)
|
||||
const dashboardStore = DashboardConfigurationStore()
|
||||
|
||||
// const data = ref(undefined)
|
||||
let interval = null;
|
||||
|
||||
onMounted(() => {
|
||||
@ -21,9 +24,13 @@ onBeforeUnmount(() => {
|
||||
|
||||
const getData = () => {
|
||||
fetchGet("/api/systemStatus", {}, (res) => {
|
||||
data.value = res.data
|
||||
dashboardStore.SystemStatus = res.data
|
||||
})
|
||||
}
|
||||
|
||||
const data = computed(() => {
|
||||
return dashboardStore.SystemStatus
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -91,7 +91,7 @@ const router = createRouter({
|
||||
{
|
||||
name: "Peers List",
|
||||
path: 'peers',
|
||||
component: () => import('@/components/configurationComponents/peerList.vue')
|
||||
component: () => import('@/components/configurationComponents/peerListNew.vue')
|
||||
},
|
||||
{
|
||||
name: "Peers Create",
|
||||
|
@ -16,6 +16,7 @@ export const DashboardConfigurationStore = defineStore('DashboardConfigurationSt
|
||||
Enable: false,
|
||||
ServerList: {}
|
||||
},
|
||||
SystemStatus: undefined,
|
||||
ActiveServerConfiguration: undefined,
|
||||
IsElectronApp: false,
|
||||
ShowNavBar: false,
|
||||
|
@ -1,12 +1,16 @@
|
||||
<script setup>
|
||||
import {onBeforeUnmount, onMounted, ref} from "vue";
|
||||
import {computed, onBeforeUnmount, onMounted, ref} from "vue";
|
||||
import {fetchGet} from "@/utilities/fetch.js";
|
||||
import LocaleText from "@/components/text/localeText.vue";
|
||||
import CpuCore from "@/components/systemStatusComponents/cpuCore.vue";
|
||||
import StorageMount from "@/components/systemStatusComponents/storageMount.vue";
|
||||
import Process from "@/components/systemStatusComponents/process.vue";
|
||||
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
|
||||
|
||||
const data = ref(undefined)
|
||||
const dashboardStore = DashboardConfigurationStore()
|
||||
const data = computed(() => {
|
||||
return dashboardStore.SystemStatus
|
||||
})
|
||||
let interval = null;
|
||||
|
||||
onMounted(() => {
|
||||
@ -22,7 +26,7 @@ onBeforeUnmount(() => {
|
||||
|
||||
const getData = () => {
|
||||
fetchGet("/api/systemStatus", {}, (res) => {
|
||||
data.value = res.data
|
||||
dashboardStore.SystemStatus = res.data
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
Loading…
Reference in New Issue
Block a user