Disable footer keys when saving
To prevent double clicks on saving, disable the submit/save keys on the DeveloperKey modal for both api and lti keys. closes PLAT-3913 Test Plan: - Create an lti key and attempt to save right away, note that the button becomes disabled until it returns saying that the json was invalid - Create a valid tool config and press save, note that the save button disables until the next screen appears and reenables at that time - Save the customizations and note the same thing until the modal closes - do the same with an api key and note that saving disables the button until closes - also open the modal for each type and refresh teh page, note that it takes you back to the page with the modal open Change-Id: Id1d1a2a2baa6fe00b2dafb406eec25040540b84c Reviewed-on: https://gerrit.instructure.com/171481 Tested-by: Jenkins Reviewed-by: Weston Dransfield <wdransfield@instructure.com> QA-Review: Weston Dransfield <wdransfield@instructure.com> Product-Review: Marc Phillips <mphillips@instructure.com>
This commit is contained in:
parent
d3cd41bda0
commit
07132b9f92
|
@ -44,7 +44,7 @@ export default class LtiKeyFooter extends React.Component {
|
|||
const buttonText = customizing ? I18n.t('Save Customizations') : I18n.t('Save and Customize')
|
||||
|
||||
return (
|
||||
<Button onClick={clickHandler} variant="primary">
|
||||
<Button onClick={clickHandler} variant="primary" disabled={this.props.disable}>
|
||||
{buttonText}
|
||||
</Button>
|
||||
)
|
||||
|
@ -67,5 +67,6 @@ LtiKeyFooter.propTypes = {
|
|||
onCancelClick: PropTypes.func.isRequired,
|
||||
onSaveClick: PropTypes.func.isRequired,
|
||||
onAdvanceToCustomization: PropTypes.func.isRequired,
|
||||
customizing: PropTypes.bool.isRequired
|
||||
customizing: PropTypes.bool.isRequired,
|
||||
disable: PropTypes.bool
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ const NewKeyFooter = props => {
|
|||
return (
|
||||
<ModalFooter>
|
||||
<Button onClick={props.onCancelClick}>{I18n.t('Cancel')}</Button>
|
||||
<Button onClick={props.onSaveClick} variant="primary">
|
||||
<Button onClick={props.onSaveClick} variant="primary" disabled={props.disable}>
|
||||
{I18n.t('Save Key')}
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
|
@ -36,7 +36,8 @@ const NewKeyFooter = props => {
|
|||
|
||||
NewKeyFooter.propTypes = {
|
||||
onCancelClick: PropTypes.func.isRequired,
|
||||
onSaveClick: PropTypes.func.isRequired
|
||||
onSaveClick: PropTypes.func.isRequired,
|
||||
disable: PropTypes.bool
|
||||
}
|
||||
|
||||
export default NewKeyFooter
|
||||
|
|
|
@ -129,12 +129,12 @@ export default class DeveloperKeyModal extends React.Component {
|
|||
return this.props.createLtiKeyState.isLtiKey
|
||||
}
|
||||
|
||||
get isSaving() {
|
||||
return this.props.createOrEditDeveloperKeyState.developerKeyCreateOrEditPending || this.props.createLtiKeyState.saveToolConfigurationPending
|
||||
}
|
||||
|
||||
modalBody() {
|
||||
const isSavingDeveloperKey = this.props.createOrEditDeveloperKeyState.developerKeyCreateOrEditPending
|
||||
const isSavingLtiToolConfig = this.props.createLtiKeyState.saveToolConfigurationPending
|
||||
if (
|
||||
isSavingDeveloperKey || isSavingLtiToolConfig
|
||||
) {
|
||||
if (this.isSaving) {
|
||||
return this.spinner()
|
||||
}
|
||||
return this.developerKeyForm()
|
||||
|
@ -142,19 +142,22 @@ export default class DeveloperKeyModal extends React.Component {
|
|||
|
||||
modalFooter() {
|
||||
if (this.isLtiKey) {
|
||||
const { createLtiKeyState, store, actions } = this.props
|
||||
return(
|
||||
<LtiKeyFooter
|
||||
onCancelClick={this.closeModal}
|
||||
onSaveClick={this.saveCustomizations}
|
||||
onAdvanceToCustomization={this.saveLtiToolConfiguration}
|
||||
customizing={this.props.createLtiKeyState.customizing}
|
||||
ltiKeysSetCustomizing={this.props.actions.ltiKeysSetCustomizing}
|
||||
dispatch={this.props.store.dispatch}
|
||||
customizing={createLtiKeyState.customizing}
|
||||
disable={this.isSaving}
|
||||
ltiKeysSetCustomizing={actions.ltiKeysSetCustomizing}
|
||||
dispatch={store.dispatch}
|
||||
/>
|
||||
)
|
||||
}
|
||||
return(
|
||||
<NewKeyFooter
|
||||
disable={this.isSaving}
|
||||
onCancelClick={this.closeModal}
|
||||
onSaveClick={this.submitForm}
|
||||
/>
|
||||
|
|
|
@ -29,12 +29,12 @@ import PropTypes from 'prop-types'
|
|||
|
||||
export default class DeveloperKeyModalTrigger extends React.Component {
|
||||
showCreateDeveloperKey = () => {
|
||||
this.props.store.dispatch(this.props.actions.developerKeysModalOpen())
|
||||
this.props.store.dispatch(this.props.actions.developerKeysModalOpen('api'))
|
||||
}
|
||||
|
||||
showCreateLtiKey = () => {
|
||||
this.props.store.dispatch(this.props.actions.ltiKeysSetLtiKey(true))
|
||||
this.props.store.dispatch(this.props.actions.developerKeysModalOpen())
|
||||
this.props.store.dispatch(this.props.actions.developerKeysModalOpen('lti'))
|
||||
}
|
||||
|
||||
isLti13Enabled = ENV.LTI_1_3_ENABLED
|
||||
|
|
|
@ -76,3 +76,14 @@ it("Renders the 'Save' button if not customizing", () => {
|
|||
.text()
|
||||
).toEqual('Save Customizations')
|
||||
})
|
||||
|
||||
it("Disables the save button if disable is true", () => {
|
||||
wrapper = mount(<LtiKeyFooter {...newProps()} disable />)
|
||||
expect(
|
||||
wrapper
|
||||
.find('Button')
|
||||
.at(1)
|
||||
.props()
|
||||
.disabled
|
||||
).toEqual(true)
|
||||
})
|
||||
|
|
|
@ -181,8 +181,8 @@ actions.editDeveloperKey = payload => dispatch => {
|
|||
}
|
||||
|
||||
actions.DEVELOPER_KEYS_MODAL_OPEN = 'DEVELOPER_KEYS_MODAL_OPEN'
|
||||
actions.developerKeysModalOpen = () => {
|
||||
window.location.hash = "key_modal_opened"
|
||||
actions.developerKeysModalOpen = (type = 'api') => {
|
||||
window.location.hash = `${type}_key_modal_opened`
|
||||
return {type: actions.DEVELOPER_KEYS_MODAL_OPEN}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,11 +30,15 @@ let state = store.getState()
|
|||
*/
|
||||
// ctx is context
|
||||
function renderShowDeveloperKeys(ctx) {
|
||||
if (ctx.hash === 'key_modal_opened') {
|
||||
store.dispatch(actions.developerKeysModalOpen())
|
||||
if (ctx.hash === 'api_key_modal_opened') {
|
||||
store.dispatch(actions.developerKeysModalOpen('api'))
|
||||
} else if (ctx.hash === 'lti_key_modal_opened') {
|
||||
store.dispatch(actions.developerKeysModalOpen('lti'))
|
||||
store.dispatch(actions.ltiKeysSetLtiKey(true))
|
||||
} else {
|
||||
store.dispatch(actions.developerKeysModalClose())
|
||||
store.dispatch(actions.editDeveloperKey())
|
||||
store.dispatch(actions.ltiKeysSetLtiKey(false))
|
||||
}
|
||||
|
||||
if (!state.listDeveloperKeys.listDeveloperKeysSuccessful) {
|
||||
|
|
|
@ -400,7 +400,7 @@ describe 'Developer Keys' do
|
|||
end
|
||||
|
||||
it "opens the developer key modal when open modal anchor is present" do
|
||||
get "/accounts/#{Account.default.id}/developer_keys#key_modal_opened"
|
||||
get "/accounts/#{Account.default.id}/developer_keys#api_key_modal_opened"
|
||||
expect(find_button("Save Key")).to be_present
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue