mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[Data Views] Show loading indicators when submitting a data view form to prevent multiple requests (#150576)
Closes https://github.com/elastic/kibana/issues/146125 This PR adds loading indicators to the form buttons and also disables them when submitting the form. * Creating an ad-hoc data view  * Editing an ad-hoc data view  * Creating a persisted data view  * Editing a persisted data view 
This commit is contained in:
parent
f399dd094e
commit
a6073e8458
6 changed files with 83 additions and 30 deletions
|
@ -15,31 +15,39 @@ interface EditDataViewDeps {
|
|||
onEdit: () => void;
|
||||
}
|
||||
|
||||
export const editDataViewModal = ({ dataViewName, overlays, onEdit }: EditDataViewDeps) =>
|
||||
overlays &&
|
||||
export const editDataViewModal = ({
|
||||
dataViewName,
|
||||
overlays,
|
||||
onEdit,
|
||||
}: EditDataViewDeps): Promise<void> =>
|
||||
overlays
|
||||
.openConfirm(
|
||||
i18n.translate('indexPatternEditor.editDataView.editConfirmationModal.modalDescription', {
|
||||
defaultMessage: 'Changing this data view can break other objects that depend on it.',
|
||||
}),
|
||||
{
|
||||
confirmButtonText: i18n.translate(
|
||||
'indexPatternEditor.editDataView.editConfirmationModal.confirmButton',
|
||||
? overlays
|
||||
.openConfirm(
|
||||
i18n.translate('indexPatternEditor.editDataView.editConfirmationModal.modalDescription', {
|
||||
defaultMessage: 'Changing this data view can break other objects that depend on it.',
|
||||
}),
|
||||
{
|
||||
defaultMessage: 'Confirm',
|
||||
confirmButtonText: i18n.translate(
|
||||
'indexPatternEditor.editDataView.editConfirmationModal.confirmButton',
|
||||
{
|
||||
defaultMessage: 'Confirm',
|
||||
}
|
||||
),
|
||||
title: i18n.translate(
|
||||
'indexPatternEditor.editDataView.editConfirmationModal.editHeader',
|
||||
{
|
||||
defaultMessage: `Edit '{name}'`,
|
||||
values: {
|
||||
name: dataViewName,
|
||||
},
|
||||
}
|
||||
),
|
||||
buttonColor: 'danger',
|
||||
}
|
||||
),
|
||||
title: i18n.translate('indexPatternEditor.editDataView.editConfirmationModal.editHeader', {
|
||||
defaultMessage: `Edit '{name}'`,
|
||||
values: {
|
||||
name: dataViewName,
|
||||
},
|
||||
}),
|
||||
buttonColor: 'danger',
|
||||
}
|
||||
)
|
||||
.then(async (isConfirmed) => {
|
||||
if (isConfirmed) {
|
||||
onEdit();
|
||||
}
|
||||
});
|
||||
)
|
||||
.then(async (isConfirmed) => {
|
||||
if (isConfirmed) {
|
||||
await onEdit();
|
||||
}
|
||||
})
|
||||
: Promise.resolve();
|
||||
|
|
|
@ -48,6 +48,7 @@ import {
|
|||
NameField,
|
||||
schema,
|
||||
Footer,
|
||||
SubmittingType,
|
||||
AdvancedParamsContent,
|
||||
PreviewPanel,
|
||||
RollupBetaWarning,
|
||||
|
@ -136,7 +137,7 @@ const IndexPatternEditorFlyoutContentComponent = ({
|
|||
}
|
||||
|
||||
if (editData && editData.getIndexPattern() !== formData.title) {
|
||||
editDataViewModal({
|
||||
await editDataViewModal({
|
||||
dataViewName: formData.name || formData.title,
|
||||
overlays,
|
||||
onEdit: async () => {
|
||||
|
@ -301,7 +302,14 @@ const IndexPatternEditorFlyoutContentComponent = ({
|
|||
form.setFieldValue('isAdHoc', adhoc || false);
|
||||
form.submit();
|
||||
}}
|
||||
submitDisabled={form.isSubmitted && !form.isValid}
|
||||
submitDisabled={(form.isSubmitted && !form.isValid) || form.isSubmitting}
|
||||
submittingType={
|
||||
form.isSubmitting
|
||||
? form.getFormData().isAdHoc
|
||||
? SubmittingType.savingAsAdHoc
|
||||
: SubmittingType.persisting
|
||||
: undefined
|
||||
}
|
||||
isEdit={!!editData}
|
||||
isPersisted={Boolean(editData && editData.isPersisted())}
|
||||
allowAdHoc={allowAdHoc}
|
||||
|
|
|
@ -17,9 +17,15 @@ import {
|
|||
EuiButton,
|
||||
} from '@elastic/eui';
|
||||
|
||||
export enum SubmittingType {
|
||||
savingAsAdHoc = 'savingAsAdHoc',
|
||||
persisting = 'persisting',
|
||||
}
|
||||
|
||||
interface FooterProps {
|
||||
onCancel: () => void;
|
||||
onSubmit: (isAdHoc?: boolean) => void;
|
||||
submittingType: SubmittingType | undefined;
|
||||
submitDisabled: boolean;
|
||||
isEdit: boolean;
|
||||
isPersisted: boolean;
|
||||
|
@ -53,12 +59,14 @@ const exploreButtonLabel = i18n.translate('indexPatternEditor.editor.flyoutExplo
|
|||
export const Footer = ({
|
||||
onCancel,
|
||||
onSubmit,
|
||||
submittingType,
|
||||
submitDisabled,
|
||||
isEdit,
|
||||
allowAdHoc,
|
||||
isPersisted,
|
||||
canSave,
|
||||
}: FooterProps) => {
|
||||
const isEditingAdHoc = isEdit && !isPersisted;
|
||||
const submitPersisted = () => {
|
||||
onSubmit(false);
|
||||
};
|
||||
|
@ -89,6 +97,7 @@ export const Footer = ({
|
|||
onClick={submitAdHoc}
|
||||
data-test-subj="exploreIndexPatternButton"
|
||||
disabled={submitDisabled}
|
||||
isLoading={submittingType === SubmittingType.savingAsAdHoc}
|
||||
title={i18n.translate('indexPatternEditor.editor.flyoutExploreButtonTitle', {
|
||||
defaultMessage: 'Use this data view without creating a saved object',
|
||||
})}
|
||||
|
@ -98,7 +107,7 @@ export const Footer = ({
|
|||
</EuiFlexItem>
|
||||
)}
|
||||
|
||||
{(canSave || (isEdit && !isPersisted)) && (
|
||||
{(canSave || isEditingAdHoc) && (
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButton
|
||||
color="primary"
|
||||
|
@ -106,6 +115,10 @@ export const Footer = ({
|
|||
data-test-subj="saveIndexPatternButton"
|
||||
fill
|
||||
disabled={submitDisabled}
|
||||
isLoading={
|
||||
submittingType === SubmittingType.persisting ||
|
||||
(submittingType === SubmittingType.savingAsAdHoc && isEditingAdHoc)
|
||||
}
|
||||
>
|
||||
{isEdit
|
||||
? isPersisted
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export { Footer } from './footer';
|
||||
export { Footer, SubmittingType } from './footer';
|
||||
|
|
|
@ -15,6 +15,6 @@ export { schema } from './form_schema';
|
|||
export { NameField, TimestampField, TypeField, TitleField } from './form_fields';
|
||||
export { PreviewPanel } from './preview_panel';
|
||||
export { LoadingIndices } from './loading_indices';
|
||||
export { Footer } from './footer';
|
||||
export { Footer, SubmittingType } from './footer';
|
||||
export { AdvancedParamsContent } from './advanced_params_content';
|
||||
export { RollupBetaWarning } from './rollup_beta_warning';
|
||||
|
|
|
@ -186,6 +186,30 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
expect(await testSubjects.exists('field-name-agent')).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
it('should disable Save button after pressing', async function () {
|
||||
await PageObjects.settings.clickEditIndexButton();
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
|
||||
await retry.try(async () => {
|
||||
await PageObjects.settings.setIndexPatternField('logs*');
|
||||
});
|
||||
await PageObjects.settings.selectTimeFieldOption('@timestamp');
|
||||
|
||||
expect(await testSubjects.isEnabled('saveIndexPatternButton')).to.be(true);
|
||||
await (await PageObjects.settings.getSaveDataViewButtonActive()).click();
|
||||
|
||||
// wait for the confirmation modal to open
|
||||
await retry.waitFor('confirmation modal', async () => {
|
||||
return await testSubjects.exists('confirmModalConfirmButton');
|
||||
});
|
||||
|
||||
// while the confirmation modal is open, we can check that the form button has actually become disabled
|
||||
expect(await testSubjects.isEnabled('saveIndexPatternButton')).to.be(false);
|
||||
|
||||
await testSubjects.click('confirmModalConfirmButton');
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
});
|
||||
});
|
||||
|
||||
describe('index pattern deletion', function indexDelete() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue