Skip to content

Commit

Permalink
🐛 Convert assessment wizard to modal (#1486)
Browse files Browse the repository at this point in the history
- https://issues.redhat.com/browse/MTA-1437 
- https://issues.redhat.com/browse/MTA-1467
Resolves loading state for slow connections & moves the assessment
wizard to a modal to simplify code & improve UX. This was approved by
Justin from UXD.

---------

Signed-off-by: ibolton336 <[email protected]>
  • Loading branch information
ibolton336 authored Oct 27, 2023
1 parent 4624f4d commit 6179d70
Show file tree
Hide file tree
Showing 8 changed files with 157 additions and 214 deletions.
3 changes: 2 additions & 1 deletion client/public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@
"maxfileSize": "Max file size of 1MB exceeded. Upload a smaller file.",
"dragAndDropFile": "Drag and drop your file here or upload one.",
"uploadYamlFile": "Upload your YAML file",
"deleteQuestionnaire": "Deleting a questionnaire will cascade into the deletion of all answered questionnaires associated to applications and/or archetypes.",
"deleteQuestionnire": "Deleting a questionnaire will cascade into the deletion of all answered questionnaires associated to applications and/or archetypes.",
"confirmDeletion": "Confirm deletion by typing <1>{{nameToDelete}}</1> below:"
},
"title": {
Expand All @@ -122,6 +122,7 @@
"importApplicationFile": "Import application file",
"import": "Import {{what}}",
"leavePage": "Leave page",
"leaveAssessment": "Leave assessment",
"new": "New {{what}}",
"newArchetype": "Create new archetype",
"newAssessment": "New assessment",
Expand Down
11 changes: 0 additions & 11 deletions client/src/app/Routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import { ErrorBoundary } from "react-error-boundary";
import { ErrorFallback } from "@app/components/ErrorFallback";
import { FEATURES_ENABLED } from "./FeatureFlags";

const Assessment = lazy(() => import("./pages/assessment/assessment-page"));
const Review = lazy(() => import("./pages/review/review-page"));
const AssessmentSettings = lazy(
() =>
Expand Down Expand Up @@ -80,16 +79,6 @@ export const devRoutes: IRoute[] = [
comp: ManageImports,
exact: false,
},
{
path: Paths.archetypesAssessment,
comp: Assessment,
exact: false,
},
{
path: Paths.applicationsAssessment,
comp: Assessment,
exact: false,
},
{
path: Paths.archetypeReview,
comp: Review,
Expand Down
73 changes: 0 additions & 73 deletions client/src/app/pages/assessment/assessment-page.tsx

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
useCreateAssessmentMutation,
useDeleteAssessmentMutation,
} from "@app/queries/assessments";
import { Button } from "@patternfly/react-core";
import { Button, Spinner } from "@patternfly/react-core";
import React, { FunctionComponent } from "react";
import { useHistory } from "react-router-dom";
import "./dynamic-assessment-actions-row.css";
Expand All @@ -20,7 +20,11 @@ import { formatPath, getAxiosErrorMessage } from "@app/utils/utils";
import { Td } from "@patternfly/react-table";
import { NotificationsContext } from "@app/components/NotificationsContext";
import { useTranslation } from "react-i18next";
import { useQueryClient } from "@tanstack/react-query";
import {
useIsFetching,
useIsMutating,
useQueryClient,
} from "@tanstack/react-query";
import { TrashIcon } from "@patternfly/react-icons";
import useIsArchetype from "@app/hooks/useIsArchetype";

Expand All @@ -36,11 +40,19 @@ interface DynamicAssessmentActionsRowProps {
archetype?: Archetype;
assessment?: Assessment;
isReadonly?: boolean;
onOpenModal: (assessment: Assessment) => void;
}

const DynamicAssessmentActionsRow: FunctionComponent<
DynamicAssessmentActionsRowProps
> = ({ questionnaire, application, archetype, assessment, isReadonly }) => {
> = ({
questionnaire,
application,
archetype,
assessment,
isReadonly,
onOpenModal,
}) => {
const isArchetype = useIsArchetype();
const history = useHistory();
const { t } = useTranslation();
Expand All @@ -64,7 +76,11 @@ const DynamicAssessmentActionsRow: FunctionComponent<
}),
variant: "success",
});
queryClient.invalidateQueries([assessmentsByItemIdQueryKey]);
queryClient.invalidateQueries([
assessmentsByItemIdQueryKey,
application?.id,
isArchetype,
]);
};

const onDeleteError = (error: AxiosError) => {
Expand All @@ -74,10 +90,11 @@ const DynamicAssessmentActionsRow: FunctionComponent<
});
};

const { mutate: deleteAssessment } = useDeleteAssessmentMutation(
onDeleteAssessmentSuccess,
onDeleteError
);
const { mutate: deleteAssessment, isLoading: isDeleting } =
useDeleteAssessmentMutation(onDeleteAssessmentSuccess, onDeleteError);

const isFetching = useIsFetching();
const isMutating = useIsMutating();

const { mutateAsync: deleteAssessmentAsync } = useDeleteAssessmentMutation(
onDeleteAssessmentSuccess,
Expand Down Expand Up @@ -117,19 +134,8 @@ const DynamicAssessmentActionsRow: FunctionComponent<

try {
const result = await createAssessmentAsync(newAssessment);
if (isArchetype) {
history.push(
formatPath(Paths.archetypesAssessment, {
assessmentId: result.id,
})
);
} else {
history.push(
formatPath(Paths.applicationsAssessment, {
assessmentId: result.id,
})
);
}

onOpenModal(result);
} catch (error) {
console.error("Error while creating assessment:", error);
pushNotification({
Expand Down Expand Up @@ -165,17 +171,8 @@ const DynamicAssessmentActionsRow: FunctionComponent<

if (action === AssessmentAction.Take) {
takeAssessment();
} else if (action === AssessmentAction.Continue) {
history.push(
formatPath(
isArchetype
? Paths.archetypesAssessment
: Paths.applicationsAssessment,
{
assessmentId: assessment?.id,
}
)
);
} else if (action === AssessmentAction.Continue && assessment?.id) {
onOpenModal(assessment);
} else if (action === AssessmentAction.Retake) {
if (assessment) {
try {
Expand Down Expand Up @@ -204,7 +201,7 @@ const DynamicAssessmentActionsRow: FunctionComponent<
<>
<Td>
<div>
{!isReadonly ? (
{isReadonly ? null : !isDeleting && !isFetching && !isMutating ? (
<Button
type="button"
variant="primary"
Expand All @@ -215,7 +212,11 @@ const DynamicAssessmentActionsRow: FunctionComponent<
>
{determineAction()}
</Button>
) : null}
) : (
<Spinner role="status" size="md">
<span className="sr-only">Loading...</span>
</Spinner>
)}
{assessment?.status === "complete" ? (
<Button
type="button"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from "react";
import React, { useState } from "react";
import { Table, Tbody, Td, Th, Thead, Tr } from "@patternfly/react-table";

import { useLocalTableControls } from "@app/hooks/table-controls";
Expand All @@ -15,6 +15,7 @@ import {
Questionnaire,
} from "@app/api/models";
import DynamicAssessmentActionsRow from "./dynamic-assessment-actions-row";
import AssessmentModal from "../../assessment-wizard/assessment-wizard-modal";

interface QuestionnairesTableProps {
tableName: string;
Expand Down Expand Up @@ -48,6 +49,18 @@ const QuestionnairesTable: React.FC<QuestionnairesTableProps> = ({
numRenderedColumns,
propHelpers: { tableProps, getThProps, getTrProps, getTdProps },
} = tableControls;

const [createdAssessment, setCreatedAssessment] = useState<Assessment | null>(
null
);
const handleModalOpen = (assessment: Assessment) => {
setCreatedAssessment(assessment);
};

const handleModalClose = () => {
setCreatedAssessment(null);
};

return (
<>
<Table
Expand Down Expand Up @@ -86,10 +99,7 @@ const QuestionnairesTable: React.FC<QuestionnairesTableProps> = ({
);

return (
<Tr
key={questionnaire.name}
{...getTrProps({ item: questionnaire })}
>
<Tr key={questionnaire.name}>
<TableRowContentWithControls
{...tableControls}
item={questionnaire}
Expand All @@ -112,6 +122,7 @@ const QuestionnairesTable: React.FC<QuestionnairesTableProps> = ({
application={application}
archetype={archetype}
isReadonly={isReadonly}
onOpenModal={handleModalOpen}
/>
) : null}
</TableRowContentWithControls>
Expand All @@ -121,6 +132,11 @@ const QuestionnairesTable: React.FC<QuestionnairesTableProps> = ({
</Tbody>
</ConditionalTableBody>
</Table>
<AssessmentModal
isOpen={!!createdAssessment}
onRequestClose={handleModalClose}
assessment={createdAssessment}
/>
</>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { Modal, ModalVariant } from "@patternfly/react-core";
import React, { FunctionComponent } from "react";
import { AssessmentWizard } from "./assessment-wizard";
import { Assessment } from "@app/api/models";

interface AssessmentModalProps {
isOpen: boolean;
onRequestClose: () => void;
assessment: Assessment | null;
}

const AssessmentModal: FunctionComponent<AssessmentModalProps> = ({
isOpen,
onRequestClose,
assessment,
}) => {
return (
<>
{isOpen && assessment && (
<Modal
isOpen={isOpen}
onClose={onRequestClose}
showClose={false}
aria-label="Application assessment wizard modal"
hasNoBodyWrapper
onEscapePress={onRequestClose}
variant={ModalVariant.large}
>
<AssessmentWizard assessment={assessment} onClose={onRequestClose} />
</Modal>
)}
</>
);
};

export default AssessmentModal;
Loading

0 comments on commit 6179d70

Please sign in to comment.