-
Notifications
You must be signed in to change notification settings - Fork 64
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(inventory grops): group name modal (#1755)
* feat(inventory grops): group name modal * feat(inventory groups): updated test * feat(inventory groups): updated the mock server config and api * feat(inventory groups): added tests and fixed api requests * feat(inventory groups): added useCallback and removed axios * feat(inventory groups): more tests and chrome fix * feat(inventory groups): updated package lock and babel * feat(inventory-groups): updated the modal and api * feat(inventory groups): updating debounce and tests * feat(inventory groups): updated tests and schema validators * feat(inventory groups): updated test for empty state * feat(inventory groups): resolve test issues and updated configs * feat(inventory grops): api request change
- Loading branch information
Showing
14 changed files
with
2,123 additions
and
1,252 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
92 changes: 92 additions & 0 deletions
92
src/components/InventoryGroups/Modals/CreateGroupModal.cy.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
/* eslint-disable camelcase */ | ||
import React from 'react'; | ||
import { mount } from '@cypress/react'; | ||
import CreateGroupModal from './CreateGroupModal'; | ||
import { | ||
TEXT_INPUT | ||
} from '@redhat-cloud-services/frontend-components-utilities'; | ||
import { Provider } from 'react-redux'; | ||
import { MemoryRouter } from 'react-router-dom'; | ||
import { getStore } from '../../../store'; | ||
|
||
const mockResponse = [ | ||
{ | ||
count: 50, | ||
page: 20, | ||
per_page: 20, | ||
total: 50, | ||
results: [ | ||
{ | ||
created_at: '2020-02-09T10:16:07.996Z', | ||
host_ids: ['bA6deCFc19564430AB814bf8F70E8cEf'], | ||
id: '3f01b55457674041b75e41829bcee1dca', | ||
name: 'sre-group0', | ||
updated_at: '2020-02-09T10:16:07.996Z' | ||
}, | ||
{ | ||
created_at: '2020-02-09T10:16:07.996Z', | ||
host_ids: ['bA6deCFc19564430AB814bf8F70E8cEf'], | ||
id: '3f01b55457674041b75e41829bcee1dca', | ||
name: 'sre-group1', | ||
updated_at: '2020-02-09T10:16:07.996Z' | ||
}, | ||
{ | ||
created_at: '2020-02-09T10:16:07.996Z', | ||
host_ids: ['bA6deCFc19564430AB814bf8F70E8cEf'], | ||
id: '3f01b55457674041b75e41829bcee1dca', | ||
name: 'sre-group2', | ||
updated_at: '2020-02-09T10:16:07.996Z' | ||
}, | ||
{ | ||
created_at: '2020-02-09T10:16:07.996Z', | ||
host_ids: ['bA6deCFc19564430AB814bf8F70E8cEf'], | ||
id: '3f01b55457674041b75e41829bcee1dca', | ||
name: 'sre-group3', | ||
updated_at: '2020-02-09T10:16:07.996Z' | ||
} | ||
] | ||
} | ||
]; | ||
|
||
describe('Create Group Modal', () => { | ||
before(() => { | ||
cy.window().then(window => window.insights = { | ||
chrome: { | ||
isProd: false, | ||
auth: { | ||
getUser: () => { | ||
return Promise.resolve({}); | ||
} | ||
} | ||
} | ||
}); | ||
}); | ||
|
||
beforeEach(() => { | ||
|
||
cy.intercept('POST', '**/api/inventory/v1/groups', { | ||
statusCode: 504 | ||
}).as('create_group'); | ||
cy.intercept('GET', '**/api/inventory/v1/groups', { | ||
statusCode: 200, body: { | ||
...mockResponse | ||
} | ||
}).as('validate'); | ||
|
||
mount( | ||
<MemoryRouter> | ||
<Provider store={getStore()}> | ||
<CreateGroupModal isModalOpen={true} reloadData={() => console.log('data reloaded')}/> | ||
</Provider> | ||
</MemoryRouter> | ||
); | ||
}); | ||
|
||
it('Input is fillable and firing a validation request that succeeds', () => { | ||
cy.get(TEXT_INPUT).type('sre-group0'); | ||
cy.wait('@validate').then((xhr) => { | ||
expect(xhr.request.url).to.contain('groups');} | ||
); | ||
cy.get(`button[type="submit"]`).should('have.attr', 'aria-disabled', 'true'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import React, { useCallback, useMemo } from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import { createGroupSchema } from './ModalSchemas/schemes'; | ||
import Modal from './Modal'; | ||
import apiWithToast from '../utils/apiWithToast'; | ||
import { | ||
createGroup, | ||
validateGroupName | ||
} from '../utils/api'; | ||
import { useDispatch } from 'react-redux'; | ||
import awesomeDebouncePromise from 'awesome-debounce-promise'; | ||
|
||
const CreateGroupModal = ({ | ||
isModalOpen, | ||
setIsModalOpen, | ||
reloadData | ||
}) => { | ||
const dispatch = useDispatch(); | ||
|
||
const handleCreateGroup = useCallback( | ||
(values) => { | ||
const statusMessages = { | ||
onSuccess: { | ||
title: 'Success', | ||
description: `${values.name} has been created successfully` | ||
}, | ||
onError: { title: 'Error', description: 'Failed to create group' } | ||
}; | ||
return apiWithToast(dispatch, () => createGroup(values), statusMessages); | ||
}, | ||
[isModalOpen] | ||
); | ||
|
||
const schema = useMemo(() => { | ||
const check = async (value) => { | ||
const results = await validateGroupName(value); | ||
if (results === true) { | ||
throw 'Group name already exists'; | ||
} | ||
|
||
return undefined; | ||
}; | ||
|
||
// eslint-disable-next-line new-cap | ||
const d = awesomeDebouncePromise(check, 500, { onlyResolvesLast: false }); | ||
return createGroupSchema(d); | ||
}, []); | ||
|
||
return ( | ||
<Modal | ||
data-testid="create-group-modal" | ||
isModalOpen={isModalOpen} | ||
closeModal={() => setIsModalOpen(false)} | ||
title="Create group" | ||
submitLabel="Create" | ||
schema={schema} | ||
reloadData={reloadData} | ||
onSubmit={handleCreateGroup} | ||
/> | ||
); | ||
}; | ||
|
||
export default CreateGroupModal; | ||
|
||
CreateGroupModal.propTypes = { | ||
isModalOpen: PropTypes.bool, | ||
setIsModalOpen: PropTypes.func, | ||
reloadData: PropTypes.func, | ||
deviceIds: PropTypes.array, | ||
isOpen: PropTypes.bool | ||
}; |
24 changes: 24 additions & 0 deletions
24
src/components/InventoryGroups/Modals/CreateGroupModal.test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import React from 'react'; | ||
import { render, screen } from '@testing-library/react'; | ||
import '@testing-library/jest-dom'; | ||
import { getStore } from '../../../store'; | ||
import { Provider } from 'react-redux'; | ||
import { MemoryRouter } from 'react-router-dom'; | ||
|
||
import CreateGroupModal from './CreateGroupModal'; | ||
|
||
describe('CreateGroupModal', () => { | ||
it('renders correctly', () => { | ||
render( | ||
<MemoryRouter> | ||
<Provider store={getStore()}> | ||
<CreateGroupModal isModalOpen={true} reloadData={() => console.log('data reloaded')}/> | ||
</Provider> | ||
</MemoryRouter> | ||
); | ||
expect(screen.getByRole('heading', { name: /Create group/ })).toBeInTheDocument(); | ||
expect(screen.getByRole('textbox')).toBeInTheDocument(); | ||
expect(screen.getByRole('button', { name: /Create/ })).toBeInTheDocument(); | ||
expect(screen.getByRole('button', { name: /Cancel/ })).toBeInTheDocument(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import React from 'react'; | ||
import { Modal } from '@patternfly/react-core'; | ||
import FormRenderer from '@data-driven-forms/react-form-renderer/form-renderer'; | ||
import FormTemplate from '@data-driven-forms/pf4-component-mapper/form-template'; | ||
import componentMapper from '@data-driven-forms/pf4-component-mapper/component-mapper'; | ||
import PropTypes from 'prop-types'; | ||
|
||
const RepoModal = ({ | ||
isModalOpen, | ||
title, | ||
titleIconVariant, | ||
closeModal, | ||
submitLabel, | ||
schema, | ||
initialValues, | ||
variant, | ||
reloadData, | ||
size, | ||
onSubmit | ||
}) => { | ||
return ( | ||
<Modal | ||
ouiaId="group-modal" | ||
variant={size ?? 'small'} | ||
title={title} | ||
titleIconVariant={titleIconVariant ?? null} | ||
isOpen={isModalOpen} | ||
onClose={closeModal} | ||
> | ||
<FormRenderer | ||
schema={schema} | ||
FormTemplate={(props) => ( | ||
<FormTemplate | ||
{...props} | ||
submitLabel={submitLabel} | ||
disableSubmit={['invalid']} | ||
buttonsProps={{ | ||
submit: { variant } | ||
}} | ||
/> | ||
)} | ||
initialValues={initialValues} | ||
componentMapper={componentMapper} | ||
//reload comes from the table and fetches fresh data | ||
onSubmit={async (values) => { | ||
await onSubmit(values); | ||
setTimeout(async () => await reloadData(), 500); | ||
closeModal(); | ||
}} | ||
onCancel={() => closeModal()} | ||
/> | ||
</Modal> | ||
); | ||
}; | ||
|
||
RepoModal.propTypes = { | ||
isModalOpen: PropTypes.bool, | ||
title: PropTypes.string, | ||
closeModal: PropTypes.func, | ||
reloadData: PropTypes.func, | ||
submitLabel: PropTypes.string, | ||
schema: PropTypes.object, | ||
initialValues: PropTypes.object, | ||
variant: PropTypes.string, | ||
onSubmit: PropTypes.func, | ||
size: PropTypes.string, | ||
additionalMappers: PropTypes.object, | ||
titleIconVariant: PropTypes.any, | ||
validatorMapper: PropTypes.object | ||
}; | ||
|
||
export default RepoModal; |
24 changes: 24 additions & 0 deletions
24
src/components/InventoryGroups/Modals/ModalSchemas/schemes.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import validatorTypes from '@data-driven-forms/react-form-renderer/validator-types'; | ||
import componentTypes from '@data-driven-forms/react-form-renderer/component-types'; | ||
import { nameValidator } from '../../helpers/validate'; | ||
|
||
export const createGroupSchema = (namePresenceValidator) => ({ | ||
fields: [ | ||
{ | ||
component: componentTypes.TEXT_FIELD, | ||
name: 'name', | ||
label: 'Group name', | ||
helperText: | ||
'Can only contain letters, numbers, spaces, hyphens ( - ), and underscores( _ ).', | ||
isRequired: true, | ||
autoFocus: true, | ||
validate: [ | ||
// async validator has to be first in the list | ||
namePresenceValidator, | ||
{ type: validatorTypes.REQUIRED }, | ||
{ type: validatorTypes.MAX_LENGTH, threshold: 50 }, | ||
nameValidator | ||
] | ||
} | ||
] | ||
}); |
Oops, something went wrong.