Skip to content

Commit

Permalink
Move Analysis Details to full page view
Browse files Browse the repository at this point in the history
Related changes:
1. extend BreadCrumbPath component to support non-links
2. refactor CSS styles for SimpleDocumentViewer to support both modal
   and in-page mode
3. create new route for the analysis details page:
   /applications/:applicationId/analysis-details/:taskId

Reference-Url: #1929
Signed-off-by: Radoslaw Szwajkowski <rszwajko@redhat.com>
  • Loading branch information
rszwajko committed Jun 7, 2024
1 parent a957271 commit 0f9147f
Show file tree
Hide file tree
Showing 9 changed files with 122 additions and 55 deletions.
7 changes: 7 additions & 0 deletions client/src/app/Paths.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
export const DevPaths = {
// Developer perspective
applications: "/applications",
applicationsAnalysisDetails:
"/applications/:applicationId/analysis-details/:taskId",
applicationsAnalysisTab: "/applications/analysis-tab",
applicationsAssessmentTab: "/applications/assessment-tab",
applicationsImports: "/applications/application-imports",
Expand Down Expand Up @@ -86,3 +88,8 @@ export interface ReviewRoute {
export interface ImportSummaryRoute {
importId: string;
}

export interface AnalysisDetailsRoute {
applicationId: string;
taskId: string;
}
9 changes: 8 additions & 1 deletion client/src/app/Routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ const ManageImports = lazy(() => import("./pages/applications/manage-imports"));
const ImportDetails = lazy(
() => import("./pages/applications/manage-imports-details")
);

const AnalysisDetails = lazy(
() => import("./pages/applications/analysis-details")
);
const Reports = lazy(() => import("./pages/reports"));
const Controls = lazy(() => import("./pages/controls"));
const Identities = lazy(() => import("./pages/identities"));
Expand Down Expand Up @@ -74,6 +76,11 @@ export const devRoutes: IRoute<DevPathValues>[] = [
comp: ImportDetails,
exact: false,
},
{
path: Paths.applicationsAnalysisDetails,
comp: AnalysisDetails,
exact: false,
},
{
path: Paths.applicationsImports,
comp: ManageImports,
Expand Down
7 changes: 6 additions & 1 deletion client/src/app/components/BreadCrumbPath.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Link } from "react-router-dom";
import { Breadcrumb, BreadcrumbItem, Button } from "@patternfly/react-core";

export interface BreadCrumbPathProps {
breadcrumbs: { title: string; path: string | (() => void) }[];
breadcrumbs: { title: string; path?: string | (() => void) }[];
}

export const BreadCrumbPath: React.FC<BreadCrumbPathProps> = ({
Expand All @@ -12,6 +12,11 @@ export const BreadCrumbPath: React.FC<BreadCrumbPathProps> = ({
return (
<Breadcrumb>
{breadcrumbs.map((crumb, i, { length }) => {
if (!crumb.path) {
// the item is not a link
return <BreadcrumbItem key={i}>{crumb.title}</BreadcrumbItem>;
}

const isLast = i === length - 1;

const link =
Expand Down
2 changes: 1 addition & 1 deletion client/src/app/components/PageHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { HorizontalNav } from "./HorizontalNav";
export interface PageHeaderProps {
title: string;
description?: React.ReactNode;
breadcrumbs: { title: string; path: string | (() => void) }[];
breadcrumbs: { title: string; path?: string | (() => void) }[];
btnActions?: React.ReactNode;
navItems?: { title: string; path: string }[];
}
Expand Down
36 changes: 14 additions & 22 deletions client/src/app/components/SimpleDocumentViewer.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
}

/* Match empty state layout to the editor layout so they take up exactly the same space */
.simple-task-viewer .simple-task-viewer-empty-state {
.simple-task-viewer-code .simple-task-viewer-empty-state {
padding: var(--pf-v5-c-code-editor__code--PaddingTop)
var(--pf-v5-c-code-editor__code--PaddingRight)
var(--pf-v5-c-code-editor__code--PaddingBottom)
Expand All @@ -17,37 +17,28 @@

/*
Make all of the containers of the MonacoEditor component take the maximum height so the
editor can always be as tall as possible in the Modal.
editor can always be as tall as possible.
*/
.simple-task-viewer[class*="full-height"] .pf-v5-c-modal-box__body {
.simple-task-viewer[class*="full-height"] .pf-v5-c-modal-box__body,
.simple-task-viewer-container {
display: flex;
flex-direction: column;
}

.simple-task-viewer[class*="full-height"]
.pf-v5-c-modal-box__body
.pf-v5-c-code-editor {
.simple-task-viewer-code {
flex-grow: 1;
height: 100%;
}

.simple-task-viewer[class*="full-height"]
.pf-v5-c-modal-box__body
.pf-v5-c-code-editor
.pf-v5-c-file-upload {
.simple-task-viewer-code .pf-v5-c-file-upload {
height: 100%;
}

.simple-task-viewer[class*="full-height"]
.pf-v5-c-modal-box__body
.pf-v5-c-code-editor
.pf-v5-c-file-upload
.pf-v5-c-code-editor__main {
.simple-task-viewer-code .pf-v5-c-file-upload .pf-v5-c-code-editor__main {
flex-grow: 1;
}

.simple-task-viewer[class*="full-height"]
.pf-v5-c-modal-box__body
.pf-v5-c-code-editor
.simple-task-viewer-code
.pf-v5-c-file-upload
.pf-v5-c-code-editor__main
.pf-v5-c-code-editor__code {
Expand All @@ -58,20 +49,21 @@
Tweak the code editor so we can put the language selection toggle group in the
"Language Label" location
*/
.simple-task-viewer .pf-v5-c-code-editor__controls {
.simple-task-viewer-code .pf-v5-c-code-editor__controls {
flex-grow: 1;
}

.simple-task-viewer .pf-v5-c-code-editor__header-main {
.simple-task-viewer-code .pf-v5-c-code-editor__header-main {
display: none;
}

.simple-task-viewer .pf-v5-c-code-editor__tab.language-toggle-group-container {
.simple-task-viewer-code
.pf-v5-c-code-editor__tab.language-toggle-group-container {
padding: 0;
border: none;
}

.simple-task-viewer .language-toggle-group {
.simple-task-viewer-code .language-toggle-group {
--pf-v5-c-toggle-group__button--FontSize: var(--pf-v5-global--FontSize--md);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import React from "react";
import { useParams } from "react-router-dom";
import { useTranslation } from "react-i18next";

import { PageSection } from "@patternfly/react-core";

import { AnalysisDetailsRoute, Paths } from "@app/Paths";
import { PageHeader } from "@app/components/PageHeader";
import { formatPath } from "@app/utils/utils";
import { SimpleDocumentViewer } from "@app/components/SimpleDocumentViewer";
import { useFetchApplicationById } from "@app/queries/applications";
import { useFetchTaskByID } from "@app/queries/tasks";

export const AnalysisDetails: React.FC = () => {
// i18
const { t } = useTranslation();

// Router
const { applicationId, taskId } = useParams<AnalysisDetailsRoute>();

const { application } = useFetchApplicationById(applicationId);
const { task } = useFetchTaskByID(Number(taskId));
const taskName =
(typeof task != "string" ? task?.name : taskId) ?? t("terms.unknown");
const appName = application?.name ?? t("terms.unknown") ?? "";

return (
<>
<PageSection variant="light">
<PageHeader
title={`Analysis details for ${taskName}`}
breadcrumbs={[
{
title: t("terms.applications"),
path: Paths.applications,
},
{
title: appName,
},
{
title: t("actions.analysisDetails"),
path: formatPath(Paths.applicationsAnalysisDetails, {
applicationId: applicationId,
taskId: taskId,
}),
},
]}
/>
</PageSection>
<PageSection className="simple-task-viewer-container">
<SimpleDocumentViewer documentId={Number(taskId)} height="full" />
</PageSection>
</>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { AnalysisDetails as default } from "./AnalysisDetails";
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@ import { ApplicationDependenciesForm } from "@app/components/ApplicationDependen
import { useState } from "react";
import { ApplicationAnalysisStatus } from "../components/application-analysis-status";
import { ApplicationDetailDrawer } from "../components/application-detail-drawer/application-detail-drawer";
import { SimpleDocumentViewerModal } from "@app/components/SimpleDocumentViewer";
import { AnalysisWizard } from "../analysis-wizard/analysis-wizard";
import { TaskGroupProvider } from "../analysis-wizard/components/TaskGroupContext";
import { ApplicationIdentityForm } from "../components/application-identity-form/application-identity-form";
Expand Down Expand Up @@ -553,11 +552,6 @@ export const ApplicationsTable: React.FC = () => {
const [isApplicationImportModalOpen, setIsApplicationImportModalOpen] =
useState(false);

const [taskToView, setTaskToView] = useState<{
name: string;
task: number | undefined;
}>();

const userScopes: string[] = token?.scope.split(" ") || [],
importWriteAccess = checkAccess(userScopes, importsWriteScopes),
applicationWriteAccess = checkAccess(userScopes, applicationsWriteScopes),
Expand Down Expand Up @@ -1072,11 +1066,20 @@ export const ApplicationsTable: React.FC = () => {
? [
{
title: t("actions.analysisDetails"),
onClick: () =>
setTaskToView({
name: application.name,
task: getTask(application)?.id,
}),
onClick: () => {
const taskId = getTask(application)?.id;
if (taskId && application.id) {
history.push(
formatPath(
Paths.applicationsAnalysisDetails,
{
applicationId: application.id,
taskId,
}
)
);
}
},
},
]
: []),
Expand Down Expand Up @@ -1153,11 +1156,6 @@ export const ApplicationsTable: React.FC = () => {
onClose={() => setSaveApplicationModalState(null)}
/>
)}
<SimpleDocumentViewerModal
title={`Analysis details for ${taskToView?.name}`}
documentId={taskToView?.task}
onClose={() => setTaskToView(undefined)}
/>
<Modal
isOpen={isDependenciesModalOpen}
variant="medium"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from "react";
import { Link } from "react-router-dom";
import { Link, useHistory } from "react-router-dom";
import { useTranslation } from "react-i18next";

import {
Expand Down Expand Up @@ -52,7 +52,6 @@ import {
PageDrawerContent,
} from "@app/components/PageDrawerContext";
import { EmptyTextMessage } from "@app/components/EmptyTextMessage";
import { SimpleDocumentViewerModal } from "@app/components/SimpleDocumentViewer";
import { LabelsFromItems } from "@app/components/labels/labels-from-items/labels-from-items";
import { RiskLabel } from "@app/components/RiskLabel";
import { ReviewFields } from "@app/components/detail-drawer/review-fields";
Expand All @@ -62,6 +61,8 @@ import { AssessedArchetypes } from "./components/assessed-archetypes";
import DownloadButton from "./components/download-button";
import { ApplicationDetailFields } from "./application-detail-fields";
import { ApplicationFacts } from "./application-facts";
import { formatPath } from "@app/utils/utils";
import { Paths } from "@app/Paths";

export interface IApplicationDetailDrawerProps
extends Pick<IPageDrawerContentProps, "onCloseClick"> {
Expand Down Expand Up @@ -101,8 +102,6 @@ export const ApplicationDetailDrawer: React.FC<
const { identities } = useFetchIdentities();
const { facts, isFetching } = useFetchFacts(application?.id);

const [taskIdToView, setTaskIdToView] = React.useState<number>();

let matchingSourceCredsRef: Identity | undefined;
let matchingMavenCredsRef: Identity | undefined;
if (application && identities) {
Expand All @@ -113,6 +112,16 @@ export const ApplicationDetailDrawer: React.FC<
const notAvailable = <EmptyTextMessage message={t("terms.notAvailable")} />;

const enableDownloadSetting = useSetting("download.html.enabled");
const history = useHistory();
const navigateToAnalysisDetails = () =>
application?.id &&
task?.id &&
history.push(
formatPath(Paths.applicationsAnalysisDetails, {
applicationId: application?.id,
taskId: task?.id,
})
);

const reviewedArchetypes =
application?.archetypes
Expand Down Expand Up @@ -340,7 +349,7 @@ export const ApplicationDetailDrawer: React.FC<
}
type="button"
variant="link"
onClick={() => setTaskIdToView(task.id)}
onClick={navigateToAnalysisDetails}
className={spacing.ml_0}
style={{ margin: "0", padding: "0" }}
>
Expand Down Expand Up @@ -401,7 +410,7 @@ export const ApplicationDetailDrawer: React.FC<
}
type="button"
variant="link"
onClick={() => setTaskIdToView(task.id)}
onClick={navigateToAnalysisDetails}
className={spacing.ml_0}
style={{ margin: "0", padding: "0" }}
>
Expand Down Expand Up @@ -429,7 +438,7 @@ export const ApplicationDetailDrawer: React.FC<
}
type="button"
variant="link"
onClick={() => setTaskIdToView(task?.id)}
onClick={navigateToAnalysisDetails}
className={spacing.ml_0}
style={{ margin: "0", padding: "0" }}
>
Expand All @@ -440,13 +449,6 @@ export const ApplicationDetailDrawer: React.FC<
)}
</>
)}
<SimpleDocumentViewerModal
title={`Analysis details for ${application?.name}`}
documentId={taskIdToView}
onClose={() => {
setTaskIdToView(undefined);
}}
/>
</TextContent>
{!isFetching && !!facts.length && (
<ApplicationFacts facts={facts} />
Expand Down

0 comments on commit 0f9147f

Please sign in to comment.