mirror of
https://github.com/donaldzou/WGDashboard.git
synced 2025-10-03 07:46:18 +00:00
46
src/static/app/package-lock.json
generated
46
src/static/app/package-lock.json
generated
@@ -25,6 +25,7 @@
|
||||
"npm": "^10.5.0",
|
||||
"ol": "^10.2.1",
|
||||
"pinia": "^3.0.3",
|
||||
"pinia-plugin-persistedstate": "^4.5.0",
|
||||
"qrcode": "^1.5.3",
|
||||
"qrcodejs": "^1.0.0",
|
||||
"simple-code-editor": "^2.0.9",
|
||||
@@ -3030,6 +3031,12 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/deep-pick-omit": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmmirror.com/deep-pick-omit/-/deep-pick-omit-1.2.1.tgz",
|
||||
"integrity": "sha512-2J6Kc/m3irCeqVG42T+SaUMesaK7oGWaedGnQQK/+O0gYc+2SP5bKh/KKTE7d7SJ+GCA9UUE1GRzh6oDe0EnGw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/defaults": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmmirror.com/defaults/-/defaults-1.0.4.tgz",
|
||||
@@ -3051,6 +3058,12 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/defu": {
|
||||
"version": "6.1.4",
|
||||
"resolved": "https://registry.npmmirror.com/defu/-/defu-6.1.4.tgz",
|
||||
"integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
@@ -3060,6 +3073,12 @@
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/destr": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmmirror.com/destr/-/destr-2.0.5.tgz",
|
||||
"integrity": "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/detect-libc": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmmirror.com/detect-libc/-/detect-libc-2.0.4.tgz",
|
||||
@@ -7564,6 +7583,33 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/pinia-plugin-persistedstate": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmmirror.com/pinia-plugin-persistedstate/-/pinia-plugin-persistedstate-4.5.0.tgz",
|
||||
"integrity": "sha512-QTkP1xJVyCdr2I2p3AKUZM84/e+IS+HktRxKGAIuDzkyaKKV48mQcYkJFVVDuvTxlI5j6X3oZObpqoVB8JnWpw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"deep-pick-omit": "^1.2.1",
|
||||
"defu": "^6.1.4",
|
||||
"destr": "^2.0.5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@nuxt/kit": ">=3.0.0",
|
||||
"@pinia/nuxt": ">=0.10.0",
|
||||
"pinia": ">=3.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@nuxt/kit": {
|
||||
"optional": true
|
||||
},
|
||||
"@pinia/nuxt": {
|
||||
"optional": true
|
||||
},
|
||||
"pinia": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/pinia/node_modules/@vue/devtools-api": {
|
||||
"version": "7.7.7",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-7.7.7.tgz",
|
||||
|
@@ -29,6 +29,7 @@
|
||||
"npm": "^10.5.0",
|
||||
"ol": "^10.2.1",
|
||||
"pinia": "^3.0.3",
|
||||
"pinia-plugin-persistedstate": "^4.5.0",
|
||||
"qrcode": "^1.5.3",
|
||||
"qrcodejs": "^1.0.0",
|
||||
"simple-code-editor": "^2.0.9",
|
||||
|
@@ -41,6 +41,7 @@ export default {
|
||||
|
||||
<template>
|
||||
<div class="card shadow-sm rounded-3 peerCard"
|
||||
:id="'peer_'+Peer.id"
|
||||
:class="{'border-warning': Peer.restricted}">
|
||||
<div>
|
||||
<div v-if="!Peer.restricted" class="card-header bg-transparent d-flex align-items-center gap-2 border-0">
|
||||
|
@@ -189,6 +189,17 @@ const searchPeers = computed(() => {
|
||||
return 0;
|
||||
}).slice(0, showPeersCount.value)
|
||||
})
|
||||
|
||||
watch(() => route.query.id, (newValue) => {
|
||||
if (newValue){
|
||||
wireguardConfigurationStore.searchString = newValue
|
||||
}else{
|
||||
wireguardConfigurationStore.searchString = undefined
|
||||
}
|
||||
}, {
|
||||
immediate: true
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@@ -15,7 +15,6 @@ export default {
|
||||
return {store, wireguardConfigurationStore}
|
||||
},
|
||||
props: {
|
||||
|
||||
configuration: Object
|
||||
},
|
||||
data(){
|
||||
@@ -43,18 +42,6 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
debounce(){
|
||||
if (!this.searchStringTimeout){
|
||||
this.searchStringTimeout = setTimeout(() => {
|
||||
this.wireguardConfigurationStore.searchString = this.searchString;
|
||||
}, 300)
|
||||
}else{
|
||||
clearTimeout(this.searchStringTimeout)
|
||||
this.searchStringTimeout = setTimeout(() => {
|
||||
this.wireguardConfigurationStore.searchString = this.searchString;
|
||||
}, 300)
|
||||
}
|
||||
},
|
||||
updateSort(sort){
|
||||
fetchPost("/api/updateDashboardConfigurationItem", {
|
||||
section: "Server",
|
||||
|
@@ -3,13 +3,14 @@ import {GetLocale} from "@/utilities/locale.js";
|
||||
import {computed, onMounted, ref, useTemplateRef} from "vue";
|
||||
import {WireguardConfigurationsStore} from "@/stores/WireguardConfigurationsStore.js";
|
||||
import LocaleText from "@/components/text/localeText.vue";
|
||||
import {useRoute, useRouter} from "vue-router";
|
||||
|
||||
const searchBarPlaceholder = computed(() => {
|
||||
return GetLocale("Search Peers...")
|
||||
})
|
||||
let searchStringTimeout = undefined
|
||||
const searchString = ref("")
|
||||
const wireguardConfigurationStore = WireguardConfigurationsStore()
|
||||
const searchString = ref(wireguardConfigurationStore.searchString)
|
||||
|
||||
const debounce = () => {
|
||||
if (!searchStringTimeout){
|
||||
@@ -27,10 +28,18 @@ const debounce = () => {
|
||||
const emits = defineEmits(['close'])
|
||||
const input = useTemplateRef('searchBar')
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
if (route.query.peer){
|
||||
searchString.value = route.query.peer
|
||||
router.replace({ query: null })
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
input.value.focus();
|
||||
})
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@@ -29,17 +29,17 @@ export default {
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
if (!window.localStorage.getItem('ConfigurationListSort')){
|
||||
window.localStorage.setItem('ConfigurationListSort', JSON.stringify(this.currentSort))
|
||||
}else{
|
||||
this.currentSort = JSON.parse(window.localStorage.getItem('ConfigurationListSort'))
|
||||
}
|
||||
|
||||
if (!window.localStorage.getItem('ConfigurationListDisplay')){
|
||||
window.localStorage.setItem('ConfigurationListDisplay', this.currentDisplay)
|
||||
}else{
|
||||
this.currentDisplay = window.localStorage.getItem('ConfigurationListDisplay')
|
||||
}
|
||||
// if (!window.localStorage.getItem('ConfigurationListSort')){
|
||||
// window.localStorage.setItem('ConfigurationListSort', JSON.stringify(this.currentSort))
|
||||
// }else{
|
||||
// this.currentSort = JSON.parse(window.localStorage.getItem('ConfigurationListSort'))
|
||||
// }
|
||||
//
|
||||
// if (!window.localStorage.getItem('ConfigurationListDisplay')){
|
||||
// window.localStorage.setItem('ConfigurationListDisplay', this.currentDisplay)
|
||||
// }else{
|
||||
// this.currentDisplay = window.localStorage.getItem('ConfigurationListDisplay')
|
||||
// }
|
||||
|
||||
|
||||
await this.wireguardConfigurationsStore.getConfigurations();
|
||||
@@ -54,17 +54,8 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
configurations(){
|
||||
return [...this.wireguardConfigurationsStore.Configurations]
|
||||
return this.wireguardConfigurationsStore.sortConfigurations
|
||||
.filter(x => x.Name.toLowerCase().includes(this.searchKey) || x.PublicKey.includes(this.searchKey) || !this.searchKey)
|
||||
.sort((a, b) => {
|
||||
if (this.currentSort.order === 'desc') {
|
||||
return this.dotNotation(a, this.currentSort.key) < this.dotNotation(b, this.currentSort.key) ?
|
||||
1 : this.dotNotation(a, this.currentSort.key) > this.dotNotation(b, this.currentSort.key) ? -1 : 0;
|
||||
} else {
|
||||
return this.dotNotation(a, this.currentSort.key) > this.dotNotation(b, this.currentSort.key) ?
|
||||
1 : this.dotNotation(a, this.currentSort.key) < this.dotNotation(b, this.currentSort.key) ? -1 : 0;
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -76,18 +67,16 @@ export default {
|
||||
return result
|
||||
},
|
||||
updateSort(key){
|
||||
if (this.currentSort.key === key){
|
||||
if (this.currentSort.order === 'asc') this.currentSort.order = 'desc'
|
||||
else this.currentSort.order = 'asc'
|
||||
if (this.wireguardConfigurationsStore.CurrentSort.key === key){
|
||||
this.wireguardConfigurationsStore.CurrentSort.order =
|
||||
this.wireguardConfigurationsStore.CurrentSort.order === 'asc' ? 'desc' : 'asc'
|
||||
}else{
|
||||
this.currentSort.key = key
|
||||
this.wireguardConfigurationsStore.CurrentSort.key = key
|
||||
}
|
||||
window.localStorage.setItem('ConfigurationListSort', JSON.stringify(this.currentSort))
|
||||
},
|
||||
updateDisplay(key){
|
||||
if (this.currentDisplay !== key){
|
||||
this.currentDisplay = key
|
||||
window.localStorage.setItem('ConfigurationListDisplay', this.currentDisplay)
|
||||
if (this.wireguardConfigurationsStore.CurrentDisplay !== key){
|
||||
this.wireguardConfigurationsStore.CurrentDisplay = key
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -121,12 +110,12 @@ export default {
|
||||
<div class="d-flex ms-auto ms-lg-0">
|
||||
<a role="button"
|
||||
@click="updateSort(sv)"
|
||||
:class="{'bg-primary-subtle text-primary-emphasis': this.currentSort.key === sv}"
|
||||
class="px-2 py-1 rounded-3" v-for="(s, sv) in this.sort">
|
||||
:class="{'bg-primary-subtle text-primary-emphasis': this.wireguardConfigurationsStore.CurrentSort.key === sv}"
|
||||
class="px-2 py-1 rounded-3" v-for="(s, sv) in this.wireguardConfigurationsStore.SortOptions">
|
||||
<small>
|
||||
<i class="bi me-2"
|
||||
:class="[this.currentSort.order === 'asc' ? 'bi-sort-up' : 'bi-sort-down']"
|
||||
v-if="this.currentSort.key === sv"></i>{{s}}
|
||||
:class="[this.wireguardConfigurationsStore.CurrentSort.order === 'asc' ? 'bi-sort-up' : 'bi-sort-down']"
|
||||
v-if="this.wireguardConfigurationsStore.CurrentSort.key === sv"></i>{{s}}
|
||||
</small>
|
||||
</a>
|
||||
</div>
|
||||
@@ -139,7 +128,7 @@ export default {
|
||||
<a role="button"
|
||||
@click="updateDisplay(x.name)"
|
||||
v-for="x in [{name: 'List', key: 'list'}, {name: 'Grid', key: 'grid'}]"
|
||||
:class="{'bg-primary-subtle text-primary-emphasis': this.currentDisplay === x.name}"
|
||||
:class="{'bg-primary-subtle text-primary-emphasis': this.wireguardConfigurationsStore.CurrentDisplay === x.name}"
|
||||
class="px-2 py-1 rounded-3">
|
||||
<small>
|
||||
<i class="bi me-2" :class="'bi-' + x.key"></i> <LocaleText :t="x.name"></LocaleText>
|
||||
@@ -167,7 +156,7 @@ export default {
|
||||
<LocaleText t="You don't have any WireGuard configurations yet. Please check the configuration folder or change it in Settings. By default the folder is /etc/wireguard."></LocaleText>
|
||||
</p>
|
||||
<ConfigurationCard
|
||||
:display="this.currentDisplay"
|
||||
:display="this.wireguardConfigurationsStore.CurrentDisplay"
|
||||
v-for="(c, index) in configurations"
|
||||
:delay="index*0.03 + 's'"
|
||||
v-else-if="this.configurationLoaded"
|
||||
|
@@ -74,14 +74,14 @@ export default {
|
||||
</RouterLink></li>
|
||||
<li class="nav-item">
|
||||
<RouterLink class="nav-link rounded-3" to="/settings"
|
||||
exact-active-class="active">
|
||||
active-class="active">
|
||||
<i class="bi bi-gear me-2"></i>
|
||||
<LocaleText t="Settings"></LocaleText>
|
||||
</RouterLink>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<RouterLink class="nav-link rounded-3" to="/clients"
|
||||
exact-active-class="active">
|
||||
active-class="active">
|
||||
<i class="bi bi-people me-2"></i>
|
||||
<LocaleText t="Clients"></LocaleText>
|
||||
</RouterLink>
|
||||
@@ -98,7 +98,7 @@ export default {
|
||||
<LocaleText t="WireGuard Configurations"></LocaleText>
|
||||
</h6>
|
||||
<ul class="nav flex-column px-2 gap-1">
|
||||
<li class="nav-item" v-for="c in this.wireguardConfigurationsStore.Configurations">
|
||||
<li class="nav-item" v-for="c in this.wireguardConfigurationsStore.sortConfigurations">
|
||||
<RouterLink :to="'/configuration/'+c.Name + '/peers'" class="nav-link nav-conf-link rounded-3"
|
||||
active-class="active"
|
||||
>
|
||||
|
@@ -9,6 +9,7 @@ import { createPinia } from 'pinia'
|
||||
import App from './App.vue'
|
||||
import router from './router/router.js'
|
||||
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
|
||||
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
|
||||
let Locale;
|
||||
await fetch("/api/locale")
|
||||
.then(res => res.json())
|
||||
@@ -19,11 +20,12 @@ await fetch("/api/locale")
|
||||
const app = createApp(App)
|
||||
app.use(router)
|
||||
const pinia = createPinia();
|
||||
|
||||
pinia.use(piniaPluginPersistedstate)
|
||||
pinia.use(({ store }) => {
|
||||
store.$router = markRaw(router)
|
||||
})
|
||||
|
||||
|
||||
app.use(pinia)
|
||||
const store = DashboardConfigurationStore()
|
||||
store.Locale = Locale;
|
||||
|
@@ -5,9 +5,19 @@ import {GetLocale} from "@/utilities/locale.js";
|
||||
|
||||
export const WireguardConfigurationsStore = defineStore('WireguardConfigurationsStore', {
|
||||
state: () => ({
|
||||
Configurations: undefined,
|
||||
Configurations: [],
|
||||
searchString: "",
|
||||
ConfigurationListInterval: undefined,
|
||||
SortOptions: {
|
||||
Name: GetLocale("Name"),
|
||||
Status: GetLocale("Status"),
|
||||
'DataUsage.Total': GetLocale("Total Usage")
|
||||
},
|
||||
CurrentSort: {
|
||||
key: "Name",
|
||||
order: "asc"
|
||||
},
|
||||
CurrentDisplay: "List",
|
||||
PeerScheduleJobs: {
|
||||
dropdowns: {
|
||||
Field: [
|
||||
@@ -66,6 +76,19 @@ export const WireguardConfigurationsStore = defineStore('WireguardConfigurations
|
||||
}
|
||||
}
|
||||
}),
|
||||
getters: {
|
||||
sortConfigurations(){
|
||||
return [...this.Configurations].sort((a, b) => {
|
||||
if (this.CurrentSort.order === 'desc') {
|
||||
return this.dotNotation(a, this.CurrentSort.key) < this.dotNotation(b, this.CurrentSort.key) ?
|
||||
1 : this.dotNotation(a, this.CurrentSort.key) > this.dotNotation(b, this.CurrentSort.key) ? -1 : 0;
|
||||
} else {
|
||||
return this.dotNotation(a, this.CurrentSort.key) > this.dotNotation(b, this.CurrentSort.key) ?
|
||||
1 : this.dotNotation(a, this.CurrentSort.key) < this.dotNotation(b, this.CurrentSort.key) ? -1 : 0;
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
async getConfigurations(){
|
||||
await fetchGet("/api/getWireguardConfigurations", {}, (res) => {
|
||||
@@ -73,6 +96,14 @@ export const WireguardConfigurationsStore = defineStore('WireguardConfigurations
|
||||
// this.Configurations = []
|
||||
});
|
||||
},
|
||||
|
||||
dotNotation(object, dotNotation){
|
||||
let result = dotNotation.split('.').reduce((o, key) => o && o[key], object)
|
||||
if (typeof result === "string"){
|
||||
return result.toLowerCase()
|
||||
}
|
||||
return result
|
||||
},
|
||||
regexCheckIP(ip){
|
||||
let regex = /((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$))/;
|
||||
return regex.test(ip)
|
||||
@@ -84,5 +115,10 @@ export const WireguardConfigurationsStore = defineStore('WireguardConfigurations
|
||||
const reg = /^[A-Za-z0-9+/]{43}=?=?$/;
|
||||
return reg.test(key)
|
||||
}
|
||||
},
|
||||
persist: {
|
||||
pick: [
|
||||
"CurrentSort", "CurrentDisplay"
|
||||
]
|
||||
}
|
||||
});
|
Reference in New Issue
Block a user