From 97d505ca08e7d8c293732947e9ea27b8fec48404 Mon Sep 17 00:00:00 2001 From: lgalis Date: Wed, 28 Aug 2024 11:46:20 -0400 Subject: [PATCH] [AAP-25086] Remove the controller token from the UI (#3063) --- .../e2e/eda/admin-user/controller-token.cy.ts | 37 ------- .../access/users/CreateControllerToken.tsx | 99 ------------------- .../users/UserPage/ControllerTokens.tsx | 60 ----------- frontend/eda/access/users/UserPage/MyPage.tsx | 5 +- .../eda/access/users/UserPage/UserPage.tsx | 1 - .../users/hooks/useControllerTokenActions.tsx | 28 ------ .../users/hooks/useControllerTokenFilters.tsx | 19 ---- .../hooks/useControllerTokensActions.tsx | 48 --------- .../hooks/useControllerTokensColumns.tsx | 30 ------ .../users/hooks/useDeleteControllerTokens.tsx | 39 -------- frontend/eda/common/edaErrorAdapter.cy.tsx | 4 +- frontend/eda/main/EdaRoutes.tsx | 4 - frontend/eda/main/useEdaNavigation.tsx | 22 ----- frontend/eda/overview/EdaOverview.tsx | 8 -- .../RulebookActivationForm.tsx | 28 +----- 15 files changed, 4 insertions(+), 428 deletions(-) delete mode 100644 cypress/e2e/eda/admin-user/controller-token.cy.ts delete mode 100644 frontend/eda/access/users/CreateControllerToken.tsx delete mode 100644 frontend/eda/access/users/UserPage/ControllerTokens.tsx delete mode 100644 frontend/eda/access/users/hooks/useControllerTokenActions.tsx delete mode 100644 frontend/eda/access/users/hooks/useControllerTokenFilters.tsx delete mode 100644 frontend/eda/access/users/hooks/useControllerTokensActions.tsx delete mode 100644 frontend/eda/access/users/hooks/useControllerTokensColumns.tsx delete mode 100644 frontend/eda/access/users/hooks/useDeleteControllerTokens.tsx diff --git a/cypress/e2e/eda/admin-user/controller-token.cy.ts b/cypress/e2e/eda/admin-user/controller-token.cy.ts deleted file mode 100644 index 53fcf1e6f4..0000000000 --- a/cypress/e2e/eda/admin-user/controller-token.cy.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { EdaControllerToken } from '../../../../frontend/eda/interfaces/EdaControllerToken'; -import { edaAPI } from '../../../support/formatApiPathForEDA'; - -describe('EDA Admin User', () => { - const checkEmptyState = () => { - cy.contains('h4', 'You currently do not have any tokens from Automation Controller.'); - cy.contains( - 'div', - 'Please create a token from Automation Controller by using the button below.' - ); - cy.contains('button', 'Create controller token').should('be.enabled'); - }; - - it('checks the empty state for Controller token page and create Controller token CTA does not exist with existing token', () => { - cy.getEdaActiveUser().then((edaUser) => { - cy.intercept('GET', edaAPI`/users/me/awx-tokens/?page=1&page_size=10`).as('checkToken'); - cy.navigateTo('eda', 'users'); - cy.contains('h1', 'Users'); - cy.contains( - '[data-cy="app-description"]', - 'A user is someone who has access to Event Driven Automation with associated permissions and credentials.' - ); - cy.contains('a', edaUser.username).click(); - cy.contains('li', 'Controller Tokens').click(); - cy.wait('@checkToken') - .its('response.body.results') - .then((results: Array) => { - if (results.length === 0) { - checkEmptyState(); - } else { - cy.get('tbody').children('tr').should('exist'); - cy.contains('button', 'Create controller token').should('not.exist'); - } - }); - }); - }); -}); diff --git a/frontend/eda/access/users/CreateControllerToken.tsx b/frontend/eda/access/users/CreateControllerToken.tsx deleted file mode 100644 index 989e29e35b..0000000000 --- a/frontend/eda/access/users/CreateControllerToken.tsx +++ /dev/null @@ -1,99 +0,0 @@ -import { useTranslation } from 'react-i18next'; -import { useNavigate } from 'react-router-dom'; -import { - PageFormSubmitHandler, - PageFormTextInput, - PageHeader, - PageLayout, - useGetPageUrl, - usePageNavigate, -} from '../../../../framework'; -import { usePostRequest } from '../../../common/crud/usePostRequest'; -import { EdaPageForm } from '../../common/EdaPageForm'; -import { edaAPI } from '../../common/eda-utils'; -import { useEdaActiveUser } from '../../common/useEdaActiveUser'; -import { EdaControllerToken, EdaControllerTokenCreate } from '../../interfaces/EdaControllerToken'; -import { EdaRoute } from '../../main/EdaRoutes'; - -function ControllerTokenInputs(props: { tokenPlaceHolder?: string }) { - const { t } = useTranslation(); - const { tokenPlaceHolder } = props; - return ( - <> - - name="name" - label={t('Name')} - placeholder={t('Enter name')} - isRequired - maxLength={150} - /> - - name="description" - label={t('Description')} - placeholder={t('Enter description ')} - maxLength={150} - /> - - name="token" - label={t('Token')} - isRequired - maxLength={150} - placeholder={tokenPlaceHolder ?? t('Enter controller token')} - /> - - ); -} - -export function CreateControllerToken(props: { - breadCrumbTitle?: string; - pageTitle?: string; - tokenPlaceHolder?: string; - submitText?: string; -}) { - const { breadCrumbTitle, pageTitle, tokenPlaceHolder, submitText } = props; - const { t } = useTranslation(); - const navigate = useNavigate(); - const pageNavigate = usePageNavigate(); - const postRequest = usePostRequest(); - const { activeEdaUser } = useEdaActiveUser(); - - const onSubmit: PageFormSubmitHandler = async (token) => { - await postRequest(edaAPI`/users/me/awx-tokens/`, token); - pageNavigate(EdaRoute.MyTokens, { params: { id: activeEdaUser?.id } }); - }; - const onCancel = () => navigate(-1); - - const getPageUrl = useGetPageUrl(); - - const canViewUsers = activeEdaUser?.is_superuser; - const breadcrumbs = [ - ...(canViewUsers ? [{ label: t('Users'), to: getPageUrl(EdaRoute.Users) }] : []), - { - label: activeEdaUser?.username ?? '', - to: canViewUsers - ? getPageUrl(EdaRoute.UserPage, { params: { id: activeEdaUser?.id } }) - : getPageUrl(EdaRoute.MyPage, { params: { id: activeEdaUser?.id } }), - }, - { - label: breadCrumbTitle ?? t('Controller tokens'), - to: canViewUsers - ? getPageUrl(EdaRoute.UserTokens, { params: { id: activeEdaUser?.id } }) - : getPageUrl(EdaRoute.MyTokens, { params: { id: activeEdaUser?.id } }), - }, - { label: activeEdaUser?.username ?? '' }, - ]; - - return ( - - - - - - - ); -} diff --git a/frontend/eda/access/users/UserPage/ControllerTokens.tsx b/frontend/eda/access/users/UserPage/ControllerTokens.tsx deleted file mode 100644 index a83b25f20d..0000000000 --- a/frontend/eda/access/users/UserPage/ControllerTokens.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import { useTranslation } from 'react-i18next'; -import { PageLayout, PageTable, usePageNavigate } from '../../../../../framework'; -import { edaAPI } from '../../../common/eda-utils'; -import { useEdaView } from '../../../common/useEventDrivenView'; -import { EdaControllerToken } from '../../../interfaces/EdaControllerToken'; -import { EdaRoute } from '../../../main/EdaRoutes'; -import { useControllerTokenActions } from '../hooks/useControllerTokenActions'; -import { useControllerTokensActions } from '../hooks/useControllerTokensActions'; -import { useControllerTokensColumns } from '../hooks/useControllerTokensColumns'; -import { PlusCircleIcon } from '@patternfly/react-icons'; -import { DetailInfo } from '../../../../../framework/components/DetailInfo'; - -export function ControllerTokens(props: { - createTokenRoute?: string; - infoMessage?: string; - createTokenButtonLabel?: string; - emptyStateTitle?: string; - emptyStateDescription?: string; -}) { - const { t } = useTranslation(); - const pageNavigate = usePageNavigate(); - const tableColumns = useControllerTokensColumns(); - const createRoute = props.createTokenRoute || EdaRoute.CreateControllerToken; - - const view = useEdaView({ - url: edaAPI`/users/me/awx-tokens/`, - tableColumns, - }); - const toolbarActions = useControllerTokensActions( - view, - createRoute, - props.createTokenButtonLabel - ); - const rowActions = useControllerTokenActions(view); - return ( - - {props.infoMessage && } - } - emptyStateButtonText={t(props.createTokenButtonLabel || 'Create controller token')} - emptyStateButtonClick={() => pageNavigate(createRoute)} - {...view} - defaultSubtitle={t('Controller tokens')} - /> - - ); -} diff --git a/frontend/eda/access/users/UserPage/MyPage.tsx b/frontend/eda/access/users/UserPage/MyPage.tsx index b3764aff6d..6460c36498 100644 --- a/frontend/eda/access/users/UserPage/MyPage.tsx +++ b/frontend/eda/access/users/UserPage/MyPage.tsx @@ -83,10 +83,7 @@ export function MyPage() { } /> diff --git a/frontend/eda/access/users/UserPage/UserPage.tsx b/frontend/eda/access/users/UserPage/UserPage.tsx index 814e5ca199..2b7411cd60 100644 --- a/frontend/eda/access/users/UserPage/UserPage.tsx +++ b/frontend/eda/access/users/UserPage/UserPage.tsx @@ -91,7 +91,6 @@ export function UserPage() { ? [ { label: t('Details'), page: EdaRoute.UserDetails }, { label: t('Roles'), page: EdaRoute.UserRoles }, - { label: t('Controller Tokens'), page: EdaRoute.UserTokens }, ] : [ { label: t('Details'), page: EdaRoute.UserDetails }, diff --git a/frontend/eda/access/users/hooks/useControllerTokenActions.tsx b/frontend/eda/access/users/hooks/useControllerTokenActions.tsx deleted file mode 100644 index 10a9654f84..0000000000 --- a/frontend/eda/access/users/hooks/useControllerTokenActions.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { ButtonVariant } from '@patternfly/react-core'; -import { TrashIcon } from '@patternfly/react-icons'; -import { useMemo } from 'react'; -import { useTranslation } from 'react-i18next'; -import { IPageAction, PageActionSelection, PageActionType } from '../../../../../framework'; -import { IEdaView } from '../../../common/useEventDrivenView'; -import { EdaControllerToken } from '../../../interfaces/EdaControllerToken'; -import { useDeleteControllerTokens } from './useDeleteControllerTokens'; - -export function useControllerTokenActions(view: IEdaView) { - const { t } = useTranslation(); - const deleteControllerTokens = useDeleteControllerTokens(view.unselectItemsAndRefresh); - return useMemo[]>( - () => [ - { - type: PageActionType.Button, - variant: ButtonVariant.primary, - selection: PageActionSelection.Single, - icon: TrashIcon, - isPinned: true, - label: t('Delete controller token'), - onClick: (token: EdaControllerToken) => deleteControllerTokens([token]), - isDanger: true, - }, - ], - [deleteControllerTokens, t] - ); -} diff --git a/frontend/eda/access/users/hooks/useControllerTokenFilters.tsx b/frontend/eda/access/users/hooks/useControllerTokenFilters.tsx deleted file mode 100644 index 0af73e7682..0000000000 --- a/frontend/eda/access/users/hooks/useControllerTokenFilters.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import { useMemo } from 'react'; -import { useTranslation } from 'react-i18next'; -import { IToolbarFilter, ToolbarFilterType } from '../../../../../framework'; - -export function useControllerFilters() { - const { t } = useTranslation(); - return useMemo( - () => [ - { - key: 'name', - label: t('Name'), - type: ToolbarFilterType.MultiText, - query: 'name', - comparison: 'startsWith', - }, - ], - [t] - ); -} diff --git a/frontend/eda/access/users/hooks/useControllerTokensActions.tsx b/frontend/eda/access/users/hooks/useControllerTokensActions.tsx deleted file mode 100644 index ef344b3587..0000000000 --- a/frontend/eda/access/users/hooks/useControllerTokensActions.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import { ButtonVariant } from '@patternfly/react-core'; -import { PlusCircleIcon, TrashIcon } from '@patternfly/react-icons'; -import { useMemo } from 'react'; -import { useTranslation } from 'react-i18next'; -import { - IPageAction, - PageActionSelection, - PageActionType, - usePageNavigate, -} from '../../../../../framework'; -import { IEdaView } from '../../../common/useEventDrivenView'; -import { EdaControllerToken } from '../../../interfaces/EdaControllerToken'; -import { EdaRoute } from '../../../main/EdaRoutes'; -import { useDeleteControllerTokens } from './useDeleteControllerTokens'; - -export function useControllerTokensActions( - view: IEdaView, - createTokenRoute?: string, - createTokenButtonLabel?: string -) { - const { t } = useTranslation(); - const pageNavigate = usePageNavigate(); - const createRoute = createTokenRoute || EdaRoute.CreateControllerToken; - const deleteControllerTokens = useDeleteControllerTokens(view.unselectItemsAndRefresh); - return useMemo[]>( - () => [ - { - type: PageActionType.Button, - selection: PageActionSelection.None, - variant: ButtonVariant.primary, - isPinned: true, - icon: PlusCircleIcon, - label: t(createTokenButtonLabel || 'Create controller token'), - onClick: () => pageNavigate(createRoute), - }, - { - type: PageActionType.Button, - selection: PageActionSelection.Multiple, - icon: TrashIcon, - label: t('Delete selected controller tokens'), - onClick: (controllerTokens: EdaControllerToken[]) => - deleteControllerTokens(controllerTokens), - isDanger: true, - }, - ], - [deleteControllerTokens, pageNavigate, t, createRoute, createTokenButtonLabel] - ); -} diff --git a/frontend/eda/access/users/hooks/useControllerTokensColumns.tsx b/frontend/eda/access/users/hooks/useControllerTokensColumns.tsx deleted file mode 100644 index d0779175b2..0000000000 --- a/frontend/eda/access/users/hooks/useControllerTokensColumns.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import { useMemo } from 'react'; -import { useTranslation } from 'react-i18next'; -import { ColumnModalOption, DateTimeCell, ITableColumn, TextCell } from '../../../../../framework'; -import { EdaControllerToken } from '../../../interfaces/EdaControllerToken'; - -export function useControllerTokensColumns() { - const { t } = useTranslation(); - return useMemo[]>( - () => [ - { - header: t('Name'), - cell: (token) => , - card: 'name', - list: 'name', - }, - { - header: t('Description'), - cell: (token) => token.description && , - }, - { - header: t('Created'), - cell: (token: EdaControllerToken) => - token.created_at && , - value: (token) => token.created_at, - modal: ColumnModalOption.hidden, - }, - ], - [t] - ); -} diff --git a/frontend/eda/access/users/hooks/useDeleteControllerTokens.tsx b/frontend/eda/access/users/hooks/useDeleteControllerTokens.tsx deleted file mode 100644 index e3d57e4029..0000000000 --- a/frontend/eda/access/users/hooks/useDeleteControllerTokens.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import { useCallback, useMemo } from 'react'; -import { useTranslation } from 'react-i18next'; -import { compareStrings } from '../../../../../framework'; -import { requestDelete } from '../../../../common/crud/Data'; -import { idKeyFn } from '../../../../common/utils/nameKeyFn'; -import { edaAPI } from '../../../common/eda-utils'; -import { EdaControllerToken } from '../../../interfaces/EdaControllerToken'; -import { useEdaBulkConfirmation } from '../../../common/useEdaBulkConfirmation'; -import { useControllerTokensColumns } from './useControllerTokensColumns'; - -export function useDeleteControllerTokens(onComplete: (credentials: EdaControllerToken[]) => void) { - const { t } = useTranslation(); - const confirmationColumns = useControllerTokensColumns(); - const actionColumns = useMemo(() => [confirmationColumns[0]], [confirmationColumns]); - const bulkAction = useEdaBulkConfirmation(); - return useCallback( - (controllerTokens: EdaControllerToken[]) => { - bulkAction({ - title: t('Permanently delete controller tokens', { count: controllerTokens.length }), - confirmText: - controllerTokens.length === 1 - ? t('Yes, I confirm that I want to delete this token.') - : t('Yes, I confirm that I want to delete these {{count}} tokens.', { - count: controllerTokens.length, - }), - actionButtonText: t('Delete controller tokens', { count: controllerTokens.length }), - items: controllerTokens.sort((l, r) => compareStrings(l.name, r.name)), - keyFn: idKeyFn, - isDanger: true, - confirmationColumns, - actionColumns, - onComplete, - actionFn: (token: EdaControllerToken, signal) => - requestDelete(edaAPI`/users/me/awx-tokens/${token.id.toString()}/`, signal), - }); - }, - [actionColumns, bulkAction, confirmationColumns, onComplete, t] - ); -} diff --git a/frontend/eda/common/edaErrorAdapter.cy.tsx b/frontend/eda/common/edaErrorAdapter.cy.tsx index 4b32793d8a..8f166cd14c 100644 --- a/frontend/eda/common/edaErrorAdapter.cy.tsx +++ b/frontend/eda/common/edaErrorAdapter.cy.tsx @@ -64,12 +64,12 @@ describe('edaErrorAdapter', () => { undefined, 400, {}, - { non_field_errors: ['No controller token specified'] } + { non_field_errors: ['Generic non-field error'] } ); const result = edaErrorAdapter(error); expect(result.genericErrors.length).equal(1); expect(result.fieldErrors.length).equal(0); - expect(result.genericErrors).to.deep.equal([{ message: 'No controller token specified' }]); + expect(result.genericErrors).to.deep.equal([{ message: 'Generic non-field error' }]); }); }); diff --git a/frontend/eda/main/EdaRoutes.tsx b/frontend/eda/main/EdaRoutes.tsx index 62b4cfff0a..e17cbd2643 100644 --- a/frontend/eda/main/EdaRoutes.tsx +++ b/frontend/eda/main/EdaRoutes.tsx @@ -66,9 +66,7 @@ export enum EdaRoute { UserPage = 'eda-user-page', MyPage = 'eda-me-page', MyDetails = 'eda-my-details', - MyTokens = 'eda-my-tokens', UserDetails = 'eda-user-details', - UserTokens = 'eda-user-tokens', UserRoles = 'eda-user-roles', UserAddRoles = 'eda-user-add-roles', @@ -84,8 +82,6 @@ export enum EdaRoute { RolePage = 'eda-role-page', RoleDetails = 'eda-role-details', - CreateControllerToken = 'eda-create-controller-token', - EventStreams = 'eda-event-streams', CreateEventStream = 'eda-create-event-stream', EditEventStream = 'eda-edit-event-stream', diff --git a/frontend/eda/main/useEdaNavigation.tsx b/frontend/eda/main/useEdaNavigation.tsx index a4cd6ca44d..fca8fb15f5 100644 --- a/frontend/eda/main/useEdaNavigation.tsx +++ b/frontend/eda/main/useEdaNavigation.tsx @@ -29,10 +29,8 @@ import { TeamDetails } from '../access/teams/TeamPage/TeamDetails'; import { CreateTeam, EditTeam } from '../access/teams/TeamPage/TeamForm'; import { TeamPage } from '../access/teams/TeamPage/TeamPage'; import { Teams } from '../access/teams/Teams'; -import { CreateControllerToken } from '../access/users/CreateControllerToken'; import { EdaAddUserRoles } from '../access/users/EdaAddUserRoles'; import { CreateUser, EditCurrentUser, EditUser } from '../access/users/EditUser'; -import { ControllerTokens } from '../access/users/UserPage/ControllerTokens'; import { EdaMyDetails } from '../access/users/UserPage/EdaMyDetails'; import { EdaUserDetails } from '../access/users/UserPage/EdaUserDetails'; import { EdaUserRoles } from '../access/users/UserPage/EdaUserRoles'; @@ -403,11 +401,6 @@ export function useEdaNavigation() { path: 'details', element: , }, - { - id: EdaRoute.MyTokens, - path: 'tokens', - element: , - }, { path: '', element: , @@ -444,11 +437,6 @@ export function useEdaNavigation() { path: 'roles', element: , }, - { - id: EdaRoute.UserTokens, - path: 'tokens', - element: , - }, { path: '', element: , @@ -460,16 +448,6 @@ export function useEdaNavigation() { path: ':id/roles/add-roles', element: , }, - { - path: 'tokens', - children: [ - { - id: EdaRoute.CreateControllerToken, - path: 'create', - element: , - }, - ], - }, { path: '', element: , diff --git a/frontend/eda/overview/EdaOverview.tsx b/frontend/eda/overview/EdaOverview.tsx index f01ec76867..6c5346e226 100644 --- a/frontend/eda/overview/EdaOverview.tsx +++ b/frontend/eda/overview/EdaOverview.tsx @@ -85,14 +85,6 @@ export function EdaOverview() { {t(', or follow the steps below.')} - - - {t('Controller Token')} - - >( - edaAPI`/users/me/awx-tokens/?page=1&page_size=200` - ); - const { data: eventStreams } = useGet>(edaAPI`/event-streams/`); const [_, setDialog] = usePageDialog(); @@ -308,27 +304,6 @@ export function RulebookActivationInputs() { labelHelp={t('Decision environments are a container image to run Ansible rulebooks.')} labelHelpTitle={t('Decision environment')} /> - - name="awx_token_id" - label={t('Controller token')} - placeholderText={t('Select controller token')} - options={ - tokens?.results - ? tokens.results.map((item: { name: string; id: number }) => ({ - label: item.name, - value: item.id, - })) - : [] - } - footer={ - Create controller token - } - labelHelpTitle={t('Controller tokens')} - labelHelp={[ - t('Controller tokens are used to authenticate with controller API.'), - t('Controller tokens can be added under the current user details.'), - ]} - /> name="restart_policy" label={t('Restart policy')} @@ -393,7 +368,6 @@ type IEdaRulebookActivationInputs = Omit