@strapi/admin 4.0.0-beta.14 → 4.0.0-beta.15
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/AuthenticatedApp/index.js +2 -1
- package/admin/src/components/{UpgradePlanModal → UpgradePlanModal}/index.js +0 -0
- package/admin/src/content-manager/components/DynamicTable/TableRows/index.js +2 -1
- package/admin/src/content-manager/components/EditViewDataManagerProvider/index.js +3 -1
- package/admin/src/content-manager/components/EditViewDataManagerProvider/utils/schema.js +1 -1
- package/admin/src/content-manager/components/SelectMany/index.js +11 -2
- package/admin/src/content-manager/components/SelectOne/index.js +34 -21
- package/admin/src/content-manager/components/SelectWrapper/index.js +4 -7
- package/admin/src/content-manager/components/Wysiwyg/Editor.js +3 -2
- package/admin/src/content-manager/components/Wysiwyg/EditorStylesContainer.js +5 -2
- package/admin/src/content-manager/components/Wysiwyg/WysiwygNav.js +1 -1
- package/admin/src/content-manager/pages/EditView/Informations/index.js +3 -2
- package/admin/src/content-manager/pages/EditView/index.js +3 -6
- package/admin/src/pages/AuthPage/components/Register/index.js +0 -9
- package/admin/src/pages/AuthPage/utils/forms.js +2 -2
- package/admin/src/pages/ProfilePage/index.js +3 -2
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/ContentBox/index.js +5 -2
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/index.js +13 -1
- package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/DeleteButton/index.js +6 -2
- package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/index.js +12 -2
- package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/index.js +7 -0
- package/admin/src/pages/SettingsPage/pages/Roles/ListPage/index.js +1 -1
- package/admin/src/pages/SettingsPage/pages/Users/EditPage/index.js +3 -3
- package/admin/src/pages/SettingsPage/pages/Users/ListPage/DynamicTable/TableRows/index.js +4 -3
- package/admin/src/pages/SettingsPage/pages/Users/ListPage/ModalForm/utils/schema.js +1 -1
- package/admin/src/pages/SettingsPage/pages/Users/utils/validations/users/edit.js +2 -2
- package/admin/src/pages/SettingsPage/pages/Users/utils/validations/users/profile.js +6 -2
- package/admin/src/utils/getFullName.js +9 -0
- package/admin/src/utils/index.js +1 -1
- package/build/3226.0dc582b2.chunk.js +2 -0
- package/build/3226.0dc582b2.chunk.js.LICENSE.txt +15 -0
- package/build/4362.fd69112c.chunk.js +1 -0
- package/build/4715.35096dd7.chunk.js +1 -0
- package/build/6250.11ba8b50.chunk.js +1 -0
- package/build/Admin-authenticatedApp.62e5ca51.chunk.js +1 -0
- package/build/Admin_profilePage.3aa61921.chunk.js +1 -0
- package/build/Admin_settingsPage.363ad01d.chunk.js +1 -0
- package/build/admin-edit-users.bcdd2e4d.chunk.js +1 -0
- package/build/admin-users.a2d08780.chunk.js +1 -0
- package/build/api-tokens-create-page.ac4285ba.chunk.js +1 -0
- package/build/api-tokens-edit-page.b8900ddd.chunk.js +1 -0
- package/build/api-tokens-list-page.d451255e.chunk.js +1 -0
- package/build/content-manager.d09d2a3a.chunk.js +1 -0
- package/build/index.html +1 -1
- package/build/main.3414cc4f.js +2 -0
- package/build/main.3414cc4f.js.LICENSE.txt +91 -0
- package/build/runtime~main.cc96a027.js +1 -0
- package/ee/server/controllers/authentication/middlewares.js +1 -1
- package/package.json +7 -7
- package/server/services/user.js +14 -0
- package/server/validation/authentication/register.js +2 -2
- package/server/validation/common-validators.js +1 -1
- package/server/validation/user.js +3 -3
|
@@ -9,12 +9,13 @@ import PluginsInitializer from '../PluginsInitializer';
|
|
|
9
9
|
import RBACProvider from '../RBACProvider';
|
|
10
10
|
import { fetchAppInfo, fetchCurrentUserPermissions, fetchStrapiLatestRelease } from './utils/api';
|
|
11
11
|
import checkLatestStrapiVersion from './utils/checkLatestStrapiVersion';
|
|
12
|
+
import { getFullName } from '../../utils';
|
|
12
13
|
|
|
13
14
|
const strapiVersion = packageJSON.version;
|
|
14
15
|
|
|
15
16
|
const AuthenticatedApp = () => {
|
|
16
17
|
const userInfo = auth.getUserInfo();
|
|
17
|
-
const userName = get(userInfo, 'username') ||
|
|
18
|
+
const userName = get(userInfo, 'username') || getFullName(userInfo.firstname, userInfo.lastname);
|
|
18
19
|
const [userDisplayName, setUserDisplayName] = useState(userName);
|
|
19
20
|
const { showReleaseNotification } = useConfigurations();
|
|
20
21
|
const [
|
|
File without changes
|
|
@@ -13,6 +13,7 @@ import { useHistory } from 'react-router-dom';
|
|
|
13
13
|
import { useIntl } from 'react-intl';
|
|
14
14
|
import { usePluginsQueryParams } from '../../../hooks';
|
|
15
15
|
import CellContent from '../CellContent';
|
|
16
|
+
import { getFullName } from '../../../../utils';
|
|
16
17
|
|
|
17
18
|
const TableRows = ({
|
|
18
19
|
canCreate,
|
|
@@ -69,7 +70,7 @@ const TableRows = ({
|
|
|
69
70
|
id: 'app.component.table.select.one-entry',
|
|
70
71
|
defaultMessage: `Select {target}`,
|
|
71
72
|
},
|
|
72
|
-
{ target:
|
|
73
|
+
{ target: getFullName(data.firstname, data.lastname) }
|
|
73
74
|
)}
|
|
74
75
|
checked={isChecked}
|
|
75
76
|
onChange={() => {
|
|
@@ -518,7 +518,9 @@ const EditViewDataManagerProvider = ({
|
|
|
518
518
|
when={!isEqual(modifiedData, initialData)}
|
|
519
519
|
message={formatMessage({ id: 'global.prompt.unsaved' })}
|
|
520
520
|
/>
|
|
521
|
-
<form onSubmit={handleSubmit}>
|
|
521
|
+
<form noValidate onSubmit={handleSubmit}>
|
|
522
|
+
{children}
|
|
523
|
+
</form>
|
|
522
524
|
</>
|
|
523
525
|
)}
|
|
524
526
|
</>
|
|
@@ -5,6 +5,7 @@ import isEmpty from 'lodash/isEmpty';
|
|
|
5
5
|
import Select, { createFilter } from 'react-select';
|
|
6
6
|
import { Box } from '@strapi/design-system/Box';
|
|
7
7
|
import { Stack } from '@strapi/design-system/Stack';
|
|
8
|
+
import { Typography } from '@strapi/design-system/Typography';
|
|
8
9
|
import ListItem from './ListItem';
|
|
9
10
|
|
|
10
11
|
function SelectMany({
|
|
@@ -26,6 +27,7 @@ function SelectMany({
|
|
|
26
27
|
styles,
|
|
27
28
|
targetModel,
|
|
28
29
|
value,
|
|
30
|
+
description,
|
|
29
31
|
}) {
|
|
30
32
|
const { formatMessage } = useIntl();
|
|
31
33
|
|
|
@@ -37,7 +39,7 @@ function SelectMany({
|
|
|
37
39
|
};
|
|
38
40
|
|
|
39
41
|
return (
|
|
40
|
-
|
|
42
|
+
<Stack size={1}>
|
|
41
43
|
<Select
|
|
42
44
|
components={components}
|
|
43
45
|
isDisabled={isDisabled}
|
|
@@ -95,11 +97,17 @@ function SelectMany({
|
|
|
95
97
|
})}
|
|
96
98
|
</Stack>
|
|
97
99
|
</Box>
|
|
98
|
-
|
|
100
|
+
{description && (
|
|
101
|
+
<Typography variant="pi" textColor="neutral600">
|
|
102
|
+
{description}
|
|
103
|
+
</Typography>
|
|
104
|
+
)}
|
|
105
|
+
</Stack>
|
|
99
106
|
);
|
|
100
107
|
}
|
|
101
108
|
|
|
102
109
|
SelectMany.defaultProps = {
|
|
110
|
+
description: '',
|
|
103
111
|
components: {},
|
|
104
112
|
placeholder: null,
|
|
105
113
|
searchToPersist: null,
|
|
@@ -133,6 +141,7 @@ SelectMany.propTypes = {
|
|
|
133
141
|
styles: PropTypes.object.isRequired,
|
|
134
142
|
targetModel: PropTypes.string.isRequired,
|
|
135
143
|
value: PropTypes.array,
|
|
144
|
+
description: PropTypes.string,
|
|
136
145
|
};
|
|
137
146
|
|
|
138
147
|
export default memo(SelectMany);
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import React, { memo } from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import { useIntl } from 'react-intl';
|
|
4
|
+
import { Stack } from '@strapi/design-system/Stack';
|
|
5
|
+
import { Typography } from '@strapi/design-system/Typography';
|
|
4
6
|
import get from 'lodash/get';
|
|
5
7
|
import isNull from 'lodash/isNull';
|
|
6
8
|
import Select from 'react-select';
|
|
@@ -21,36 +23,46 @@ function SelectOne({
|
|
|
21
23
|
placeholder,
|
|
22
24
|
styles,
|
|
23
25
|
value,
|
|
26
|
+
description,
|
|
24
27
|
}) {
|
|
25
28
|
const { formatMessage } = useIntl();
|
|
26
29
|
|
|
27
30
|
return (
|
|
28
|
-
<
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
placeholder
|
|
31
|
+
<Stack size={1}>
|
|
32
|
+
<Select
|
|
33
|
+
components={{
|
|
34
|
+
...components,
|
|
35
|
+
SingleValue,
|
|
36
|
+
}}
|
|
37
|
+
id={name}
|
|
38
|
+
isClearable
|
|
39
|
+
isDisabled={isDisabled}
|
|
40
|
+
isLoading={isLoading}
|
|
41
|
+
mainField={mainField}
|
|
42
|
+
options={options}
|
|
43
|
+
onChange={onChange}
|
|
44
|
+
onInputChange={onInputChange}
|
|
45
|
+
onMenuClose={onMenuClose}
|
|
46
|
+
onMenuOpen={onMenuOpen}
|
|
47
|
+
onMenuScrollToBottom={onMenuScrollToBottom}
|
|
48
|
+
placeholder={formatMessage(
|
|
49
|
+
placeholder || { id: 'components.Select.placeholder', defaultMessage: 'Select...' }
|
|
50
|
+
)}
|
|
51
|
+
styles={styles}
|
|
52
|
+
value={isNull(value) ? null : { label: get(value, [mainField.name], ''), value }}
|
|
53
|
+
/>
|
|
54
|
+
|
|
55
|
+
{description && (
|
|
56
|
+
<Typography variant="pi" textColor="neutral600">
|
|
57
|
+
{description}
|
|
58
|
+
</Typography>
|
|
46
59
|
)}
|
|
47
|
-
|
|
48
|
-
value={isNull(value) ? null : { label: get(value, [mainField.name], ''), value }}
|
|
49
|
-
/>
|
|
60
|
+
</Stack>
|
|
50
61
|
);
|
|
51
62
|
}
|
|
52
63
|
|
|
53
64
|
SelectOne.defaultProps = {
|
|
65
|
+
description: '',
|
|
54
66
|
components: {},
|
|
55
67
|
placeholder: null,
|
|
56
68
|
value: null,
|
|
@@ -79,6 +91,7 @@ SelectOne.propTypes = {
|
|
|
79
91
|
}),
|
|
80
92
|
styles: PropTypes.object.isRequired,
|
|
81
93
|
value: PropTypes.object,
|
|
94
|
+
description: PropTypes.string,
|
|
82
95
|
};
|
|
83
96
|
|
|
84
97
|
export default memo(SelectOne);
|
|
@@ -50,7 +50,7 @@ const buildParams = (query, paramsToKeep) => {
|
|
|
50
50
|
}, {});
|
|
51
51
|
};
|
|
52
52
|
function SelectWrapper({
|
|
53
|
-
|
|
53
|
+
description,
|
|
54
54
|
editable,
|
|
55
55
|
labelAction,
|
|
56
56
|
intlLabel,
|
|
@@ -316,6 +316,7 @@ function SelectWrapper({
|
|
|
316
316
|
styles={styles}
|
|
317
317
|
targetModel={targetModel}
|
|
318
318
|
value={value}
|
|
319
|
+
description={description}
|
|
319
320
|
/>
|
|
320
321
|
</Stack>
|
|
321
322
|
);
|
|
@@ -390,7 +391,7 @@ function SelectWrapper({
|
|
|
390
391
|
|
|
391
392
|
SelectWrapper.defaultProps = {
|
|
392
393
|
editable: true,
|
|
393
|
-
|
|
394
|
+
description: '',
|
|
394
395
|
labelAction: null,
|
|
395
396
|
isFieldAllowed: true,
|
|
396
397
|
placeholder: null,
|
|
@@ -398,11 +399,7 @@ SelectWrapper.defaultProps = {
|
|
|
398
399
|
|
|
399
400
|
SelectWrapper.propTypes = {
|
|
400
401
|
editable: PropTypes.bool,
|
|
401
|
-
|
|
402
|
-
// id: PropTypes.string.isRequired,
|
|
403
|
-
// defaultMessage: PropTypes.string.isRequired,
|
|
404
|
-
// values: PropTypes.object,
|
|
405
|
-
// }),
|
|
402
|
+
description: PropTypes.string,
|
|
406
403
|
intlLabel: PropTypes.shape({
|
|
407
404
|
id: PropTypes.string.isRequired,
|
|
408
405
|
defaultMessage: PropTypes.string.isRequired,
|
|
@@ -31,13 +31,14 @@ const Editor = ({
|
|
|
31
31
|
},
|
|
32
32
|
readOnly: false,
|
|
33
33
|
smartIndent: false,
|
|
34
|
+
placeholder,
|
|
34
35
|
});
|
|
35
36
|
|
|
36
37
|
CodeMirror.commands.newlineAndIndentContinueMarkdownList = newlineAndIndentContinueMarkdownList;
|
|
37
38
|
editorRef.current.on('change', doc => {
|
|
38
39
|
onChangeRef.current({ target: { name, value: doc.getValue(), type: 'wysiwyg' } });
|
|
39
40
|
});
|
|
40
|
-
}, [editorRef, textareaRef, name]);
|
|
41
|
+
}, [editorRef, textareaRef, name, placeholder]);
|
|
41
42
|
|
|
42
43
|
useEffect(() => {
|
|
43
44
|
if (value && !editorRef.current.state.focused) {
|
|
@@ -65,7 +66,7 @@ const Editor = ({
|
|
|
65
66
|
return (
|
|
66
67
|
<EditorAndPreviewWrapper>
|
|
67
68
|
<EditorStylesContainer disabled={disabled || isPreviewMode}>
|
|
68
|
-
<textarea ref={textareaRef}
|
|
69
|
+
<textarea ref={textareaRef} />
|
|
69
70
|
</EditorStylesContainer>
|
|
70
71
|
{isPreviewMode && <PreviewWysiwyg data={value} />}
|
|
71
72
|
</EditorAndPreviewWrapper>
|
|
@@ -5,6 +5,9 @@ import styled from 'styled-components';
|
|
|
5
5
|
export const EditorStylesContainer = styled.div`
|
|
6
6
|
cursor: ${({ disabled }) => (disabled ? 'not-allowed !important' : 'auto')};
|
|
7
7
|
/* BASICS */
|
|
8
|
+
.CodeMirror-placeholder {
|
|
9
|
+
color: ${({ theme }) => theme.colors.neutral600} !important;
|
|
10
|
+
}
|
|
8
11
|
|
|
9
12
|
.CodeMirror {
|
|
10
13
|
/* Set height, width, borders, and global font properties here */
|
|
@@ -12,6 +15,8 @@ export const EditorStylesContainer = styled.div`
|
|
|
12
15
|
height: 290px;
|
|
13
16
|
color: ${({ theme }) => theme.colors.neutral800};
|
|
14
17
|
direction: ltr;
|
|
18
|
+
font-family: --apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell,
|
|
19
|
+
'Open Sans', 'Helvetica Neue', sans-serif;
|
|
15
20
|
}
|
|
16
21
|
|
|
17
22
|
/* PADDING */
|
|
@@ -331,8 +336,6 @@ export const EditorStylesContainer = styled.div`
|
|
|
331
336
|
}
|
|
332
337
|
|
|
333
338
|
span {
|
|
334
|
-
font-family: --apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell,
|
|
335
|
-
'Open Sans', 'Helvetica Neue', sans-serif;
|
|
336
339
|
color: ${({ theme }) => theme.colors.neutral800} !important;
|
|
337
340
|
}
|
|
338
341
|
`;
|
|
@@ -10,7 +10,7 @@ import { Flex } from '@strapi/design-system/Flex';
|
|
|
10
10
|
import Bold from '@strapi/icons/Bold';
|
|
11
11
|
import Italic from '@strapi/icons/Italic';
|
|
12
12
|
import Underline from '@strapi/icons/Underline';
|
|
13
|
-
import Strikethrough from '@strapi/icons/
|
|
13
|
+
import Strikethrough from '@strapi/icons/Strikethrough';
|
|
14
14
|
import BulletList from '@strapi/icons/BulletList';
|
|
15
15
|
import NumberList from '@strapi/icons/NumberList';
|
|
16
16
|
import Code from '@strapi/icons/Code';
|
|
@@ -8,6 +8,7 @@ import { Flex } from '@strapi/design-system/Flex';
|
|
|
8
8
|
import { Stack } from '@strapi/design-system/Stack';
|
|
9
9
|
import { getTrad } from '../../../utils';
|
|
10
10
|
import getUnits from './utils/getUnits';
|
|
11
|
+
import { getFullName } from '../../../../utils';
|
|
11
12
|
|
|
12
13
|
const Informations = () => {
|
|
13
14
|
const { formatMessage, formatRelativeTime } = useIntl();
|
|
@@ -17,7 +18,7 @@ const Informations = () => {
|
|
|
17
18
|
const updatedByFirstname = initialData.updatedBy?.firstname || '';
|
|
18
19
|
const updatedByLastname = initialData.updatedBy?.lastname || '';
|
|
19
20
|
const updatedByUsername = initialData.updatedBy?.username;
|
|
20
|
-
const updatedBy = updatedByUsername ||
|
|
21
|
+
const updatedBy = updatedByUsername || getFullName(updatedByFirstname, updatedByLastname);
|
|
21
22
|
const currentTime = useRef(Date.now());
|
|
22
23
|
const timestamp = initialData[updatedAt]
|
|
23
24
|
? new Date(initialData[updatedAt]).getTime()
|
|
@@ -28,7 +29,7 @@ const Informations = () => {
|
|
|
28
29
|
|
|
29
30
|
return (
|
|
30
31
|
<Box>
|
|
31
|
-
<Typography variant="sigma" textColor="neutral600">
|
|
32
|
+
<Typography variant="sigma" textColor="neutral600" id="additional-informations">
|
|
32
33
|
{formatMessage({
|
|
33
34
|
id: getTrad('containers.Edit.information'),
|
|
34
35
|
defaultMessage: 'Information',
|
|
@@ -252,7 +252,7 @@ const EditView = ({
|
|
|
252
252
|
{displayedRelationsLength > 0 && (
|
|
253
253
|
<Box
|
|
254
254
|
as="aside"
|
|
255
|
-
aria-labelledby="
|
|
255
|
+
aria-labelledby="relations-title"
|
|
256
256
|
background="neutral0"
|
|
257
257
|
borderColor="neutral150"
|
|
258
258
|
hasRadius
|
|
@@ -262,7 +262,7 @@ const EditView = ({
|
|
|
262
262
|
paddingTop={6}
|
|
263
263
|
shadow="tableShadow"
|
|
264
264
|
>
|
|
265
|
-
<Typography variant="sigma" textColor="neutral600">
|
|
265
|
+
<Typography variant="sigma" textColor="neutral600" id="relations-title">
|
|
266
266
|
{formatMessage(
|
|
267
267
|
{
|
|
268
268
|
id: getTrad('containers.Edit.relations'),
|
|
@@ -283,10 +283,7 @@ const EditView = ({
|
|
|
283
283
|
{...fieldSchema}
|
|
284
284
|
{...metadatas}
|
|
285
285
|
key={name}
|
|
286
|
-
description={
|
|
287
|
-
id: metadatas.description,
|
|
288
|
-
defaultMessage: metadatas.description,
|
|
289
|
-
}}
|
|
286
|
+
description={metadatas.description}
|
|
290
287
|
intlLabel={{
|
|
291
288
|
id: metadatas.label,
|
|
292
289
|
defaultMessage: metadatas.label,
|
|
@@ -155,15 +155,6 @@ const Register = ({ fieldsToDisable, noSignin, onSubmit, schema }) => {
|
|
|
155
155
|
<GridItem col={6}>
|
|
156
156
|
<TextInput
|
|
157
157
|
name="lastname"
|
|
158
|
-
error={
|
|
159
|
-
errors.lastname
|
|
160
|
-
? formatMessage({
|
|
161
|
-
id: errors.lastname,
|
|
162
|
-
defaultMessage: 'This value is required.',
|
|
163
|
-
})
|
|
164
|
-
: undefined
|
|
165
|
-
}
|
|
166
|
-
required
|
|
167
158
|
value={values.lastname}
|
|
168
159
|
onChange={handleChange}
|
|
169
160
|
label={formatMessage({
|
|
@@ -59,7 +59,7 @@ const forms = {
|
|
|
59
59
|
fieldsToOmit: ['userInfo.confirmPassword', 'userInfo.news', 'userInfo.email'],
|
|
60
60
|
schema: yup.object().shape({
|
|
61
61
|
firstname: yup.string().required(translatedErrors.required),
|
|
62
|
-
lastname: yup.string()
|
|
62
|
+
lastname: yup.string(),
|
|
63
63
|
password: yup
|
|
64
64
|
.string()
|
|
65
65
|
.min(8, translatedErrors.minLength)
|
|
@@ -83,7 +83,7 @@ const forms = {
|
|
|
83
83
|
fieldsToOmit: ['confirmPassword', 'news'],
|
|
84
84
|
schema: yup.object().shape({
|
|
85
85
|
firstname: yup.string().required(translatedErrors.required),
|
|
86
|
-
lastname: yup.string()
|
|
86
|
+
lastname: yup.string(),
|
|
87
87
|
password: yup
|
|
88
88
|
.string()
|
|
89
89
|
.min(8, translatedErrors.minLength)
|
|
@@ -33,6 +33,7 @@ import Check from '@strapi/icons/Check';
|
|
|
33
33
|
import useLocalesProvider from '../../components/LocalesProvider/useLocalesProvider';
|
|
34
34
|
import { fetchUser, putUser } from './utils/api';
|
|
35
35
|
import schema from './utils/schema';
|
|
36
|
+
import { getFullName } from '../../utils';
|
|
36
37
|
|
|
37
38
|
const PasswordInput = styled(TextInput)`
|
|
38
39
|
::-ms-reveal {
|
|
@@ -87,7 +88,7 @@ const ProfilePage = () => {
|
|
|
87
88
|
await queryClient.invalidateQueries('user');
|
|
88
89
|
|
|
89
90
|
auth.setUserInfo(data);
|
|
90
|
-
const userDisplayName = data.username ||
|
|
91
|
+
const userDisplayName = data.username || getFullName(data.firstname, data.lastname);
|
|
91
92
|
setUserDisplayName(userDisplayName);
|
|
92
93
|
changeLocale(data.preferedLanguage);
|
|
93
94
|
|
|
@@ -172,7 +173,7 @@ const ProfilePage = () => {
|
|
|
172
173
|
return (
|
|
173
174
|
<Form>
|
|
174
175
|
<HeaderLayout
|
|
175
|
-
title={data.username ||
|
|
176
|
+
title={data.username || getFullName(data.firstname, data.lastname)}
|
|
176
177
|
primaryAction={
|
|
177
178
|
<Button startIcon={<Check />} loading={isSubmitting} type="submit">
|
|
178
179
|
{formatMessage({ id: 'form.button.save', defaultMessage: 'Save' })}
|
package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/ContentBox/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useRef } from 'react';
|
|
2
2
|
import { useIntl } from 'react-intl';
|
|
3
|
-
import { ContentBox, useNotification } from '@strapi/helper-plugin';
|
|
3
|
+
import { ContentBox, useNotification, useTracking } from '@strapi/helper-plugin';
|
|
4
4
|
import { IconButton } from '@strapi/design-system/IconButton';
|
|
5
5
|
import Duplicate from '@strapi/icons/Duplicate';
|
|
6
6
|
import PropTypes from 'prop-types';
|
|
@@ -10,6 +10,8 @@ import Key from '@strapi/icons/Key';
|
|
|
10
10
|
const HeaderContentBox = ({ apiToken }) => {
|
|
11
11
|
const { formatMessage } = useIntl();
|
|
12
12
|
const toggleNotification = useNotification();
|
|
13
|
+
const { trackUsage } = useTracking();
|
|
14
|
+
const trackUsageRef = useRef(trackUsage);
|
|
13
15
|
|
|
14
16
|
return (
|
|
15
17
|
<ContentBox
|
|
@@ -18,6 +20,7 @@ const HeaderContentBox = ({ apiToken }) => {
|
|
|
18
20
|
<span style={{ alignSelf: 'start' }}>
|
|
19
21
|
<CopyToClipboard
|
|
20
22
|
onCopy={() => {
|
|
23
|
+
trackUsageRef('didCopyTokenKey');
|
|
21
24
|
toggleNotification({
|
|
22
25
|
type: 'success',
|
|
23
26
|
message: { id: 'Settings.apiTokens.notification.copied' },
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useEffect, useRef } from 'react';
|
|
2
2
|
import { useIntl } from 'react-intl';
|
|
3
3
|
import {
|
|
4
4
|
SettingsPageTitle,
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
Form,
|
|
7
7
|
useOverlayBlocker,
|
|
8
8
|
useNotification,
|
|
9
|
+
useTracking,
|
|
9
10
|
} from '@strapi/helper-plugin';
|
|
10
11
|
import { HeaderLayout, ContentLayout } from '@strapi/design-system/Layout';
|
|
11
12
|
import { Main } from '@strapi/design-system/Main';
|
|
@@ -37,6 +38,8 @@ const ApiTokenCreateView = () => {
|
|
|
37
38
|
const { lockApp, unlockApp } = useOverlayBlocker();
|
|
38
39
|
const toggleNotification = useNotification();
|
|
39
40
|
const history = useHistory();
|
|
41
|
+
const { trackUsage } = useTracking();
|
|
42
|
+
const trackUsageRef = useRef(trackUsage);
|
|
40
43
|
|
|
41
44
|
const {
|
|
42
45
|
params: { id },
|
|
@@ -44,6 +47,10 @@ const ApiTokenCreateView = () => {
|
|
|
44
47
|
|
|
45
48
|
const isCreating = id === 'create';
|
|
46
49
|
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
trackUsageRef.current(isCreating ? 'didAddTokenFromList' : 'didEditTokenFromList');
|
|
52
|
+
}, [isCreating]);
|
|
53
|
+
|
|
47
54
|
if (history.location.state?.apiToken.accessKey) {
|
|
48
55
|
apiToken = history.location.state.apiToken;
|
|
49
56
|
}
|
|
@@ -73,6 +80,7 @@ const ApiTokenCreateView = () => {
|
|
|
73
80
|
}
|
|
74
81
|
|
|
75
82
|
const handleSubmit = async (body, actions) => {
|
|
83
|
+
trackUsageRef.current(isCreating ? 'willCreateToken' : 'willEditToken');
|
|
76
84
|
lockApp();
|
|
77
85
|
|
|
78
86
|
try {
|
|
@@ -89,6 +97,10 @@ const ApiTokenCreateView = () => {
|
|
|
89
97
|
message: formatMessage({ id: 'notification.success.saved', defaultMessage: 'Saved' }),
|
|
90
98
|
});
|
|
91
99
|
|
|
100
|
+
trackUsageRef.current(isCreating ? 'didCreateToken' : 'didEditToken', {
|
|
101
|
+
type: apiToken.type,
|
|
102
|
+
});
|
|
103
|
+
|
|
92
104
|
if (isCreating) {
|
|
93
105
|
history.replace(`/settings/api-tokens/${response.id}`, { apiToken: response });
|
|
94
106
|
}
|
package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/DeleteButton/index.js
CHANGED
|
@@ -2,17 +2,21 @@ import React from 'react';
|
|
|
2
2
|
import Trash from '@strapi/icons/Trash';
|
|
3
3
|
import { IconButton } from '@strapi/design-system/IconButton';
|
|
4
4
|
import { Box } from '@strapi/design-system/Box';
|
|
5
|
-
import { stopPropagation } from '@strapi/helper-plugin';
|
|
5
|
+
import { stopPropagation, useTracking } from '@strapi/helper-plugin';
|
|
6
6
|
import { useIntl } from 'react-intl';
|
|
7
7
|
import PropTypes from 'prop-types';
|
|
8
8
|
|
|
9
9
|
const DeleteButton = ({ tokenName, onClickDelete }) => {
|
|
10
10
|
const { formatMessage } = useIntl();
|
|
11
|
+
const { trackUsage } = useTracking();
|
|
11
12
|
|
|
12
13
|
return (
|
|
13
14
|
<Box paddingLeft={1} {...stopPropagation}>
|
|
14
15
|
<IconButton
|
|
15
|
-
onClick={
|
|
16
|
+
onClick={() => {
|
|
17
|
+
trackUsage('willDeleteToken');
|
|
18
|
+
onClickDelete();
|
|
19
|
+
}}
|
|
16
20
|
label={formatMessage(
|
|
17
21
|
{
|
|
18
22
|
id: 'app.component.table.delete',
|
|
@@ -2,7 +2,13 @@ import React from 'react';
|
|
|
2
2
|
import { Typography } from '@strapi/design-system/Typography';
|
|
3
3
|
import { Tbody, Tr, Td } from '@strapi/design-system/Table';
|
|
4
4
|
import { Flex } from '@strapi/design-system/Flex';
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
RelativeTime,
|
|
7
|
+
useQueryParams,
|
|
8
|
+
onRowClick,
|
|
9
|
+
pxToRem,
|
|
10
|
+
useTracking,
|
|
11
|
+
} from '@strapi/helper-plugin';
|
|
6
12
|
import { useIntl } from 'react-intl';
|
|
7
13
|
import PropTypes from 'prop-types';
|
|
8
14
|
import { useHistory } from 'react-router-dom';
|
|
@@ -17,6 +23,7 @@ const TableRows = ({ canDelete, canUpdate, onClickDelete, withBulkActions, rows
|
|
|
17
23
|
push,
|
|
18
24
|
location: { pathname },
|
|
19
25
|
} = useHistory();
|
|
26
|
+
const { trackUsage } = useTracking();
|
|
20
27
|
|
|
21
28
|
const apiTokens = rows.sort((a, b) => {
|
|
22
29
|
const comparaison = a.name.localeCompare(b.name);
|
|
@@ -31,7 +38,10 @@ const TableRows = ({ canDelete, canUpdate, onClickDelete, withBulkActions, rows
|
|
|
31
38
|
<Tr
|
|
32
39
|
key={apiToken.id}
|
|
33
40
|
{...onRowClick({
|
|
34
|
-
fn: () =>
|
|
41
|
+
fn: () => {
|
|
42
|
+
trackUsage('willEditTokenFromList');
|
|
43
|
+
push(`${pathname}/${apiToken.id}`);
|
|
44
|
+
},
|
|
35
45
|
condition: canUpdate,
|
|
36
46
|
})}
|
|
37
47
|
>
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
useRBAC,
|
|
9
9
|
NoContent,
|
|
10
10
|
DynamicTable,
|
|
11
|
+
useTracking,
|
|
11
12
|
} from '@strapi/helper-plugin';
|
|
12
13
|
import { HeaderLayout, ContentLayout } from '@strapi/design-system/Layout';
|
|
13
14
|
import { Main } from '@strapi/design-system/Main';
|
|
@@ -31,6 +32,7 @@ const ApiTokenListView = () => {
|
|
|
31
32
|
allowedActions: { canCreate, canDelete, canUpdate, canRead },
|
|
32
33
|
} = useRBAC(adminPermissions.settings['api-tokens']);
|
|
33
34
|
const { push } = useHistory();
|
|
35
|
+
const { trackUsage } = useTracking();
|
|
34
36
|
|
|
35
37
|
useEffect(() => {
|
|
36
38
|
push({ search: qs.stringify({ sort: 'name:ASC' }, { encode: false }) });
|
|
@@ -39,10 +41,13 @@ const ApiTokenListView = () => {
|
|
|
39
41
|
const { data: apiTokens, status, isFetching } = useQuery(
|
|
40
42
|
['api-tokens'],
|
|
41
43
|
async () => {
|
|
44
|
+
trackUsage('willAccessTokenList');
|
|
42
45
|
const {
|
|
43
46
|
data: { data },
|
|
44
47
|
} = await axiosInstance.get(`/admin/api-tokens`);
|
|
45
48
|
|
|
49
|
+
trackUsage('didAccessTokenList', { number: data.length });
|
|
50
|
+
|
|
46
51
|
return data;
|
|
47
52
|
},
|
|
48
53
|
{
|
|
@@ -67,6 +72,7 @@ const ApiTokenListView = () => {
|
|
|
67
72
|
{
|
|
68
73
|
onSuccess: async () => {
|
|
69
74
|
await queryClient.invalidateQueries(['api-tokens']);
|
|
75
|
+
trackUsage('didDeleteToken');
|
|
70
76
|
},
|
|
71
77
|
onError: err => {
|
|
72
78
|
if (err?.response?.data?.data) {
|
|
@@ -100,6 +106,7 @@ const ApiTokenListView = () => {
|
|
|
100
106
|
data-testid="create-api-token-button"
|
|
101
107
|
startIcon={<Plus />}
|
|
102
108
|
size="L"
|
|
109
|
+
onClick={() => trackUsage('willAddTokenFromList')}
|
|
103
110
|
to="/settings/api-tokens/create"
|
|
104
111
|
>
|
|
105
112
|
{formatMessage({
|
|
@@ -20,7 +20,7 @@ import { useIntl } from 'react-intl';
|
|
|
20
20
|
import { useHistory } from 'react-router-dom';
|
|
21
21
|
import RoleRow from './components/RoleRow';
|
|
22
22
|
import EmptyRole from './components/EmptyRole';
|
|
23
|
-
import UpgradePlanModal from '../../../../../components/UpgradePlanModal
|
|
23
|
+
import UpgradePlanModal from '../../../../../components/UpgradePlanModal';
|
|
24
24
|
import { useRolesList } from '../../../../../hooks';
|
|
25
25
|
|
|
26
26
|
const useSortedRoles = () => {
|
|
@@ -29,7 +29,7 @@ import { Stack } from '@strapi/design-system/Stack';
|
|
|
29
29
|
import ArrowLeft from '@strapi/icons/ArrowLeft';
|
|
30
30
|
import Check from '@strapi/icons/Check';
|
|
31
31
|
import MagicLink from 'ee_else_ce/pages/SettingsPage/pages/Users/components/MagicLink';
|
|
32
|
-
import { formatAPIErrors } from '../../../../../utils';
|
|
32
|
+
import { formatAPIErrors, getFullName } from '../../../../../utils';
|
|
33
33
|
import { fetchUser, putUser } from './utils/api';
|
|
34
34
|
import layout from './utils/layout';
|
|
35
35
|
import { editValidation } from '../utils/validations/users';
|
|
@@ -89,7 +89,7 @@ const EditPage = ({ canUpdate }) => {
|
|
|
89
89
|
if (id.toString() === userInfos.id.toString()) {
|
|
90
90
|
auth.setUserInfo(data);
|
|
91
91
|
|
|
92
|
-
const userDisplayName = get(body, 'username') ||
|
|
92
|
+
const userDisplayName = get(body, 'username') || getFullName(body.firstname, body.lastname);
|
|
93
93
|
|
|
94
94
|
setUserDisplayName(userDisplayName);
|
|
95
95
|
}
|
|
@@ -131,7 +131,7 @@ const EditPage = ({ canUpdate }) => {
|
|
|
131
131
|
}, {});
|
|
132
132
|
|
|
133
133
|
const headerLabelName =
|
|
134
|
-
initialData.username ||
|
|
134
|
+
initialData.username || getFullName(initialData.firstname, initialData.lastname);
|
|
135
135
|
|
|
136
136
|
const title = formatMessage(headerLabel, { name: headerLabelName });
|
|
137
137
|
|