Project list and starting editing

This commit is contained in:
2024-08-06 15:16:48 +02:00
parent a3d0b3b5bd
commit aba56bb034
24 changed files with 1189 additions and 943 deletions

View File

@@ -24,6 +24,4 @@ const afterText = computed(() => {
const pos = props.text.toLowerCase().indexOf(props.matched.toLowerCase()) + props.matched.length;
return props.text.substring(pos);
})
console.log(props, beforeText.value, afterText.value);
</script>

View File

@@ -5,14 +5,27 @@ function hideLeftPanel(_: Event)
}
const route = useRoute();
const showing = ref(false);
const project = parseInt(Array.isArray(route.params.projectId) ? '' : route.params.projectId);
const project = computed(() => parseInt(Array.isArray(route.params.projectId) ? '0' : route.params.projectId));
const { data: navigation } = await useFetch(() => isNaN(project) ? '' : `/api/project/${project}/navigation`);
const { data: navigation, execute, status, error } = await useFetch(() => `/api/project/${project.value}/navigation`, {
immediate: false,
});
if(route.params.projectId && project.value !== 0)
{
showing.value = true;
execute();
}
else
{
showing.value = false;
}
</script>
<template>
<div class="site-body-left-column">
<div :class="{'desktop-hidden': !showing}" class="site-body-left-column">
<div class="site-body-left-column-inner">
<div class="nav-view-outer">
<div class="nav-view">

View File

@@ -1,3 +1,32 @@
<template>
<slot
:data="data?.data"
:body="data?.body"
:toc="data?.toc"
:excerpt="data?.excerpt"
:error="error"
>
<MDCRenderer
v-if="body"
:tag="tag"
:class="props.class"
:body="body"
:data="data?.data"
:unwrap="props.unwrap"
:components="{
a: ProseA,
h1: ProseH1,
h2: ProseH2,
h3: ProseH3,
h4: ProseH4,
h5: ProseH5,
h6: ProseH6,
blockquote: ProseBlockquote,
}"
/>
</slot>
</template>
<script setup lang="ts">
import ProseA from "~/components/content/prose/ProseA.vue";
import ProseH1 from "~/components/content/prose/ProseH1.vue";
@@ -7,27 +36,54 @@ import ProseH4 from "~/components/content/prose/ProseH4.vue";
import ProseH5 from "~/components/content/prose/ProseH5.vue";
import ProseH6 from "~/components/content/prose/ProseH6.vue";
import ProseBlockquote from "~/components/content/prose/ProseBlockquote.vue";
const props = defineProps<{
content: string
}>();
const parser = useMarkdown();
const ast = await parser(props.content);
</script>
<template>
<Suspense>
<template #fallback>
<div class="loading"></div>
</template>
<MDCRenderer :body="ast?.body" :data="ast?.data" :components="{
a: ProseA,
h1: ProseH1,
h2: ProseH2,
h3: ProseH3,
h4: ProseH4,
h5: ProseH5,
h6: ProseH6,
blockquote: ProseBlockquote,
}" />
</Suspense>
</template>
import { hash } from 'ohash'
import { useAsyncData } from 'nuxt/app'
import { watch, computed } from 'vue'
const props = defineProps({
tag: {
type: [String, Boolean],
default: 'div'
},
content: {
type: [String, Object],
required: true
},
excerpt: {
type: Boolean,
default: false
},
class: {
type: [String, Array, Object],
default: ''
},
unwrap: {
type: [Boolean, String],
default: false
}
})
const model = defineModel<number>({
default: 0,
});
const parser = useMarkdown();
const key = computed(() => hash(props.content))
const { data, refresh, error } = await useAsyncData(key.value, async () => {
const timer = performance.now();
if (typeof props.content !== 'string') {
model.value = performance.now() - timer;
return props.content
}
const result = await parser(props.content);
model.value = performance.now() - timer;
return result;
})
const body = computed(() => props.excerpt ? data.value?.excerpt : data.value?.body)
watch(() => props.content, () => {
refresh()
})
</script>

View File

@@ -54,8 +54,10 @@ async function debounced()
@mouseleave="(e) => (e.target as HTMLElement).classList.remove('is-selected')"
@mousedown.prevent="navigateTo(`/explorer/${result.id}${result.home}`); input = ''">
<div class="suggestion-content">
<div class="suggestion-title">
<BoldContent :text="result.name" :matched="input" />
<BoldContent class="suggestion-title" :text="result.name" :matched="input" />
<div class="suggestion-subtext">
<div class="suggestion-text">{{ result.username }}</div>
<div class="suggestion-text">{{ result.pages }} pages</div>
</div>
</div>
</div>
@@ -64,10 +66,10 @@ async function debounced()
@mouseleave="(e) => (e.target as HTMLElement).classList.remove('is-selected')"
@mousedown.prevent="navigateTo(`/explorer/${result.project}${result.path}`); input = ''">
<div class="suggestion-content">
<div class="suggestion-title">
<ProseA :href="result.path" :project="result.project">
<BoldContent :text="result.title" :matched="input" />
</ProseA>
<BoldContent class="suggestion-title" :text="result.title" :matched="input" />
<div class="suggestion-subtext">
<div class="suggestion-text">{{ result.username }}</div>
<div class="suggestion-text">{{ result.comments }} commentaires</div>
</div>
</div>
</div>
@@ -76,11 +78,7 @@ async function debounced()
@mouseleave="(e) => (e.target as HTMLElement).classList.remove('is-selected')"
@mousedown.prevent="navigateTo(`/user/${result.id}`); input = ''">
<div class="suggestion-content">
<div class="suggestion-title">
<div>
<BoldContent :text="result.username" :matched="input" />
</div>
</div>
<BoldContent class="suggestion-title" :text="result.username" :matched="input" />
</div>
</div>
<div class="suggestion-empty"

View File

@@ -26,7 +26,7 @@
<div v-else class="loading"></div>
</div>
</Teleport>
<NuxtLink :to="path" :class="class" noPrefetch @mouseenter="(e) => showPreview(e, true)" @mouseleave="hidePreview">
<NuxtLink :to="{ path, force: true }" :class="class" noPrefetch @mouseenter="(e) => showPreview(e, true)" @mouseleave="hidePreview">
<slot v-bind="$attrs"></slot>
</NuxtLink>
</template>
@@ -74,22 +74,30 @@ if (parseURL(props.href).protocol !== undefined)
let id = ref(props.project);
if(id.value === undefined)
{
id = useProject().id;
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)
if(!external.value)
{
execute();
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>

View File

@@ -51,7 +51,7 @@ function hideLeftPanel(_: Event)
<NavigationLink v-if="hasChildren" v-for="l of link.children" :link="l" :project="project" />
</div>
</template>
<NuxtLink @click="hideLeftPanel" v-else class="tree-item-self" :to="`/explorer/${project}${link.path}`"
<NuxtLink @click="hideLeftPanel" v-else class="tree-item-self" :to="{ path: `/explorer/${project}${link.path}`, force: true }"
:active-class="'mod-active'" :data-type="link.type === 'Canvas' ? 'graph' : undefined">
<div class="tree-item-inner">{{ link.title }}</div>
</NuxtLink>

View File

@@ -19,7 +19,7 @@ const hasChildren = computed(() => {
<template>
<div class="tree-item">
<div class="tree-item-self" :class="{'is-clickable': hasChildren}" data-path="{{ props.link.title }}">
<NuxtLink no-prefetch class="tree-item-inner" :href="{hash: '#' + props.link.id}">{{ props.link.text }}</NuxtLink>
<NuxtLink no-prefetch class="tree-item-inner" :to="{ hash: '#' + props.link.id, force: true }">{{ props.link.text }}</NuxtLink>
</div>
<div class="tree-item-children">
<TocLink v-if="hasChildren" v-for="link of props.link.children" :link="link" />