Remove external link dialog

This commit is contained in:
andrewwallacespeckle
2025-07-22 14:03:35 +01:00
parent 154d935089
commit 28e4ecc8dc
7 changed files with 2 additions and 111 deletions
@@ -5,7 +5,7 @@
no-shadow
class="mx-auto w-full"
>
<div class="flex flex-col gap-4" data-no-external-confirm>
<div class="flex flex-col gap-4">
<div v-if="!workspaceInvite" class="flex flex-col items-center gap-y-2 pb-4">
<h1 class="text-heading-xl text-center inline-block">
{{ title }}
@@ -1,7 +1,7 @@
<!-- eslint-disable vuejs-accessibility/no-static-element-interactions -->
<!-- eslint-disable vuejs-accessibility/click-events-have-key-events -->
<template>
<div class="group h-full" data-no-external-confirm>
<div class="group h-full">
<template v-if="showSidebar">
<Portal to="mobile-navigation">
<div class="lg:hidden">
@@ -1,44 +0,0 @@
<template>
<LayoutDialog v-model:open="open" max-width="xs" :buttons="buttons">
<template #header>Leaving Speckle</template>
<p class="mb-2">You're about to open the link below in a new tab:</p>
<div class="p-3 bg-highlight-2 rounded-md font-mono break-all">
{{ state.url }}
</div>
<p class="mt-2 mb-4">
This is an external website. Speckle is not responsible for its content or
security.
</p>
<p class="font-medium">Do you want to continue?</p>
</LayoutDialog>
</template>
<script setup lang="ts">
import { useExternalLinkDialogState } from '~/lib/common/composables/externalLinkDialog'
import type { LayoutDialogButton } from '@speckle/ui-components'
const { state, close } = useExternalLinkDialogState()
const buttons = computed((): LayoutDialogButton[] => [
{
text: 'Cancel',
props: { color: 'subtle' },
onClick: () => {
close(false)
}
},
{
text: 'Continue',
onClick: () => {
window.open(state.value.url, '_blank', 'noopener,noreferrer')
close(true)
}
}
])
const open = computed({
get: () => state.value.open,
set: (v) => {
if (!v) close(false)
}
})
</script>
@@ -5,7 +5,6 @@
</ClientOnly>
<SingletonFileUploadErrorDialog />
<SingletonAppErrorStateManager />
<SingletonExternalLinkDialog />
</div>
<div v-else />
</template>
@@ -22,7 +22,6 @@
:disabled="disabled"
:project-id="projectId"
:disable-invitation-cta="!canInvite"
data-no-external-confirm
@submit="onSubmit"
@created="$emit('created')"
/>
@@ -1,29 +0,0 @@
type ExternalLinkState = {
open: boolean
url: string
_resolver?: (accepted: boolean) => void
}
const useSharedExternalLinkState = () =>
useState<ExternalLinkState>('global_external_link', () => ({
open: false,
url: ''
}))
export const useExternalLinkDialogController = () => {
const state = useSharedExternalLinkState()
const confirm = (url: string) =>
new Promise<boolean>((resolve) => {
state.value = { open: true, url, _resolver: resolve }
})
return { confirm }
}
export const useExternalLinkDialogState = () => {
const state = useSharedExternalLinkState()
const close = (accepted: boolean) => {
state.value.open = false
state.value._resolver?.(accepted)
}
return { state: readonly(state), close }
}
@@ -1,34 +0,0 @@
import { useExternalLinkDialogController } from '~/lib/common/composables/externalLinkDialog'
export default defineNuxtPlugin(() => {
const { confirm } = useExternalLinkDialogController()
const handler = (e: MouseEvent) => {
// Ignore modified / non-left clicks
if (e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return
const a = (e.target as HTMLElement).closest('a[href]') as HTMLAnchorElement | null
if (!a) return
if (a.hasAttribute('download') || a.closest('[data-no-external-confirm]')) return
const url = new URL(a.href, window.location.href)
const isWhitelisted = (url: URL) =>
url.hostname === 'speckle.systems' ||
url.hostname.endsWith('.speckle.systems') ||
url.hostname === 'speckle.community' ||
url.hostname.endsWith('.speckle.community') ||
url.hostname === 'speckle.xyz' ||
url.hostname.endsWith('.speckle.xyz') ||
url.hostname === 'speckle.dev' ||
url.hostname.endsWith('.speckle.dev')
if (isWhitelisted(url) || url.origin === window.location.origin) return
e.preventDefault()
void confirm(a.href)
}
document.addEventListener('click', handler, true)
})