From 3e301e9c1e35b2d45fcdb0063542fc4047fdd4db Mon Sep 17 00:00:00 2001 From: Bassel Kanso Date: Wed, 31 Aug 2022 01:57:31 +0300 Subject: [PATCH] - Changes permissions layout - Update tests --- .../components/ActionBoundRoutes/index.js | 53 + .../components/BoundRoute/getMethodColor.js | 41 + .../EditView/components/BoundRoute/index.js | 72 + .../CollapsableContentType/CheckBoxWrapper.js | 30 + .../CollapsableContentType/index.js | 42 +- .../EditView/components/Permissions/index.js | 40 +- .../pages/ApiTokens/EditView/index.js | 11 +- .../pages/ApiTokens/EditView/init.js | 2 + .../pages/ApiTokens/EditView/reducer.js | 4 + .../tests/__snapshots__/index.test.js.snap | 1244 ++++++++--------- .../ApiTokens/EditView/tests/index.test.js | 35 +- .../ApiTokens/EditView/tests/reducer.test.js | 9 + 12 files changed, 870 insertions(+), 713 deletions(-) create mode 100644 packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/ActionBoundRoutes/index.js create mode 100644 packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/BoundRoute/getMethodColor.js create mode 100644 packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/BoundRoute/index.js create mode 100644 packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/CollapsableContentType/CheckBoxWrapper.js diff --git a/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/ActionBoundRoutes/index.js b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/ActionBoundRoutes/index.js new file mode 100644 index 0000000000..25feb0661a --- /dev/null +++ b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/ActionBoundRoutes/index.js @@ -0,0 +1,53 @@ +import React from 'react'; +import { useIntl } from 'react-intl'; +import { Typography } from '@strapi/design-system/Typography'; +import { Stack } from '@strapi/design-system/Stack'; +import { GridItem } from '@strapi/design-system/Grid'; +import BoundRoute from '../BoundRoute'; +import { useApiTokenPermissionsContext } from '../../../../../../../contexts/ApiTokenPermissions'; + +const ActionBoundRoutes = () => { + const { + value: { selectedAction, routes }, + } = useApiTokenPermissionsContext(); + const { formatMessage } = useIntl(); + + return ( + + {selectedAction ? ( + + {routes.map((route, key) => ( + // eslint-disable-next-line react/no-array-index-key + + ))} + + ) : ( + + + {formatMessage({ + id: 'Settings.apiTokens.createPage.permissions.header.title', + defaultMessage: 'Advanced settings', + })} + + + {formatMessage({ + id: 'Settings.apiTokens.createPage.permissions.header.hint', + defaultMessage: + "Select the application's actions or the plugin's actions and click on the cog icon to display the bound route", + })} + + + )} + + ); +}; + +export default ActionBoundRoutes; diff --git a/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/BoundRoute/getMethodColor.js b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/BoundRoute/getMethodColor.js new file mode 100644 index 0000000000..1ad903b389 --- /dev/null +++ b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/BoundRoute/getMethodColor.js @@ -0,0 +1,41 @@ +const getMethodColor = (verb) => { + switch (verb) { + case 'POST': { + return { + text: 'success600', + border: 'success200', + background: 'success100', + }; + } + case 'GET': { + return { + text: 'secondary600', + border: 'secondary200', + background: 'secondary100', + }; + } + case 'PUT': { + return { + text: 'warning600', + border: 'warning200', + background: 'warning100', + }; + } + case 'DELETE': { + return { + text: 'danger600', + border: 'danger200', + background: 'danger100', + }; + } + default: { + return { + text: 'neutral600', + border: 'neutral200', + background: 'neutral100', + }; + } + } +}; + +export default getMethodColor; diff --git a/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/BoundRoute/index.js b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/BoundRoute/index.js new file mode 100644 index 0000000000..efc052fc7b --- /dev/null +++ b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/BoundRoute/index.js @@ -0,0 +1,72 @@ +import React from 'react'; +import styled from 'styled-components'; +import { Stack } from '@strapi/design-system/Stack'; +import { Box } from '@strapi/design-system/Box'; +import { Typography } from '@strapi/design-system/Typography'; +import map from 'lodash/map'; +import tail from 'lodash/tail'; +import { useIntl } from 'react-intl'; +import PropTypes from 'prop-types'; +import getMethodColor from './getMethodColor'; + +const MethodBox = styled(Box)` + margin: -1px; + border-radius: ${({ theme }) => theme.spaces[1]} 0 0 ${({ theme }) => theme.spaces[1]}; +`; + +function BoundRoute({ route }) { + const { formatMessage } = useIntl(); + + const { method, handler: title, path } = route; + const formattedRoute = path ? tail(path.split('/')) : []; + const [controller = '', action = ''] = title ? title.split('.') : []; + const colors = getMethodColor(route.method); + + return ( + + + {formatMessage({ + id: 'Settings.apiTokens.createPage.BoundRoute.title', + defaultMessage: 'Bound route to', + })} +   + {controller} + + .{action} + + + + + + {method} + + + + {map(formattedRoute, (value) => ( + + /{value} + + ))} + + + + ); +} + +BoundRoute.defaultProps = { + route: { + handler: 'Nocontroller.error', + method: 'GET', + path: '/there-is-no-path', + }, +}; + +BoundRoute.propTypes = { + route: PropTypes.shape({ + handler: PropTypes.string, + method: PropTypes.string, + path: PropTypes.string, + }), +}; + +export default BoundRoute; diff --git a/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/CollapsableContentType/CheckBoxWrapper.js b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/CollapsableContentType/CheckBoxWrapper.js new file mode 100644 index 0000000000..9d80ecc39a --- /dev/null +++ b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/CollapsableContentType/CheckBoxWrapper.js @@ -0,0 +1,30 @@ +import styled, { css } from 'styled-components'; +import { Box } from '@strapi/design-system/Box'; + +const activeCheckboxWrapperStyles = css` + background: ${(props) => props.theme.colors.primary100}; + svg { + opacity: 1; + } +`; + +const CheckboxWrapper = styled(Box)` + display: flex; + justify-content: space-between; + align-items: center; + + svg { + opacity: 0; + path { + fill: ${(props) => props.theme.colors.primary600}; + } + } + + /* Show active style both on hover and when the action is selected */ + ${(props) => props.isActive && activeCheckboxWrapperStyles} + &:hover { + ${activeCheckboxWrapperStyles} + } +`; + +export default CheckboxWrapper; diff --git a/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/CollapsableContentType/index.js b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/CollapsableContentType/index.js index 0d5f6a4bf9..ea7c580927 100644 --- a/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/CollapsableContentType/index.js +++ b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/CollapsableContentType/index.js @@ -6,9 +6,11 @@ import { Grid, GridItem } from '@strapi/design-system/Grid'; import { Typography } from '@strapi/design-system/Typography'; import { Box } from '@strapi/design-system/Box'; import { Flex } from '@strapi/design-system/Flex'; +import CogIcon from '@strapi/icons/Cog'; import styled from 'styled-components'; import PropTypes from 'prop-types'; import { useApiTokenPermissionsContext } from '../../../../../../../contexts/ApiTokenPermissions'; +import CheckboxWrapper from './CheckBoxWrapper'; const Border = styled.div` flex: 1; @@ -25,7 +27,7 @@ const CollapsableContentType = ({ indexExpandendCollapsedContent, }) => { const { - value: { onChangeSelectAll, onChange, selectedActions }, + value: { onChangeSelectAll, onChange, selectedActions, setSelectedAction, selectedAction }, } = useApiTokenPermissionsContext(); const [expanded, setExpanded] = useState(false); @@ -44,6 +46,8 @@ const CollapsableContentType = ({ } }, [indexExpandendCollapsedContent, orderNumber, expanded]); + const isActionSelected = (actionId) => actionId === selectedAction; + return ( { return ( - - { - onChange({ target: { value: action.actionId } }); - }} - disabled={disabled} + + - {action.action} - + { + onChange({ target: { value: action.actionId } }); + }} + disabled={disabled} + > + {action.action} + + + ); })} diff --git a/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/Permissions/index.js b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/Permissions/index.js index 1fcfafc645..f81db58bbf 100644 --- a/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/Permissions/index.js +++ b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/Permissions/index.js @@ -1,9 +1,10 @@ import React, { memo } from 'react'; import { useIntl } from 'react-intl'; -import { Box } from '@strapi/design-system/Box'; import { Typography } from '@strapi/design-system/Typography'; import { Stack } from '@strapi/design-system/Stack'; +import { Grid, GridItem } from '@strapi/design-system/Grid'; import ContentTypesSection from '../ContenTypesSection'; +import ActionBoundRoutes from '../ActionBoundRoutes'; import { useApiTokenPermissionsContext } from '../../../../../../../contexts/ApiTokenPermissions'; const Permissions = ({ ...props }) => { @@ -13,23 +14,26 @@ const Permissions = ({ ...props }) => { const { formatMessage } = useIntl(); return ( - - - - {formatMessage({ - id: 'Settings.apiTokens.createPage.permissions.title', - defaultMessage: 'Permissions', - })} - - - {formatMessage({ - id: 'Settings.apiTokens.createPage.permissions.description', - defaultMessage: 'Only actions bound by a route are listed below.', - })} - - - {data.permissions && } - + + + + + {formatMessage({ + id: 'Settings.apiTokens.createPage.permissions.title', + defaultMessage: 'Permissions', + })} + + + {formatMessage({ + id: 'Settings.apiTokens.createPage.permissions.description', + defaultMessage: 'Only actions bound by a route are listed below.', + })} + + + {data?.permissions && } + + + ); }; diff --git a/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/index.js b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/index.js index 29ffbe4f80..17ba1761c1 100644 --- a/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/index.js +++ b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/index.js @@ -100,7 +100,7 @@ const ApiTokenCreateView = () => { dispatch({ type: 'UPDATE_PERMISSIONS', - value: data.permissions, + value: data?.permissions, }); return data; @@ -247,10 +247,18 @@ const ApiTokenCreateView = () => { } }; + const setSelectedAction = ({ target: { value } }) => { + dispatch({ + type: 'SET_SELECTED_ACTION', + value, + }); + }; + const providerValue = { ...state, onChange: handleChangeCheckbox, onChangeSelectAll: handleChangeSelectAllCheckbox, + setSelectedAction, }; const canEditInputs = (canUpdate && !isCreating) || (canCreate && isCreating); @@ -272,7 +280,6 @@ const ApiTokenCreateView = () => { description: apiToken?.description || '', type: apiToken?.type, lifespan: apiToken?.lifespan, - permissions: apiToken?.permissions, }} onSubmit={handleSubmit} > diff --git a/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/init.js b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/init.js index a337dfc513..a9ba8b9377 100644 --- a/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/init.js +++ b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/init.js @@ -3,6 +3,8 @@ import { transformPermissionsData } from './utils'; const init = (state, permissions = []) => { return { ...state, + selectedAction: null, + routes: [], selectedActions: [], data: transformPermissionsData(permissions), }; diff --git a/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/reducer.js b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/reducer.js index 14a181484f..05d2493a11 100644 --- a/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/reducer.js +++ b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/reducer.js @@ -39,6 +39,10 @@ const reducer = (state, action) => draftState.selectedActions = [...action.value]; break; } + case 'SET_SELECTED_ACTION': { + draftState.selectedAction = action.value; + break; + } default: return draftState; } diff --git a/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/tests/__snapshots__/index.test.js.snap b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/tests/__snapshots__/index.test.js.snap index f1c712b7f3..c69fb8e4ad 100644 --- a/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/tests/__snapshots__/index.test.js.snap +++ b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/tests/__snapshots__/index.test.js.snap @@ -11,11 +11,7 @@ exports[`ADMIN | Pages | API TOKENS | EditView renders and matches the snapshot box-shadow: 0px 1px 4px rgba(33,33,52,0.1); } -.c57 { - box-shadow: 0px 1px 4px rgba(33,33,52,0.1); -} - -.c69 { +.c63 { background: #ffffff; padding: 16px; } @@ -357,6 +353,15 @@ exports[`ADMIN | Pages | API TOKENS | EditView renders and matches the snapshot margin-top: 16px; } +.c61 > * { + margin-top: 0; + margin-bottom: 0; +} + +.c61 > * + * { + margin-top: 8px; +} + .c25 { -webkit-align-items: stretch; -webkit-box-align: stretch; @@ -640,6 +645,12 @@ exports[`ADMIN | Pages | API TOKENS | EditView renders and matches the snapshot line-height: 1.33; } +.c62 { + color: #666687; + font-size: 0.875rem; + line-height: 1.43; +} + .c6 { color: #4945ff; font-size: 0.75rem; @@ -710,7 +721,7 @@ exports[`ADMIN | Pages | API TOKENS | EditView renders and matches the snapshot display: flex; } -.c91 { +.c87 { border: 0; -webkit-clip: rect(0 0 0 0); clip: rect(0 0 0 0); @@ -782,109 +793,61 @@ exports[`ADMIN | Pages | API TOKENS | EditView renders and matches the snapshot outline: none; } +.c57 { + background: #ffffff; + border-radius: 4px; + box-shadow: 0px 1px 4px rgba(33,33,52,0.1); +} + +.c60 { + padding-top: 24px; + padding-right: 32px; + padding-bottom: 24px; + padding-left: 32px; +} + +.c86 { + background: #eaeaef; + padding-top: 24px; + padding-right: 32px; + padding-bottom: 24px; + padding-left: 32px; +} + .c23 { display: grid; grid-template-columns: repeat(12,1fr); gap: 20px; } +.c58 { + display: grid; + grid-template-columns: repeat(12,1fr); + gap: 0px; +} + .c24 { grid-column: span 6; max-width: 100%; } -.c65 { - font-weight: 600; - color: #271fe0; - font-size: 0.875rem; - line-height: 1.43; +.c59 { + grid-column: span 7; + max-width: 100%; } -.c68 { - font-weight: 600; - color: #666687; - font-size: 0.875rem; - line-height: 1.43; +.c85 { + grid-column: span 5; + max-width: 100%; } -.c63 { - background: #ffffff; - padding: 16px; -} - -.c66 { - background: #f6f6f9; - padding: 12px; -} - -.c58 { - -webkit-align-items: flex-end; - -webkit-box-align: flex-end; - -ms-flex-align: flex-end; - align-items: flex-end; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; -} - -.c64 { - border-bottom: 1px solid #ffffff; -} - -.c67 { - border-bottom: 1px solid #eaeaef; -} - -.c61 { - border: none; - background: transparent; - padding: 0; - outline-offset: -2px; -} - -.c60 + .c60 > .c62 { - border-left: 1px solid #eaeaef; -} - -.c61 .c62 { - border-right: none; -} - -.c61[aria-disabled='true'] { - cursor: not-allowed; -} - -.c59 > * { - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; -} - -.c59 .c60:first-of-type .c62 { - border-radius: 4px 0 0 0; -} - -.c59 .c60:last-of-type .c62 { - border-radius: 0 4px 0 0; -} - -.c59 .c60[aria-selected="true"] .c62 { - border-radius: 4px 4px 0 0; - border-left: none; - border-right: none; -} - -.c83 { +.c77 { color: #4945ff; font-size: 0.75rem; line-height: 1.33; } -.c84 { +.c78 { color: #4a4a6a; display: block; white-space: nowrap; @@ -895,11 +858,11 @@ exports[`ADMIN | Pages | API TOKENS | EditView renders and matches the snapshot line-height: 1.25; } -.c70 { +.c64 { border-radius: 4px; } -.c73 { +.c67 { background: #f6f6f9; padding-top: 24px; padding-right: 24px; @@ -907,21 +870,21 @@ exports[`ADMIN | Pages | API TOKENS | EditView renders and matches the snapshot padding-left: 24px; } -.c76 { +.c70 { max-width: 100%; -webkit-flex: 1; -ms-flex: 1; flex: 1; } -.c79 { +.c73 { min-width: 0px; -webkit-flex: 1; -ms-flex: 1; flex: 1; } -.c85 { +.c79 { background: #dcdce4; border-radius: 50%; cursor: pointer; @@ -933,12 +896,12 @@ exports[`ADMIN | Pages | API TOKENS | EditView renders and matches the snapshot cursor: pointer; } -.c87 { +.c81 { color: #666687; width: 0.6875rem; } -.c90 { +.c84 { background: #ffffff; padding-top: 24px; padding-right: 24px; @@ -946,7 +909,7 @@ exports[`ADMIN | Pages | API TOKENS | EditView renders and matches the snapshot padding-left: 24px; } -.c74 { +.c68 { -webkit-align-items: center; -webkit-box-align: center; -ms-flex-align: center; @@ -964,7 +927,7 @@ exports[`ADMIN | Pages | API TOKENS | EditView renders and matches the snapshot justify-content: space-between; } -.c77 { +.c71 { -webkit-align-items: center; -webkit-box-align: center; -ms-flex-align: center; @@ -978,7 +941,7 @@ exports[`ADMIN | Pages | API TOKENS | EditView renders and matches the snapshot flex-direction: row; } -.c86 { +.c80 { -webkit-align-items: center; -webkit-box-align: center; -ms-flex-align: center; @@ -999,70 +962,70 @@ exports[`ADMIN | Pages | API TOKENS | EditView renders and matches the snapshot justify-content: center; } -.c71 { +.c65 { border: 1px solid #f6f6f9; } -.c71:hover:not([aria-disabled='true']) { +.c65:hover:not([aria-disabled='true']) { border: 1px solid #4945ff; } -.c71:hover:not([aria-disabled='true']) .sc-wAsCI { +.c65:hover:not([aria-disabled='true']) .sc-OVzLa { color: #271fe0; } -.c71:hover:not([aria-disabled='true']) .c82 { +.c65:hover:not([aria-disabled='true']) .c76 { color: #4945ff; } -.c71:hover:not([aria-disabled='true']) > .c72 { +.c65:hover:not([aria-disabled='true']) > .c66 { background: #f0f0ff; } -.c71:hover:not([aria-disabled='true']) [data-strapi-dropdown='true'] { +.c65:hover:not([aria-disabled='true']) [data-strapi-dropdown='true'] { background: #d9d8ff; } -.c89 { +.c83 { border: 1px solid #ffffff; } -.c89:hover:not([aria-disabled='true']) { +.c83:hover:not([aria-disabled='true']) { border: 1px solid #4945ff; } -.c89:hover:not([aria-disabled='true']) .sc-wAsCI { +.c83:hover:not([aria-disabled='true']) .sc-OVzLa { color: #271fe0; } -.c89:hover:not([aria-disabled='true']) .c82 { +.c83:hover:not([aria-disabled='true']) .c76 { color: #4945ff; } -.c89:hover:not([aria-disabled='true']) > .c72 { +.c83:hover:not([aria-disabled='true']) > .c66 { background: #f0f0ff; } -.c89:hover:not([aria-disabled='true']) [data-strapi-dropdown='true'] { +.c83:hover:not([aria-disabled='true']) [data-strapi-dropdown='true'] { background: #d9d8ff; } -.c80 { +.c74 { background: transparent; border: none; position: relative; outline: none; } -.c80[aria-disabled='true'] { +.c74[aria-disabled='true'] { pointer-events: none; } -.c80[aria-disabled='true'] svg path { +.c74[aria-disabled='true'] svg path { fill: #666687; } -.c80 svg { +.c74 svg { display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; @@ -1070,11 +1033,11 @@ exports[`ADMIN | Pages | API TOKENS | EditView renders and matches the snapshot font-size: 0.625rem; } -.c80 svg path { +.c74 svg path { fill: #4945ff; } -.c80:after { +.c74:after { -webkit-transition-property: all; transition-property: all; -webkit-transition-duration: 0.2s; @@ -1089,11 +1052,11 @@ exports[`ADMIN | Pages | API TOKENS | EditView renders and matches the snapshot border: 2px solid transparent; } -.c80:focus-visible { +.c74:focus-visible { outline: none; } -.c80:focus-visible:after { +.c74:focus-visible:after { border-radius: 8px; content: ''; position: absolute; @@ -1104,42 +1067,42 @@ exports[`ADMIN | Pages | API TOKENS | EditView renders and matches the snapshot border: 2px solid #4945ff; } -.c78 > * { +.c72 > * { margin-left: 0; margin-right: 0; } -.c78 > * + * { +.c72 > * + * { margin-left: 12px; } -.c88 path { +.c82 path { fill: #666687; } -.c81 { +.c75 { text-align: left; } -.c81 > span { +.c75 > span { max-width: 100%; } -.c81 svg { +.c75 svg { width: 0.875rem; height: 0.875rem; } -.c81 svg path { +.c75 svg path { fill: #8e8ea9; } -.c75 { +.c69 { min-height: 5.5rem; border-radius: 4px; } -.c75:hover svg path { +.c69:hover svg path { fill: #4945ff; } @@ -1155,6 +1118,30 @@ exports[`ADMIN | Pages | API TOKENS | EditView renders and matches the snapshot } } +@media (max-width:68.75rem) { + .c59 { + grid-column: span; + } +} + +@media (max-width:34.375rem) { + .c59 { + grid-column: span; + } +} + +@media (max-width:68.75rem) { + .c85 { + grid-column: span; + } +} + +@media (max-width:34.375rem) { + .c85 { + grid-column: span; + } +} +
-
+
-
+
- - - -
-
+

+ Permissions +

+

+ Only actions bound by a route are listed below. +

+
+
+
- -
- -
-
-
-
-
-
-
- -
- -
+ + +
+
+
+
+ +
+ +
+
+
+
+
+
+
+
+
+
+

+ Advanced settings +

+

+ Select the application's actions or the plugin's actions and click on the cog icon to display the bound route +

@@ -1760,7 +1719,7 @@ exports[`ADMIN | Pages | API TOKENS | EditView renders and matches the snapshot

* { + margin-top: 0; + margin-bottom: 0; +} + +.c71 > * + * { + margin-top: 8px; +} + .c33 { -webkit-align-items: stretch; -webkit-box-align: stretch; @@ -2626,7 +2580,7 @@ exports[`ADMIN | Pages | API TOKENS | EditView renders and matches the snapshot word-break: break-all; } -.c102 { +.c96 { border: 0; -webkit-clip: rect(0 0 0 0); clip: rect(0 0 0 0); @@ -2698,109 +2652,61 @@ exports[`ADMIN | Pages | API TOKENS | EditView renders and matches the snapshot outline: none; } +.c67 { + background: #ffffff; + border-radius: 4px; + box-shadow: 0px 1px 4px rgba(33,33,52,0.1); +} + +.c70 { + padding-top: 24px; + padding-right: 32px; + padding-bottom: 24px; + padding-left: 32px; +} + +.c95 { + background: #eaeaef; + padding-top: 24px; + padding-right: 32px; + padding-bottom: 24px; + padding-left: 32px; +} + .c31 { display: grid; grid-template-columns: repeat(12,1fr); gap: 20px; } +.c68 { + display: grid; + grid-template-columns: repeat(12,1fr); + gap: 0px; +} + .c32 { grid-column: span 6; max-width: 100%; } -.c76 { - font-weight: 600; - color: #271fe0; - font-size: 0.875rem; - line-height: 1.43; -} - -.c79 { - font-weight: 600; - color: #666687; - font-size: 0.875rem; - line-height: 1.43; -} - -.c74 { - background: #ffffff; - padding: 16px; -} - -.c77 { - background: #f6f6f9; - padding: 12px; -} - .c69 { - -webkit-align-items: flex-end; - -webkit-box-align: flex-end; - -ms-flex-align: flex-end; - align-items: flex-end; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; -} - -.c75 { - border-bottom: 1px solid #ffffff; -} - -.c78 { - border-bottom: 1px solid #eaeaef; -} - -.c72 { - border: none; - background: transparent; - padding: 0; - outline-offset: -2px; -} - -.c71 + .c71 > .c73 { - border-left: 1px solid #eaeaef; -} - -.c72 .c73 { - border-right: none; -} - -.c72[aria-disabled='true'] { - cursor: not-allowed; -} - -.c70 > * { - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; -} - -.c70 .c71:first-of-type .c73 { - border-radius: 4px 0 0 0; -} - -.c70 .c71:last-of-type .c73 { - border-radius: 0 4px 0 0; -} - -.c70 .c71[aria-selected="true"] .c73 { - border-radius: 4px 4px 0 0; - border-left: none; - border-right: none; + grid-column: span 7; + max-width: 100%; } .c94 { + grid-column: span 5; + max-width: 100%; +} + +.c86 { color: #4945ff; font-size: 0.75rem; line-height: 1.33; } -.c95 { +.c87 { color: #4a4a6a; display: block; white-space: nowrap; @@ -2811,11 +2717,11 @@ exports[`ADMIN | Pages | API TOKENS | EditView renders and matches the snapshot line-height: 1.25; } -.c81 { +.c73 { border-radius: 4px; } -.c84 { +.c76 { background: #f6f6f9; padding-top: 24px; padding-right: 24px; @@ -2823,21 +2729,21 @@ exports[`ADMIN | Pages | API TOKENS | EditView renders and matches the snapshot padding-left: 24px; } -.c87 { +.c79 { max-width: 100%; -webkit-flex: 1; -ms-flex: 1; flex: 1; } -.c90 { +.c82 { min-width: 0px; -webkit-flex: 1; -ms-flex: 1; flex: 1; } -.c96 { +.c88 { background: #dcdce4; border-radius: 50%; cursor: pointer; @@ -2849,12 +2755,12 @@ exports[`ADMIN | Pages | API TOKENS | EditView renders and matches the snapshot cursor: pointer; } -.c98 { +.c90 { color: #666687; width: 0.6875rem; } -.c101 { +.c93 { background: #ffffff; padding-top: 24px; padding-right: 24px; @@ -2862,7 +2768,7 @@ exports[`ADMIN | Pages | API TOKENS | EditView renders and matches the snapshot padding-left: 24px; } -.c85 { +.c77 { -webkit-align-items: center; -webkit-box-align: center; -ms-flex-align: center; @@ -2880,7 +2786,7 @@ exports[`ADMIN | Pages | API TOKENS | EditView renders and matches the snapshot justify-content: space-between; } -.c88 { +.c80 { -webkit-align-items: center; -webkit-box-align: center; -ms-flex-align: center; @@ -2894,7 +2800,7 @@ exports[`ADMIN | Pages | API TOKENS | EditView renders and matches the snapshot flex-direction: row; } -.c97 { +.c89 { -webkit-align-items: center; -webkit-box-align: center; -ms-flex-align: center; @@ -2915,70 +2821,70 @@ exports[`ADMIN | Pages | API TOKENS | EditView renders and matches the snapshot justify-content: center; } -.c82 { +.c74 { border: 1px solid #f6f6f9; } -.c82:hover:not([aria-disabled='true']) { +.c74:hover:not([aria-disabled='true']) { border: 1px solid #4945ff; } -.c82:hover:not([aria-disabled='true']) .sc-wAsCI { +.c74:hover:not([aria-disabled='true']) .sc-OVzLa { color: #271fe0; } -.c82:hover:not([aria-disabled='true']) .c93 { +.c74:hover:not([aria-disabled='true']) .c85 { color: #4945ff; } -.c82:hover:not([aria-disabled='true']) > .c83 { +.c74:hover:not([aria-disabled='true']) > .c75 { background: #f0f0ff; } -.c82:hover:not([aria-disabled='true']) [data-strapi-dropdown='true'] { +.c74:hover:not([aria-disabled='true']) [data-strapi-dropdown='true'] { background: #d9d8ff; } -.c100 { +.c92 { border: 1px solid #ffffff; } -.c100:hover:not([aria-disabled='true']) { +.c92:hover:not([aria-disabled='true']) { border: 1px solid #4945ff; } -.c100:hover:not([aria-disabled='true']) .sc-wAsCI { +.c92:hover:not([aria-disabled='true']) .sc-OVzLa { color: #271fe0; } -.c100:hover:not([aria-disabled='true']) .c93 { +.c92:hover:not([aria-disabled='true']) .c85 { color: #4945ff; } -.c100:hover:not([aria-disabled='true']) > .c83 { +.c92:hover:not([aria-disabled='true']) > .c75 { background: #f0f0ff; } -.c100:hover:not([aria-disabled='true']) [data-strapi-dropdown='true'] { +.c92:hover:not([aria-disabled='true']) [data-strapi-dropdown='true'] { background: #d9d8ff; } -.c91 { +.c83 { background: transparent; border: none; position: relative; outline: none; } -.c91[aria-disabled='true'] { +.c83[aria-disabled='true'] { pointer-events: none; } -.c91[aria-disabled='true'] svg path { +.c83[aria-disabled='true'] svg path { fill: #666687; } -.c91 svg { +.c83 svg { display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; @@ -2986,11 +2892,11 @@ exports[`ADMIN | Pages | API TOKENS | EditView renders and matches the snapshot font-size: 0.625rem; } -.c91 svg path { +.c83 svg path { fill: #4945ff; } -.c91:after { +.c83:after { -webkit-transition-property: all; transition-property: all; -webkit-transition-duration: 0.2s; @@ -3005,11 +2911,11 @@ exports[`ADMIN | Pages | API TOKENS | EditView renders and matches the snapshot border: 2px solid transparent; } -.c91:focus-visible { +.c83:focus-visible { outline: none; } -.c91:focus-visible:after { +.c83:focus-visible:after { border-radius: 8px; content: ''; position: absolute; @@ -3020,42 +2926,42 @@ exports[`ADMIN | Pages | API TOKENS | EditView renders and matches the snapshot border: 2px solid #4945ff; } -.c89 > * { +.c81 > * { margin-left: 0; margin-right: 0; } -.c89 > * + * { +.c81 > * + * { margin-left: 12px; } -.c99 path { +.c91 path { fill: #666687; } -.c92 { +.c84 { text-align: left; } -.c92 > span { +.c84 > span { max-width: 100%; } -.c92 svg { +.c84 svg { width: 0.875rem; height: 0.875rem; } -.c92 svg path { +.c84 svg path { fill: #8e8ea9; } -.c86 { +.c78 { min-height: 5.5rem; border-radius: 4px; } -.c86:hover svg path { +.c78:hover svg path { fill: #4945ff; } @@ -3071,6 +2977,30 @@ exports[`ADMIN | Pages | API TOKENS | EditView renders and matches the snapshot } } +@media (max-width:68.75rem) { + .c69 { + grid-column: span; + } +} + +@media (max-width:34.375rem) { + .c69 { + grid-column: span; + } +} + +@media (max-width:68.75rem) { + .c94 { + grid-column: span; + } +} + +@media (max-width:34.375rem) { + .c94 { + grid-column: span; + } +} +

({ ...jest.requireActual('@strapi/helper-plugin'), @@ -27,18 +28,27 @@ jest.mock('@strapi/helper-plugin', () => ({ })), })); -jest.spyOn(axiosInstance, 'get').mockResolvedValue({ - data: { +jest.spyOn(axiosInstance, 'get').mockImplementation((path) => { + if (path === '/admin/content-api/permissions') { + return { data }; + } + + return { data: { - id: 1, - name: 'My super token', - description: 'This describe my super token', - type: 'read-only', - createdAt: '2021-11-15T00:00:00.000Z', + data: { + id: 1, + name: 'My super token', + description: 'This describe my super token', + type: 'read-only', + createdAt: '2021-11-15T00:00:00.000Z', + permissions: [], + }, }, - }, + }; }); +// jest.spyOn(axiosInstance, 'get').mockResolvedValue({ data }); + jest.spyOn(Date, 'now').mockImplementation(() => new Date('2015-10-01T08:00:00.000Z')); const client = new QueryClient({ @@ -72,13 +82,17 @@ describe('ADMIN | Pages | API TOKENS | EditView', () => { jest.resetAllMocks(); }); - it('renders and matches the snapshot when creating token', () => { + it('renders and matches the snapshot when creating token', async () => { const history = createMemoryHistory(); const App = makeApp(history); - const { container } = render(App); + const { container, getByText } = render(App); history.push('/settings/api-tokens/create'); + await waitFor(() => { + expect(getByText('Address')).toBeInTheDocument(); + }); + expect(container).toMatchSnapshot(); }); @@ -92,6 +106,7 @@ describe('ADMIN | Pages | API TOKENS | EditView', () => { await waitFor(() => { expect(getByText('My super token')).toBeInTheDocument(); expect(getByText('This describe my super token')).toBeInTheDocument(); + expect(getByText('Address')).toBeInTheDocument(); }); expect(container).toMatchSnapshot(); diff --git a/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/tests/reducer.test.js b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/tests/reducer.test.js index 0d073d8536..7e9ebfa203 100644 --- a/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/tests/reducer.test.js +++ b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/tests/reducer.test.js @@ -59,4 +59,13 @@ describe('ADMIN | Pages | API TOKENS | EditView | reducer', () => { 'api::category.category.findOne', ]); }); + + it('should add a selectedAction', () => { + const action = { + type: 'SET_SELECTED_ACTION', + value: 'api::address.address.find', + }; + + expect(reducer(initialState, action).selectedAction).toBe('api::address.address.find'); + }); });