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
This commit is contained in:
@@ -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>
|
||||||
@@ -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>
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #actions>
|
<template #actions>
|
||||||
<DialogClose>
|
<DialogClose as-child>
|
||||||
<BaseSecondaryButton>{{ $t('dialog.cancel') }}</BaseSecondaryButton>
|
<BaseSecondaryButton>{{ $t('dialog.cancel') }}</BaseSecondaryButton>
|
||||||
</DialogClose>
|
</DialogClose>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -186,6 +186,18 @@
|
|||||||
as="span"
|
as="span"
|
||||||
/>
|
/>
|
||||||
</ClientsDeleteDialog>
|
</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>
|
</FormGroup>
|
||||||
</FormElement>
|
</FormElement>
|
||||||
</PanelBody>
|
</PanelBody>
|
||||||
|
|||||||
@@ -117,7 +117,9 @@
|
|||||||
"notConnected": "Client not connected",
|
"notConnected": "Client not connected",
|
||||||
"endpoint": "Endpoint",
|
"endpoint": "Endpoint",
|
||||||
"endpointDesc": "IP of the client from which the WireGuard connection is established",
|
"endpointDesc": "IP of the client from which the WireGuard connection is established",
|
||||||
"search": "Search clients..."
|
"search": "Search clients...",
|
||||||
|
"config": "Configuration",
|
||||||
|
"viewConfig": "View Configuration"
|
||||||
},
|
},
|
||||||
"dialog": {
|
"dialog": {
|
||||||
"change": "Change",
|
"change": "Change",
|
||||||
@@ -238,6 +240,12 @@
|
|||||||
"preDown": "PreDown",
|
"preDown": "PreDown",
|
||||||
"postDown": "PostDown"
|
"postDown": "PostDown"
|
||||||
},
|
},
|
||||||
|
"copy": {
|
||||||
|
"notSupported": "Copy is not supported",
|
||||||
|
"copied": "Copied!",
|
||||||
|
"failed": "Copy failed",
|
||||||
|
"copy": "Copy"
|
||||||
|
},
|
||||||
"awg": {
|
"awg": {
|
||||||
"jCLabel": "Junk packet count (Jc)",
|
"jCLabel": "Junk packet count (Jc)",
|
||||||
"jCDescription": "Number of junk packets to send (1-128, recommended: 4-12)",
|
"jCDescription": "Number of junk packets to send (1-128, recommended: 4-12)",
|
||||||
|
|||||||
Reference in New Issue
Block a user