Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🐛 inherit review data from multiple archetypes #1493

Merged
merged 5 commits into from
Oct 30, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions client/public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@
"category": "Category",
"color": "Color",
"comments": "Comments",
"commentsFromApplication": "Application comments",
"completed": "Completed",
"confidence": "Confidence",
"connected": "Connected",
Expand Down Expand Up @@ -354,8 +355,10 @@
"reports": "Reports",
"repositoryType": "Repository type",
"review": "Review",
"reviews": "Reviews",
"reviewComments": "Review comments",
"risk": "Risk",
"riskFromApplication": "Application risk",
"scheduled": "Scheduled",
"select": "Select",
"settingsAllowApps": "Allow reviewing applications without running an assessment first",
Expand Down
2 changes: 1 addition & 1 deletion client/src/app/api/rest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ export const deleteApplicationDependency = (
// Reviews

export const getReviews = (): Promise<Review[]> => {
return axios.get(`${REVIEWS}`);
return axios.get(`${REVIEWS}`).then((response) => response.data);
};

export const getReviewById = (id: number | string): Promise<Review> => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ import { NoDataEmptyState } from "@app/components/NoDataEmptyState";
import { ConditionalTooltip } from "@app/components/ConditionalTooltip";
import { getAssessmentsByItemId } from "@app/api/rest";
import { ApplicationDependenciesForm } from "@app/components/ApplicationDependenciesFormContainer/ApplicationDependenciesForm";
import { useFetchArchetypes } from "@app/queries/archetypes";

export const ApplicationsTable: React.FC = () => {
const { t } = useTranslation();
Expand Down Expand Up @@ -147,6 +148,13 @@ export const ApplicationsTable: React.FC = () => {
refetch: fetchApplications,
} = useFetchApplications();

const {
archetypes,
isFetching: isFetchingArchetypes,
error: archetypesFetchError,
refetch: fetchArchetypes,
} = useFetchArchetypes();
Copy link
Member

@sjd78 sjd78 Oct 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a thought -- when the application assessment + analysis tables are combine, it would be good to rework the data fetching & data cross-references into its own hook. That way the hook can do something like...

heavyApplication = {
  ...applicaiton,
  archetypes: mapRefsToObject(applicaiton.archetypes, archetypes),
  isReviewed: ....,
  hasReviewedArchetype: ...,
}

...then the component code can just wire things together

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1


const onDeleteApplicationSuccess = (appIDCount: number) => {
pushNotification({
title: t("toastr.success.applicationDeleted", {
Expand Down Expand Up @@ -515,7 +523,6 @@ export const ApplicationsTable: React.FC = () => {
);
}
};

return (
<ConditionalRender
when={isFetchingApplications && !(applications || applicationsFetchError)}
Expand Down Expand Up @@ -618,6 +625,19 @@ export const ApplicationsTable: React.FC = () => {
>
<Tbody>
{currentPageItems?.map((application, rowIndex) => {
const isAppReviewed = !!application.review;
const applicationArchetypes = application.archetypes?.map(
(archetypeRef) => {
return archetypes.find(
(archetype) => archetype.id === archetypeRef.id
);
}
);

const hasReviewedArchetype = applicationArchetypes?.some(
(archetype) => !!archetype?.review
);

return (
<Tr
key={application.name}
Expand Down Expand Up @@ -669,7 +689,9 @@ export const ApplicationsTable: React.FC = () => {
>
<IconedStatus
preset={
application.review ? "Completed" : "NotStarted"
isAppReviewed || hasReviewedArchetype
? "Completed"
: "NotStarted"
}
/>
</Td>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { EmptyTextMessage } from "@app/components/EmptyTextMessage";
import { Application } from "@app/api/models";
import { IconedStatus } from "@app/components/IconedStatus";
import { useFetchAssessmentsByItemId } from "@app/queries/assessments";
import { useFetchQuestionnaires } from "@app/queries/questionnaires";

export interface ApplicationAssessmentStatusProps {
application: Application;
Expand All @@ -22,8 +23,12 @@ export const ApplicationAssessmentStatus: React.FC<
isFetching: isFetchingAssessmentsById,
fetchError,
} = useFetchAssessmentsByItemId(false, application.id);

if (application?.assessed) {
const { questionnaires } = useFetchQuestionnaires();
const requiredQuestionnaireExists = questionnaires?.some(
(q) => q.required === true
);
//NOTE: Application.assessed is true if an app is assigned to an archetype and no required questionnaires exist
if (application?.assessed && requiredQuestionnaireExists) {
return <IconedStatus preset="Completed" />;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,13 @@ import {
import spacing from "@patternfly/react-styles/css/utilities/Spacing/spacing";

import { EmptyTextMessage } from "@app/components/EmptyTextMessage";
import { EFFORT_ESTIMATE_LIST, PROPOSED_ACTION_LIST } from "@app/Constants";
import { Ref, Task } from "@app/api/models";
import {
ApplicationDetailDrawer,
IApplicationDetailDrawerProps,
} from "./application-detail-drawer";
import { useFetchReviewById } from "@app/queries/reviews";
import { ReviewedArchetypeItem } from "./reviewed-archetype-item";
import { ReviewFields } from "./review-fields";
import { RiskLabel } from "@app/components/RiskLabel";

export interface IApplicationDetailDrawerAssessmentProps
Expand All @@ -34,11 +33,6 @@ export const ApplicationDetailDrawerAssessment: React.FC<
> = ({ application, onCloseClick, task }) => {
const { t } = useTranslation();

const { review: appReview } = useFetchReviewById(application?.review?.id);
const notYetReviewed = (
<EmptyTextMessage message={t("terms.notYetReviewed")} />
);

return (
<ApplicationDetailDrawer
application={application}
Expand Down Expand Up @@ -88,71 +82,16 @@ export const ApplicationDetailDrawerAssessment: React.FC<
)}
</DescriptionListDescription>
</DescriptionListGroup>
<TextContent className={spacing.mtLg}>
<Title headingLevel="h3" size="md">
{t("terms.applicationReview")}
</Title>
</TextContent>
<DescriptionListGroup>
<DescriptionListTerm>
{t("terms.proposedAction")}
</DescriptionListTerm>
<DescriptionListDescription cy-data="proposed-action">
{appReview ? (
<Label>
{PROPOSED_ACTION_LIST[appReview.proposedAction]
? t(PROPOSED_ACTION_LIST[appReview.proposedAction].i18Key)
: appReview.proposedAction}
</Label>
) : (
notYetReviewed
)}
</DescriptionListDescription>
</DescriptionListGroup>
<DescriptionListGroup>
<DescriptionListTerm>
{t("terms.effortEstimate")}
</DescriptionListTerm>
<DescriptionListDescription cy-data="effort-estimate">
{appReview
? EFFORT_ESTIMATE_LIST[appReview.effortEstimate]
? t(EFFORT_ESTIMATE_LIST[appReview.effortEstimate].i18Key)
: appReview.effortEstimate
: notYetReviewed}
</DescriptionListDescription>
</DescriptionListGroup>
<DescriptionListGroup>
<DescriptionListTerm>
{t("terms.businessCriticality")}
</DescriptionListTerm>
<DescriptionListDescription cy-data="business-criticality">
{appReview?.businessCriticality || notYetReviewed}
</DescriptionListDescription>
</DescriptionListGroup>
<DescriptionListGroup>
<DescriptionListTerm>
{t("terms.workPriority")}
</DescriptionListTerm>
<DescriptionListDescription cy-data="work-priority">
{appReview?.workPriority || notYetReviewed}
</DescriptionListDescription>
</DescriptionListGroup>
<DescriptionListGroup>
<DescriptionListTerm>{t("terms.risk")}</DescriptionListTerm>
<DescriptionListDescription cy-data="risk">
<RiskLabel risk={application?.risk || "unknown"} />
</DescriptionListDescription>
</DescriptionListGroup>
</DescriptionList>
<TextContent className={spacing.mtLg}>
<Title headingLevel="h3" size="md">
{t("terms.reviewComments")}
{t("terms.riskFromApplication")}
</Title>
<Text component="small" cy-data="review-comments">
{appReview?.comments || notYetReviewed}
<Text component="small" cy-data="comments">
<RiskLabel risk={application?.risk || "unknown"} />
</Text>
<Title headingLevel="h3" size="md">
{t("terms.comments")}
{t("terms.commentsFromApplication")}
</Title>
<Text component="small" cy-data="comments">
{application?.comments || (
Expand All @@ -162,6 +101,7 @@ export const ApplicationDetailDrawerAssessment: React.FC<
</TextContent>
</>
}
reviewsTabContent={<ReviewFields application={application} />}
/>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,15 @@ export interface IApplicationDetailDrawerProps
detailsTabMainContent: React.ReactNode;
reportsTabContent?: React.ReactNode;
factsTabContent?: React.ReactNode;
reviewsTabContent?: React.ReactNode;
}

enum TabKey {
Details = 0,
Tags,
Reports,
Facts,
Reviews,
}

export const ApplicationDetailDrawer: React.FC<
Expand All @@ -53,6 +55,7 @@ export const ApplicationDetailDrawer: React.FC<
detailsTabMainContent,
reportsTabContent = null,
factsTabContent = null,
reviewsTabContent = null,
}) => {
const { t } = useTranslation();
const [activeTabKey, setActiveTabKey] = React.useState<TabKey>(
Expand Down Expand Up @@ -169,6 +172,14 @@ export const ApplicationDetailDrawer: React.FC<
{factsTabContent}
</Tab>
) : null}
{reviewsTabContent ? (
<Tab
eventKey={TabKey.Reviews}
title={<TabTitleText>{t("terms.reviews")}</TabTitleText>}
>
{reviewsTabContent}
</Tab>
) : null}
</Tabs>
</PageDrawerContent>
);
Expand Down
Loading