Finished translating most of the UI. Left with notifications

This commit is contained in:
Donald Zou 2024-09-19 22:32:15 +08:00
parent 17a9fe5024
commit 94bf1c2484
22 changed files with 290 additions and 90 deletions

View file

@ -1983,7 +1983,10 @@ def API_ping_getAllPeersIpAddress():
allowed_ip = p.allowed_ip.replace(" ", "").split(",")
parsed = []
for x in allowed_ip:
ip = ipaddress.ip_network(x, strict=False)
try:
ip = ipaddress.ip_network(x, strict=False)
except ValueError as e:
print(f"{p.id} - {c.Name}")
if len(list(ip.hosts())) == 1:
parsed.append(str(ip.hosts()[0]))
endpoint = p.endpoint.replace(" ", "").replace("(none)", "")
@ -2073,7 +2076,7 @@ def API_getDashboardUpdate():
htmlUrl = data.get('html_url')
if tagName is not None and htmlUrl is not None:
if tagName != DASHBOARD_VERSION:
return ResponseObject(message=f"{tagName} is now avaible for update!", data=htmlUrl)
return ResponseObject(message=f"{tagName} is now available for update!", data=htmlUrl)
else:
return ResponseObject(message="You're on the latest version")
return ResponseObject(False)

View file

@ -1,6 +1,6 @@
{
"name": "app",
"version": "4.0.2",
"version": "4.1.0",
"private": true,
"type": "module",
"scripts": {

View file

@ -2,9 +2,12 @@
import {fetchGet} from "@/utilities/fetch.js";
import {WireguardConfigurationsStore} from "@/stores/WireguardConfigurationsStore.js";
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
import LocaleText from "@/components/text/localeText.vue";
import {GetLocale} from "@/utilities/locale.js";
export default {
name: "allowedIPsInput",
components: {LocaleText},
props: {
data: Object,
saving: Boolean,
@ -30,6 +33,9 @@ export default {
this.availableIp.filter(x =>
x.includes(this.availableIpSearchString) && !this.data.allowed_ips.includes(x)) :
this.availableIp.filter(x => !this.data.allowed_ips.includes(x))
},
inputGetLocale(){
return GetLocale("Enter IP Address/CIDR")
}
},
methods: {
@ -40,7 +46,7 @@ export default {
return true;
}
this.allowedIpFormatError = true;
this.dashboardStore.newMessage('WGDashboard', 'Allowed IP is invalid', 'danger')
this.dashboardStore.newMessage('WGDashboard', 'Allowed IPs is invalid', 'danger')
return false;
}
},
@ -63,7 +69,11 @@ export default {
<template>
<div :class="{inactiveField: this.bulk}">
<label for="peer_allowed_ip_textbox" class="form-label">
<small class="text-muted">Allowed IPs <code>(Required)</code></small>
<small class="text-muted">
<LocaleText t="Allowed IPs"></LocaleText>
<code>
<LocaleText t="(Required)"></LocaleText>
</code></small>
</label>
<div class="d-flex gap-2 flex-wrap" :class="{'mb-2': this.data.allowed_ips.length > 0}">
<TransitionGroup name="list">
@ -77,7 +87,7 @@ export default {
<div class="d-flex gap-2 align-items-center">
<div class="input-group">
<input type="text" class="form-control form-control-sm rounded-start-3"
placeholder="Enter IP Address/CIDR"
:placeholder="this.inputGetLocale"
:class="{'is-invalid': this.allowedIpFormatError}"
v-model="customAvailableIp"
:disabled="bulk">
@ -88,23 +98,29 @@ export default {
<i class="bi bi-plus-lg"></i>
</button>
</div>
<small class="text-muted">or</small>
<small class="text-muted">
<LocaleText t="or"></LocaleText>
</small>
<div class="dropdown flex-grow-1">
<button class="btn btn-outline-secondary btn-sm dropdown-toggle rounded-3 w-100"
:disabled="!availableIp || bulk"
data-bs-auto-close="outside"
type="button" data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-filter-circle me-2"></i>
Pick Available IP
<LocaleText t="Pick Available IP"></LocaleText>
</button>
<ul class="dropdown-menu mt-2 shadow w-100 dropdown-menu-end rounded-3"
v-if="this.availableIp"
style="overflow-y: scroll; max-height: 270px; width: 300px !important;">
<li>
<div class="px-3 pb-2 pt-1">
<input class="form-control form-control-sm rounded-3"
v-model="this.availableIpSearchString"
placeholder="Search...">
<div class="px-3 pb-2 pt-1 d-flex gap-3 align-items-center">
<label for="availableIpSearchString" class="text-muted">
<i class="bi bi-search"></i>
</label>
<input
id="availableIpSearchString"
class="form-control form-control-sm rounded-3"
v-model="this.availableIpSearchString">
</div>
</li>
<li v-for="ip in this.searchAvailableIps" >
@ -113,7 +129,9 @@ export default {
</a>
</li>
<li v-if="this.searchAvailableIps.length === 0">
<small class="px-3 text-muted">No available IP containing "{{this.availableIpSearchString}}"</small>
<small class="px-3 text-muted">
<LocaleText t="No available IP containing"></LocaleText>
"{{this.availableIpSearchString}}"</small>
</li>
</ul>
</div>

View file

@ -1,10 +1,19 @@
<script>
import LocaleText from "@/components/text/localeText.vue";
import {GetLocale} from "@/utilities/locale.js";
export default {
name: "bulkAdd",
components: {LocaleText},
props: {
saving: Boolean,
data: Object,
availableIp: undefined
},
computed:{
bulkAddGetLocale(){
return GetLocale("How many peers you want to add?")
}
}
}
</script>
@ -17,20 +26,22 @@ export default {
:disabled="!this.availableIp"
id="bulk_add" v-model="this.data.bulkAdd">
<label class="form-check-label me-2" for="bulk_add">
<small><strong>Bulk Add</strong></small>
<small><strong>
<LocaleText t="Bulk Add"></LocaleText>
</strong></small>
</label>
</div>
<p :class="{'mb-0': !this.data.bulkAdd}"><small class="text-muted d-block">
By adding peers by bulk, each peer's name will be auto generated, and Allowed IP will be assign to the next available IP.
<LocaleText t="By adding peers by bulk, each peer's name will be auto generated, and Allowed IP will be assign to the next available IP."></LocaleText>
</small></p>
<div class="form-group" v-if="this.data.bulkAdd">
<input class="form-control form-control-sm rounded-3 mb-1" type="number" min="1"
:max="this.availableIp.length"
v-model="this.data.bulkAddAmount"
placeholder="How many peers you want to add?">
:placeholder="this.bulkAddGetLocale">
<small class="text-muted">
You can add up to <strong>{{this.availableIp.length}}</strong> peers
<LocaleText :t="`You can add up to ` + this.availableIp.length + ' peers'"></LocaleText>
</small>
</div>
</div>

View file

@ -1,9 +1,11 @@
<script>
import {WireguardConfigurationsStore} from "@/stores/WireguardConfigurationsStore.js";
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
import LocaleText from "@/components/text/localeText.vue";
export default {
name: "dnsInput",
components: {LocaleText},
props: {
data: Object,
@ -50,7 +52,9 @@ export default {
<template>
<div>
<label for="peer_DNS_textbox" class="form-label">
<small class="text-muted">DNS</small>
<small class="text-muted">
<LocaleText t="DNS"></LocaleText>
</small>
</label>
<input type="text" class="form-control form-control-sm rounded-3"
:class="{'is-invalid': this.error}"

View file

@ -1,9 +1,11 @@
<script>
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
import {WireguardConfigurationsStore} from "@/stores/WireguardConfigurationsStore.js";
import LocaleText from "@/components/text/localeText.vue";
export default {
name: "endpointAllowedIps",
components: {LocaleText},
props: {
data: Object,
saving: Boolean
@ -47,7 +49,11 @@ export default {
<template>
<div>
<label for="peer_endpoint_allowed_ips" class="form-label">
<small class="text-muted">Endpoint Allowed IPs <code>(Required)</code></small>
<small class="text-muted">
<LocaleText t="Endpoint Allowed IPs"></LocaleText>
<code>
<LocaleText t="(Required)"></LocaleText>
</code></small>
</label>
<input type="text" class="form-control form-control-sm rounded-3"
:class="{'is-invalid': error}"

View file

@ -1,6 +1,9 @@
<script>
import LocaleText from "@/components/text/localeText.vue";
export default {
name: "mtuInput",
components: {LocaleText},
props: {
data: Object,
saving: Boolean
@ -10,7 +13,9 @@ export default {
<template>
<div>
<label for="peer_mtu" class="form-label"><small class="text-muted">MTU</small></label>
<label for="peer_mtu" class="form-label"><small class="text-muted">
<LocaleText t="MTU"></LocaleText>
</small></label>
<input type="number" class="form-control form-control-sm rounded-3"
:disabled="this.saving"
v-model="this.data.mtu"

View file

@ -1,6 +1,9 @@
<script>
import LocaleText from "@/components/text/localeText.vue";
export default {
name: "nameInput",
components: {LocaleText},
props: {
bulk: Boolean,
data: Object,
@ -12,7 +15,9 @@ export default {
<template>
<div :class="{inactiveField: this.bulk}">
<label for="peer_name_textbox" class="form-label">
<small class="text-muted">Name</small>
<small class="text-muted">
<LocaleText t="Name"></LocaleText>
</small>
</label>
<input type="text" class="form-control form-control-sm rounded-3"
:disabled="this.saving || this.bulk"

View file

@ -1,6 +1,9 @@
<script>
import LocaleText from "@/components/text/localeText.vue";
export default {
name: "persistentKeepAliveInput",
components: {LocaleText},
props: {
data: Object,
saving: Boolean
@ -11,7 +14,9 @@ export default {
<template>
<div>
<label for="peer_keep_alive" class="form-label">
<small class="text-muted">Persistent Keepalive</small>
<small class="text-muted">
<LocaleText t="Persistent Keepalive"></LocaleText>
</small>
</label>
<input type="number" class="form-control form-control-sm rounded-3"
:disabled="this.saving"

View file

@ -1,6 +1,9 @@
<script>
import LocaleText from "@/components/text/localeText.vue";
export default {
name: "presharedKeyInput",
components: {LocaleText},
props: {
data: Object,
saving: Boolean
@ -26,7 +29,9 @@ export default {
<div>
<div class="d-flex align-items-start">
<label for="peer_preshared_key_textbox" class="form-label">
<small class="text-muted">Pre-Shared Key</small>
<small class="text-muted">
<LocaleText t="Pre-Shared Key"></LocaleText>
</small>
</label>
<div class="form-check form-switch ms-auto">
<input class="form-check-input" type="checkbox" role="switch"

View file

@ -1,8 +1,10 @@
<script>
import "@/utilities/wireguard.js"
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
import LocaleText from "@/components/text/localeText.vue";
export default {
name: "privatePublicKeyInput",
components: {LocaleText},
props: {
data: Object,
saving: Boolean,
@ -75,7 +77,11 @@ export default {
<div class="d-flex gap-2 flex-column" :class="{inactiveField: this.bulk}">
<div>
<label for="peer_private_key_textbox" class="form-label">
<small class="text-muted">Private Key <code>(Required for QR Code and Download)</code></small>
<small class="text-muted">
<LocaleText t="Private Key"></LocaleText>
<code>
<LocaleText t="(Required for QR Code and Download)"></LocaleText>
</code></small>
</label>
<div class="input-group">
<input type="text" class="form-control form-control-sm rounded-start-3"
@ -94,14 +100,20 @@ export default {
<div>
<div class="d-flex">
<label for="public_key" class="form-label">
<small class="text-muted">Public Key <code>(Required)</code></small>
<small class="text-muted">
<LocaleText t="Public Key"></LocaleText>
<code>
<LocaleText t="(Required)"></LocaleText>
</code></small>
</label>
<div class="form-check form-switch ms-auto">
<input class="form-check-input" type="checkbox" role="switch"
:disabled="this.bulk"
id="enablePublicKeyEdit" v-model="this.editKey">
<label class="form-check-label" for="enablePublicKeyEdit">
<small>Edit</small>
<small>
<LocaleText t="Use your own Private and Public Key"></LocaleText>
</small>
</label>
</div>
</div>

View file

@ -12,10 +12,12 @@ import PersistentKeepAliveInput
from "@/components/configurationComponents/newPeersComponents/persistentKeepAliveInput.vue";
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
import BulkAdd from "@/components/configurationComponents/newPeersComponents/bulkAdd.vue";
import LocaleText from "@/components/text/localeText.vue";
export default {
name: "peerCreate",
components: {
LocaleText,
BulkAdd,
PersistentKeepAliveInput,
MtuInput,
@ -107,7 +109,9 @@ export default {
<h3 class="mb-0 text-body">
<i class="bi bi-chevron-left"></i>
</h3>
<h3 class="text-body mb-0">Add Peers</h3>
<h3 class="text-body mb-0">
<LocaleText t="Add Peers"></LocaleText>
</h3>
</RouterLink>
</div>
<div class="d-flex flex-column gap-2">
@ -137,8 +141,11 @@ export default {
v-model="this.data.preshared_key_bulkAdd"
id="bullAdd_PresharedKey_Switch" checked>
<label class="form-check-label" for="bullAdd_PresharedKey_Switch">
Pre-Share Key
{{this.data.preshared_key_bulkAdd ? "Enabled":"Disabled"}}
<small class="fw-bold">
<LocaleText t="Pre-Shared Key"></LocaleText>
<LocaleText t="Enabled" v-if="this.data.preshared_key_bulkAdd"></LocaleText>
<LocaleText t="Disabled" v-else></LocaleText>
</small>
</label>
</div>
</div>
@ -149,7 +156,8 @@ export default {
@click="this.peerCreate()"
>
<i class="bi bi-plus-circle-fill me-2" v-if="!this.saving"></i>
{{this.saving ? 'Saving...': 'Add'}}
<LocaleText t="Adding..." v-if="this.saving"></LocaleText>
<LocaleText t="Add" v-else></LocaleText>
</button>
</div>
</div>

View file

@ -176,8 +176,7 @@ export default {
}, (res) => {
if (res.status){
this.dashboardConfigurationStore.newMessage("Server",
`${this.configurationInfo.Name} is
${res.data ? 'is on':'is off'}`, "Success")
`${this.configurationInfo.Name} ${res.data ? 'is on':'is off'}`, "success")
}else{
this.dashboardConfigurationStore.newMessage("Server",
res.message, 'danger')
@ -427,8 +426,13 @@ export default {
</small></p>
<div class="form-check form-switch ms-auto">
<label class="form-check-label" style="cursor: pointer" :for="'switch' + this.configurationInfo.id">
<LocaleText t="On" v-if="this.configurationInfo.Status"></LocaleText>
<LocaleText t="Off" v-else></LocaleText>
<LocaleText t="Turning Off..." v-if="!this.configurationInfo.Status && this.configurationToggling"></LocaleText>
<LocaleText t="Turning On..." v-else-if="this.configurationInfo.Status && this.configurationToggling"></LocaleText>
<LocaleText t="On" v-else-if="this.configurationInfo.Status && !this.configurationToggling"></LocaleText>
<LocaleText t="Off" v-else-if="!this.configurationInfo.Status && !this.configurationToggling"></LocaleText>
<span v-if="this.configurationToggling"
class="spinner-border spinner-border-sm ms-2" aria-hidden="true"></span>
</label>

View file

@ -122,7 +122,7 @@ export default {
<a class="dropdown-item d-flex" role="button"
@click="this.$emit('jobs')"
>
<i class="me-auto bi bi-app-indicator"></i> Schedule Jobs
<i class="me-auto bi bi-app-indicator"></i> <LocaleText t="Schedule Jobs"></LocaleText>
</a>
</li>
@ -133,7 +133,10 @@ export default {
@click="this.restrictPeer()"
:class="{disabled: this.restrictBtnDisabled}"
role="button">
<i class="me-auto bi bi-lock"></i> {{!this.restrictBtnDisabled ? "Restrict Access":"Restricting..."}}
<i class="me-auto bi bi-lock"></i>
<LocaleText t="Restrict Access" v-if="!this.restrictBtnDisabled"></LocaleText>
<LocaleText t="Restricting..." v-else></LocaleText>
</a>
</li>
<li>
@ -141,7 +144,9 @@ export default {
@click="this.deletePeer()"
:class="{disabled: this.deleteBtnDisabled}"
role="button">
<i class="me-auto bi bi-trash"></i> {{!this.deleteBtnDisabled ? "Delete":"Deleting..."}}
<i class="me-auto bi bi-trash"></i>
<LocaleText t="Delete" v-if="!this.deleteBtnDisabled"></LocaleText>
<LocaleText t="Deleting..." v-else></LocaleText>
</a>
</li>
</template>
@ -149,10 +154,12 @@ export default {
<li>
<a class="dropdown-item d-flex text-warning"
@click="this.allowAccessPeer()"
:class="{disabled: this.restrictBtnDisabled}"
:class="{disabled: this.allowAccessBtnDisabled}"
role="button">
<i class="me-auto bi bi-unlock"></i>
{{!this.allowAccessBtnDisabled ? "Allow Access":"Allowing..."}}
<i class="me-auto bi bi-unlock"></i>
<LocaleText t="Allow Access" v-if="!this.allowAccessBtnDisabled"></LocaleText>
<LocaleText t="Allowing Access..." v-else></LocaleText>
</a>
</li>
</template>

View file

@ -1,9 +1,11 @@
<script>
import {fetchGet} from "@/utilities/fetch.js";
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
import LocaleText from "@/components/text/localeText.vue";
export default {
name: "configurationCard",
components: {LocaleText},
props: {
c: {
Name: String,
@ -63,22 +65,30 @@ export default {
<i class="bi bi-arrow-up me-2"></i>{{c.DataUsage.Sent > 0 ? c.DataUsage.Sent.toFixed(4) : 0}} GB
</small>
<small class="text-md-end col-6 col-md-3">
<span class="dot me-2" :class="{active: c.ConnectedPeers > 0}"></span>{{c.ConnectedPeers}} Peers
<span class="dot me-2" :class="{active: c.ConnectedPeers > 0}"></span>{{c.ConnectedPeers}}
<LocaleText t="Peers"></LocaleText>
</small>
</div>
<div class="d-flex align-items-center gap-2">
<small class="text-muted">
<strong style="word-break: keep-all">Public Key</strong>
<strong style="word-break: keep-all">
<LocaleText t="Public Key"></LocaleText>
</strong>
</small>
<small class="mb-0 d-block d-lg-inline-block ">
<samp style="line-break: anywhere">{{c.PublicKey}}</samp>
</small>
<div class="form-check form-switch ms-auto">
<label class="form-check-label" style="cursor: pointer" :for="'switch' + c.PrivateKey">
{{this.configurationToggling ? 'Turning ':''}}
{{c.Status ? "On":"Off"}}
<LocaleText t="Turning Off..." v-if="!c.Status && this.configurationToggling"></LocaleText>
<LocaleText t="Turning On..." v-else-if="c.Status && this.configurationToggling"></LocaleText>
<LocaleText t="On" v-else-if="c.Status && !this.configurationToggling"></LocaleText>
<LocaleText t="Off" v-else-if="!c.Status && !this.configurationToggling"></LocaleText>
<span v-if="this.configurationToggling"
class="spinner-border spinner-border-sm" aria-hidden="true"></span>
class="spinner-border spinner-border-sm ms-2" aria-hidden="true"></span>
</label>
<input class="form-check-input"
style="cursor: pointer"

View file

@ -1,6 +1,9 @@
<script>
import LocaleText from "@/components/text/localeText.vue";
export default {
name: "message",
components: {LocaleText},
props: {
message: Object
},
@ -21,7 +24,9 @@ export default {
:id="this.message.id"
style="width: 400px">
<div class="card-body">
<small class="fw-bold d-block" style="text-transform: uppercase">FROM {{this.message.from}}</small>
<small class="fw-bold d-block" style="text-transform: uppercase">
<LocaleText t="FROM "></LocaleText>
{{this.message.from}}</small>
{{this.message.content}}
</div>
</div>

View file

@ -4,6 +4,7 @@ import {WireguardConfigurationsStore} from "@/stores/WireguardConfigurationsStor
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
import {fetchGet} from "@/utilities/fetch.js";
import LocaleText from "@/components/text/localeText.vue";
import {GetLocale} from "@/utilities/locale.js";
export default {
name: "navbar",
@ -29,7 +30,7 @@ export default {
}
this.updateMessage = res.message
}else{
this.updateMessage = "Failed to check available update"
this.updateMessage = GetLocale("Failed to check available update")
console.log(`Failed to get update: ${res.message}`)
}
})
@ -95,14 +96,15 @@ export default {
</a>
</li>
<li class="nav-item" style="font-size: 0.8rem">
<a :href="this.updateUrl" v-if="this.updateAvailable" class="text-decoration-none" target="_blank">
<a :href="this.updateUrl" v-if="this.updateAvailable" class="text-decoration-none rounded-3" target="_blank">
<small class="nav-link text-muted rounded-3" >
<LocaleText :t="this.updateMessage"></LocaleText>
(<LocaleText t="Current Version:"></LocaleText> {{ dashboardConfigurationStore.Configuration.Server.version }})
</small>
</a>
<small class="nav-link text-muted" v-else>
<small class="nav-link text-muted rounded-3" v-else>
<LocaleText :t="this.updateMessage"></LocaleText>
({{ dashboardConfigurationStore.Configuration.Server.version}})
({{ dashboardConfigurationStore.Configuration.Server.version }})
</small>
</li>
</ul>

View file

@ -2,9 +2,11 @@
import {fetchGet, fetchPost} from "@/utilities/fetch.js";
import QRCode from "qrcode";
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
import LocaleText from "@/components/text/localeText.vue";
export default {
name: "totp",
components: {LocaleText},
async setup(){
const store = DashboardConfigurationStore();
let l = ""
@ -65,14 +67,25 @@ export default {
<div class="m-auto text-body" style="width: 500px">
<div class="d-flex flex-column">
<div>
<h1 class="dashboardLogo display-4">Multi-Factor Authentication</h1>
<p class="mb-2"><small class="text-muted">1. Please scan the following QR Code to generate TOTP</small></p>
<h1 class="dashboardLogo display-4">
<LocaleText t="Multi-Factor Authentication (MFA)"></LocaleText>
</h1>
<p class="mb-2"><small class="text-muted">
<LocaleText t="1. Please scan the following QR Code to generate TOTP with your choice of authenticator"></LocaleText>
</small></p>
<canvas id="qrcode" class="rounded-3 mb-2"></canvas>
<div class="p-3 bg-body-secondary rounded-3 border mb-3">
<p class="text-muted mb-0"><small>Or you can click the link below:</small>
<p class="text-muted mb-0">
<small>
<LocaleText t="Or you can click the link below:"></LocaleText>
</small>
</p><a :href="this.l"><code style="line-break: anywhere">{{this.l}}</code></a>
</div>
<label for="totp" class="mb-2"><small class="text-muted">2. Enter the TOTP generated by your authenticator to verify</small></label>
<label for="totp" class="mb-2">
<small class="text-muted">
<LocaleText t="2. Enter the TOTP generated by your authenticator to verify"></LocaleText>
</small>
</label>
<div class="form-group mb-2">
<input class="form-control text-center totp"
id="totp" maxlength="6" type="text" inputmode="numeric" autocomplete="one-time-code"
@ -80,16 +93,12 @@ export default {
:disabled="this.verified"
>
<div class="invalid-feedback">
{{this.totpInvalidMessage}}
<LocaleText :t="this.totpInvalidMessage"></LocaleText>
</div>
<div class="valid-feedback">
TOTP verified!
<LocaleText t="TOTP verified!"></LocaleText>
</div>
</div>
<div class="alert alert-warning rounded-3">
<i class="bi bi-exclamation-triangle-fill me-2"></i> If you ever lost your TOTP and can't login, please follow instruction on
<a href="https://github.com/donaldzou/WGDashboard" target="_blank">readme.md</a> to reset.
</div>
</div>
<hr>
<div class="d-flex gap-3 mt-5 flex-column">
@ -99,12 +108,14 @@ export default {
class="btn bg-secondary-subtle text-secondary-emphasis
rounded-3
flex-grow-1 btn-lg border-1 border-secondary-subtle shadow d-flex">
I don't need MFA <i class="bi bi-chevron-right ms-auto"></i>
<LocaleText t="I don't need MFA"></LocaleText>
<i class="bi bi-chevron-right ms-auto"></i>
</RouterLink>
<RouterLink
to="/"
v-else class="btn btn-dark btn-lg d-flex btn-brand shadow align-items-center flex-grow-1 rounded-3">
Complete <i class="bi bi-chevron-right ms-auto"></i>
<LocaleText t="Complete"></LocaleText>
<i class="bi bi-chevron-right ms-auto"></i>
</RouterLink>
</div>
</div>

View file

@ -9,7 +9,7 @@ export default {
},
computed: {
getLocaleText(){
return GetLocale(this.placeholder)
return GetLocale('OTP from your authenticator')
}
}
}
@ -19,7 +19,7 @@ export default {
<input class="form-control totp"
required
id="totp" maxlength="6" type="text" inputmode="numeric" autocomplete="one-time-code"
:placeholder="this.getLocaleText('OTP from your authenticator')"
:placeholder="this.getLocaleText"
v-model="this.data.totp"
>
</template>

View file

@ -1,9 +1,10 @@
<script>
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
import {fetchPost} from "@/utilities/fetch.js";
import LocaleText from "@/components/text/localeText.vue";
export default {
name: "setup",
components: {},
components: {LocaleText},
setup(){
const store = DashboardConfigurationStore();
return {store}
@ -57,37 +58,57 @@ export default {
<div class="container-fluid login-container-fluid d-flex main pt-5 overflow-scroll"
:data-bs-theme="this.store.Configuration.Server.dashboard_theme">
<div class="m-auto text-body" style="width: 500px">
<span class="dashboardLogo display-4">Nice to meet you!</span>
<p class="mb-5">Please fill in the following fields to finish setup 😊</p>
<span class="dashboardLogo display-4">
<LocaleText t="Nice to meet you!"></LocaleText>
</span>
<p class="mb-5">
<LocaleText t="Please fill in the following fields to finish setup"></LocaleText>
😊</p>
<div>
<h3>Create an account</h3>
<h3>
<LocaleText t="Create an account"></LocaleText>
</h3>
<div class="alert alert-danger" v-if="this.errorMessage">
{{this.errorMessage}}
</div>
<div class="d-flex flex-column gap-3">
<div id="createAccount" class="d-flex flex-column gap-2">
<form id="createAccount" class="d-flex flex-column gap-2">
<div class="form-group text-body">
<label for="username" class="mb-1 text-muted">
<small>Pick an username you like</small></label>
<small>
<LocaleText t="Enter an username you like"></LocaleText>
</small></label>
<input type="text"
autocomplete="username"
v-model="this.setup.username"
class="form-control" id="username" name="username" placeholder="Maybe something like 'wiredragon'?" required>
class="form-control" id="username" name="username" required>
</div>
<div class="form-group text-body">
<label for="password" class="mb-1 text-muted">
<small>Create a password (at least 8 characters)</small></label>
<small>
<LocaleText t="Enter a password"></LocaleText>
<code>
<LocaleText t="(At least 8 characters and make sure is strong enough!)"></LocaleText>
</code>
</small>
</label>
<input type="password"
autocomplete="new-password"
v-model="this.setup.newPassword"
class="form-control" id="password" name="password" placeholder="Make sure is strong enough" required>
class="form-control" id="password" name="password" required>
</div>
<div class="form-group text-body">
<label for="confirmPassword" class="mb-1 text-muted">
<small>Confirm password</small></label>
<small>
<LocaleText t="Confirm password"></LocaleText>
</small>
</label>
<input type="password"
autocomplete="confirm-new-password"
v-model="this.setup.repeatNewPassword"
class="form-control" id="confirmPassword" name="confirmPassword" placeholder="and you can remember it :)" required>
class="form-control" id="confirmPassword" name="confirmPassword" required>
</div>
</div>
</form>
<!-- <div class="form-check form-switch">-->
<!-- <input class="form-check-input" type="checkbox" role="switch" id="enable_totp" -->
<!-- v-model="this.setup.enable_totp">-->
@ -104,9 +125,12 @@ export default {
ref="signInBtn"
:disabled="!this.goodToSubmit || this.loading || this.done" @click="this.submit()">
<span class="d-flex align-items-center w-100" v-if="!this.loading && !this.done">
Next<i class="bi bi-chevron-right ms-auto"></i></span>
<LocaleText t="Next"></LocaleText>
<i class="bi bi-chevron-right ms-auto"></i></span>
<span class="d-flex align-items-center w-100" v-else>
Saving...<span class="spinner-border ms-auto spinner-border-sm" role="status">
<LocaleText t="Saving..."></LocaleText>
<span class="spinner-border ms-auto spinner-border-sm" role="status">
<span class="visually-hidden">Loading...</span>
</span></span>
</button>

View file

@ -4,15 +4,17 @@ import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.
import {fetchGet} from "@/utilities/fetch.js";
import {ref} from "vue";
import QRCode from "qrcode";
import LocaleText from "@/components/text/localeText.vue";
export default {
name: "share",
components: {LocaleText},
async setup(){
const route = useRoute();
const loaded = ref(false)
const store = DashboardConfigurationStore();
const theme = ref("");
const peerConfiguration = ref("");
const peerConfiguration = ref(undefined);
const blob = ref(new Blob())
await fetchGet("/api/getDashboardTheme", {}, (res) => {
theme.value = res.data
@ -38,9 +40,11 @@ export default {
return {store, theme, peerConfiguration, blob}
},
mounted() {
QRCode.toCanvas(document.querySelector("#qrcode"), this.peerConfiguration.file , (error) => {
if (error) console.error(error)
})
if(this.peerConfiguration){
QRCode.toCanvas(document.querySelector("#qrcode"), this.peerConfiguration.file, (error) => {
if (error) console.error(error)
})
}
},
methods:{
download(){
@ -76,18 +80,23 @@ export default {
<div class="position-absolute w-100 h-100 top-0 start-0 d-flex animate__animated animate__fadeInUp"
style="animation-delay: 0.1s;"
>
<h3 class="m-auto">Oh no... This link is either expired or invalid.</h3>
<h3 class="m-auto">
<LocaleText t="Oh no... This link is either expired or invalid."></LocaleText>
</h3>
</div>
</div>
<div v-else class="d-flex align-items-center flex-column gap-3">
<div class="h1 dashboardLogo text-center animate__animated animate__fadeInUp">
<h6>WGDashboard</h6>
Scan QR Code from the WireGuard App
<LocaleText t="Scan QR Code with the WireGuard App to add peer"></LocaleText>
</div>
<canvas id="qrcode" class="rounded-3 shadow animate__animated animate__fadeInUp mb-3" ref="qrcode"></canvas>
<p class="text-muted animate__animated animate__fadeInUp mb-1"
style="animation-delay: 0.2s;"
>or click the button below to download the <samp>.conf</samp> file</p>
style="animation-delay: 0.2s;">
<LocaleText t="or click the button below to download the "></LocaleText>
<samp>.conf</samp>
<LocaleText t=" file"></LocaleText>
</p>
<a
:download="this.peerConfiguration.fileName + '.conf'"
:href="getBlob"

View file

@ -2,7 +2,7 @@
"Welcome to": "欢迎来到",
"Username": "用户名",
"Password": "密码",
"OTP from your authenticator": "您双因素身份验证的一次性验证码",
"OTP from your authenticator": "您多重身份验证器的一次性验证码",
"Sign In": "登录",
"Signing In\\.\\.\\.": "正在登录...",
"Access Remote Server": "访问远程服务器",
@ -35,7 +35,7 @@
"New Password": "新密码",
"Repeat New Password": "重复新密码",
"Update Password": "更新密码",
"Multi-Factor Authentication \\(MFA\\)": "多重身份验证MFA)",
"Multi-Factor Authentication \\(MFA\\)": "多重身份验证 (MFA)",
"Reset": "重置",
"Setup": "设置",
"API Keys": "API 秘钥",
@ -55,6 +55,8 @@
"Status": "状态",
"On": "已启用",
"Off": "已停用",
"Turning On\\.\\.\\.": "启用中...",
"Turning Off\\.\\.\\.": "停用中...",
"Address": "网络地址",
"Listen Port": "监听端口",
"Public Key": "公钥",
@ -66,13 +68,14 @@
"Real Time Received Data Usage": "实时接收数据量",
"Real Time Sent Data Usage": "实时发送数据量",
"Peer": "端点",
"Peers": "端点",
"Peer Settings": "端点设定",
"Download All": "全部下载",
"Search Peers\\.\\.\\.": "搜索端点...",
"Display": "显示设置",
"Sort By": "排列方式",
"Refresh Interval": "刷新间隔",
"Name": "名",
"Name": "名",
"Allowed IPs": "允许的 IP 地址",
"Restricted": "已限制端点",
"(.*) Seconds": "$1 秒",
@ -112,6 +115,7 @@
"Delete Peer": "删除端点",
"Edit": "编辑",
"Delete": "删除",
"Deleting...": "删除中...",
"Cancel": "取消",
"Save": "保存",
"No active job at the moment\\.": "没有未运行的任务",
@ -130,5 +134,47 @@
"Stop Sharing\\.\\.\\.": "停止分享中...",
"Stop Sharing": "停止分享",
"Access Restricted": "已限制访问",
"Download \\& QR Code is not available due to no private key set for this peer": "下载以及二维码功能不可用,需要填写此端点的秘钥"
"Restrict Access": "限制访问",
"Restricting\\.\\.\\.": "限制访问中...",
"Allow Access": "解除限制访问",
"Allowing Access\\.\\.\\.": "解除限制访问中...",
"Download \\& QR Code is not available due to no private key set for this peer": "下载以及二维码功能不可用,需要填写此端点的秘钥",
"Add Peers": "创建端点",
"Bulk Add": "批量添加",
"By adding peers by bulk, each peer's name will be auto generated, and Allowed IP will be assign to the next available IP\\.": "如果选择批量添加端点,系统会自动生成每一个端点的名称,并且会自动安排可用的 IP 地址。",
"How many peers you want to add\\?": "您想添加多少个端点?",
"You can add up to (.*) peers": "您最多可以添加 $1 个端点",
"Use your own Private and Public Key": "使用您自己的秘钥和公钥",
"Enter IP Address/CIDR": "输入 IP 地址/前缀长度",
"or": "或",
"Pick Available IP": "选择可用的 IP 地址",
"No available IP containing": "没有可用的 IP 地址含有 ",
"Add": "创建",
"Adding\\.\\.\\.": "创建中...",
"Failed to check available update": "获取更新失败",
"Nice to meet you!": "很高兴见到您!",
"Please fill in the following fields to finish setup": "请填入以下信息来完成初始化设置",
"Create an account": "创建账户",
"Enter an username you like": "输入一个您喜欢的用户名",
"Enter a password": "输入密码",
"\\(At least 8 characters and make sure is strong enough!\\)": "(至少8个字符或以上并且确保它足够复杂哟!)",
"Confirm password": "确认密码",
"Next": "下一步",
"Saving\\.\\.\\.": "保存中...",
"1\\. Please scan the following QR Code to generate TOTP with your choice of authenticator": "1. 请使用您选择的验证器扫描以下二维码来生成一次性验证码",
"Or you can click the link below:": "或者您可以点击以下链接:",
"2\\. Enter the TOTP generated by your authenticator to verify": "2. 请输入验证器生成的一次性验证码进行验证",
"TOTP verified!": "一次性验证码验证成功!",
"I don't need MFA": "我不需要多重身份验证 (MFA)",
"Complete": "完成",
"(v[0-9.]{1,}) is now available for update!": "有新版本 $1 可更新!",
"Current Version:": "当前版本: ",
"Oh no\\.\\.\\. This link is either expired or invalid\\.": "噢不!此链接已过期或不正确。",
"Scan QR Code with the WireGuard App to add peer": "使用 WireGuard APP 扫描以下二维码来添加端点",
"or click the button below to download the ": "或点击下面的按钮下载 ",
" file": " 文件",
"FROM ": "来自 ",
"(.*) is on": "$1 已启用",
"(.*) is off": "$1 已停用",
"Allowed IPs is invalid": "允许的 IP 地址错误"
}