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
+