mirror of
https://github.com/donaldzou/WGDashboard.git
synced 2024-11-06 16:00:28 +01:00
Peer schedule style is almost done
But I don't feel it quite right..
This commit is contained in:
parent
6c529a6908
commit
2d838b69fd
@ -126,6 +126,7 @@ class PeerJobs:
|
||||
self.__getJobs()
|
||||
|
||||
def __getJobs(self):
|
||||
self.Jobs.clear()
|
||||
jobs = self.jobdbCursor.execute("SELECT * FROM PeerJobs WHERE ExpireDate IS NULL").fetchall()
|
||||
for job in jobs:
|
||||
self.Jobs.append(PeerJob(
|
||||
@ -158,6 +159,22 @@ class PeerJobs:
|
||||
def searchJob(self, Configuration: str, Peer: str):
|
||||
return list(filter(lambda x: x.Configuration == Configuration and x.Peer == Peer, self.Jobs))
|
||||
|
||||
def saveJob(self, Job: PeerJob) -> tuple[bool, list] | tuple[bool, str]:
|
||||
try:
|
||||
if (len(str(Job.CreationDate))) == 0:
|
||||
self.jobdbCursor.execute('''
|
||||
INSERT INTO PeerJobs VALUES (?, ?, ?, ?, ?, ?, strftime('%Y-%m-%d %H:%M:%S','now'), NULL, ?)
|
||||
''', (Job.JobID, Job.Configuration, Job.Peer, Job.Field, Job.Operator, Job.Value, Job.Action,))
|
||||
else:
|
||||
self.jobdbCursor.execute('''
|
||||
UPDATE PeerJobs SET Field = ?, Operator = ?, Value = ?, Action = ? WHERE JobID = ?
|
||||
''', (Job.Field, Job.Operator, Job.Value, Job.Action, 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)
|
||||
|
||||
|
||||
class WireguardConfiguration:
|
||||
class InvalidConfigurationFileException(Exception):
|
||||
@ -233,7 +250,6 @@ class WireguardConfiguration:
|
||||
self.__parser.write(configFile)
|
||||
|
||||
self.Peers: list[Peer] = []
|
||||
|
||||
# Create tables in database
|
||||
self.__createDatabase()
|
||||
self.getPeersList()
|
||||
@ -638,6 +654,7 @@ class Peer:
|
||||
self.getJobs()
|
||||
|
||||
def toJson(self):
|
||||
self.getJobs()
|
||||
return self.__dict__
|
||||
|
||||
def __repr__(self):
|
||||
@ -1368,6 +1385,32 @@ def API_getDashboardTheme():
|
||||
return ResponseObject(data=DashboardConfig.GetConfig("Server", "dashboard_theme")[1])
|
||||
|
||||
|
||||
@app.route('/api/savePeerScheduleJob/', methods=["POST"])
|
||||
def API_savePeerScheduleJob():
|
||||
data = request.json
|
||||
if "Job" not in data.keys() not in WireguardConfigurations.keys():
|
||||
return ResponseObject(False, "Please specify job")
|
||||
job: dict = data['Job']
|
||||
if "Peer" not in job.keys() or "Configuration" not in job.keys():
|
||||
return ResponseObject(False, "Please specify peer and configuration")
|
||||
configuration = WireguardConfigurations.get(job['Configuration'])
|
||||
f, fp = configuration.searchPeer(job['Peer'])
|
||||
if not f:
|
||||
return ResponseObject(False, "Peer does not exist in this configuration")
|
||||
|
||||
s, p = AllPeerJobs.saveJob(PeerJob(
|
||||
job['JobID'], job['Configuration'], job['Peer'], job['Field'], job['Operator'], job['Value'],
|
||||
job['CreationDate'], job['ExpireDate'], job['Action']))
|
||||
if s:
|
||||
return ResponseObject(s, data=p)
|
||||
return ResponseObject(s, message=p)
|
||||
|
||||
|
||||
'''
|
||||
Tools
|
||||
'''
|
||||
|
||||
|
||||
@app.route('/api/ping/getAllPeersIpAddress')
|
||||
def API_ping_getAllPeersIpAddress():
|
||||
ips = {}
|
||||
@ -1546,19 +1589,6 @@ def gunicornConfig():
|
||||
return app_ip, app_port
|
||||
|
||||
|
||||
# def runGunicorn():
|
||||
# sqldb = sqlite3.connect(os.path.join(CONFIGURATION_PATH, 'db', 'wgdashboard.db'), check_same_thread=False)
|
||||
# sqldb.row_factory = sqlite3.Row
|
||||
# cursor = sqldb.cursor()
|
||||
# _, app_ip = DashboardConfig.GetConfig("Server", "app_ip")
|
||||
# _, app_port = DashboardConfig.GetConfig("Server", "app_port")
|
||||
# WireguardConfigurations = _getConfigurationList()
|
||||
# bgThread = threading.Thread(target=backGroundThread)
|
||||
# bgThread.daemon = True
|
||||
# bgThread.start()
|
||||
# return app
|
||||
|
||||
|
||||
sqldb = sqlite3.connect(os.path.join(CONFIGURATION_PATH, 'db', 'wgdashboard.db'), check_same_thread=False)
|
||||
sqldb.row_factory = sqlite3.Row
|
||||
cursor = sqldb.cursor()
|
||||
@ -1572,4 +1602,3 @@ bgThread.start()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(host=app_ip, debug=True, port=app_port)
|
||||
|
||||
|
@ -3,6 +3,7 @@ import ScheduleDropdown from "@/components/configurationComponents/peerScheduleJ
|
||||
import SchedulePeerJob from "@/components/configurationComponents/peerScheduleJobsComponents/schedulePeerJob.vue";
|
||||
export default {
|
||||
name: "peerJobs",
|
||||
|
||||
props:{
|
||||
selectedPeer: Object
|
||||
},
|
||||
@ -67,33 +68,65 @@ export default {
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
|
||||
deleteJob(j, index){
|
||||
if (j.CreationDate){
|
||||
|
||||
}else{
|
||||
this.selectedPeer.jobs = this.selectedPeer.jobs.filter(x => x.JobID !== j.JobID)
|
||||
}
|
||||
},
|
||||
addJob(){
|
||||
this.selectedPeer.jobs.push(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,
|
||||
Value: "",
|
||||
CreationDate: "",
|
||||
ExpireDate: "",
|
||||
Action: this.dropdowns.Action[0].value
|
||||
}))
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
</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="card m-auto 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
|
||||
<strong></strong>
|
||||
</h4>
|
||||
<button type="button" class="btn-close ms-auto" @click="this.$emit('close')"></button>
|
||||
</div>
|
||||
<div class="card-body px-4 pb-4 pt-0">
|
||||
<!-- <div class="d-flex gap-2 mb-3">-->
|
||||
<!-- <small>{{selectedPeer.name ? selectedPeer.name : "Untitled Peer"}}</small>-->
|
||||
<!-- <small class="ms-auto"><samp>{{this.selectedPeer.id}}</samp></small>-->
|
||||
<!-- </div>-->
|
||||
|
||||
|
||||
<SchedulePeerJob
|
||||
:dropdowns="this.dropdowns"
|
||||
:pjob="job" v-for="job in this.selectedPeer.jobs">
|
||||
</SchedulePeerJob>
|
||||
<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
|
||||
<strong></strong>
|
||||
</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="d-flex align-items-center mb-3">
|
||||
<input class="form-control form-control-sm w-auto rounded-3" placeholder="Search Job...">
|
||||
<button class="btn btn-sm btn-primary rounded-3 ms-auto" @click="this.addJob()">
|
||||
<i class="bi bi-plus-lg me-2"></i> Job
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
<TransitionGroup name="fade">
|
||||
<SchedulePeerJob
|
||||
@refresh="this.$emit('refresh')"
|
||||
@delete="this.deleteJob(job)"
|
||||
:dropdowns="this.dropdowns"
|
||||
:key="job.JobID"
|
||||
:pjob="job" v-for="(job) in this.selectedPeer.jobs">
|
||||
</SchedulePeerJob>
|
||||
</TransitionGroup>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -551,6 +551,7 @@ export default {
|
||||
</Transition>
|
||||
<Transition name="fade">
|
||||
<PeerJobs
|
||||
@refresh="this.getPeers()"
|
||||
v-if="this.peerScheduleJobs.modalOpen"
|
||||
:selectedPeer="this.peerScheduleJobs.selectedPeer"
|
||||
@close="this.peerScheduleJobs.modalOpen = false">
|
||||
|
@ -14,15 +14,17 @@ export default {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="peerSettingContainer w-100 h-100 position-absolute top-0 start-0">
|
||||
<div class="container d-flex h-100 w-100">
|
||||
<div class="card m-auto 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>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<canvas id="qrcode" class="rounded-3 shadow" ref="qrcode"></canvas>
|
||||
<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="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>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<canvas id="qrcode" class="rounded-3 shadow" ref="qrcode"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -30,8 +32,4 @@ export default {
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.peerSettingContainer {
|
||||
background-color: #00000060;
|
||||
z-index: 1000;
|
||||
}
|
||||
</style>
|
@ -8,8 +8,10 @@ export default {
|
||||
data: String,
|
||||
edit: false
|
||||
},
|
||||
mounted() {
|
||||
console.log(this.options)
|
||||
setup(props) {
|
||||
if (props.data === undefined){
|
||||
this.$emit('update', this.options[0].value)
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
currentSelection(){
|
||||
@ -21,7 +23,8 @@ export default {
|
||||
|
||||
<template>
|
||||
<div class="dropdown scheduleDropdown">
|
||||
<button class="btn btn-sm btn-outline-primary rounded-3" :class="{disabled: !edit}" type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
<button class="btn btn-sm btn-outline-primary rounded-3"
|
||||
:class="{'disabled': !edit}" type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
<samp>{{this.currentSelection.display}}</samp>
|
||||
</button>
|
||||
<ul class="dropdown-menu rounded-3 shadow" style="font-size: 0.875rem; width: 200px">
|
||||
@ -40,4 +43,7 @@ export default {
|
||||
opacity: 1;
|
||||
background-color: rgba(13, 110, 253, 0.09);
|
||||
}
|
||||
.btn{
|
||||
//padding: 0.1rem 0.4rem;
|
||||
}
|
||||
</style>
|
@ -1,5 +1,8 @@
|
||||
<script>
|
||||
import ScheduleDropdown from "@/components/configurationComponents/peerScheduleJobsComponents/scheduleDropdown.vue";
|
||||
import {ref} from "vue";
|
||||
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
|
||||
import {fetchPost} from "@/utilities/fetch.js";
|
||||
|
||||
export default {
|
||||
name: "schedulePeerJob",
|
||||
@ -8,22 +11,45 @@ export default {
|
||||
dropdowns: Array[Object],
|
||||
pjob: Object
|
||||
},
|
||||
setup(props){
|
||||
const job = ref({})
|
||||
const edit = ref(false)
|
||||
const newJob = ref(false)
|
||||
job.value = JSON.parse(JSON.stringify(props.pjob))
|
||||
if (!job.value.CreationDate){
|
||||
edit.value = true
|
||||
newJob.value = true
|
||||
}
|
||||
const store = DashboardConfigurationStore()
|
||||
return {job, edit, newJob, store}
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
job: Object,
|
||||
inputType: undefined,
|
||||
edit: false
|
||||
}
|
||||
},
|
||||
beforeMount() {
|
||||
this.job = JSON.parse(JSON.stringify(this.pjob))
|
||||
watch:{
|
||||
pjob: {
|
||||
deep: true,
|
||||
handler(newValue){
|
||||
this.job = JSON.parse(JSON.stringify(newValue))
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
save(){
|
||||
if (this.job.Field && this.job.Operator && this.job.Action && this.job.Value){
|
||||
if (this.job.Field === 'date'){
|
||||
this.job.Value = new Date(this.job.Value).getTime();
|
||||
}
|
||||
fetchPost(`/api/savePeerScheduleJob/`, {
|
||||
Job: this.job
|
||||
}, (res) => {
|
||||
if (res.status){
|
||||
this.edit = false;
|
||||
this.store.newMessage("Server", "Job Saved!", "success")
|
||||
this.$emit("refresh")
|
||||
}else{
|
||||
this.store.newMessage("Server", res.message, "danger")
|
||||
}
|
||||
})
|
||||
}else{
|
||||
this.alert();
|
||||
}
|
||||
@ -40,23 +66,28 @@ export default {
|
||||
}, 2000)
|
||||
},
|
||||
reset(){
|
||||
this.job = JSON.parse(JSON.stringify(this.pjob));
|
||||
this.edit = false;
|
||||
if(this.job.CreationDate){
|
||||
this.job = JSON.parse(JSON.stringify(this.pjob));
|
||||
this.edit = false;
|
||||
}else{
|
||||
this.$emit('delete')
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="card shadow-sm rounded-3">
|
||||
<div class="card shadow-sm rounded-3 mb-2" :class="{'border-warning-subtle': this.newJob}">
|
||||
<div class="card-header bg-transparent text-muted border-0">
|
||||
<small class="d-flex">
|
||||
<small class="d-flex" v-if="!this.newJob">
|
||||
<strong class="me-auto">Job ID</strong>
|
||||
<samp>{{this.job.JobID}}</samp>
|
||||
</small>
|
||||
<small v-else><span class="badge text-bg-warning">Unsaved Job</span></small>
|
||||
</div>
|
||||
<div class="card-body pt-1" style="font-family: var(--bs-font-monospace)">
|
||||
<div class="d-flex gap-3 align-items-center mb-2">
|
||||
<div class="d-flex gap-2 align-items-center mb-2">
|
||||
<samp>
|
||||
if
|
||||
</samp>
|
||||
@ -87,18 +118,17 @@ export default {
|
||||
v-model="this.job.Value"
|
||||
style="width: auto">
|
||||
<samp>
|
||||
{{this.dropdowns.Field.find(x => x.value === this.job.Field).unit}} {
|
||||
{{this.dropdowns.Field.find(x => x.value === this.job.Field)?.unit}} {
|
||||
</samp>
|
||||
</div>
|
||||
<div class="px-5 d-flex gap-3 align-items-center">
|
||||
<samp>execute</samp>
|
||||
<div class="px-5 d-flex gap-2 align-items-center">
|
||||
<samp>then</samp>
|
||||
<ScheduleDropdown
|
||||
:edit="edit"
|
||||
:options="this.dropdowns.Action"
|
||||
:data="this.job.Action"
|
||||
@update="(value) => this.job.Action = value"
|
||||
></ScheduleDropdown>
|
||||
<samp>;</samp>
|
||||
</div>
|
||||
<div class="d-flex gap-3">
|
||||
<samp>}</samp>
|
||||
@ -123,5 +153,11 @@ export default {
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
*{
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
input{
|
||||
padding: 0.1rem 0.4rem;
|
||||
}
|
||||
</style>
|
@ -55,128 +55,131 @@ export default {
|
||||
<template>
|
||||
<div class="peerSettingContainer w-100 h-100 position-absolute top-0 start-0">
|
||||
<div class="container d-flex h-100 w-100">
|
||||
<div class="card m-auto rounded-3 shadow" style="width: 700px">
|
||||
<div class="card-header bg-transparent d-flex align-items-center gap-2 border-0 p-4">
|
||||
<h4 class="mb-0">Peer Settings</h4>
|
||||
<button type="button" class="btn-close ms-auto" @click="this.$emit('close')"></button>
|
||||
</div>
|
||||
<div class="card-body px-4 pb-4" v-if="this.data">
|
||||
<div class="d-flex flex-column gap-2 mb-4">
|
||||
<div>
|
||||
<small class="text-muted">Public Key</small><br>
|
||||
<small><samp>{{this.data.id}}</samp></small>
|
||||
</div>
|
||||
<div>
|
||||
<label for="peer_name_textbox" class="form-label">
|
||||
<small class="text-muted">Name</small>
|
||||
</label>
|
||||
<input type="text" class="form-control form-control-sm rounded-3"
|
||||
:disabled="this.saving"
|
||||
v-model="this.data.name"
|
||||
id="peer_name_textbox" placeholder="">
|
||||
</div>
|
||||
<div>
|
||||
<div class="d-flex position-relative">
|
||||
<label for="peer_private_key_textbox" class="form-label">
|
||||
<small class="text-muted">Private Key <code>(Required for QR Code and Download)</code></small>
|
||||
</label>
|
||||
<a role="button" class="ms-auto text-decoration-none toggleShowKey"
|
||||
@click="this.showKey = !this.showKey"
|
||||
>
|
||||
<i class="bi" :class="[this.showKey ? 'bi-eye-slash-fill':'bi-eye-fill']"></i>
|
||||
</a>
|
||||
<div class="m-auto modal-dialog-centered dashboardModal">
|
||||
<div class="card rounded-3 shadow flex-grow-1">
|
||||
<div class="card-header bg-transparent d-flex align-items-center gap-2 border-0 p-4">
|
||||
<h4 class="mb-0">Peer Settings</h4>
|
||||
<button type="button" class="btn-close ms-auto" @click="this.$emit('close')"></button>
|
||||
</div>
|
||||
<div class="card-body px-4 pb-4" v-if="this.data">
|
||||
<div class="d-flex flex-column gap-2 mb-4">
|
||||
<div>
|
||||
<small class="text-muted">Public Key</small><br>
|
||||
<small><samp>{{this.data.id}}</samp></small>
|
||||
</div>
|
||||
<input :type="[this.showKey ? 'text':'password']" class="form-control form-control-sm rounded-3"
|
||||
:disabled="this.saving"
|
||||
v-model="this.data.private_key"
|
||||
id="peer_private_key_textbox"
|
||||
style="padding-right: 40px">
|
||||
</div>
|
||||
<div>
|
||||
<label for="peer_allowed_ip_textbox" class="form-label">
|
||||
<small class="text-muted">Allowed IPs <code>(Required)</code></small>
|
||||
</label>
|
||||
<input type="text" class="form-control form-control-sm rounded-3"
|
||||
:disabled="this.saving"
|
||||
v-model="this.data.allowed_ip"
|
||||
id="peer_allowed_ip_textbox">
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="peer_endpoint_allowed_ips" class="form-label">
|
||||
<small class="text-muted">Endpoint Allowed IPs <code>(Required)</code></small>
|
||||
</label>
|
||||
<input type="text" class="form-control form-control-sm rounded-3"
|
||||
:disabled="this.saving"
|
||||
v-model="this.data.endpoint_allowed_ip"
|
||||
id="peer_endpoint_allowed_ips">
|
||||
</div>
|
||||
<div>
|
||||
<label for="peer_DNS_textbox" class="form-label">
|
||||
<small class="text-muted">DNS</small>
|
||||
</label>
|
||||
<input type="text" class="form-control form-control-sm rounded-3"
|
||||
:disabled="this.saving"
|
||||
v-model="this.data.DNS"
|
||||
id="peer_DNS_textbox">
|
||||
</div>
|
||||
<hr>
|
||||
<div class="accordion mt-2" id="peerSettingsAccordion">
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header">
|
||||
<button class="accordion-button rounded-3 collapsed" type="button"
|
||||
data-bs-toggle="collapse" data-bs-target="#peerSettingsAccordionOptional">
|
||||
Optional Settings
|
||||
</button>
|
||||
</h2>
|
||||
<div id="peerSettingsAccordionOptional" class="accordion-collapse collapse"
|
||||
data-bs-parent="#peerSettingsAccordion">
|
||||
<div class="accordion-body d-flex flex-column gap-2 mb-2">
|
||||
<div>
|
||||
<label for="peer_preshared_key_textbox" class="form-label">
|
||||
<small class="text-muted">Pre-Shared Key</small>
|
||||
</label>
|
||||
<input type="text" class="form-control form-control-sm rounded-3"
|
||||
:disabled="this.saving"
|
||||
v-model="this.data.preshared_key"
|
||||
id="peer_preshared_key_textbox">
|
||||
</div>
|
||||
<div>
|
||||
<label for="peer_mtu" class="form-label"><small class="text-muted">MTU</small></label>
|
||||
<input type="number" class="form-control form-control-sm rounded-3"
|
||||
:disabled="this.saving"
|
||||
v-model="this.data.mtu"
|
||||
id="peer_mtu">
|
||||
</div>
|
||||
<div>
|
||||
<label for="peer_keep_alive" class="form-label">
|
||||
<small class="text-muted">Persistent Keepalive</small>
|
||||
</label>
|
||||
<input type="number" class="form-control form-control-sm rounded-3"
|
||||
:disabled="this.saving"
|
||||
v-model="this.data.keepalive"
|
||||
id="peer_keep_alive">
|
||||
<div>
|
||||
<label for="peer_name_textbox" class="form-label">
|
||||
<small class="text-muted">Name</small>
|
||||
</label>
|
||||
<input type="text" class="form-control form-control-sm rounded-3"
|
||||
:disabled="this.saving"
|
||||
v-model="this.data.name"
|
||||
id="peer_name_textbox" placeholder="">
|
||||
</div>
|
||||
<div>
|
||||
<div class="d-flex position-relative">
|
||||
<label for="peer_private_key_textbox" class="form-label">
|
||||
<small class="text-muted">Private Key <code>(Required for QR Code and Download)</code></small>
|
||||
</label>
|
||||
<a role="button" class="ms-auto text-decoration-none toggleShowKey"
|
||||
@click="this.showKey = !this.showKey"
|
||||
>
|
||||
<i class="bi" :class="[this.showKey ? 'bi-eye-slash-fill':'bi-eye-fill']"></i>
|
||||
</a>
|
||||
</div>
|
||||
<input :type="[this.showKey ? 'text':'password']" class="form-control form-control-sm rounded-3"
|
||||
:disabled="this.saving"
|
||||
v-model="this.data.private_key"
|
||||
id="peer_private_key_textbox"
|
||||
style="padding-right: 40px">
|
||||
</div>
|
||||
<div>
|
||||
<label for="peer_allowed_ip_textbox" class="form-label">
|
||||
<small class="text-muted">Allowed IPs <code>(Required)</code></small>
|
||||
</label>
|
||||
<input type="text" class="form-control form-control-sm rounded-3"
|
||||
:disabled="this.saving"
|
||||
v-model="this.data.allowed_ip"
|
||||
id="peer_allowed_ip_textbox">
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="peer_endpoint_allowed_ips" class="form-label">
|
||||
<small class="text-muted">Endpoint Allowed IPs <code>(Required)</code></small>
|
||||
</label>
|
||||
<input type="text" class="form-control form-control-sm rounded-3"
|
||||
:disabled="this.saving"
|
||||
v-model="this.data.endpoint_allowed_ip"
|
||||
id="peer_endpoint_allowed_ips">
|
||||
</div>
|
||||
<div>
|
||||
<label for="peer_DNS_textbox" class="form-label">
|
||||
<small class="text-muted">DNS</small>
|
||||
</label>
|
||||
<input type="text" class="form-control form-control-sm rounded-3"
|
||||
:disabled="this.saving"
|
||||
v-model="this.data.DNS"
|
||||
id="peer_DNS_textbox">
|
||||
</div>
|
||||
<hr>
|
||||
<div class="accordion mt-2" id="peerSettingsAccordion">
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header">
|
||||
<button class="accordion-button rounded-3 collapsed" type="button"
|
||||
data-bs-toggle="collapse" data-bs-target="#peerSettingsAccordionOptional">
|
||||
Optional Settings
|
||||
</button>
|
||||
</h2>
|
||||
<div id="peerSettingsAccordionOptional" class="accordion-collapse collapse"
|
||||
data-bs-parent="#peerSettingsAccordion">
|
||||
<div class="accordion-body d-flex flex-column gap-2 mb-2">
|
||||
<div>
|
||||
<label for="peer_preshared_key_textbox" class="form-label">
|
||||
<small class="text-muted">Pre-Shared Key</small>
|
||||
</label>
|
||||
<input type="text" class="form-control form-control-sm rounded-3"
|
||||
:disabled="this.saving"
|
||||
v-model="this.data.preshared_key"
|
||||
id="peer_preshared_key_textbox">
|
||||
</div>
|
||||
<div>
|
||||
<label for="peer_mtu" class="form-label"><small class="text-muted">MTU</small></label>
|
||||
<input type="number" class="form-control form-control-sm rounded-3"
|
||||
:disabled="this.saving"
|
||||
v-model="this.data.mtu"
|
||||
id="peer_mtu">
|
||||
</div>
|
||||
<div>
|
||||
<label for="peer_keep_alive" class="form-label">
|
||||
<small class="text-muted">Persistent Keepalive</small>
|
||||
</label>
|
||||
<input type="number" class="form-control form-control-sm rounded-3"
|
||||
:disabled="this.saving"
|
||||
v-model="this.data.keepalive"
|
||||
id="peer_keep_alive">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<button class="btn btn-secondary rounded-3 shadow"
|
||||
@click="this.reset()"
|
||||
:disabled="!this.dataChanged || this.saving">
|
||||
Reset <i class="bi bi-arrow-clockwise ms-2"></i>
|
||||
</button>
|
||||
|
||||
<button class="ms-auto btn btn-dark btn-brand rounded-3 px-3 py-2 shadow"
|
||||
:disabled="!this.dataChanged || this.saving"
|
||||
@click="this.savePeer()"
|
||||
>
|
||||
Save Peer<i class="bi bi-save-fill ms-2"></i></button>
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<button class="btn btn-secondary rounded-3 shadow"
|
||||
@click="this.reset()"
|
||||
:disabled="!this.dataChanged || this.saving">
|
||||
Reset <i class="bi bi-arrow-clockwise ms-2"></i>
|
||||
</button>
|
||||
|
||||
<button class="ms-auto btn btn-dark btn-brand rounded-3 px-3 py-2 shadow"
|
||||
:disabled="!this.dataChanged || this.saving"
|
||||
@click="this.savePeer()"
|
||||
>
|
||||
Save Peer<i class="bi bi-save-fill ms-2"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -14,8 +14,8 @@ export default {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="col-md-3 col-lg-2 d-md-block p-3">
|
||||
<nav id="sidebarMenu" class=" bg-body-tertiary sidebar border h-100 rounded-3 shadow" >
|
||||
<div class="col-md-3 col-lg-2 d-md-block p-3" style="height: calc(-50px + 100vh);">
|
||||
<nav id="sidebarMenu" class=" bg-body-tertiary sidebar border h-100 rounded-3 shadow overflow-y-scroll" >
|
||||
<div class="sidebar-sticky pt-3">
|
||||
<ul class="nav flex-column">
|
||||
<li class="nav-item">
|
||||
|
@ -1119,4 +1119,13 @@ pre.index-alert {
|
||||
.peerSettingContainer {
|
||||
background-color: #00000060;
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
.dashboardModal{
|
||||
min-height: calc(100% - 1.75rem * 2);
|
||||
width: 700px
|
||||
}
|
||||
|
||||
.dashboardModal > .card{
|
||||
margin: 1.75rem;
|
||||
}
|
Loading…
Reference in New Issue
Block a user