Skip to content

Commit

Permalink
Merge branch 'main' into review-archetypes
Browse files Browse the repository at this point in the history
  • Loading branch information
ibolton336 authored Sep 21, 2023
2 parents 038230e + 6825317 commit 9d6a48b
Show file tree
Hide file tree
Showing 9 changed files with 283 additions and 118 deletions.
5 changes: 3 additions & 2 deletions client/public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
},
"composed": {
"add": "Add {{what}}",
"new": "New {{what}}",
"applicationAssessment": "Application assessment",
"applicationInventory": "Application inventory",
"businessCriticality": "Business criticality (1=low, 10=high)",
Expand Down Expand Up @@ -170,8 +171,8 @@
"noDataAvailableTitle": "No data available",
"noResultsFoundBody": "No results match the filter criteria. Remove all filters or clear all filters to show results.",
"noResultsFoundTitle": "No results found",
"overrideAssessmentDescription": "The archetype for {{what}} already has an assessment.",
"overrideAssessmentConfirmation": "Do you want to create a dedicated assessment for this application?",
"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?",
"reasonForError": "The reported reason for the error:",
"reviewInstructions": "Use this section to provide your assessment of the possible migration/modernization plan and effort estimation.",
Expand Down
6 changes: 6 additions & 0 deletions client/src/app/Paths.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export enum Paths {
archetypesAssessment = "/archetypes/assessment/:assessmentId",
applicationsAssessment = "/applications/assessment/:assessmentId",
applicationAssessmentActions = "/applications/assessment-actions/:applicationId",
viewArchetypes = "/applications/view-archetypes/:applicationId/archetypes/:archetypeId",
archetypeAssessmentActions = "/archetypes/assessment-actions/:archetypeId",
applicationAssessmentSummary = "/applications/assessment-summary/:assessmentId",
archetypeAssessmentSummary = "/archetypes/assessment-summary/:assessmentId",
Expand Down Expand Up @@ -58,6 +59,11 @@ export interface AssessmentActionsRoute {
archetypeId?: string;
}

export interface ViewArchetypesRoute {
applicationId?: string;
archetypeId?: string;
}

export interface ReviewRoute {
applicationId?: string;
archetypeId?: string;
Expand Down
9 changes: 9 additions & 0 deletions client/src/app/Routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ const Questionnaire = lazy(
() => import("./pages/assessment-management/questionnaire/questionnaire-page")
);

const ViewArchetypes = lazy(
() =>
import("./pages/assessment/components/view-archetypes/view-archetypes-page")
);
const AssessmentActions = lazy(
() =>
import(
Expand Down Expand Up @@ -106,6 +110,11 @@ export const devRoutes: IRoute[] = [
comp: AssessmentActions,
exact: false,
},
{
path: Paths.viewArchetypes,
comp: ViewArchetypes,
exact: false,
},
{
path: Paths.applicationAssessmentSummary,
comp: AssessmentSummary,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,15 @@ import { useQueryClient } from "@tanstack/react-query";
import { useLocalTableControls } from "@app/hooks/table-controls";

// Queries
import { Application, Assessment, Task } from "@app/api/models";
import { Application, Assessment, Ref, Task } from "@app/api/models";
import {
ApplicationsQueryKey,
useBulkDeleteApplicationMutation,
useFetchApplications,
} from "@app/queries/applications";
import { useFetchTasks } from "@app/queries/tasks";
import { useDeleteAssessmentMutation } from "@app/queries/assessments";
import { useDeleteReviewMutation, useFetchReviews } from "@app/queries/reviews";
import { useDeleteReviewMutation } from "@app/queries/reviews";
import { useFetchIdentities } from "@app/queries/identities";
import { useFetchTagCategories } from "@app/queries/tags";

Expand All @@ -86,6 +86,7 @@ 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 } from "@app/api/rest";

export const ApplicationsTable: React.FC = () => {
const { t } = useTranslation();
Expand All @@ -106,28 +107,17 @@ export const ApplicationsTable: React.FC = () => {
const createUpdateApplications =
saveApplicationModalState !== "create" ? saveApplicationModalState : null;

const [applicationToCopyAssessmentFrom, setApplicationToCopyAssessmentFrom] =
React.useState<Application | null>(null);

const isCopyAssessmentModalOpen = applicationToCopyAssessmentFrom !== null;

const [isAssessModalOpen, setAssessModalOpen] = React.useState(false);
const [archetypeRefsToOverride, setArchetypeRefsToOverride] = React.useState<
Ref[] | null
>(null);

const [
applicationToCopyAssessmentAndReviewFrom,
setCopyAssessmentAndReviewModalState,
] = React.useState<Application | null>(null);

const isCopyAssessmentAndReviewModalOpen =
applicationToCopyAssessmentAndReviewFrom !== null;
const [applicationToAssess, setApplicationToAssess] =
React.useState<Application | null>(null);

const [applicationDependenciesToManage, setApplicationDependenciesToManage] =
React.useState<Application | null>(null);
const isDependenciesModalOpen = applicationDependenciesToManage !== null;

const [applicationToAssess, setApplicationToAssess] =
React.useState<Application | null>(null);

const [assessmentToEdit, setAssessmentToEdit] =
React.useState<Assessment | null>(null);

Expand Down Expand Up @@ -156,9 +146,6 @@ export const ApplicationsTable: React.FC = () => {
refetch: fetchApplications,
} = useFetchApplications();

//TODO: check if any archetypes match this application here
const matchingArchetypes = [];

const onDeleteApplicationSuccess = (appIDCount: number) => {
pushNotification({
title: t("toastr.success.applicationDeleted", {
Expand Down Expand Up @@ -401,12 +388,6 @@ export const ApplicationsTable: React.FC = () => {
selectionState: { selectedItems: selectedRows },
} = tableControls;

const {
reviews,
isFetching: isFetchingReviews,
fetchError: fetchErrorReviews,
} = useFetchReviews();

const [isApplicationImportModalOpen, setIsApplicationImportModalOpen] =
React.useState(false);

Expand Down Expand Up @@ -460,19 +441,56 @@ export const ApplicationsTable: React.FC = () => {
: [];
const dropdownItems = [...importDropdownItems, ...applicationDeleteDropdown];

const assessSelectedApp = (application: Application) => {
// if application/archetype has an assessment, ask if user wants to override it
if (matchingArchetypes.length) {
setAssessModalOpen(true);
setApplicationToAssess(application);
const handleNavToAssessment = (application: Application) => {
application?.id &&
history.push(
formatPath(Paths.applicationAssessmentActions, {
applicationId: application?.id,
})
);
};

const handleNavToViewArchetypes = (application: Application) => {
application?.id &&
archetypeRefsToOverride?.length &&
history.push(
formatPath(Paths.viewArchetypes, {
applicationId: application?.id,
archetypeId: archetypeRefsToOverride[0].id,
})
);
};

const assessSelectedApp = async (application: Application) => {
setApplicationToAssess(application);

if (application?.archetypes?.length) {
for (const archetypeRef of application.archetypes) {
try {
const assessments = await getAssessmentsByItemId(
true,
archetypeRef.id
);

if (assessments && assessments.length > 0) {
setArchetypeRefsToOverride(application.archetypes);
break;
} else {
handleNavToAssessment(application);
}
} catch (error) {
console.error(
`Error fetching archetype with ID ${archetypeRef.id}:`,
error
);
pushNotification({
title: t("terms.error"),
variant: "danger",
});
}
}
} else {
application?.id &&
history.push(
formatPath(Paths.applicationAssessmentActions, {
applicationId: application?.id,
})
);
setApplicationToAssess(null);
handleNavToAssessment(application);
}
};
const reviewSelectedApp = (application: Application) => {
Expand Down Expand Up @@ -858,23 +876,36 @@ export const ApplicationsTable: React.FC = () => {
}}
/>
<ConfirmDialog
title={t("dialog.title.newAssessment")}
title={t("composed.new", {
what: t("terms.assessment").toLowerCase(),
})}
alertMessage={t("message.overrideAssessmentDescription", {
what:
archetypeRefsToOverride
?.map((archetypeRef) => archetypeRef.name)
.join(", ") || "Archetype name",
})}
message={t("message.overrideAssessmentConfirmation")}
titleIconVariant={"warning"}
isOpen={isAssessModalOpen}
message={t("message.overrideArchetypeConfirmation")}
isOpen={archetypeRefsToOverride !== null}
confirmBtnVariant={ButtonVariant.primary}
confirmBtnLabel={t("actions.accept")}
confirmBtnLabel={t("actions.override")}
cancelBtnLabel={t("actions.cancel")}
onCancel={() => setApplicationToAssess(null)}
onClose={() => setApplicationToAssess(null)}
onConfirm={() => {
customActionLabel={t("actions.viewArchetypes")}
onCancel={() => setArchetypeRefsToOverride(null)}
onClose={() => setArchetypeRefsToOverride(null)}
onCustomAction={() => {
applicationToAssess &&
history.push(
formatPath(Paths.applicationAssessmentActions, {
applicationId: applicationToAssess?.id,
})
);
setApplicationToAssess(null);
handleNavToViewArchetypes(applicationToAssess);
}}
onConfirm={() => {
history.push(
formatPath(Paths.applicationAssessmentActions, {
applicationId: activeRowItem?.id,
})
);
setArchetypeRefsToOverride(null);
applicationToAssess && handleNavToAssessment(applicationToAssess);
}}
/>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,14 +133,14 @@ export const ImportQuestionnaireForm: React.FC<
name="yamlFile"
label={t("terms.uploadYamlFile")}
fieldId="yamlFile"
helperText={t("dialog.uploadYamlFile")}
helperText={t("dialog.message.uploadYamlFile")}
renderInput={({ field: { onChange, name }, fieldState: { error } }) => (
<FileUpload
id={`${name}-file-upload`}
name={name}
value={filename}
filename={filename}
filenamePlaceholder={t("dialog.dragAndDropFile")}
filenamePlaceholder={t("dialog.message.dragAndDropFile")}
dropzoneProps={{
accept: {
"text/yaml": [".yml", ".yaml"],
Expand All @@ -151,7 +151,7 @@ export const ImportQuestionnaireForm: React.FC<
if (currentFile.file.size > 1000000) {
methods.setError(name, {
type: "custom",
message: t("dialog.maxFileSize"),
message: t("dialog.message.maxFileSize"),
});
}
setIsFileRejected(true);
Expand Down
Loading

0 comments on commit 9d6a48b

Please sign in to comment.