@strapi/admin 4.4.0-beta.1 → 4.4.0-beta.3

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.
Files changed (97) hide show
  1. package/admin/src/StrapiApp.js +4 -12
  2. package/admin/src/components/Providers/index.js +14 -10
  3. package/admin/src/content-manager/components/FieldTypeIcon/index.js +31 -1
  4. package/admin/src/content-manager/components/Inputs/index.js +30 -10
  5. package/admin/src/content-manager/pages/EditSettingsView/components/FormModal.js +7 -2
  6. package/admin/src/content-manager/pages/EditSettingsView/index.js +2 -1
  7. package/admin/src/content-manager/pages/EditView/index.js +91 -84
  8. package/admin/src/core/apis/CustomFields.js +80 -0
  9. package/admin/src/core/apis/index.js +1 -0
  10. package/admin/src/hooks/index.js +0 -1
  11. package/admin/src/pages/AuthPage/utils/forms.js +2 -2
  12. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/index.js +180 -452
  13. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/utils/schema.js +1 -2
  14. package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/DeleteButton/index.js +0 -1
  15. package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/UpdateButton/index.js +36 -3
  16. package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/index.js +11 -13
  17. package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/index.js +2 -3
  18. package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/utils/tableHeaders.js +8 -8
  19. package/admin/src/pages/SettingsPage/pages/ApiTokens/ProtectedEditView/index.js +1 -1
  20. package/admin/src/pages/SettingsPage/pages/Users/ListPage/ModalForm/utils/schema.js +1 -1
  21. package/admin/src/pages/SettingsPage/pages/Users/utils/validations/users/profile.js +2 -2
  22. package/admin/src/permissions/defaultPermissions.js +6 -2
  23. package/admin/src/translations/en.json +0 -17
  24. package/build/524.40377968.chunk.js +644 -0
  25. package/build/{Admin-authenticatedApp.3a31a087.chunk.js → Admin-authenticatedApp.50e41ff2.chunk.js} +1 -1
  26. package/build/{Admin_homePage.6d5e3236.chunk.js → Admin_homePage.118926e0.chunk.js} +1 -1
  27. package/build/{Admin_profilePage.83991a6c.chunk.js → Admin_profilePage.9d50ac44.chunk.js} +4 -4
  28. package/build/{Admin_settingsPage.fc9c607a.chunk.js → Admin_settingsPage.98a711e5.chunk.js} +16 -16
  29. package/build/admin-app.8bc3e80f.chunk.js +112 -0
  30. package/build/admin-edit-roles-page.554ba3fa.chunk.js +1 -0
  31. package/build/{admin-edit-users.5bebf473.chunk.js → admin-edit-users.c585212f.chunk.js} +2 -2
  32. package/build/{admin-users.dccd5f4c.chunk.js → admin-users.97a08630.chunk.js} +1 -1
  33. package/build/api-tokens-create-page.4c262d6e.chunk.js +1 -0
  34. package/build/api-tokens-edit-page.10a9d368.chunk.js +1 -0
  35. package/build/api-tokens-list-page.442c9f3c.chunk.js +15 -0
  36. package/build/content-manager.2a6f876d.chunk.js +1178 -0
  37. package/build/content-type-builder-list-view.5b3cd768.chunk.js +194 -0
  38. package/build/content-type-builder-translation-en-json.f985c9c4.chunk.js +1 -0
  39. package/build/content-type-builder.d4610e20.chunk.js +145 -0
  40. package/build/en-json.12bc5a14.chunk.js +1 -0
  41. package/build/index.html +1 -1
  42. package/build/{main.cdfda31e.js → main.fdc482f3.js} +1151 -1151
  43. package/build/{runtime~main.fa8f8898.js → runtime~main.29105d25.js} +2 -2
  44. package/build/sso-settings-page.445184e0.chunk.js +1 -0
  45. package/build/{webhook-edit-page.9e46fc3f.chunk.js → webhook-edit-page.d2ea3351.chunk.js} +1 -1
  46. package/package.json +7 -8
  47. package/server/bootstrap.js +1 -19
  48. package/server/config/admin-actions.js +0 -20
  49. package/server/content-types/api-token.js +1 -25
  50. package/server/content-types/index.js +0 -1
  51. package/server/controllers/api-token.js +1 -24
  52. package/server/controllers/index.js +0 -1
  53. package/server/routes/api-tokens.js +0 -11
  54. package/server/routes/index.js +0 -2
  55. package/server/services/api-token.js +29 -310
  56. package/server/services/constants.js +0 -10
  57. package/server/services/permission/engine-hooks.js +82 -0
  58. package/server/services/permission/engine.js +226 -36
  59. package/server/services/permission.js +1 -4
  60. package/server/strategies/admin.js +1 -7
  61. package/server/strategies/api-token.js +11 -71
  62. package/server/validation/api-tokens.js +2 -12
  63. package/server/validation/common-validators.js +1 -1
  64. package/admin/src/contexts/ApiTokenPermissions/index.js +0 -24
  65. package/admin/src/hooks/useRegenerate/index.js +0 -34
  66. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/ActionBoundRoutes/index.js +0 -56
  67. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/BoundRoute/getMethodColor.js +0 -41
  68. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/BoundRoute/index.js +0 -72
  69. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/CollapsableContentType/CheckBoxWrapper.js +0 -30
  70. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/CollapsableContentType/index.js +0 -150
  71. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/ContenTypesSection/index.js +0 -37
  72. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/Permissions/index.js +0 -40
  73. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/Regenerate/index.js +0 -68
  74. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/init.js +0 -13
  75. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/reducer.js +0 -55
  76. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/utils/getDateOfExpiration.js +0 -16
  77. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/utils/index.js +0 -5
  78. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/utils/transformPermissionsData.js +0 -36
  79. package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/DefaultButton/index.js +0 -63
  80. package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/ReadButton/index.js +0 -19
  81. package/build/4235.982b5799.chunk.js +0 -30
  82. package/build/611.a91aff91.chunk.js +0 -158
  83. package/build/7379.d246dd38.chunk.js +0 -1
  84. package/build/admin-app.41b6472c.chunk.js +0 -112
  85. package/build/admin-edit-roles-page.4dd6bcb9.chunk.js +0 -1
  86. package/build/api-tokens-create-page.29cc87b6.chunk.js +0 -1
  87. package/build/api-tokens-edit-page.c294a88f.chunk.js +0 -1
  88. package/build/api-tokens-list-page.bb36535f.chunk.js +0 -16
  89. package/build/content-manager.fb5ee865.chunk.js +0 -1178
  90. package/build/content-type-builder-list-view.8cc534e0.chunk.js +0 -194
  91. package/build/content-type-builder-translation-en-json.201bfb78.chunk.js +0 -1
  92. package/build/content-type-builder.42cecba9.chunk.js +0 -142
  93. package/build/en-json.a9918c93.chunk.js +0 -1
  94. package/build/sso-settings-page.9ceb0140.chunk.js +0 -1
  95. package/server/content-types/api-token-permission.js +0 -36
  96. package/server/controllers/content-api.js +0 -15
  97. package/server/routes/content-api.js +0 -20
@@ -1,72 +0,0 @@
1
- import React from 'react';
2
- import styled from 'styled-components';
3
- import { Stack } from '@strapi/design-system/Stack';
4
- import { Box } from '@strapi/design-system/Box';
5
- import { Typography } from '@strapi/design-system/Typography';
6
- import map from 'lodash/map';
7
- import tail from 'lodash/tail';
8
- import { useIntl } from 'react-intl';
9
- import PropTypes from 'prop-types';
10
- import getMethodColor from './getMethodColor';
11
-
12
- const MethodBox = styled(Box)`
13
- margin: -1px;
14
- border-radius: ${({ theme }) => theme.spaces[1]} 0 0 ${({ theme }) => theme.spaces[1]};
15
- `;
16
-
17
- function BoundRoute({ route }) {
18
- const { formatMessage } = useIntl();
19
-
20
- const { method, handler: title, path } = route;
21
- const formattedRoute = path ? tail(path.split('/')) : [];
22
- const [controller = '', action = ''] = title ? title.split('.') : [];
23
- const colors = getMethodColor(route.method);
24
-
25
- return (
26
- <Stack spacing={2}>
27
- <Typography variant="delta" as="h3">
28
- {formatMessage({
29
- id: 'Settings.apiTokens.createPage.BoundRoute.title',
30
- defaultMessage: 'Bound route to',
31
- })}
32
- &nbsp;
33
- <span>{controller}</span>
34
- <Typography variant="delta" textColor="primary600">
35
- .{action}
36
- </Typography>
37
- </Typography>
38
- <Stack horizontal hasRadius background="neutral0" borderColor="neutral200" spacing={0}>
39
- <MethodBox background={colors.background} borderColor={colors.border} padding={2}>
40
- <Typography fontWeight="bold" textColor={colors.text}>
41
- {method}
42
- </Typography>
43
- </MethodBox>
44
- <Box paddingLeft={2} paddingRight={2}>
45
- {map(formattedRoute, (value) => (
46
- <Typography key={value} textColor={value.includes(':') ? 'neutral600' : 'neutral900'}>
47
- /{value}
48
- </Typography>
49
- ))}
50
- </Box>
51
- </Stack>
52
- </Stack>
53
- );
54
- }
55
-
56
- BoundRoute.defaultProps = {
57
- route: {
58
- handler: 'Nocontroller.error',
59
- method: 'GET',
60
- path: '/there-is-no-path',
61
- },
62
- };
63
-
64
- BoundRoute.propTypes = {
65
- route: PropTypes.shape({
66
- handler: PropTypes.string,
67
- method: PropTypes.string,
68
- path: PropTypes.string,
69
- }),
70
- };
71
-
72
- export default BoundRoute;
@@ -1,30 +0,0 @@
1
- import styled, { css } from 'styled-components';
2
- import { Box } from '@strapi/design-system/Box';
3
-
4
- const activeCheckboxWrapperStyles = css`
5
- background: ${(props) => props.theme.colors.primary100};
6
- svg {
7
- opacity: 1;
8
- }
9
- `;
10
-
11
- const CheckboxWrapper = styled(Box)`
12
- display: flex;
13
- justify-content: space-between;
14
- align-items: center;
15
-
16
- svg {
17
- opacity: 0;
18
- path {
19
- fill: ${(props) => props.theme.colors.primary600};
20
- }
21
- }
22
-
23
- /* Show active style both on hover and when the action is selected */
24
- ${(props) => props.isActive && activeCheckboxWrapperStyles}
25
- &:hover {
26
- ${activeCheckboxWrapperStyles}
27
- }
28
- `;
29
-
30
- export default CheckboxWrapper;
@@ -1,150 +0,0 @@
1
- import React, { useState, useEffect } from 'react';
2
- import { capitalize } from 'lodash';
3
- import { Accordion, AccordionToggle, AccordionContent } from '@strapi/design-system/Accordion';
4
- import { Checkbox } from '@strapi/design-system/Checkbox';
5
- import { Grid, GridItem } from '@strapi/design-system/Grid';
6
- import { Typography } from '@strapi/design-system/Typography';
7
- import { Box } from '@strapi/design-system/Box';
8
- import { Flex } from '@strapi/design-system/Flex';
9
- import CogIcon from '@strapi/icons/Cog';
10
- import styled from 'styled-components';
11
- import PropTypes from 'prop-types';
12
- import { useApiTokenPermissionsContext } from '../../../../../../../contexts/ApiTokenPermissions';
13
- import CheckboxWrapper from './CheckBoxWrapper';
14
-
15
- const Border = styled.div`
16
- flex: 1;
17
- align-self: center;
18
- border-top: 1px solid ${({ theme }) => theme.colors.neutral150};
19
- `;
20
-
21
- const CollapsableContentType = ({
22
- controllers,
23
- label,
24
- orderNumber,
25
- disabled,
26
- onExpanded,
27
- indexExpandendCollapsedContent,
28
- }) => {
29
- const {
30
- value: { onChangeSelectAll, onChange, selectedActions, setSelectedAction, selectedAction },
31
- } = useApiTokenPermissionsContext();
32
- const [expanded, setExpanded] = useState(false);
33
-
34
- const handleExpandedAccordion = () => {
35
- setExpanded((s) => !s);
36
- onExpanded(orderNumber);
37
- };
38
-
39
- useEffect(() => {
40
- if (
41
- indexExpandendCollapsedContent !== null &&
42
- indexExpandendCollapsedContent !== orderNumber &&
43
- expanded
44
- ) {
45
- setExpanded(false);
46
- }
47
- }, [indexExpandendCollapsedContent, orderNumber, expanded]);
48
-
49
- const isActionSelected = (actionId) => actionId === selectedAction;
50
-
51
- return (
52
- <Accordion
53
- expanded={expanded}
54
- onToggle={handleExpandedAccordion}
55
- variant={orderNumber % 2 ? 'primary' : 'secondary'}
56
- >
57
- <AccordionToggle title={capitalize(label)} />
58
- <AccordionContent>
59
- {controllers?.map((controller) => {
60
- const allActionsSelected = controller.actions.every((action) =>
61
- selectedActions.includes(action.actionId)
62
- );
63
-
64
- const someActionsSelected = controller.actions.some((action) =>
65
- selectedActions.includes(action.actionId)
66
- );
67
-
68
- return (
69
- <Box key={`${label}.${controller?.controller}`}>
70
- <Flex justifyContent="space-between" alignItems="center" padding={4}>
71
- <Box paddingRight={4}>
72
- <Typography variant="sigma" textColor="neutral600">
73
- {controller?.controller}
74
- </Typography>
75
- </Box>
76
- <Border />
77
- <Box paddingLeft={4}>
78
- <Checkbox
79
- value={allActionsSelected}
80
- indeterminate={!allActionsSelected && someActionsSelected}
81
- onValueChange={() => {
82
- onChangeSelectAll({ target: { value: [...controller.actions] } });
83
- }}
84
- disabled={disabled}
85
- >
86
- Select all
87
- </Checkbox>
88
- </Box>
89
- </Flex>
90
- <Grid gap={4} padding={4}>
91
- {controller?.actions &&
92
- controller?.actions.map((action) => {
93
- return (
94
- <GridItem col={6} key={action.actionId}>
95
- <CheckboxWrapper
96
- isActive={isActionSelected(action.actionId)}
97
- padding={2}
98
- hasRadius
99
- >
100
- <Checkbox
101
- value={selectedActions.includes(action.actionId)}
102
- name={action.actionId}
103
- onValueChange={() => {
104
- onChange({ target: { value: action.actionId } });
105
- }}
106
- disabled={disabled}
107
- >
108
- {action.action}
109
- </Checkbox>
110
- <button
111
- type="button"
112
- data-testid="action-cog"
113
- onClick={() =>
114
- setSelectedAction({ target: { value: action.actionId } })
115
- }
116
- style={{ display: 'inline-flex', alignItems: 'center' }}
117
- >
118
- <CogIcon />
119
- </button>
120
- </CheckboxWrapper>
121
- </GridItem>
122
- );
123
- })}
124
- </Grid>
125
- </Box>
126
- );
127
- })}
128
- </AccordionContent>
129
- </Accordion>
130
- );
131
- };
132
-
133
- CollapsableContentType.defaultProps = {
134
- controllers: [],
135
- orderNumber: 0,
136
- disabled: false,
137
- onExpanded: () => null,
138
- indexExpandendCollapsedContent: null,
139
- };
140
-
141
- CollapsableContentType.propTypes = {
142
- controllers: PropTypes.array,
143
- orderNumber: PropTypes.number,
144
- label: PropTypes.string.isRequired,
145
- disabled: PropTypes.bool,
146
- onExpanded: PropTypes.func,
147
- indexExpandendCollapsedContent: PropTypes.number,
148
- };
149
-
150
- export default CollapsableContentType;
@@ -1,37 +0,0 @@
1
- import React, { useState } from 'react';
2
- import PropTypes from 'prop-types';
3
- import { Box } from '@strapi/design-system/Box';
4
- import CollapsableContentType from '../CollapsableContentType';
5
-
6
- const ContentTypesSection = ({ section, ...props }) => {
7
- const [indexExpandedCollpsedContent, setIndexExpandedCollpsedContent] = useState(null);
8
- const handleExpandedCollpsedContentIndex = (index) => setIndexExpandedCollpsedContent(index);
9
-
10
- return (
11
- <Box padding={4} background="neutral0">
12
- {section &&
13
- section.map((api, index) => (
14
- <CollapsableContentType
15
- key={api.apiId}
16
- label={api.label}
17
- controllers={api.controllers}
18
- orderNumber={index}
19
- indexExpandendCollapsedContent={indexExpandedCollpsedContent}
20
- onExpanded={handleExpandedCollpsedContentIndex}
21
- name={api.apiId}
22
- {...props}
23
- />
24
- ))}
25
- </Box>
26
- );
27
- };
28
-
29
- ContentTypesSection.defaultProps = {
30
- section: null,
31
- };
32
-
33
- ContentTypesSection.propTypes = {
34
- section: PropTypes.arrayOf(PropTypes.object),
35
- };
36
-
37
- export default ContentTypesSection;
@@ -1,40 +0,0 @@
1
- import React, { memo } from 'react';
2
- import { useIntl } from 'react-intl';
3
- import { Typography } from '@strapi/design-system/Typography';
4
- import { Stack } from '@strapi/design-system/Stack';
5
- import { Grid, GridItem } from '@strapi/design-system/Grid';
6
- import ContentTypesSection from '../ContenTypesSection';
7
- import ActionBoundRoutes from '../ActionBoundRoutes';
8
- import { useApiTokenPermissionsContext } from '../../../../../../../contexts/ApiTokenPermissions';
9
-
10
- const Permissions = ({ ...props }) => {
11
- const {
12
- value: { data },
13
- } = useApiTokenPermissionsContext();
14
- const { formatMessage } = useIntl();
15
-
16
- return (
17
- <Grid gap={0} shadow="filterShadow" hasRadius background="neutral0">
18
- <GridItem col={7} paddingTop={6} paddingBottom={6} paddingLeft={7} paddingRight={7}>
19
- <Stack spacing={2}>
20
- <Typography variant="delta" as="h2">
21
- {formatMessage({
22
- id: 'Settings.apiTokens.createPage.permissions.title',
23
- defaultMessage: 'Permissions',
24
- })}
25
- </Typography>
26
- <Typography as="p" textColor="neutral600">
27
- {formatMessage({
28
- id: 'Settings.apiTokens.createPage.permissions.description',
29
- defaultMessage: 'Only actions bound by a route are listed below.',
30
- })}
31
- </Typography>
32
- </Stack>
33
- {data?.permissions && <ContentTypesSection section={data?.permissions} {...props} />}
34
- </GridItem>
35
- <ActionBoundRoutes />
36
- </Grid>
37
- );
38
- };
39
-
40
- export default memo(Permissions);
@@ -1,68 +0,0 @@
1
- import React, { useState } from 'react';
2
- import PropTypes from 'prop-types';
3
- import { useIntl } from 'react-intl';
4
- import { Button } from '@strapi/design-system/Button';
5
- import Refresh from '@strapi/icons/Refresh';
6
- import { ConfirmDialog } from '@strapi/helper-plugin';
7
- import { useRegenerate } from '../../../../../../../hooks';
8
-
9
- export const Regenerate = ({ onRegenerate, idToRegenerate }) => {
10
- const { formatMessage } = useIntl();
11
- const [showConfirmDialog, setShowConfirmDialog] = useState(false);
12
- const { regenerateData, isLoadingConfirmation } = useRegenerate(idToRegenerate, onRegenerate);
13
- const handleConfirmRegeneration = async () => {
14
- regenerateData();
15
- setShowConfirmDialog(false);
16
- };
17
-
18
- return (
19
- <>
20
- <Button
21
- startIcon={<Refresh />}
22
- type="button"
23
- size="S"
24
- variant="tertiary"
25
- onClick={() => setShowConfirmDialog(true)}
26
- name="regenerate"
27
- >
28
- {formatMessage({
29
- id: 'Settings.apiTokens.regenerate',
30
- defaultMessage: 'Regenerate',
31
- })}
32
- </Button>
33
-
34
- <ConfirmDialog
35
- bodyText={{
36
- id: 'Settings.apiTokens.popUpWarning.message',
37
- defaultMessage: 'Are you sure you want to regenerate this token?',
38
- }}
39
- iconRightButton={<Refresh />}
40
- isConfirmButtonLoading={isLoadingConfirmation}
41
- isOpen={showConfirmDialog}
42
- onToggleDialog={() => setShowConfirmDialog(false)}
43
- onConfirm={handleConfirmRegeneration}
44
- leftButtonText={{
45
- id: 'Settings.apiTokens.Button.cancel',
46
- defaultMessage: 'Cancel',
47
- }}
48
- rightButtonText={{
49
- id: 'Settings.apiTokens.Button.regenerate',
50
- defaultMessage: 'Regenerate',
51
- }}
52
- title={{
53
- id: 'Settings.apiTokens.RegenerateDialog.title',
54
- defaultMessage: 'Regenerate token',
55
- }}
56
- />
57
- </>
58
- );
59
- };
60
-
61
- Regenerate.defaultProps = { onRegenerate() {} };
62
-
63
- Regenerate.propTypes = {
64
- onRegenerate: PropTypes.func,
65
- idToRegenerate: PropTypes.string.isRequired,
66
- };
67
-
68
- export default Regenerate;
@@ -1,13 +0,0 @@
1
- import { transformPermissionsData } from './utils';
2
-
3
- const init = (state, permissions = []) => {
4
- return {
5
- ...state,
6
- selectedAction: null,
7
- routes: [],
8
- selectedActions: [],
9
- data: transformPermissionsData(permissions),
10
- };
11
- };
12
-
13
- export default init;
@@ -1,55 +0,0 @@
1
- /* eslint-disable consistent-return */
2
- import produce from 'immer';
3
- import { pull } from 'lodash';
4
- import { transformPermissionsData } from './utils';
5
-
6
- export const initialState = {
7
- data: {},
8
- selectedActions: [],
9
- };
10
-
11
- const reducer = (state, action) =>
12
- produce(state, (draftState) => {
13
- switch (action.type) {
14
- case 'ON_CHANGE': {
15
- if (draftState.selectedActions.includes(action.value)) {
16
- pull(draftState.selectedActions, action.value);
17
- } else {
18
- draftState.selectedActions.push(action.value);
19
- }
20
- break;
21
- }
22
- case 'SELECT_ALL_ACTIONS': {
23
- draftState.selectedActions = [...draftState.data.allActionsIds];
24
-
25
- break;
26
- }
27
- case 'ON_CHANGE_READ_ONLY': {
28
- const onlyReadOnlyActions = draftState.data.allActionsIds.filter(
29
- (actionId) => actionId.includes('find') || actionId.includes('findOne')
30
- );
31
- draftState.selectedActions = [...onlyReadOnlyActions];
32
- break;
33
- }
34
- case 'UPDATE_PERMISSIONS_LAYOUT': {
35
- draftState.data = transformPermissionsData(action.value);
36
- break;
37
- }
38
- case 'UPDATE_ROUTES': {
39
- draftState.routes = { ...action.value };
40
- break;
41
- }
42
- case 'UPDATE_PERMISSIONS': {
43
- draftState.selectedActions = [...action.value];
44
- break;
45
- }
46
- case 'SET_SELECTED_ACTION': {
47
- draftState.selectedAction = action.value;
48
- break;
49
- }
50
- default:
51
- return draftState;
52
- }
53
- });
54
-
55
- export default reducer;
@@ -1,16 +0,0 @@
1
- import { addDays, format } from 'date-fns';
2
- import * as locales from 'date-fns/locale';
3
-
4
- const getDateOfExpiration = (createdAt, duration, language = 'en') => {
5
- if (duration && typeof duration === 'number') {
6
- const durationInDays = duration / 24 / 60 / 60 / 1000;
7
-
8
- return format(addDays(new Date(createdAt), durationInDays), 'PPP', {
9
- locale: locales[language],
10
- });
11
- }
12
-
13
- return 'Unlimited';
14
- };
15
-
16
- export default getDateOfExpiration;
@@ -1,5 +0,0 @@
1
- import getDateOfExpiration from './getDateOfExpiration';
2
- import schema from './schema';
3
- import transformPermissionsData from './transformPermissionsData';
4
-
5
- export { getDateOfExpiration, schema, transformPermissionsData };
@@ -1,36 +0,0 @@
1
- import { flatten } from 'lodash';
2
-
3
- const transformPermissionsData = (data) => {
4
- const layout = {
5
- allActionsIds: [],
6
- permissions: [],
7
- };
8
-
9
- layout.permissions = Object.keys(data).map((apiId) => ({
10
- apiId,
11
- label: apiId.split('::')[1],
12
- controllers: flatten(
13
- Object.keys(data[apiId].controllers).map((controller) => ({
14
- controller,
15
- actions: flatten(
16
- data[apiId].controllers[controller].map((action) => {
17
- const actionId = `${apiId}.${controller}.${action}`;
18
-
19
- if (apiId.includes('api::')) {
20
- layout.allActionsIds.push(actionId);
21
- }
22
-
23
- return {
24
- action,
25
- actionId,
26
- };
27
- })
28
- ),
29
- }))
30
- ),
31
- }));
32
-
33
- return layout;
34
- };
35
-
36
- export default transformPermissionsData;
@@ -1,63 +0,0 @@
1
- import React from 'react';
2
- import { useIntl } from 'react-intl';
3
- import PropTypes from 'prop-types';
4
- import { Link } from '@strapi/helper-plugin';
5
- import { useHistory } from 'react-router-dom';
6
- import styled from 'styled-components';
7
-
8
- const MESSAGES_MAP = {
9
- edit: {
10
- id: 'app.component.table.edit',
11
- defaultMessage: 'Edit {target}',
12
- },
13
- read: {
14
- id: 'app.component.table.read',
15
- defaultMessage: 'Read {target}',
16
- },
17
- };
18
-
19
- const LinkStyled = styled(Link)`
20
- svg {
21
- path {
22
- fill: ${({ theme }) => theme.colors.neutral500};
23
- }
24
- }
25
-
26
- &:hover,
27
- &:focus {
28
- svg {
29
- path {
30
- fill: ${({ theme }) => theme.colors.neutral800};
31
- }
32
- }
33
- }
34
- `;
35
-
36
- const DefaultButton = ({ tokenName, tokenId, buttonType, children }) => {
37
- const { formatMessage } = useIntl();
38
- const {
39
- location: { pathname },
40
- } = useHistory();
41
-
42
- return (
43
- <LinkStyled
44
- to={`${pathname}/${tokenId}`}
45
- title={formatMessage(MESSAGES_MAP[buttonType], { target: tokenName })}
46
- >
47
- {children}
48
- </LinkStyled>
49
- );
50
- };
51
-
52
- DefaultButton.propTypes = {
53
- tokenName: PropTypes.string.isRequired,
54
- tokenId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
55
- buttonType: PropTypes.string,
56
- children: PropTypes.node.isRequired,
57
- };
58
-
59
- DefaultButton.defaultProps = {
60
- buttonType: 'edit',
61
- };
62
-
63
- export default DefaultButton;
@@ -1,19 +0,0 @@
1
- import React from 'react';
2
- import Eye from '@strapi/icons/Eye';
3
- import PropTypes from 'prop-types';
4
- import DefaultButton from '../DefaultButton';
5
-
6
- const ReadButton = ({ tokenName, tokenId }) => {
7
- return (
8
- <DefaultButton tokenName={tokenName} tokenId={tokenId} buttonType="read">
9
- <Eye />
10
- </DefaultButton>
11
- );
12
- };
13
-
14
- ReadButton.propTypes = {
15
- tokenName: PropTypes.string.isRequired,
16
- tokenId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
17
- };
18
-
19
- export default ReadButton;