From 0a5fb483370fa71944f88c168e0c56a1ac956f5b Mon Sep 17 00:00:00 2001
From: Aaron Jude Tanael <69955418+eyronjuude@users.noreply.github.com>
Date: Fri, 18 Jul 2025 21:49:30 +0800
Subject: [PATCH 01/21] perf: use batch loading for Await-based loadMore in
news
---
.../src/lib/components/loading/Await.svelte | 63 ++++++++-----------
.../src/routes/news/+page.server.ts | 49 +++++++++++++--
.../src/routes/news/[slug]/+page.server.ts | 53 ++++++++++++++--
3 files changed, 117 insertions(+), 48 deletions(-)
diff --git a/website-frontend/src/lib/components/loading/Await.svelte b/website-frontend/src/lib/components/loading/Await.svelte
index 569b6aeb..b8384aa6 100644
--- a/website-frontend/src/lib/components/loading/Await.svelte
+++ b/website-frontend/src/lib/components/loading/Await.svelte
@@ -1,28 +1,29 @@
@@ -47,33 +48,21 @@
{#if data.length < count}
-
- {/if}
- {#if data.length > limit}
-
+
{/if}
Showing {Math.min(currentLimit, count)} items out of {count}Showing {data.length} items out of {count}
{:catch}
diff --git a/website-frontend/src/routes/news/+page.server.ts b/website-frontend/src/routes/news/+page.server.ts
index b61abd0f..baa36de9 100644
--- a/website-frontend/src/routes/news/+page.server.ts
+++ b/website-frontend/src/routes/news/+page.server.ts
@@ -3,13 +3,14 @@ import { aggregate, readItems, readSingleton } from '@directus/sdk';
import getDirectusInstance from '$lib/directus';
import { awaitAsync, parse, parseAsync, pipeAsync, promise } from 'valibot';
import { News } from '$lib/models/news';
-import { redirect } from '@sveltejs/kit';
import { NewsOverview } from '$lib/models/news_overview.js';
+import type { Actions } from './$types';
-export async function load({ fetch, url }) {
+const news_limit = 12;
+
+export async function load({ fetch }) {
const directus = getDirectusInstance(fetch);
const news_overview = parse(NewsOverview, await directus.request(readSingleton('news_overview')));
- const news_limit = 12;
const news_count = await directus
.request(
aggregate('news', {
@@ -17,8 +18,6 @@ export async function load({ fetch, url }) {
})
)
.then((res) => parseInt(res[0].count ?? '0'));
- if (parseInt(url.searchParams.get('limit') ?? news_limit.toString()) < news_limit)
- throw redirect(302, url.pathname);
const news = parseAsync(
pipeAsync(promise(), awaitAsync(), News),
directus.request(
@@ -40,10 +39,48 @@ export async function load({ fetch, url }) {
}
],
sort: ['-date_created'],
- limit: Math.max(news_limit, parseInt(url.searchParams.get('limit') ?? '0'))
+ limit: news_limit
})
)
);
return { news_overview, news_limit, news_count, news };
}
+
+export const actions = {
+ loadMore: async ({ request }) => {
+ const data = await request.formData();
+ const directus = getDirectusInstance(null);
+ const news = parse(
+ News,
+ await directus.request(
+ readItems('news', {
+ fields: [
+ '*',
+ {
+ user_created: ['first_name', 'last_name']
+ },
+ {
+ user_updated: ['first_name', 'last_name']
+ },
+ {
+ news_tags: [
+ {
+ news_tags_id: ['name']
+ }
+ ]
+ }
+ ],
+ sort: ['-date_created'],
+ offset: parseInt((data.get('offset') ?? '0') as string),
+ limit: news_limit
+ })
+ )
+ );
+
+ return {
+ success: true,
+ items: news
+ };
+ }
+} satisfies Actions;
diff --git a/website-frontend/src/routes/news/[slug]/+page.server.ts b/website-frontend/src/routes/news/[slug]/+page.server.ts
index ac5a0318..eda32940 100644
--- a/website-frontend/src/routes/news/[slug]/+page.server.ts
+++ b/website-frontend/src/routes/news/[slug]/+page.server.ts
@@ -1,9 +1,12 @@
/** @type {import('./$types').PageServerLoad} */
import { aggregate, readItems } from '@directus/sdk';
import getDirectusInstance from '$lib/directus';
-import { error, redirect } from '@sveltejs/kit';
+import { error } from '@sveltejs/kit';
import { parse } from 'valibot';
import { News, NewsItem } from '$lib/models/news';
+import type { Actions } from './$types';
+
+const other_news_limit = 12;
export async function load({ url, params, fetch }) {
const directus = getDirectusInstance(fetch);
@@ -43,7 +46,6 @@ export async function load({ url, params, fetch }) {
const news_item = parse(NewsItem, news[0]);
- const other_news_limit = 12;
const other_news_count = await directus
.request(
aggregate('news', {
@@ -60,8 +62,6 @@ export async function load({ url, params, fetch }) {
})
)
.then((res) => res[0].count);
- if (parseInt(url.searchParams.get('limit') ?? other_news_limit.toString()) < other_news_limit)
- throw redirect(302, url.pathname);
const other_news = parse(
News,
await directus.request(
@@ -88,7 +88,7 @@ export async function load({ url, params, fetch }) {
}
},
sort: ['-date_created'],
- limit: Math.max(other_news_limit, parseInt(url.searchParams.get('limit') ?? '0'))
+ limit: other_news_limit
})
)
);
@@ -97,3 +97,46 @@ export async function load({ url, params, fetch }) {
return { link, other_news_limit, other_news_count, other_news, news_item };
}
+
+export const actions = {
+ loadMore: async ({ request, params }) => {
+ const data = await request.formData();
+ const directus = getDirectusInstance(null);
+ const other_news = parse(
+ News,
+ await directus.request(
+ readItems('news', {
+ fields: [
+ '*',
+ {
+ user_created: ['first_name', 'last_name']
+ },
+ {
+ user_updated: ['first_name', 'last_name']
+ },
+ {
+ news_tags: [
+ {
+ news_tags_id: ['name']
+ }
+ ]
+ }
+ ],
+ filter: {
+ slug: {
+ _neq: params.slug
+ }
+ },
+ sort: ['-date_created'],
+ offset: parseInt((data.get('offset') ?? '0') as string),
+ limit: other_news_limit
+ })
+ )
+ );
+
+ return {
+ success: true,
+ items: other_news
+ };
+ }
+} satisfies Actions;
From 76144c72d7fc11ef81e655d24485a15a8619e9ef Mon Sep 17 00:00:00 2001
From: Aaron Jude Tanael <69955418+eyronjuude@users.noreply.github.com>
Date: Fri, 18 Jul 2025 21:55:35 +0800
Subject: [PATCH 02/21] feat: use fetch parameter for getDirectusInstance in
loadMore server action
---
website-frontend/src/routes/news/+page.server.ts | 4 ++--
website-frontend/src/routes/news/[slug]/+page.server.ts | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/website-frontend/src/routes/news/+page.server.ts b/website-frontend/src/routes/news/+page.server.ts
index baa36de9..964306a4 100644
--- a/website-frontend/src/routes/news/+page.server.ts
+++ b/website-frontend/src/routes/news/+page.server.ts
@@ -48,9 +48,9 @@ export async function load({ fetch }) {
}
export const actions = {
- loadMore: async ({ request }) => {
+ loadMore: async ({ request, fetch }) => {
const data = await request.formData();
- const directus = getDirectusInstance(null);
+ const directus = getDirectusInstance(fetch);
const news = parse(
News,
await directus.request(
diff --git a/website-frontend/src/routes/news/[slug]/+page.server.ts b/website-frontend/src/routes/news/[slug]/+page.server.ts
index eda32940..106def18 100644
--- a/website-frontend/src/routes/news/[slug]/+page.server.ts
+++ b/website-frontend/src/routes/news/[slug]/+page.server.ts
@@ -99,9 +99,9 @@ export async function load({ url, params, fetch }) {
}
export const actions = {
- loadMore: async ({ request, params }) => {
+ loadMore: async ({ request, params, fetch }) => {
const data = await request.formData();
- const directus = getDirectusInstance(null);
+ const directus = getDirectusInstance(fetch);
const other_news = parse(
News,
await directus.request(
From 6511e8edc94bc618391650dad1a16b16229fa9a1 Mon Sep 17 00:00:00 2001
From: Aaron Jude Tanael <69955418+eyronjuude@users.noreply.github.com>
Date: Sat, 19 Jul 2025 01:39:54 +0800
Subject: [PATCH 03/21] fix: lazy load other_news
---
website-frontend/src/routes/news/[slug]/+page.server.ts | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/website-frontend/src/routes/news/[slug]/+page.server.ts b/website-frontend/src/routes/news/[slug]/+page.server.ts
index 106def18..e65183b7 100644
--- a/website-frontend/src/routes/news/[slug]/+page.server.ts
+++ b/website-frontend/src/routes/news/[slug]/+page.server.ts
@@ -2,7 +2,7 @@
import { aggregate, readItems } from '@directus/sdk';
import getDirectusInstance from '$lib/directus';
import { error } from '@sveltejs/kit';
-import { parse } from 'valibot';
+import { awaitAsync, parse, parseAsync, pipeAsync, promise } from 'valibot';
import { News, NewsItem } from '$lib/models/news';
import type { Actions } from './$types';
@@ -62,9 +62,9 @@ export async function load({ url, params, fetch }) {
})
)
.then((res) => res[0].count);
- const other_news = parse(
- News,
- await directus.request(
+ const other_news = parseAsync(
+ pipeAsync(promise(), awaitAsync(), News),
+ directus.request(
readItems('news', {
fields: [
'*',
From 82bac70bc46e7282ff488d585c3b315b0bb5539b Mon Sep 17 00:00:00 2001
From: Aaron Jude Tanael <69955418+eyronjuude@users.noreply.github.com>
Date: Sat, 19 Jul 2025 01:40:38 +0800
Subject: [PATCH 04/21] fix: set data as Promise
> in Await
component
---
website-frontend/src/lib/components/loading/Await.svelte | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/website-frontend/src/lib/components/loading/Await.svelte b/website-frontend/src/lib/components/loading/Await.svelte
index b8384aa6..ef1cd034 100644
--- a/website-frontend/src/lib/components/loading/Await.svelte
+++ b/website-frontend/src/lib/components/loading/Await.svelte
@@ -7,7 +7,7 @@
export let onDark = false;
export let layout;
- export let data: Array;
+ export let data: Promise>;
export let text;
export let component;
export let count;
@@ -19,7 +19,7 @@
formData.set('offset', (offset + limit).toString());
return async ({ result }: { result: ActionResult }) => {
if (result.type === 'success' && result.data) {
- data = [...(await data), ...result.data.items];
+ data = Promise.all([...(await data), ...result.data.items]);
offset = offset + limit;
}
};
From c28ed4e9ee4c54d5d46c2ec6e7349169ccd13bf6 Mon Sep 17 00:00:00 2001
From: Aaron Jude Tanael <69955418+eyronjuude@users.noreply.github.com>
Date: Sat, 19 Jul 2025 09:09:54 +0800
Subject: [PATCH 05/21] feat: add data stream and query support for Await
---
.../src/lib/components/loading/Await.svelte | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/website-frontend/src/lib/components/loading/Await.svelte b/website-frontend/src/lib/components/loading/Await.svelte
index ef1cd034..70228433 100644
--- a/website-frontend/src/lib/components/loading/Await.svelte
+++ b/website-frontend/src/lib/components/loading/Await.svelte
@@ -4,22 +4,25 @@
import { Frown, Plus } from 'lucide-svelte';
import { enhance } from '$app/forms';
import type { ActionResult } from '@sveltejs/kit';
+ import { page } from '$app/stores';
export let onDark = false;
export let layout;
- export let data: Promise>;
+ export let data: Promise>;
export let text;
export let component;
export let count;
export let limit: number;
+ $: query = new URLSearchParams($page.url.searchParams.toString());
$: offset = 0;
- const handleLoadMore = ({ formData }: { formData: FormData }) => {
+ const handleLoadMore = async ({ formData }: { formData: FormData }) => {
+ formData.set('data', JSON.stringify(await data));
formData.set('offset', (offset + limit).toString());
return async ({ result }: { result: ActionResult }) => {
if (result.type === 'success' && result.data) {
- data = Promise.all([...(await data), ...result.data.items]);
+ data = result.data.items;
offset = offset + limit;
}
};
@@ -48,7 +51,7 @@
{#if data.length < count}
-
- {:then data}
+ {:then}
- {#each data as item}
+ {#each items as item}
{/each}
- {#if data.length < count}
+ {#if items.length < count}
{:catch}
From 32858090bd62f2216b850ed58e49e33c72349854 Mon Sep 17 00:00:00 2001
From: Aaron Jude Tanael <69955418+eyronjuude@users.noreply.github.com>
Date: Sat, 19 Jul 2025 17:12:38 +0800
Subject: [PATCH 08/21] fix: apply Await fixes for /news
---
website-frontend/src/routes/news/+page.server.ts | 12 +++++++-----
website-frontend/src/routes/news/+page.svelte | 3 +--
website-frontend/src/routes/news/+page.ts | 1 -
.../src/routes/news/[slug]/+page.server.ts | 12 +++++++-----
website-frontend/src/routes/news/[slug]/+page.svelte | 3 +--
5 files changed, 16 insertions(+), 15 deletions(-)
diff --git a/website-frontend/src/routes/news/+page.server.ts b/website-frontend/src/routes/news/+page.server.ts
index 81b42891..be429914 100644
--- a/website-frontend/src/routes/news/+page.server.ts
+++ b/website-frontend/src/routes/news/+page.server.ts
@@ -6,7 +6,7 @@ import { News } from '$lib/models/news';
import { NewsOverview } from '$lib/models/news_overview.js';
import type { Actions } from './$types';
-const news_limit = 12;
+const limit = 12;
export async function load({ fetch }) {
const directus = getDirectusInstance(fetch);
@@ -39,18 +39,19 @@ export async function load({ fetch }) {
}
],
sort: ['-date_created'],
- limit: news_limit
+ limit
})
)
);
- return { news_overview, news_limit, news_count, news };
+ return { news_overview, news_count, news };
}
export const actions = {
loadMore: async ({ request, fetch }) => {
const data = await request.formData();
const directus = getDirectusInstance(fetch);
+ const offset = parseInt((data.get('offset') ?? '0') as string) + limit;
const news = parse(
News,
await directus.request(
@@ -72,8 +73,8 @@ export const actions = {
}
],
sort: ['-date_created'],
- offset: parseInt((data.get('offset') ?? '0') as string),
- limit: news_limit
+ offset,
+ limit
})
)
);
@@ -81,6 +82,7 @@ export const actions = {
const items = [...JSON.parse(data.get('data') as string), ...news];
return {
success: true,
+ offset,
items
};
}
diff --git a/website-frontend/src/routes/news/+page.svelte b/website-frontend/src/routes/news/+page.svelte
index 4c1e0267..4000e2cb 100644
--- a/website-frontend/src/routes/news/+page.svelte
+++ b/website-frontend/src/routes/news/+page.svelte
@@ -7,7 +7,7 @@
export let data;
- $: ({ news_overview, news_limit, news_count, news } = data);
+ $: ({ news_overview, news_count, news } = data);
@@ -25,7 +25,6 @@
text="news"
component={NewsCard}
count={news_count}
- limit={news_limit}
/>
diff --git a/website-frontend/src/routes/news/+page.ts b/website-frontend/src/routes/news/+page.ts
index 110d7348..1114c213 100644
--- a/website-frontend/src/routes/news/+page.ts
+++ b/website-frontend/src/routes/news/+page.ts
@@ -2,7 +2,6 @@
export async function load({ data }) {
return {
news_overview: data.news_overview,
- news_limit: data.news_limit,
news_count: data.news_count,
news: data.news
};
diff --git a/website-frontend/src/routes/news/[slug]/+page.server.ts b/website-frontend/src/routes/news/[slug]/+page.server.ts
index e5edd4d4..3e97b47a 100644
--- a/website-frontend/src/routes/news/[slug]/+page.server.ts
+++ b/website-frontend/src/routes/news/[slug]/+page.server.ts
@@ -6,7 +6,7 @@ import { awaitAsync, parse, parseAsync, pipeAsync, promise } from 'valibot';
import { News, NewsItem } from '$lib/models/news';
import type { Actions } from './$types';
-const other_news_limit = 12;
+const limit = 12;
export async function load({ url, params, fetch }) {
const directus = getDirectusInstance(fetch);
@@ -88,20 +88,21 @@ export async function load({ url, params, fetch }) {
}
},
sort: ['-date_created'],
- limit: other_news_limit
+ limit
})
)
);
const link = new URL(url.toString()).toString();
- return { link, other_news_limit, other_news_count, other_news, news_item };
+ return { link, other_news_count, other_news, news_item };
}
export const actions = {
loadMore: async ({ request, params, fetch }) => {
const data = await request.formData();
const directus = getDirectusInstance(fetch);
+ const offset = parseInt((data.get('offset') ?? '0') as string) + limit;
const other_news = parse(
News,
await directus.request(
@@ -128,8 +129,8 @@ export const actions = {
}
},
sort: ['-date_created'],
- offset: parseInt((data.get('offset') ?? '0') as string),
- limit: other_news_limit
+ offset,
+ limit
})
)
);
@@ -137,6 +138,7 @@ export const actions = {
const items = [...JSON.parse(data.get('data') as string), ...other_news];
return {
success: true,
+ offset,
items
};
}
diff --git a/website-frontend/src/routes/news/[slug]/+page.svelte b/website-frontend/src/routes/news/[slug]/+page.svelte
index c9d080e5..81336967 100644
--- a/website-frontend/src/routes/news/[slug]/+page.svelte
+++ b/website-frontend/src/routes/news/[slug]/+page.svelte
@@ -10,7 +10,7 @@
export let data;
let banner_height: number;
- $: ({ link, other_news_limit, other_news_count, other_news, news_item } = data);
+ $: ({ link, other_news_count, other_news, news_item } = data);
$: news_tags = news_item.news_tags
? news_item.news_tags
@@ -110,7 +110,6 @@
text="other news"
component={NewsCard}
count={other_news_count}
- limit={other_news_limit}
/>
From 2dd00c417caa480de1934238e723c05d76c092a8 Mon Sep 17 00:00:00 2001
From: Aaron Jude Tanael <69955418+eyronjuude@users.noreply.github.com>
Date: Sat, 19 Jul 2025 17:40:57 +0800
Subject: [PATCH 09/21] fix: remove offset dependency in Await component
---
website-frontend/src/lib/components/loading/Await.svelte | 4 ----
1 file changed, 4 deletions(-)
diff --git a/website-frontend/src/lib/components/loading/Await.svelte b/website-frontend/src/lib/components/loading/Await.svelte
index d2013e25..e736d096 100644
--- a/website-frontend/src/lib/components/loading/Await.svelte
+++ b/website-frontend/src/lib/components/loading/Await.svelte
@@ -14,18 +14,14 @@
export let count;
let items: object[] = [];
- let offset: number = 0;
$: query = new URLSearchParams($page.url.searchParams.toString());
- $: offset = 0;
$: data.then((res) => (items = res));
const handleLoadMore = ({ formData }: { formData: FormData }) => {
formData.set('data', JSON.stringify(items));
- formData.set('offset', offset.toString());
return async ({ result }: { result: ActionResult }) => {
if (result.type === 'success' && result.data) {
items = result.data.items;
- offset = result.data.offset;
}
};
};
From a8fdb6e655429dd257daf5bd0a7ea5141e6dd797 Mon Sep 17 00:00:00 2001
From: Aaron Jude Tanael <69955418+eyronjuude@users.noreply.github.com>
Date: Sat, 19 Jul 2025 17:41:56 +0800
Subject: [PATCH 10/21] fix: remove offset form dependency for server actions
in /news
---
website-frontend/src/routes/news/+page.server.ts | 7 +++----
website-frontend/src/routes/news/[slug]/+page.server.ts | 7 +++----
2 files changed, 6 insertions(+), 8 deletions(-)
diff --git a/website-frontend/src/routes/news/+page.server.ts b/website-frontend/src/routes/news/+page.server.ts
index be429914..c6aa1549 100644
--- a/website-frontend/src/routes/news/+page.server.ts
+++ b/website-frontend/src/routes/news/+page.server.ts
@@ -50,8 +50,8 @@ export async function load({ fetch }) {
export const actions = {
loadMore: async ({ request, fetch }) => {
const data = await request.formData();
+ const current = JSON.parse(data.get('data') as string);
const directus = getDirectusInstance(fetch);
- const offset = parseInt((data.get('offset') ?? '0') as string) + limit;
const news = parse(
News,
await directus.request(
@@ -73,16 +73,15 @@ export const actions = {
}
],
sort: ['-date_created'],
- offset,
+ offset: current.length,
limit
})
)
);
- const items = [...JSON.parse(data.get('data') as string), ...news];
+ const items = [...current, ...news];
return {
success: true,
- offset,
items
};
}
diff --git a/website-frontend/src/routes/news/[slug]/+page.server.ts b/website-frontend/src/routes/news/[slug]/+page.server.ts
index 3e97b47a..7c55c5c4 100644
--- a/website-frontend/src/routes/news/[slug]/+page.server.ts
+++ b/website-frontend/src/routes/news/[slug]/+page.server.ts
@@ -101,8 +101,8 @@ export async function load({ url, params, fetch }) {
export const actions = {
loadMore: async ({ request, params, fetch }) => {
const data = await request.formData();
+ const current = JSON.parse(data.get('data') as string);
const directus = getDirectusInstance(fetch);
- const offset = parseInt((data.get('offset') ?? '0') as string) + limit;
const other_news = parse(
News,
await directus.request(
@@ -129,16 +129,15 @@ export const actions = {
}
},
sort: ['-date_created'],
- offset,
+ offset: current.length,
limit
})
)
);
- const items = [...JSON.parse(data.get('data') as string), ...other_news];
+ const items = [...current, ...other_news];
return {
success: true,
- offset,
items
};
}
From 0e62d919b6d316b3597fe90af09fb95a942f94a4 Mon Sep 17 00:00:00 2001
From: Aaron Jude Tanael <69955418+eyronjuude@users.noreply.github.com>
Date: Sat, 19 Jul 2025 20:37:48 +0800
Subject: [PATCH 11/21] feat: use Await loadMore for publications
---
.../research/publications/+page.server.ts | 188 +++++++++++++++---
.../routes/research/publications/+page.svelte | 65 +++---
.../src/routes/research/publications/+page.ts | 5 +-
3 files changed, 192 insertions(+), 66 deletions(-)
diff --git a/website-frontend/src/routes/research/publications/+page.server.ts b/website-frontend/src/routes/research/publications/+page.server.ts
index af04e2f8..30da9f49 100644
--- a/website-frontend/src/routes/research/publications/+page.server.ts
+++ b/website-frontend/src/routes/research/publications/+page.server.ts
@@ -1,11 +1,14 @@
/** @type {import('./$types').PageServerLoad} */
-import { readItem, readItems, readSingleton } from '@directus/sdk';
+import { aggregate, readItems, readSingleton } from '@directus/sdk';
import getDirectusInstance from '$lib/directus';
-import { parse } from 'valibot';
+import { awaitAsync, parse, parseAsync, pipeAsync, promise } from 'valibot';
import { Publications } from '$lib/models/publications';
import { Laboratories } from '$lib/models/laboratories';
import { PublicationsTags } from '$lib/models/publications_tags.js';
import { Research } from '$lib/models/research';
+import type { Actions } from '@sveltejs/kit';
+
+const limit = 12;
export async function load({ fetch, url }) {
const directus = getDirectusInstance(fetch);
@@ -18,6 +21,10 @@ export async function load({ fetch, url }) {
tags: url.searchParams.getAll('tags')
};
+ const people = new Map(
+ (await directus.request(readItems('people'))).map((person) => [person.id, person])
+ );
+
const years_filters = await (async () => {
const res = parse(
Publications,
@@ -60,10 +67,31 @@ export async function load({ fetch, url }) {
)
).map(({ name }) => name);
- const publications = await (async () => {
- const res = parse(
- Publications,
- await directus.request(
+ const publications_count = await directus
+ .request(
+ aggregate('publications', {
+ aggregate: { count: '*' },
+ query: {
+ filter: {
+ 'year(publish_date)': { _in: filters.years.length !== 0 ? filters.years : undefined },
+ laboratory: {
+ name: { _in: filters.laboratories.length !== 0 ? filters.laboratories : undefined }
+ },
+ publication_tags: {
+ publications_tags_id: {
+ name: { _in: filters.tags.length !== 0 ? filters.tags : undefined }
+ }
+ }
+ }
+ }
+ })
+ )
+ .then((res) => parseInt(res[0].count ?? '0'));
+
+ const publications = parseAsync(
+ pipeAsync(promise(), awaitAsync(), Publications),
+ directus
+ .request(
readItems('publications', {
fields: [
'*',
@@ -86,33 +114,131 @@ export async function load({ fetch, url }) {
}
}
},
- sort: ['-publish_date']
+ sort: ['-publish_date'],
+ limit
})
)
- );
-
- return await Promise.all(
- res.map(async (item) => {
- return await {
- ...item,
- authors: await Promise.all(
- item.authors
- ? item.authors.map(async (author) => {
- if (typeof author.link === 'undefined') return author;
- if (typeof author.link === 'object') {
- const person = await directus.request(readItem('people', author.link.key));
- return {
- ...author,
- link: `/people/${person.username}`
- };
- }
- })
- : []
+ .then(
+ async (res) =>
+ await Promise.all(
+ res.map(async (item) => {
+ return {
+ ...item,
+ authors: await Promise.all(
+ item.authors
+ ? item.authors.map(async (author) => {
+ if (typeof author.link === 'undefined') return author;
+ if (typeof author.link === 'object') {
+ const person = people.get(author.link.key);
+ return {
+ ...author,
+ link: `/people/${person ? (person.username ?? '') : ''}`
+ };
+ }
+ })
+ : []
+ )
+ };
+ })
)
- };
- })
- );
- })();
+ )
+ );
- return { research, publications, years_filters, laboratories_filters, tags_filters };
+ return {
+ research,
+ years_filters,
+ laboratories_filters,
+ tags_filters,
+ publications_count,
+ publications
+ };
}
+
+export const actions = {
+ loadMore: async ({ request, fetch, url }) => {
+ const data = await request.formData();
+ const current = JSON.parse(data.get('data') as string);
+ const directus = getDirectusInstance(fetch);
+ const filters = {
+ years: url.searchParams.getAll('year'),
+ laboratories: url.searchParams.getAll('laboratory'),
+ tags: url.searchParams.getAll('tags')
+ };
+ const people = new Map(
+ (await directus.request(readItems('people'))).map((person) => [person.id, person])
+ );
+ const publications = parse(
+ Publications,
+ await directus
+ .request(
+ readItems('publications', {
+ fields: [
+ '*',
+ {
+ publication_tags: [
+ {
+ publications_tags_id: ['name']
+ }
+ ]
+ }
+ ],
+ filter: {
+ 'year(publish_date)': { _in: filters.years.length !== 0 ? filters.years : undefined },
+ laboratory: {
+ name: { _in: filters.laboratories.length !== 0 ? filters.laboratories : undefined }
+ },
+ publication_tags: {
+ publications_tags_id: {
+ name: { _in: filters.tags.length !== 0 ? filters.tags : undefined }
+ }
+ }
+ },
+ sort: ['-publish_date'],
+ offset: current.length,
+ limit
+ })
+ )
+ .then(
+ async (res) =>
+ await Promise.all(
+ res.map(async (item) => {
+ return {
+ ...item,
+ authors: await Promise.all(
+ item.authors
+ ? item.authors.map(async (author) => {
+ if (typeof author.link === 'undefined') return author;
+ if (typeof author.link === 'object') {
+ const person = people.get(author.link.key);
+ return {
+ ...author,
+ link: `/people/${person ? (person.username ?? '') : ''}`
+ };
+ }
+ })
+ : []
+ )
+ };
+ })
+ )
+ )
+ );
+ const items = [...current, ...publications].sort((a, b) => {
+ if ((url.searchParams.get('sort') ?? '') === 'author') {
+ const aLastName = a.authors[0]?.last_name || '';
+ const bLastName = b.authors[0]?.last_name || '';
+ return aLastName.localeCompare(bLastName);
+ } else if ((url.searchParams.get('sort') ?? '') === 'title') {
+ const a_title = a.title || '';
+ const b_title = b.title || '';
+ return a_title.localeCompare(b_title);
+ } else {
+ return (b.publish_date ?? '1970-01-01').localeCompare(a.publish_date ?? '1970-01-01');
+ }
+ });
+ return {
+ success: true,
+ items
+ };
+ }
+} satisfies Actions;
diff --git a/website-frontend/src/routes/research/publications/+page.svelte b/website-frontend/src/routes/research/publications/+page.svelte
index aee27199..c97b9ace 100644
--- a/website-frontend/src/routes/research/publications/+page.svelte
+++ b/website-frontend/src/routes/research/publications/+page.svelte
@@ -1,20 +1,26 @@