This commit is contained in:
Sergey Yarkov 2026-01-21 23:17:09 +03:00
parent d8d812a282
commit 515302fed3
11 changed files with 101 additions and 347 deletions

View File

@ -12,6 +12,7 @@ export default defineConfig({
site: "https://yarkov.tech",
compressHTML: true,
output: "server",
prefetch: true,
server: {
port: 9966,
host: true,

View File

@ -32,8 +32,6 @@ type Mutation {
create_appeal_items(data: [create_appeal_input!], filter: appeal_filter, limit: Int, offset: Int, page: Int, search: String, sort: [String]): [appeal!]!
create_article_item(data: create_article_input!): article
create_article_items(data: [create_article_input!], filter: article_filter, limit: Int, offset: Int, page: Int, search: String, sort: [String]): [article!]!
create_article_tag_item(data: create_article_tag_input!): article_tag
create_article_tag_items(data: [create_article_tag_input!], filter: article_tag_filter, limit: Int, offset: Int, page: Int, search: String, sort: [String]): [article_tag!]!
create_article_translations_item(data: create_article_translations_input!): article_translations
create_article_translations_items(data: [create_article_translations_input!], filter: article_translations_filter, limit: Int, offset: Int, page: Int, search: String, sort: [String]): [article_translations!]!
create_article_translations_tag_item(data: create_article_translations_tag_input!): article_translations_tag
@ -54,8 +52,6 @@ type Mutation {
delete_appeal_items(ids: [ID]!): delete_many
delete_article_item(id: ID!): delete_one
delete_article_items(ids: [ID]!): delete_many
delete_article_tag_item(id: ID!): delete_one
delete_article_tag_items(ids: [ID]!): delete_many
delete_article_translations_item(id: ID!): delete_one
delete_article_translations_items(ids: [ID]!): delete_many
delete_article_translations_tag_item(id: ID!): delete_one
@ -78,9 +74,6 @@ type Mutation {
update_article_batch(data: [update_article_input!], filter: article_filter, limit: Int, offset: Int, page: Int, search: String, sort: [String]): [article!]!
update_article_item(data: update_article_input!, id: ID!): article
update_article_items(data: update_article_input!, filter: article_filter, ids: [ID]!, limit: Int, offset: Int, page: Int, search: String, sort: [String]): [article!]!
update_article_tag_batch(data: [update_article_tag_input!], filter: article_tag_filter, limit: Int, offset: Int, page: Int, search: String, sort: [String]): [article_tag!]!
update_article_tag_item(data: update_article_tag_input!, id: ID!): article_tag
update_article_tag_items(data: update_article_tag_input!, filter: article_tag_filter, ids: [ID]!, limit: Int, offset: Int, page: Int, search: String, sort: [String]): [article_tag!]!
update_article_translations_batch(data: [update_article_translations_input!], filter: article_translations_filter, limit: Int, offset: Int, page: Int, search: String, sort: [String]): [article_translations!]!
update_article_translations_item(data: update_article_translations_input!, id: ID!): article_translations
update_article_translations_items(data: update_article_translations_input!, filter: article_translations_filter, ids: [ID]!, limit: Int, offset: Int, page: Int, search: String, sort: [String]): [article_translations!]!
@ -118,10 +111,6 @@ type Query {
article_aggregated(filter: article_filter, groupBy: [String], limit: Int, offset: Int, page: Int, search: String, sort: [String]): [article_aggregated!]!
article_by_id(id: ID!, version: String): article
article_by_version(id: ID!, version: String!): version_article
article_tag(filter: article_tag_filter, limit: Int, offset: Int, page: Int, search: String, sort: [String]): [article_tag!]!
article_tag_aggregated(filter: article_tag_filter, groupBy: [String], limit: Int, offset: Int, page: Int, search: String, sort: [String]): [article_tag_aggregated!]!
article_tag_by_id(id: ID!, version: String): article_tag
article_tag_by_version(id: ID!, version: String!): version_article_tag
article_translations(filter: article_translations_filter, limit: Int, offset: Int, page: Int, search: String, sort: [String]): [article_translations!]!
article_translations_aggregated(filter: article_translations_filter, groupBy: [String], limit: Int, offset: Int, page: Int, search: String, sort: [String]): [article_translations_aggregated!]!
article_translations_by_id(id: ID!, version: String): article_translations
@ -163,7 +152,6 @@ type Query {
type Subscription {
appeal_mutated(event: EventEnum): appeal_mutated
article_mutated(event: EventEnum): article_mutated
article_tag_mutated(event: EventEnum): article_tag_mutated
article_translations_mutated(event: EventEnum): article_translations_mutated
article_translations_tag_mutated(event: EventEnum): article_translations_tag_mutated
directus_access_mutated(event: EventEnum): directus_access_mutated
@ -256,6 +244,7 @@ type appeal_mutated {
type article {
id: ID!
title: String
translations(filter: article_translations_filter, limit: Int, offset: Int, page: Int, search: String, sort: [String]): [article_translations]
translations_func: count_functions
}
@ -275,6 +264,7 @@ type article_aggregated {
type article_aggregated_count {
id: Int
title: Int
translations: Int
}
@ -286,6 +276,7 @@ input article_filter {
_and: [article_filter]
_or: [article_filter]
id: number_filter_operators
title: string_filter_operators
translations: article_translations_quantifier_filter
translations_func: count_function_filter_operators
}
@ -296,51 +287,6 @@ type article_mutated {
key: ID!
}
type article_tag {
article_id(filter: article_filter, limit: Int, offset: Int, page: Int, search: String, sort: [String]): article
id: ID!
tag_id(filter: tag_filter, limit: Int, offset: Int, page: Int, search: String, sort: [String]): tag
}
type article_tag_aggregated {
avg: article_tag_aggregated_fields
avgDistinct: article_tag_aggregated_fields
count: article_tag_aggregated_count
countAll: Int
countDistinct: article_tag_aggregated_count
group: JSON
max: article_tag_aggregated_fields
min: article_tag_aggregated_fields
sum: article_tag_aggregated_fields
sumDistinct: article_tag_aggregated_fields
}
type article_tag_aggregated_count {
article_id: Int
id: Int
tag_id: Int
}
type article_tag_aggregated_fields {
article_id: Float
id: Float
tag_id: Float
}
input article_tag_filter {
_and: [article_tag_filter]
_or: [article_tag_filter]
article_id: article_filter
id: number_filter_operators
tag_id: tag_filter
}
type article_tag_mutated {
data: article_tag
event: EventEnum
key: ID!
}
type article_translations {
article_id(filter: article_filter, limit: Int, offset: Int, page: Int, search: String, sort: [String]): article
author(filter: directus_users_filter, limit: Int, offset: Int, page: Int, search: String, sort: [String]): directus_users
@ -541,15 +487,10 @@ input create_appeal_input {
input create_article_input {
id: ID
title: String
translations: [create_article_translations_input]
}
input create_article_tag_input {
article_id: create_article_input
id: ID
tag_id: create_tag_input
}
input create_article_translations_input {
article_id: create_article_input
author: create_directus_users_input
@ -722,7 +663,7 @@ input create_home_page_translations_input {
input create_languages_input {
code: ID!
direction: String
name: String
name: String!
}
input create_project_input {
@ -1959,7 +1900,7 @@ input id_filter_operators {
type languages {
code: ID!
direction: String
name: String
name: String!
}
type languages_aggregated {
@ -2204,15 +2145,10 @@ input update_appeal_input {
input update_article_input {
id: ID
title: String
translations: [update_article_translations_input]
}
input update_article_tag_input {
article_id: update_article_input
id: ID
tag_id: update_tag_input
}
input update_article_translations_input {
article_id: update_article_input
author: update_directus_users_input
@ -2423,15 +2359,10 @@ type version_appeal {
type version_article {
id: ID
title: String
translations: JSON
}
type version_article_tag {
article_id: JSON
id: ID
tag_id: JSON
}
type version_article_translations {
article_id: JSON
author: JSON

View File

@ -6,8 +6,8 @@ import { ArticleQuery } from "@/src/graphql/graphql";
import "./ArticlesList.scss";
type UiStringsType = { "articles.empty": string };
type ArticlesBlockType = Record<string, ArticleQuery["article"][0]["translations"]>;
type Articles = ArticleQuery["article_translations"];
type ArticlesBlockType = Record<string, Articles>;
type ArticlesListProps = {
articles: ArticlesBlockType;
@ -31,9 +31,7 @@ const ArticlesList: Component<ArticlesListProps> = (props) => {
}: {
params: { search: string; tags?: string[] };
}): ArticlesBlockType => {
const filter = (
cb: (articles: ArticleQuery["article"][0]["translations"]) => ArticleQuery["article"][0]["translations"]
) => {
const filter = (cb: (articles: Articles) => Articles) => {
return Object.fromEntries(
Object.keys(props.articles)
.map((year) => [year, cb(props.articles[year])])

View File

@ -6,11 +6,12 @@ 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 data = await getRecentArticleList(siteSettings?.recent_articles_limit || 5);
const articles = utils.filterArticlesByPageLang(data, pageLang);
const articles = await getRecentArticleList(siteSettings?.recent_articles_limit || 5);
const filteredArticles = utils.filterArticlesByPageLang<RecentArticleQuery>(articles, pageLang);
const isEmpty = articles.length === 0;
---
@ -26,7 +27,7 @@ const isEmpty = articles.length === 0;
<div itemscope itemtype='http://schema.org/Blog'>
{
!isEmpty ? (
articles.map((a) => (
filteredArticles.map((a) => (
<ArticleItem
slug={a.slug}
title={a.title}

View File

@ -13,4 +13,4 @@ if (!SUPPORTED_LANGUAGES.includes(pageLang)) pageLang = DEFAULT_LANGUAGE;
const href = pageLang === DEFAULT_LANGUAGE ? to : `/${pageLang}${to}`;
---
<a href={href} {...attrs}><slot /></a>
<a data-astro-prefetch href={href} {...attrs}><slot /></a>

View File

@ -1,6 +1,6 @@
import siteconfig from "../siteconfig.json";
export const DEFAULT_LANGUAGE: LanguageKeys = "ru";
export const DEFAULT_LANGUAGE: LanguageKeys = "en";
export const IS_SITE_UNDER_CONSTRUCTION = siteconfig.isSiteUnderConstruction;
export const SUPPORTED_LANGUAGES: SupportedLanguages = ["ru", "en"];
export const URL_BLOG_PREFIX = "blog";

View File

@ -17,8 +17,8 @@ import * as types from './graphql';
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_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($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 {\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 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,
@ -30,8 +30,8 @@ type 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\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_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($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 {\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 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,
@ -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.
*/
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;
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;
/**
* 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_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;
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;
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/

View File

@ -38,8 +38,6 @@ export type Mutation = {
create_appeal_items: Array<Appeal>;
create_article_item?: Maybe<Article>;
create_article_items: Array<Article>;
create_article_tag_item?: Maybe<Article_Tag>;
create_article_tag_items: Array<Article_Tag>;
create_article_translations_item?: Maybe<Article_Translations>;
create_article_translations_items: Array<Article_Translations>;
create_article_translations_tag_item?: Maybe<Article_Translations_Tag>;
@ -60,8 +58,6 @@ export type Mutation = {
delete_appeal_items?: Maybe<Delete_Many>;
delete_article_item?: Maybe<Delete_One>;
delete_article_items?: Maybe<Delete_Many>;
delete_article_tag_item?: Maybe<Delete_One>;
delete_article_tag_items?: Maybe<Delete_Many>;
delete_article_translations_item?: Maybe<Delete_One>;
delete_article_translations_items?: Maybe<Delete_Many>;
delete_article_translations_tag_item?: Maybe<Delete_One>;
@ -84,9 +80,6 @@ export type Mutation = {
update_article_batch: Array<Article>;
update_article_item?: Maybe<Article>;
update_article_items: Array<Article>;
update_article_tag_batch: Array<Article_Tag>;
update_article_tag_item?: Maybe<Article_Tag>;
update_article_tag_items: Array<Article_Tag>;
update_article_translations_batch: Array<Article_Translations>;
update_article_translations_item?: Maybe<Article_Translations>;
update_article_translations_items: Array<Article_Translations>;
@ -148,22 +141,6 @@ export type MutationCreate_Article_ItemsArgs = {
};
export type MutationCreate_Article_Tag_ItemArgs = {
data: Create_Article_Tag_Input;
};
export type MutationCreate_Article_Tag_ItemsArgs = {
data?: InputMaybe<Array<Create_Article_Tag_Input>>;
filter?: InputMaybe<Article_Tag_Filter>;
limit?: InputMaybe<Scalars['Int']['input']>;
offset?: InputMaybe<Scalars['Int']['input']>;
page?: InputMaybe<Scalars['Int']['input']>;
search?: InputMaybe<Scalars['String']['input']>;
sort?: InputMaybe<Array<InputMaybe<Scalars['String']['input']>>>;
};
export type MutationCreate_Article_Translations_ItemArgs = {
data: Create_Article_Translations_Input;
};
@ -312,16 +289,6 @@ export type MutationDelete_Article_ItemsArgs = {
};
export type MutationDelete_Article_Tag_ItemArgs = {
id: Scalars['ID']['input'];
};
export type MutationDelete_Article_Tag_ItemsArgs = {
ids: Array<InputMaybe<Scalars['ID']['input']>>;
};
export type MutationDelete_Article_Translations_ItemArgs = {
id: Scalars['ID']['input'];
};
@ -460,35 +427,6 @@ export type MutationUpdate_Article_ItemsArgs = {
};
export type MutationUpdate_Article_Tag_BatchArgs = {
data?: InputMaybe<Array<Update_Article_Tag_Input>>;
filter?: InputMaybe<Article_Tag_Filter>;
limit?: InputMaybe<Scalars['Int']['input']>;
offset?: InputMaybe<Scalars['Int']['input']>;
page?: InputMaybe<Scalars['Int']['input']>;
search?: InputMaybe<Scalars['String']['input']>;
sort?: InputMaybe<Array<InputMaybe<Scalars['String']['input']>>>;
};
export type MutationUpdate_Article_Tag_ItemArgs = {
data: Update_Article_Tag_Input;
id: Scalars['ID']['input'];
};
export type MutationUpdate_Article_Tag_ItemsArgs = {
data: Update_Article_Tag_Input;
filter?: InputMaybe<Article_Tag_Filter>;
ids: Array<InputMaybe<Scalars['ID']['input']>>;
limit?: InputMaybe<Scalars['Int']['input']>;
offset?: InputMaybe<Scalars['Int']['input']>;
page?: InputMaybe<Scalars['Int']['input']>;
search?: InputMaybe<Scalars['String']['input']>;
sort?: InputMaybe<Array<InputMaybe<Scalars['String']['input']>>>;
};
export type MutationUpdate_Article_Translations_BatchArgs = {
data?: InputMaybe<Array<Update_Article_Translations_Input>>;
filter?: InputMaybe<Article_Translations_Filter>;
@ -740,10 +678,6 @@ export type Query = {
article_aggregated: Array<Article_Aggregated>;
article_by_id?: Maybe<Article>;
article_by_version?: Maybe<Version_Article>;
article_tag: Array<Article_Tag>;
article_tag_aggregated: Array<Article_Tag_Aggregated>;
article_tag_by_id?: Maybe<Article_Tag>;
article_tag_by_version?: Maybe<Version_Article_Tag>;
article_translations: Array<Article_Translations>;
article_translations_aggregated: Array<Article_Translations_Aggregated>;
article_translations_by_id?: Maybe<Article_Translations>;
@ -849,39 +783,6 @@ export type QueryArticle_By_VersionArgs = {
};
export type QueryArticle_TagArgs = {
filter?: InputMaybe<Article_Tag_Filter>;
limit?: InputMaybe<Scalars['Int']['input']>;
offset?: InputMaybe<Scalars['Int']['input']>;
page?: InputMaybe<Scalars['Int']['input']>;
search?: InputMaybe<Scalars['String']['input']>;
sort?: InputMaybe<Array<InputMaybe<Scalars['String']['input']>>>;
};
export type QueryArticle_Tag_AggregatedArgs = {
filter?: InputMaybe<Article_Tag_Filter>;
groupBy?: InputMaybe<Array<InputMaybe<Scalars['String']['input']>>>;
limit?: InputMaybe<Scalars['Int']['input']>;
offset?: InputMaybe<Scalars['Int']['input']>;
page?: InputMaybe<Scalars['Int']['input']>;
search?: InputMaybe<Scalars['String']['input']>;
sort?: InputMaybe<Array<InputMaybe<Scalars['String']['input']>>>;
};
export type QueryArticle_Tag_By_IdArgs = {
id: Scalars['ID']['input'];
version?: InputMaybe<Scalars['String']['input']>;
};
export type QueryArticle_Tag_By_VersionArgs = {
id: Scalars['ID']['input'];
version: Scalars['String']['input'];
};
export type QueryArticle_TranslationsArgs = {
filter?: InputMaybe<Article_Translations_Filter>;
limit?: InputMaybe<Scalars['Int']['input']>;
@ -1169,7 +1070,6 @@ export type Subscription = {
__typename?: 'Subscription';
appeal_mutated?: Maybe<Appeal_Mutated>;
article_mutated?: Maybe<Article_Mutated>;
article_tag_mutated?: Maybe<Article_Tag_Mutated>;
article_translations_mutated?: Maybe<Article_Translations_Mutated>;
article_translations_tag_mutated?: Maybe<Article_Translations_Tag_Mutated>;
directus_access_mutated?: Maybe<Directus_Access_Mutated>;
@ -1214,11 +1114,6 @@ export type SubscriptionArticle_MutatedArgs = {
};
export type SubscriptionArticle_Tag_MutatedArgs = {
event?: InputMaybe<EventEnum>;
};
export type SubscriptionArticle_Translations_MutatedArgs = {
event?: InputMaybe<EventEnum>;
};
@ -1438,6 +1333,7 @@ export type Appeal_Mutated = {
export type Article = {
__typename?: 'article';
id: Scalars['ID']['output'];
title?: Maybe<Scalars['String']['output']>;
translations?: Maybe<Array<Maybe<Article_Translations>>>;
translations_func?: Maybe<Count_Functions>;
};
@ -1469,6 +1365,7 @@ export type Article_Aggregated = {
export type Article_Aggregated_Count = {
__typename?: 'article_aggregated_count';
id?: Maybe<Scalars['Int']['output']>;
title?: Maybe<Scalars['Int']['output']>;
translations?: Maybe<Scalars['Int']['output']>;
};
@ -1481,6 +1378,7 @@ export type Article_Filter = {
_and?: InputMaybe<Array<InputMaybe<Article_Filter>>>;
_or?: InputMaybe<Array<InputMaybe<Article_Filter>>>;
id?: InputMaybe<Number_Filter_Operators>;
title?: InputMaybe<String_Filter_Operators>;
translations?: InputMaybe<Article_Translations_Quantifier_Filter>;
translations_func?: InputMaybe<Count_Function_Filter_Operators>;
};
@ -1492,76 +1390,6 @@ export type Article_Mutated = {
key: Scalars['ID']['output'];
};
export type Article_Tag = {
__typename?: 'article_tag';
article_id?: Maybe<Article>;
id: Scalars['ID']['output'];
tag_id?: Maybe<Tag>;
};
export type Article_TagArticle_IdArgs = {
filter?: InputMaybe<Article_Filter>;
limit?: InputMaybe<Scalars['Int']['input']>;
offset?: InputMaybe<Scalars['Int']['input']>;
page?: InputMaybe<Scalars['Int']['input']>;
search?: InputMaybe<Scalars['String']['input']>;
sort?: InputMaybe<Array<InputMaybe<Scalars['String']['input']>>>;
};
export type Article_TagTag_IdArgs = {
filter?: InputMaybe<Tag_Filter>;
limit?: InputMaybe<Scalars['Int']['input']>;
offset?: InputMaybe<Scalars['Int']['input']>;
page?: InputMaybe<Scalars['Int']['input']>;
search?: InputMaybe<Scalars['String']['input']>;
sort?: InputMaybe<Array<InputMaybe<Scalars['String']['input']>>>;
};
export type Article_Tag_Aggregated = {
__typename?: 'article_tag_aggregated';
avg?: Maybe<Article_Tag_Aggregated_Fields>;
avgDistinct?: Maybe<Article_Tag_Aggregated_Fields>;
count?: Maybe<Article_Tag_Aggregated_Count>;
countAll?: Maybe<Scalars['Int']['output']>;
countDistinct?: Maybe<Article_Tag_Aggregated_Count>;
group?: Maybe<Scalars['JSON']['output']>;
max?: Maybe<Article_Tag_Aggregated_Fields>;
min?: Maybe<Article_Tag_Aggregated_Fields>;
sum?: Maybe<Article_Tag_Aggregated_Fields>;
sumDistinct?: Maybe<Article_Tag_Aggregated_Fields>;
};
export type Article_Tag_Aggregated_Count = {
__typename?: 'article_tag_aggregated_count';
article_id?: Maybe<Scalars['Int']['output']>;
id?: Maybe<Scalars['Int']['output']>;
tag_id?: Maybe<Scalars['Int']['output']>;
};
export type Article_Tag_Aggregated_Fields = {
__typename?: 'article_tag_aggregated_fields';
article_id?: Maybe<Scalars['Float']['output']>;
id?: Maybe<Scalars['Float']['output']>;
tag_id?: Maybe<Scalars['Float']['output']>;
};
export type Article_Tag_Filter = {
_and?: InputMaybe<Array<InputMaybe<Article_Tag_Filter>>>;
_or?: InputMaybe<Array<InputMaybe<Article_Tag_Filter>>>;
article_id?: InputMaybe<Article_Filter>;
id?: InputMaybe<Number_Filter_Operators>;
tag_id?: InputMaybe<Tag_Filter>;
};
export type Article_Tag_Mutated = {
__typename?: 'article_tag_mutated';
data?: Maybe<Article_Tag>;
event?: Maybe<EventEnum>;
key: Scalars['ID']['output'];
};
export type Article_Translations = {
__typename?: 'article_translations';
article_id?: Maybe<Article>;
@ -1843,15 +1671,10 @@ export type Create_Appeal_Input = {
export type Create_Article_Input = {
id?: InputMaybe<Scalars['ID']['input']>;
title?: InputMaybe<Scalars['String']['input']>;
translations?: InputMaybe<Array<InputMaybe<Create_Article_Translations_Input>>>;
};
export type Create_Article_Tag_Input = {
article_id?: InputMaybe<Create_Article_Input>;
id?: InputMaybe<Scalars['ID']['input']>;
tag_id?: InputMaybe<Create_Tag_Input>;
};
export type Create_Article_Translations_Input = {
article_id?: InputMaybe<Create_Article_Input>;
author?: InputMaybe<Create_Directus_Users_Input>;
@ -2024,7 +1847,7 @@ export type Create_Home_Page_Translations_Input = {
export type Create_Languages_Input = {
code: Scalars['ID']['input'];
direction?: InputMaybe<Scalars['String']['input']>;
name?: InputMaybe<Scalars['String']['input']>;
name: Scalars['String']['input'];
};
export type Create_Project_Input = {
@ -3891,7 +3714,7 @@ export type Languages = {
__typename?: 'languages';
code: Scalars['ID']['output'];
direction?: Maybe<Scalars['String']['output']>;
name?: Maybe<Scalars['String']['output']>;
name: Scalars['String']['output'];
};
export type Languages_Aggregated = {
@ -4194,15 +4017,10 @@ export type Update_Appeal_Input = {
export type Update_Article_Input = {
id?: InputMaybe<Scalars['ID']['input']>;
title?: InputMaybe<Scalars['String']['input']>;
translations?: InputMaybe<Array<InputMaybe<Update_Article_Translations_Input>>>;
};
export type Update_Article_Tag_Input = {
article_id?: InputMaybe<Update_Article_Input>;
id?: InputMaybe<Scalars['ID']['input']>;
tag_id?: InputMaybe<Update_Tag_Input>;
};
export type Update_Article_Translations_Input = {
article_id?: InputMaybe<Update_Article_Input>;
author?: InputMaybe<Update_Directus_Users_Input>;
@ -4415,16 +4233,10 @@ export type Version_Appeal = {
export type Version_Article = {
__typename?: 'version_article';
id?: Maybe<Scalars['ID']['output']>;
title?: Maybe<Scalars['String']['output']>;
translations?: Maybe<Scalars['JSON']['output']>;
};
export type Version_Article_Tag = {
__typename?: 'version_article_tag';
article_id?: Maybe<Scalars['JSON']['output']>;
id?: Maybe<Scalars['ID']['output']>;
tag_id?: Maybe<Scalars['JSON']['output']>;
};
export type Version_Article_Translations = {
__typename?: 'version_article_translations';
article_id?: Maybe<Scalars['JSON']['output']>;
@ -4544,21 +4356,21 @@ export type CreateAppealQueryMutation = { __typename?: 'Mutation', create_appeal
export type ArticleQueryVariables = Exact<{ [key: string]: never; }>;
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 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 }> };
export type RecentArticleQueryVariables = Exact<{
limit: Scalars['Int']['input'];
}>;
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 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 Article_TranslationsQueryVariables = Exact<{
slug: Scalars['String']['input'];
}>;
export type Article_TranslationsQuery = { __typename?: 'Query', article_translations: Array<{ __typename?: 'article_translations', id: string, title: string, description: string, slug: string, content: string, pub_date: any, views: number, tags?: Array<{ __typename?: 'article_translations_tag', tag_id?: { __typename?: 'tag', title: string } | null } | null> | null, author?: { __typename?: 'directus_users', first_name?: string | null, last_name?: string | null } | null, languages_code?: { __typename?: 'languages', code: string, name?: string | null } | null, cover_image?: { __typename?: 'directus_files', title?: string | null, type?: string | null, filename_disk?: string | null } | null, article_id?: { __typename?: 'article', translations?: Array<{ __typename?: 'article_translations', slug: string, pub_date: any, languages_code?: { __typename?: 'languages', code: string, name?: string | null } | null } | null> | null } | null }> };
export type Article_TranslationsQuery = { __typename?: 'Query', article_translations: Array<{ __typename?: 'article_translations', id: string, title: string, description: string, slug: string, content: string, pub_date: any, views: number, tags?: Array<{ __typename?: 'article_translations_tag', tag_id?: { __typename?: 'tag', title: string } | null } | null> | null, author?: { __typename?: 'directus_users', first_name?: string | null, last_name?: string | null } | null, languages_code?: { __typename?: 'languages', code: string, name: string } | null, cover_image?: { __typename?: 'directus_files', title?: string | null, type?: string | null, filename_disk?: string | null } | null, article_id?: { __typename?: 'article', translations?: Array<{ __typename?: 'article_translations', slug: string, pub_date: any, languages_code?: { __typename?: 'languages', code: string, name: string } | null } | null> | null } | null }> };
export type Update_Article_Translations_ItemMutationVariables = Exact<{
id: Scalars['ID']['input'];
@ -4639,36 +4451,36 @@ export const CreateAppealQueryDocument = new TypedDocumentString(`
`) as unknown as TypedDocumentString<CreateAppealQueryMutation, CreateAppealQueryMutationVariables>;
export const ArticleDocument = new TypedDocumentString(`
query Article {
article_translations(filter: {status: {_eq: "published"}}) {
id
title
tags {
tag_id {
title
article {
translations(filter: {status: {_eq: "published"}}) {
id
title
tags {
tag_id {
title
}
}
description
slug
pub_date
languages_code {
code
name
}
}
description
slug
pub_date
languages_code {
code
name
}
}
}
`) as unknown as TypedDocumentString<ArticleQuery, ArticleQueryVariables>;
export const RecentArticleDocument = new TypedDocumentString(`
query RecentArticle($limit: Int!) {
article_translations(
filter: {status: {_eq: "published"}}
sort: ["-pub_date"]
limit: $limit
) {
title
slug
pub_date
languages_code {
code
article(limit: $limit, sort: ["-translations.pub_date"]) {
translations(filter: {status: {_eq: "published"}}) {
title
slug
pub_date
languages_code {
code
}
}
}
}

View File

@ -6,7 +6,7 @@ import { getArticleList } from "../queries";
// TODO: generate feed for RU, EN, ... languages
export async function GET() {
const articles = (await getArticleList()).flatMap((a) => a.translations);
const articles = await getArticleList();
return rss({
title: SITE_METADATA.name,
description: utils.translate("site.description", "ru"),

View File

@ -5,20 +5,22 @@ import { Article_Translations } from "../graphql/graphql";
export async function getArticleList() {
const ArticleQuery = graphql(`
query Article {
article_translations(filter: { status: { _eq: "published" } }) {
id
title
tags {
tag_id {
title
article {
translations(filter: { status: { _eq: "published" } }) {
id
title
tags {
tag_id {
title
}
}
description
slug
pub_date
languages_code {
code
name
}
}
description
slug
pub_date
languages_code {
code
name
}
}
}
@ -28,18 +30,20 @@ export async function getArticleList() {
if (!result.data) return [];
return result.data.article_translations;
return result.data.article;
}
export async function getRecentArticleList(limit: number = 5) {
const RecentArticleQuery = graphql(`
query RecentArticle($limit: Int!) {
article_translations(filter: { status: { _eq: "published" } }, sort: ["-pub_date"], limit: $limit) {
title
slug
pub_date
languages_code {
code
article(limit: $limit, sort: ["-translations.pub_date"]) {
translations(filter: { status: { _eq: "published" } }) {
title
slug
pub_date
languages_code {
code
}
}
}
}
@ -49,7 +53,7 @@ export async function getRecentArticleList(limit: number = 5) {
if (!result.data) return [];
return result.data.article_translations;
return result.data.article;
}
export async function getArticleTranslationsBySlug(slug: string) {

View File

@ -1,21 +1,28 @@
import { DEFAULT_LANGUAGE } from "@root/constants";
import { Article_Translations, ArticleQuery } from "../graphql/graphql";
import { Article, Article_Translations, 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<T>(
articles: Array<T & Pick<Article_Translations, "languages_code">>,
export function filterArticlesByPageLang<QueryT extends RecentArticleQuery>(
articles: QueryT["article"][0],
pageLang: LanguageKeys
) {
if (!articles) return [];
if (articles && articles.length >= 2) {
const pageLangArticles = articles.filter((a) => a && a.languages_code?.code.split("-")[0] === pageLang);
if (pageLangArticles.length !== 0) return pageLangArticles;
return articles;
}
return articles;
const filteredArticles = articles.flatMap((a) => {
// Filter by articles by page lang
if (a.translations.length >= 2) {
const pageLangTranslations = a.translations.filter((a) => a.languages_code?.code.split("-")[0] === pageLang);
if (pageLangTranslations.length !== 0) return pageLangTranslations;
// No articles found by page lang. Return first translation.
return [a.translations[0]];
}
return a.translations;
});
return filteredArticles;
}
/**