Skip to content

Commit

Permalink
🐛 Decouple form actions from ApplicationForm
Browse files Browse the repository at this point in the history
Split ApplicationForm into a data hook and view component.
Use extracted submit and cancel actions inside Modal's footer.

Signed-off-by: Radoslaw Szwajkowski <[email protected]>
  • Loading branch information
rszwajko committed Mar 14, 2024
1 parent c2ef03c commit fd48938
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ import { useFetchTagsWithTagItems } from "@app/queries/tags";
// Relative components
import { ApplicationAssessmentStatus } from "../components/application-assessment-status";
import { ApplicationBusinessService } from "../components/application-business-service";
import { ApplicationForm } from "../components/application-form";
import { ImportApplicationsForm } from "../components/import-applications-form";
import { ConditionalRender } from "@app/components/ConditionalRender";
import { NoDataEmptyState } from "@app/components/NoDataEmptyState";
Expand All @@ -108,6 +107,7 @@ import { ApplicationIdentityForm } from "../components/application-identity-form
import { ApplicationReviewStatus } from "../components/application-review-status/application-review-status";
import { KebabDropdown } from "@app/components/KebabDropdown";
import { useFetchArchetypes } from "@app/queries/archetypes";
import { ApplicationFormModal } from "../components/application-form/application-form-modal";

export const ApplicationsTable: React.FC = () => {
const { t } = useTranslation();
Expand Down Expand Up @@ -1105,21 +1105,11 @@ export const ApplicationsTable: React.FC = () => {
/>
)}
</Modal>
<Modal
title={
createUpdateApplications
? t("dialog.title.updateApplication")
: t("dialog.title.newApplication")
}
variant="medium"
isOpen={isCreateUpdateApplicationsModalOpen}
<ApplicationFormModal
application={createUpdateApplications}
onClose={() => setSaveApplicationModalState(null)}
>
<ApplicationForm
application={createUpdateApplications}
onClose={() => setSaveApplicationModalState(null)}
/>
</Modal>
isOpen={isCreateUpdateApplicationsModalOpen}
/>
<SimpleDocumentViewerModal
title={`Analysis details for ${taskToView?.name}`}
documentId={taskToView?.task}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
TAG_CATEGORIES,
} from "@app/api/rest";
import mock from "@app/test-config/mockInstance";
import { ApplicationForm } from "../application-form";
import { ApplicationFormStandalone } from "../application-form";
import userEvent from "@testing-library/user-event";

import "@testing-library/jest-dom/extend-expect";
Expand All @@ -34,7 +34,9 @@ describe("Component: application-form", () => {

mock.onGet(`${BUSINESS_SERVICES}`).reply(200, businessServices);

render(<ApplicationForm application={null} onClose={mockChangeValue} />);
render(
<ApplicationFormStandalone application={null} onClose={mockChangeValue} />
);
const nameInput = await screen.findByLabelText("Name *");
fireEvent.change(nameInput, {
target: { value: "app-name" },
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import * as React from "react";
import { Button, ButtonVariant, Modal } from "@patternfly/react-core";
import { ApplicationForm, useApplicationFormHook } from "./application-form";
import { Application } from "@app/api/models";
import { useTranslation } from "react-i18next";

export interface ApplicationFormModalProps {
application: Application | null;
onClose: () => void;
isOpen: boolean;
}

export const ApplicationFormModal: React.FC<ApplicationFormModalProps> = ({
application,
onClose,
isOpen,
}) => {
const { t } = useTranslation();
const formProps = useApplicationFormHook({ application, onClose });
return (
<Modal
title={
application
? t("dialog.title.updateApplication")
: t("dialog.title.newApplication")
}
variant="medium"
isOpen={isOpen}
onClose={onClose}
actions={[
<Button
key="submit"
id="submit"
aria-label="submit"
variant={ButtonVariant.primary}
isDisabled={formProps.isSubmitDisabled}
onClick={formProps.onSubmit}
>
{!application ? t("actions.create") : t("actions.save")}
</Button>,
<Button
key="cancel"
id="cancel"
aria-label="cancel"
variant={ButtonVariant.link}
isDisabled={formProps.isCancelDisabled}
onClick={onClose}
>
{t("actions.cancel")}
</Button>,
]}
>
<ApplicationForm
{...formProps}
application={application}
onClose={onClose}
/>
</Modal>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,10 @@ export interface ApplicationFormProps {
onClose: () => void;
}

export const ApplicationForm: React.FC<ApplicationFormProps> = ({
export const useApplicationFormHook = ({
application,
onClose,
}) => {
}: ApplicationFormProps) => {
const { t } = useTranslation();
const {
existingApplications,
Expand Down Expand Up @@ -316,9 +316,64 @@ export const ApplicationForm: React.FC<ApplicationFormProps> = ({
toString: () => `Subversion`,
},
];
return {
handleSubmit,
onValidSubmit,
setBasicExpanded,
isBasicExpanded,
control,
tagItems,
stakeholdersOptions,
setSourceCodeExpanded,
isSourceCodeExpanded,
kindOptions,
setBinaryExpanded,
isBinaryExpanded,
isSubmitDisabled: !isValid || isSubmitting || isValidating || !isDirty,
isCancelDisabled: isSubmitting || isValidating,
stakeholders,
businessServiceOptions,
onSubmit: () => handleSubmit(onValidSubmit),
};
};

export const ApplicationFormStandalone: React.FC<ApplicationFormProps> = (
props
) => (
<ApplicationForm
{...props}
showFormButtons={true}
{...useApplicationFormHook(props)}
/>
);

export const ApplicationForm: React.FC<
ReturnType<typeof useApplicationFormHook> & {
showFormButtons?: boolean;
} & ApplicationFormProps
> = ({
onSubmit,
setBasicExpanded,
isBasicExpanded,
control,
tagItems,
stakeholdersOptions,
setSourceCodeExpanded,
isSourceCodeExpanded,
kindOptions,
setBinaryExpanded,
isBinaryExpanded,
isSubmitDisabled,
isCancelDisabled,
stakeholders,
businessServiceOptions,
showFormButtons = false,
application,
onClose,
}) => {
const { t } = useTranslation();
return (
<Form onSubmit={handleSubmit(onValidSubmit)}>
<Form onSubmit={onSubmit}>
<ExpandableSection
toggleText={"Basic information"}
className="toggle"
Expand Down Expand Up @@ -623,27 +678,29 @@ export const ApplicationForm: React.FC<ApplicationFormProps> = ({
/>
</div>
</ExpandableSection>
<ActionGroup>
<Button
type="submit"
id="submit"
aria-label="submit"
variant={ButtonVariant.primary}
isDisabled={!isValid || isSubmitting || isValidating || !isDirty}
>
{!application ? t("actions.create") : t("actions.save")}
</Button>
<Button
type="button"
id="cancel"
aria-label="cancel"
variant={ButtonVariant.link}
isDisabled={isSubmitting || isValidating}
onClick={onClose}
>
{t("actions.cancel")}
</Button>
</ActionGroup>
{showFormButtons && (
<ActionGroup>
<Button
type="submit"
id="submit"
aria-label="submit"
variant={ButtonVariant.primary}
isDisabled={isSubmitDisabled}
>
{!application ? t("actions.create") : t("actions.save")}
</Button>
<Button
type="button"
id="cancel"
aria-label="cancel"
variant={ButtonVariant.link}
isDisabled={isCancelDisabled}
onClick={onClose}
>
{t("actions.cancel")}
</Button>
</ActionGroup>
)}
</Form>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { ApplicationForm } from "./application-form";
export { ApplicationFormStandalone as ApplicationForm } from "./application-form";

0 comments on commit fd48938

Please sign in to comment.