Skip to content

Commit

Permalink
Merge branch 'main' into mta-1314
Browse files Browse the repository at this point in the history
  • Loading branch information
ibolton336 authored Sep 25, 2023
2 parents 992a541 + fbd5e3d commit f6f9308
Show file tree
Hide file tree
Showing 10 changed files with 189 additions and 107 deletions.
10 changes: 6 additions & 4 deletions client/src/app/api/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,7 @@ export interface Questionnaire {
revision: number;
questions: number;
rating: string;
dateImported: string;
createTime: string;
required: boolean;
system: boolean;
sections: Section[];
Expand Down Expand Up @@ -687,10 +687,12 @@ export interface Answer {
selected?: boolean;
}
export interface Thresholds {
red: number;
unknown: number;
yellow: number;
red?: number;
unknown?: number;
yellow?: number;
green?: number;
}

export type AssessmentStatus = "empty" | "started" | "complete";
export type Risk = "green" | "yellow" | "red" | "unknown";

Expand Down
189 changes: 107 additions & 82 deletions client/src/app/pages/applications/analysis-wizard/analysis-wizard.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import * as React from "react";
import { useIsMutating } from "@tanstack/react-query";
import { FormProvider, useForm } from "react-hook-form";
import { Truncate } from "@patternfly/react-core";
import {
Modal,
ModalVariant,
Wizard,
WizardStepFunctionType,
} from "@patternfly/react-core/deprecated";
WizardStep,
WizardStepType,
WizardHeader,
Truncate,
} from "@patternfly/react-core";
import { useTranslation } from "react-i18next";

import {
Expand Down Expand Up @@ -297,10 +301,8 @@ export const AnalysisWizard: React.FC<IAnalysisWizard> = ({
onClose();
};

const onMove: WizardStepFunctionType = (
{ id, name },
{ prevId, prevName }
) => {
const onMove = (current: WizardStepType) => {
const id = current.id;
if (id && stepIdReached < (id as number)) setStepIdReached(id as number);
if (id === StepId.SetTargets) {
if (!taskGroup) {
Expand All @@ -311,93 +313,116 @@ export const AnalysisWizard: React.FC<IAnalysisWizard> = ({

const analyzableApplications = useAnalyzableApplications(applications, mode);

const getStepNavProps = (stepId: StepId, forceBlock = false) => ({
enableNext:
!forceBlock &&
stepIdReached >= stepId &&
(firstInvalidStep === null || firstInvalidStep >= stepId + 1),
canJumpTo:
!forceBlock &&
stepIdReached >= stepId &&
(firstInvalidStep === null || firstInvalidStep >= stepId),
});
const isStepEnabled = (stepId: StepId) => {
return (
stepIdReached + 1 >= stepId &&
(firstInvalidStep === null || firstInvalidStep >= stepId)
);
};

const steps = [
{
name: t("wizard.terms.configureAnalysis"),
steps: [
{
id: StepId.AnalysisMode,
name: t("wizard.terms.analysisMode"),
component: (
<WizardStep
name={t("wizard.terms.configureAnalysis")}
id="wizard-configureAnalysis"
steps={[
<WizardStep
id={StepId.AnalysisMode}
name={t("wizard.terms.analysisMode")}
isDisabled={!isStepEnabled(StepId.AnalysisMode)}
footer={{
isNextDisabled:
!isMutating && !isStepEnabled(StepId.AnalysisMode + 1),
}}
>
<>
<SetMode
isSingleApp={applications.length === 1 ? true : false}
isModeValid={isModeValid}
/>
),
...getStepNavProps(StepId.AnalysisMode, !!isMutating),
},
{
id: StepId.SetTargets,
name: t("wizard.terms.setTargets"),
component: <SetTargets />,
...getStepNavProps(StepId.SetTargets),
},
{
id: StepId.Scope,
name: t("wizard.terms.scope"),
component: <SetScope />,
...getStepNavProps(StepId.Scope),
},
],
},
{
name: t("wizard.terms.advanced"),
steps: [
{
id: StepId.CustomRules,
name: t("wizard.terms.customRules"),
component: <CustomRules />,
...getStepNavProps(StepId.CustomRules),
},
{
id: StepId.Options,
name: t("wizard.terms.options"),
component: <SetOptions />,
...getStepNavProps(StepId.Options),
},
],
},
{
id: StepId.Review,
name: t("wizard.terms.review"),
component: <Review applications={applications} mode={mode} />,
nextButtonText: "Run",
...getStepNavProps(StepId.Review),
},
</>
</WizardStep>,
<WizardStep
id={StepId.SetTargets}
name={t("wizard.terms.setTargets")}
isDisabled={!isStepEnabled(StepId.SetTargets)}
footer={{ isNextDisabled: !isStepEnabled(StepId.SetTargets + 1) }}
>
<SetTargets />
</WizardStep>,
<WizardStep
id={StepId.Scope}
name={t("wizard.terms.scope")}
isDisabled={!isStepEnabled(StepId.Scope)}
footer={{ isNextDisabled: !isStepEnabled(StepId.Scope + 1) }}
>
<SetScope />
</WizardStep>,
]}
></WizardStep>,
<WizardStep
name={t("wizard.terms.advanced")}
id="wizard-advanced"
steps={[
<WizardStep
id={StepId.CustomRules}
name={t("wizard.terms.customRules")}
isDisabled={!isStepEnabled(StepId.CustomRules)}
footer={{ isNextDisabled: !isStepEnabled(StepId.CustomRules + 1) }}
>
<CustomRules />
</WizardStep>,
<WizardStep
id={StepId.Options}
name={t("wizard.terms.options")}
isDisabled={!isStepEnabled(StepId.Options)}
footer={{ isNextDisabled: !isStepEnabled(StepId.Options + 1) }}
>
<SetOptions />
</WizardStep>,
]}
></WizardStep>,
<WizardStep
name={t("wizard.terms.review")}
id={StepId.Review}
isDisabled={!isStepEnabled(StepId.Review)}
>
<Review applications={applications} mode={mode} />
</WizardStep>,
];

return (
<>
{isOpen && (
<FormProvider {...methods}>
<Wizard
<Modal
isOpen={isOpen}
title="Application analysis"
description={
<Truncate
content={applications.map((app) => app.name).join(", ")}
/>
}
navAriaLabel={`${title} steps`}
mainAriaLabel={`${title} content`}
steps={steps}
onNext={onMove}
onBack={onMove}
onSave={handleSubmit(onSubmit)}
onClose={() => {
handleCancel();
}}
/>
showClose={false}
aria-label="Application analysis wizard modal"
hasNoBodyWrapper
onEscapePress={handleCancel}
variant={ModalVariant.large}
>
<Wizard
onClose={handleCancel}
onSave={handleSubmit(onSubmit)}
onStepChange={(_event, currentStep: WizardStepType) =>
onMove(currentStep)
}
header={
<WizardHeader
onClose={handleCancel}
title="Application analysis"
description={
<Truncate
content={applications.map((app) => app.name).join(", ")}
/>
}
/>
}
>
{steps}
</Wizard>
</Modal>
</FormProvider>
)}
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
EmptyState,
EmptyStateBody,
EmptyStateIcon,
List,
MenuToggle,
MenuToggleElement,
Modal,
Expand Down Expand Up @@ -51,7 +52,10 @@ import { useHistory } from "react-router-dom";
import { Paths } from "@app/Paths";
import { ImportQuestionnaireForm } from "@app/pages/assessment-management/import-questionnaire-form/import-questionnaire-form";
import ConfirmDeleteDialog from "@app/components/ConfirmDeleteDialog/ConfirmDeleteDialog";
import { ExportQuestionnaireDropdownItem } from "./ExportQuestionnaireDropdownItem";
import { ExportQuestionnaireDropdownItem } from "./components/export-questionnaire-dropdown-item";
import dayjs from "dayjs";
import { QuestionnaireQuestionsColumn } from "./components/questionnaire-questions-column";
import { QuestionnaireThresholdsColumn } from "./components/questionnaire-thresholds-column";

const AssessmentSettings: React.FC = () => {
const { t } = useTranslation();
Expand Down Expand Up @@ -108,7 +112,7 @@ const AssessmentSettings: React.FC = () => {
name: "Name",
questions: "Questions",
rating: "Rating",
dateImported: "Date imported",
createTime: "Date imported",
},
isSelectable: false,
expandableVariant: null,
Expand All @@ -127,10 +131,10 @@ const AssessmentSettings: React.FC = () => {
},
},
],
sortableColumns: ["name", "dateImported"],
sortableColumns: ["name", "createTime"],
getSortValues: (questionnaire) => ({
name: questionnaire.name || "",
dateImported: questionnaire.dateImported || "",
createTime: questionnaire.createTime || "",
}),
initialSort: { columnKey: "name", direction: "asc" },
hasPagination: true,
Expand Down Expand Up @@ -225,7 +229,7 @@ const AssessmentSettings: React.FC = () => {
<Th {...getThProps({ columnKey: "name" })} />
<Th {...getThProps({ columnKey: "questions" })} />
<Th {...getThProps({ columnKey: "rating" })} />
<Th {...getThProps({ columnKey: "dateImported" })} />
<Th {...getThProps({ columnKey: "createTime" })} />
</TableHeaderContentWithControls>
</Tr>
</Thead>
Expand All @@ -247,6 +251,10 @@ const AssessmentSettings: React.FC = () => {
numRenderedColumns={numRenderedColumns}
>
{currentPageItems?.map((questionnaire, rowIndex) => {
const formattedDate = dayjs(questionnaire.createTime)
.utc()
.format("YYYY-MM-DD HH:mm:ss");

return (
<Tbody key={questionnaire.id}>
<Tr>
Expand Down Expand Up @@ -283,19 +291,25 @@ const AssessmentSettings: React.FC = () => {
width={10}
{...getTdProps({ columnKey: "questions" })}
>
{questionnaire.questions}
<QuestionnaireQuestionsColumn
questionnaire={questionnaire}
/>
</Td>
<Td
width={15}
{...getTdProps({ columnKey: "rating" })}
>
{questionnaire.rating}
<List isPlain>
<QuestionnaireThresholdsColumn
questionnaire={questionnaire}
/>
</List>
</Td>
<Td
width={25}
{...getTdProps({ columnKey: "dateImported" })}
{...getTdProps({ columnKey: "createTime" })}
>
{questionnaire.dateImported}
{formattedDate}
</Td>
<Td width={10}>
<Dropdown
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from "react";
import { Text } from "@patternfly/react-core";
import { Questionnaire } from "@app/api/models";

export const QuestionnaireQuestionsColumn: React.FC<{
questionnaire: Questionnaire;
}> = ({ questionnaire }) => {
const totalQuestions = (questionnaire.sections || []).reduce(
(total, section) => {
return total + (section.questions ? section.questions.length : 0);
},
0
);
return <Text>{totalQuestions}</Text>;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from "react";
import { ListItem } from "@patternfly/react-core";
import { Questionnaire, Thresholds } from "@app/api/models";

export const QuestionnaireThresholdsColumn: React.FC<{
questionnaire: Questionnaire;
}> = ({ questionnaire }) => {
const thresholdsToListItems = (thresholds: Thresholds) => {
const thresholdKeys: (keyof Thresholds)[] = Object.keys(
thresholds
) as (keyof Thresholds)[];

return (
<>
{thresholdKeys.map((color) => {
const percentage: number = thresholds[color] || 0;
return (
<ListItem key={color}>
{color} {percentage}%
</ListItem>
);
})}
</>
);
};
return thresholdsToListItems(questionnaire.thresholds || {});
};
Loading

0 comments on commit f6f9308

Please sign in to comment.