Fix UI support old software urls (#15727)

relates to #15704

Support old software/:id urls and forward them to software/versions/:id

Also some small UI state improvements
This commit is contained in:
Gabriel Hernandez 2023-12-18 21:12:00 +00:00 committed by GitHub
parent 32580c823d
commit a10a951827
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 98 additions and 71 deletions

View file

@ -9,6 +9,7 @@ import softwareAPI, {
import MainContent from "components/MainContent";
import TableDataError from "components/DataError";
import Spinner from "components/Spinner";
import SoftwareDetailsSummary from "../components/SoftwareDetailsSummary";
import SoftwareTitleDetailsTable from "./SoftwareTitleDetailsTable";
@ -43,37 +44,47 @@ const SoftwareTitleDetailsPage = ({
}
);
if (!softwareTitle) {
return null;
}
const renderContent = () => {
if (isSoftwareTitleLoading) {
return <Spinner />;
}
if (isSoftwareTitleError) {
return <TableDataError className={`${baseClass}__table-error`} />;
}
if (!softwareTitle) {
return null;
}
return (
<>
<SoftwareDetailsSummary
id={softwareId}
title={softwareTitle.name}
type={formatSoftwareType(softwareTitle)}
versions={softwareTitle.versions.length}
hosts={softwareTitle.hosts_count}
queryParam="software_title_id"
name={softwareTitle.name}
source={softwareTitle.source}
/>
{/* TODO: can we use Card here for card styles */}
<div className={`${baseClass}__versions-section`}>
<h2>Versions</h2>
<SoftwareTitleDetailsTable
router={router}
data={softwareTitle.versions}
isLoading={isSoftwareTitleLoading}
/>
</div>
</>
);
};
return (
<MainContent className={baseClass}>
{isSoftwareTitleError ? (
<TableDataError className={`${baseClass}__table-error`} />
) : (
<>
<SoftwareDetailsSummary
id={softwareId}
title={softwareTitle.name}
type={formatSoftwareType(softwareTitle)}
versions={softwareTitle.versions.length}
hosts={softwareTitle.hosts_count}
queryParam="software_title_id"
name={softwareTitle.name}
source={softwareTitle.source}
/>
{/* TODO: can we use Card here for card styles */}
<div className={`${baseClass}__versions-section`}>
<h2>Versions</h2>
<SoftwareTitleDetailsTable
router={router}
data={softwareTitle.versions}
isLoading={isSoftwareTitleLoading}
/>
</div>
</>
)}
<>{renderContent()}</>
</MainContent>
);
};

View file

@ -18,6 +18,7 @@ import TableContainer from "components/TableContainer";
import CustomLink from "components/CustomLink";
import EmptyTable from "components/EmptyTable";
import TableDataError from "components/DataError";
import Spinner from "components/Spinner";
import generateSoftwareVersionDetailsTableConfig from "./SoftwareVersionDetailsTableConfig";
import SoftwareDetailsSummary from "../components/SoftwareDetailsSummary";
@ -55,9 +56,7 @@ const SoftwareVersionDetailsPage = ({
routeParams,
}: ISoftwareTitleDetailsPageProps) => {
const versionId = parseInt(routeParams.id, 10);
const { isPremiumTier, isSandboxMode, filteredSoftwarePath } = useContext(
AppContext
);
const { isPremiumTier, isSandboxMode } = useContext(AppContext);
const {
data: softwareVersion,
@ -95,49 +94,59 @@ const SoftwareVersionDetailsPage = ({
[isPremiumTier, isSandboxMode]
);
if (!softwareVersion) {
return null;
}
const renderContent = () => {
if (isSoftwareVersionLoading) {
return <Spinner />;
}
if (isSoftwareVersionError) {
return <TableDataError className={`${baseClass}__table-error`} />;
}
if (!softwareVersion) {
return null;
}
return (
<>
<SoftwareDetailsSummary
id={softwareVersion.id}
title={`${softwareVersion.name}, ${softwareVersion.version}`}
type={formatSoftwareType(softwareVersion)}
hosts={hostsCount ?? 0}
queryParam="software_version_id"
name={softwareVersion.name}
source={softwareVersion.source}
/>
<div className={`${baseClass}__vulnerabilities-section`}>
<h2 className="section__header">Vulnerabilities</h2>
{softwareVersion?.vulnerabilities?.length ? (
<div className="vuln-table">
<TableContainer
columnConfigs={tableHeaders}
data={softwareVersion.vulnerabilities}
defaultSortHeader={isPremiumTier ? "epss_probability" : "cve"}
defaultSortDirection={"desc"}
emptyComponent={NoVulnsDetected}
isAllPagesSelected={false}
isLoading={isSoftwareVersionLoading}
isClientSidePagination
pageSize={20}
resultsTitle={"vulnerabilities"}
showMarkAllPages={false}
/>
</div>
) : (
<NoVulnsDetected />
)}
</div>
</>
);
};
return (
<MainContent className={baseClass}>
{isSoftwareVersionError ? (
<TableDataError className={`${baseClass}__table-error`} />
) : (
<>
<SoftwareDetailsSummary
id={softwareVersion.id}
title={`${softwareVersion.name}, ${softwareVersion.version}`}
type={formatSoftwareType(softwareVersion)}
hosts={hostsCount ?? 0}
queryParam="software_version_id"
name={softwareVersion.name}
source={softwareVersion.source}
/>
<div className={`${baseClass}__vulnerabilities-section`}>
<h2 className="section__header">Vulnerabilities</h2>
{softwareVersion?.vulnerabilities?.length ? (
<div className="vuln-table">
<TableContainer
columnConfigs={tableHeaders}
data={softwareVersion.vulnerabilities}
defaultSortHeader={isPremiumTier ? "epss_probability" : "cve"}
defaultSortDirection={"desc"}
emptyComponent={NoVulnsDetected}
isAllPagesSelected={false}
isLoading={isSoftwareVersionLoading}
isClientSidePagination
pageSize={20}
resultsTitle={"vulnerabilities"}
showMarkAllPages={false}
/>
</div>
) : (
<NoVulnsDetected />
)}
</div>
</>
)}
<>{renderContent()}</>
</MainContent>
);
};

View file

@ -218,6 +218,8 @@ const routes = (
<Route component={SoftwarePage}>
<Route path="titles" component={SoftwareTitles} />
<Route path="versions" component={SoftwareVersions} />
{/* This redirect keeps the old software/:id working */}
<Redirect from=":id" to="versions/:id" />
</Route>
<Route path="titles/:id" component={SoftwareTitleDetailsPage} />
<Route path="versions/:id" component={SoftwareVersionDetailsPage} />

View file

@ -85,7 +85,12 @@ export default {
FORGOT_PASSWORD: `${URL_PREFIX}/login/forgot`,
NO_ACCESS: `${URL_PREFIX}/login/denied`,
API_ONLY_USER: `${URL_PREFIX}/apionlyuser`,
// error pages
FLEET_403: `${URL_PREFIX}/403`,
FLEET_404: `${URL_PREFIX}/404`,
FLEET_500: `${URL_PREFIX}/500`,
LOGIN: `${URL_PREFIX}/login`,
LOGOUT: `${URL_PREFIX}/logout`,
MANAGE_HOSTS: `${URL_PREFIX}/hosts/manage`,