mirror of
https://github.com/donaldzou/WGDashboard.git
synced 2025-07-05 12:46:59 +00:00
Added sorting and search to configuration list
This commit is contained in:
parent
d92e62e40b
commit
3e01079caf
@ -3108,7 +3108,6 @@ def ProtocolsEnabled() -> list[str]:
|
|||||||
protocols.append("wg")
|
protocols.append("wg")
|
||||||
return protocols
|
return protocols
|
||||||
|
|
||||||
|
|
||||||
def InitWireguardConfigurationsList(startup: bool = False):
|
def InitWireguardConfigurationsList(startup: bool = False):
|
||||||
confs = os.listdir(DashboardConfig.GetConfig("Server", "wg_conf_path")[1])
|
confs = os.listdir(DashboardConfig.GetConfig("Server", "wg_conf_path")[1])
|
||||||
confs.sort()
|
confs.sort()
|
||||||
@ -3164,7 +3163,6 @@ def startThreads():
|
|||||||
scheduleJobThread.daemon = True
|
scheduleJobThread.daemon = True
|
||||||
scheduleJobThread.start()
|
scheduleJobThread.start()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
startThreads()
|
startThreads()
|
||||||
app.run(host=app_ip, debug=False, port=app_port)
|
app.run(host=app_ip, debug=False, port=app_port)
|
@ -204,6 +204,9 @@ export default {
|
|||||||
this.dashboardConfigurationStore.newMessage("Server",
|
this.dashboardConfigurationStore.newMessage("Server",
|
||||||
res.message, 'danger')
|
res.message, 'danger')
|
||||||
}
|
}
|
||||||
|
this.wireguardConfigurationStore.Configurations.find(x => x.Name === this.configurationInfo.Name).Status = res.data
|
||||||
|
console.log(this.wireguardConfigurationStore.Configurations.find(x => x.Name === this.configurationInfo.Name).Status)
|
||||||
|
|
||||||
this.configurationInfo.Status = res.data
|
this.configurationInfo.Status = res.data
|
||||||
this.configurationToggling = false;
|
this.configurationToggling = false;
|
||||||
})
|
})
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
<script>
|
<script>
|
||||||
import {wgdashboardStore} from "@/stores/wgdashboardStore.js";
|
|
||||||
import {WireguardConfigurationsStore} from "@/stores/WireguardConfigurationsStore.js";
|
import {WireguardConfigurationsStore} from "@/stores/WireguardConfigurationsStore.js";
|
||||||
import ConfigurationCard from "@/components/configurationListComponents/configurationCard.vue";
|
import ConfigurationCard from "@/components/configurationListComponents/configurationCard.vue";
|
||||||
import LocaleText from "@/components/text/localeText.vue";
|
import LocaleText from "@/components/text/localeText.vue";
|
||||||
import SystemStatus from "@/components/systemStatusComponents/systemStatusWidget.vue";
|
import SystemStatus from "@/components/systemStatusComponents/systemStatusWidget.vue";
|
||||||
|
import {GetLocale} from "@/utilities/locale.js";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "configurationList",
|
name: "configurationList",
|
||||||
@ -14,10 +14,26 @@ export default {
|
|||||||
},
|
},
|
||||||
data(){
|
data(){
|
||||||
return {
|
return {
|
||||||
configurationLoaded: false
|
configurationLoaded: false,
|
||||||
|
sort: {
|
||||||
|
Name: GetLocale("Name"),
|
||||||
|
Status: GetLocale("Status"),
|
||||||
|
'DataUsage.Total': GetLocale("Total Usage")
|
||||||
|
},
|
||||||
|
currentSort: {
|
||||||
|
key: "Name",
|
||||||
|
order: "asc"
|
||||||
|
},
|
||||||
|
searchKey: ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async mounted() {
|
async mounted() {
|
||||||
|
if (!window.localStorage.getItem('ConfigurationListSort')){
|
||||||
|
window.localStorage.setItem('ConfigurationListSort', JSON.stringify(this.currentSort))
|
||||||
|
}else{
|
||||||
|
this.currentSort = JSON.parse(window.localStorage.getItem('ConfigurationListSort'))
|
||||||
|
}
|
||||||
|
|
||||||
await this.wireguardConfigurationsStore.getConfigurations();
|
await this.wireguardConfigurationsStore.getConfigurations();
|
||||||
this.configurationLoaded = true;
|
this.configurationLoaded = true;
|
||||||
|
|
||||||
@ -27,6 +43,37 @@ export default {
|
|||||||
},
|
},
|
||||||
beforeUnmount() {
|
beforeUnmount() {
|
||||||
clearInterval(this.wireguardConfigurationsStore.ConfigurationListInterval)
|
clearInterval(this.wireguardConfigurationsStore.ConfigurationListInterval)
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
configurations(){
|
||||||
|
return [...this.wireguardConfigurationsStore.Configurations]
|
||||||
|
.filter(x => x.Name.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: {
|
||||||
|
dotNotation(object, dotNotation){
|
||||||
|
return dotNotation.split('.').reduce((o, key) => o && o[key], object)
|
||||||
|
},
|
||||||
|
updateSort(key){
|
||||||
|
if (this.currentSort.key === key){
|
||||||
|
if (this.currentSort.order === 'asc') this.currentSort.order = 'desc'
|
||||||
|
else this.currentSort.order = 'asc'
|
||||||
|
}else{
|
||||||
|
this.currentSort.key = key
|
||||||
|
}
|
||||||
|
window.localStorage.setItem('ConfigurationListSort', JSON.stringify(this.currentSort))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -35,33 +82,53 @@ export default {
|
|||||||
<div class="mt-md-5 mt-3">
|
<div class="mt-md-5 mt-3">
|
||||||
<div class="container-md">
|
<div class="container-md">
|
||||||
<SystemStatus></SystemStatus>
|
<SystemStatus></SystemStatus>
|
||||||
<div class="d-flex mb-4 configurationListTitle align-items-center gap-3">
|
<div class="d-flex mb-4 configurationListTitle align-items-md-center gap-3 flex-column flex-md-row">
|
||||||
<h2 class="text-body d-flex">
|
<h2 class="text-body d-flex mb-0">
|
||||||
<span>
|
|
||||||
<LocaleText t="WireGuard Configurations"></LocaleText>
|
<LocaleText t="WireGuard Configurations"></LocaleText>
|
||||||
</span>
|
|
||||||
</h2>
|
</h2>
|
||||||
<RouterLink to="/new_configuration"
|
<RouterLink to="/new_configuration"
|
||||||
class="btn btn-dark btn-brand rounded-3 p-2 shadow ms-auto rounded-3">
|
class="ms-md-auto py-2 text-decoration-none btn text-primary-emphasis bg-primary-subtle rounded-3 border-1 border-primary-subtle">
|
||||||
<h2 class="mb-0" style="line-height: 0">
|
<i class="bi bi-plus-circle me-2"></i><LocaleText t="Configuration"></LocaleText>
|
||||||
<i class="bi bi-plus-circle"></i>
|
|
||||||
</h2>
|
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
<RouterLink to="/restore_configuration"
|
<RouterLink to="/restore_configuration"
|
||||||
class="btn btn-dark btn-brand p-2 shadow ms-2" style="border-radius: 100%">
|
class="py-2 text-decoration-none btn text-primary-emphasis bg-primary-subtle rounded-3 border-1 border-primary-subtle">
|
||||||
<h2 class="mb-0" style="line-height: 0">
|
<i class="bi bi-clock-history me-2"></i><LocaleText t="Restore"></LocaleText>
|
||||||
<i class="bi bi-clock-history "></i>
|
|
||||||
</h2>
|
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="text-body filter mb-3 d-flex gap-2 flex-column flex-md-row" v-if="this.configurationLoaded">
|
||||||
|
<div class="d-flex align-items-center gap-3 align-items-center ">
|
||||||
|
<small class="text-muted">
|
||||||
|
<LocaleText t="Sort By"></LocaleText>
|
||||||
|
</small>
|
||||||
|
<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">
|
||||||
|
<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}}
|
||||||
|
</small>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex align-items-center ms-md-auto">
|
||||||
|
<label for="configurationSearch" class="text-muted">
|
||||||
|
<i class="bi bi-search me-2"></i>
|
||||||
|
</label>
|
||||||
|
<input class="form-control form-control-sm rounded-3"
|
||||||
|
v-model="this.searchKey"
|
||||||
|
id="configurationSearch">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<TransitionGroup name="fade" tag="div" class="d-flex flex-column gap-3 mb-4">
|
<TransitionGroup name="fade" tag="div" class="d-flex flex-column gap-3 mb-4">
|
||||||
<p class="text-muted"
|
<p class="text-muted"
|
||||||
key="noConfiguration"
|
key="noConfiguration"
|
||||||
v-if="this.configurationLoaded && this.wireguardConfigurationsStore.Configurations.length === 0">
|
v-if="this.configurationLoaded && this.wireguardConfigurationsStore.Configurations.length === 0">
|
||||||
<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>
|
<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>
|
</p>
|
||||||
<ConfigurationCard v-for="(c, index) in this.wireguardConfigurationsStore.Configurations"
|
<ConfigurationCard v-for="(c, index) in configurations"
|
||||||
:delay="index*0.05 + 's'"
|
:delay="index*0.05 + 's'"
|
||||||
v-else-if="this.configurationLoaded"
|
v-else-if="this.configurationLoaded"
|
||||||
:key="c.Name" :c="c"></ConfigurationCard>
|
:key="c.Name" :c="c"></ConfigurationCard>
|
||||||
@ -73,9 +140,7 @@ export default {
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.configurationListTitle{
|
.filter a{
|
||||||
.btn{
|
text-decoration: none;
|
||||||
border-radius: 50% !important;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
@ -1,5 +1,4 @@
|
|||||||
<script>
|
<script>
|
||||||
import {wgdashboardStore} from "@/stores/wgdashboardStore.js";
|
|
||||||
import {WireguardConfigurationsStore} from "@/stores/WireguardConfigurationsStore.js";
|
import {WireguardConfigurationsStore} from "@/stores/WireguardConfigurationsStore.js";
|
||||||
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
|
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
|
||||||
import {fetchGet} from "@/utilities/fetch.js";
|
import {fetchGet} from "@/utilities/fetch.js";
|
||||||
|
@ -156,7 +156,6 @@ router.beforeEach(async (to, from, next) => {
|
|||||||
dashboardConfigurationStore.ShowNavBar = false;
|
dashboardConfigurationStore.ShowNavBar = false;
|
||||||
document.querySelector(".loadingBar").classList.remove("loadingDone")
|
document.querySelector(".loadingBar").classList.remove("loadingDone")
|
||||||
document.querySelector(".loadingBar").classList.add("loading")
|
document.querySelector(".loadingBar").classList.add("loading")
|
||||||
console.log(to.path)
|
|
||||||
if (to.meta.requiresAuth){
|
if (to.meta.requiresAuth){
|
||||||
if (!dashboardConfigurationStore.getActiveCrossServer()){
|
if (!dashboardConfigurationStore.getActiveCrossServer()){
|
||||||
if (await checkAuth()){
|
if (await checkAuth()){
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
import {defineStore} from "pinia";
|
|
||||||
import {fetchGet} from "@/utilities/fetch.js";
|
|
||||||
|
|
||||||
|
|
||||||
export const wgdashboardStore = defineStore('WGDashboardStore', {
|
|
||||||
state: () => ({
|
|
||||||
WireguardConfigurations: undefined,
|
|
||||||
DashboardConfiguration: undefined
|
|
||||||
}),
|
|
||||||
actions: {
|
|
||||||
async getDashboardConfiguration(){
|
|
||||||
await fetchGet("/api/getDashboardConfiguration", {}, (res) => {
|
|
||||||
console.log(res.status)
|
|
||||||
if (res.status) this.DashboardConfiguration = res.data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user