From 7c11115c4452b6d452a79bcb7838b70ae7631c7e Mon Sep 17 00:00:00 2001 From: Fedor Abrashin Date: Mon, 9 Dec 2024 12:56:50 +0300 Subject: [PATCH] feat(docs): add last time edit date --- docusaurus.config.ts | 212 +++++++++--------- i18n/en/code.json | 2 +- package.json | 1 + .../CustomLastUpdate/CustomLastUpdate.tsx | 29 +++ src/components/CustomLastUpdate/index.tsx | 1 + src/theme/DocItem/Footer/index.tsx | 39 ++-- src/theme/DocItem/Layout/index.tsx | 80 +++++++ src/theme/DocItem/Layout/styles.module.css | 10 + yarn.lock | 103 ++++++++- 9 files changed, 351 insertions(+), 126 deletions(-) create mode 100644 src/components/CustomLastUpdate/CustomLastUpdate.tsx create mode 100644 src/components/CustomLastUpdate/index.tsx create mode 100644 src/theme/DocItem/Layout/index.tsx create mode 100644 src/theme/DocItem/Layout/styles.module.css diff --git a/docusaurus.config.ts b/docusaurus.config.ts index 443ec5e6..057323a7 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -1,10 +1,10 @@ -import dotenv from 'dotenv' +import dotenv from 'dotenv'; import type { Config } from '@docusaurus/types'; import type { Options, ThemeConfig } from '@docusaurus/preset-classic'; -import { themes } from 'prism-react-renderer' +import { themes } from 'prism-react-renderer'; import plugins from './plugins'; -dotenv.config() +dotenv.config(); const googleVerificationCode = process.env.GOOGLE_VERIFICATION_CODE; const yandexVerificationCode = process.env.YANDEX_VERIFICATION_CODE; @@ -45,6 +45,7 @@ const config: Config = { docs: { routeBasePath: '/', sidebarPath: require.resolve('./sidebars.js'), + showLastUpdateTime: true, editUrl: ({ docPath }) => `https://github.com/sendsay-ru/sendsay-docs/edit/stable/docs/${docPath}`, }, @@ -58,116 +59,115 @@ const config: Config = { ], ], - themeConfig: - { - navbar: { - logo: { - alt: 'Sendsay docs', - src: 'img/logo.svg', - className: 'no-border', - }, - items: [ - { - type: 'dropdown', - label: 'Главная', - labelMode: 'dynamic', - position: 'left', - items: [ - { - type: 'docSidebar', - sidebarId: 'docs', - label: 'Главная', - }, - { - type: 'docSidebar', - sidebarId: 'integrations', - label: 'Интеграции', - }, - { - type: 'docSidebar', - sidebarId: 'videolessons', - label: 'Видеоуроки', - }, - { - type: 'docSidebar', - sidebarId: 'updates', - label: 'Обновления', - }, - ], - }, - { - type: 'docSidebar', - position: 'left', - sidebarId: 'docs', - label: 'Главная', - displayedLocale: 'ru', - }, - { - type: 'docSidebar', - position: 'left', - sidebarId: 'integrations', - label: 'Интеграции', - displayedLocale: 'ru', - }, - { - type: 'docSidebar', - position: 'left', - sidebarId: 'videolessons', - label: 'Видеоуроки', - displayedLocale: 'ru', - }, - { - type: 'docSidebar', - position: 'left', - sidebarId: 'updates', - label: 'Обновления', - displayedLocale: 'ru', - }, - { - href: 'https://app.sendsay.ru', - label: 'Sendsay', - position: 'right', - }, - { - href: 'https://sendsay.ru/api/api.html', - label: 'API', - position: 'right', - }, - { - type: 'localeDropdown', - position: 'right', - }, - ], - }, - footer: { - style: 'light', - copyright: `Copyright © ${new Date().getFullYear()} Sendsay.`, - }, - prism: { - theme: themes.github, - darkTheme: themes.dracula, + themeConfig: { + navbar: { + logo: { + alt: 'Sendsay docs', + src: 'img/logo.svg', + className: 'no-border', }, - colorMode: { - disableSwitch: true, - }, - zoom: { - selector: '.markdown img', - background: { - light: 'rgb(255, 255, 255)', - dark: 'rgb(50, 50, 50)', + items: [ + { + type: 'dropdown', + label: 'Главная', + labelMode: 'dynamic', + position: 'left', + items: [ + { + type: 'docSidebar', + sidebarId: 'docs', + label: 'Главная', + }, + { + type: 'docSidebar', + sidebarId: 'integrations', + label: 'Интеграции', + }, + { + type: 'docSidebar', + sidebarId: 'videolessons', + label: 'Видеоуроки', + }, + { + type: 'docSidebar', + sidebarId: 'updates', + label: 'Обновления', + }, + ], + }, + { + type: 'docSidebar', + position: 'left', + sidebarId: 'docs', + label: 'Главная', + displayedLocale: 'ru', + }, + { + type: 'docSidebar', + position: 'left', + sidebarId: 'integrations', + label: 'Интеграции', + displayedLocale: 'ru', + }, + { + type: 'docSidebar', + position: 'left', + sidebarId: 'videolessons', + label: 'Видеоуроки', + displayedLocale: 'ru', + }, + { + type: 'docSidebar', + position: 'left', + sidebarId: 'updates', + label: 'Обновления', + displayedLocale: 'ru', }, - }, - metadata: [ { - name: 'google-site-verification', - content: googleVerificationCode, + href: 'https://app.sendsay.ru', + label: 'Sendsay', + position: 'right', }, { - name: 'yandex-verification', - content: yandexVerificationCode, + href: 'https://sendsay.ru/api/api.html', + label: 'API', + position: 'right', + }, + { + type: 'localeDropdown', + position: 'right', }, ], - } satisfies ThemeConfig, + }, + footer: { + style: 'light', + copyright: `Copyright © ${new Date().getFullYear()} Sendsay.`, + }, + prism: { + theme: themes.github, + darkTheme: themes.dracula, + }, + colorMode: { + disableSwitch: true, + }, + zoom: { + selector: '.markdown img', + background: { + light: 'rgb(255, 255, 255)', + dark: 'rgb(50, 50, 50)', + }, + }, + metadata: [ + { + name: 'google-site-verification', + content: googleVerificationCode, + }, + { + name: 'yandex-verification', + content: yandexVerificationCode, + }, + ], + } satisfies ThemeConfig, }; module.exports = config; diff --git a/i18n/en/code.json b/i18n/en/code.json index 95aee8e8..4d6dc551 100644 --- a/i18n/en/code.json +++ b/i18n/en/code.json @@ -163,7 +163,7 @@ "description": "Title for link to heading" }, "theme.lastUpdated.atDate": { - "message": " on {date}", + "message": "Updated: {date}", "description": "The words used to describe on which date a page has been last updated" }, "theme.lastUpdated.byUser": { diff --git a/package.json b/package.json index 000a4f7e..8fba5d53 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,7 @@ "prism-react-renderer": "^2.1.0", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-intl": "^7.0.4", "tailwindcss": "^3.4.1" }, "devDependencies": { diff --git a/src/components/CustomLastUpdate/CustomLastUpdate.tsx b/src/components/CustomLastUpdate/CustomLastUpdate.tsx new file mode 100644 index 00000000..1df85e60 --- /dev/null +++ b/src/components/CustomLastUpdate/CustomLastUpdate.tsx @@ -0,0 +1,29 @@ +import React from 'react'; +import Translate from '@docusaurus/Translate'; + +const NARROW_SPACE = '\u202F'; + +export const CustomLastUpdate = ({ lastUpdatedAt }: { lastUpdatedAt: number }): JSX.Element => ( +
+ + {new Intl.DateTimeFormat('ru', { + day: 'numeric', + month: 'long', + timeZone: 'UTC', + }).format(lastUpdatedAt)} + {NARROW_SPACE} + {new Intl.DateTimeFormat('ru', { + year: 'numeric', + }).format(lastUpdatedAt)} + + ), + }} + > + {'Обновлено: {date}'} + +
+); diff --git a/src/components/CustomLastUpdate/index.tsx b/src/components/CustomLastUpdate/index.tsx new file mode 100644 index 00000000..cb0a5f50 --- /dev/null +++ b/src/components/CustomLastUpdate/index.tsx @@ -0,0 +1 @@ +export { CustomLastUpdate } from './CustomLastUpdate'; diff --git a/src/theme/DocItem/Footer/index.tsx b/src/theme/DocItem/Footer/index.tsx index 5398d180..33709923 100644 --- a/src/theme/DocItem/Footer/index.tsx +++ b/src/theme/DocItem/Footer/index.tsx @@ -8,9 +8,8 @@ import LastUpdated from '@theme/LastUpdated'; import EditThisPage from '@theme/EditThisPage'; import TagsListInline, { type Props as TagsListInlineProps } from '@theme/TagsListInline'; import { Feedback } from '../../../components/Feedback'; - -import styles from './styles.module.css'; import { useSearchParams } from '../../../hooks'; +import styles from './styles.module.css'; const TagsRow = (props: TagsListInlineProps) => (
@@ -29,33 +28,36 @@ const EditMetaRow = ({ lastUpdatedAt, lastUpdatedBy, formattedLastUpdatedAt, -}: EditMetaRowProps) => ( -
-
{editUrl && }
+}: EditMetaRowProps) => { + const queryParams = useSearchParams(); -
- {(lastUpdatedAt || lastUpdatedBy) && ( - + const isEditorMode = queryParams && queryParams.get('edit') === 'true'; + + return ( +
+ {isEditorMode &&
{editUrl && }
} + + {false && ( +
+ +
)}
-
-); + ); +}; const DocItemFooter = (): JSX.Element | null => { const { metadata } = useDoc(); - const queryParams = useSearchParams(); - - const isEditorMode = queryParams && queryParams.get('edit') === 'true'; const { editUrl, lastUpdatedAt, formattedLastUpdatedAt, lastUpdatedBy, tags } = metadata; const canDisplayTagsRow = tags.length > 0; - const canDisplayEditMetaRow = !!(editUrl || lastUpdatedAt || lastUpdatedBy) && isEditorMode; + const canDisplayEditMetaRow = Boolean(editUrl || lastUpdatedAt || lastUpdatedBy); const canDisplayFooter = canDisplayTagsRow || canDisplayEditMetaRow; @@ -66,6 +68,7 @@ const DocItemFooter = (): JSX.Element | null => { return (