Skip to content

Commit

Permalink
fix: cannot stop importing images MAASENG-2864 (#5351)
Browse files Browse the repository at this point in the history
  • Loading branch information
petermakowski authored Mar 15, 2024
1 parent 064adb5 commit 2384eb4
Show file tree
Hide file tree
Showing 10 changed files with 97 additions and 8 deletions.
2 changes: 2 additions & 0 deletions src/app/base/components/FormikForm/FormikForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ const FormikForm = <V extends object, E = null>({
submitDisabled,
submitLabel,
"aria-label": ariaLabel,
buttonsBehavior = "coupled",
...formikProps
}: Props<V, E>): JSX.Element => {
return (
Expand All @@ -53,6 +54,7 @@ const FormikForm = <V extends object, E = null>({
allowAllEmpty={allowAllEmpty}
allowUnchanged={allowUnchanged}
aria-label={ariaLabel}
buttonsBehavior={buttonsBehavior}
buttonsClassName={buttonsClassName}
buttonsHelp={buttonsHelp}
buttonsHelpClassName={buttonsHelpClassName}
Expand Down
13 changes: 12 additions & 1 deletion src/app/base/components/FormikFormButtons/FormikFormButtons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ export type Props<V> = {
submitAppearance?: ActionButtonProps["appearance"];
submitDisabled?: boolean;
submitLabel?: string;
/**
* Determines the behavior of the primary and secondary submit buttons.
* - "coupled" (default): The secondary submit button is disabled if the primary submit button is disabled.
* - "independent": The secondary submit button's disabled state is controlled independently.
*/
buttonsBehavior?: "coupled" | "independent";
};

export enum TestIds {
Expand Down Expand Up @@ -62,6 +68,7 @@ export const FormikFormButtons = <V,>({
submitAppearance = "positive",
submitDisabled,
submitLabel = "Save",
buttonsBehavior = "coupled",
}: Props<V>): JSX.Element => {
const formikContext = useFormikContext<V>();
const { values } = formikContext;
Expand All @@ -77,7 +84,11 @@ export const FormikFormButtons = <V,>({
<Button
className="formik-form-buttons__button"
data-testid={TestIds.SecondarySubmit}
disabled={secondarySubmitDisabled || submitDisabled}
disabled={
buttonsBehavior === "coupled"
? secondarySubmitDisabled || submitDisabled
: secondarySubmitDisabled
}
onClick={
secondarySubmit
? () => secondarySubmit(values, formikContext)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ const FormikFormContent = <V extends object, E = null>({
saving,
submitDisabled,
"aria-label": ariaLabel,
buttonsBehavior = "coupled",
...buttonsProps
}: Props<V, E>): JSX.Element => {
const formikContext = useFormikContext<V>();
Expand Down Expand Up @@ -191,6 +192,7 @@ const FormikFormContent = <V extends object, E = null>({
{editable && (
<FormikFormButtons
{...buttonsProps}
buttonsBehavior={buttonsBehavior}
cancelDisabled={cancelDisabled === false ? false : saving}
inline={inline}
saved={saved}
Expand Down
1 change: 1 addition & 0 deletions src/app/images/components/ImagesTable/ImagesTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ const generateImageRow = (
},
{ content: image.arch, className: "arch-col" },
{ content: "—", className: "size-col" },
{ content: "—", className: "diskless-col" },
{
content: (
<DoubleRow
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
bootResource as bootResourceFactory,
bootResourceOtherImage as otherImageFactory,
bootResourceState as bootResourceStateFactory,
bootResourceStatuses as bootResourceStatusesFactory,
rootState as rootStateFactory,
} from "@/testing/factories";
import {
Expand Down Expand Up @@ -116,6 +117,21 @@ describe("OtherImages", () => {
).not.toBeInTheDocument();
});

it("enables 'Stop import' button if images are saving", async () => {
const otherImages = [otherImageFactory()];
const state = rootStateFactory({
bootresource: bootResourceStateFactory({
otherImages,
statuses: bootResourceStatusesFactory({ savingOther: true }),
}),
});
renderWithBrowserRouter(<OtherImages />, { state });
const stopImportButton = screen.getByRole("button", {
name: OtherImagesLabels.StopImport,
});
expect(stopImportButton).toBeEnabled();
});

it(`can dispatch an action to stop importing other images if at least one is
downloading`, async () => {
const state = rootStateFactory({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ const OtherImages = (): JSX.Element | null => {
return images;
}, []);
const imagesDownloading = resources.some((resource) => resource.downloading);
const canStopImport = imagesDownloading && !stoppingImport;
const canStopImport = (saving || imagesDownloading) && !stoppingImport;

return (
<>
Expand All @@ -94,6 +94,7 @@ const OtherImages = (): JSX.Element | null => {
<h4>{Labels.OtherImages}</h4>
<FormikForm<OtherImagesValues>
allowUnchanged
buttonsBehavior="independent"
cleanup={cleanup}
enableReinitialize
errors={error}
Expand All @@ -120,7 +121,14 @@ const OtherImages = (): JSX.Element | null => {
dispatch(cleanup());
dispatch(bootResourceActions.stopImport());
}}
secondarySubmitLabel={canStopImport ? Labels.StopImport : null}
secondarySubmitDisabled={stoppingImport}
secondarySubmitLabel={
canStopImport
? stoppingImport
? "Stopping image import..."
: Labels.StopImport
: null
}
submitLabel={Labels.SubmitLabel}
validationSchema={OtherImagesSchema}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
bootResource as bootResourceFactory,
bootResourceUbuntuCoreImage as ubuntuCoreImageFactory,
bootResourceState as bootResourceStateFactory,
bootResourceStatuses as bootResourceStatusesFactory,
rootState as rootStateFactory,
} from "@/testing/factories";
import {
Expand Down Expand Up @@ -147,6 +148,20 @@ describe("UbuntuCoreImages", () => {
).not.toBeInTheDocument();
});

it("enables 'Stop import' button if images are saving", async () => {
const state = rootStateFactory({
bootresource: bootResourceStateFactory({
ubuntuCoreImages: [ubuntuCoreImageFactory()],
statuses: bootResourceStatusesFactory({ savingUbuntuCore: true }),
}),
});
renderWithBrowserRouter(<UbuntuCoreImages />, { state });
const stopImportButton = screen.getByRole("button", {
name: UbuntuCoreImagesLabels.StopImport,
});
expect(stopImportButton).toBeEnabled();
});

it(`can dispatch an action to stop importing Ubuntu core images if at least
one is downloading`, async () => {
const state = rootStateFactory({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ const UbuntuCoreImages = (): JSX.Element | null => {
return images;
}, []);
const imagesDownloading = resources.some((resource) => resource.downloading);
const canStopImport = imagesDownloading && !stoppingImport;
const canStopImport = (saving || imagesDownloading) && !stoppingImport;

return (
<>
Expand All @@ -94,6 +94,7 @@ const UbuntuCoreImages = (): JSX.Element | null => {
<h4>{Labels.CoreImages}</h4>
<FormikForm<UbuntuCoreImagesValues>
allowUnchanged
buttonsBehavior="independent"
cleanup={cleanup}
enableReinitialize
errors={error}
Expand All @@ -120,7 +121,14 @@ const UbuntuCoreImages = (): JSX.Element | null => {
dispatch(cleanup());
dispatch(bootResourceActions.stopImport());
}}
secondarySubmitLabel={canStopImport ? Labels.StopImport : null}
secondarySubmitDisabled={stoppingImport}
secondarySubmitLabel={
canStopImport
? stoppingImport
? "Stopping image import..."
: Labels.StopImport
: null
}
submitLabel={Labels.SubmitLabel}
validationSchema={UbuntuCoreImagesSchema}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import type { RootState } from "@/app/store/root/types";
import {
bootResource as bootResourceFactory,
bootResourceState as bootResourceStateFactory,
bootResourceStatuses as bootResourceStatusesFactory,
bootResourceUbuntu as bootResourceUbuntuFactory,
bootResourceUbuntuArch as bootResourceUbuntuArchFactory,
bootResourceUbuntuRelease as bootResourceUbuntuReleaseFactory,
Expand Down Expand Up @@ -229,6 +230,24 @@ describe("UbuntuImages", () => {
).toStrictEqual(expectedAction);
});

it("enables 'Stop import' button if images are saving", async () => {
const source = sourceFactory();
const state = rootStateFactory({
bootresource: bootResourceStateFactory({
resources: [
bootResourceFactory({ downloading: true, name: "ubuntu/focal" }),
],
ubuntu: bootResourceUbuntuFactory(),
statuses: bootResourceStatusesFactory({ savingUbuntu: true }),
}),
});
renderWithBrowserRouter(<UbuntuImages sources={[source]} />, { state });
const stopImportButton = screen.getByRole("button", {
name: UbuntuImagesLabels.StopImport,
});
expect(stopImportButton).toBeEnabled();
});

it("disables form with a notification if more than one source detected", () => {
const sources = [sourceFactory(), sourceFactory()];
const state = rootStateFactory({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ const UbuntuImages = ({ sources }: Props): JSX.Element | null => {
return images;
}, []);
const imagesDownloading = resources.some((resource) => resource.downloading);
const canStopImport = imagesDownloading && !stoppingImport;
const canStopImport = (saving || imagesDownloading) && !stoppingImport;
const mainSource = sources.length > 0 ? sources[0] : null;
const tooManySources = sources.length > 1;

Expand All @@ -102,6 +102,7 @@ const UbuntuImages = ({ sources }: Props): JSX.Element | null => {
<Strip shallow>
<FormikForm<UbuntuImagesValues>
allowUnchanged
buttonsBehavior="independent"
cleanup={cleanup}
editable={!tooManySources}
enableReinitialize
Expand Down Expand Up @@ -146,12 +147,18 @@ const UbuntuImages = ({ sources }: Props): JSX.Element | null => {
}}
saved={saved}
saving={saving || stoppingImport}
savingLabel={stoppingImport ? "Stopping image import..." : null}
secondarySubmit={() => {
dispatch(cleanup());
dispatch(bootResourceActions.stopImport());
}}
secondarySubmitLabel={canStopImport ? Labels.StopImport : null}
secondarySubmitDisabled={stoppingImport}
secondarySubmitLabel={
canStopImport
? stoppingImport
? "Stopping image import..."
: Labels.StopImport
: null
}
submitLabel={Labels.SubmitLabel}
validationSchema={UbuntuImagesSchema}
>
Expand Down

0 comments on commit 2384eb4

Please sign in to comment.