mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2025-11-29 02:42:51 +00:00
277 lines
No EOL
13 KiB
HTML
277 lines
No EOL
13 KiB
HTML
{{ template "page/head_start" .}}
|
|
<!-- <link rel="stylesheet" href="{{ .base_path }}assets/jquery/jquery.modal.min.css" /> -->
|
|
<link rel="stylesheet" href="{{ .base_path }}assets/bootstrap/bootstrap.min.css">
|
|
{{ template "page/head_end" .}} {{ template
|
|
"page/body_start" .}}
|
|
|
|
<a-layout id="app" v-cloak :class="themeSwitcher.currentTheme + ' settings-page'">
|
|
<a-sidebar></a-sidebar>
|
|
<a-layout id="content-layout">
|
|
<a-layout-content>
|
|
<a-spin :spinning="loadingStates.spinning" :delay="500" tip='{{ i18n "loading"}}'>
|
|
<transition name="list" appear>
|
|
<a-alert type="error" v-if="confAlerts.length>0 && loadingStates.fetched"
|
|
:style="{ marginBottom: '10px' }" message='{{ i18n "secAlertTitle" }}' color="red" show-icon
|
|
slot="description">
|
|
<b>{{ i18n "secAlertConf" }}</b>
|
|
<ul>
|
|
<li v-for="a in confAlerts">[[ a ]]</li>
|
|
</ul>
|
|
</template>
|
|
</a-alert>
|
|
</transition>
|
|
<transition name="list" appear>
|
|
<template>
|
|
<div class="row" v-cloak>
|
|
<div class="col-md-12">
|
|
<div class="card-header">
|
|
<h3 class="card-title">Server Management</h3>
|
|
<div class="card-tools">
|
|
<button class="btn btn-primary" @click="showAddModal">Add Server</button>
|
|
</div>
|
|
</div>
|
|
<div class="card-body">
|
|
<table class="table table-bordered">
|
|
<thead>
|
|
<tr>
|
|
<th>#</th>
|
|
<th>Name</th>
|
|
<th>Address</th>
|
|
<th>Port</th>
|
|
<th>Enabled</th>
|
|
<th>Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<template v-if="servers.length>0">
|
|
<tr v-for="(server, index) in servers">
|
|
<td>[[ index + 1 ]]</td>
|
|
<td>[[ server.name ]]</td>
|
|
<td>[[ server.address ]]</td>
|
|
<td>[[ server.port ]]</td>
|
|
<td><span v-if="server.enable"
|
|
class="badge bg-success">Yes</span><span v-else
|
|
class="badge bg-danger">No</span>
|
|
</td>
|
|
<td><button class="btn btn-info btn-sm"
|
|
@click="showEditModal(server)">Edit</button><button
|
|
class="btn btn-danger btn-sm"
|
|
@click="deleteServer(server.id)">Delete</button></td>
|
|
</tr>
|
|
</template>
|
|
<tr v-else>
|
|
<td colspan="6" class="text-center">No servers found</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
</template>
|
|
</transition>
|
|
<transition>
|
|
<template>
|
|
<!-- Add/Edit Modal -->
|
|
<div class="modal fade" data-backdrop="false" id="serverModal" tabindex="-1" role="dialog">
|
|
<div class="modal-dialog" role="document">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">[[ modal.title ]]</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal"
|
|
aria-label="Close">
|
|
<span aria-hidden="true">×</span>
|
|
</button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<form>
|
|
<div class="form-group">
|
|
<label>Name</label>
|
|
<input type="text" class="form-control" v-model="modal.server.name" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label>Address (IP or Domain)</label>
|
|
<input type="text" class="form-control"
|
|
v-model="modal.server.address" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label>Port</label>
|
|
<input type="number" class="form-control"
|
|
v-model.number="modal.server.port" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label>API Key</label>
|
|
<input type="text" class="form-control" v-model="modal.server.apiKey" />
|
|
</div>
|
|
<div class="form-check">
|
|
<input type="checkbox" class="form-check-input"
|
|
v-model="modal.server.enable" />
|
|
<label class="form-check-label">Enabled</label>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
|
|
Close
|
|
</button>
|
|
<button type="button" class="btn btn-primary" @click="saveServer">
|
|
Save
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</transition>
|
|
|
|
</a-spin>
|
|
|
|
</a-layout-content>
|
|
|
|
</a-layout>
|
|
</a-layout>
|
|
|
|
|
|
{{template "page/body_scripts" .}} {{template "component/aSidebar" .}}
|
|
{{template "component/aThemeSwitch" .}}
|
|
<!-- <script src="{{ .base_path }}assets/jquery/jquery.min.js"></script> -->
|
|
<!--<script src="{{ .base_path }}assets/jquery/jquery.modal.min.js"></script> -->
|
|
|
|
<script src="{{ .base_path }}assets/bootstrap/bootstrap.min.js"></script>
|
|
|
|
<script>
|
|
const app = new Vue({
|
|
delimiters: ["[[", "]]"],
|
|
mixins: [MediaQueryMixin],
|
|
el: "#app",
|
|
data: {
|
|
themeSwitcher,
|
|
loadingStates: {
|
|
fetched: false,
|
|
spinning: false,
|
|
},
|
|
servers: [],
|
|
modal: {
|
|
title: "",
|
|
server: {
|
|
name: "",
|
|
address: "",
|
|
port: 0,
|
|
apiKey: "",
|
|
enable: true,
|
|
},
|
|
},
|
|
},
|
|
methods: {
|
|
loadServers() {
|
|
|
|
axios.get('{{.base_path}}panel/api/servers/list')
|
|
.then(response => {
|
|
this.servers = response.data.obj;
|
|
if (this.servers.length == 0) {
|
|
|
|
}
|
|
})
|
|
.catch(error => {
|
|
alert(error);
|
|
});
|
|
},
|
|
showAddModal() {
|
|
this.modal.title = "Add Server";
|
|
this.modal.server = {
|
|
name: "",
|
|
address: "",
|
|
port: 0,
|
|
apiKey: "",
|
|
enable: true,
|
|
};
|
|
|
|
const modalEl = document.getElementById('serverModal');
|
|
const modal = new bootstrap.Modal(modalEl);
|
|
modal.show();
|
|
},
|
|
showEditModal(server) {
|
|
this.modal.title = "Edit Server";
|
|
this.modal.server = Object.assign({}, server);
|
|
|
|
const modalEl = document.getElementById('serverModal');
|
|
const modal = new bootstrap.Modal(modalEl);
|
|
modal.show();
|
|
},
|
|
saveServer() {
|
|
let url = "{{.base_path}}panel/api/servers/add";
|
|
if (this.modal.server.id) {
|
|
url = `{{.base_path}}panel/api/servers/update/${this.modal.server.id}`;
|
|
}
|
|
|
|
console.log(this.modal.server);
|
|
axios
|
|
.post(url, this.modal.server)
|
|
.then((response) => {
|
|
alert(response.data.msg);
|
|
|
|
const modalEl = document.getElementById('serverModal');
|
|
const modal = bootstrap.Modal.getInstance(modalEl);
|
|
modal.hide();
|
|
|
|
this.loadServers();
|
|
})
|
|
.catch((error) => {
|
|
alert(error.response.data.msg);
|
|
});
|
|
},
|
|
deleteServer(id) {
|
|
if (!confirm("Are you sure you want to delete this server?")) {
|
|
return;
|
|
}
|
|
axios
|
|
.post(`{{.base_path}}panel/api/servers/del/${id}`)
|
|
.then((response) => {
|
|
alert(response.data.msg);
|
|
this.loadServers();
|
|
})
|
|
.catch((error) => {
|
|
alert(error.response.data.msg);
|
|
});
|
|
},
|
|
},
|
|
computed: {
|
|
confAlerts: {
|
|
get: function () {
|
|
if (!this.allSetting) return [];
|
|
var alerts = [];
|
|
if (window.location.protocol !== "https:")
|
|
alerts.push('{{ i18n "secAlertSSL" }}');
|
|
if (this.allSetting.webPort === 2053)
|
|
alerts.push('{{ i18n "secAlertPanelPort" }}');
|
|
panelPath = window.location.pathname.split("/").length < 4;
|
|
if (panelPath && this.allSetting.webBasePath == "/")
|
|
alerts.push('{{ i18n "secAlertPanelURI" }}');
|
|
if (this.allSetting.subEnable) {
|
|
subPath =
|
|
this.allSetting.subURI.length > 0
|
|
? new URL(this.allSetting.subURI).pathname
|
|
: this.allSetting.subPath;
|
|
if (subPath == "/sub/")
|
|
alerts.push('{{ i18n "secAlertSubURI" }}');
|
|
}
|
|
if (this.allSetting.subJsonEnable) {
|
|
subJsonPath =
|
|
this.allSetting.subJsonURI.length > 0
|
|
? new URL(this.allSetting.subJsonURI).pathname
|
|
: this.allSetting.subJsonPath;
|
|
if (subJsonPath == "/json/")
|
|
alerts.push('{{ i18n "secAlertSubJsonURI" }}');
|
|
}
|
|
return alerts;
|
|
},
|
|
},
|
|
},
|
|
|
|
mounted() {
|
|
this.loadServers();
|
|
},
|
|
});
|
|
</script>
|
|
{{ template "page/body_end" .}} |