Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UI – Clarify expected behavior of policy host counts, dashboard controls software count, and controls os updates versions count #25150

Merged
merged 5 commits into from
Jan 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions changes/23512-clarify-expected-behavior-of-host-counts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Clarify expected behavior of policy host counts, dashboard controls software count, and controls
os updates versions count.
10 changes: 9 additions & 1 deletion frontend/pages/DashboardPage/DashboardPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,15 @@ const DashboardPage = ({ router, location }: IDashboardProps): JSX.Element => {
setSoftwareTitleDetail(
<LastUpdatedText
lastUpdatedAt={data.counts_updated_at}
whatToRetrieve="software"
customTooltipText={
<>
Fleet periodically queries all hosts to
<br />
retrieve software. Click to view
<br />
hosts for the most up-to-date lists.
</>
}
/>
);
setShowSoftwareCard(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,17 @@ const CurrentVersionSection = ({
return (
<LastUpdatedText
lastUpdatedAt={data?.counts_updated_at}
whatToRetrieve="operating systems"
customTooltipText={
<>
Fleet periodically queries all hosts to
<br />
retrieve operating systems. Click to
<br />
view hosts for the most up-to-date
<br />
lists.
</>
}
/>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useQuery } from "react-query";
import { InjectedRouter } from "react-router/lib/Router";
import PATHS from "router/paths";
import { isEqual } from "lodash";
import { formatDistanceToNowStrict } from "date-fns";

import { getNextLocationPath, wait } from "utilities/helpers";

Expand Down Expand Up @@ -44,6 +45,7 @@ import Spinner from "components/Spinner";
import TeamsDropdown from "components/TeamsDropdown";
import TableDataError from "components/DataError";
import MainContent from "components/MainContent";
import LastUpdatedText from "components/LastUpdatedText";

import PoliciesTable from "./components/PoliciesTable";
import OtherWorkflowsModal from "./components/OtherWorkflowsModal";
Expand Down Expand Up @@ -776,22 +778,43 @@ const ManagePolicyPage = ({
}
}

const renderPoliciesCount = (count?: number) => {
const renderPoliciesCountAndLastUpdated = (
count?: number,
policies?: IPolicyStats[]
) => {
// Hide count if fetching count || there are errors OR there are no policy results with no a search filter
const isFetchingCount = !isAllTeamsSelected
? isFetchingTeamCountMergeInherited
: isFetchingGlobalCount;

const hideCount =
const hide =
isFetchingCount ||
policiesErrors ||
(!policyResults && searchQuery === "");

if (hideCount) {
if (hide) {
return null;
}
// Figure the time since the host counts were updated by finding first policy item with host_count_updated_at.
const updatedAt =
policies?.find((p) => !!p.host_count_updated_at)?.host_count_updated_at ||
"";

return <TableCount name="policies" count={count} />;
return (
<>
<TableCount name="policies" count={count} />
<LastUpdatedText
lastUpdatedAt={updatedAt}
customTooltipText={
<>
Counts are updated hourly. Click host
<br />
counts for the most up-to-date count.
</>
}
/>
</>
);
};

const renderMainTable = () => {
Expand All @@ -815,7 +838,12 @@ const ManagePolicyPage = ({
currentTeam={currentTeamSummary}
currentAutomatedPolicies={currentAutomatedPolicies}
isPremiumTier={isPremiumTier}
renderPoliciesCount={() => renderPoliciesCount(globalPoliciesCount)}
renderPoliciesCount={() =>
renderPoliciesCountAndLastUpdated(
globalPoliciesCount,
globalPolicies
)
}
searchQuery={searchQuery}
sortHeader={sortHeader}
sortDirection={sortDirection}
Expand Down Expand Up @@ -844,7 +872,10 @@ const ManagePolicyPage = ({
currentTeam={currentTeamSummary}
currentAutomatedPolicies={currentAutomatedPolicies}
renderPoliciesCount={() =>
renderPoliciesCount(teamPoliciesCountMergeInherited)
renderPoliciesCountAndLastUpdated(
teamPoliciesCountMergeInherited,
teamPolicies
)
}
isPremiumTier={isPremiumTier}
searchQuery={searchQuery}
Expand Down
4 changes: 4 additions & 0 deletions frontend/pages/policies/ManagePoliciesPage/_styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -295,4 +295,8 @@
}
}
}

.component__last-updated-text {
font-weight: normal;
}
Comment on lines +299 to +301
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why normal here and bold everywhere else? e.g.

image

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated globally here after confirming with @eugkuo https://github.com/fleetdm/fleet/pull/25143/files#r1904469843

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eugkuo 's comment to be consistent and unbold everywhere: #25143 (comment)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good, @jacobshandling in that case let's remove this carve-out so that it uses the global style

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RachelElysia I'm going to merge this in since it's approved – since your PR is still waiting for review, can you please remove this one-off style in favor of the global update in your PR?

}
Original file line number Diff line number Diff line change
@@ -1,37 +1,20 @@
import Icon from "components/Icon";
import React from "react";
import TooltipWrapper from "components/TooltipWrapper";

interface IPassingColumnHeaderProps {
isPassing: boolean;
timeSinceHostCountUpdate: string;
}

const baseClass = "passing-column-header";

const PassingColumnHeader = ({
isPassing,
timeSinceHostCountUpdate,
}: IPassingColumnHeaderProps) => {
const PassingColumnHeader = ({ isPassing }: IPassingColumnHeaderProps) => {
const iconName = isPassing ? "success" : "error";
const columnText = isPassing ? "Yes" : "No";
const updateText = timeSinceHostCountUpdate
? `Host count updated ${timeSinceHostCountUpdate}.`
: "";

return (
<div className={baseClass}>
<Icon name={iconName} />
<TooltipWrapper
tipContent={
<>
{updateText}
<br /> Counts are updated hourly.
</>
}
>
<span className="status-header-text">{columnText}</span>
</TooltipWrapper>
<span className="status-header-text">{columnText}</span>
</div>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ const PoliciesTable = ({
selectedTeamId: currentTeam?.id,
hasPermissionAndPoliciesToDelete,
},
policiesList,
isPremiumTier
)}
data={generateDataSet(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,7 @@
// disable this rule as it was throwing an error in Header and Cell component
// definitions for the selection row for some reason when we dont really need it.
import React from "react";
import {
formatDistanceToNowStrict,
millisecondsToHours,
millisecondsToMinutes,
} from "date-fns";
import { millisecondsToHours, millisecondsToMinutes } from "date-fns";
import { Tooltip as ReactTooltip5 } from "react-tooltip-5";
// @ts-ignore
import Checkbox from "components/forms/fields/Checkbox";
Expand Down Expand Up @@ -91,27 +87,10 @@ const generateTableHeaders = (
hasPermissionAndPoliciesToDelete?: boolean;
tableType?: string;
},
policiesList: IPolicyStats[] = [],
isPremiumTier?: boolean
): IDataColumn[] => {
const { selectedTeamId, hasPermissionAndPoliciesToDelete } = options;
const viewingTeamPolicies = selectedTeamId !== -1;
// Figure the time since the host counts were updated.
// First, find first policy item with host_count_updated_at.
const updatedAt =
policiesList.find((p) => !!p.host_count_updated_at)
?.host_count_updated_at || "";
let timeSinceHostCountUpdate = "";
if (updatedAt) {
try {
timeSinceHostCountUpdate = formatDistanceToNowStrict(
new Date(updatedAt),
{ addSuffix: true }
);
} catch (e) {
// Do nothing.
}
}

const tableHeaders: IDataColumn[] = [
{
Expand Down Expand Up @@ -170,12 +149,7 @@ const generateTableHeaders = (
title: "Yes",
Header: (cellProps) => (
<HeaderCell
value={
<PassingColumnHeader
isPassing
timeSinceHostCountUpdate={timeSinceHostCountUpdate}
/>
}
value={<PassingColumnHeader isPassing />}
isSortedDesc={cellProps.column.isSortedDesc}
/>
),
Expand Down Expand Up @@ -221,12 +195,7 @@ const generateTableHeaders = (
title: "No",
Header: (cellProps) => (
<HeaderCell
value={
<PassingColumnHeader
isPassing={false}
timeSinceHostCountUpdate={timeSinceHostCountUpdate}
/>
}
value={<PassingColumnHeader isPassing={false} />}
isSortedDesc={cellProps.column.isSortedDesc}
/>
),
Expand Down
Loading