Fleet UI: Host details page includes team_id param in URL (#39801)
This commit is contained in:
@@ -0,0 +1 @@
|
||||
- Fleet UI: Host details page includes team_id param in URL to allow retaining team on refresh
|
||||
@@ -87,7 +87,7 @@ const lastSeenTime = (status: string, seenTime: string): string => {
|
||||
return "Online";
|
||||
};
|
||||
|
||||
const allHostTableHeaders: IHostTableColumnConfig[] = [
|
||||
const allHostTableHeaders = (teamId?: number): IHostTableColumnConfig[] => [
|
||||
// We are using React Table useRowSelect functionality for the selection header.
|
||||
// More information on its API can be found here
|
||||
// https://react-table.tanstack.com/docs/api/useRowSelect
|
||||
@@ -158,7 +158,7 @@ const allHostTableHeaders: IHostTableColumnConfig[] = [
|
||||
return (
|
||||
<LinkCell
|
||||
value={cellProps.cell.value}
|
||||
path={PATHS.HOST_DETAILS(cellProps.row.original.id)}
|
||||
path={PATHS.HOST_DETAILS(cellProps.row.original.id, teamId)}
|
||||
title={lastSeenTime(
|
||||
cellProps.row.original.status,
|
||||
cellProps.row.original.seen_time
|
||||
@@ -697,11 +697,13 @@ const defaultHiddenColumns = [
|
||||
const generateAvailableTableHeaders = ({
|
||||
isFreeTier = true,
|
||||
isOnlyObserver = true,
|
||||
teamId,
|
||||
}: {
|
||||
isFreeTier: boolean | undefined;
|
||||
isOnlyObserver: boolean | undefined;
|
||||
teamId?: number;
|
||||
}): IHostTableColumnConfig[] => {
|
||||
return allHostTableHeaders.reduce(
|
||||
return allHostTableHeaders(teamId).reduce(
|
||||
(columns: Column<IHost>[], currentColumn: Column<IHost>) => {
|
||||
// skip over column headers that are not shown in free observer tier
|
||||
if (isFreeTier) {
|
||||
@@ -738,17 +740,21 @@ const generateVisibleTableColumns = ({
|
||||
hiddenColumns,
|
||||
isFreeTier = true,
|
||||
isOnlyObserver = true,
|
||||
teamId,
|
||||
}: {
|
||||
hiddenColumns: string[];
|
||||
isFreeTier: boolean | undefined;
|
||||
isOnlyObserver: boolean | undefined;
|
||||
teamId?: number;
|
||||
}): IHostTableColumnConfig[] => {
|
||||
// remove columns set as hidden by the user.
|
||||
return generateAvailableTableHeaders({ isFreeTier, isOnlyObserver }).filter(
|
||||
(column) => {
|
||||
return !hiddenColumns.includes(column.id as string);
|
||||
}
|
||||
);
|
||||
return generateAvailableTableHeaders({
|
||||
isFreeTier,
|
||||
isOnlyObserver,
|
||||
teamId,
|
||||
}).filter((column) => {
|
||||
return !hiddenColumns.includes(column.id as string);
|
||||
});
|
||||
};
|
||||
|
||||
export {
|
||||
|
||||
@@ -1568,6 +1568,7 @@ const ManageHostsPage = ({
|
||||
hiddenColumns: currentHiddenColumns,
|
||||
isFreeTier,
|
||||
isOnlyObserver,
|
||||
teamId: teamIdForApi,
|
||||
});
|
||||
|
||||
const columnIds = tableColumns
|
||||
@@ -1810,6 +1811,7 @@ const ManageHostsPage = ({
|
||||
isOnlyObserver ||
|
||||
isGlobalTechnician ||
|
||||
(!isOnGlobalTeam && !isTeamMaintainerOrTeamAdmin),
|
||||
teamId: teamIdForApi,
|
||||
});
|
||||
|
||||
const emptyState = () => {
|
||||
|
||||
@@ -163,6 +163,7 @@ interface IHostDetailsProps {
|
||||
query?: string;
|
||||
order_key?: string;
|
||||
order_direction?: "asc" | "desc";
|
||||
team_id?: string;
|
||||
};
|
||||
search?: string;
|
||||
};
|
||||
@@ -973,7 +974,7 @@ const HostDetailsPage = ({
|
||||
const onClickAddQuery = () => {
|
||||
router.push(
|
||||
getPathWithQueryParams(PATHS.NEW_QUERY, {
|
||||
team_id: currentTeam?.id,
|
||||
team_id: currentTeam?.id || location.query.team_id,
|
||||
host_id: hostIdFromURL,
|
||||
})
|
||||
);
|
||||
@@ -1097,12 +1098,20 @@ const HostDetailsPage = ({
|
||||
|
||||
const navigateToNav = (i: number): void => {
|
||||
const navPath = hostDetailsSubNav[i].pathname;
|
||||
router.push(navPath);
|
||||
router.push(
|
||||
getPathWithQueryParams(navPath, {
|
||||
team_id: currentTeam?.id || location.query.team_id,
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
const navigateToSoftwareTab = (i: number): void => {
|
||||
const navPath = hostSoftwareSubNav[i].pathname;
|
||||
router.push(navPath);
|
||||
router.push(
|
||||
getPathWithQueryParams(navPath, {
|
||||
team_id: currentTeam?.id || location.query.team_id,
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
const isHostTeamAdmin = permissions.isTeamAdmin(currentUser, host?.team_id);
|
||||
@@ -1285,7 +1294,12 @@ const HostDetailsPage = ({
|
||||
<div className={`${baseClass}__header-links`}>
|
||||
<BackButton
|
||||
text="Back to all hosts"
|
||||
path={filteredHostsPath || PATHS.MANAGE_HOSTS}
|
||||
path={
|
||||
filteredHostsPath ||
|
||||
getPathWithQueryParams(PATHS.MANAGE_HOSTS, {
|
||||
team_id: location.query.team_id,
|
||||
})
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div className={`${baseClass}__header-summary`}>
|
||||
|
||||
@@ -119,7 +119,7 @@ const HostQueryReport = ({
|
||||
<div className={`${baseClass}__header__row1`}>
|
||||
<BackButton
|
||||
text="Back to host details"
|
||||
path={PATHS.HOST_DETAILS_PAGE(hostId)}
|
||||
path={PATHS.HOST_DETAILS(hostId)}
|
||||
/>
|
||||
</div>
|
||||
<div className={`${baseClass}__header__row2`}>
|
||||
|
||||
@@ -88,6 +88,7 @@ export const parseHostSoftwareLibraryQueryParams = (queryParams: {
|
||||
order_key?: string;
|
||||
order_direction?: "asc" | "desc";
|
||||
self_service?: string;
|
||||
team_id?: string;
|
||||
}) => {
|
||||
const searchQuery = queryParams?.query ?? DEFAULT_SEARCH_QUERY;
|
||||
const sortHeader = queryParams?.order_key ?? DEFAULT_SORT_HEADER;
|
||||
@@ -97,6 +98,9 @@ export const parseHostSoftwareLibraryQueryParams = (queryParams: {
|
||||
: DEFAULT_PAGE;
|
||||
const pageSize = DEFAULT_PAGE_SIZE;
|
||||
const selfService = queryParams?.self_service === "true";
|
||||
const teamId = queryParams?.team_id
|
||||
? parseInt(queryParams.team_id, 10)
|
||||
: undefined;
|
||||
|
||||
return {
|
||||
page,
|
||||
@@ -106,6 +110,7 @@ export const parseHostSoftwareLibraryQueryParams = (queryParams: {
|
||||
per_page: pageSize,
|
||||
available_for_install: true, // always true for host installers
|
||||
self_service: selfService,
|
||||
team_id: teamId,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -605,6 +610,7 @@ const HostSoftwareLibrary = ({
|
||||
page={queryParams.page}
|
||||
pagePath={pathname}
|
||||
selfService={queryParams.self_service}
|
||||
teamId={queryParams.team_id}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
+4
@@ -41,6 +41,7 @@ interface IHostSoftwareLibraryTableProps {
|
||||
page: number;
|
||||
pagePath: string;
|
||||
selfService: boolean;
|
||||
teamId?: number;
|
||||
}
|
||||
|
||||
const HostSoftwareLibraryTable = ({
|
||||
@@ -56,6 +57,7 @@ const HostSoftwareLibraryTable = ({
|
||||
selfService,
|
||||
page,
|
||||
pagePath,
|
||||
teamId,
|
||||
}: IHostSoftwareLibraryTableProps) => {
|
||||
const determineQueryParamChange = useCallback(
|
||||
(newTableQuery: ITableQueryData) => {
|
||||
@@ -85,6 +87,7 @@ const HostSoftwareLibraryTable = ({
|
||||
order_direction: newTableQuery.sortDirection,
|
||||
order_key: newTableQuery.sortHeader,
|
||||
page: changedParam === "pageIndex" ? newTableQuery.pageIndex : 0,
|
||||
team_id: teamId,
|
||||
...(selfService && { self_service: "true" }),
|
||||
};
|
||||
|
||||
@@ -125,6 +128,7 @@ const HostSoftwareLibraryTable = ({
|
||||
orderDirection: sortDirection,
|
||||
orderKey: sortHeader,
|
||||
page: 0, // resets page index
|
||||
teamId,
|
||||
...(value === "selfService" && { selfService: true }),
|
||||
};
|
||||
|
||||
|
||||
@@ -81,6 +81,7 @@ export const parseHostSoftwareQueryParams = (queryParams: {
|
||||
max_cvss_score?: string;
|
||||
self_service?: string;
|
||||
category_id?: string;
|
||||
team_id?: string;
|
||||
}) => {
|
||||
const searchQuery = queryParams?.query ?? DEFAULT_SEARCH_QUERY;
|
||||
const sortHeader = queryParams?.order_key ?? DEFAULT_SORT_HEADER;
|
||||
@@ -96,6 +97,9 @@ export const parseHostSoftwareQueryParams = (queryParams: {
|
||||
? parseInt(queryParams.category_id, 10)
|
||||
: undefined;
|
||||
const selfService = queryParams?.self_service === "true";
|
||||
const teamId = queryParams?.team_id
|
||||
? parseInt(queryParams.team_id, 10)
|
||||
: undefined;
|
||||
|
||||
return {
|
||||
page,
|
||||
@@ -110,6 +114,7 @@ export const parseHostSoftwareQueryParams = (queryParams: {
|
||||
exploit: softwareVulnFilters.exploit,
|
||||
available_for_install: false, // always false for host software
|
||||
category_id: categoryId,
|
||||
team_id: teamId,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -228,6 +233,7 @@ const HostSoftware = ({
|
||||
orderKey: queryParams.order_key,
|
||||
perPage: queryParams.per_page,
|
||||
page: 0, // resets page index
|
||||
team_id: queryParams.team_id,
|
||||
...buildSoftwareVulnFiltersQueryParams(vulnFilters),
|
||||
};
|
||||
|
||||
@@ -304,6 +310,7 @@ const HostSoftware = ({
|
||||
min_cvss_score: queryParams.min_cvss_score,
|
||||
max_cvss_score: queryParams.max_cvss_score,
|
||||
})}
|
||||
teamId={queryParams.team_id}
|
||||
onAddFiltersClick={toggleSoftwareFiltersModal}
|
||||
// for my device software details modal toggling
|
||||
isMyDevicePage={isMyDevicePage}
|
||||
|
||||
@@ -75,6 +75,7 @@ interface IHostSoftwareTableProps {
|
||||
page: number;
|
||||
pagePath: string;
|
||||
vulnFilters: ISoftwareVulnFiltersParams;
|
||||
teamId?: number;
|
||||
onAddFiltersClick: () => void;
|
||||
isMyDevicePage?: boolean;
|
||||
onShowInventoryVersions: (software: IHostSoftware) => void;
|
||||
@@ -92,6 +93,7 @@ const HostSoftwareTable = ({
|
||||
page,
|
||||
pagePath,
|
||||
vulnFilters,
|
||||
teamId,
|
||||
onAddFiltersClick,
|
||||
isMyDevicePage,
|
||||
onShowInventoryVersions,
|
||||
@@ -124,6 +126,7 @@ const HostSoftwareTable = ({
|
||||
order_direction: newTableQuery.sortDirection,
|
||||
order_key: newTableQuery.sortHeader,
|
||||
page: changedParam === "pageIndex" ? newTableQuery.pageIndex : 0,
|
||||
team_id: teamId,
|
||||
...buildSoftwareVulnFiltersQueryParams(vulnFilters),
|
||||
};
|
||||
return newQueryParam;
|
||||
|
||||
@@ -257,7 +257,10 @@ const QueryDetailsPage = ({
|
||||
const backPath = () => {
|
||||
if (filteredQueriesPath) return filteredQueriesPath;
|
||||
|
||||
if (hostId) return getPathWithQueryParams(PATHS.HOST_DETAILS(hostId));
|
||||
if (hostId)
|
||||
return getPathWithQueryParams(
|
||||
PATHS.HOST_DETAILS(hostId, currentTeamId)
|
||||
);
|
||||
|
||||
return getPathWithQueryParams(PATHS.MANAGE_QUERIES, {
|
||||
team_id: currentTeamId,
|
||||
|
||||
@@ -381,7 +381,7 @@ const EditQueryPage = ({
|
||||
}
|
||||
|
||||
if (hostId) {
|
||||
return getPathWithQueryParams(PATHS.HOST_DETAILS(hostId));
|
||||
return getPathWithQueryParams(PATHS.HOST_DETAILS(hostId, currentTeamId));
|
||||
}
|
||||
|
||||
if (filteredQueriesPath) return filteredQueriesPath;
|
||||
|
||||
@@ -141,10 +141,10 @@ export default {
|
||||
MANAGE_HOSTS_LABEL: (labelId: number | string): string => {
|
||||
return `${URL_PREFIX}/hosts/manage/labels/${labelId}`;
|
||||
},
|
||||
HOST_DETAILS_PAGE: (id: number): string => {
|
||||
return `${URL_PREFIX}/hosts/${id}`;
|
||||
},
|
||||
HOST_DETAILS: (id: number): string => {
|
||||
HOST_DETAILS: (id: number, teamId?: number): string => {
|
||||
if (teamId) {
|
||||
return `${URL_PREFIX}/hosts/${id}/details?team_id=${teamId}`;
|
||||
}
|
||||
return `${URL_PREFIX}/hosts/${id}/details`;
|
||||
},
|
||||
HOST_SCRIPTS: (id: number): string => {
|
||||
|
||||
Reference in New Issue
Block a user