types fix + limit recent articles

This commit is contained in:
Sergey Yarkov 2025-12-18 23:32:23 +03:00
parent 0e951d2aca
commit d8d812a282
11 changed files with 82 additions and 198 deletions

View File

@ -12,7 +12,7 @@
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "astro dev", "dev": "astro dev",
"build": "astro build", "build": "astro check && astro build",
"start": "node --env-file=.env ./dist/server/entry.mjs", "start": "node --env-file=.env ./dist/server/entry.mjs",
"preview": "astro preview", "preview": "astro preview",
"astro": "astro", "astro": "astro",

View File

@ -7,7 +7,7 @@ const tocTitle = t("article.tableOfContents");
<div itemprop='articleBody' class='article-content'><slot /></div> <div itemprop='articleBody' class='article-content'><slot /></div>
<script define:vars={{ tocTitle }}> <script is:inline define:vars={{ tocTitle }}>
var $toc = document.querySelector(".toc"); var $toc = document.querySelector(".toc");
if ($toc) { if ($toc) {
$toc.querySelector("summary").textContent = tocTitle; $toc.querySelector("summary").textContent = tocTitle;

View File

@ -6,7 +6,8 @@ import { getArticleList } from "@root/queries/article";
const t = useTranslation(Astro); const t = useTranslation(Astro);
const pageLang = getLanguageFromURL(Astro.url.pathname); const pageLang = getLanguageFromURL(Astro.url.pathname);
const articles = (await getArticleList()).flatMap((a) => filterArticlesByPageLang(a.translations, pageLang)); const data = await getArticleList();
const articles = filterArticlesByPageLang(data, pageLang);
const articleBlocks = formatToArticleBlocks(articles); const articleBlocks = formatToArticleBlocks(articles);
--- ---

View File

@ -5,16 +5,12 @@ import ArticleItem from "@components/ArticleItem";
import EmptyList from "@components/EmptyList.astro"; import EmptyList from "@components/EmptyList.astro";
import UIString from "@components/UIString.astro"; import UIString from "@components/UIString.astro";
import TranslatedLink from "@components/TranslatedLink.astro"; import TranslatedLink from "@components/TranslatedLink.astro";
import { getRecentArticleList } from "../queries"; import { getRecentArticleList, getSiteSettings } from "../queries";
export interface Props {
limit?: number;
}
const { limit = 1 } = Astro.props;
const pageLang = getLanguageFromURL(Astro.url.pathname); const pageLang = getLanguageFromURL(Astro.url.pathname);
const data = await getRecentArticleList(); const siteSettings = await getSiteSettings();
const articles = data.flatMap((a) => utils.filterArticlesByPageLang(a.translations, pageLang)); const data = await getRecentArticleList(siteSettings?.recent_articles_limit || 5);
const articles = utils.filterArticlesByPageLang(data, pageLang);
const isEmpty = articles.length === 0; const isEmpty = articles.length === 0;
--- ---
@ -30,12 +26,7 @@ const isEmpty = articles.length === 0;
<div itemscope itemtype='http://schema.org/Blog'> <div itemscope itemtype='http://schema.org/Blog'>
{ {
!isEmpty ? ( !isEmpty ? (
articles articles.map((a) => (
.slice(0, limit)
.reverse()
.map(
(a) =>
a && (
<ArticleItem <ArticleItem
slug={a.slug} slug={a.slug}
title={a.title} title={a.title}
@ -43,8 +34,7 @@ const isEmpty = articles.length === 0;
pub_date={a.pub_date} pub_date={a.pub_date}
pageLang={pageLang} pageLang={pageLang}
/> />
) ))
)
) : ( ) : (
<EmptyList /> <EmptyList />
) )

View File

@ -1,60 +0,0 @@
---
import { buildToc } from "@root/utils";
import type { MarkdownHeading } from "astro";
import TableOfContentsHeading from "./TableOfContentsHeading.astro";
import { useTranslation } from "@root/i18n/utils";
export interface Props {
headings: MarkdownHeading[];
}
const toc = buildToc(Astro.props.headings, 3);
const t = useTranslation(Astro);
---
<details class='toc'>
<summary>{t("article.tableOfContents")}</summary>
<nav>
<div>
<ul>
{toc.map((heading) => <TableOfContentsHeading heading={heading} />)}
</ul>
</div>
</nav>
</details>
<script>
var $toc = document.querySelector(".toc");
if ($toc) {
$toc.addEventListener("click", (e) => (e.target as HTMLElement).tagName === "A" && $toc!.removeAttribute("open"));
}
</script>
<style lang='scss' is:global>
.toc {
cursor: pointer;
display: block;
position: absolute;
& summary {
font-size: var(--font-size-lg);
}
& nav {
background-color: var(--background-card);
border: 1px solid var(--border-color);
border-radius: var(--border-radius-lg);
margin-top: 10px;
padding: 10px 16px;
& ul {
& a {
display: block;
margin-bottom: 10px;
color: var(--font-color);
text-decoration: none;
}
& li ul {
margin-left: 15px;
}
}
}
}
</style>

View File

@ -1,16 +0,0 @@
---
import type { MarkdownHeadingToc } from "@root/utils";
export interface Props {
heading: MarkdownHeadingToc;
}
const { heading } = Astro.props;
---
<li>
<a href={`#${heading.slug}`}>{heading.text}</a>
<ul>
{heading.subheadings?.map((subheading) => <Astro.self heading={subheading} />)}
</ul>
</li>

View File

@ -17,8 +17,8 @@ import * as types from './graphql';
type Documents = { type Documents = {
"\n\t\tquery LatestAppealByClientIpQuery($client_ip: String!, $limit: Int!) {\n\t\t\tappeal(filter: { client_ip: { _eq: $client_ip } }, sort: [\"-date_created\"], limit: $limit) {\n\t\t\t\tclient_ip\n\t\t\t\tdate_created\n\t\t\t}\n\t\t}\n\t": typeof types.LatestAppealByClientIpQueryDocument, "\n\t\tquery LatestAppealByClientIpQuery($client_ip: String!, $limit: Int!) {\n\t\t\tappeal(filter: { client_ip: { _eq: $client_ip } }, sort: [\"-date_created\"], limit: $limit) {\n\t\t\t\tclient_ip\n\t\t\t\tdate_created\n\t\t\t}\n\t\t}\n\t": typeof types.LatestAppealByClientIpQueryDocument,
"\n\t\tmutation CreateAppealQuery(\n\t\t\t$name: String!\n\t\t\t$email: String!\n\t\t\t$subject: String!\n\t\t\t$message: String!\n\t\t\t$client_ip: String!\n\t\t) {\n\t\t\tcreate_appeal_item(\n\t\t\t\tdata: { name: $name, email: $email, subject: $subject, message: $message, client_ip: $client_ip }\n\t\t\t) {\n\t\t\t\tid\n\t\t\t}\n\t\t}\n\t": typeof types.CreateAppealQueryDocument, "\n\t\tmutation CreateAppealQuery(\n\t\t\t$name: String!\n\t\t\t$email: String!\n\t\t\t$subject: String!\n\t\t\t$message: String!\n\t\t\t$client_ip: String!\n\t\t) {\n\t\t\tcreate_appeal_item(\n\t\t\t\tdata: { name: $name, email: $email, subject: $subject, message: $message, client_ip: $client_ip }\n\t\t\t) {\n\t\t\t\tid\n\t\t\t}\n\t\t}\n\t": typeof types.CreateAppealQueryDocument,
"\n\t\tquery Article {\n\t\t\tarticle {\n\t\t\t\ttranslations(filter: { status: { _eq: \"published\" } }) {\n\t\t\t\t\tid\n\t\t\t\t\ttitle\n\t\t\t\t\ttags {\n\t\t\t\t\t\ttag_id {\n\t\t\t\t\t\t\ttitle\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tdescription\n\t\t\t\t\tslug\n\t\t\t\t\tpub_date\n\t\t\t\t\tlanguages_code {\n\t\t\t\t\t\tcode\n\t\t\t\t\t\tname\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t": typeof types.ArticleDocument, "\n\t\tquery Article {\n\t\t\tarticle_translations(filter: { status: { _eq: \"published\" } }) {\n\t\t\t\tid\n\t\t\t\ttitle\n\t\t\t\ttags {\n\t\t\t\t\ttag_id {\n\t\t\t\t\t\ttitle\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tdescription\n\t\t\t\tslug\n\t\t\t\tpub_date\n\t\t\t\tlanguages_code {\n\t\t\t\t\tcode\n\t\t\t\t\tname\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t": typeof types.ArticleDocument,
"\n\t\tquery RecentArticle {\n\t\t\tarticle {\n\t\t\t\ttranslations(filter: { status: { _eq: \"published\" } }, sort: [\"-pub_date\"]) {\n\t\t\t\t\ttitle\n\t\t\t\t\tcover_image {\n\t\t\t\t\t\tid\n\t\t\t\t\t\ttitle\n\t\t\t\t\t}\n\t\t\t\t\tslug\n\t\t\t\t\tpub_date\n\t\t\t\t\tviews\n\t\t\t\t\tlanguages_code {\n\t\t\t\t\t\tcode\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t": typeof types.RecentArticleDocument, "\n\t\tquery RecentArticle($limit: Int!) {\n\t\t\tarticle_translations(filter: { status: { _eq: \"published\" } }, sort: [\"-pub_date\"], limit: $limit) {\n\t\t\t\ttitle\n\t\t\t\tslug\n\t\t\t\tpub_date\n\t\t\t\tlanguages_code {\n\t\t\t\t\tcode\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t": typeof types.RecentArticleDocument,
"\n\t\tquery Article_translations($slug: String!) {\n\t\t\tarticle_translations(filter: { slug: { _eq: $slug } }) {\n\t\t\t\tid\n\t\t\t\ttitle\n\t\t\t\ttags {\n\t\t\t\t\ttag_id {\n\t\t\t\t\t\ttitle\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tdescription\n\t\t\t\tslug\n\t\t\t\tcontent\n\t\t\t\tauthor {\n\t\t\t\t\tfirst_name\n\t\t\t\t\tlast_name\n\t\t\t\t}\n\t\t\t\tpub_date\n\t\t\t\tviews\n\t\t\t\tlanguages_code {\n\t\t\t\t\tcode\n\t\t\t\t\tname\n\t\t\t\t}\n\t\t\t\tcover_image {\n\t\t\t\t\ttitle\n\t\t\t\t\ttype\n\t\t\t\t\tfilename_disk\n\t\t\t\t}\n\t\t\t\tarticle_id {\n\t\t\t\t\ttranslations {\n\t\t\t\t\t\tslug\n\t\t\t\t\t\tlanguages_code {\n\t\t\t\t\t\t\tcode\n\t\t\t\t\t\t\tname\n\t\t\t\t\t\t}\n\t\t\t\t\t\tpub_date\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t": typeof types.Article_TranslationsDocument, "\n\t\tquery Article_translations($slug: String!) {\n\t\t\tarticle_translations(filter: { slug: { _eq: $slug } }) {\n\t\t\t\tid\n\t\t\t\ttitle\n\t\t\t\ttags {\n\t\t\t\t\ttag_id {\n\t\t\t\t\t\ttitle\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tdescription\n\t\t\t\tslug\n\t\t\t\tcontent\n\t\t\t\tauthor {\n\t\t\t\t\tfirst_name\n\t\t\t\t\tlast_name\n\t\t\t\t}\n\t\t\t\tpub_date\n\t\t\t\tviews\n\t\t\t\tlanguages_code {\n\t\t\t\t\tcode\n\t\t\t\t\tname\n\t\t\t\t}\n\t\t\t\tcover_image {\n\t\t\t\t\ttitle\n\t\t\t\t\ttype\n\t\t\t\t\tfilename_disk\n\t\t\t\t}\n\t\t\t\tarticle_id {\n\t\t\t\t\ttranslations {\n\t\t\t\t\t\tslug\n\t\t\t\t\t\tlanguages_code {\n\t\t\t\t\t\t\tcode\n\t\t\t\t\t\t\tname\n\t\t\t\t\t\t}\n\t\t\t\t\t\tpub_date\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t": typeof types.Article_TranslationsDocument,
"\n\t\tmutation Update_article_translations_item($id: ID!, $views: Int!) {\n\t\t\tupdate_article_translations_item(id: $id, data: { views: $views }) {\n\t\t\t\tviews\n\t\t\t}\n\t\t}\n\t": typeof types.Update_Article_Translations_ItemDocument, "\n\t\tmutation Update_article_translations_item($id: ID!, $views: Int!) {\n\t\t\tupdate_article_translations_item(id: $id, data: { views: $views }) {\n\t\t\t\tviews\n\t\t\t}\n\t\t}\n\t": typeof types.Update_Article_Translations_ItemDocument,
"\n\t\tquery AboutMeQuery($pageLang: String!) {\n\t\t\tglobal_translations(filter: { languages_code: { code: { _contains: $pageLang } } }) {\n\t\t\t\tabout\n\t\t\t}\n\t\t}\n\t": typeof types.AboutMeQueryDocument, "\n\t\tquery AboutMeQuery($pageLang: String!) {\n\t\t\tglobal_translations(filter: { languages_code: { code: { _contains: $pageLang } } }) {\n\t\t\t\tabout\n\t\t\t}\n\t\t}\n\t": typeof types.AboutMeQueryDocument,
@ -30,8 +30,8 @@ type Documents = {
const documents: Documents = { const documents: Documents = {
"\n\t\tquery LatestAppealByClientIpQuery($client_ip: String!, $limit: Int!) {\n\t\t\tappeal(filter: { client_ip: { _eq: $client_ip } }, sort: [\"-date_created\"], limit: $limit) {\n\t\t\t\tclient_ip\n\t\t\t\tdate_created\n\t\t\t}\n\t\t}\n\t": types.LatestAppealByClientIpQueryDocument, "\n\t\tquery LatestAppealByClientIpQuery($client_ip: String!, $limit: Int!) {\n\t\t\tappeal(filter: { client_ip: { _eq: $client_ip } }, sort: [\"-date_created\"], limit: $limit) {\n\t\t\t\tclient_ip\n\t\t\t\tdate_created\n\t\t\t}\n\t\t}\n\t": types.LatestAppealByClientIpQueryDocument,
"\n\t\tmutation CreateAppealQuery(\n\t\t\t$name: String!\n\t\t\t$email: String!\n\t\t\t$subject: String!\n\t\t\t$message: String!\n\t\t\t$client_ip: String!\n\t\t) {\n\t\t\tcreate_appeal_item(\n\t\t\t\tdata: { name: $name, email: $email, subject: $subject, message: $message, client_ip: $client_ip }\n\t\t\t) {\n\t\t\t\tid\n\t\t\t}\n\t\t}\n\t": types.CreateAppealQueryDocument, "\n\t\tmutation CreateAppealQuery(\n\t\t\t$name: String!\n\t\t\t$email: String!\n\t\t\t$subject: String!\n\t\t\t$message: String!\n\t\t\t$client_ip: String!\n\t\t) {\n\t\t\tcreate_appeal_item(\n\t\t\t\tdata: { name: $name, email: $email, subject: $subject, message: $message, client_ip: $client_ip }\n\t\t\t) {\n\t\t\t\tid\n\t\t\t}\n\t\t}\n\t": types.CreateAppealQueryDocument,
"\n\t\tquery Article {\n\t\t\tarticle {\n\t\t\t\ttranslations(filter: { status: { _eq: \"published\" } }) {\n\t\t\t\t\tid\n\t\t\t\t\ttitle\n\t\t\t\t\ttags {\n\t\t\t\t\t\ttag_id {\n\t\t\t\t\t\t\ttitle\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tdescription\n\t\t\t\t\tslug\n\t\t\t\t\tpub_date\n\t\t\t\t\tlanguages_code {\n\t\t\t\t\t\tcode\n\t\t\t\t\t\tname\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t": types.ArticleDocument, "\n\t\tquery Article {\n\t\t\tarticle_translations(filter: { status: { _eq: \"published\" } }) {\n\t\t\t\tid\n\t\t\t\ttitle\n\t\t\t\ttags {\n\t\t\t\t\ttag_id {\n\t\t\t\t\t\ttitle\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tdescription\n\t\t\t\tslug\n\t\t\t\tpub_date\n\t\t\t\tlanguages_code {\n\t\t\t\t\tcode\n\t\t\t\t\tname\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t": types.ArticleDocument,
"\n\t\tquery RecentArticle {\n\t\t\tarticle {\n\t\t\t\ttranslations(filter: { status: { _eq: \"published\" } }, sort: [\"-pub_date\"]) {\n\t\t\t\t\ttitle\n\t\t\t\t\tcover_image {\n\t\t\t\t\t\tid\n\t\t\t\t\t\ttitle\n\t\t\t\t\t}\n\t\t\t\t\tslug\n\t\t\t\t\tpub_date\n\t\t\t\t\tviews\n\t\t\t\t\tlanguages_code {\n\t\t\t\t\t\tcode\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t": types.RecentArticleDocument, "\n\t\tquery RecentArticle($limit: Int!) {\n\t\t\tarticle_translations(filter: { status: { _eq: \"published\" } }, sort: [\"-pub_date\"], limit: $limit) {\n\t\t\t\ttitle\n\t\t\t\tslug\n\t\t\t\tpub_date\n\t\t\t\tlanguages_code {\n\t\t\t\t\tcode\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t": types.RecentArticleDocument,
"\n\t\tquery Article_translations($slug: String!) {\n\t\t\tarticle_translations(filter: { slug: { _eq: $slug } }) {\n\t\t\t\tid\n\t\t\t\ttitle\n\t\t\t\ttags {\n\t\t\t\t\ttag_id {\n\t\t\t\t\t\ttitle\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tdescription\n\t\t\t\tslug\n\t\t\t\tcontent\n\t\t\t\tauthor {\n\t\t\t\t\tfirst_name\n\t\t\t\t\tlast_name\n\t\t\t\t}\n\t\t\t\tpub_date\n\t\t\t\tviews\n\t\t\t\tlanguages_code {\n\t\t\t\t\tcode\n\t\t\t\t\tname\n\t\t\t\t}\n\t\t\t\tcover_image {\n\t\t\t\t\ttitle\n\t\t\t\t\ttype\n\t\t\t\t\tfilename_disk\n\t\t\t\t}\n\t\t\t\tarticle_id {\n\t\t\t\t\ttranslations {\n\t\t\t\t\t\tslug\n\t\t\t\t\t\tlanguages_code {\n\t\t\t\t\t\t\tcode\n\t\t\t\t\t\t\tname\n\t\t\t\t\t\t}\n\t\t\t\t\t\tpub_date\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t": types.Article_TranslationsDocument, "\n\t\tquery Article_translations($slug: String!) {\n\t\t\tarticle_translations(filter: { slug: { _eq: $slug } }) {\n\t\t\t\tid\n\t\t\t\ttitle\n\t\t\t\ttags {\n\t\t\t\t\ttag_id {\n\t\t\t\t\t\ttitle\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tdescription\n\t\t\t\tslug\n\t\t\t\tcontent\n\t\t\t\tauthor {\n\t\t\t\t\tfirst_name\n\t\t\t\t\tlast_name\n\t\t\t\t}\n\t\t\t\tpub_date\n\t\t\t\tviews\n\t\t\t\tlanguages_code {\n\t\t\t\t\tcode\n\t\t\t\t\tname\n\t\t\t\t}\n\t\t\t\tcover_image {\n\t\t\t\t\ttitle\n\t\t\t\t\ttype\n\t\t\t\t\tfilename_disk\n\t\t\t\t}\n\t\t\t\tarticle_id {\n\t\t\t\t\ttranslations {\n\t\t\t\t\t\tslug\n\t\t\t\t\t\tlanguages_code {\n\t\t\t\t\t\t\tcode\n\t\t\t\t\t\t\tname\n\t\t\t\t\t\t}\n\t\t\t\t\t\tpub_date\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t": types.Article_TranslationsDocument,
"\n\t\tmutation Update_article_translations_item($id: ID!, $views: Int!) {\n\t\t\tupdate_article_translations_item(id: $id, data: { views: $views }) {\n\t\t\t\tviews\n\t\t\t}\n\t\t}\n\t": types.Update_Article_Translations_ItemDocument, "\n\t\tmutation Update_article_translations_item($id: ID!, $views: Int!) {\n\t\t\tupdate_article_translations_item(id: $id, data: { views: $views }) {\n\t\t\t\tviews\n\t\t\t}\n\t\t}\n\t": types.Update_Article_Translations_ItemDocument,
"\n\t\tquery AboutMeQuery($pageLang: String!) {\n\t\t\tglobal_translations(filter: { languages_code: { code: { _contains: $pageLang } } }) {\n\t\t\t\tabout\n\t\t\t}\n\t\t}\n\t": types.AboutMeQueryDocument, "\n\t\tquery AboutMeQuery($pageLang: String!) {\n\t\t\tglobal_translations(filter: { languages_code: { code: { _contains: $pageLang } } }) {\n\t\t\t\tabout\n\t\t\t}\n\t\t}\n\t": types.AboutMeQueryDocument,
@ -52,11 +52,11 @@ export function graphql(source: "\n\t\tmutation CreateAppealQuery(\n\t\t\t$name:
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql(source: "\n\t\tquery Article {\n\t\t\tarticle {\n\t\t\t\ttranslations(filter: { status: { _eq: \"published\" } }) {\n\t\t\t\t\tid\n\t\t\t\t\ttitle\n\t\t\t\t\ttags {\n\t\t\t\t\t\ttag_id {\n\t\t\t\t\t\t\ttitle\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tdescription\n\t\t\t\t\tslug\n\t\t\t\t\tpub_date\n\t\t\t\t\tlanguages_code {\n\t\t\t\t\t\tcode\n\t\t\t\t\t\tname\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t"): typeof import('./graphql').ArticleDocument; export function graphql(source: "\n\t\tquery Article {\n\t\t\tarticle_translations(filter: { status: { _eq: \"published\" } }) {\n\t\t\t\tid\n\t\t\t\ttitle\n\t\t\t\ttags {\n\t\t\t\t\ttag_id {\n\t\t\t\t\t\ttitle\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tdescription\n\t\t\t\tslug\n\t\t\t\tpub_date\n\t\t\t\tlanguages_code {\n\t\t\t\t\tcode\n\t\t\t\t\tname\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t"): typeof import('./graphql').ArticleDocument;
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql(source: "\n\t\tquery RecentArticle {\n\t\t\tarticle {\n\t\t\t\ttranslations(filter: { status: { _eq: \"published\" } }, sort: [\"-pub_date\"]) {\n\t\t\t\t\ttitle\n\t\t\t\t\tcover_image {\n\t\t\t\t\t\tid\n\t\t\t\t\t\ttitle\n\t\t\t\t\t}\n\t\t\t\t\tslug\n\t\t\t\t\tpub_date\n\t\t\t\t\tviews\n\t\t\t\t\tlanguages_code {\n\t\t\t\t\t\tcode\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t"): typeof import('./graphql').RecentArticleDocument; export function graphql(source: "\n\t\tquery RecentArticle($limit: Int!) {\n\t\t\tarticle_translations(filter: { status: { _eq: \"published\" } }, sort: [\"-pub_date\"], limit: $limit) {\n\t\t\t\ttitle\n\t\t\t\tslug\n\t\t\t\tpub_date\n\t\t\t\tlanguages_code {\n\t\t\t\t\tcode\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t"): typeof import('./graphql').RecentArticleDocument;
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */

View File

@ -4544,12 +4544,14 @@ export type CreateAppealQueryMutation = { __typename?: 'Mutation', create_appeal
export type ArticleQueryVariables = Exact<{ [key: string]: never; }>; export type ArticleQueryVariables = Exact<{ [key: string]: never; }>;
export type ArticleQuery = { __typename?: 'Query', article: Array<{ __typename?: 'article', translations?: Array<{ __typename?: 'article_translations', id: string, title: string, description: string, slug: string, pub_date: any, tags?: Array<{ __typename?: 'article_translations_tag', tag_id?: { __typename?: 'tag', title: string } | null } | null> | null, languages_code?: { __typename?: 'languages', code: string, name?: string | null } | null } | null> | null }> }; export type ArticleQuery = { __typename?: 'Query', article_translations: Array<{ __typename?: 'article_translations', id: string, title: string, description: string, slug: string, pub_date: any, tags?: Array<{ __typename?: 'article_translations_tag', tag_id?: { __typename?: 'tag', title: string } | null } | null> | null, languages_code?: { __typename?: 'languages', code: string, name?: string | null } | null }> };
export type RecentArticleQueryVariables = Exact<{ [key: string]: never; }>; export type RecentArticleQueryVariables = Exact<{
limit: Scalars['Int']['input'];
}>;
export type RecentArticleQuery = { __typename?: 'Query', article: Array<{ __typename?: 'article', translations?: Array<{ __typename?: 'article_translations', title: string, slug: string, pub_date: any, views: number, cover_image?: { __typename?: 'directus_files', id: string, title?: string | null } | null, languages_code?: { __typename?: 'languages', code: string } | null } | null> | null }> }; export type RecentArticleQuery = { __typename?: 'Query', article_translations: Array<{ __typename?: 'article_translations', title: string, slug: string, pub_date: any, languages_code?: { __typename?: 'languages', code: string } | null }> };
export type Article_TranslationsQueryVariables = Exact<{ export type Article_TranslationsQueryVariables = Exact<{
slug: Scalars['String']['input']; slug: Scalars['String']['input'];
@ -4637,8 +4639,7 @@ export const CreateAppealQueryDocument = new TypedDocumentString(`
`) as unknown as TypedDocumentString<CreateAppealQueryMutation, CreateAppealQueryMutationVariables>; `) as unknown as TypedDocumentString<CreateAppealQueryMutation, CreateAppealQueryMutationVariables>;
export const ArticleDocument = new TypedDocumentString(` export const ArticleDocument = new TypedDocumentString(`
query Article { query Article {
article { article_translations(filter: {status: {_eq: "published"}}) {
translations(filter: {status: {_eq: "published"}}) {
id id
title title
tags { tags {
@ -4654,26 +4655,22 @@ export const ArticleDocument = new TypedDocumentString(`
name name
} }
} }
}
} }
`) as unknown as TypedDocumentString<ArticleQuery, ArticleQueryVariables>; `) as unknown as TypedDocumentString<ArticleQuery, ArticleQueryVariables>;
export const RecentArticleDocument = new TypedDocumentString(` export const RecentArticleDocument = new TypedDocumentString(`
query RecentArticle { query RecentArticle($limit: Int!) {
article { article_translations(
translations(filter: {status: {_eq: "published"}}, sort: ["-pub_date"]) { filter: {status: {_eq: "published"}}
sort: ["-pub_date"]
limit: $limit
) {
title title
cover_image {
id
title
}
slug slug
pub_date pub_date
views
languages_code { languages_code {
code code
} }
} }
}
} }
`) as unknown as TypedDocumentString<RecentArticleQuery, RecentArticleQueryVariables>; `) as unknown as TypedDocumentString<RecentArticleQuery, RecentArticleQueryVariables>;
export const Article_TranslationsDocument = new TypedDocumentString(` export const Article_TranslationsDocument = new TypedDocumentString(`

View File

@ -5,8 +5,7 @@ import { Article_Translations } from "../graphql/graphql";
export async function getArticleList() { export async function getArticleList() {
const ArticleQuery = graphql(` const ArticleQuery = graphql(`
query Article { query Article {
article { article_translations(filter: { status: { _eq: "published" } }) {
translations(filter: { status: { _eq: "published" } }) {
id id
title title
tags { tags {
@ -23,42 +22,34 @@ export async function getArticleList() {
} }
} }
} }
}
`); `);
const result = await execute(ArticleQuery); const result = await execute(ArticleQuery);
if (!result.data) return []; if (!result.data) return [];
return result.data.article; return result.data.article_translations;
} }
export async function getRecentArticleList() { export async function getRecentArticleList(limit: number = 5) {
const RecentArticleQuery = graphql(` const RecentArticleQuery = graphql(`
query RecentArticle { query RecentArticle($limit: Int!) {
article { article_translations(filter: { status: { _eq: "published" } }, sort: ["-pub_date"], limit: $limit) {
translations(filter: { status: { _eq: "published" } }, sort: ["-pub_date"]) {
title title
cover_image {
id
title
}
slug slug
pub_date pub_date
views
languages_code { languages_code {
code code
} }
} }
} }
}
`); `);
const result = await execute(RecentArticleQuery); const result = await execute(RecentArticleQuery, { limit });
if (!result.data) return []; if (!result.data) return [];
return result.data.article; return result.data.article_translations;
} }
export async function getArticleTranslationsBySlug(slug: string) { export async function getArticleTranslationsBySlug(slug: string) {

View File

@ -28,5 +28,5 @@ const t = useTranslation(Astro);
</SplashLink> </SplashLink>
</SplashLinks> </SplashLinks>
</Splash> </Splash>
<RecentArticles limit={5} /> <RecentArticles />
</PageLayout> </PageLayout>

View File

@ -1,13 +1,12 @@
import type { MarkdownHeading } from "astro";
import { DEFAULT_LANGUAGE } from "@root/constants"; import { DEFAULT_LANGUAGE } from "@root/constants";
import { ArticleQuery } from "../graphql/graphql"; import { Article_Translations, ArticleQuery } from "../graphql/graphql";
/** /**
* If there is a translation of an article in the current language of the page, * If there is a translation of an article in the current language of the page,
* the remaining articles with other translations should be removed. * the remaining articles with other translations should be removed.
*/ */
export function filterArticlesByPageLang( export function filterArticlesByPageLang<T>(
articles: ArticleQuery["article"][number]["translations"], articles: Array<T & Pick<Article_Translations, "languages_code">>,
pageLang: LanguageKeys pageLang: LanguageKeys
) { ) {
if (!articles) return []; if (!articles) return [];
@ -33,8 +32,8 @@ export function createRelativeArticleUrl(
return `${lang}/${prefix}/${date}/${slug}`; return `${lang}/${prefix}/${date}/${slug}`;
} }
export function formatToArticleBlocks(articles: ArticleQuery["article"][0]["translations"]) { export function formatToArticleBlocks<T>(articles: Array<T & Pick<Article_Translations, "pub_date">>) {
const blocks: Record<string, ArticleQuery["article"][0]["translations"]> = {}; const blocks: Record<string, Array<T & Pick<Article_Translations, "pub_date">>> = {};
if (!articles) return {}; if (!articles) return {};
@ -48,21 +47,3 @@ export function formatToArticleBlocks(articles: ArticleQuery["article"][0]["tran
return blocks; return blocks;
} }
export type MarkdownHeadingToc = MarkdownHeading & { subheadings?: MarkdownHeading[] };
export function buildToc(headings: MarkdownHeading[], maxDepth: number = 2) {
const toc: MarkdownHeadingToc[] = [];
const parentHeadings = new Map();
headings.forEach((h) => {
const heading = { ...h, subheadings: [] };
parentHeadings.set(heading.depth, heading);
if (heading.depth === 1) {
toc.push(heading);
} else if (heading.depth <= maxDepth) {
parentHeadings.get(heading.depth - 1)?.subheadings.push(heading);
}
});
return toc;
}