From 35eb2f15eeb4e1cbcf5cde7f15942da70ca73e8e Mon Sep 17 00:00:00 2001 From: Ian Bolton Date: Thu, 9 Nov 2023 19:22:51 -0500 Subject: [PATCH] :sparkles: Override review confirmation & drawer updates (#1527) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Adds review override as discussed in the Tuesday UXD call - Shows either the app level review if it exists or the matched archetype reviews in the app drawer review tab - not both. Screenshot 2023-11-08 at 4 12 41 PM --------- Signed-off-by: ibolton336 --- client/public/locales/en/translation.json | 5 +- .../applications-table/applications-table.tsx | 79 +++++++++++++++++-- .../review-fields.tsx | 13 ++- 3 files changed, 80 insertions(+), 17 deletions(-) diff --git a/client/public/locales/en/translation.json b/client/public/locales/en/translation.json index b5bbf95c9..d15a7d46b 100644 --- a/client/public/locales/en/translation.json +++ b/client/public/locales/en/translation.json @@ -184,8 +184,9 @@ "noResultsFoundTitle": "No results found", "overrideAssessmentDescription": "The application {{name}} already is associated with archetypes: {{what}}.", "overrideAssessmentConfirmation": "Do you want to create a dedicated assessment for this application and override the inherited archetype assessment(s)?", - "overrideReviewConfirmation": "This application has already been reviewed. Do you want to continue?", - "overrideArchetypeReviewConfirmation": "This archetype has already been reviewed. Do you want to continue?", + "overrideArchetypeReviewDescription": "The application {{name}} already is associated with archetypes: {{what}}.", + "overrideArchetypeReviewConfirmation": "Do you want to create a dedicated review for this application and override the inherited archetype review?", + "overrideReviewConfirmation": "This archetype has already been reviewed. Do you want to continue?", "reasonForError": "The reported reason for the error:", "reviewInstructions": "Use this section to provide your assessment of the possible migration/modernization plan and effort estimation.", "savingSelection": "Saving selection", diff --git a/client/src/app/pages/applications/applications-table/applications-table.tsx b/client/src/app/pages/applications/applications-table/applications-table.tsx index 96b7d5818..5e6546020 100644 --- a/client/src/app/pages/applications/applications-table/applications-table.tsx +++ b/client/src/app/pages/applications/applications-table/applications-table.tsx @@ -92,7 +92,11 @@ import { ImportApplicationsForm } from "../components/import-applications-form"; import { ConditionalRender } from "@app/components/ConditionalRender"; import { NoDataEmptyState } from "@app/components/NoDataEmptyState"; import { ConditionalTooltip } from "@app/components/ConditionalTooltip"; -import { getAssessmentsByItemId, getTaskById } from "@app/api/rest"; +import { + getArchetypeById, + getAssessmentsByItemId, + getTaskById, +} from "@app/api/rest"; import { ApplicationDependenciesForm } from "@app/components/ApplicationDependenciesFormContainer/ApplicationDependenciesForm"; import { useFetchArchetypes } from "@app/queries/archetypes"; import { useState } from "react"; @@ -127,9 +131,15 @@ export const ApplicationsTable: React.FC = () => { Ref[] | null >(null); + const [archetypeRefsToOverrideReview, setArchetypeRefsToOverrideReview] = + React.useState(null); + const [applicationToAssess, setApplicationToAssess] = React.useState(null); + const [applicationToReview, setApplicationToReview] = + React.useState(null); + /*** Analysis */ const [isAnalyzeModalOpen, setAnalyzeModalOpen] = useState(false); @@ -635,8 +645,38 @@ export const ApplicationsTable: React.FC = () => { handleNavToAssessment(application); } }; - const reviewSelectedApp = (application: Application) => { - if (application.review) { + + const reviewSelectedApp = async (application: Application) => { + setApplicationToReview(application); + if (application?.archetypes?.length) { + for (const archetypeRef of application.archetypes) { + try { + const archetype = await getArchetypeById(archetypeRef.id); + + if (archetype?.review) { + setArchetypeRefsToOverrideReview(application.archetypes); + break; + } else if (application.review) { + setReviewToEdit(application.id); + } else { + history.push( + formatPath(Paths.applicationsReview, { + applicationId: application.id, + }) + ); + } + } catch (error) { + console.error( + `Error fetching archetype with ID ${archetypeRef.id}:`, + error + ); + pushNotification({ + title: t("terms.error"), + variant: "danger", + }); + } + } + } else if (application.review) { setReviewToEdit(application.id); } else { history.push( @@ -1202,6 +1242,34 @@ export const ApplicationsTable: React.FC = () => { setReviewToEdit(null); }} /> + archetypeRef.name) + .join(", ") || "Archetype name", + })} + message={t("message.overrideArchetypeReviewConfirmation")} + titleIconVariant={"warning"} + isOpen={archetypeRefsToOverrideReview !== null} + confirmBtnVariant={ButtonVariant.primary} + confirmBtnLabel={t("actions.override")} + cancelBtnLabel={t("actions.cancel")} + onCancel={() => setArchetypeRefsToOverrideReview(null)} + onClose={() => setArchetypeRefsToOverrideReview(null)} + onConfirm={() => { + applicationToReview && + history.push( + formatPath(Paths.applicationsReview, { + applicationId: applicationToReview?.id, + }) + ); + setArchetypeRefsToOverride(null); + }} + /> { handleNavToViewArchetypes(applicationToAssess); }} onConfirm={() => { - history.push( - formatPath(Paths.applicationAssessmentActions, { - applicationId: activeItem?.id, - }) - ); setArchetypeRefsToOverride(null); applicationToAssess && handleNavToAssessment(applicationToAssess); }} diff --git a/client/src/app/pages/applications/components/application-detail-drawer/review-fields.tsx b/client/src/app/pages/applications/components/application-detail-drawer/review-fields.tsx index f10ef8cca..291003561 100644 --- a/client/src/app/pages/applications/components/application-detail-drawer/review-fields.tsx +++ b/client/src/app/pages/applications/components/application-detail-drawer/review-fields.tsx @@ -49,7 +49,7 @@ export const ReviewFields: React.FC<{ .filter(Boolean); const groupedReviewList: ReviewDrawerLabelItem[] = [ - ...(archetypeReview + ...(archetypeReview && !appReview ? [ { review: archetypeReview, @@ -66,12 +66,11 @@ export const ReviewFields: React.FC<{ isArchetype: false, }, ] - : []), - ...matchedArchetypeReviews.map((archetypeReview) => ({ - review: archetypeReview, - name: archetypeReview?.archetype?.name, - isArchetype: true, - })), + : matchedArchetypeReviews.map((archetypeReview) => ({ + review: archetypeReview, + name: archetypeReview?.archetype?.name, + isArchetype: true, + }))), ].filter((item) => item.review?.proposedAction); return (