Skip to content

Commit

Permalink
Add submitting lock for workspace create page
Browse files Browse the repository at this point in the history
Signed-off-by: Lin Wang <[email protected]>
  • Loading branch information
wanglam committed Aug 28, 2024
1 parent 2b51171 commit 4df837f
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ describe('WorkspaceCreateActionPanel', () => {
formId={formId}
formData={{ name: longName, description: formData.description }}
application={mockApplication}
isSubmitting={false}
/>
);
const createButton = screen.getByText('Create workspace');
Expand All @@ -40,6 +41,7 @@ describe('WorkspaceCreateActionPanel', () => {
formId={formId}
formData={{ name: formData.name, description: longDescription }}
application={mockApplication}
isSubmitting={false}
/>
);
const createButton = screen.getByText('Create workspace');
Expand All @@ -52,9 +54,23 @@ describe('WorkspaceCreateActionPanel', () => {
formId={formId}
formData={formData}
application={mockApplication}
isSubmitting={false}
/>
);
const createButton = screen.getByText('Create workspace');
expect(createButton.closest('button')).not.toBeDisabled();
});

it('should disable the "Create Workspace" and "Cancel" button when submitting', () => {
render(
<WorkspaceCreateActionPanel
formId={formId}
formData={{ name: 'test' }}
application={mockApplication}
isSubmitting
/>
);
expect(screen.getByText('Create workspace').closest('button')).toBeDisabled();
expect(screen.getByText('Cancel').closest('button')).toBeDisabled();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@ interface WorkspaceCreateActionPanelProps {
formId: string;
formData: Pick<WorkspaceFormDataState, 'name' | 'description'>;
application: ApplicationStart;
isSubmitting: boolean;
}

export const WorkspaceCreateActionPanel = ({
formId,
formData,
application,
isSubmitting,
}: WorkspaceCreateActionPanelProps) => {
const [isCancelModalVisible, setIsCancelModalVisible] = useState(false);
const closeCancelModal = useCallback(() => setIsCancelModalVisible(false), []);
Expand All @@ -38,6 +40,7 @@ export const WorkspaceCreateActionPanel = ({
<EuiSmallButtonEmpty
data-test-subj="workspaceForm-bottomBar-cancelButton"
onClick={showCancelModal}
disabled={isSubmitting}
>
{i18n.translate('workspace.form.right.sidebar.buttons.cancelText', {
defaultMessage: 'Cancel',
Expand All @@ -50,7 +53,8 @@ export const WorkspaceCreateActionPanel = ({
form={formId}
data-test-subj="workspaceForm-bottomBar-createButton"
fill
disabled={createButtonDisabled}
disabled={createButtonDisabled || isSubmitting}
isLoading={isSubmitting}
>
{i18n.translate('workspace.form.right.sidebar.buttons.createWorkspaceText', {
defaultMessage: 'Create workspace',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -344,4 +344,33 @@ describe('WorkspaceCreator', () => {
});
expect(notificationToastsAddDanger).not.toHaveBeenCalled();
});

it('should not create workspace API when submitting', async () => {
workspaceClientCreate.mockImplementationOnce(
() =>
new Promise((resolve) => {
setTimeout(resolve, 100);
})
);
const { getByTestId } = render(<WorkspaceCreator />);
// Ensure workspace create form rendered
await waitFor(() => {
expect(getByTestId('workspaceForm-bottomBar-createButton')).toBeInTheDocument();
});
const nameInput = getByTestId('workspaceForm-workspaceDetails-nameInputText');
fireEvent.input(nameInput, {
target: { value: 'test workspace name' },
});
fireEvent.click(getByTestId('workspaceUseCase-observability'));
fireEvent.click(getByTestId('workspaceForm-bottomBar-createButton'));
expect(workspaceClientCreate).toHaveBeenCalledTimes(1);

fireEvent.click(getByTestId('workspaceForm-bottomBar-createButton'));
expect(workspaceClientCreate).toHaveBeenCalledTimes(1);

await waitFor(() => {
fireEvent.click(getByTestId('workspaceForm-bottomBar-createButton'));
expect(workspaceClientCreate).toHaveBeenCalledTimes(2);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

import React, { useCallback } from 'react';
import React, { useCallback, useState } from 'react';
import { EuiPage, EuiPageBody, EuiPageContent, euiPaletteColorBlind } from '@elastic/eui';
import { i18n } from '@osd/i18n';
import { BehaviorSubject } from 'rxjs';
Expand Down Expand Up @@ -43,6 +43,7 @@ export const WorkspaceCreator = (props: WorkspaceCreatorProps) => {
dataSourceManagement?: DataSourceManagementPluginSetup;
navigationUI: NavigationPublicPluginStart['ui'];
}>();
const [isFormSubmitting, setIsFormSubmitting] = useState(false);

const isPermissionEnabled = application?.capabilities.workspaces.permissionEnabled;
const { isOnlyAllowEssential, availableUseCases } = useFormAvailableUseCases({
Expand All @@ -65,6 +66,10 @@ export const WorkspaceCreator = (props: WorkspaceCreatorProps) => {
const handleWorkspaceFormSubmit = useCallback(
async (data: WorkspaceFormSubmitData) => {
let result;
if (isFormSubmitting) {
return;
}
setIsFormSubmitting(true);
try {
const { permissionSettings, selectedDataSources, ...attributes } = data;
const selectedDataSourceIds = (selectedDataSources ?? []).map((ds: DataSource) => {
Expand Down Expand Up @@ -105,9 +110,11 @@ export const WorkspaceCreator = (props: WorkspaceCreatorProps) => {
text: error instanceof Error ? error.message : JSON.stringify(error),
});
return;
} finally {
setIsFormSubmitting(false);
}
},
[notifications?.toasts, http, application, workspaceClient]
[notifications?.toasts, http, application, workspaceClient, isFormSubmitting]
);

const isFormReadyToRender =
Expand Down Expand Up @@ -146,6 +153,7 @@ export const WorkspaceCreator = (props: WorkspaceCreatorProps) => {
dataSourceManagement={dataSourceManagement}
availableUseCases={availableUseCases}
defaultValues={defaultWorkspaceFormValues}
isSubmitting={isFormSubmitting}
/>
)}
</EuiPageContent>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const setup = (

return render(
<WorkspaceCreatorForm
isSubmitting={false}
application={application}
savedObjects={savedObjects}
operationType={WorkspaceOperationType.Create}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,11 @@ import { generateRightSidebarScrollProps, RightSidebarScrollField } from './util

import './workspace_creator_form.scss';

export const WorkspaceCreatorForm = (props: WorkspaceFormProps) => {
interface WorkspaceCreatorFormProps extends WorkspaceFormProps {
isSubmitting: boolean;
}

export const WorkspaceCreatorForm = (props: WorkspaceCreatorFormProps) => {
const {
application,
savedObjects,
Expand Down Expand Up @@ -217,6 +221,7 @@ export const WorkspaceCreatorForm = (props: WorkspaceFormProps) => {
formData={formData}
formId={formId}
application={application}
isSubmitting={props.isSubmitting}
/>
</div>
</div>
Expand Down

0 comments on commit 4df837f

Please sign in to comment.