mirror of
https://github.com/fleetdm/fleet
synced 2026-05-23 08:58:41 +00:00
Fleet UI: Fix os version pagination to 8 pp (#20410)
This commit is contained in:
parent
f20e4037b2
commit
cc5ec6d8ed
7 changed files with 126 additions and 18 deletions
|
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -101,10 +101,6 @@
|
|||
gap: $pad-small;
|
||||
}
|
||||
|
||||
&__profile-graphic--message {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&__button-wrap {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
|
|
|
|||
|
|
@ -59,6 +59,10 @@
|
|||
gap: $pad-small;
|
||||
}
|
||||
|
||||
&__profile-graphic--message {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&__button-wrap {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
border-right: none;
|
||||
}
|
||||
|
||||
@media (max-width: $break-md) {
|
||||
@media (max-width: 1120px) {
|
||||
.view-hosts-link {
|
||||
span {
|
||||
display: none;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in a new issue