diff --git a/packages/core/admin/admin/src/content-manager/pages/EditView/Informations/index.js b/packages/core/admin/admin/src/content-manager/pages/EditView/Informations/index.js new file mode 100644 index 0000000000..fdebd57a70 --- /dev/null +++ b/packages/core/admin/admin/src/content-manager/pages/EditView/Informations/index.js @@ -0,0 +1,63 @@ +import React, { useRef } from 'react'; +import { useIntl } from 'react-intl'; +import { useContentManagerEditViewDataManager } from '@strapi/helper-plugin'; +import { Box } from '@strapi/parts/Box'; +import { Divider } from '@strapi/parts/Divider'; +import { Text } from '@strapi/parts/Text'; +import { Row } from '@strapi/parts/Row'; +import { Stack } from '@strapi/parts/Stack'; +import { getTrad } from '../../../utils'; +import getUnits from './utils/getUnits'; + +const Informations = () => { + const { formatMessage, formatRelativeTime } = useIntl(); + const { initialData, isCreatingEntry } = useContentManagerEditViewDataManager(); + + // TODO if timestamps are still configurable in the V4 + const updatedAt = 'updated_at'; + const updatedByFirstname = initialData.updated_by?.firstname || ''; + const updatedByLastname = initialData.updated_by?.lastname || ''; + const updatedByUsername = initialData.updated_by?.username; + const updatedBy = updatedByUsername || `${updatedByFirstname} ${updatedByLastname}`; + const currentTime = useRef(new Date().getTime()); + const timestamp = initialData[updatedAt] + ? new Date(initialData[updatedAt]).getTime() + : Date.now(); + const elapsed = timestamp - currentTime.current; + + const { unit, value } = getUnits(-elapsed); + + return ( + + + {formatMessage({ + id: getTrad('containers.Edit.information'), + defaultMessage: 'Information', + })} + + + + + + + + {formatMessage({ + id: getTrad('containers.Edit.information.lastUpdate'), + })} + + {formatRelativeTime(value, unit, { numeric: 'auto' })} + + + + {formatMessage({ + id: getTrad('containers.Edit.information.by'), + })} + + {isCreatingEntry ? '-' : updatedBy} + + + + ); +}; + +export default Informations; diff --git a/packages/core/admin/admin/src/content-manager/pages/EditView/Informations/tests/index.test.js b/packages/core/admin/admin/src/content-manager/pages/EditView/Informations/tests/index.test.js new file mode 100644 index 0000000000..e0601d0fad --- /dev/null +++ b/packages/core/admin/admin/src/content-manager/pages/EditView/Informations/tests/index.test.js @@ -0,0 +1,178 @@ +/** + * + * Tests for Informations + * + */ + +import React from 'react'; +import { render } from '@testing-library/react'; +import { IntlProvider } from 'react-intl'; +import { useContentManagerEditViewDataManager } from '@strapi/helper-plugin'; +import Theme from '../../../../../components/Theme'; +import Informations from '../index'; + +jest.mock('@strapi/helper-plugin', () => ({ + useContentManagerEditViewDataManager: jest.fn(), +})); + +const makeApp = () => { + return ( + + + + + + ); +}; + +describe('CONTENT MANAGER | EditView | Header', () => { + const RealNow = Date.now; + + beforeAll(() => { + global.Date.now = jest.fn(() => new Date('2021-09-20').getTime()); + }); + + afterAll(() => { + global.Date.now = RealNow; + }); + + it('renders and matches the snaphsot', () => { + useContentManagerEditViewDataManager.mockImplementationOnce(() => ({ + initialData: {}, + isCreatingEntry: true, + })); + + const { + container: { firstChild }, + } = render(makeApp()); + + expect(firstChild).toMatchInlineSnapshot(` + .c1 { + padding-top: 8px; + padding-bottom: 24px; + } + + .c2 { + background: #eaeaef; + } + + .c3 { + height: 1px; + border: none; + margin: 0; + } + + .c0 { + font-weight: 500; + font-size: 0.75rem; + line-height: 1.33; + color: #666687; + } + + .c6 { + font-weight: 500; + font-size: 0.875rem; + line-height: 1.43; + color: #32324d; + } + + .c7 { + font-weight: 400; + font-size: 0.875rem; + line-height: 1.43; + color: #32324d; + } + + .c5 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-flex-direction: row; + -ms-flex-direction: row; + flex-direction: row; + -webkit-box-pack: justify; + -webkit-justify-content: space-between; + -ms-flex-pack: justify; + justify-content: space-between; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + } + + .c4 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; + } + + .c4 > * { + margin-top: 0; + margin-bottom: 0; + } + + .c4 > * + * { + margin-top: 16px; + } + +
+ + Information + +
+
+
+
+
+ + content-manager.containers.Edit.information.lastUpdate + + + 7 hours ago + +
+
+ + content-manager.containers.Edit.information.by + + + - + +
+
+
+ `); + }); +}); diff --git a/packages/core/admin/admin/src/content-manager/pages/EditView/Informations/utils/getUnits.js b/packages/core/admin/admin/src/content-manager/pages/EditView/Informations/utils/getUnits.js new file mode 100644 index 0000000000..89ad6f06c7 --- /dev/null +++ b/packages/core/admin/admin/src/content-manager/pages/EditView/Informations/utils/getUnits.js @@ -0,0 +1,27 @@ +const msPerMinute = 60 * 1000; +const msPerHour = msPerMinute * 60; +const msPerDay = msPerHour * 24; +const msPerMonth = msPerDay * 30; +const msPerYear = msPerDay * 365; + +const getUnits = value => { + if (value < msPerMinute) { + return { unit: 'second', value: -Math.round(value / 1000) }; + } + if (value < msPerHour) { + return { unit: 'minute', value: -Math.round(value / msPerMinute) }; + } + if (value < msPerDay) { + return { unit: 'hour', value: -Math.round(value / msPerHour) }; + } + if (value < msPerMonth) { + return { unit: 'day', value: -Math.round(value / msPerDay) }; + } + if (value < msPerYear) { + return { unit: 'month', value: -Math.round(value / msPerMonth) }; + } + + return { unit: 'year', value: -Math.round(value / msPerYear) }; +}; + +export default getUnits; diff --git a/packages/core/admin/admin/src/content-manager/pages/EditView/index.js b/packages/core/admin/admin/src/content-manager/pages/EditView/index.js index bb0a1d5f0a..effd178f97 100644 --- a/packages/core/admin/admin/src/content-manager/pages/EditView/index.js +++ b/packages/core/admin/admin/src/content-manager/pages/EditView/index.js @@ -29,6 +29,7 @@ import CollectionTypeFormWrapper from '../../components/CollectionTypeFormWrappe import EditViewDataManagerProvider from '../../components/EditViewDataManagerProvider'; import SingleTypeFormWrapper from '../../components/SingleTypeFormWrapper'; import DraftAndPublishBadge from './DraftAndPublishBadge'; +import Informations from './Informations'; import Header from './Header'; import { // createAttributesLayout, @@ -165,7 +166,7 @@ const EditView = ({ paddingRight={4} paddingTop={6} > - infos + InjectionZone +