Browse Source

feat: add config btn and modal to view and copy config (#2289)

* add view config btn and modal

* show loading state

* add note about keyboard
pull/2293/head
Bernd Storath 7 months ago
committed by GitHub
parent
commit
4e4bfc75e3
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 29
      src/app/components/Base/CodeBlock.vue
  2. 74
      src/app/components/Clients/ConfigDialog.vue
  3. 2
      src/app/components/Clients/QRCodeDialog.vue
  4. 12
      src/app/pages/clients/[id].vue
  5. 10
      src/i18n/locales/en.json

29
src/app/components/Base/CodeBlock.vue

@ -0,0 +1,29 @@
<template>
<div class="overflow-x-auto rounded border-2 border-red-800 py-2">
<pre
class="mx-2 inline-block"
@click="selectCode"
><code ref="codeBlock">{{ code }}</code></pre>
</div>
</template>
<script setup lang="ts">
defineProps<{
code: string;
}>();
const codeBlock = useTemplateRef('codeBlock');
function selectCode() {
// TODO: keyboard support?
if (codeBlock.value) {
const range = document.createRange();
range.selectNodeContents(codeBlock.value);
const sel = window.getSelection();
if (sel) {
sel.removeAllRanges();
sel.addRange(range);
}
}
}
</script>

74
src/app/components/Clients/ConfigDialog.vue

@ -0,0 +1,74 @@
<template>
<BaseDialog :trigger-class="triggerClass">
<template #trigger>
<slot />
</template>
<template #title>
{{ $t('client.config') }}
</template>
<template #description>
<div v-if="status === 'success'">
<BaseCodeBlock :code="config ?? ''" />
</div>
<div v-else>
<span>{{ $t('general.loading') }}</span>
</div>
</template>
<template #actions>
<DialogClose as-child>
<BaseSecondaryButton>{{ $t('dialog.cancel') }}</BaseSecondaryButton>
</DialogClose>
<DialogClose as-child>
<BasePrimaryButton @click="copyCode">
{{ $t('copy.copy') }}
</BasePrimaryButton>
</DialogClose>
</template>
</BaseDialog>
</template>
<script setup lang="ts">
const props = defineProps<{ triggerClass?: string; clientId: number }>();
const toast = useToast();
const { copied, copy, isSupported } = useClipboard({
// fallback does not work
legacy: false,
});
const { data: config, status } = useFetch(
`/api/client/${props.clientId}/configuration`,
{
responseType: 'text',
server: false,
}
);
async function copyCode() {
if (status.value !== 'success') {
return;
}
if (!isSupported.value) {
toast.showToast({
type: 'error',
message: $t('copy.notSupported'),
});
return;
}
await copy(config.value ?? '');
if (copied.value) {
toast.showToast({
type: 'success',
message: $t('copy.copied'),
});
} else {
toast.showToast({
type: 'error',
message: $t('copy.failed'),
});
}
}
</script>

2
src/app/components/Clients/QRCodeDialog.vue

@ -9,7 +9,7 @@
</div>
</template>
<template #actions>
<DialogClose>
<DialogClose as-child>
<BaseSecondaryButton>{{ $t('dialog.cancel') }}</BaseSecondaryButton>
</DialogClose>
</template>

12
src/app/pages/clients/[id].vue

@ -186,6 +186,18 @@
as="span"
/>
</ClientsDeleteDialog>
<ClientsConfigDialog
trigger-class="col-span-2"
:client-id="data.id"
>
<FormSecondaryActionField
:label="$t('client.viewConfig')"
class="w-full"
type="button"
tabindex="-1"
as="span"
/>
</ClientsConfigDialog>
</FormGroup>
</FormElement>
</PanelBody>

10
src/i18n/locales/en.json

@ -117,7 +117,9 @@
"notConnected": "Client not connected",
"endpoint": "Endpoint",
"endpointDesc": "IP of the client from which the WireGuard connection is established",
"search": "Search clients..."
"search": "Search clients...",
"config": "Configuration",
"viewConfig": "View Configuration"
},
"dialog": {
"change": "Change",
@ -238,6 +240,12 @@
"preDown": "PreDown",
"postDown": "PostDown"
},
"copy": {
"notSupported": "Copy is not supported",
"copied": "Copied!",
"failed": "Copy failed",
"copy": "Copy"
},
"awg": {
"jCLabel": "Junk packet count (Jc)",
"jCDescription": "Number of junk packets to send (1-128, recommended: 4-12)",

Loading…
Cancel
Save