Skip to content

Commit

Permalink
feat: show observation on side of observation log
Browse files Browse the repository at this point in the history
  • Loading branch information
StefanFl committed Dec 1, 2024
1 parent cb965ca commit 488ec9e
Show file tree
Hide file tree
Showing 7 changed files with 188 additions and 117 deletions.
24 changes: 2 additions & 22 deletions frontend/src/core/observation_logs/ObservationLogShow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { SeverityField } from "../../commons/custom_fields/SeverityField";
import { is_superuser } from "../../commons/functions";
import { ASSESSMENT_STATUS_NEEDS_APPROVAL } from "../types";
import AssessmentApproval from "./AssessmentApproval";
import ObservationLogShowAside from "./ObservationLogShowAside";

const ShowActions = () => {
const observation_log = useRecordContext();
Expand Down Expand Up @@ -66,27 +67,6 @@ const ObservationLogComponent = () => {
<Paper sx={{ marginBottom: 1, padding: 2, width: "100%" }}>
<Stack spacing={1}>
<Typography variant="h6">Observation Log</Typography>
<Labeled label="Product">
<ReferenceField
source="observation_data.product"
reference="products"
queryOptions={{ meta: { api_resource: "product_names" } }}
link="show"
sx={{ "& a": { textDecoration: "none" } }}
>
<TextField source="name" />
</ReferenceField>
</Labeled>
<Labeled label="Observation">
<ReferenceField
source="observation"
reference="observations"
link="show"
sx={{ "& a": { textDecoration: "none" } }}
>
<TextField source="title" />
</ReferenceField>
</Labeled>
<Labeled label="User">
<TextField source="user_full_name" />
</Labeled>
Expand Down Expand Up @@ -197,7 +177,7 @@ const ObservationLogComponent = () => {
};
const ObservationLogShow = () => {
return (
<Show actions={<ShowActions />} component={ObservationLogComponent}>
<Show actions={<ShowActions />} component={ObservationLogComponent} aside={<ObservationLogShowAside />}>
<Fragment />
</Show>
);
Expand Down
24 changes: 24 additions & 0 deletions frontend/src/core/observation_logs/ObservationLogShowAside.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Box } from "@mui/material";
import { WithRecord } from "react-admin";

import ObservationShowHeader from "../observations/ObservationShowHeader";
import ObservationShowOrigins from "../observations/ObservationShowOrigins";

const ObservationLogShowAside = () => {
return (
<WithRecord
render={(observation_log) => (
<Box width={"100%"} marginLeft={2} marginRight={1}>
<ObservationShowHeader observation={observation_log.observation_data} />
<ObservationShowOrigins
observation={observation_log.observation_data}
showDependencies={false}
elevated={true}
/>
</Box>
)}
/>
);
};

export default ObservationLogShowAside;
2 changes: 1 addition & 1 deletion frontend/src/core/observations/ObservationExpand.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const ObservationExpand = () => {
<ObservationShowDescriptionRecommendation />
</Paper>
)}
<ObservationShowOrigins elevated={false} />
<ObservationShowOrigins showDependencies={false} elevated={false} />
</SimpleShowLayout>
);
};
Expand Down
81 changes: 3 additions & 78 deletions frontend/src/core/observations/ObservationShow.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { Box, Paper, Stack, Typography } from "@mui/material";
import { Fragment } from "react";
import {
ChipField,
DateField,
EditButton,
Labeled,
NumberField,
Expand All @@ -19,17 +17,15 @@ import {
PERMISSION_OBSERVATION_EDIT,
PERMISSION_OBSERVATION_LOG_APPROVAL,
} from "../../access_control/types";
import { SeverityField } from "../../commons/custom_fields/SeverityField";
import TextUrlField from "../../commons/custom_fields/TextUrlField";
import { get_cwe_url, get_vulnerability_url } from "../../commons/functions";
import { useStyles } from "../../commons/layout/themes";
import AssessmentApproval from "../observation_logs/AssessmentApproval";
import ObservationLogEmbeddedList from "../observation_logs/ObservationLogEmbeddedList";
import { OBSERVATION_STATUS_IN_REVIEW, OBSERVATION_STATUS_OPEN } from "../types";
import ObservationAssessment from "./ObservationAssessment";
import ObservationRemoveAssessment from "./ObservationRemoveAssessment";
import ObservationsShowAside from "./ObservationShowAside";
import ObservationShowDescriptionRecommendation from "./ObservationShowDescriptionRecommendation";
import ObservationShowHeader from "./ObservationShowHeader";
import ObservationShowOrigins from "./ObservationShowOrigins";
import PotentialDuplicatesList from "./PotentialDuplicatesList";
import {
Expand Down Expand Up @@ -102,82 +98,11 @@ const ShowActions = () => {
};

const ObservationShowComponent = () => {
const { classes } = useStyles();

return (
<WithRecord
render={(observation) => (
<Box width={"100%"}>
<Paper sx={{ marginBottom: 2, padding: 2 }}>
<Typography variant="h6" sx={{ marginBottom: 1 }}>
Observation
</Typography>
<Stack direction="row" spacing={4}>
<Stack spacing={2}>
<Labeled>
<SeverityField label="Severity" source="current_severity" />
</Labeled>
{observation.parser_severity != "" &&
(observation.rule_severity != "" || observation.assessment_severity != "") && (
<Labeled>
<TextField source="parser_severity" />
</Labeled>
)}
{observation.rule_severity != "" && (
<Labeled>
<TextField source="rule_severity" />
</Labeled>
)}
{observation.assessment_severity != "" && (
<Labeled>
<TextField source="assessment_severity" />
</Labeled>
)}
</Stack>
<Stack spacing={2}>
<Labeled>
<ChipField source="current_status" label="Status" />
</Labeled>
{observation.parser_status != "" &&
(observation.rule_status != "" ||
observation.assessment_status != "" ||
observation.vex_status != "") && (
<Labeled>
<TextField source="parser_status" />
</Labeled>
)}
{observation.vex_status != "" && (
<Labeled label="VEX status">
<TextField source="vex_status" />
</Labeled>
)}
{observation.rule_status != "" && (
<Labeled>
<TextField source="rule_status" />
</Labeled>
)}
{observation.assessment_status != "" && (
<Labeled>
<TextField source="assessment_status" />
</Labeled>
)}
</Stack>
{observation.found != null && (
<Labeled>
<DateField source="found" />
</Labeled>
)}
{observation.risk_acceptance_expiry_date != null && (
<Labeled label="Risk acceptance expiry">
<DateField source="risk_acceptance_expiry_date" />
</Labeled>
)}
<Labeled>
<TextField source="title" className={classes.fontBigBold} />
</Labeled>
</Stack>
<ObservationShowDescriptionRecommendation />
</Paper>
<ObservationShowHeader />

{(observation.vulnerability_id != "" ||
observation.cvss3_score != null ||
Expand Down Expand Up @@ -240,7 +165,7 @@ const ObservationShowComponent = () => {
</Paper>
)}

<ObservationShowOrigins elevated={true} />
<ObservationShowOrigins showDependencies={true} elevated={true} />

<Paper sx={{ marginBottom: 2, padding: 2 }}>
<Typography variant="h6" sx={{ paddingBottom: 1 }}>
Expand Down
11 changes: 1 addition & 10 deletions frontend/src/core/observations/ObservationShowAside.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,7 @@ const MetaData = () => {
link="show"
sx={{ "& a": { textDecoration: "none" } }}
/>
{observation.branch && (
<ReferenceField
source="branch"
reference="branches"
queryOptions={{ meta: { api_resource: "branch_names" } }}
label="Branch / Version"
link={false}
sx={{ "& a": { textDecoration: "none" } }}
/>
)}
{observation.branch && <TextField label="Branch / Version" source="branch_name" />}
{observation.scanner != "" && <TextField source="scanner" />}
<TextField source="parser_data.name" label="Parser name" />
{observation.scanner_observation_id != "" && (
Expand Down
146 changes: 146 additions & 0 deletions frontend/src/core/observations/ObservationShowHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
import { Paper, Stack, Typography } from "@mui/material";
import {
ChipField,
DateField,
Labeled,
RecordContextProvider,
ReferenceField,
TextField,
useRecordContext,
} from "react-admin";

import { SeverityField } from "../../commons/custom_fields/SeverityField";
import { useStyles } from "../../commons/layout/themes";
import ObservationShowDescriptionRecommendation from "./ObservationShowDescriptionRecommendation";

type ObservationShowHeaderProps = {
observation?: any;
};

const ObservationShowHeader = ({ observation }: ObservationShowHeaderProps) => {
const { classes } = useStyles();

let in_observation_log = false;
const observation_record = useRecordContext();
if (observation) {
in_observation_log = true;
} else {
observation = observation_record;
}

return (
<RecordContextProvider value={observation}>
{observation && (
<Paper sx={{ marginBottom: 2, padding: 2 }}>
<Typography variant="h6" sx={{ marginBottom: 1 }}>
Observation
</Typography>
{in_observation_log && (
<Stack direction="row" spacing={4} sx={{ marginBottom: 2 }}>
<Labeled label="Product">
<ReferenceField
source="product_data.id"
reference="products"
queryOptions={{ meta: { api_resource: "product_names" } }}
link="show"
sx={{ "& a": { textDecoration: "none" } }}
>
<TextField source="name" />
</ReferenceField>
</Labeled>
{observation.branch && (
<Labeled label="Branch/ Version">
<TextField source="branch_name" />
</Labeled>
)}
</Stack>
)}
<Stack direction="row" spacing={4}>
<Stack spacing={2}>
<Labeled>
<SeverityField label="Severity" source="current_severity" />
</Labeled>
{!in_observation_log &&
observation.parser_severity != "" &&
(observation.rule_severity != "" || observation.assessment_severity != "") && (
<Labeled>
<TextField source="parser_severity" />
</Labeled>
)}
{!in_observation_log && observation.rule_severity != "" && (
<Labeled>
<TextField source="rule_severity" />
</Labeled>
)}
{!in_observation_log && observation.assessment_severity != "" && (
<Labeled>
<TextField source="assessment_severity" />
</Labeled>
)}
</Stack>
<Stack spacing={2}>
<Labeled>
<ChipField source="current_status" label="Status" />
</Labeled>
{!in_observation_log &&
observation.parser_status != "" &&
(observation.rule_status != "" ||
observation.assessment_status != "" ||
observation.vex_status != "") && (
<Labeled>
<TextField source="parser_status" />
</Labeled>
)}
{!in_observation_log && observation.vex_status != "" && (
<Labeled label="VEX status">
<TextField source="vex_status" />
</Labeled>
)}
{!in_observation_log && observation.rule_status != "" && (
<Labeled>
<TextField source="rule_status" />
</Labeled>
)}
{!in_observation_log && observation.assessment_status != "" && (
<Labeled>
<TextField source="assessment_status" />
</Labeled>
)}
</Stack>
{observation.found != null && (
<Labeled>
<DateField source="found" />
</Labeled>
)}
{observation.risk_acceptance_expiry_date != null && (
<Labeled label="Risk acceptance expiry">
<DateField source="risk_acceptance_expiry_date" />
</Labeled>
)}
{!in_observation_log && (
<Labeled>
<TextField source="title" className={classes.fontBigBold} />
</Labeled>
)}
{in_observation_log && (
<Labeled label="Title">
<ReferenceField
source="id"
reference="observations"
queryOptions={{ meta: { api_resource: "observation_titles" } }}
link="show"
sx={{ "& a": { textDecoration: "none" } }}
>
<TextField source="title" />
</ReferenceField>
</Labeled>
)}
</Stack>
<ObservationShowDescriptionRecommendation />
</Paper>
)}
</RecordContextProvider>
);
};

export default ObservationShowHeader;
Loading

0 comments on commit 488ec9e

Please sign in to comment.