Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(DocPage): Add updatedAt meta #198

Merged
merged 11 commits into from
Jan 17, 2024
3 changes: 2 additions & 1 deletion demo/src/Components/DocPage/page-en.json
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,8 @@
"name": "Anastasia Karavaeva",
"url": ""
}
]
],
"updatedAt": "2024-01-15T15:00:00.000Z"
},
"toc": {
"title": "Yandex.Cloud overview",
Expand Down
3 changes: 2 additions & 1 deletion demo/src/Components/DocPage/page-he.json
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,8 @@
"name": "DataUI VCS Robot",
"url": ""
}
]
],
"updatedAt": "2024-01-15T15:00:00.000Z"
},
"toc": {
"title": "סקירת פלטפורמה",
Expand Down
3 changes: 2 additions & 1 deletion demo/src/Components/DocPage/page-ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,8 @@
"name": "DataUI VCS Robot",
"url": ""
}
]
],
"updatedAt": "2024-01-15T15:00:00.000Z"
},
"toc": {
"title": "Обзор платформы",
Expand Down
21 changes: 17 additions & 4 deletions src/components/DocPage/DocPage.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, {ReactPortal} from 'react';
import React, {Fragment, ReactPortal} from 'react';

import {Link} from '@gravity-ui/icons';
import block from 'bem-cn-lite';
Expand Down Expand Up @@ -28,6 +28,7 @@ import {HTML} from '../HTML';
import {MiniToc} from '../MiniToc';
import {SearchBar, withHighlightedSearchWords} from '../SearchBar';
import {TocNavPanel} from '../TocNavPanel';
import UpdatedAtDate from '../UpdatedAtDate/UpdatedAtDate';

import './DocPage.scss';

Expand Down Expand Up @@ -382,18 +383,30 @@ class DocPage extends React.Component<DocPageInnerProps, DocPageState> {
return null;
}

const updatedAt = this.renderUpdatedAt(meta?.updatedAt);
const author = this.renderAuthor(!meta?.contributors?.length);
const contributors = this.renderContributors();

const separator = author && contributors && <div className={b('separator')}>{','}</div>;

return (
<div className={b('page-contributors')}>
{author} {separator} {contributors}
{[updatedAt, author, contributors].filter(Boolean).map((element, idx, arr) => (
<Fragment key={idx}>
{element}
{arr.length - 1 !== idx && <div className={b('separator')}>{','}</div>}
</Fragment>
))}
</div>
);
}

private renderUpdatedAt(updatedAt?: string) {
if (!updatedAt) {
return null;
}

return <UpdatedAtDate updatedAt={updatedAt} />;
}

private renderAuthor(onlyAuthor: boolean) {
const {meta} = this.props;

Expand Down
10 changes: 10 additions & 0 deletions src/components/UpdatedAtDate/UpdatedAtDate.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
@import '../../styles/mixins';

.updated-at-date {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
.updated-at-date {
.dc-updated-at-date {

display: flex;
margin: 0 0 32px;

&__title {
@include contributors-text();
}
}
35 changes: 35 additions & 0 deletions src/components/UpdatedAtDate/UpdatedAtDate.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React, {memo, useMemo} from 'react';

import block from 'bem-cn-lite';

import {getConfig} from '../../config';
import {useTranslation} from '../../hooks';
import {format} from '../../utils/date';

import './UpdatedAtDate.scss';

const b = block('updated-at-date');

export interface UpdatedAtDateProps {
updatedAt: string;
translationName?: string;
}

const UpdatedAtDate: React.FC<UpdatedAtDateProps> = (props) => {
const {updatedAt, translationName = 'updated-at-date'} = props;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Зачем давать возможность переопределять этот ключ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Почему то тоже самое мы позволяем делать в Contributors
https://github.com/diplodoc-platform/components/blob/master/src/components/Contributors/Contributors.tsx
Уберу

const {t} = useTranslation(translationName);

const updatedAtFormatted = useMemo(() => {
const {localeCode} = getConfig();
return format(updatedAt, 'longDateTime', localeCode);
}, [updatedAt]);

return (
<div className={b()}>
<div className={b('title')}>{t<string>('title')}</div>
{updatedAtFormatted}
</div>
);
};

export default memo(UpdatedAtDate);
3 changes: 3 additions & 0 deletions src/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -113,5 +113,8 @@
"paginator": {
"next": "Next page",
"prev": "Previous page"
},
"updated-at-date": {
"label-updated-at": "Updated at"
}
}
3 changes: 3 additions & 0 deletions src/i18n/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -113,5 +113,8 @@
"paginator": {
"next": "Следующая страница",
"prev": "Предыдущая страница"
},
"updated-at-date": {
"label-updated-at": "Обновлено"
}
}
2 changes: 2 additions & 0 deletions src/models/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export enum ControlSizes {
export interface Config {
lang?: string;
loc?: Loc;
localeCode?: string;
}

export interface DocSettings {
Expand Down Expand Up @@ -92,6 +93,7 @@ export interface DocMeta {
contributors?: Contributor[];
author?: unknown | Contributor;
__system?: Record<string, unknown>;
updatedAt?: string;
}

export interface TocData {
Expand Down
81 changes: 81 additions & 0 deletions src/utils/date.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
interface DateTimeFormatter {
longDate: Intl.DateTimeFormat;
shortDate: Intl.DateTimeFormat;
longMonthDay: Intl.DateTimeFormat;
shortMonthDay: Intl.DateTimeFormat;
longDateTime: Intl.DateTimeFormat;
shortDateTime: Intl.DateTimeFormat;
shortTime: Intl.DateTimeFormat;
nanoTime: Intl.DateTimeFormat;
year: Intl.DateTimeFormat;
}

const defaultRegion = 'en';

const dateTimeFormatters: Map<string, DateTimeFormatter> = new Map();

function getDateTimeFormatter(localeCode: string): DateTimeFormatter {
if (!dateTimeFormatters.has(localeCode)) {
const formatters = {
// December 20, 2012
longDate: new Intl.DateTimeFormat(localeCode, {
year: 'numeric',
month: 'long',
day: 'numeric',
}),
// 4/30/2021
shortDate: new Intl.DateTimeFormat(localeCode, {
year: 'numeric',
month: 'numeric',
day: 'numeric',
}),
// December 20
longMonthDay: new Intl.DateTimeFormat(localeCode, {month: 'long', day: 'numeric'}),
// 12/20
shortMonthDay: new Intl.DateTimeFormat(localeCode, {month: 'numeric', day: 'numeric'}),
// April 27, 2021, 3:03 PM
longDateTime: new Intl.DateTimeFormat(localeCode, {
year: 'numeric',
month: 'long',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
}),
// 4/30/2021, 2:30 PM
shortDateTime: new Intl.DateTimeFormat(localeCode, {
year: 'numeric',
month: 'numeric',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
}),
// 12:30
shortTime: new Intl.DateTimeFormat(localeCode, {hour: 'numeric', minute: 'numeric'}),
// 30:58
nanoTime: new Intl.DateTimeFormat(localeCode, {
minute: 'numeric',
second: 'numeric',
}),
// 2023
year: new Intl.DateTimeFormat(localeCode, {
year: 'numeric',
}),
};
dateTimeFormatters.set(localeCode, formatters);
}

// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- formatter will be always inserted above
return dateTimeFormatters.get(localeCode)!;
}

export const format = (
date: string | number,
formatCode: keyof DateTimeFormatter,
localeCode = defaultRegion,
) => {
let result = getDateTimeFormatter(localeCode)[formatCode].format(new Date(date));
if (formatCode === 'longDate' && ['ru-RU', 'ru-KZ'].includes(localeCode)) {
result = result.replace(/\sг\.$/, '');
}
return result;
};
Loading