diff --git a/changes/23312-update-policies-empty-state b/changes/23312-update-policies-empty-state index b02eb7f53f..3adbff0e33 100644 --- a/changes/23312-update-policies-empty-state +++ b/changes/23312-update-policies-empty-state @@ -1 +1 @@ -- Clarified text on the Policies page when no policies exist for the selected team (or All Teams) +- Clarified text on the Policies and Queries pages when no policies/queries exist for the selected team (or All Teams) diff --git a/frontend/pages/policies/ManagePoliciesPage/ManagePoliciesPage.tsx b/frontend/pages/policies/ManagePoliciesPage/ManagePoliciesPage.tsx index 8e563d7e32..915cc59aba 100644 --- a/frontend/pages/policies/ManagePoliciesPage/ManagePoliciesPage.tsx +++ b/frontend/pages/policies/ManagePoliciesPage/ManagePoliciesPage.tsx @@ -754,9 +754,8 @@ const ManagePolicyPage = ({ ? teamPolicies && teamPolicies.length > 0 : globalPolicies && globalPolicies.length > 0; - // Show CTA buttons if there is no errors AND there are policy results or a search filter - const showCtaButtons = - !policiesErrors && (policyResults || searchQuery !== ""); + // Show CTA buttons if there are no errors + const showCtaButtons = !policiesErrors; const automationsConfig = !isAllTeamsSelected ? teamConfig : config; const hasPoliciesToAutomateOrDelete = policiesAvailableToAutomate.length > 0; diff --git a/frontend/pages/policies/ManagePoliciesPage/components/PoliciesTable/PoliciesTable.tests.tsx b/frontend/pages/policies/ManagePoliciesPage/components/PoliciesTable/PoliciesTable.tests.tsx index 3b4f9c73a1..3367ce8515 100644 --- a/frontend/pages/policies/ManagePoliciesPage/components/PoliciesTable/PoliciesTable.tests.tsx +++ b/frontend/pages/policies/ManagePoliciesPage/components/PoliciesTable/PoliciesTable.tests.tsx @@ -8,6 +8,35 @@ import createMockPolicy from "__mocks__/policyMock"; import PoliciesTable from "./PoliciesTable"; describe("Policies table", () => { + it("Renders the page-wide empty state when no policies are present (free tier)", async () => { + const render = createCustomRenderer({ + context: { + app: { + isGlobalAdmin: true, + currentUser: createMockUser(), + }, + }, + }); + + render( + null} + resetPageIndex={false} + /> + ); + + expect(screen.getByText("You don't have any policies")).toBeInTheDocument(); + expect(screen.queryByText("Name")).toBeNull(); + expect(screen.queryByPlaceholderText("Search by name")).toBeNull(); + }); + it("Renders the page-wide empty state when no policies are present (all teams)", async () => { const render = createCustomRenderer({ context: { @@ -37,6 +66,7 @@ describe("Policies table", () => { screen.getByText("You don't have any policies that apply to all teams") ).toBeInTheDocument(); expect(screen.queryByText("Name")).toBeNull(); + expect(screen.queryByPlaceholderText("Search by name")).toBeNull(); }); it("Renders the page-wide empty state when no policies are present (specific team)", async () => { @@ -96,6 +126,7 @@ describe("Policies table", () => { ); expect(screen.getByText("No matching policies")).toBeInTheDocument(); + expect(screen.queryByPlaceholderText("Search by name")).toBeInTheDocument(); expect(screen.queryByText("Name")).toBeNull(); }); diff --git a/frontend/pages/policies/ManagePoliciesPage/components/PoliciesTable/PoliciesTable.tsx b/frontend/pages/policies/ManagePoliciesPage/components/PoliciesTable/PoliciesTable.tsx index ee3f098286..75d1a9a99d 100644 --- a/frontend/pages/policies/ManagePoliciesPage/components/PoliciesTable/PoliciesTable.tsx +++ b/frontend/pages/policies/ManagePoliciesPage/components/PoliciesTable/PoliciesTable.tsx @@ -62,26 +62,18 @@ const PoliciesTable = ({ "Add policies to detect device health issues and trigger automations.", }; - if ( - currentTeam?.id === null || - currentTeam?.id === APP_CONTEXT_ALL_TEAMS_ID - ) { - emptyState.header += " that apply to all teams"; - } else { - emptyState.header += " that apply to this team"; + if (isPremiumTier) { + if ( + currentTeam?.id === null || + currentTeam?.id === APP_CONTEXT_ALL_TEAMS_ID + ) { + emptyState.header += " that apply to all teams"; + } else { + emptyState.header += " that apply to this team"; + } } - if (canAddOrDeletePolicy) { - emptyState.primaryButton = ( - - ); - } else { + if (!canAddOrDeletePolicy) { emptyState.info = ""; } diff --git a/frontend/pages/queries/ManageQueriesPage/ManageQueriesPage.tsx b/frontend/pages/queries/ManageQueriesPage/ManageQueriesPage.tsx index f23dd14cc1..1502081880 100644 --- a/frontend/pages/queries/ManageQueriesPage/ManageQueriesPage.tsx +++ b/frontend/pages/queries/ManageQueriesPage/ManageQueriesPage.tsx @@ -291,6 +291,7 @@ const ManageQueriesPage = ({ router={router} queryParams={location.query} currentTeamId={teamIdForApi} + isPremiumTier={isPremiumTier} /> ); }; @@ -381,13 +382,6 @@ const ManageQueriesPage = ({ isTeamMaintainer || isObserverPlus; // isObserverPlus checks global and selected team - const hideQueryActions = - // there are no filters and no returned queries, indicating there are no global/team queries at all - !(!!location.query.query || !!location.query.platform) && - !queriesResponse?.count && - // the user has permission - (!isOnlyObserver || isObserverPlus || isAnyTeamObserverPlus); - return (
@@ -398,7 +392,7 @@ const ManageQueriesPage = ({
- {!hideQueryActions && ( + {canCustomQuery && (
{(isGlobalAdmin || isTeamAdmin) && !onlyInheritedQueries && ( - ); - } + const emptyParams: IEmptyTableProps = { + graphicName: "empty-queries", + header: "You don't have any queries", + }; - return emptyParams; - }, [ - isAnyTeamObserverPlus, - isObserverPlus, - isOnlyObserver, - onCreateQueryClick, - searchQuery, - ]); + if (isPremiumTier) { + if ( + typeof currentTeamId === "undefined" || + currentTeamId === null || + currentTeamId === APP_CONTEXT_ALL_TEAMS_ID + ) { + emptyParams.header += " that apply to all teams"; + } else { + emptyParams.header += " that apply to this team"; + } + } + + if (searchQuery || curTargetedPlatformFilter !== "all") { + delete emptyParams.graphicName; + emptyParams.header = "No matching queries"; + emptyParams.info = "No queries match the current filters."; + } else if (!isOnlyObserver || isObserverPlus || isAnyTeamObserverPlus) { + emptyParams.additionalInfo = ( + <> + Create a new query, or{" "} + + + ); + } const handlePlatformFilterDropdownChange = useCallback( (selectedTargetedPlatform: SingleValue) => { @@ -264,26 +261,7 @@ const QueriesTable = ({ ); const searchable = - (totalQueriesCount ?? 0) > 0 || - !!curTargetedPlatformFilter || - !!searchQuery; - - const emptyComponent = useCallback(() => { - const { - graphicName, - header, - info, - additionalInfo, - primaryButton, - } = getEmptyStateParams(); - return EmptyTable({ - graphicName, - header, - info, - additionalInfo, - primaryButton, - }); - }, [getEmptyStateParams]); + (totalQueriesCount ?? 0) > 0 || !!targetedPlatformParam || !!searchQuery; const trimmedSearchQuery = searchQuery.trim(); @@ -310,10 +288,13 @@ const QueriesTable = ({ variant: "text-icon", onActionButtonClick: onDeleteQueryClick, }} - emptyComponent={emptyComponent} - renderCount={() => ( - - )} + emptyComponent={() => EmptyTable(emptyParams)} + renderCount={() => + ((totalQueriesCount || searchQuery) && ( + + )) || + null + } inputPlaceHolder="Search by name" onQueryChange={onQueryChange} searchable={searchable}