Skip to content
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
8 changes: 7 additions & 1 deletion frontend/src/components/History.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,13 @@ export default function History() {

const createButton = (
<Col className="d-flex justify-content-end">
<Button id="createbutton" size="sm" color="darker" onClick={onClick}>
<Button
id="createbutton"
className="d-flex align-items-center"
size="sm"
color="darker"
onClick={onClick}
>
<BsFillPlusCircleFill />
&nbsp;Create {isJobsTablePage ? "job" : "investigation"}
</Button>
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/common/icon/icons.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { FaRegStopCircle } from "react-icons/fa";

export function DeleteIcon() {
return (
<span>
<span className="d-flex align-items-center">
<MdDeleteOutline className="text-danger me-1" />
Delete
</span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ export function InvestigationFlow(props) {
deleteKeyCode={null}
preventScrolling={false}
zoomOnDoubleClick={false}
panOnScroll
{...rest}
>
<MiniMap pannable />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { StatusTag } from "../../common/StatusTag";
import { TLPTag } from "../../common/TLPTag";
import { updateInvestigation } from "./investigationApi";

export function InvestigationInfoCard({ investigation }) {
export function InvestigationInfoCard({ investigation, refetchTree }) {
// local state
const [isOpen, setIsOpen] = React.useState(false);

Expand All @@ -39,6 +39,7 @@ export function InvestigationInfoCard({ investigation }) {
const success = await updateInvestigation(investigation.id, {
name: investigationName,
});
if (success) refetchTree();
if (!success) return;
}
setIsEditing(false);
Expand Down Expand Up @@ -152,4 +153,5 @@ export function InvestigationInfoCard({ investigation }) {

InvestigationInfoCard.propTypes = {
investigation: PropTypes.object.isRequired,
refetchTree: PropTypes.func.isRequired,
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import PropTypes from "prop-types";
import useAxios from "axios-hooks";
import { Col, Row, Container, Input } from "reactstrap";
import { MdEdit } from "react-icons/md";
import { BsFillCheckSquareFill } from "react-icons/bs";
import { BsFillCheckSquareFill, BsMarkdown } from "react-icons/bs";
import { useLocation } from "react-router-dom";

import { IconButton, Loader } from "@certego/certego-ui";
Expand All @@ -14,6 +14,7 @@ import { InvestigationActionsBar } from "./InvestigationActionBar";
import { updateInvestigation } from "./investigationApi";
import { InvestigationFlow } from "../flow/InvestigationFlow";
import { INVESTIGATION_BASE_URI } from "../../../constants/apiURLs";
import { markdownToHtml } from "../../common/markdownToHtml";

export function InvestigationOverview({
isRunningInvestigation,
Expand Down Expand Up @@ -78,63 +79,80 @@ export function InvestigationOverview({
{/* investigation metadata card */}
<Row className="g-0">
<Col>
<InvestigationInfoCard investigation={investigation} />
<InvestigationInfoCard
investigation={investigation}
refetchTree={refetchTree}
/>
</Col>
</Row>
<Row className="g-0 mt-3">
<div className="mb-2">
<div className="">
<span className="fw-bold me-2 text-light">Description</span>
{isEditing ? (
<>
<IconButton
id="save-investigation-description"
Icon={BsFillCheckSquareFill}
size="sm"
color=""
className="text-secondary"
onClick={editInvestigationDescription}
/>
<Input
id="edit-investigation-description-input"
name="textArea"
type="textarea"
onChange={(event) => {
setInvestigationDescription(event.target.value);
}}
placeholder="Enter a description"
value={investigationDescription}
style={{ minHeight: "200px", overflowY: "auto" }}
className="bg-dark"
/>
</>
) : (
<>
<IconButton
id="edit-investigation-description"
Icon={MdEdit}
size="sm"
color=""
className="text-secondary"
onClick={() => setIsEditing(true)}
title="Edit description"
titlePlacement="top"
/>
<div
className={`form-control bg-dark border-dark ${
investigationDescription ? "text-light" : "text-gray"
}`}
style={{
maxHeight: "200px",
overflowY: "auto",
whiteSpace: "pre-line",
}}
>
{investigationDescription || "No description"}
</div>
</>
<IconButton
id="edit-investigation-description"
Icon={MdEdit}
color=""
className="text-secondary justify-content-center mx-0 px-1"
onClick={() => setIsEditing(true)}
title="Edit description"
titlePlacement="top"
/>
<IconButton
id="investigation-markdown-doc"
Icon={BsMarkdown}
color=""
className="text-secondary mx-0 px-1"
title="Markdown syntax"
titlePlacement="top"
href="https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax"
target="_blank"
rel="noreferrer"
/>
{isEditing && (
<IconButton
id="save-investigation-description"
Icon={BsFillCheckSquareFill}
color=""
className="text-secondary mx-0 px-1"
onClick={editInvestigationDescription}
title="Save"
titlePlacement="top"
/>
)}
</div>
</Row>
<Row className="g-0 mt-0 mb-2">
{isEditing ? (
<Input
id="edit-investigation-description-input"
name="textArea"
type="textarea"
onChange={(event) => {
setInvestigationDescription(event.target.value);
}}
placeholder="Enter a description"
value={investigationDescription}
style={{ minHeight: "200px", overflowY: "auto" }}
className="bg-dark"
/>
) : (
<div
className={`form-control bg-dark border-dark ${
investigationDescription ? "text-light" : "text-gray"
}`}
style={{
maxHeight: "200px",
overflowY: "auto",
whiteSpace: "pre-line",
lineHeight: "0.7",
}}
>
{investigationDescription
? markdownToHtml(investigationDescription)
: "No description"}
</div>
)}
</Row>
<Row
className="g-0 mt-3"
style={{ width: "100%", height: "70%", border: "1px solid #0b2b38" }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { useLocation } from "react-router-dom";

import { ObservableClassifications } from "../../../../constants/jobConst";
import { getObservableClassification } from "../../../../utils/observables";
import { markdownToHtml } from "../../../common/markdownToHtml";

export function VisualizerTooltip({
idElement,
Expand Down Expand Up @@ -58,7 +59,7 @@ export function VisualizerTooltip({
className="bg-body p-3 py-2 mb-1 text-start"
style={{ maxWidth: "400px" }}
>
<small>{description}</small>
<small>{markdownToHtml(description)}</small>
</div>
)}
</UncontrolledTooltip>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ describe("test InvestigationOverview", () => {
expect(
container.querySelector("#edit-investigation-description"),
).toBeInTheDocument();
// markdown icon
expect(
container.querySelector("#investigation-markdown-doc"),
).toBeInTheDocument();
});

test("Edit name", async () => {
Expand Down Expand Up @@ -133,6 +137,10 @@ describe("test InvestigationOverview", () => {
expect(
container.querySelector("#edit-investigation-description"),
).toBeInTheDocument();
// markdown icon
expect(
container.querySelector("#investigation-markdown-doc"),
).toBeInTheDocument();

await user.click(editNameButton);
const editNameInput = container.querySelector(
Expand Down Expand Up @@ -197,6 +205,10 @@ describe("test InvestigationOverview", () => {
"#edit-investigation-description",
);
expect(editDescriptionButton).toBeInTheDocument();
// markdown icon
expect(
container.querySelector("#investigation-markdown-doc"),
).toBeInTheDocument();

await user.click(editDescriptionButton);
const editDescriptionInput = container.querySelector(
Expand Down