Fleet UI: Fix os version pagination to 8 pp (#20410)

This commit is contained in:
RachelElysia 2024-07-12 16:04:59 -04:00 committed by GitHub
parent f20e4037b2
commit cc5ec6d8ed
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 126 additions and 18 deletions

View file

@ -9,6 +9,7 @@ import useTeamIdParam from "hooks/useTeamIdParam";
import TabsWrapper from "components/TabsWrapper";
import MainContent from "components/MainContent";
import TeamsDropdown from "components/TeamsDropdown";
import { parseOSUpdatesCurrentVersionsQueryParams } from "./OSUpdates/components/CurrentVersionSection/CurrentVersionSection";
interface IControlsSubNavItem {
name: string;
@ -43,6 +44,8 @@ interface IManageControlsPageProps {
query: {
team_id?: string;
page?: string;
order_key?: string;
order_direction?: "asc" | "desc";
};
};
router: InjectedRouter; // v3
@ -121,7 +124,11 @@ const ManageControlsPage = ({
</TabList>
</Tabs>
</TabsWrapper>
{React.cloneElement(children, { teamIdForApi, currentPage: page })}
{React.cloneElement(children, {
teamIdForApi,
currentPage: page,
queryParams: parseOSUpdatesCurrentVersionsQueryParams(location.query),
})}
</div>
);
};

View file

@ -101,10 +101,6 @@
gap: $pad-small;
}
&__profile-graphic--message {
text-align: center;
}
&__button-wrap {
display: flex;
justify-content: flex-end;

View file

@ -59,6 +59,10 @@
gap: $pad-small;
}
&__profile-graphic--message {
text-align: center;
}
&__button-wrap {
display: flex;
justify-content: flex-end;

View file

@ -9,7 +9,7 @@
border-right: none;
}
@media (max-width: $break-md) {
@media (max-width: 1120px) {
.view-hosts-link {
span {
display: none;

View file

@ -17,6 +17,7 @@ import NudgePreview from "./components/NudgePreview";
import TurnOnMdmMessage from "../components/TurnOnMdmMessage/TurnOnMdmMessage";
import CurrentVersionSection from "./components/CurrentVersionSection";
import TargetSection from "./components/TargetSection";
import { parseOSUpdatesCurrentVersionsQueryParams } from "./components/CurrentVersionSection/CurrentVersionSection";
export type OSUpdatesSupportedPlatform =
| "darwin"
@ -42,9 +43,10 @@ const getSelectedPlatform = (
interface IOSUpdates {
router: InjectedRouter;
teamIdForApi: number;
queryParams: ReturnType<typeof parseOSUpdatesCurrentVersionsQueryParams>;
}
const OSUpdates = ({ router, teamIdForApi }: IOSUpdates) => {
const OSUpdates = ({ router, teamIdForApi, queryParams }: IOSUpdates) => {
const { isPremiumTier, config, setConfig } = useContext(AppContext);
const [
@ -113,7 +115,11 @@ const OSUpdates = ({ router, teamIdForApi }: IOSUpdates) => {
</p>
<div className={`${baseClass}__content`}>
<div className={`${baseClass}__current-version-container`}>
<CurrentVersionSection currentTeamId={teamIdForApi} />
<CurrentVersionSection
router={router}
currentTeamId={teamIdForApi}
queryParams={queryParams}
/>
</div>
<div className={`${baseClass}__taget-container`}>
<TargetSection

View file

@ -1,6 +1,7 @@
import React from "react";
import { useQuery } from "react-query";
import { AxiosError } from "axios";
import { InjectedRouter } from "react-router";
import { IOperatingSystemVersion } from "interfaces/operating_system";
import {
@ -29,18 +30,47 @@ export type IFilteredOperatingSystemVersion = Omit<
const baseClass = "os-updates-current-version-section";
interface ICurrentVersionSectionProps {
router: InjectedRouter;
currentTeamId: number;
queryParams: ReturnType<typeof parseOSUpdatesCurrentVersionsQueryParams>;
}
const DEFAULT_SORT_DIRECTION = "desc";
const DEFAULT_SORT_HEADER = "hosts_count";
const DEFAULT_PAGE = 0;
const DEFAULT_PAGE_SIZE = 8;
export const parseOSUpdatesCurrentVersionsQueryParams = (queryParams: {
page?: string;
order_key?: string;
order_direction?: "asc" | "desc";
}) => {
const sortHeader = queryParams?.order_key ?? DEFAULT_SORT_HEADER;
const sortDirection = queryParams?.order_direction ?? DEFAULT_SORT_DIRECTION;
const page = queryParams?.page
? parseInt(queryParams.page, 10)
: DEFAULT_PAGE;
const pageSize = DEFAULT_PAGE_SIZE;
return {
page,
order_key: sortHeader,
order_direction: sortDirection,
per_page: pageSize,
};
};
const CurrentVersionSection = ({
router,
currentTeamId,
queryParams,
}: ICurrentVersionSectionProps) => {
const { data, isError, isLoading: isLoadingOsVersions } = useQuery<
IOSVersionsResponse,
AxiosError
>(
["os_versions", currentTeamId],
() => getOSVersions({ teamId: currentTeamId }),
["os_versions", currentTeamId, queryParams],
() => getOSVersions({ teamId: currentTeamId, ...queryParams }),
{
retry: false,
refetchOnWindowFocus: false,
@ -91,9 +121,11 @@ const CurrentVersionSection = ({
return (
<OSVersionTable
router={router}
osVersionData={filteredOSVersionData}
currentTeamId={currentTeamId}
isLoading={isLoadingOsVersions}
queryParams={queryParams}
/>
);
};

View file

@ -1,30 +1,92 @@
import React from "react";
import React, { useCallback } from "react";
import { InjectedRouter } from "react-router";
import PATHS from "router/paths";
import { IOperatingSystemVersion } from "interfaces/operating_system";
import { getNextLocationPath } from "utilities/helpers";
import { ITableQueryData } from "components/TableContainer/TableContainer";
import TableContainer from "components/TableContainer";
import { generateTableHeaders } from "./OSVersionTableConfig";
import OSVersionsEmptyState from "../OSVersionsEmptyState";
import { parseOSUpdatesCurrentVersionsQueryParams } from "../CurrentVersionSection/CurrentVersionSection";
const baseClass = "os-version-table";
interface IOSVersionTableProps {
router: InjectedRouter;
osVersionData: IOperatingSystemVersion[];
currentTeamId: number;
isLoading: boolean;
queryParams: ReturnType<typeof parseOSUpdatesCurrentVersionsQueryParams>;
}
const DEFAULT_SORT_HEADER = "hosts_count";
const DEFAULT_SORT_DIRECTION = "desc";
const OSVersionTable = ({
router,
osVersionData,
currentTeamId,
isLoading,
queryParams,
}: IOSVersionTableProps) => {
const columns = generateTableHeaders(currentTeamId);
const determineQueryParamChange = useCallback(
(newTableQuery: ITableQueryData) => {
const changedEntry = Object.entries(newTableQuery).find(([key, val]) => {
switch (key) {
case "sortDirection":
return val !== queryParams.order_direction;
case "sortHeader":
return val !== queryParams.order_key;
case "pageIndex":
return val !== queryParams.page;
default:
return false;
}
});
return changedEntry?.[0] ?? "";
},
[queryParams.order_direction, queryParams.order_key, queryParams.page]
);
const generateNewQueryParams = useCallback(
(newTableQuery: ITableQueryData, changedParam: string) => {
const newQueryParam: Record<string, string | number | undefined> = {
team_id: currentTeamId,
order_direction: newTableQuery.sortDirection,
order_key: newTableQuery.sortHeader,
page: changedParam === "pageIndex" ? newTableQuery.pageIndex : 0,
};
return newQueryParam;
},
[currentTeamId]
);
// NOTE: this is called once on initial render and every time the query changes
const onQueryChange = useCallback(
(newTableQuery: ITableQueryData) => {
// we want to determine which query param has changed in order to
// reset the page index to 0 if any other param has changed.
const changedParam = determineQueryParamChange(newTableQuery);
// if nothing has changed, don't update the route. this can happen when
// this handler is called on the inital render. Can also happen when
// the filter dropdown is changed. That is handled on the onChange handler
// for the dropdown.
if (changedParam === "") return;
const newRoute = getNextLocationPath({
pathPrefix: PATHS.CONTROLS_OS_UPDATES,
routeTemplate: "",
queryParams: generateNewQueryParams(newTableQuery, changedParam),
});
router.replace(newRoute);
},
[determineQueryParamChange, generateNewQueryParams, router]
);
return (
<div className={baseClass}>
<TableContainer
@ -35,12 +97,13 @@ const OSVersionTable = ({
emptyComponent={OSVersionsEmptyState}
showMarkAllPages={false}
isAllPagesSelected={false}
defaultSortHeader={DEFAULT_SORT_HEADER}
defaultSortDirection={DEFAULT_SORT_DIRECTION}
defaultSortHeader={queryParams.order_key}
defaultSortDirection={queryParams.order_direction}
defaultPageIndex={queryParams.page}
disableTableHeader
disableCount
pageSize={8}
isClientSidePagination
pageSize={queryParams.per_page}
onQueryChange={onQueryChange}
/>
</div>
);