dashboard scrolls properly now #5
5 changed files with 19 additions and 13 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed } from "vue";
|
import { computed } from "vue";
|
||||||
import { RouterView } from "vue-router";
|
import { RouterView, useRoute } from "vue-router";
|
||||||
|
|
||||||
import AppHeader from "@/components/layout/AppHeader.vue";
|
import AppHeader from "@/components/layout/AppHeader.vue";
|
||||||
import AppNav from "@/components/layout/AppNav.vue";
|
import AppNav from "@/components/layout/AppNav.vue";
|
||||||
|
|
@ -8,7 +8,9 @@ import RequestErrorPanel from "@/components/patterns/RequestErrorPanel.vue";
|
||||||
import { useAuthStore } from "@/stores/auth";
|
import { useAuthStore } from "@/stores/auth";
|
||||||
|
|
||||||
const auth = useAuthStore();
|
const auth = useAuthStore();
|
||||||
|
const route = useRoute();
|
||||||
const showChrome = computed(() => auth.isAuthenticated);
|
const showChrome = computed(() => auth.isAuthenticated);
|
||||||
|
const shouldLockMainScroll = computed(() => route.meta.lockMainScroll === true);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -22,7 +24,11 @@ const showChrome = computed(() => auth.isAuthenticated);
|
||||||
class="grid h-[calc(100dvh-4.5rem)] min-h-0 grid-cols-1 grid-rows-[auto_minmax(0,1fr)] lg:grid-cols-[17rem_minmax(0,1fr)] lg:grid-rows-1"
|
class="grid h-[calc(100dvh-4.5rem)] min-h-0 grid-cols-1 grid-rows-[auto_minmax(0,1fr)] lg:grid-cols-[17rem_minmax(0,1fr)] lg:grid-rows-1"
|
||||||
>
|
>
|
||||||
<AppNav class="min-h-0 overflow-x-hidden lg:overflow-y-auto" />
|
<AppNav class="min-h-0 overflow-x-hidden lg:overflow-y-auto" />
|
||||||
<main id="app-main" class="min-h-0 min-w-0 overflow-y-auto overflow-x-hidden px-4 py-6 sm:px-6 lg:px-8">
|
<main
|
||||||
|
id="app-main"
|
||||||
|
class="min-h-0 min-w-0 overflow-x-hidden px-4 py-6 sm:px-6 lg:px-8"
|
||||||
|
:class="shouldLockMainScroll ? 'overflow-y-auto lg:overflow-y-hidden' : 'overflow-y-auto'"
|
||||||
|
>
|
||||||
<RouterView />
|
<RouterView />
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ export const router = createRouter({
|
||||||
path: "/dashboard",
|
path: "/dashboard",
|
||||||
name: "dashboard",
|
name: "dashboard",
|
||||||
component: DashboardPage,
|
component: DashboardPage,
|
||||||
meta: { requiresAuth: true },
|
meta: { requiresAuth: true, lockMainScroll: true },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/scholars",
|
path: "/scholars",
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ const props = withDefaults(
|
||||||
<section
|
<section
|
||||||
:class="
|
:class="
|
||||||
props.fill
|
props.fill
|
||||||
? 'min-w-0 flex min-h-0 flex-col gap-6 lg:h-full'
|
? 'min-w-0 flex min-h-0 flex-col gap-6 lg:h-full lg:overflow-hidden'
|
||||||
: 'page-stack min-w-0'
|
: 'page-stack min-w-0'
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
|
|
@ -23,7 +23,7 @@ const props = withDefaults(
|
||||||
<h1 class="page-title">{{ props.title }}</h1>
|
<h1 class="page-title">{{ props.title }}</h1>
|
||||||
<p v-if="props.subtitle" class="page-subtitle">{{ props.subtitle }}</p>
|
<p v-if="props.subtitle" class="page-subtitle">{{ props.subtitle }}</p>
|
||||||
</header>
|
</header>
|
||||||
<div v-if="props.fill" class="min-h-0 flex-1">
|
<div v-if="props.fill" class="flex min-h-0 flex-1 flex-col">
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
<slot v-else />
|
<slot v-else />
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ function countQueueStatuses(statuses: string[]): QueueHealth {
|
||||||
export async function fetchDashboardSnapshot(): Promise<DashboardSnapshot> {
|
export async function fetchDashboardSnapshot(): Promise<DashboardSnapshot> {
|
||||||
const [publications, runs, queueItems] = await Promise.all([
|
const [publications, runs, queueItems] = await Promise.all([
|
||||||
listPublications({ mode: "new", limit: 20 }),
|
listPublications({ mode: "new", limit: 20 }),
|
||||||
listRuns({ limit: 5 }),
|
listRuns({ limit: 20 }),
|
||||||
listQueueItems(200),
|
listQueueItems(200),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ onMounted(() => {
|
||||||
subtitle="Track recent publication updates and monitor background profile checks."
|
subtitle="Track recent publication updates and monitor background profile checks."
|
||||||
fill
|
fill
|
||||||
>
|
>
|
||||||
<div class="flex min-h-0 flex-1 flex-col gap-4">
|
<div class="flex min-h-0 flex-1 flex-col gap-4 xl:overflow-hidden">
|
||||||
<RequestStateAlerts
|
<RequestStateAlerts
|
||||||
:success-message="successMessage"
|
:success-message="successMessage"
|
||||||
:error-message="errorMessage"
|
:error-message="errorMessage"
|
||||||
|
|
@ -96,10 +96,10 @@ onMounted(() => {
|
||||||
@dismiss-success="successMessage = null"
|
@dismiss-success="successMessage = null"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div class="min-h-0 flex-1">
|
<div class="h-0 min-h-0 flex-1 xl:overflow-hidden">
|
||||||
<AsyncStateGate :loading="loading" :loading-lines="6" :show-empty="false">
|
<AsyncStateGate :loading="loading" :loading-lines="6" :show-empty="false">
|
||||||
<template v-if="snapshot">
|
<template v-if="snapshot">
|
||||||
<section class="grid min-h-0 gap-4 xl:h-full xl:grid-cols-2">
|
<section class="grid min-h-0 gap-4 xl:h-full xl:grid-cols-2 xl:grid-rows-[minmax(0,1fr)] xl:overflow-hidden">
|
||||||
<AppCard class="flex min-h-0 flex-col gap-4 xl:h-full xl:overflow-hidden">
|
<AppCard class="flex min-h-0 flex-col gap-4 xl:h-full xl:overflow-hidden">
|
||||||
<div class="flex flex-wrap items-center justify-between gap-2">
|
<div class="flex flex-wrap items-center justify-between gap-2">
|
||||||
<div class="space-y-1">
|
<div class="space-y-1">
|
||||||
|
|
@ -120,7 +120,7 @@ onMounted(() => {
|
||||||
body="When a completed update check discovers changes, they will appear here."
|
body="When a completed update check discovers changes, they will appear here."
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<ul v-else class="grid min-h-0 flex-1 gap-3 overflow-y-auto pr-1">
|
<ul v-else class="grid min-h-0 flex-1 content-start gap-3 overflow-y-scroll overscroll-contain pr-1">
|
||||||
<li
|
<li
|
||||||
v-for="item in snapshot.recentPublications.slice(0, 20)"
|
v-for="item in snapshot.recentPublications.slice(0, 20)"
|
||||||
:key="item.publication_id"
|
:key="item.publication_id"
|
||||||
|
|
@ -149,7 +149,7 @@ onMounted(() => {
|
||||||
</ul>
|
</ul>
|
||||||
</AppCard>
|
</AppCard>
|
||||||
|
|
||||||
<div class="grid min-h-0 gap-4 xl:h-full xl:grid-rows-[auto_minmax(0,1fr)]">
|
<div class="grid min-h-0 gap-4 xl:h-full xl:grid-rows-[auto_minmax(0,1fr)] xl:overflow-hidden">
|
||||||
<AppCard class="flex min-h-0 flex-col gap-4">
|
<AppCard class="flex min-h-0 flex-col gap-4">
|
||||||
<div class="flex items-center gap-1">
|
<div class="flex items-center gap-1">
|
||||||
<h2 class="text-lg font-semibold text-ink-primary">Overview</h2>
|
<h2 class="text-lg font-semibold text-ink-primary">Overview</h2>
|
||||||
|
|
@ -237,14 +237,14 @@ onMounted(() => {
|
||||||
body="Start an update check to begin monitoring activity."
|
body="Start an update check to begin monitoring activity."
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div class="grid min-h-0 flex-1 gap-2 xl:overflow-hidden">
|
<div class="flex min-h-0 flex-1 flex-col gap-2 xl:overflow-hidden">
|
||||||
<p class="text-xs font-semibold uppercase tracking-wide text-muted">Recent checks</p>
|
<p class="text-xs font-semibold uppercase tracking-wide text-muted">Recent checks</p>
|
||||||
<AppEmptyState
|
<AppEmptyState
|
||||||
v-if="snapshot.recentRuns.length === 0"
|
v-if="snapshot.recentRuns.length === 0"
|
||||||
title="No checks yet"
|
title="No checks yet"
|
||||||
body="Check history will appear here."
|
body="Check history will appear here."
|
||||||
/>
|
/>
|
||||||
<ul v-else class="grid gap-2 overflow-y-auto pr-1">
|
<ul v-else class="grid min-h-0 flex-1 content-start gap-2 overflow-y-auto overscroll-contain pr-1">
|
||||||
<li
|
<li
|
||||||
v-for="run in snapshot.recentRuns"
|
v-for="run in snapshot.recentRuns"
|
||||||
:key="run.id"
|
:key="run.id"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue