mirror of
https://github.com/donaldzou/WGDashboard.git
synced 2024-11-21 14:51:45 +01:00
Finished job logs :)
This commit is contained in:
parent
b65828416f
commit
63e8553a09
17
package-lock.json
generated
Normal file
17
package-lock.json
generated
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "Wireguard-Dashboard",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"dependencies": {
|
||||
"dayjs": "^1.11.12"
|
||||
}
|
||||
},
|
||||
"node_modules/dayjs": {
|
||||
"version": "1.11.12",
|
||||
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.12.tgz",
|
||||
"integrity": "sha512-Rt2g+nTbLlDWZTwwrIXjy9MeiZmSDI375FvZs72ngxx8PDC6YXOeR3q5LAuPzjZQxhiWdRKac7RKV+YyQYfYIg=="
|
||||
}
|
||||
}
|
||||
}
|
5
package.json
Normal file
5
package.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"dayjs": "^1.11.12"
|
||||
}
|
||||
}
|
@ -76,7 +76,7 @@ class CustomJsonEncoder(DefaultJSONProvider):
|
||||
super().__init__(app)
|
||||
|
||||
def default(self, o):
|
||||
if isinstance(o, WireguardConfiguration) or isinstance(o, Peer) or isinstance(o, PeerJob):
|
||||
if isinstance(o, WireguardConfiguration) or isinstance(o, Peer) or isinstance(o, PeerJob) or isinstance(o, Log):
|
||||
return o.toJson()
|
||||
return super().default(self, o)
|
||||
|
||||
@ -99,6 +99,10 @@ class Log:
|
||||
"Status": self.Status,
|
||||
"Message": self.Message
|
||||
}
|
||||
|
||||
def __dict__(self):
|
||||
return self.toJson()
|
||||
|
||||
class Logger:
|
||||
def __init__(self):
|
||||
self.loggerdb = sqlite3.connect(os.path.join(CONFIGURATION_PATH, 'db', 'wgdashboard_log.db'),
|
||||
@ -120,21 +124,26 @@ class Logger:
|
||||
self.loggerdbCursor.execute(f"INSERT INTO JobLog (LogID, JobID, Status, Message) VALUES (?, ?, ?, ?)",
|
||||
(str(uuid.uuid4()), JobID, Status, Message,))
|
||||
self.loggerdb.commit()
|
||||
self.getLogs()
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return False
|
||||
return True
|
||||
|
||||
def getLogs(self, all: bool = False):
|
||||
def getLogs(self, all: bool = False, configName = None) -> list[Log]:
|
||||
logs: list[Log] = []
|
||||
try:
|
||||
table = self.loggerdb.execute(f"SELECT * FROM JobLog ORDER BY LogDate DESC {'LIMIT 5' if not all else ''}").fetchall()
|
||||
allJobs = AllPeerJobs.getAllJobs(configName)
|
||||
allJobsID = ", ".join([f"'{x.JobID}'" for x in allJobs])
|
||||
table = self.loggerdb.execute(f"SELECT * FROM JobLog WHERE JobID IN ({allJobsID}) ORDER BY LogDate DESC").fetchall()
|
||||
self.logs.clear()
|
||||
for l in table:
|
||||
self.logs.append(
|
||||
logs.append(
|
||||
Log(l["LogID"], l["JobID"], l["LogDate"], l["Status"], l["Message"]))
|
||||
except Exception as e:
|
||||
pass
|
||||
return logs
|
||||
return logs
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -186,7 +195,18 @@ class PeerJobs:
|
||||
self.Jobs.append(PeerJob(
|
||||
job['JobID'], job['Configuration'], job['Peer'], job['Field'], job['Operator'], job['Value'],
|
||||
job['CreationDate'], job['ExpireDate'], job['Action']))
|
||||
# print(self.Jobs)
|
||||
|
||||
def getAllJobs(self, configuration: str = None):
|
||||
if configuration is not None:
|
||||
jobs = self.jobdbCursor.execute(
|
||||
f"SELECT * FROM PeerJobs WHERE Configuration = ?", (configuration, )).fetchall()
|
||||
j = []
|
||||
for job in jobs:
|
||||
j.append(PeerJob(
|
||||
job['JobID'], job['Configuration'], job['Peer'], job['Field'], job['Operator'], job['Value'],
|
||||
job['CreationDate'], job['ExpireDate'], job['Action']))
|
||||
return j
|
||||
return []
|
||||
|
||||
def __createPeerJobsDatabase(self):
|
||||
existingTable = self.jobdbCursor.execute("SELECT name from sqlite_master where type='table'").fetchall()
|
||||
@ -239,21 +259,6 @@ class PeerJobs:
|
||||
except Exception as e:
|
||||
return False, str(e)
|
||||
|
||||
# def finishJob(self, Job: PeerJob) -> tuple[bool, list] | tuple[bool, str]:
|
||||
# try:
|
||||
# if (len(str(Job.CreationDate))) == 0:
|
||||
# return False, "Job does not exist"
|
||||
# self.jobdbCursor.execute('''
|
||||
# UPDATE PeerJobs SET ExpireDate = strftime('%Y-%m-%d %H:%M:%S','now') WHERE JobId = ?
|
||||
# ''', (Job.JobID,))
|
||||
# self.jobdb.commit()
|
||||
# self.__getJobs()
|
||||
# return True, list(
|
||||
# filter(lambda x: x.Configuration == Job.Configuration and x.Peer == Job.Peer and x.JobID == Job.JobID,
|
||||
# self.Jobs))
|
||||
# except Exception as e:
|
||||
# return False, str(e)
|
||||
|
||||
def runJob(self):
|
||||
needToDelete = []
|
||||
for job in self.Jobs:
|
||||
@ -1555,6 +1560,17 @@ def API_deletePeerScheduleJob():
|
||||
return ResponseObject(s, data=p)
|
||||
return ResponseObject(s, message=p)
|
||||
|
||||
@app.route('/api/getPeerScheduleJobLogs/<configName>', methods=['GET'])
|
||||
def API_getPeerScheduleJobLogs(configName):
|
||||
if configName not in WireguardConfigurations.keys():
|
||||
return ResponseObject(False, "Configuration does not exist")
|
||||
data = request.args.get("requestAll")
|
||||
requestAll = False
|
||||
if data is not None and data == "true":
|
||||
requestAll = True
|
||||
return ResponseObject(data=JobLogger.getLogs(requestAll, configName))
|
||||
|
||||
|
||||
|
||||
'''
|
||||
Tools
|
||||
|
8
src/static/app/package-lock.json
generated
8
src/static/app/package-lock.json
generated
@ -14,7 +14,7 @@
|
||||
"bootstrap": "^5.3.2",
|
||||
"bootstrap-icons": "^1.11.2",
|
||||
"cidr-tools": "^7.0.4",
|
||||
"dayjs": "^1.11.10",
|
||||
"dayjs": "^1.11.12",
|
||||
"fuse.js": "^7.0.0",
|
||||
"i": "^0.3.7",
|
||||
"is-cidr": "^5.0.3",
|
||||
@ -938,9 +938,9 @@
|
||||
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
|
||||
},
|
||||
"node_modules/dayjs": {
|
||||
"version": "1.11.10",
|
||||
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz",
|
||||
"integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ=="
|
||||
"version": "1.11.12",
|
||||
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.12.tgz",
|
||||
"integrity": "sha512-Rt2g+nTbLlDWZTwwrIXjy9MeiZmSDI375FvZs72ngxx8PDC6YXOeR3q5LAuPzjZQxhiWdRKac7RKV+YyQYfYIg=="
|
||||
},
|
||||
"node_modules/decamelize": {
|
||||
"version": "1.2.0",
|
||||
|
@ -15,7 +15,7 @@
|
||||
"bootstrap": "^5.3.2",
|
||||
"bootstrap-icons": "^1.11.2",
|
||||
"cidr-tools": "^7.0.4",
|
||||
"dayjs": "^1.11.10",
|
||||
"dayjs": "^1.11.12",
|
||||
"fuse.js": "^7.0.0",
|
||||
"i": "^0.3.7",
|
||||
"is-cidr": "^5.0.3",
|
||||
|
@ -61,9 +61,9 @@ export default {
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body pt-1" style="font-size: 0.9rem">
|
||||
<h5>
|
||||
<h6>
|
||||
{{Peer.name ? Peer.name : 'Untitled Peer'}}
|
||||
</h5>
|
||||
</h6>
|
||||
<div class="mb-2">
|
||||
<small class="text-muted">Public Key</small>
|
||||
<p class="mb-0"><samp>{{Peer.id}}</samp></p>
|
||||
@ -100,13 +100,14 @@ export default {
|
||||
<style scoped>
|
||||
|
||||
.slide-fade-leave-active, .slide-fade-enter-active{
|
||||
transition: all 0.2s cubic-bezier(1, 0.5, 0.8, 1);
|
||||
transition: all 0.2s cubic-bezier(0.82, 0.58, 0.17, 0.9);
|
||||
}
|
||||
|
||||
.slide-fade-enter-from,
|
||||
.slide-fade-leave-to {
|
||||
transform: translateY(20px);
|
||||
opacity: 0;
|
||||
filter: blur(3px);
|
||||
}
|
||||
|
||||
.subMenuBtn.active{
|
||||
@ -114,7 +115,7 @@ export default {
|
||||
}
|
||||
|
||||
.peerCard{
|
||||
transition: box-shadow 0.1s cubic-bezier(1, 0.5, 0.8, 1);
|
||||
transition: box-shadow 0.1s cubic-bezier(0.82, 0.58, 0.17, 0.9);
|
||||
}
|
||||
|
||||
.peerCard:hover{
|
||||
|
@ -1,9 +1,13 @@
|
||||
<script>
|
||||
import ScheduleDropdown from "@/components/configurationComponents/peerScheduleJobsComponents/scheduleDropdown.vue";
|
||||
import SchedulePeerJob from "@/components/configurationComponents/peerScheduleJobsComponents/schedulePeerJob.vue";
|
||||
import {WireguardConfigurationsStore} from "@/stores/WireguardConfigurationsStore.js";
|
||||
export default {
|
||||
name: "peerJobs",
|
||||
|
||||
setup(){
|
||||
const store = WireguardConfigurationsStore();
|
||||
return {store}
|
||||
},
|
||||
props:{
|
||||
selectedPeer: Object
|
||||
},
|
||||
@ -13,78 +17,24 @@ export default {
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
dropdowns: {
|
||||
Field: [
|
||||
{
|
||||
display: "Total Received",
|
||||
value: "total_receive",
|
||||
unit: "GB",
|
||||
type: 'number'
|
||||
},
|
||||
{
|
||||
display: "Total Sent",
|
||||
value: "total_sent",
|
||||
unit: "GB",
|
||||
type: 'number'
|
||||
},
|
||||
{
|
||||
display: "Total Data",
|
||||
value: "total_data",
|
||||
unit: "GB",
|
||||
type: 'number'
|
||||
},
|
||||
{
|
||||
display: "Date",
|
||||
value: "date",
|
||||
type: 'date'
|
||||
}
|
||||
],
|
||||
Operator: [
|
||||
{
|
||||
display: "equal",
|
||||
value: "eq"
|
||||
},
|
||||
{
|
||||
display: "not equal",
|
||||
value: "neq"
|
||||
},
|
||||
{
|
||||
display: "larger than",
|
||||
value: "lgt"
|
||||
},
|
||||
{
|
||||
display: "less than",
|
||||
value: "lst"
|
||||
},
|
||||
],
|
||||
Action: [
|
||||
{
|
||||
display: "Restrict Peer",
|
||||
value: "restrict"
|
||||
},
|
||||
{
|
||||
display: "Delete Peer",
|
||||
value: "delete"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
deleteJob(j){
|
||||
this.selectedPeer.jobs = this.selectedPeer.jobs.filter(x => x.JobID !== j.JobID)
|
||||
this.selectedPeer.jobs = this.selectedPeer.jobs.filter(x => x.JobID !== j.JobID);
|
||||
},
|
||||
addJob(){
|
||||
this.selectedPeer.jobs.unshift(JSON.parse(JSON.stringify({
|
||||
JobID: crypto.randomUUID(),
|
||||
Configuration: this.selectedPeer.configuration.Name,
|
||||
Peer: this.selectedPeer.id,
|
||||
Field: this.dropdowns.Field[0].value,
|
||||
Operator: this.dropdowns.Operator[0].value,
|
||||
Field: this.store.PeerScheduleJobs.dropdowns.Field[0].value,
|
||||
Operator: this.store.PeerScheduleJobs.dropdowns.Operator[0].value,
|
||||
Value: "",
|
||||
CreationDate: "",
|
||||
ExpireDate: "",
|
||||
Action: this.dropdowns.Action[0].value
|
||||
Action: this.store.PeerScheduleJobs.dropdowns.Action[0].value
|
||||
}))
|
||||
)
|
||||
}
|
||||
@ -96,7 +46,7 @@ export default {
|
||||
<template>
|
||||
<div class="peerSettingContainer w-100 h-100 position-absolute top-0 start-0 overflow-y-scroll">
|
||||
<div class="container d-flex h-100 w-100">
|
||||
<div class="m-auto modal-dialog-centered dashboardModal mt-0">
|
||||
<div class="m-auto modal-dialog-centered dashboardModal">
|
||||
<div class="card rounded-3 shadow" style="width: 700px">
|
||||
<div class="card-header bg-transparent d-flex align-items-center gap-2 border-0 p-4 pb-2">
|
||||
<h4 class="mb-0 fw-normal">Schedule Jobs
|
||||
@ -106,25 +56,26 @@ export default {
|
||||
</div>
|
||||
<div class="card-body px-4 pb-4 pt-2 position-relative">
|
||||
<div class="d-flex align-items-center mb-3">
|
||||
<button class="btn btn-sm btn-primary rounded-3" @click="this.addJob()">
|
||||
<button class="btn bg-primary-subtle border-1 border-primary-subtle text-primary-emphasis rounded-3 shadow"
|
||||
|
||||
@click="this.addJob()">
|
||||
<i class="bi bi-plus-lg me-2"></i> Job
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
<TransitionGroup name="schedulePeerJobTransition" tag="div" class="position-relative">
|
||||
<SchedulePeerJob
|
||||
@refresh="(j) => this.selectedPeer.jobs[index] = j"
|
||||
@refresh="this.$emit('refresh')"
|
||||
@delete="this.deleteJob(job)"
|
||||
:dropdowns="this.dropdowns"
|
||||
:dropdowns="this.store.PeerScheduleJobs.dropdowns"
|
||||
:key="job.JobID"
|
||||
:pjob="job" v-for="(job, index) in this.selectedPeer.jobs">
|
||||
</SchedulePeerJob>
|
||||
|
||||
<div class="card" key="none" v-if="this.selectedPeer.jobs.length === 0">
|
||||
<div class="card-body text-muted text-center">
|
||||
<h1><i class="bi bi-emoji-frown-fill"></i></h1>
|
||||
<h6 class="mb-0">This peer does not have any job yet.</h6>
|
||||
<div class="card shadow-sm" key="none"
|
||||
style="height: 153px"
|
||||
v-if="this.selectedPeer.jobs.length === 0">
|
||||
<div class="card-body text-muted text-center d-flex">
|
||||
<h6 class="m-auto">This peer does not have any job yet.</h6>
|
||||
</div>
|
||||
</div>
|
||||
</TransitionGroup>
|
||||
|
@ -0,0 +1,86 @@
|
||||
<script>
|
||||
import SchedulePeerJob from "@/components/configurationComponents/peerScheduleJobsComponents/schedulePeerJob.vue";
|
||||
import {WireguardConfigurationsStore} from "@/stores/WireguardConfigurationsStore.js";
|
||||
import {v4} from "uuid";
|
||||
|
||||
export default {
|
||||
name: "peerJobsAllModal",
|
||||
setup(){
|
||||
const store = WireguardConfigurationsStore();
|
||||
return {store}
|
||||
},
|
||||
components: {SchedulePeerJob},
|
||||
props: {
|
||||
configurationPeers: Array[Object]
|
||||
},
|
||||
methods:{
|
||||
getuuid(){
|
||||
return v4();
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
getAllJobs(){
|
||||
return this.configurationPeers.filter(x => x.jobs.length > 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="peerSettingContainer w-100 h-100 position-absolute top-0 start-0 overflow-y-scroll">
|
||||
<div class="container d-flex h-100 w-100">
|
||||
<div class="m-auto modal-dialog-centered dashboardModal">
|
||||
<div class="card rounded-3 shadow" style="width: 700px">
|
||||
<div class="card-header bg-transparent d-flex align-items-center gap-2 border-0 p-4 pb-2">
|
||||
<h4 class="mb-0 fw-normal">All Active Jobs
|
||||
</h4>
|
||||
<button type="button" class="btn-close ms-auto" @click="this.$emit('close')"></button>
|
||||
</div>
|
||||
<div class="card-body px-4 pb-4 pt-2 ">
|
||||
<div class="accordion" id="peerJobsLogsModalAccordion" v-if="this.getAllJobs.length > 0">
|
||||
<div class="accordion-item" v-for="(p, index) in this.getAllJobs" :key="p.id">
|
||||
<h2 class="accordion-header">
|
||||
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse"
|
||||
:data-bs-target="'#collapse_' + index">
|
||||
<small>
|
||||
<strong>
|
||||
<span v-if="p.name">
|
||||
{{p.name}} •
|
||||
</span>
|
||||
<samp class="text-muted">{{p.id}}</samp>
|
||||
</strong>
|
||||
</small>
|
||||
</button>
|
||||
</h2>
|
||||
<div :id="'collapse_' + index" class="accordion-collapse collapse"
|
||||
data-bs-parent="#peerJobsLogsModalAccordion">
|
||||
<div class="accordion-body">
|
||||
<SchedulePeerJob
|
||||
@delete="this.$emit('refresh')"
|
||||
@refresh="this.$emit('refresh')"
|
||||
:dropdowns="this.store.PeerScheduleJobs.dropdowns"
|
||||
:viewOnly="true"
|
||||
:key="job.JobID"
|
||||
:pjob="job" v-for="job in p.jobs">
|
||||
</SchedulePeerJob>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card shadow-sm"
|
||||
style="height: 153px"
|
||||
v-else>
|
||||
<div class="card-body text-muted text-center d-flex">
|
||||
<h6 class="m-auto">No active job at the moment.</h6>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@ -0,0 +1,162 @@
|
||||
<script>
|
||||
import dayjs from "dayjs";
|
||||
import {fetchGet} from "@/utilities/fetch.js";
|
||||
export default {
|
||||
name: "peerJobsLogsModal",
|
||||
props: {
|
||||
configurationInfo: Object
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
dataLoading: true,
|
||||
data: [],
|
||||
logFetchTime: undefined,
|
||||
showLogID: false,
|
||||
showJobID: true,
|
||||
showSuccessJob: true,
|
||||
showFailedJob: true,
|
||||
showLogAmount: 10
|
||||
}
|
||||
},
|
||||
async mounted(){
|
||||
await this.fetchLog();
|
||||
},
|
||||
methods: {
|
||||
async fetchLog(){
|
||||
this.dataLoading = true;
|
||||
await fetchGet(`/api/getPeerScheduleJobLogs/${this.configurationInfo.Name}`, {}, (res) => {
|
||||
this.data = res.data;
|
||||
this.logFetchTime = dayjs().format("YYYY-MM-DD HH:mm:ss")
|
||||
this.dataLoading = false;
|
||||
});
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
getLogs(){
|
||||
return this.data
|
||||
.filter(x => {
|
||||
return (this.showSuccessJob && x.Status === "1") || (this.showFailedJob && x.Status === "0")
|
||||
})
|
||||
},
|
||||
showLogs(){
|
||||
return this.getLogs.slice(0, this.showLogAmount);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="peerSettingContainer w-100 h-100 position-absolute top-0 start-0 overflow-y-scroll">
|
||||
<div class="container-fluid d-flex h-100 w-100">
|
||||
<div class="m-auto mt-0 modal-dialog-centered dashboardModal" style="width: 100%">
|
||||
<div class="card rounded-3 shadow w-100" >
|
||||
<div class="card-header bg-transparent d-flex align-items-center gap-2 border-0 p-4 pb-0">
|
||||
<h4 class="mb-0">Jobs Logs</h4>
|
||||
<button type="button" class="btn-close ms-auto" @click="this.$emit('close')"></button>
|
||||
</div>
|
||||
<div class="card-body px-4 pb-4 pt-2">
|
||||
<div v-if="!this.dataLoading">
|
||||
<p>Updated at: {{this.logFetchTime}}</p>
|
||||
<div class="mb-2 d-flex gap-3">
|
||||
<button @click="this.fetchLog()"
|
||||
class="btn btn-sm rounded-3 shadow-sm
|
||||
text-info-emphasis bg-info-subtle border-1 border-info-subtle me-1">
|
||||
<i class="bi bi-arrow-clockwise me-2"></i>
|
||||
Refresh
|
||||
</button>
|
||||
<div class="d-flex gap-3 align-items-center">
|
||||
<span class="text-muted">Filter</span>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" v-model="this.showSuccessJob"
|
||||
id="jobLogsShowSuccessCheck">
|
||||
<label class="form-check-label" for="jobLogsShowSuccessCheck">
|
||||
<span class="badge text-success-emphasis bg-success-subtle">Success</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" v-model="this.showFailedJob"
|
||||
id="jobLogsShowFailedCheck">
|
||||
<label class="form-check-label" for="jobLogsShowFailedCheck">
|
||||
<span class="badge text-danger-emphasis bg-danger-subtle">Failed</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex gap-3 align-items-center ms-auto">
|
||||
<span class="text-muted">Display</span>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox"
|
||||
v-model="showJobID"
|
||||
id="jobLogsShowJobIDCheck">
|
||||
<label class="form-check-label" for="jobLogsShowJobIDCheck">
|
||||
Job ID
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox"
|
||||
v-model="showLogID"
|
||||
id="jobLogsShowLogIDCheck">
|
||||
<label class="form-check-label" for="jobLogsShowLogIDCheck">
|
||||
Log ID
|
||||
</label>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Date</th>
|
||||
<th scope="col" v-if="showLogID">Log ID</th>
|
||||
<th scope="col" v-if="showJobID">Job ID</th>
|
||||
<th scope="col">Status</th>
|
||||
<th scope="col">Message</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="log in this.showLogs" style="font-size: 0.875rem">
|
||||
<th scope="row">{{log.LogDate}}</th>
|
||||
<td v-if="showLogID"><samp class="text-muted">{{log.LogID}}</samp></td>
|
||||
<td v-if="showJobID"><samp class="text-muted">{{log.JobID}}</samp></td>
|
||||
<td>
|
||||
<span class="badge" :class="[log.Status === '1' ? 'text-success-emphasis bg-success-subtle':'text-danger-emphasis bg-danger-subtle']">
|
||||
{{log.Status === "1" ? 'Success': 'Failed'}}
|
||||
</span>
|
||||
</td>
|
||||
<td>{{log.Message}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
<div class="d-flex gap-2">
|
||||
<button v-if="this.getLogs.length > this.showLogAmount"
|
||||
@click="this.showLogAmount += 20"
|
||||
class="btn btn-sm rounded-3 shadow-sm
|
||||
text-primary-emphasis bg-primary-subtle border-1 border-primary-subtle">
|
||||
<i class="bi bi-chevron-down me-2"></i>
|
||||
Show More
|
||||
</button>
|
||||
<button v-if="this.showLogAmount > 20"
|
||||
@click="this.showLogAmount = 20"
|
||||
class="btn btn-sm rounded-3 shadow-sm
|
||||
text-primary-emphasis bg-primary-subtle border-1 border-primary-subtle">
|
||||
<i class="bi bi-chevron-up me-2"></i>
|
||||
Collapse
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex align-items-center flex-column" v-else>
|
||||
<div class="spinner-border text-body" role="status">
|
||||
<span class="visually-hidden">Loading...</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@ -37,6 +37,8 @@ import PeerSettings from "@/components/configurationComponents/peerSettings.vue"
|
||||
import PeerQRCode from "@/components/configurationComponents/peerQRCode.vue";
|
||||
import PeerCreate from "@/components/configurationComponents/peerCreate.vue";
|
||||
import PeerJobs from "@/components/configurationComponents/peerJobs.vue";
|
||||
import PeerJobsAllModal from "@/components/configurationComponents/peerJobsAllModal.vue";
|
||||
import PeerJobsLogsModal from "@/components/configurationComponents/peerJobsLogsModal.vue";
|
||||
|
||||
Chart.register(
|
||||
ArcElement,
|
||||
@ -66,7 +68,9 @@ Chart.register(
|
||||
|
||||
export default {
|
||||
name: "peerList",
|
||||
components: {PeerJobs, PeerCreate, PeerQRCode, PeerSettings, PeerSearch, Peer, Line, Bar},
|
||||
components: {
|
||||
PeerJobsLogsModal,
|
||||
PeerJobsAllModal, PeerJobs, PeerCreate, PeerQRCode, PeerSettings, PeerSearch, Peer, Line, Bar},
|
||||
setup(){
|
||||
const dashboardConfigurationStore = DashboardConfigurationStore();
|
||||
const wireguardConfigurationStore = WireguardConfigurationsStore();
|
||||
@ -119,6 +123,12 @@ export default {
|
||||
},
|
||||
peerCreate: {
|
||||
modalOpen: false
|
||||
},
|
||||
peerScheduleJobsAll: {
|
||||
modalOpen: false
|
||||
},
|
||||
peerScheduleJobsLogs: {
|
||||
modalOpen: false
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -173,19 +183,6 @@ export default {
|
||||
}, (res) => {
|
||||
this.configurationInfo = res.data.configurationInfo;
|
||||
this.configurationPeers = res.data.configurationPeers;
|
||||
|
||||
// let modals = [this.peerSetting, this.peerScheduleJobs, this.peerQRCode]
|
||||
// modals.forEach(x => {
|
||||
//
|
||||
// if (x.modalOpen && this.configurationPeers.find(p => p.id === x.selectedPeer.id)){
|
||||
// x.selectedPeer = this.configurationPeers.find(p => p.id === x.selectedPeer.id)
|
||||
// console.log(this.configurationPeers.find(p => p.id === x.selectedPeer.id))
|
||||
// }else{
|
||||
// x.modalOpen = false
|
||||
// }
|
||||
// })
|
||||
|
||||
|
||||
this.configurationPeers.forEach(x => {
|
||||
x.restricted = false;
|
||||
})
|
||||
@ -534,12 +531,16 @@ export default {
|
||||
<!-- <div class="d-flex align-items-center gap-3 mb-2">-->
|
||||
<!-- <h3>Peers</h3>-->
|
||||
<!-- </div>-->
|
||||
<PeerSearch :configuration="this.configurationInfo"></PeerSearch>
|
||||
<PeerSearch
|
||||
@jobsAll="this.peerScheduleJobsAll.modalOpen = true"
|
||||
@jobLogs="this.peerScheduleJobsLogs.modalOpen = true"
|
||||
:configuration="this.configurationInfo"></PeerSearch>
|
||||
<TransitionGroup name="list" tag="div" class="row gx-2 gy-2 z-0">
|
||||
<div class="col-12 col-lg-6 col-xl-4"
|
||||
:key="peer.id"
|
||||
v-for="peer in this.searchPeers">
|
||||
<Peer :Peer="peer"
|
||||
|
||||
@refresh="this.getPeers()"
|
||||
@jobs="peerScheduleJobs.modalOpen = true; peerScheduleJobs.selectedPeer = this.configurationPeers.find(x => x.id === peer.id)"
|
||||
@setting="peerSetting.modalOpen = true; peerSetting.selectedPeer = this.configurationPeers.find(x => x.id === peer.id)"
|
||||
@ -548,7 +549,7 @@ export default {
|
||||
</div>
|
||||
</TransitionGroup>
|
||||
</div>
|
||||
<Transition name="fade">
|
||||
<Transition name="zoom">
|
||||
<PeerSettings v-if="this.peerSetting.modalOpen"
|
||||
key="settings"
|
||||
:selectedPeer="this.peerSetting.selectedPeer"
|
||||
@ -556,13 +557,13 @@ export default {
|
||||
@close="this.peerSetting.modalOpen = false">
|
||||
</PeerSettings>
|
||||
</Transition>
|
||||
<Transition name="fade">
|
||||
<Transition name="zoom">
|
||||
<PeerQRCode :peerConfigData="this.peerQRCode.peerConfigData"
|
||||
key="qrcode"
|
||||
@close="this.peerQRCode.modalOpen = false"
|
||||
v-if="peerQRCode.modalOpen"></PeerQRCode>
|
||||
</Transition>
|
||||
<Transition name="fade">
|
||||
<Transition name="zoom">
|
||||
<PeerJobs
|
||||
@refresh="this.getPeers()"
|
||||
v-if="this.peerScheduleJobs.modalOpen"
|
||||
@ -570,13 +571,22 @@ export default {
|
||||
@close="this.peerScheduleJobs.modalOpen = false">
|
||||
</PeerJobs>
|
||||
</Transition>
|
||||
|
||||
<!-- <Transition name="fade">-->
|
||||
<!-- -->
|
||||
<!-- </Transition>-->
|
||||
<!-- <Transition name="fade">-->
|
||||
<!-- -->
|
||||
<!-- </Transition>-->
|
||||
<Transition name="zoom">
|
||||
<PeerJobsAllModal
|
||||
v-if="this.peerScheduleJobsAll.modalOpen"
|
||||
@refresh="this.getPeers()"
|
||||
@close="this.peerScheduleJobsAll.modalOpen = false"
|
||||
:configurationPeers="this.configurationPeers"
|
||||
>
|
||||
</PeerJobsAllModal>
|
||||
</Transition>
|
||||
<Transition name="zoom">
|
||||
<PeerJobsLogsModal v-if="this.peerScheduleJobsLogs.modalOpen"
|
||||
@close="this.peerScheduleJobsLogs.modalOpen = false"
|
||||
:configurationInfo="this.configurationInfo"
|
||||
>
|
||||
</PeerJobsLogsModal>
|
||||
</Transition>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -6,7 +6,8 @@ export default {
|
||||
peerConfigData: String
|
||||
},
|
||||
mounted() {
|
||||
QRCode.toCanvas(document.querySelector("#qrcode"), this.peerConfigData , function (error) {
|
||||
QRCode.toCanvas(document.querySelector("#qrcode"), this.peerConfigData , (error) => {
|
||||
console.log(this.peerConfigData)
|
||||
if (error) console.error(error)
|
||||
})
|
||||
}
|
||||
@ -14,10 +15,10 @@ export default {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="peerSettingContainer w-100 h-100 position-absolute top-0 start-0 overflow-y-scroll">
|
||||
<div class="container d-flex h-100 w-100 m-auto">
|
||||
<div class="modal-dialog-centered dashboardModal">
|
||||
<div class="card m-auto rounded-3 shadow">
|
||||
<div class="peerSettingContainer w-100 h-100 position-absolute top-0 start-0">
|
||||
<div class="container d-flex h-100 w-100">
|
||||
<div class="m-auto modal-dialog-centered dashboardModal justify-content-center">
|
||||
<div class="card rounded-3 shadow">
|
||||
<div class="card-header bg-transparent d-flex align-items-center gap-2 border-0 p-4 pb-0">
|
||||
<h4 class="mb-0">QR Code</h4>
|
||||
<button type="button" class="btn-close ms-auto" @click="this.$emit('close')"></button>
|
||||
|
@ -9,7 +9,8 @@ export default {
|
||||
components: {ScheduleDropdown},
|
||||
props: {
|
||||
dropdowns: Array[Object],
|
||||
pjob: Object
|
||||
pjob: Object,
|
||||
viewOnly: false
|
||||
},
|
||||
setup(props){
|
||||
const job = ref({})
|
||||
|
@ -137,6 +137,28 @@ export default {
|
||||
</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="dropdown">
|
||||
<button class="btn dropdown-toggle text-secondary-emphasis bg-secondary-subtle rounded-3 border-1 border-secondary-subtle shadow-sm"
|
||||
type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
<i class="bi bi-three-dots me-2"></i>More
|
||||
</button>
|
||||
<ul class="dropdown-menu shadow mt-2 rounded-3">
|
||||
<li>
|
||||
<h6 class="dropdown-header">Peer Jobs</h6>
|
||||
</li>
|
||||
<li>
|
||||
<a role="button" class="dropdown-item" @click="this.$emit('jobsAll')">
|
||||
All Active Jobs
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a role="button" class="dropdown-item" @click="this.$emit('jobLogs')">
|
||||
Logs
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -53,7 +53,7 @@ export default {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="peerSettingContainer w-100 h-100 position-absolute top-0 start-0">
|
||||
<div class="peerSettingContainer w-100 h-100 position-absolute top-0 start-0 overflow-y-scroll">
|
||||
<div class="container d-flex h-100 w-100">
|
||||
<div class="m-auto modal-dialog-centered dashboardModal">
|
||||
<div class="card rounded-3 shadow flex-grow-1">
|
||||
|
@ -5,7 +5,64 @@ import isCidr from "is-cidr";
|
||||
export const WireguardConfigurationsStore = defineStore('WireguardConfigurationsStore', {
|
||||
state: () => ({
|
||||
Configurations: undefined,
|
||||
searchString: ""
|
||||
searchString: "",
|
||||
PeerScheduleJobs: {
|
||||
dropdowns: {
|
||||
Field: [
|
||||
{
|
||||
display: "Total Received",
|
||||
value: "total_receive",
|
||||
unit: "GB",
|
||||
type: 'number'
|
||||
},
|
||||
{
|
||||
display: "Total Sent",
|
||||
value: "total_sent",
|
||||
unit: "GB",
|
||||
type: 'number'
|
||||
},
|
||||
{
|
||||
display: "Total Data",
|
||||
value: "total_data",
|
||||
unit: "GB",
|
||||
type: 'number'
|
||||
},
|
||||
{
|
||||
display: "Date",
|
||||
value: "date",
|
||||
type: 'date'
|
||||
}
|
||||
],
|
||||
Operator: [
|
||||
{
|
||||
display: "equal",
|
||||
value: "eq"
|
||||
},
|
||||
{
|
||||
display: "not equal",
|
||||
value: "neq"
|
||||
},
|
||||
{
|
||||
display: "larger than",
|
||||
value: "lgt"
|
||||
},
|
||||
{
|
||||
display: "less than",
|
||||
value: "lst"
|
||||
},
|
||||
],
|
||||
Action: [
|
||||
{
|
||||
display: "Restrict Peer",
|
||||
value: "restrict"
|
||||
},
|
||||
{
|
||||
display: "Delete Peer",
|
||||
value: "delete"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}),
|
||||
actions: {
|
||||
async getConfigurations(){
|
||||
|
@ -1119,6 +1119,7 @@ pre.index-alert {
|
||||
.peerSettingContainer {
|
||||
background-color: #00000060;
|
||||
z-index: 9999;
|
||||
backdrop-filter: blur(1px);
|
||||
}
|
||||
|
||||
.dashboardModal{
|
||||
@ -1128,4 +1129,18 @@ pre.index-alert {
|
||||
|
||||
.dashboardModal > .card{
|
||||
margin: 1.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
.zoom-enter-active,
|
||||
.zoom-leave-active {
|
||||
transition: all 0.3s cubic-bezier(0.82, 0.58, 0.17, 0.9);
|
||||
/*position: absolute;*/
|
||||
/*padding-top: 50px*/
|
||||
}
|
||||
|
||||
.zoom-enter-from,
|
||||
.zoom-leave-to {
|
||||
transform: scale(1.1);
|
||||
filter: blur(3px);
|
||||
opacity: 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user