diff --git a/config/searchExcludeRoutes.json b/config/searchExcludeRoutes.json index 5e62546c..31a27ad7 100644 --- a/config/searchExcludeRoutes.json +++ b/config/searchExcludeRoutes.json @@ -1 +1 @@ -["/automations/automations-by-event/welcome-series", "/updates/HVG123РЕ97E"] +["/automations/automations-by-event/welcome-series", "/updates/HVG123РЕ97E", "/updates/BC1ADF523"] diff --git a/docs/account-settings/how-to-create-sublogin.md b/docs/account-settings/how-to-create-sublogin.md index 2d3e83e0..67d2dcac 100644 --- a/docs/account-settings/how-to-create-sublogin.md +++ b/docs/account-settings/how-to-create-sublogin.md @@ -1,6 +1,12 @@ --- sidebar_position: 1 sidebar_label: 'Как создать учётную запись' +recent_article: + status: update + theses: + - Keisgfsgd + - Lorem + - fgdgsfgasfgafga asdfadfasdf --- # Как создать учётную запись для нового пользователя diff --git a/docs/automations/autoimport/how-to-set-autoexport.mdx b/docs/automations/autoimport/how-to-set-autoexport.mdx index ffe305e1..88e20fc1 100644 --- a/docs/automations/autoimport/how-to-set-autoexport.mdx +++ b/docs/automations/autoimport/how-to-set-autoexport.mdx @@ -1,6 +1,8 @@ --- sidebar_position: 2 sidebar_label: 'Экспорт по шаблону' +recent_article: + status: new --- # Как настроить регулярный экспорт по шаблону diff --git a/docs/updates/docs-list/index.mdx b/docs/updates/docs-list/index.mdx new file mode 100644 index 00000000..6179c603 --- /dev/null +++ b/docs/updates/docs-list/index.mdx @@ -0,0 +1,11 @@ +--- +slug: '/updates/docs-list' +title: 'Новое в Базе знаний' +sidebar_position: 2 +recent_article: + ignore: true +--- + +import DocCardList from '@site/src/theme/DocCardList'; + + diff --git a/docs/updates/docs-list/recent-articles.mdx b/docs/updates/docs-list/recent-articles.mdx new file mode 100644 index 00000000..27a0414a --- /dev/null +++ b/docs/updates/docs-list/recent-articles.mdx @@ -0,0 +1,11 @@ +--- +title: 'Обновления документации' +description: '' +sidebar_position: 2 +recent_article: + ignore: true +--- + +import { RecentlyUpdatedArticlesIframe } from '@site/src/components/RecentlyUpdatedArticles'; + + diff --git a/docs/updates/list/index.mdx b/docs/updates/list/index.mdx index cc04507c..fc7ea5c7 100644 --- a/docs/updates/list/index.mdx +++ b/docs/updates/list/index.mdx @@ -1,9 +1,11 @@ --- slug: '/updates/list' -title: 'Список обновлений' +title: 'Новое в платорме' description: 'Всё про email-рассылки: как создавать выпуски, персонализировать контент и что нужно настраивать дополнительно' -sidebar_position: 2 +sidebar_position: 1 hide_title: true +recent_article: + ignore: true --- import ChangeLog, { toc as changeLogToc } from './2024/updates-november-2024.mdx'; diff --git a/docusaurus.config.ts b/docusaurus.config.ts index 057323a7..261216c3 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -42,13 +42,8 @@ const config: Config = { googleTagManager: { containerId: baseGTM, }, - docs: { - routeBasePath: '/', - sidebarPath: require.resolve('./sidebars.js'), - showLastUpdateTime: true, - editUrl: ({ docPath }) => - `https://github.com/sendsay-ru/sendsay-docs/edit/stable/docs/${docPath}`, - }, + // we use extended version to get recently updated articles + docs: false, theme: { customCss: require.resolve('./src/css/custom.css'), }, diff --git a/i18n/en/code.json b/i18n/en/code.json index 0a910b12..da4d922f 100644 --- a/i18n/en/code.json +++ b/i18n/en/code.json @@ -163,9 +163,13 @@ "description": "Title for link to heading" }, "lastUpdated.atDate": { - "message": "Updated: ", + "message": "Updated:", "description": "The words used to describe on which date a page has been last updated" }, + "lastUpdated.createDate": { + "message": "Published:", + "description": "The words used to describe on which date a page has been published" + }, "theme.lastUpdated.byUser": { "message": " by {user}", "description": "The words used to describe by who the page has been last updated" diff --git a/i18n/en/docusaurus-plugin-content-docs/current/updates/docs-list/index.mdx b/i18n/en/docusaurus-plugin-content-docs/current/updates/docs-list/index.mdx new file mode 100644 index 00000000..f0f79600 --- /dev/null +++ b/i18n/en/docusaurus-plugin-content-docs/current/updates/docs-list/index.mdx @@ -0,0 +1,7 @@ +--- +hide_title: true +--- + +import { Redirect } from '@docusaurus/router'; + +; diff --git a/i18n/en/docusaurus-plugin-content-docs/current/updates/docs-list/recent-articles.mdx b/i18n/en/docusaurus-plugin-content-docs/current/updates/docs-list/recent-articles.mdx new file mode 100644 index 00000000..f0f79600 --- /dev/null +++ b/i18n/en/docusaurus-plugin-content-docs/current/updates/docs-list/recent-articles.mdx @@ -0,0 +1,7 @@ +--- +hide_title: true +--- + +import { Redirect } from '@docusaurus/router'; + +; diff --git a/package.json b/package.json index 1d69bfaf..8f88e059 100644 --- a/package.json +++ b/package.json @@ -47,11 +47,14 @@ "docusaurus-plugin-yandex-metrica": "^1.2.0", "glob": "^8.0.3", "memfs": "^3.4.2", + "node-polyfill-webpack-plugin": "4.1.0", "postcss": "^8.4.33", "prism-react-renderer": "^2.1.0", + "process": "^0.11.10", "react": "^18.2.0", "react-dom": "^18.2.0", - "tailwindcss": "^3.4.1" + "tailwindcss": "^3.4.1", + "webpack": "^5.0.0" }, "devDependencies": { "@docusaurus/module-type-aliases": "^3.6.3", diff --git a/plugins.js b/plugins.js index e9676c94..b47ce5af 100644 --- a/plugins.js +++ b/plugins.js @@ -4,6 +4,17 @@ const yandexMetricaCounter = process.env.YANDEX_METRICA_COUNTER_ID; const plugins = [ './src/plugins/iframe-detected', './src/plugins/tailwind', + './src/plugins/webpackConfig', + [ + './src/plugins/docs-plugin-extended', + { + routeBasePath: '/', + sidebarPath: require.resolve('./sidebars.js'), + showLastUpdateTime: true, + editUrl: ({ docPath }) => + `https://github.com/sendsay-ru/sendsay-docs/edit/stable/docs/${docPath}`, + }, + ], [ 'docusaurus-lunr-search', { diff --git a/src/components/CustomLastUpdate/CustomLastUpdate.tsx b/src/components/CustomLastUpdate/CustomLastUpdate.tsx index 76248e10..3eff52d1 100644 --- a/src/components/CustomLastUpdate/CustomLastUpdate.tsx +++ b/src/components/CustomLastUpdate/CustomLastUpdate.tsx @@ -1,36 +1,77 @@ import React from 'react'; import { translate } from '@docusaurus/Translate'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; +import clsx from 'clsx'; const NBSP = '\u00A0'; -export const CustomLastUpdate = ({ lastUpdatedAt }: { lastUpdatedAt: number }): JSX.Element => { +export const enum CustomLastUpdateType { + Tag = 'tag', + UpdateDate = 'updateDate', + CreationDate = 'creationDate', +} + +interface CustomLastUpdateProps { + lastUpdatedAt: number; + type: CustomLastUpdateType; + frontMatter?: { + recent_article?: { + ignore: boolean; + }; + }; +} + +const UpdateMark = (): JSX.Element =>
; +const NewMark = (): JSX.Element =>
; + +export const CustomLastUpdate = ({ + lastUpdatedAt, + frontMatter = {}, + type = CustomLastUpdateType.Tag, +}: CustomLastUpdateProps): JSX.Element => { const { i18n } = useDocusaurusContext(); const isRuLocale = i18n.currentLocale === 'ru'; - const formattedUpdatedAt = lastUpdatedAt * 1000; + + if (frontMatter.recent_article && frontMatter.recent_article.ignore) { + return null; + } return ( -
- - {translate({ id: 'lastUpdated.atDate', message: 'Обновлено: ' })} +
+
+
+ {type === CustomLastUpdateType.UpdateDate && } + {type === CustomLastUpdateType.CreationDate && } + + {type === CustomLastUpdateType.CreationDate + ? translate({ id: 'lastUpdated.createDate', message: 'Опубликовано:' }) + : translate({ id: 'lastUpdated.atDate', message: 'Обновлено:' })} + {NBSP} +
-
); }; diff --git a/src/components/Feedback/Feedback.tsx b/src/components/Feedback/Feedback.tsx index bc248e67..c1d269a4 100644 --- a/src/components/Feedback/Feedback.tsx +++ b/src/components/Feedback/Feedback.tsx @@ -2,7 +2,7 @@ import React, { useState } from 'react'; import clsx from 'clsx'; import BrowserOnly from '@docusaurus/BrowserOnly'; import { translate } from '@docusaurus/Translate'; -import { useDoc } from '@docusaurus/theme-common/internal'; +import { useDoc } from '@docusaurus/plugin-content-docs/client'; import { PositiveFeedbackIcon, NegativeFeedbackIcon } from '../../ui/icons'; import { pushAnalytics } from '../../utils/analytics'; diff --git a/src/components/RecentlyUpdatedArticles/RecentlyUpdatedArticles.js b/src/components/RecentlyUpdatedArticles/RecentlyUpdatedArticles.js new file mode 100644 index 00000000..c4a372bb --- /dev/null +++ b/src/components/RecentlyUpdatedArticles/RecentlyUpdatedArticles.js @@ -0,0 +1,76 @@ +import React from 'react'; +import Layout from '@theme/Layout'; +import { CustomLastUpdate } from '../CustomLastUpdate'; +import { CustomLastUpdateType } from '../CustomLastUpdate/CustomLastUpdate'; +import { RECENT_ARTICLES_CONTENT_ID } from './constants.js'; + +const NBSP = '\u00A0'; + +const ArticleStatus = { + New: 'new', + Updated: 'updated', +}; + +const RecentlyUpdatedArticlesCard = ({ children, slug }) => { + const handleClick = () => { + document.dispatchEvent(new CustomEvent('redirect', { detail: { slug } })); + }; + + return ( +
+ {children} +
+ ); +}; + +const RecentlyUpdatedArticlesChanges = ({ frontMatter }) => { + const theses = frontMatter?.recent_article?.theses; + + if (!theses) { + return null; + } + + return ( +
+ {theses.map((item, index) => ( + + —{NBSP} + {item} + {index === theses.length - 1 ? '.' : ';'} + + ))} +
+ ); +}; + +const RecentlyUpdatedArticles = ({ recentArticles }) => ( + +
+ {recentArticles.map(({ title, lastUpdatedAt, frontMatter, slug }) => ( + +
+
+ {title} +
+ + +
+ + +
+ ))} +
+
+); + +export default RecentlyUpdatedArticles; diff --git a/src/components/RecentlyUpdatedArticles/RecentlyUpdatedArticlesIframe.tsx b/src/components/RecentlyUpdatedArticles/RecentlyUpdatedArticlesIframe.tsx new file mode 100644 index 00000000..e6b4926a --- /dev/null +++ b/src/components/RecentlyUpdatedArticles/RecentlyUpdatedArticlesIframe.tsx @@ -0,0 +1,54 @@ +import React, { useRef, useState } from 'react'; +import { RECENT_ARTICLES_CONTENT_ID, RECENT_ARTICLES_TEMP_URL } from './constants.js'; +import { useHistory } from '@docusaurus/router'; + +export const RecentlyUpdatedArticlesIframe = () => { + const history = useHistory(); + const iframeRef = useRef(); + + const [isError, setIsError] = useState(false); + + const handleRedirectInIframe: EventListener = ({ detail }: CustomEvent) => { + if (detail?.slug) { + history.push(detail.slug); + } + }; + + const resizeIframe = () => { + if (!iframeRef.current) { + return; + } + + const recentArticleContentElement = iframeRef.current.contentWindow.document.getElementById( + RECENT_ARTICLES_CONTENT_ID + ); + + if (!recentArticleContentElement) { + setIsError(true); + } + + iframeRef.current.style.height = `${recentArticleContentElement?.scrollHeight}px`; + + iframeRef.current?.contentWindow.document.addEventListener('redirect', handleRedirectInIframe); + }; + + if (isError) { + return На странице произошёл сбой.; + } + + return ( +