From 43edf1a9a43f693113c457eb94c44dffbed33d5a Mon Sep 17 00:00:00 2001 From: Nico <32375741+nulmete@users.noreply.github.com> Date: Fri, 5 Jun 2026 11:25:54 -0300 Subject: [PATCH] Reuse Policies' Automations button on Dashboard, Software, and Reports (#46846) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolves #45147 (AutomationsButton introduced as part of that issue) ## Testing - [x] QA'd all new/changed functionality manually ## Summary by CodeRabbit * **New Features** * Introduces a standardized "Automations" button (settings icon + label) and replaces prior controls across Dashboard, Software, Policies, and Queries pages. * Info cards and page actions now support an "automations" action type to consistently open automation management from relevant UIs. --- .../AutomationsButton/AutomationsButton.tsx | 35 +++++++++++++++++++ .../buttons/AutomationsButton/index.ts | 1 + frontend/components/buttons/Button/index.ts | 1 + .../pages/DashboardPage/DashboardPage.tsx | 3 +- .../components/InfoCard/InfoCard.tsx | 15 ++++++++ frontend/pages/SoftwarePage/SoftwarePage.tsx | 8 ++--- .../ManagePoliciesPage/ManagePoliciesPage.tsx | 12 ++----- .../policies/ManagePoliciesPage/_styles.scss | 6 ---- .../ManageQueriesPage/ManageQueriesPage.tsx | 15 +++----- 9 files changed, 64 insertions(+), 32 deletions(-) create mode 100644 frontend/components/buttons/AutomationsButton/AutomationsButton.tsx create mode 100644 frontend/components/buttons/AutomationsButton/index.ts diff --git a/frontend/components/buttons/AutomationsButton/AutomationsButton.tsx b/frontend/components/buttons/AutomationsButton/AutomationsButton.tsx new file mode 100644 index 0000000000..d7b29390bf --- /dev/null +++ b/frontend/components/buttons/AutomationsButton/AutomationsButton.tsx @@ -0,0 +1,35 @@ +import React from "react"; +import classnames from "classnames"; + +import Button, { IButtonProps } from "components/buttons/Button"; +import Icon from "components/Icon"; + +const baseClass = "automations-button"; + +export type IAutomationsButtonProps = Pick< + IButtonProps, + "onClick" | "disabled" | "className" | "size" +>; + +const AutomationsButton = ({ + onClick, + disabled, + className, + size, +}: IAutomationsButtonProps): JSX.Element => { + const classNames = classnames(baseClass, className); + + return ( + + Automations + + ); +}; + +export default AutomationsButton; diff --git a/frontend/components/buttons/AutomationsButton/index.ts b/frontend/components/buttons/AutomationsButton/index.ts new file mode 100644 index 0000000000..5d008f710c --- /dev/null +++ b/frontend/components/buttons/AutomationsButton/index.ts @@ -0,0 +1 @@ +export { default } from "./AutomationsButton"; diff --git a/frontend/components/buttons/Button/index.ts b/frontend/components/buttons/Button/index.ts index c4719be7c0..1a5b182e44 100644 --- a/frontend/components/buttons/Button/index.ts +++ b/frontend/components/buttons/Button/index.ts @@ -1 +1,2 @@ export { default } from "./Button"; +export type { IButtonProps, ButtonVariant } from "./Button"; diff --git a/frontend/pages/DashboardPage/DashboardPage.tsx b/frontend/pages/DashboardPage/DashboardPage.tsx index d63ed4e080..bc47c0c20a 100644 --- a/frontend/pages/DashboardPage/DashboardPage.tsx +++ b/frontend/pages/DashboardPage/DashboardPage.tsx @@ -665,8 +665,7 @@ const DashboardPage = ({ router, location }: IDashboardProps): JSX.Element => { showTitle: showActivityFeedTitle, action: canEditActivityFeedAutomations ? { - type: "button", - text: "Manage automations", + type: "automations", onClick: () => setShowActivityFeedAutomationsModal(true), } : undefined, diff --git a/frontend/pages/DashboardPage/components/InfoCard/InfoCard.tsx b/frontend/pages/DashboardPage/components/InfoCard/InfoCard.tsx index 5926da84b0..e3ca2cacdf 100644 --- a/frontend/pages/DashboardPage/components/InfoCard/InfoCard.tsx +++ b/frontend/pages/DashboardPage/components/InfoCard/InfoCard.tsx @@ -3,6 +3,7 @@ import { browserHistory } from "react-router"; import Card from "components/Card"; import Button from "components/buttons/Button"; +import AutomationsButton from "components/buttons/AutomationsButton"; import Icon from "components/Icon"; import classnames from "classnames"; @@ -22,6 +23,10 @@ interface IInfoCardProps { type: "button"; text: string; onClick?: () => void; + } + | { + type: "automations"; + onClick?: () => void; }; total_host_count?: number; showTitle?: boolean; @@ -59,6 +64,16 @@ const useInfoCard = ({ const renderAction = () => { if (action) { + if (action.type === "automations") { + return ( + + ); + } + if (action.type === "button") { return ( { position="top" showArrow > - - Manage automations - + /> )} {canAddSoftware && ( diff --git a/frontend/pages/policies/ManagePoliciesPage/ManagePoliciesPage.tsx b/frontend/pages/policies/ManagePoliciesPage/ManagePoliciesPage.tsx index fa586eaa46..aad26190d8 100644 --- a/frontend/pages/policies/ManagePoliciesPage/ManagePoliciesPage.tsx +++ b/frontend/pages/policies/ManagePoliciesPage/ManagePoliciesPage.tsx @@ -48,7 +48,7 @@ import teamsAPI, { ILoadTeamResponse } from "services/entities/teams"; import { ITableQueryData } from "components/TableContainer/TableContainer"; import TableCount from "components/TableContainer/TableCount"; import Button from "components/buttons/Button"; -import Icon from "components/Icon"; +import AutomationsButton from "components/buttons/AutomationsButton"; import { SingleValue } from "react-select-5"; import DropdownWrapper from "components/forms/fields/DropdownWrapper"; @@ -880,16 +880,10 @@ const ManagePolicyPage = ({ let automationsButton = null; if (canEditAutomationsSettings) { automationsButton = ( - - <> - Automations - > - + /> ); if (!hasPoliciesToAutomate) { const tipContent = diff --git a/frontend/pages/policies/ManagePoliciesPage/_styles.scss b/frontend/pages/policies/ManagePoliciesPage/_styles.scss index 652dbd9936..416525f721 100644 --- a/frontend/pages/policies/ManagePoliciesPage/_styles.scss +++ b/frontend/pages/policies/ManagePoliciesPage/_styles.scss @@ -23,12 +23,6 @@ min-width: 277px; } - &__automations-button { - display: flex; - align-items: center; - gap: $pad-small; - } - &__header { display: flex; align-items: center; diff --git a/frontend/pages/queries/ManageQueriesPage/ManageQueriesPage.tsx b/frontend/pages/queries/ManageQueriesPage/ManageQueriesPage.tsx index 025a854e8f..a54650292b 100644 --- a/frontend/pages/queries/ManageQueriesPage/ManageQueriesPage.tsx +++ b/frontend/pages/queries/ManageQueriesPage/ManageQueriesPage.tsx @@ -34,6 +34,7 @@ import PATHS from "router/paths"; import PageDescription from "components/PageDescription"; import Button from "components/buttons/Button"; +import AutomationsButton from "components/buttons/AutomationsButton"; import TableDataError from "components/DataError"; import MainContent from "components/MainContent"; import TeamsDropdown from "components/TeamsDropdown"; @@ -425,13 +426,10 @@ const ManageQueriesPage = ({ {canManageAutomations && (isManageAutomationsEnabled ? ( - - Manage automations - + /> ) : ( - - Manage automations - + /> ))} {canCustomQuery && (