From 8ddf4f1523be882a86b07a42ad4b5ec1b8eac11e Mon Sep 17 00:00:00 2001 From: Scott Dickerson Date: Thu, 11 Jul 2024 13:36:22 -0400 Subject: [PATCH] :bug: Fix application edit data source (#2008) Resolves: #2007 Resolves: https://issues.redhat.com/browse/MTA-3232 Summary of changes: - The application edit form needs to use the base `Application` data and not the `DecoratedApplication` as its basis for generating an update request. Extra information added by the decoration will be unknown to the hub endpoint and will cause issues. - All references to `Application` in the application table code have been updated to `DecoratedApplication` - Any adjustments needed when a `DecoratedApplication` is passed to a child component as an `Application` have been made - The dereferencing part of decoration has been moved to a `direct` container. This will allow the reuse of the `Application` property name without replacing it. Signed-off-by: Scott J Dickerson --- .../applications-table/applications-table.tsx | 63 ++++++++++--------- .../useDecoratedApplications.ts | 13 ++-- 2 files changed, 41 insertions(+), 35 deletions(-) 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 66fd40211..97159ccf9 100644 --- a/client/src/app/pages/applications/applications-table/applications-table.tsx +++ b/client/src/app/pages/applications/applications-table/applications-table.tsx @@ -70,7 +70,7 @@ import { // Queries import { getArchetypeById, getAssessmentsByItemId } from "@app/api/rest"; -import { Application, Assessment, Ref } from "@app/api/models"; +import { Assessment, Ref } from "@app/api/models"; import { useBulkDeleteApplicationMutation, useFetchApplications, @@ -117,7 +117,7 @@ export const ApplicationsTable: React.FC = () => { // ----- State for the modals const [saveApplicationModalState, setSaveApplicationModalState] = useState< - "create" | Application | null + "create" | DecoratedApplication | null >(null); const isCreateUpdateApplicationsModalOpen = @@ -134,15 +134,15 @@ export const ApplicationsTable: React.FC = () => { useState(null); const [applicationToAssess, setApplicationToAssess] = - useState(null); + useState(null); const [applicationToReview, setApplicationToReview] = - useState(null); + useState(null); const [isAnalyzeModalOpen, setAnalyzeModalOpen] = useState(false); const [applicationDependenciesToManage, setApplicationDependenciesToManage] = - useState(null); + useState(null); const isDependenciesModalOpen = applicationDependenciesToManage !== null; const [assessmentToEdit, setAssessmentToEdit] = useState( @@ -152,15 +152,14 @@ export const ApplicationsTable: React.FC = () => { const [reviewToEdit, setReviewToEdit] = useState(null); const [applicationsToDelete, setApplicationsToDelete] = useState< - Application[] + DecoratedApplication[] >([]); const [assessmentToDiscard, setAssessmentToDiscard] = - useState(null); + useState(null); - const [reviewToDiscard, setReviewToDiscard] = useState( - null - ); + const [reviewToDiscard, setReviewToDiscard] = + useState(null); const [endOfAppImportPeriod, setEndOfAppImportPeriod] = useState( dayjs() @@ -169,7 +168,7 @@ export const ApplicationsTable: React.FC = () => { const [ saveApplicationsCredentialsModalState, setSaveApplicationsCredentialsModalState, - ] = useState<"create" | Application[] | null>(null); + ] = useState<"create" | DecoratedApplication[] | null>(null); const isCreateUpdateCredentialsModalOpen = saveApplicationsCredentialsModalState !== null; const applicationsCredentialsToUpdate = @@ -277,7 +276,7 @@ export const ApplicationsTable: React.FC = () => { } ); - const discardReview = async (application: Application) => { + const discardReview = async (application: DecoratedApplication) => { if (application.review) { deleteReview({ id: application.review.id, @@ -302,7 +301,7 @@ export const ApplicationsTable: React.FC = () => { } ); - const discardAssessment = async (application: Application) => { + const discardAssessment = async (application: DecoratedApplication) => { if (application.assessments) { application.assessments.forEach((assessment) => { deleteAssessment({ @@ -368,7 +367,8 @@ export const ApplicationsTable: React.FC = () => { key: name, value: name, })), - matcher: (filter: string, app: Application) => app.name === filter, + matcher: (filter: string, app: DecoratedApplication) => + app.name === filter, }, { categoryKey: "archetypes", @@ -418,7 +418,7 @@ export const ApplicationsTable: React.FC = () => { { value: "proxy", label: "Proxy" }, ], getItemValue: (app) => { - const identityKinds = app.identities + const identityKinds = app.direct.identities ?.map(({ kind }) => kind as string) ?.filter(Boolean) ?.join("^"); @@ -588,10 +588,7 @@ export const ApplicationsTable: React.FC = () => { key="manage-applications-credentials" isDisabled={selectedRows.length < 1} onClick={() => { - const selectedApps: Application[] = selectedRows.map( - ({ _ }) => _ - ); - setSaveApplicationsCredentialsModalState(selectedApps); + setSaveApplicationsCredentialsModalState(selectedRows); }} > {t("actions.manageCredentials")} @@ -631,7 +628,7 @@ export const ApplicationsTable: React.FC = () => { (app) => !!app.tasks.currentAnalyzer ); - const handleNavToAssessment = (application: Application) => { + const handleNavToAssessment = (application: DecoratedApplication) => { application?.id && history.push( formatPath(Paths.applicationAssessmentActions, { @@ -640,7 +637,7 @@ export const ApplicationsTable: React.FC = () => { ); }; - const handleNavToViewArchetypes = (application: Application) => { + const handleNavToViewArchetypes = (application: DecoratedApplication) => { application?.id && archetypeRefsToOverride?.length && history.push( @@ -651,7 +648,7 @@ export const ApplicationsTable: React.FC = () => { ); }; - const assessSelectedApp = async (application: Application) => { + const assessSelectedApp = async (application: DecoratedApplication) => { setApplicationToAssess(application); if (application?.archetypes?.length) { @@ -684,7 +681,7 @@ export const ApplicationsTable: React.FC = () => { } }; - const reviewSelectedApp = async (application: Application) => { + const reviewSelectedApp = async (application: DecoratedApplication) => { setApplicationToReview(application); if (application?.archetypes?.length) { for (const archetypeRef of application.archetypes) { @@ -1017,7 +1014,7 @@ export const ApplicationsTable: React.FC = () => { title: t("actions.manageCredentials"), onClick: () => setSaveApplicationsCredentialsModalState([ - application._, + application, ]), }, analysesReadAccess && @@ -1094,14 +1091,14 @@ export const ApplicationsTable: React.FC = () => { > {applicationsCredentialsToUpdate && ( a._)} onClose={() => setSaveApplicationsCredentialsModalState(null)} /> )} {isCreateUpdateApplicationsModalOpen && ( setSaveApplicationModalState(null)} /> )} @@ -1115,7 +1112,7 @@ export const ApplicationsTable: React.FC = () => { > {applicationDependenciesToManage && ( setApplicationDependenciesToManage(null)} /> )} @@ -1189,8 +1186,10 @@ export const ApplicationsTable: React.FC = () => { onCancel={() => setAssessmentToDiscard(null)} onClose={() => setAssessmentToDiscard(null)} onConfirm={() => { - discardAssessment(assessmentToDiscard!); - setAssessmentToDiscard(null); + if (assessmentToDiscard !== null) { + discardAssessment(assessmentToDiscard); + setAssessmentToDiscard(null); + } }} /> { onCancel={() => setReviewToDiscard(null)} onClose={() => setReviewToDiscard(null)} onConfirm={() => { - discardReview(reviewToDiscard!); - setReviewToDiscard(null); + if (reviewToDiscard !== null) { + discardReview(reviewToDiscard); + setReviewToDiscard(null); + } }} /> identities.find(({ id }) => id === identity.id)) - ?.filter(Boolean), + direct: { + identities: app.identities + ?.map((identity) => identities.find(({ id }) => id === identity.id)) + ?.filter(Boolean), + }, }; da.tasksStatus = chooseApplicationTaskStatus(da);