From c41a54072b003731ba992664b49e7dfb2bc97cd6 Mon Sep 17 00:00:00 2001 From: sergeyyarkov Date: Mon, 23 Feb 2026 21:03:12 +0300 Subject: [PATCH] upd --- src/components/ArticlesList.astro | 7 +++--- src/components/ArticlesList/ArticlesList.tsx | 2 +- src/components/RecentArticles.astro | 24 +++++++++++--------- src/graphql/gql.ts | 12 +++++----- src/graphql/graphql.ts | 6 +++-- src/queries/article.ts | 1 + src/queries/global.ts | 1 + src/utils/article.ts | 16 ++++++++----- 8 files changed, 40 insertions(+), 29 deletions(-) diff --git a/src/components/ArticlesList.astro b/src/components/ArticlesList.astro index 90a671e..4ae6234 100644 --- a/src/components/ArticlesList.astro +++ b/src/components/ArticlesList.astro @@ -1,14 +1,15 @@ --- import { useTranslation, getLanguageFromURL } from "@i18n/utils"; -import { filterArticlesByPageLang, formatToArticleBlocks } from "@utils/article"; +import * as utils from "@utils/article"; import List from "@components/ArticlesList"; import { getArticleList } from "@root/queries/article"; +import { ArticleQuery } from "../graphql/graphql"; const t = useTranslation(Astro); const pageLang = getLanguageFromURL(Astro.url.pathname); const data = await getArticleList(); -const articles = filterArticlesByPageLang(data, pageLang); -const articleBlocks = formatToArticleBlocks(articles); +const articles = utils.filterArticlesByPageLang(data, pageLang); +const articleBlocks = utils.formatToArticleBlocks(articles); --- diff --git a/src/components/ArticlesList/ArticlesList.tsx b/src/components/ArticlesList/ArticlesList.tsx index d2782e7..997d8db 100644 --- a/src/components/ArticlesList/ArticlesList.tsx +++ b/src/components/ArticlesList/ArticlesList.tsx @@ -6,7 +6,7 @@ import { ArticleQuery } from "@/src/graphql/graphql"; import "./ArticlesList.scss"; type UiStringsType = { "articles.empty": string }; -type Articles = ArticleQuery["article_translations"]; +type Articles = ArticleQuery["article"][0]["translations"]; type ArticlesBlockType = Record; type ArticlesListProps = { diff --git a/src/components/RecentArticles.astro b/src/components/RecentArticles.astro index c1fdb47..7338425 100644 --- a/src/components/RecentArticles.astro +++ b/src/components/RecentArticles.astro @@ -6,12 +6,11 @@ import EmptyList from "@components/EmptyList.astro"; import UIString from "@components/UIString.astro"; import TranslatedLink from "@components/TranslatedLink.astro"; import { getRecentArticleList, getSiteSettings } from "../queries"; -import { RecentArticleQuery } from "../graphql/graphql"; const pageLang = getLanguageFromURL(Astro.url.pathname); const siteSettings = await getSiteSettings(); const articles = await getRecentArticleList(siteSettings?.recent_articles_limit || 5); -const filteredArticles = utils.filterArticlesByPageLang(articles, pageLang); +const filteredArticles = utils.filterArticlesByPageLang(articles, pageLang); const isEmpty = articles.length === 0; --- @@ -27,15 +26,18 @@ const isEmpty = articles.length === 0;
{ !isEmpty ? ( - filteredArticles.map((a) => ( - - )) + filteredArticles.map( + (a) => + a && ( + + ) + ) ) : ( ) diff --git a/src/graphql/gql.ts b/src/graphql/gql.ts index 0f7b71c..c2f6a11 100644 --- a/src/graphql/gql.ts +++ b/src/graphql/gql.ts @@ -18,12 +18,12 @@ 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\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 RecentArticle($limit: Int!) {\n\t\t\tarticle(limit: $limit, sort: [\"-translations.pub_date\"]) {\n\t\t\t\ttranslations(filter: { status: { _eq: \"published\" } }) {\n\t\t\t\t\ttitle\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}\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(limit: $limit, sort: [\"-translations.pub_date\"]) {\n\t\t\t\ttranslations(filter: { status: { _eq: \"published\" } }) {\n\t\t\t\t\ttitle\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.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\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 ContactsQuery {\n\t\t\tglobal {\n\t\t\t\temail\n\t\t\t\tgithub\n\t\t\t\ttelegram\n\t\t\t}\n\t\t}\n\t": typeof types.ContactsQueryDocument, - "\n\t\tquery SiteSettingsQuery {\n\t\t\tglobal {\n\t\t\t\tym_counter\n\t\t\t\trecent_articles_limit\n\t\t\t}\n\t\t}\n\t": typeof types.SiteSettingsQueryDocument, + "\n\t\tquery SiteSettingsQuery {\n\t\t\tglobal {\n\t\t\t\tym_counter\n\t\t\t\trecent_articles_limit\n\t\t\t\tgithub\n\t\t\t}\n\t\t}\n\t": typeof types.SiteSettingsQueryDocument, "\n\t\tquery Project_translations($pageLang: String!) {\n\t\t\tproject_translations(filter: { languages_code: { code: { _contains: $pageLang } } }, sort: [\"-year\"]) {\n\t\t\t\tid\n\t\t\t\ttitle\n\t\t\t\tyear\n\t\t\t\tdescription\n\t\t\t\tsource_url\n\t\t\t\tdemo_url\n\t\t\t\tarticle_url\n\t\t\t\ticon {\n\t\t\t\t\tfilename_disk\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t": typeof types.Project_TranslationsDocument, "\n\t\tquery Tag {\n\t\t\ttag {\n\t\t\t\tid\n\t\t\t\ttitle\n\t\t\t}\n\t\t}\n\t": typeof types.TagDocument, }; @@ -31,12 +31,12 @@ 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\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 RecentArticle($limit: Int!) {\n\t\t\tarticle(limit: $limit, sort: [\"-translations.pub_date\"]) {\n\t\t\t\ttranslations(filter: { status: { _eq: \"published\" } }) {\n\t\t\t\t\ttitle\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}\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(limit: $limit, sort: [\"-translations.pub_date\"]) {\n\t\t\t\ttranslations(filter: { status: { _eq: \"published\" } }) {\n\t\t\t\t\ttitle\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.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\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 ContactsQuery {\n\t\t\tglobal {\n\t\t\t\temail\n\t\t\t\tgithub\n\t\t\t\ttelegram\n\t\t\t}\n\t\t}\n\t": types.ContactsQueryDocument, - "\n\t\tquery SiteSettingsQuery {\n\t\t\tglobal {\n\t\t\t\tym_counter\n\t\t\t\trecent_articles_limit\n\t\t\t}\n\t\t}\n\t": types.SiteSettingsQueryDocument, + "\n\t\tquery SiteSettingsQuery {\n\t\t\tglobal {\n\t\t\t\tym_counter\n\t\t\t\trecent_articles_limit\n\t\t\t\tgithub\n\t\t\t}\n\t\t}\n\t": types.SiteSettingsQueryDocument, "\n\t\tquery Project_translations($pageLang: String!) {\n\t\t\tproject_translations(filter: { languages_code: { code: { _contains: $pageLang } } }, sort: [\"-year\"]) {\n\t\t\t\tid\n\t\t\t\ttitle\n\t\t\t\tyear\n\t\t\t\tdescription\n\t\t\t\tsource_url\n\t\t\t\tdemo_url\n\t\t\t\tarticle_url\n\t\t\t\ticon {\n\t\t\t\t\tfilename_disk\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t": types.Project_TranslationsDocument, "\n\t\tquery Tag {\n\t\t\ttag {\n\t\t\t\tid\n\t\t\t\ttitle\n\t\t\t}\n\t\t}\n\t": types.TagDocument, }; @@ -56,7 +56,7 @@ export function graphql(source: "\n\t\tquery Article {\n\t\t\tarticle {\n\t\t\t\ /** * 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($limit: Int!) {\n\t\t\tarticle(limit: $limit, sort: [\"-translations.pub_date\"]) {\n\t\t\t\ttranslations(filter: { status: { _eq: \"published\" } }) {\n\t\t\t\t\ttitle\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}\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(limit: $limit, sort: [\"-translations.pub_date\"]) {\n\t\t\t\ttranslations(filter: { status: { _eq: \"published\" } }) {\n\t\t\t\t\ttitle\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').RecentArticleDocument; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ @@ -76,7 +76,7 @@ export function graphql(source: "\n\t\tquery ContactsQuery {\n\t\t\tglobal {\n\t /** * 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 SiteSettingsQuery {\n\t\t\tglobal {\n\t\t\t\tym_counter\n\t\t\t\trecent_articles_limit\n\t\t\t}\n\t\t}\n\t"): typeof import('./graphql').SiteSettingsQueryDocument; +export function graphql(source: "\n\t\tquery SiteSettingsQuery {\n\t\t\tglobal {\n\t\t\t\tym_counter\n\t\t\t\trecent_articles_limit\n\t\t\t\tgithub\n\t\t\t}\n\t\t}\n\t"): typeof import('./graphql').SiteSettingsQueryDocument; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ diff --git a/src/graphql/graphql.ts b/src/graphql/graphql.ts index 894212b..3f83eca 100644 --- a/src/graphql/graphql.ts +++ b/src/graphql/graphql.ts @@ -4363,7 +4363,7 @@ export type RecentArticleQueryVariables = Exact<{ }>; -export type RecentArticleQuery = { __typename?: 'Query', article: Array<{ __typename?: 'article', translations?: Array<{ __typename?: 'article_translations', title: string, slug: string, pub_date: any, languages_code?: { __typename?: 'languages', code: string } | null } | null> | null }> }; +export type RecentArticleQuery = { __typename?: 'Query', article: Array<{ __typename?: 'article', translations?: Array<{ __typename?: 'article_translations', title: string, slug: string, pub_date: any, languages_code?: { __typename?: 'languages', code: string, name: string } | null } | null> | null }> }; export type Article_TranslationsQueryVariables = Exact<{ slug: Scalars['String']['input']; @@ -4395,7 +4395,7 @@ export type ContactsQueryQuery = { __typename?: 'Query', global?: { __typename?: export type SiteSettingsQueryQueryVariables = Exact<{ [key: string]: never; }>; -export type SiteSettingsQueryQuery = { __typename?: 'Query', global?: { __typename?: 'global', ym_counter?: number | null, recent_articles_limit?: number | null } | null }; +export type SiteSettingsQueryQuery = { __typename?: 'Query', global?: { __typename?: 'global', ym_counter?: number | null, recent_articles_limit?: number | null, github: string } | null }; export type Project_TranslationsQueryVariables = Exact<{ pageLang: Scalars['String']['input']; @@ -4480,6 +4480,7 @@ export const RecentArticleDocument = new TypedDocumentString(` pub_date languages_code { code + name } } } @@ -4554,6 +4555,7 @@ export const SiteSettingsQueryDocument = new TypedDocumentString(` global { ym_counter recent_articles_limit + github } } `) as unknown as TypedDocumentString; diff --git a/src/queries/article.ts b/src/queries/article.ts index 8f95505..21e5e09 100644 --- a/src/queries/article.ts +++ b/src/queries/article.ts @@ -43,6 +43,7 @@ export async function getRecentArticleList(limit: number = 5) { pub_date languages_code { code + name } } } diff --git a/src/queries/global.ts b/src/queries/global.ts index 333fd05..ae8c8d4 100644 --- a/src/queries/global.ts +++ b/src/queries/global.ts @@ -39,6 +39,7 @@ export async function getSiteSettings() { global { ym_counter recent_articles_limit + github } } `); diff --git a/src/utils/article.ts b/src/utils/article.ts index fb6e0c4..6fb5495 100644 --- a/src/utils/article.ts +++ b/src/utils/article.ts @@ -1,18 +1,22 @@ import { DEFAULT_LANGUAGE } from "@root/constants"; -import { Article, Article_Translations, RecentArticleQuery } from "../graphql/graphql"; +import { Article_Translations, ArticleQuery, RecentArticleQuery } from "../graphql/graphql"; /** * If there is a translation of an article in the current language of the page, * the remaining articles with other translations should be removed. */ -export function filterArticlesByPageLang( - articles: QueryT["article"][0], +export function filterArticlesByPageLang( + articles: T extends RecentArticleQuery["article"][0]["translations"] + ? RecentArticleQuery["article"] + : ArticleQuery["article"], pageLang: LanguageKeys ) { const filteredArticles = articles.flatMap((a) => { + if (!a.translations) return []; + // Filter by articles by page lang if (a.translations.length >= 2) { - const pageLangTranslations = a.translations.filter((a) => a.languages_code?.code.split("-")[0] === pageLang); + const pageLangTranslations = a.translations.filter((a) => a && a.languages_code?.code.split("-")[0] === pageLang); if (pageLangTranslations.length !== 0) return pageLangTranslations; // No articles found by page lang. Return first translation. @@ -39,8 +43,8 @@ export function createRelativeArticleUrl( return `${lang}/${prefix}/${date}/${slug}`; } -export function formatToArticleBlocks(articles: Array>) { - const blocks: Record>> = {}; +export function formatToArticleBlocks(articles: ArticleQuery["article"][0]["translations"]) { + const blocks: Record = {}; if (!articles) return {};