Files
nimbus/resources/js/components/domain/Client/Request/ShareableLinkDialog.vue
Mazen Touati 2895a0ddc6 feat(export): add shareable links (#41)
* feat(export): add shareable links

* chore: reconfigure PW

* test: fix namespace

* style: apply prettier

* chore: reduce workers count in CI for PW

tests are running slower (to the point some time out) and flaky

* fix: initialize pending request from store immediately

* chore: apply rector
2026-01-24 03:01:32 +01:00

90 lines
3.2 KiB
Vue

<script setup lang="ts">
import { AppButton } from '@/components/base/button';
import {
AppDialog,
AppDialogContent,
AppDialogDescription,
AppDialogHeader,
AppDialogTitle,
} from '@/components/base/dialog';
import { useClipboard } from '@vueuse/core';
import { Check, Copy, Link2 } from 'lucide-vue-next';
interface ShareableLinkDialogProps {
open: boolean;
link: string;
}
const props = defineProps<ShareableLinkDialogProps>();
const emits = defineEmits<{
'update:open': [value: boolean];
}>();
const { copy, copied } = useClipboard();
const copyLink = () => {
copy(props.link);
};
const closeDialog = () => {
emits('update:open', false);
};
</script>
<template>
<AppDialog :open="open" @update:open="emits('update:open', $event)">
<AppDialogContent
class="flex max-h-[90vh] max-w-2xl flex-col overflow-hidden sm:max-w-2xl"
>
<AppDialogHeader>
<AppDialogTitle class="flex items-center gap-2">
<Link2 class="size-5" />
Shareable Link
</AppDialogTitle>
<AppDialogDescription>
Share this link with your teammates to restore the exact request state
and response.
</AppDialogDescription>
</AppDialogHeader>
<div class="flex flex-1 flex-col space-y-4 overflow-hidden">
<div class="rounded-md bg-indigo-50 p-3 dark:bg-indigo-900/20">
<p class="text-sm text-indigo-800 dark:text-indigo-200">
This link contains the full request configuration and the latest
response. Anyone with this link can restore the exact state in
their Nimbus instance.
</p>
</div>
<div class="flex min-h-0 flex-1 flex-col space-y-3">
<div class="mb-2 flex items-center justify-between">
<h4 class="text-sm font-medium text-gray-700 dark:text-gray-300">
Link
</h4>
<AppButton
variant="outline"
size="sm"
class="flex items-center gap-2"
@click="copyLink"
>
<Check v-if="copied" class="h-4 w-4" />
<Copy v-else class="h-4 w-4" />
{{ copied ? 'Copied!' : 'Copy' }}
</AppButton>
</div>
<pre
class="bg-subtle-background text-foreground flex-1 overflow-auto rounded-md border p-4 font-mono text-sm leading-relaxed break-all whitespace-break-spaces"
data-testid="shareable-link-content"
>{{ link }}</pre
>
</div>
</div>
<div class="flex justify-end border-t pt-4 dark:border-gray-700">
<AppButton variant="outline" @click="closeDialog">Close</AppButton>
</div>
</AppDialogContent>
</AppDialog>
</template>