diff --git a/dashboard/src/components/Firewall.vue b/dashboard/src/components/Firewall.vue
new file mode 100644
index 000000000..ca880d40e
--- /dev/null
+++ b/dashboard/src/components/Firewall.vue
@@ -0,0 +1,168 @@
+
+
+
+
+
+
+
+
+
+
+
{{ $t('network.firewall.blockedIpRanges') }}
+
{{ $t('network.firewall.blocklist', { blockCount: blocklistLength }) }}
+
+
+
{{ $t('network.trustedIpRanges') }}
+
{{ $t('network.trustedIps.summary', { trustCount: trustedIpsLength }) }}
+
+
+
+
diff --git a/dashboard/src/components/Ipv4Config.vue b/dashboard/src/components/Ipv4Config.vue
new file mode 100644
index 000000000..a6d743e34
--- /dev/null
+++ b/dashboard/src/components/Ipv4Config.vue
@@ -0,0 +1,162 @@
+
+
+
+
+
+
+
+ {{ $t('network.ip.description') }}
+
+
+
{{ $t('network.ip.provider') }}
+
{{ prettyIpProviderName(provider) }}
+
+
+
{{ $t('network.ip.address') }}
+
{{ address || `${detectedAddress} (${$t('network.ip.detected')})` }}
+
+
+
{{ $t('network.ip.interface') }}
+
{{ interfaceName }}
+
+
+
+
+
+
diff --git a/dashboard/src/components/Ipv6Config.vue b/dashboard/src/components/Ipv6Config.vue
new file mode 100644
index 000000000..ee544722c
--- /dev/null
+++ b/dashboard/src/components/Ipv6Config.vue
@@ -0,0 +1,162 @@
+
+
+
+
+
+
+
+ {{ $t('network.ipv6.description') }}
+
+
+
{{ $t('network.ip.provider') }}
+
{{ prettyIpProviderName(provider) }}
+
+
+
{{ $t('network.ip.address') }}
+
{{ address || `${detectedAddress} (${$t('network.ip.detected')})` }}
+
+
+
{{ $t('network.ip.interface') }}
+
{{ interfaceName }}
+
+
+
+
+
+
diff --git a/dashboard/src/models/NetworkModel.js b/dashboard/src/models/NetworkModel.js
index be29aa4d6..319cf82e6 100644
--- a/dashboard/src/models/NetworkModel.js
+++ b/dashboard/src/models/NetworkModel.js
@@ -14,6 +14,22 @@ function create(origin, accessToken) {
if (error || result.status !== 200) return [error || result];
return [null, result.body];
},
+ async setIpv4Config(provider, ip, ifname) {
+ const data = { provider };
+
+ if (provider === 'fixed') data.ip = ip;
+ else if (provider === 'network-interface') data.ifname = ifname;
+
+ let error, result;
+ try {
+ result = await fetcher.post(`${origin}/api/v1/network/ipv4_config`, data, { access_token: accessToken });
+ } catch (e) {
+ error = e;
+ }
+
+ if (error || result.status !== 200) return [error || result];
+ return [null];
+ },
async getIpv4() {
let error, result;
try {
@@ -36,6 +52,22 @@ function create(origin, accessToken) {
if (error || result.status !== 200) return [error || result];
return [null, result.body];
},
+ async setIpv6Config(provider, ip, ifname) {
+ const data = { provider };
+
+ if (provider === 'fixed') data.ip = ip;
+ else if (provider === 'network-interface') data.ifname = ifname;
+
+ let error, result;
+ try {
+ result = await fetcher.post(`${origin}/api/v1/network/ipv6_config`, data, { access_token: accessToken });
+ } catch (e) {
+ error = e;
+ }
+
+ if (error || result.status !== 200) return [error || result];
+ return [null];
+ },
async getIpv6() {
let error, result;
try {
diff --git a/dashboard/src/style.css b/dashboard/src/style.css
index a21c953e0..7f048d5d3 100644
--- a/dashboard/src/style.css
+++ b/dashboard/src/style.css
@@ -150,4 +150,12 @@ tr:hover .table-actions {
text-overflow: ellipsis;
overflow: hidden;
text-wrap: nowrap;
-}
\ No newline at end of file
+}
+
+.actionable {
+ cursor: pointer;
+}
+
+.actionable:hover {
+ color: var(--pankow-color-primary);
+}
diff --git a/dashboard/src/views/NetworkView.vue b/dashboard/src/views/NetworkView.vue
index c38e56d9e..88d267892 100644
--- a/dashboard/src/views/NetworkView.vue
+++ b/dashboard/src/views/NetworkView.vue
@@ -5,115 +5,13 @@ const API_ORIGIN = import.meta.env.VITE_API_ORIGIN ? import.meta.env.VITE_API_OR
import { ref, onMounted } from 'vue';
import { Button } from 'pankow';
import Section from '../components/Section.vue';
+import Ipv4Config from '../components/Ipv4Config.vue';
+import Ipv6Config from '../components/Ipv6Config.vue';
+import Firewall from '../components/Firewall.vue';
import NetworkModel from '../models/NetworkModel.js';
const networkModel = NetworkModel.create(API_ORIGIN, localStorage.token);
-// keep in sync with sysinfo.js
-const ipv4Providers = [
- { name: 'Disabled', value: 'noop' },
- { name: 'Public IP', value: 'generic' },
- { name: 'Static IP Address', value: 'fixed' },
- { name: 'Network Interface', value: 'network-interface' }
-];
-
-const ipv6Providers = [
- { name: 'Disabled', value: 'noop' },
- { name: 'Public IP', value: 'generic' },
- { name: 'Static IP Address', value: 'fixed' },
- { name: 'Network Interface', value: 'network-interface' }
-];
-
-function prettyIpProviderName(provider) {
- switch (provider) {
- case 'noop': return 'Disabled';
- case 'generic': return 'Public IP';
- case 'fixed': return 'Static IP Address';
- case 'network-interface': return 'Network Interface';
- default: return 'Unknown';
- }
-}
-
-// IPv4
-const ipv4Provider = ref('');
-const ipv4Address = ref('');
-const ipv4DetectedAddress = ref('');
-const ipv4InterfaceName = ref('');
-
-async function refreshIpv4() {
- let [error, result] = await networkModel.getIpv4Config();
- if (error) return console.error(error);
-
- ipv4Provider.value = result.provider;
- ipv4Address.value = result.ip;
- ipv4InterfaceName.value = result.ifname;
-
- [error, result] = await networkModel.getIpv4();
- if (error) return console.error(error);
-
- ipv4DetectedAddress.value = result;
-}
-
-function onIpv4Configure() {
-
-}
-
-// IPv6
-const ipv6Provider = ref('');
-const ipv6Address = ref('');
-const ipv6DetectedAddress = ref('');
-const ipv6InterfaceName = ref('');
-
-async function refreshIpv6() {
- let [error, result] = await networkModel.getIpv6Config();
- if (error) return console.error(error);
-
- ipv6Provider.value = result.provider;
- ipv6Address.value = result.ip;
- ipv6InterfaceName.value = result.ifname;
-
- [error, result] = await networkModel.getIpv6();
- if (error) return console.error(error);
-
- ipv6DetectedAddress.value = result;
-}
-
-function onIpv6Configure() {
-
-}
-
-// Firewall
-
-const blocklistLength = ref(0);
-const blocklist = ref('');
-
-function onBlocklistEdit() {
-
-}
-
-async function refreshBlocklist() {
- const [error, result] = await networkModel.getBlocklist();
- if (error) return console.error(error);
-
- blocklist.value = result;
- blocklistLength.value = result.split('\n').filter(function (l) { return l.length !== 0 && l[0] !== '#'; }).length;
-}
-
-const trustedIpsLength = ref(0);
-const trustedIps = ref('');
-
-function onTrustedIpsEdit() {
-}
-
-async function refreshTrustedIps() {
- const [error, result] = await networkModel.getTrustedIps();
- if (error) return console.error(error);
-
- trustedIps.value = result;
- trustedIpsLength.value = result.split('\n').filter(function (l) { return l.length !== 0 && l[0] !== '#'; }).length;
-}
-
-// dyndns
const dynDnsBusy = ref(false);
const dynDnsIsEnabled = ref(false);
@@ -135,11 +33,7 @@ async function onDyndnsToggle() {
}
onMounted(async () => {
- await refreshIpv4();
- await refreshIpv6();
await refreshDynDns();
- await refreshBlocklist();
- await refreshTrustedIps();
});
@@ -148,55 +42,9 @@ onMounted(async () => {
{{ $t('network.title') }}
-
- {{ $t('network.ip.description') }}
-
-
-
{{ $t('network.ip.provider') }}
-
{{ prettyIpProviderName(ipv4Provider) }}
-
-
-
{{ $t('network.ip.address') }}
-
{{ ipv4Address || `${ipv4DetectedAddress} (${$t('network.ip.detected')})` }}
-
-
-
{{ $t('network.ip.interface') }}
-
{{ ipv4InterfaceName }}
-
-
-
-
-
-
- {{ $t('network.ipv6.description') }}
-
-
-
{{ $t('network.ip.provider') }}
-
{{ prettyIpProviderName(ipv6Provider) }}
-
-
-
{{ $t('network.ip.address') }}
-
{{ ipv6Address || `${ipv6DetectedAddress} (${$t('network.ip.detected')})` }}
-
-
-
-
{{ $t('network.ip.interface') }}
-
{{ ipv6InterfaceName }}
-
-
-
-
-
-
-
-
{{ $t('network.firewall.blockedIpRanges') }}
-
{{ $t('network.firewall.blocklist', { blockCount: blocklistLength }) }}
-
-
-
{{ $t('network.trustedIpRanges') }}
-
{{ $t('network.trustedIps.summary', { trustCount: trustedIpsLength }) }}
-
-
+
+
+
{{ $t('network.dyndns.description') }}