Reconmap/web-client

View on GitHub
src/components/vulnerabilities/templates/List.jsx

Summary

Maintainability
D
1 day
Test Coverage
import VulnerabilityBadge from "components/badges/VulnerabilityBadge";
import PageTitle from "components/logic/PageTitle";
import AscendingSortLink from "components/ui/AscendingSortLink";
import Breadcrumb from "components/ui/Breadcrumb";
import DescendingSortLink from "components/ui/DescendingSortLink";
import { IconDocumentDuplicate, IconPlus } from "components/ui/Icons";
import Loading from "components/ui/Loading";
import NoResults from "components/ui/NoResults";
import CreateButton from "components/ui/buttons/Create";
import DeleteIconButton from "components/ui/buttons/DeleteIconButton";
import LinkButton from "components/ui/buttons/Link";
import PrimaryButton from "components/ui/buttons/Primary";
import useDelete from "hooks/useDelete";
import useFetch from "hooks/useFetch";
import { useState } from "react";
import { Link, useNavigate } from "react-router-dom";
import secureApiFetch from "services/api";
import VulnerabilityCategorySpan from "../categories/Span";

const VulnerabilityTemplatesList = () => {
    const navigate = useNavigate();
    const [sortBy, setSortBy] = useState({
        column: "insert_ts",
        order: "DESC",
    });
    const [templates, updateTemplates] = useFetch(
        `/vulnerabilities?isTemplate=1&orderColumn=${sortBy.column}&orderDirection=${sortBy.order}`,
    );

    const cloneVulnerability = (ev, templateId) => {
        ev.stopPropagation();

        secureApiFetch(`/vulnerabilities/${templateId}/clone`, {
            method: "POST",
        })
            .then((resp) => resp.json())
            .then((data) => {
                navigate(`/vulnerabilities/${data.vulnerabilityId}/edit`);
            });
    };

    const onSortChange = (ev, column, order) => {
        ev.preventDefault();

        setSortBy({ column: column, order: order });
    };

    const viewTemplate = (templateId) => {
        navigate(`/vulnerabilities/templates/${templateId}`);
    };

    const destroy = useDelete("/vulnerabilities/", updateTemplates);

    const deleteTemplate = (ev, templateId) => {
        ev.stopPropagation();

        destroy(templateId);
    };

    const onAddVulnerabilityTemplateClick = () => {
        navigate(`/vulnerabilities/create?isTemplate=true`);
    };

    return (
        <>
            <PageTitle value="Vulnerability templates" />
            <div className="heading">
                <Breadcrumb>
                    <Link to="/vulnerabilities">Vulnerabilities</Link>
                </Breadcrumb>

                <CreateButton onClick={onAddVulnerabilityTemplateClick}>
                    Add vulnerability template
                </CreateButton>
            </div>
            <title
                title="Vulnerability templates"
                icon={<IconDocumentDuplicate />}
            />
            {!templates ? (
                <Loading />
            ) : (
                <table className="rm-listing">
                    <thead>
                        <tr>
                            <th>Summary</th>
                            <th colSpan={2}>
                                <DescendingSortLink
                                    callback={onSortChange}
                                    property="category_name"
                                />{" "}
                                Category{" "}
                                <AscendingSortLink
                                    callback={onSortChange}
                                    property="category_name"
                                />
                            </th>
                        </tr>
                    </thead>
                    <tbody>
                        {templates.length === 0 ? (
                            <tr>
                                <td colSpan={3}>
                                    <NoResults />
                                </td>
                            </tr>
                        ) : (
                            templates.map((template) => (
                                <tr
                                    key={template.id}
                                    onClick={() => viewTemplate(template.id)}
                                >
                                    <td>
                                        <VulnerabilityBadge
                                            vulnerability={template}
                                        />
                                    </td>
                                    <td>
                                        <VulnerabilityCategorySpan
                                            name={template.category_name}
                                            parentName={
                                                template.parent_category_name
                                            }
                                        />
                                    </td>
                                    <td textAlign="right">
                                        <PrimaryButton
                                            onClick={(ev) =>
                                                cloneVulnerability(
                                                    ev,
                                                    template.id,
                                                )
                                            }
                                            key={template.id}
                                            title="Clone"
                                            leftIcon={<IconPlus />}
                                        >
                                            Clone and edit
                                        </PrimaryButton>
                                        <LinkButton
                                            href={`/vulnerabilities/${template.id}/edit`}
                                        >
                                            Edit
                                        </LinkButton>
                                        <DeleteIconButton
                                            onClick={(ev) =>
                                                deleteTemplate(ev, template.id)
                                            }
                                        />
                                    </td>
                                </tr>
                            ))
                        )}
                    </tbody>
                </table>
            )}
        </>
    );
};

export default VulnerabilityTemplatesList;