@strapi/admin 4.0.0-next.15 → 4.0.0-next.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/admin/src/components/AutoReloadOverlayBlockerProvider/Blocker.js +56 -24
- package/admin/src/components/AutoReloadOverlayBlockerProvider/Overlay.js +3 -15
- package/admin/src/components/AutoReloadOverlayBlockerProvider/index.js +6 -6
- package/admin/src/components/LeftMenu/index.js +91 -16
- package/admin/src/content-manager/components/DynamicTable/CellContent/Media/FileWrapper.js +3 -17
- package/admin/src/content-manager/components/Inputs/index.js +4 -1
- package/admin/src/content-manager/components/SelectWrapper/index.js +4 -1
- package/admin/src/content-manager/pages/EditView/DeleteLink/index.js +5 -2
- package/admin/src/pages/AuthPage/components/ForgotPassword/index.js +2 -2
- package/admin/src/pages/AuthPage/components/Login/BaseLogin.js +1 -1
- package/admin/src/pages/AuthPage/components/Register/index.js +1 -1
- package/admin/src/pages/HomePage/ContentBlocks.js +5 -1
- package/admin/src/pages/HomePage/SocialLinks.js +62 -6
- package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/ConditionsModal/index.js +2 -2
- package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/ContentTypeCollapse/Collapse/index.js +6 -2
- package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/ContentTypes/index.js +2 -1
- package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/RoleForm/index.js +3 -13
- package/admin/src/pages/SettingsPage/pages/Webhooks/ListView/index.js +2 -2
- package/admin/src/translations/ar.json +0 -15
- package/admin/src/translations/cs.json +0 -23
- package/admin/src/translations/de.json +0 -34
- package/admin/src/translations/dk.json +0 -33
- package/admin/src/translations/en.json +80 -79
- package/admin/src/translations/es.json +0 -30
- package/admin/src/translations/fr.json +0 -26
- package/admin/src/translations/he.json +0 -18
- package/admin/src/translations/id.json +0 -29
- package/admin/src/translations/it.json +0 -34
- package/admin/src/translations/ja.json +0 -22
- package/admin/src/translations/ko.json +0 -20
- package/admin/src/translations/ms.json +0 -26
- package/admin/src/translations/nl.json +0 -17
- package/admin/src/translations/no.json +0 -18
- package/admin/src/translations/pl.json +0 -28
- package/admin/src/translations/pt-BR.json +0 -20
- package/admin/src/translations/pt.json +0 -21
- package/admin/src/translations/ru.json +0 -33
- package/admin/src/translations/sk.json +0 -28
- package/admin/src/translations/sv.json +0 -2
- package/admin/src/translations/th.json +0 -28
- package/admin/src/translations/tr.json +0 -18
- package/admin/src/translations/uk.json +0 -25
- package/admin/src/translations/vi.json +0 -20
- package/admin/src/translations/zh-Hans.json +0 -24
- package/admin/src/translations/zh.json +0 -15
- package/build/1920.6f7ee484.chunk.js +1 -0
- package/build/2321.0bd82db2.chunk.js +1 -0
- package/build/3736.e4c31780.chunk.js +1 -0
- package/build/3742.7cb60b42.chunk.js +1 -0
- package/build/5381.572f0c02.chunk.js +1 -0
- package/build/5935.dd43c971.chunk.js +2 -0
- package/build/5935.dd43c971.chunk.js.LICENSE.txt +14 -0
- package/build/6317.574fe2fa.chunk.js +2 -0
- package/build/6317.574fe2fa.chunk.js.LICENSE.txt +15 -0
- package/build/6505.d132ab1b.chunk.js +1 -0
- package/build/8089.d60269e4.chunk.js +1 -0
- package/build/9572.3e00ebbb.chunk.js +1 -0
- package/build/9626.21391f2a.chunk.js +1 -0
- package/build/9662.f9dc41c4.chunk.js +1 -0
- package/build/9669.15e70c2f.chunk.js +1 -0
- package/build/Admin-authenticatedApp.eeb514c9.chunk.js +1 -0
- package/build/Admin_homePage.8a4dcfaa.chunk.js +1 -0
- package/build/Admin_marketplace.2c239cd9.chunk.js +1 -0
- package/build/Admin_pluginsPage.fe1587a6.chunk.js +1 -0
- package/build/Admin_settingsPage.303c83d5.chunk.js +1 -0
- package/build/admin-edit-roles-page.eb718f56.chunk.js +1 -0
- package/build/ar-json.f9cb55b0.chunk.js +1 -0
- package/build/content-manager.8219dae0.chunk.js +1 -0
- package/build/cs-json.13271b78.chunk.js +1 -0
- package/build/de-json.79a51add.chunk.js +1 -0
- package/build/dk-json.c65ffcc3.chunk.js +1 -0
- package/build/documentation-page.84f380a7.chunk.js +1 -0
- package/build/documentation-translation-zh-Hans-json.e53d0c79.chunk.js +1 -0
- package/build/email-settings-page.cb22fda9.chunk.js +1 -0
- package/build/email-translation-ar-json.536b0217.chunk.js +1 -0
- package/build/email-translation-cs-json.8f533c9b.chunk.js +1 -0
- package/build/email-translation-de-json.89f5373e.chunk.js +1 -0
- package/build/email-translation-dk-json.9c95cf96.chunk.js +1 -0
- package/build/email-translation-en-json.5ec38fe9.chunk.js +1 -0
- package/build/email-translation-es-json.fec78330.chunk.js +1 -0
- package/build/email-translation-fr-json.76afb1c3.chunk.js +1 -0
- package/build/email-translation-id-json.1b3e055a.chunk.js +1 -0
- package/build/email-translation-it-json.7273fee2.chunk.js +1 -0
- package/build/email-translation-ja-json.b75afc52.chunk.js +1 -0
- package/build/email-translation-ko-json.eb9a23cd.chunk.js +1 -0
- package/build/email-translation-ms-json.af7c5861.chunk.js +1 -0
- package/build/email-translation-nl-json.10fec023.chunk.js +1 -0
- package/build/email-translation-pl-json.ebda42d5.chunk.js +1 -0
- package/build/email-translation-pt-BR-json.338d8b7c.chunk.js +1 -0
- package/build/email-translation-pt-json.1cd0fedf.chunk.js +1 -0
- package/build/email-translation-ru-json.2c369331.chunk.js +1 -0
- package/build/email-translation-sk-json.ba2e026d.chunk.js +1 -0
- package/build/email-translation-th-json.16457076.chunk.js +1 -0
- package/build/email-translation-tr-json.92e0a5d9.chunk.js +1 -0
- package/build/email-translation-uk-json.d00dd5b1.chunk.js +1 -0
- package/build/email-translation-vi-json.ed425dde.chunk.js +1 -0
- package/build/email-translation-zh-Hans-json.e2c630b6.chunk.js +1 -0
- package/build/email-translation-zh-json.2a06ebac.chunk.js +1 -0
- package/build/en-json.b4b93170.chunk.js +1 -0
- package/build/es-json.f5f967b8.chunk.js +1 -0
- package/build/fr-json.f53cb20f.chunk.js +1 -0
- package/build/he-json.ef9db0b0.chunk.js +1 -0
- package/build/i18n-translation-en-json.17af559c.chunk.js +1 -0
- package/build/i18n-translation-zh-Hans-json.670b4940.chunk.js +1 -0
- package/build/id-json.444fb2bc.chunk.js +1 -0
- package/build/index.html +1 -1
- package/build/it-json.d096e255.chunk.js +1 -0
- package/build/ja-json.7ddf0d03.chunk.js +1 -0
- package/build/ko-json.d567bad9.chunk.js +1 -0
- package/build/main.f54a69d1.js +2 -0
- package/build/main.f54a69d1.js.LICENSE.txt +120 -0
- package/build/ms-json.877857c6.chunk.js +1 -0
- package/build/nl-json.53a278ac.chunk.js +1 -0
- package/build/no-json.253312ce.chunk.js +1 -0
- package/build/pl-json.f949cbf1.chunk.js +1 -0
- package/build/pt-BR-json.16a743f0.chunk.js +1 -0
- package/build/pt-json.b9c55575.chunk.js +1 -0
- package/build/ru-json.3a833400.chunk.js +1 -0
- package/build/runtime~main.33a02236.js +1 -0
- package/build/sk-json.e7672f7e.chunk.js +1 -0
- package/build/sv-json.a2c408b3.chunk.js +1 -0
- package/build/th-json.6de26f39.chunk.js +1 -0
- package/build/tr-json.07b54f78.chunk.js +1 -0
- package/build/uk-json.36a7841e.chunk.js +1 -0
- package/build/upload-settings.9900e97b.chunk.js +1 -0
- package/build/upload-translation-en-json.555efcc4.chunk.js +1 -0
- package/build/upload-translation-zh-Hans-json.79473d61.chunk.js +1 -0
- package/build/upload.676c3cbd.chunk.js +1 -0
- package/build/users-advanced-settings-page.26c25559.chunk.js +1 -0
- package/build/users-permissions-translation-ar-json.6fe0dcf5.chunk.js +1 -0
- package/build/users-permissions-translation-cs-json.dd4bb452.chunk.js +1 -0
- package/build/users-permissions-translation-de-json.1505b462.chunk.js +1 -0
- package/build/users-permissions-translation-dk-json.6b47229f.chunk.js +1 -0
- package/build/users-permissions-translation-en-json.3e650c44.chunk.js +1 -0
- package/build/users-permissions-translation-es-json.768cc00e.chunk.js +1 -0
- package/build/users-permissions-translation-fr-json.12f3c930.chunk.js +1 -0
- package/build/users-permissions-translation-id-json.ec3deaf0.chunk.js +1 -0
- package/build/users-permissions-translation-it-json.baa4f859.chunk.js +1 -0
- package/build/users-permissions-translation-ja-json.3ddd4418.chunk.js +1 -0
- package/build/users-permissions-translation-ko-json.90c2d129.chunk.js +1 -0
- package/build/users-permissions-translation-ms-json.dc405667.chunk.js +1 -0
- package/build/users-permissions-translation-nl-json.2d8e847a.chunk.js +1 -0
- package/build/users-permissions-translation-pl-json.b150dfb0.chunk.js +1 -0
- package/build/users-permissions-translation-pt-BR-json.0c494c69.chunk.js +1 -0
- package/build/users-permissions-translation-pt-json.0fccc389.chunk.js +1 -0
- package/build/users-permissions-translation-ru-json.4389c542.chunk.js +1 -0
- package/build/users-permissions-translation-sk-json.2602e768.chunk.js +1 -0
- package/build/users-permissions-translation-sv-json.438e46f7.chunk.js +1 -0
- package/build/users-permissions-translation-th-json.abe0558b.chunk.js +1 -0
- package/build/users-permissions-translation-tr-json.269ee593.chunk.js +1 -0
- package/build/users-permissions-translation-uk-json.ffd9a4ee.chunk.js +1 -0
- package/build/users-permissions-translation-vi-json.c2cd19d5.chunk.js +1 -0
- package/build/users-permissions-translation-zh-Hans-json.2d909528.chunk.js +1 -0
- package/build/users-permissions-translation-zh-json.7f3027c5.chunk.js +1 -0
- package/build/vi-json.12dacb71.chunk.js +1 -0
- package/build/webhook-list-page.949cefb9.chunk.js +1 -0
- package/build/zh-Hans-json.85999634.chunk.js +1 -0
- package/build/zh-json.2e957d0f.chunk.js +1 -0
- package/package.json +7 -7
- package/admin/src/components/AutoReloadOverlayBlockerProvider/Content.js +0 -29
- package/admin/src/components/AutoReloadOverlayBlockerProvider/Wrapper.js +0 -94
|
@@ -1,16 +1,37 @@
|
|
|
1
1
|
import React, { useEffect } from 'react';
|
|
2
2
|
import ReactDOM from 'react-dom';
|
|
3
|
-
import {
|
|
3
|
+
import { useIntl } from 'react-intl';
|
|
4
|
+
import styled, { keyframes } from 'styled-components';
|
|
5
|
+
import Time from '@strapi/icons/Time';
|
|
6
|
+
import Reload from '@strapi/icons/Reload';
|
|
7
|
+
import { Link } from '@strapi/parts/Link';
|
|
8
|
+
import { Box } from '@strapi/parts/Box';
|
|
9
|
+
import { Stack } from '@strapi/parts/Stack';
|
|
10
|
+
import { Row } from '@strapi/parts/Row';
|
|
11
|
+
import { H1, H2 } from '@strapi/parts/Text';
|
|
4
12
|
import PropTypes from 'prop-types';
|
|
5
|
-
import Content from './Content';
|
|
6
13
|
import Overlay from './Overlay';
|
|
7
|
-
import Wrapper from './Wrapper';
|
|
8
14
|
|
|
9
15
|
const overlayContainer = document.createElement('div');
|
|
10
16
|
const ID = 'autoReloadOverlayBlocker';
|
|
11
17
|
overlayContainer.setAttribute('id', ID);
|
|
12
18
|
|
|
13
|
-
const
|
|
19
|
+
const rotation = keyframes`
|
|
20
|
+
from {
|
|
21
|
+
transform: rotate(0deg);
|
|
22
|
+
}
|
|
23
|
+
to {
|
|
24
|
+
transform: rotate(359deg);
|
|
25
|
+
}
|
|
26
|
+
`;
|
|
27
|
+
|
|
28
|
+
const LoaderReload = styled(Reload)`
|
|
29
|
+
animation: ${rotation} 1s infinite linear;
|
|
30
|
+
${({ small }) => small && `width: 25px; height: 25px;`}
|
|
31
|
+
`;
|
|
32
|
+
|
|
33
|
+
const Blocker = ({ displayedIcon, description, title, elapsed, isOpen }) => {
|
|
34
|
+
const { formatMessage } = useIntl();
|
|
14
35
|
useEffect(() => {
|
|
15
36
|
document.body.appendChild(overlayContainer);
|
|
16
37
|
|
|
@@ -22,26 +43,38 @@ const Blocker = ({ className, displayedIcon, description, title, elapsed, isOpen
|
|
|
22
43
|
if (isOpen) {
|
|
23
44
|
return ReactDOM.createPortal(
|
|
24
45
|
<Overlay>
|
|
25
|
-
<
|
|
26
|
-
<
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
target="_blank"
|
|
37
|
-
rel="noopener noreferrer"
|
|
38
|
-
>
|
|
39
|
-
Read the documentation
|
|
40
|
-
</a>
|
|
41
|
-
</div>
|
|
46
|
+
<Box>
|
|
47
|
+
<Row>
|
|
48
|
+
{displayedIcon === 'reload' && (
|
|
49
|
+
<Box paddingRight={3} style={{ alignSelf: 'baseline' }}>
|
|
50
|
+
<LoaderReload width="4rem" height="4rem" />
|
|
51
|
+
</Box>
|
|
52
|
+
)}
|
|
53
|
+
{displayedIcon === 'time' && (
|
|
54
|
+
<Box paddingRight={3} style={{ alignSelf: 'center' }}>
|
|
55
|
+
<Time width="3.8rem" height="3.8rem" />
|
|
56
|
+
</Box>
|
|
42
57
|
)}
|
|
43
|
-
|
|
44
|
-
|
|
58
|
+
<Stack size={2}>
|
|
59
|
+
<H1>{formatMessage(title)}</H1>
|
|
60
|
+
<H2 textColor="neutral600">{formatMessage(description)}</H2>
|
|
61
|
+
<Row>
|
|
62
|
+
{elapsed < 15 && (
|
|
63
|
+
<Link
|
|
64
|
+
href="https://strapi.io/documentation"
|
|
65
|
+
target="_blank"
|
|
66
|
+
onClick={e => {
|
|
67
|
+
e.preventDefault();
|
|
68
|
+
window.open('https://strapi.io/documentation', '_blank');
|
|
69
|
+
}}
|
|
70
|
+
>
|
|
71
|
+
Read the documentation
|
|
72
|
+
</Link>
|
|
73
|
+
)}
|
|
74
|
+
</Row>
|
|
75
|
+
</Stack>
|
|
76
|
+
</Row>
|
|
77
|
+
</Box>
|
|
45
78
|
</Overlay>,
|
|
46
79
|
overlayContainer
|
|
47
80
|
);
|
|
@@ -51,7 +84,6 @@ const Blocker = ({ className, displayedIcon, description, title, elapsed, isOpen
|
|
|
51
84
|
};
|
|
52
85
|
|
|
53
86
|
Blocker.propTypes = {
|
|
54
|
-
className: PropTypes.string.isRequired,
|
|
55
87
|
displayedIcon: PropTypes.oneOfType([PropTypes.string, PropTypes.array]).isRequired,
|
|
56
88
|
description: PropTypes.object.isRequired,
|
|
57
89
|
elapsed: PropTypes.number.isRequired,
|
|
@@ -11,24 +11,12 @@ const Overlay = styled.div`
|
|
|
11
11
|
&:before {
|
|
12
12
|
content: '';
|
|
13
13
|
position: fixed;
|
|
14
|
-
top:
|
|
14
|
+
top: 0;
|
|
15
15
|
right: 0;
|
|
16
16
|
bottom: 0;
|
|
17
17
|
left: 0;
|
|
18
|
-
background:
|
|
19
|
-
opacity: 0.
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
&:after {
|
|
23
|
-
content: '';
|
|
24
|
-
position: fixed;
|
|
25
|
-
top: 6rem;
|
|
26
|
-
right: 0;
|
|
27
|
-
bottom: 0;
|
|
28
|
-
left: 24rem;
|
|
29
|
-
background: linear-gradient(#fbfbfb 20%, rgba(0, 0, 100, 0) 100%);
|
|
30
|
-
box-shadow: inset 0px 2px 4px rgba(0, 0, 0, 0.1);
|
|
31
|
-
box-shadow: inset 0 1px 2px 0 rgba(40, 42, 49, 0.16);
|
|
18
|
+
background: ${({ theme }) => theme.colors.neutral200};
|
|
19
|
+
opacity: 0.8;
|
|
32
20
|
}
|
|
33
21
|
|
|
34
22
|
> div {
|
|
@@ -28,7 +28,8 @@ const AutoReloadOverlayBlockerProvider = ({ children }) => {
|
|
|
28
28
|
|
|
29
29
|
if (isOpen) {
|
|
30
30
|
timer = setInterval(() => {
|
|
31
|
-
if (elapsed > 15) {
|
|
31
|
+
// if (elapsed > 15) {
|
|
32
|
+
if (elapsed > 30) {
|
|
32
33
|
clearInterval(timer);
|
|
33
34
|
|
|
34
35
|
return null;
|
|
@@ -47,8 +48,8 @@ const AutoReloadOverlayBlockerProvider = ({ children }) => {
|
|
|
47
48
|
};
|
|
48
49
|
}, [isOpen, elapsed]);
|
|
49
50
|
|
|
50
|
-
let displayedIcon = config?.icon || '
|
|
51
|
-
|
|
51
|
+
let displayedIcon = config?.icon || 'reload';
|
|
52
|
+
|
|
52
53
|
let description = {
|
|
53
54
|
id: config?.description || 'components.OverlayBlocker.description',
|
|
54
55
|
defaultMessage:
|
|
@@ -60,8 +61,8 @@ const AutoReloadOverlayBlockerProvider = ({ children }) => {
|
|
|
60
61
|
};
|
|
61
62
|
|
|
62
63
|
if (elapsed > 15) {
|
|
63
|
-
displayedIcon =
|
|
64
|
-
|
|
64
|
+
displayedIcon = 'time';
|
|
65
|
+
|
|
65
66
|
description = {
|
|
66
67
|
id: 'components.OverlayBlocker.description.serverError',
|
|
67
68
|
defaultMessage: 'The server should have restarted, please check your logs in the terminal.',
|
|
@@ -81,7 +82,6 @@ const AutoReloadOverlayBlockerProvider = ({ children }) => {
|
|
|
81
82
|
displayedIcon={displayedIcon}
|
|
82
83
|
isOpen={isOpen}
|
|
83
84
|
elapsed={elapsed}
|
|
84
|
-
className={className}
|
|
85
85
|
description={description}
|
|
86
86
|
title={title}
|
|
87
87
|
/>
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useRef, useState } from 'react';
|
|
2
|
+
import styled from 'styled-components';
|
|
2
3
|
import PropTypes from 'prop-types';
|
|
3
4
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
4
5
|
import { useIntl } from 'react-intl';
|
|
5
|
-
import {
|
|
6
|
-
import styled from 'styled-components';
|
|
7
|
-
import { Button } from '@strapi/parts/Button';
|
|
6
|
+
import { NavLink as Link } from 'react-router-dom';
|
|
8
7
|
import { Divider } from '@strapi/parts/Divider';
|
|
9
8
|
import {
|
|
10
9
|
MainNav,
|
|
@@ -15,7 +14,12 @@ import {
|
|
|
15
14
|
NavUser,
|
|
16
15
|
NavCondense,
|
|
17
16
|
} from '@strapi/parts/MainNav';
|
|
17
|
+
import { FocusTrap } from '@strapi/parts/FocusTrap';
|
|
18
|
+
import { Box } from '@strapi/parts/Box';
|
|
19
|
+
import { Text } from '@strapi/parts/Text';
|
|
20
|
+
import { Stack } from '@strapi/parts/Stack';
|
|
18
21
|
import ContentIcon from '@strapi/icons/ContentIcon';
|
|
22
|
+
import Logout from '@strapi/icons/Logout';
|
|
19
23
|
import { auth, usePersistentState, useAppInfos } from '@strapi/helper-plugin';
|
|
20
24
|
import useConfigurations from '../../hooks/useConfigurations';
|
|
21
25
|
|
|
@@ -26,13 +30,64 @@ const IconWrapper = styled.span`
|
|
|
26
30
|
}
|
|
27
31
|
`;
|
|
28
32
|
|
|
33
|
+
const LinkUserWrapper = styled(Box)`
|
|
34
|
+
width: ${150 / 16}rem;
|
|
35
|
+
position: absolute;
|
|
36
|
+
bottom: ${({ theme }) => theme.spaces[9]};
|
|
37
|
+
left: ${({ theme }) => theme.spaces[5]};
|
|
38
|
+
`;
|
|
39
|
+
|
|
40
|
+
const LinkUser = styled(Link)`
|
|
41
|
+
display: flex;
|
|
42
|
+
justify-content: space-between;
|
|
43
|
+
align-items: center;
|
|
44
|
+
text-decoration: none;
|
|
45
|
+
padding: ${({ theme }) => `${theme.spaces[2]} ${theme.spaces[4]}`};
|
|
46
|
+
border-radius: ${({ theme }) => theme.spaces[1]};
|
|
47
|
+
|
|
48
|
+
&:hover {
|
|
49
|
+
background: ${({ theme, logout }) =>
|
|
50
|
+
logout ? theme.colors.danger100 : theme.colors.primary100};
|
|
51
|
+
text-decoration: none;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
svg {
|
|
55
|
+
path {
|
|
56
|
+
fill: ${({ theme }) => theme.colors.danger600};
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
`;
|
|
60
|
+
|
|
29
61
|
const LeftMenu = ({ generalSectionLinks, pluginsSectionLinks }) => {
|
|
62
|
+
const buttonRef = useRef();
|
|
63
|
+
const [userLinksVisible, setUserLinksVisible] = useState(false);
|
|
30
64
|
const { menuLogo } = useConfigurations();
|
|
31
|
-
const { push } = useHistory();
|
|
32
65
|
const [condensed, setCondensed] = usePersistentState('navbar-condensed', false);
|
|
33
66
|
const { userDisplayName } = useAppInfos();
|
|
34
67
|
const { formatMessage } = useIntl();
|
|
35
68
|
|
|
69
|
+
const initials = userDisplayName
|
|
70
|
+
.split(' ')
|
|
71
|
+
.map(name => name.substring(0, 1))
|
|
72
|
+
.join('')
|
|
73
|
+
.substring(0, 2);
|
|
74
|
+
|
|
75
|
+
const handleToggleUserLinks = () => setUserLinksVisible(prev => !prev);
|
|
76
|
+
|
|
77
|
+
const handleLogout = () => {
|
|
78
|
+
auth.clearAppStorage();
|
|
79
|
+
handleToggleUserLinks();
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const handleBlur = e => {
|
|
83
|
+
if (
|
|
84
|
+
!e.currentTarget.contains(e.relatedTarget) &&
|
|
85
|
+
e.relatedTarget?.parentElement?.id !== 'main-nav-user-button'
|
|
86
|
+
) {
|
|
87
|
+
setUserLinksVisible(false);
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
|
|
36
91
|
return (
|
|
37
92
|
<MainNav condensed={condensed}>
|
|
38
93
|
<NavBrand
|
|
@@ -80,23 +135,43 @@ const LeftMenu = ({ generalSectionLinks, pluginsSectionLinks }) => {
|
|
|
80
135
|
{formatMessage(link.intlLabel)}
|
|
81
136
|
</NavLink>
|
|
82
137
|
))}
|
|
83
|
-
{/* This is temporary */}
|
|
84
|
-
<Button
|
|
85
|
-
type="button"
|
|
86
|
-
onClick={() => {
|
|
87
|
-
auth.clearAppStorage();
|
|
88
|
-
push('/auth/login');
|
|
89
|
-
}}
|
|
90
|
-
>
|
|
91
|
-
Logout
|
|
92
|
-
</Button>
|
|
93
138
|
</NavSection>
|
|
94
139
|
) : null}
|
|
95
140
|
</NavSections>
|
|
96
141
|
|
|
97
|
-
<NavUser
|
|
142
|
+
<NavUser
|
|
143
|
+
id="main-nav-user-button"
|
|
144
|
+
ref={buttonRef}
|
|
145
|
+
onClick={handleToggleUserLinks}
|
|
146
|
+
initials={initials}
|
|
147
|
+
>
|
|
98
148
|
{userDisplayName}
|
|
99
149
|
</NavUser>
|
|
150
|
+
{userLinksVisible && (
|
|
151
|
+
<LinkUserWrapper onBlur={handleBlur} padding={1} shadow="tableShadow" background="neutral0">
|
|
152
|
+
<FocusTrap onEscape={handleToggleUserLinks}>
|
|
153
|
+
<Stack size={0}>
|
|
154
|
+
<LinkUser onClick={handleToggleUserLinks} to="/me">
|
|
155
|
+
<Text>
|
|
156
|
+
{formatMessage({
|
|
157
|
+
id: 'app.components.LeftMenu.profile',
|
|
158
|
+
defaultMessage: 'Profile',
|
|
159
|
+
})}
|
|
160
|
+
</Text>
|
|
161
|
+
</LinkUser>
|
|
162
|
+
<LinkUser onClick={handleLogout} logout="logout" to="/auth/login">
|
|
163
|
+
<Text textColor="danger600">
|
|
164
|
+
{formatMessage({
|
|
165
|
+
id: 'app.components.LeftMenu.logout',
|
|
166
|
+
defaultMessage: 'Logout',
|
|
167
|
+
})}
|
|
168
|
+
</Text>
|
|
169
|
+
<Logout />
|
|
170
|
+
</LinkUser>
|
|
171
|
+
</Stack>
|
|
172
|
+
</FocusTrap>
|
|
173
|
+
</LinkUserWrapper>
|
|
174
|
+
)}
|
|
100
175
|
|
|
101
176
|
<NavCondense onClick={() => setCondensed(s => !s)}>
|
|
102
177
|
{condensed
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import styled from 'styled-components';
|
|
4
4
|
import { Row } from '@strapi/parts/Row';
|
|
@@ -12,7 +12,6 @@ const Wrapper = styled(Row)`
|
|
|
12
12
|
border: 1px solid ${({ theme }) => theme.colors.neutral200};
|
|
13
13
|
background: ${({ theme }) => theme.colors.neutral150};
|
|
14
14
|
padding-left: 1px;
|
|
15
|
-
z-index: ${({ hovering }) => (hovering ? 1 : undefined)};
|
|
16
15
|
|
|
17
16
|
span {
|
|
18
17
|
line-height: 0.6rem;
|
|
@@ -20,29 +19,16 @@ const Wrapper = styled(Row)`
|
|
|
20
19
|
}
|
|
21
20
|
`;
|
|
22
21
|
|
|
23
|
-
const FileWrapper = ({ children,
|
|
24
|
-
const [previewVisible, setPreviewVisible] = useState(false);
|
|
25
|
-
|
|
22
|
+
const FileWrapper = ({ children, ...props }) => {
|
|
26
23
|
return (
|
|
27
|
-
<Wrapper
|
|
28
|
-
justifyContent="center"
|
|
29
|
-
alignItems="center"
|
|
30
|
-
hovering={preview && previewVisible}
|
|
31
|
-
onMouseEnter={() => setPreviewVisible(true)}
|
|
32
|
-
onMouseLeave={() => setPreviewVisible(false)}
|
|
33
|
-
>
|
|
24
|
+
<Wrapper justifyContent="center" alignItems="center" as="span" {...props}>
|
|
34
25
|
<TableLabel textColor="neutral600">{children}</TableLabel>
|
|
35
26
|
</Wrapper>
|
|
36
27
|
);
|
|
37
28
|
};
|
|
38
29
|
|
|
39
|
-
FileWrapper.defaultProps = {
|
|
40
|
-
preview: true,
|
|
41
|
-
};
|
|
42
|
-
|
|
43
30
|
FileWrapper.propTypes = {
|
|
44
31
|
children: PropTypes.string.isRequired,
|
|
45
|
-
preview: PropTypes.bool,
|
|
46
32
|
};
|
|
47
33
|
|
|
48
34
|
export default FileWrapper;
|
|
@@ -46,7 +46,7 @@ const DeleteLink = ({ isCreatingEntry, onDelete, onDeleteSucceeded, trackerPrope
|
|
|
46
46
|
|
|
47
47
|
return (
|
|
48
48
|
<>
|
|
49
|
-
<Button onClick={toggleWarningDelete} size="S" startIcon={<Delete />} variant="danger">
|
|
49
|
+
<Button onClick={toggleWarningDelete} size="S" startIcon={<Delete />} variant="danger-light">
|
|
50
50
|
{formatMessage({
|
|
51
51
|
id: getTrad('containers.Edit.delete-entry'),
|
|
52
52
|
defaultMessage: 'Delete this entry',
|
|
@@ -71,4 +71,7 @@ DeleteLink.propTypes = {
|
|
|
71
71
|
|
|
72
72
|
const Memoized = memo(DeleteLink, isEqual);
|
|
73
73
|
|
|
74
|
-
export default connect(
|
|
74
|
+
export default connect(
|
|
75
|
+
Memoized,
|
|
76
|
+
select
|
|
77
|
+
);
|
|
@@ -40,8 +40,8 @@ const ForgotPassword = ({ onSubmit, schema }) => {
|
|
|
40
40
|
<Box paddingTop={6} paddingBottom={7}>
|
|
41
41
|
<H1>
|
|
42
42
|
{formatMessage({
|
|
43
|
-
id: 'Auth.form.button.password-
|
|
44
|
-
defaultMessage: 'Password
|
|
43
|
+
id: 'Auth.form.button.password-recovery',
|
|
44
|
+
defaultMessage: 'Password Recovery',
|
|
45
45
|
})}
|
|
46
46
|
</H1>
|
|
47
47
|
</Box>
|
|
@@ -53,7 +53,11 @@ const ContentBlocks = () => {
|
|
|
53
53
|
iconBackground="warning100"
|
|
54
54
|
/>
|
|
55
55
|
</BlockLink>
|
|
56
|
-
<BlockLink
|
|
56
|
+
<BlockLink
|
|
57
|
+
href="https://strapi.io/blog/categories/tutorials"
|
|
58
|
+
target="_blank"
|
|
59
|
+
rel="noopener noreferrer nofollow"
|
|
60
|
+
>
|
|
57
61
|
<ContentBox
|
|
58
62
|
title={formatMessage({
|
|
59
63
|
id: 'app.components.BlockLink.tutorial',
|
|
@@ -16,10 +16,57 @@ import ExternalLink from '@strapi/icons/ExternalLink';
|
|
|
16
16
|
import Github from '@strapi/icons/Github';
|
|
17
17
|
import Slack from '@strapi/icons/Slack';
|
|
18
18
|
import Reddit from '@strapi/icons/Reddit';
|
|
19
|
+
import Strapi from '@strapi/icons/Strapi';
|
|
19
20
|
import Twitter from '@strapi/icons/Twitter';
|
|
20
|
-
import Medium from '@strapi/icons/Medium';
|
|
21
21
|
import Discourse from '@strapi/icons/Discourse';
|
|
22
22
|
|
|
23
|
+
const StyledReddit = styled(Reddit)`
|
|
24
|
+
> path:first-child {
|
|
25
|
+
fill: #ff4500;
|
|
26
|
+
}
|
|
27
|
+
> path:last-child {
|
|
28
|
+
fill: ${({ theme }) => theme.colors.neutral0};
|
|
29
|
+
}
|
|
30
|
+
`;
|
|
31
|
+
const StyledStrapi = styled(Strapi)`
|
|
32
|
+
> path:first-child {
|
|
33
|
+
fill: #8e75ff;
|
|
34
|
+
}
|
|
35
|
+
> path:nth-child(2) {
|
|
36
|
+
fill: #8e75ff;
|
|
37
|
+
}
|
|
38
|
+
> path:nth-child(3) {
|
|
39
|
+
fill: #8e75ff;
|
|
40
|
+
}
|
|
41
|
+
`;
|
|
42
|
+
|
|
43
|
+
const StyledTwitter = styled(Twitter)`
|
|
44
|
+
path {
|
|
45
|
+
fill: #1da1f2 !important;
|
|
46
|
+
}
|
|
47
|
+
`;
|
|
48
|
+
|
|
49
|
+
const StyledDiscourse = styled(Discourse)`
|
|
50
|
+
> path:first-child {
|
|
51
|
+
fill: #231f20;
|
|
52
|
+
}
|
|
53
|
+
> path:nth-child(2) {
|
|
54
|
+
fill: #fff9ae;
|
|
55
|
+
}
|
|
56
|
+
> path:nth-child(3) {
|
|
57
|
+
fill: #00aeef;
|
|
58
|
+
}
|
|
59
|
+
> path:nth-child(4) {
|
|
60
|
+
fill: #00a94f;
|
|
61
|
+
}
|
|
62
|
+
> path:nth-child(5) {
|
|
63
|
+
fill: #f15d22;
|
|
64
|
+
}
|
|
65
|
+
> path:nth-child(6) {
|
|
66
|
+
fill: #e31b23;
|
|
67
|
+
}
|
|
68
|
+
`;
|
|
69
|
+
|
|
23
70
|
const socialLinks = [
|
|
24
71
|
{
|
|
25
72
|
name: 'Github',
|
|
@@ -36,27 +83,33 @@ const socialLinks = [
|
|
|
36
83
|
{
|
|
37
84
|
name: 'Reddit',
|
|
38
85
|
link: 'https://www.reddit.com/r/Strapi/',
|
|
39
|
-
icon: <
|
|
86
|
+
icon: <StyledReddit />,
|
|
40
87
|
alt: 'reddit',
|
|
41
88
|
},
|
|
42
89
|
{
|
|
43
90
|
name: 'Twitter',
|
|
44
91
|
link: 'https://twitter.com/strapijs',
|
|
45
|
-
icon: <
|
|
92
|
+
icon: <StyledTwitter />,
|
|
46
93
|
alt: 'twitter',
|
|
47
94
|
},
|
|
48
95
|
{
|
|
49
96
|
name: 'Medium',
|
|
50
97
|
link: 'https://medium.com/@strapi',
|
|
51
|
-
icon: <
|
|
98
|
+
icon: <StyledStrapi />,
|
|
52
99
|
alt: 'medium',
|
|
53
100
|
},
|
|
54
101
|
{
|
|
55
102
|
name: 'Forum',
|
|
56
103
|
link: 'https://forum.strapi.io',
|
|
57
|
-
icon: <
|
|
104
|
+
icon: <StyledDiscourse />,
|
|
58
105
|
alt: 'forum',
|
|
59
106
|
},
|
|
107
|
+
{
|
|
108
|
+
name: 'Career',
|
|
109
|
+
link: 'https://strapi.io/careers',
|
|
110
|
+
icon: <StyledStrapi />,
|
|
111
|
+
alt: 'career',
|
|
112
|
+
},
|
|
60
113
|
];
|
|
61
114
|
|
|
62
115
|
const LinkCustom = styled(LinkButton)`
|
|
@@ -115,7 +168,10 @@ const SocialLinks = () => {
|
|
|
115
168
|
})}
|
|
116
169
|
</WordWrap>
|
|
117
170
|
</Stack>
|
|
118
|
-
<Link
|
|
171
|
+
<Link
|
|
172
|
+
href="https://portal.productboard.com/strapi/1-roadmap/tabs/2-under-consideration"
|
|
173
|
+
endIcon={<ExternalLink />}
|
|
174
|
+
>
|
|
119
175
|
{formatMessage({
|
|
120
176
|
id: 'app.components.HomePage.roadmap',
|
|
121
177
|
defaultMessage: 'See our road map',
|
package/admin/src/pages/SettingsPage/pages/Roles/EditPage/components/ConditionsModal/index.js
CHANGED
|
@@ -73,9 +73,9 @@ const ConditionsModal = ({ actions, headerBreadCrumbs, isFormDisabled, onClosed,
|
|
|
73
73
|
};
|
|
74
74
|
|
|
75
75
|
return (
|
|
76
|
-
<ModalLayout onClose={onClosed}>
|
|
76
|
+
<ModalLayout labelledBy="condition-modal-breadcrumbs" onClose={onClosed}>
|
|
77
77
|
<ModalHeader>
|
|
78
|
-
<Breadcrumbs label={headerBreadCrumbs.join(', ')}>
|
|
78
|
+
<Breadcrumbs id="condition-modal-breadcrumbs" label={headerBreadCrumbs.join(', ')}>
|
|
79
79
|
{headerBreadCrumbs.map(label => (
|
|
80
80
|
<Crumb key={label}>
|
|
81
81
|
{upperFirst(
|
|
@@ -18,6 +18,7 @@ import { cellWidth, rowHeight } from '../../Permissions/utils/constants';
|
|
|
18
18
|
import RowLabelWithCheckbox from '../../RowLabelWithCheckbox';
|
|
19
19
|
import { getCheckboxState } from '../../utils';
|
|
20
20
|
import generateCheckboxesActions from './utils/generateCheckboxesActions';
|
|
21
|
+
import activeStyle from '../utils/activeStyle';
|
|
21
22
|
|
|
22
23
|
const activeRowStyle = (theme, isActive) => `
|
|
23
24
|
${Wrapper} {
|
|
@@ -31,6 +32,10 @@ const activeRowStyle = (theme, isActive) => `
|
|
|
31
32
|
${ConditionsButton} {
|
|
32
33
|
display: block;
|
|
33
34
|
}
|
|
35
|
+
&:hover {
|
|
36
|
+
${activeStyle(theme)}
|
|
37
|
+
}
|
|
38
|
+
|
|
34
39
|
`;
|
|
35
40
|
|
|
36
41
|
const Wrapper = styled.div`
|
|
@@ -75,7 +80,7 @@ const Chevron = styled(Box)`
|
|
|
75
80
|
}
|
|
76
81
|
`;
|
|
77
82
|
|
|
78
|
-
const TinyDot = styled
|
|
83
|
+
const TinyDot = styled.span`
|
|
79
84
|
position: absolute;
|
|
80
85
|
top: -6px;
|
|
81
86
|
left: 37px;
|
|
@@ -228,7 +233,6 @@ const Collapse = ({
|
|
|
228
233
|
}
|
|
229
234
|
)}
|
|
230
235
|
</Row>
|
|
231
|
-
<Box style={{ width: 120 }} />
|
|
232
236
|
{isModalOpen && (
|
|
233
237
|
<ConditionsModal
|
|
234
238
|
headerBreadCrumbs={[label, 'app.components.LeftMenuLinkContainer.settings']}
|
|
@@ -2,6 +2,7 @@ import React, { memo } from 'react';
|
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import { Box } from '@strapi/parts/Box';
|
|
4
4
|
import styled from 'styled-components';
|
|
5
|
+
import sortBy from 'lodash/sortBy';
|
|
5
6
|
import ContentTypeCollapses from '../ContentTypeCollapses';
|
|
6
7
|
import GlobalActions from '../GlobalActions';
|
|
7
8
|
|
|
@@ -10,7 +11,7 @@ const StyledBox = styled(Box)`
|
|
|
10
11
|
`;
|
|
11
12
|
|
|
12
13
|
const ContentTypes = ({ isFormDisabled, kind, layout: { actions, subjects } }) => {
|
|
13
|
-
const sortedSubjects = [...subjects]
|
|
14
|
+
const sortedSubjects = sortBy([...subjects], 'label');
|
|
14
15
|
|
|
15
16
|
return (
|
|
16
17
|
<StyledBox background="neutral0">
|
|
@@ -6,19 +6,9 @@ import { Stack } from '@strapi/parts/Stack';
|
|
|
6
6
|
import { Text } from '@strapi/parts/Text';
|
|
7
7
|
import { Textarea } from '@strapi/parts/Textarea';
|
|
8
8
|
import { TextInput } from '@strapi/parts/TextInput';
|
|
9
|
+
import { Button } from '@strapi/parts/Button';
|
|
9
10
|
import PropTypes from 'prop-types';
|
|
10
11
|
import { useIntl } from 'react-intl';
|
|
11
|
-
import styled from 'styled-components';
|
|
12
|
-
|
|
13
|
-
const UsersRoleNumber = styled.div`
|
|
14
|
-
border: 1px solid ${({ theme }) => theme.colors.primary200};
|
|
15
|
-
background: ${({ theme }) => theme.colors.primary100};
|
|
16
|
-
padding: ${({ theme }) => `${theme.spaces[2]} ${theme.spaces[4]}`};
|
|
17
|
-
color: ${({ theme }) => theme.colors.primary600};
|
|
18
|
-
border-radius: ${({ theme }) => theme.borderRadius};
|
|
19
|
-
font-size: ${12 / 16}rem;
|
|
20
|
-
font-weight: bold;
|
|
21
|
-
`;
|
|
22
12
|
|
|
23
13
|
const RoleForm = ({ disabled, role, values, errors, onChange, onBlur }) => {
|
|
24
14
|
const { formatMessage } = useIntl();
|
|
@@ -50,7 +40,7 @@ const RoleForm = ({ disabled, role, values, errors, onChange, onBlur }) => {
|
|
|
50
40
|
</Text>
|
|
51
41
|
</Box>
|
|
52
42
|
</Box>
|
|
53
|
-
<
|
|
43
|
+
<Button disabled variant="secondary">
|
|
54
44
|
{formatMessage(
|
|
55
45
|
{
|
|
56
46
|
id: 'Settings.roles.form.button.users-with-role',
|
|
@@ -59,7 +49,7 @@ const RoleForm = ({ disabled, role, values, errors, onChange, onBlur }) => {
|
|
|
59
49
|
},
|
|
60
50
|
{ number: role.usersCount }
|
|
61
51
|
)}
|
|
62
|
-
</
|
|
52
|
+
</Button>
|
|
63
53
|
</Row>
|
|
64
54
|
<Grid gap={4}>
|
|
65
55
|
<GridItem col={6}>
|
|
@@ -310,8 +310,8 @@ const ListView = () => {
|
|
|
310
310
|
icon={<AddIcon />}
|
|
311
311
|
>
|
|
312
312
|
{formatMessage({
|
|
313
|
-
id: 'Settings.webhooks.list.
|
|
314
|
-
defaultMessage: 'Add
|
|
313
|
+
id: 'Settings.webhooks.list.button.add',
|
|
314
|
+
defaultMessage: 'Add new webhook',
|
|
315
315
|
})}
|
|
316
316
|
</TFooter>
|
|
317
317
|
}
|