diff --git a/cypress/support/actions/settings/SettingsAction.ts b/cypress/support/actions/settings/SettingsAction.ts index 4181df31..ecf9bf59 100644 --- a/cypress/support/actions/settings/SettingsAction.ts +++ b/cypress/support/actions/settings/SettingsAction.ts @@ -17,7 +17,10 @@ export default class SettingAction { } deleteSshKey(name: string) { - settings.getDeleteBtn().should('be.visible').click({ force: true, multiple: true }); + settings.getDeleteBtn(name); + cy.log('enter the name and confirm'); + cy.getBySel('confirm-input').type(name); + cy.getBySel('deleteConfirm').click(); cy.contains(name).should('not.exist'); } } diff --git a/cypress/support/repositories/settings/SettingsRepository.ts b/cypress/support/repositories/settings/SettingsRepository.ts index d5405906..6f7a3a37 100644 --- a/cypress/support/repositories/settings/SettingsRepository.ts +++ b/cypress/support/repositories/settings/SettingsRepository.ts @@ -10,7 +10,16 @@ export default class SettingsRepository { getSubmitBtn() { return cy.getBySel('sshKey').parent().next(); } - getDeleteBtn() { - return cy.getBySel('deleteKey').getBySel('deleteBtn'); + + getKeyToDelete() { + return cy.getBySel('data-row'); + } + getDeleteBtn(name: string) { + this.getKeyToDelete() + .contains(name) + .parent() + .within(() => { + cy.getBySel('deleteKey').getBySel('delete').click(); + }); } } diff --git a/src/components/DeleteConfirm/index.js b/src/components/DeleteConfirm/index.js index 7b4d97df..8902b7f1 100644 --- a/src/components/DeleteConfirm/index.js +++ b/src/components/DeleteConfirm/index.js @@ -11,6 +11,7 @@ import { color } from 'lib/variables'; export const DeleteConfirm = ({ deleteType, deleteName, + deleteMessage, icon, onDelete, inputValue, @@ -28,11 +29,15 @@ export const DeleteConfirm = ({ -

- This will delete all resources associated with the {deleteType}{' '} - {deleteName} and cannot be undone. Make sure this is something you - really want to do! -

+ {deleteMessage ? ( +

{deleteMessage}

+ ) : ( +

+ This will delete all resources associated with the {deleteType}{' '} + {deleteName} and cannot be undone. Make sure this is something you + really want to do! +

+ )}

Type the name of the {deleteType} to confirm.

diff --git a/src/components/DeleteConfirm/index.stories.tsx b/src/components/DeleteConfirm/index.stories.tsx index 2b124b7c..9abf06e9 100644 --- a/src/components/DeleteConfirm/index.stories.tsx +++ b/src/components/DeleteConfirm/index.stories.tsx @@ -45,6 +45,7 @@ export const WithConfirmationBlocked = ({ icon={} deleteType="environment" deleteName="Forty-two" + deleteMessage onDelete={onDeleteFunction} inputValue="" setInputValue={setInputValueFunction} diff --git a/src/components/SshKeys/index.js b/src/components/SshKeys/index.js index abaa4fe1..196581a5 100644 --- a/src/components/SshKeys/index.js +++ b/src/components/SshKeys/index.js @@ -2,11 +2,13 @@ import React, { useEffect, useState } from 'react'; import { Mutation } from 'react-apollo'; import Skeleton from 'react-loading-skeleton'; -import { Col, Modal, Row, Space } from 'antd'; +import { Col, Modal, Row, Space, notification } from 'antd'; import Button from 'components/Button'; +import DeleteConfirm from 'components/DeleteConfirm'; import DeleteUserSSHPublicKey from 'lib/mutation/DeleteUserSSHPublicKey'; import UpdateUserSSHPublicKey from 'lib/mutation/UpdateUserSSHPublicKey'; import Me from 'lib/query/Me'; +import { color } from 'lib/variables'; import moment from 'moment'; import { StyledKeys } from './StyledKeys'; @@ -28,10 +30,25 @@ const SshKeys = ({ me: { id, email, sshKeys: keys }, loading, handleRefetch }) = }; const openModal = keyObject => { - setEditState(keyObject); + setEditState({ ...keyObject, publicKey: getPK(keyObject) }); setModalOpen(true); }; + const [api, contextHolder] = notification.useNotification({ maxCount: 1 }); + + const getPK = key => { + return key.keyType + ' ' + key.keyValue; + }; + const openNotificationWithIcon = errorMessage => { + api['error']({ + message: 'There was a problem updating the SSH key.', + description: errorMessage, + placement: 'top', + duration: 0, + style: { width: '500px' }, + }); + }; + useEffect(() => { setIsLoading(loading); }, [loading]); @@ -52,7 +69,7 @@ const SshKeys = ({ me: { id, email, sshKeys: keys }, loading, handleRefetch }) = {keys && keys.map(key => ( -
+
{key.id} - {key.name}
@@ -78,35 +95,35 @@ const SshKeys = ({ me: { id, email, sshKeys: keys }, loading, handleRefetch }) = console.error(e)}> {(updateUserSSHPublicKey, { loading, called, error, data }) => { - if (error) { - return
{error.message}
; - } - if (data) { handleRefetch(); closeModal(); } return ( - + }) + } + > + Update + + {error && openNotificationWithIcon(error.message)} + ); }}
@@ -160,12 +177,22 @@ const SshKeys = ({ me: { id, email, sshKeys: keys }, loading, handleRefetch }) = return
{error.message}
; } + const deleteMessage = ( + <> + This action will delete the SSH key{' '} + {key.name} and cannot be + undone. + + ); + return ( - + /> ); }} diff --git a/src/layouts/GlobalStyles/index.tsx b/src/layouts/GlobalStyles/index.tsx index 0866b67c..74b14ca5 100644 --- a/src/layouts/GlobalStyles/index.tsx +++ b/src/layouts/GlobalStyles/index.tsx @@ -68,13 +68,18 @@ body { } } .ant-modal .ant-modal-content{ - background: ${props => (props.theme.colorScheme === 'dark' ? '#eaeaea' : '#fff')}; + background:${props => props.theme.backgrounds.primary};; .ant-modal-header{ border-radius: 0; background-color: transparent; + + .ant-modal-title{ + color: ${props => props.theme.texts.primary}; + } } .ant-modal-body { margin-block: 1rem; + color: ${props => props.theme.texts.primary}; > * { margin-bottom: 0.5rem; } diff --git a/src/lib/query/Me.js b/src/lib/query/Me.js index e8a88b06..ffca22c8 100644 --- a/src/lib/query/Me.js +++ b/src/lib/query/Me.js @@ -11,6 +11,7 @@ export default gql` id name keyType + keyValue created keyFingerprint }