103 lines
3.4 KiB
Vue
103 lines
3.4 KiB
Vue
<template>
|
|
<Teleport to="body" v-if="!external && hovered && status !== 'pending'">
|
|
<div class="popover hover-popover is-loaded" :style="pos" @mouseenter="(e) => showPreview(e, false)"
|
|
@mouseleave="hidePreview">
|
|
<template v-if="!!page && !!page[0]">
|
|
<div class="markdown-embed" v-if="page[0].type === 'Markdown' && page[0].content.length > 0">
|
|
<div class="markdown-embed-content">
|
|
<div class="markdown-preview-view markdown-rendered node-insert-event hide-title">
|
|
<div class="markdown-preview-sizer markdown-preview-section" style="padding-bottom: 0px;">
|
|
<h1 v-if="page[0]?.title">{{ page[0]?.title }}</h1>
|
|
<Markdown v-model="page[0].content" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div v-else-if="page[0].type === 'Canvas'" class="canvas-embed is-loaded">
|
|
<CanvasRenderer :canvas="JSON.parse(page[0].content)" />
|
|
</div>
|
|
<div class="markdown-embed" v-else>
|
|
<div class="not-found-container">
|
|
<div class="not-found-title">Impossible de prévisualiser</div>
|
|
<div class="not-found-description">Cliquez sur le lien pour accéder au contenu</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<div v-else class="loading"></div>
|
|
</div>
|
|
</Teleport>
|
|
<NuxtLink :to="{ path, force: true }" :class="class" noPrefetch @mouseenter="(e) => showPreview(e, true)" @mouseleave="hidePreview">
|
|
<slot v-bind="$attrs"></slot>
|
|
</NuxtLink>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { parseURL } from 'ufo';
|
|
|
|
function showPreview(e: Event, bbox: boolean) {
|
|
clearTimeout(timeout);
|
|
if (bbox) {
|
|
const target = e.currentTarget as HTMLElement;
|
|
const rect = target?.getBoundingClientRect();
|
|
const r: any = {};
|
|
if (rect.bottom + 450 < window.innerHeight)
|
|
r.top = (rect.bottom + 4) + "px";
|
|
else
|
|
r.bottom = (window.innerHeight - rect.top + 4) + "px";
|
|
if (rect.right + 550 < window.innerWidth)
|
|
r.left = rect.left + "px";
|
|
else
|
|
r.right = (window.innerWidth - rect.right + 4) + "px";
|
|
pos.value = r;
|
|
}
|
|
hovered.value = true;
|
|
}
|
|
function hidePreview(e: Event) {
|
|
timeout = setTimeout(() => hovered.value = false, 300);
|
|
}
|
|
|
|
interface Prop
|
|
{
|
|
href?: string;
|
|
class?: string;
|
|
project?: number;
|
|
}
|
|
const props = defineProps<Prop>();
|
|
const path = ref(props.href), external = ref(false), hovered = ref(false), pos = ref<any>();
|
|
let timeout: NodeJS.Timeout;
|
|
|
|
if (parseURL(props.href).protocol !== undefined)
|
|
{
|
|
external.value = true;
|
|
}
|
|
|
|
let id = ref(props.project);
|
|
if(id.value === undefined)
|
|
{
|
|
id.value = useProject().id.value;
|
|
}
|
|
|
|
const { data: page, status, error, execute } = await useLazyFetch(`/api/project/${id.value}/file`, {
|
|
query: {
|
|
search: "%" + parseURL(props.href).pathname,
|
|
},
|
|
immediate: false,
|
|
dedupe: 'defer',
|
|
});
|
|
|
|
if(!external.value)
|
|
{
|
|
await execute();
|
|
}
|
|
|
|
if(status.value === 'error')
|
|
{
|
|
console.error(error.value);
|
|
}
|
|
|
|
if (page.value && page.value[0])
|
|
{
|
|
path.value = `/explorer/${id.value}${page.value[0].path}`;
|
|
console.log(path.value);
|
|
}
|
|
</script> |