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

✨ Move Analysis Details to full page view #1930

Merged
merged 2 commits into from
Jun 9, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
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
Loading