From 55e39073296f7e13a840f198495d2f7f108c6274 Mon Sep 17 00:00:00 2001 From: Simone Taeggi Date: Tue, 9 Aug 2022 15:36:11 +0200 Subject: [PATCH 1/8] enable api tokens always without permissions --- .../core/admin/admin/src/permissions/defaultPermissions.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/packages/core/admin/admin/src/permissions/defaultPermissions.js b/packages/core/admin/admin/src/permissions/defaultPermissions.js index a2ff388692..be3e6b9b9d 100644 --- a/packages/core/admin/admin/src/permissions/defaultPermissions.js +++ b/packages/core/admin/admin/src/permissions/defaultPermissions.js @@ -76,12 +76,7 @@ const permissions = { update: [{ action: 'admin::webhooks.update', subject: null }], }, 'api-tokens': { - main: [ - { action: 'admin::api-tokens.create', subject: null }, - { action: 'admin::api-tokens.read', subject: null }, - { action: 'admin::api-tokens.update', subject: null }, - { action: 'admin::api-tokens.delete', subject: null }, - ], + main: [], create: [{ action: 'admin::api-tokens.create', subject: null }], delete: [{ action: 'admin::api-tokens.delete', subject: null }], read: [{ action: 'admin::api-tokens.read', subject: null }], From 1000f6aed313c78c643de8ef8b778e28cca92b7c Mon Sep 17 00:00:00 2001 From: Simone Taeggi Date: Wed, 10 Aug 2022 12:09:00 +0200 Subject: [PATCH 2/8] add the read icon to see the read view with enabled fields --- .../DynamicTable/DefaultButton/index.js | 62 +++++++++++++++++++ .../ListView/DynamicTable/ReadButton/index.js | 19 ++++++ .../DynamicTable/UpdateButton/index.js | 39 +----------- .../ApiTokens/ListView/DynamicTable/index.js | 8 ++- .../pages/ApiTokens/ListView/index.js | 5 +- 5 files changed, 94 insertions(+), 39 deletions(-) create mode 100644 packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/DefaultButton/index.js create mode 100644 packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/ReadButton/index.js diff --git a/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/DefaultButton/index.js b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/DefaultButton/index.js new file mode 100644 index 0000000000..fe0e0ae91e --- /dev/null +++ b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/DefaultButton/index.js @@ -0,0 +1,62 @@ +import React from 'react'; +import { useIntl } from 'react-intl'; +import PropTypes from 'prop-types'; +import { Link } from '@strapi/helper-plugin'; +import { useHistory } from 'react-router-dom'; +import styled from 'styled-components'; + +const MESSAGES_MAP = { + edit: { + id: 'app.component.table.edit', + defaultMessage: 'Edit {target}', + }, + read: { + id: 'app.component.table.read', + defaultMessage: 'Read {target}', + }, +}; + +const LinkStyled = styled(Link)` + svg { + path { + fill: ${({ theme }) => theme.colors.neutral500}; + } + } + + &:hover { + svg { + path { + fill: ${({ theme }) => theme.colors.neutral800}; + } + } + } +`; + +const DefaultButton = ({ tokenName, tokenId, buttonType, children }) => { + const { formatMessage } = useIntl(); + const { + location: { pathname }, + } = useHistory(); + + return ( + + {children} + + ); +}; + +DefaultButton.propTypes = { + tokenName: PropTypes.string.isRequired, + tokenId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired, + buttonType: PropTypes.string, + children: PropTypes.node.isRequired, +}; + +DefaultButton.defaultProps = { + buttonType: 'edit', +}; + +export default DefaultButton; diff --git a/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/ReadButton/index.js b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/ReadButton/index.js new file mode 100644 index 0000000000..2991407fe1 --- /dev/null +++ b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/ReadButton/index.js @@ -0,0 +1,19 @@ +import React from 'react'; +import Eye from '@strapi/icons/Eye'; +import PropTypes from 'prop-types'; +import DefaultButton from '../DefaultButton'; + +const ReadButton = ({ tokenName, tokenId }) => { + return ( + + + + ); +}; + +ReadButton.propTypes = { + tokenName: PropTypes.string.isRequired, + tokenId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired, +}; + +export default ReadButton; diff --git a/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/UpdateButton/index.js b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/UpdateButton/index.js index 0c5a77ab5e..f781e03543 100644 --- a/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/UpdateButton/index.js +++ b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/UpdateButton/index.js @@ -1,46 +1,13 @@ import React from 'react'; import Pencil from '@strapi/icons/Pencil'; -import { useIntl } from 'react-intl'; import PropTypes from 'prop-types'; -import { Link } from '@strapi/helper-plugin'; -import { useHistory } from 'react-router-dom'; -import styled from 'styled-components'; - -const LinkUpdate = styled(Link)` - svg { - path { - fill: ${({ theme }) => theme.colors.neutral500}; - } - } - - &:hover { - svg { - path { - fill: ${({ theme }) => theme.colors.neutral800}; - } - } - } -`; +import DefaultButton from '../DefaultButton'; const UpdateButton = ({ tokenName, tokenId }) => { - const { formatMessage } = useIntl(); - const { - location: { pathname }, - } = useHistory(); - return ( - + - + ); }; diff --git a/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/index.js b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/index.js index 1e4a6ce6ad..fce83eced6 100644 --- a/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/index.js +++ b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/index.js @@ -14,8 +14,9 @@ import PropTypes from 'prop-types'; import { useHistory } from 'react-router-dom'; import DeleteButton from './DeleteButton'; import UpdateButton from './UpdateButton'; +import ReadButton from './ReadButton'; -const TableRows = ({ canDelete, canUpdate, onClickDelete, withBulkActions, rows }) => { +const TableRows = ({ canDelete, canUpdate, canRead, onClickDelete, withBulkActions, rows }) => { const { formatMessage } = useIntl(); const [{ query }] = useQueryParams(); const [, sortOrder] = query.sort.split(':'); @@ -73,6 +74,9 @@ const TableRows = ({ canDelete, canUpdate, onClickDelete, withBulkActions, rows {canUpdate && } + {!canUpdate && canRead && ( + + )} {canDelete && ( {}, rows: [], withBulkActions: false, @@ -100,6 +105,7 @@ TableRows.defaultProps = { TableRows.propTypes = { canDelete: PropTypes.bool, canUpdate: PropTypes.bool, + canRead: PropTypes.bool, onClickDelete: PropTypes.func, rows: PropTypes.array, withBulkActions: PropTypes.bool, diff --git a/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/index.js b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/index.js index b8d5cff399..6add5886b4 100644 --- a/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/index.js +++ b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/index.js @@ -135,15 +135,16 @@ const ApiTokenListView = () => { headers={tableHeaders} contentType="api-tokens" rows={apiTokens} - withBulkActions={canDelete || canUpdate} + withBulkActions={canDelete || canUpdate || canRead} isLoading={isLoading} onConfirmDelete={id => deleteMutation.mutateAsync(id)} > )} From ce780870cff8feef9ee7d5ce01f7abfffa10ca8b Mon Sep 17 00:00:00 2001 From: Simone Taeggi Date: Fri, 12 Aug 2022 15:43:29 +0200 Subject: [PATCH 3/8] add tests coverage script --- packages/core/admin/package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/core/admin/package.json b/packages/core/admin/package.json index a17c2afa7f..68ad3b234b 100644 --- a/packages/core/admin/package.json +++ b/packages/core/admin/package.json @@ -34,7 +34,8 @@ "test:front": "cross-env IS_EE=true jest --config ./jest.config.front.js", "test:front:watch": "cross-env IS_EE=true jest --config ./jest.config.front.js --watchAll", "test:front:ce": "cross-env IS_EE=false jest --config ./jest.config.front.js", - "test:front:watch:ce": "cross-env IS_EE=false jest --config ./jest.config.front.js --watchAll" + "test:front:watch:ce": "cross-env IS_EE=false jest --config ./jest.config.front.js --watchAll", + "test:front:ce:cov": "cross-env IS_EE=false jest --config ./jest.config.front.js --coverage --collectCoverageFrom='/packages/core/admin/admin/**/*.js' --coverageDirectory='/packages/core/admin/coverage'" }, "dependencies": { "@babel/core": "7.18.10", From df6504fafc263ee01938f9d8e016f94f71dc1fd8 Mon Sep 17 00:00:00 2001 From: Simone Taeggi Date: Fri, 12 Aug 2022 15:46:18 +0200 Subject: [PATCH 4/8] add a name attribute to the delete button --- .../DynamicTable/DeleteButton/index.js | 1 + .../ListView/DynamicTable/ReadButton/index.js | 2 +- .../ApiTokens/ListView/tests/index.test.js | 28 +++++++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/DeleteButton/index.js b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/DeleteButton/index.js index 2ed062fbfa..2ae7b441cb 100644 --- a/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/DeleteButton/index.js +++ b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/DeleteButton/index.js @@ -24,6 +24,7 @@ const DeleteButton = ({ tokenName, onClickDelete }) => { }, { target: `${tokenName}` } )} + name="delete" noBorder icon={} /> diff --git a/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/ReadButton/index.js b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/ReadButton/index.js index 2991407fe1..85c9f96dbf 100644 --- a/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/ReadButton/index.js +++ b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/ReadButton/index.js @@ -5,7 +5,7 @@ import DefaultButton from '../DefaultButton'; const ReadButton = ({ tokenName, tokenId }) => { return ( - + ); diff --git a/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/tests/index.test.js b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/tests/index.test.js index 36152ba60a..0dc791eedb 100644 --- a/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/tests/index.test.js +++ b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/tests/index.test.js @@ -956,6 +956,7 @@ describe('ADMIN | Pages | API TOKENS | ListPage', () => { aria-disabled="false" aria-labelledby="tooltip-3" class="c25 c26" + name="delete" tabindex="-1" type="button" > @@ -999,4 +1000,31 @@ describe('ADMIN | Pages | API TOKENS | ListPage', () => { await waitFor(() => expect(queryByTestId('create-api-token-button')).not.toBeInTheDocument()); }); + + it('should show the delete button when the user have the rights to delete', async () => { + const history = createMemoryHistory(); + history.push('/settings/api-tokens'); + const app = makeApp(history); + + const { container } = render(app); + + await waitFor(() => { + expect(container.querySelector('button[name="delete"]')).toBeInTheDocument(); + }); + }); + + it('should show the read button when the user have the rights to read and not to update', async () => { + useRBAC.mockImplementationOnce(() => ({ + allowedActions: { canCreate: false, canDelete: false, canRead: true, canUpdate: false }, + })); + const history = createMemoryHistory(); + history.push('/settings/api-tokens'); + const app = makeApp(history); + + const { container } = render(app); + + await waitFor(() => { + expect(container.querySelector('a[title*="Edit"]')).toBeInTheDocument(); + }); + }); }); From 714233a0ce6e33975e77927b49beb09e68d24d16 Mon Sep 17 00:00:00 2001 From: Simone Taeggi Date: Fri, 12 Aug 2022 16:55:33 +0200 Subject: [PATCH 5/8] add read button test --- .../ApiTokens/ListView/tests/index.test.js | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/tests/index.test.js b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/tests/index.test.js index 0dc791eedb..251295d9e1 100644 --- a/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/tests/index.test.js +++ b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/tests/index.test.js @@ -15,9 +15,7 @@ jest.mock('@strapi/helper-plugin', () => ({ ...jest.requireActual('@strapi/helper-plugin'), useNotification: jest.fn(), useFocusWhenNavigate: jest.fn(), - useRBAC: jest.fn(() => ({ - allowedActions: { canCreate: true, canDelete: true, canRead: true, canUpdate: true }, - })), + useRBAC: jest.fn(), useGuidedTour: jest.fn(() => ({ startSection: jest.fn(), })), @@ -73,6 +71,9 @@ describe('ADMIN | Pages | API TOKENS | ListPage', () => { }); it('should show a list of api tokens', async () => { + useRBAC.mockImplementation(() => ({ + allowedActions: { canCreate: true, canDelete: true, canRead: true, canUpdate: true }, + })); const history = createMemoryHistory(); history.push('/settings/api-tokens'); const app = makeApp(history); @@ -989,7 +990,7 @@ describe('ADMIN | Pages | API TOKENS | ListPage', () => { }); it('should not show the create button when the user does not have the rights to create', async () => { - useRBAC.mockImplementationOnce(() => ({ + useRBAC.mockImplementation(() => ({ allowedActions: { canCreate: false, canDelete: true, canRead: true, canUpdate: true }, })); @@ -1002,6 +1003,9 @@ describe('ADMIN | Pages | API TOKENS | ListPage', () => { }); it('should show the delete button when the user have the rights to delete', async () => { + useRBAC.mockImplementation(() => ({ + allowedActions: { canCreate: false, canDelete: true, canRead: true, canUpdate: false }, + })); const history = createMemoryHistory(); history.push('/settings/api-tokens'); const app = makeApp(history); @@ -1014,8 +1018,8 @@ describe('ADMIN | Pages | API TOKENS | ListPage', () => { }); it('should show the read button when the user have the rights to read and not to update', async () => { - useRBAC.mockImplementationOnce(() => ({ - allowedActions: { canCreate: false, canDelete: false, canRead: true, canUpdate: false }, + useRBAC.mockImplementation(() => ({ + allowedActions: { canCreate: false, canDelete: true, canRead: true, canUpdate: false }, })); const history = createMemoryHistory(); history.push('/settings/api-tokens'); @@ -1024,7 +1028,7 @@ describe('ADMIN | Pages | API TOKENS | ListPage', () => { const { container } = render(app); await waitFor(() => { - expect(container.querySelector('a[title*="Edit"]')).toBeInTheDocument(); + expect(container.querySelector('a[title*="Read"]')).toBeInTheDocument(); }); }); }); From 59dbe4c634027aa2af6b2c0964e44dcf27f709a4 Mon Sep 17 00:00:00 2001 From: Simone Taeggi Date: Tue, 16 Aug 2022 10:18:32 +0200 Subject: [PATCH 6/8] add the css focus style in the default button --- .../ApiTokens/ListView/DynamicTable/DefaultButton/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/DefaultButton/index.js b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/DefaultButton/index.js index fe0e0ae91e..a2f881ef78 100644 --- a/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/DefaultButton/index.js +++ b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/DefaultButton/index.js @@ -23,7 +23,8 @@ const LinkStyled = styled(Link)` } } - &:hover { + &:hover, + &:focus { svg { path { fill: ${({ theme }) => theme.colors.neutral800}; From a8d960599a567b50ffffe14606a831f91c28de82 Mon Sep 17 00:00:00 2001 From: Simone Taeggi Date: Tue, 16 Aug 2022 10:26:43 +0200 Subject: [PATCH 7/8] fix title value --- .../ApiTokens/ListView/DynamicTable/DefaultButton/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/DefaultButton/index.js b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/DefaultButton/index.js index a2f881ef78..2d08392ac6 100644 --- a/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/DefaultButton/index.js +++ b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/DefaultButton/index.js @@ -42,7 +42,7 @@ const DefaultButton = ({ tokenName, tokenId, buttonType, children }) => { return ( {children} From d23ae7b1a7f5d5045a1354adeee29e425ac4acf4 Mon Sep 17 00:00:00 2001 From: Simone Taeggi Date: Tue, 16 Aug 2022 10:45:18 +0200 Subject: [PATCH 8/8] update snapshots --- .../SettingsPage/pages/ApiTokens/ListView/tests/index.test.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/tests/index.test.js b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/tests/index.test.js index 251295d9e1..80bc878204 100644 --- a/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/tests/index.test.js +++ b/packages/core/admin/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/tests/index.test.js @@ -632,7 +632,8 @@ describe('ADMIN | Pages | API TOKENS | ListPage', () => { fill: #8e8ea9; } - .c36:hover svg path { + .c36:hover svg path, + .c36:focus svg path { fill: #32324d; }