From 4db06f2cbb1734e3da79f9253babb97e9fc4e49a Mon Sep 17 00:00:00 2001 From: RachelElysia <71795832+RachelElysia@users.noreply.github.com> Date: Wed, 20 Mar 2024 16:07:27 -0400 Subject: [PATCH] Fleet Calendar feature: Updates to manage automations modal (#17652) --- .../ManagePoliciesPage/ManagePoliciesPage.tsx | 11 +- .../ExamplePayload/ExamplePayload.tsx | 64 +++++++ .../components/ExamplePayload/_styles.scss | 9 + .../components/ExamplePayload/index.ts | 1 + .../ExampleTicket.tsx} | 42 +---- .../components/ExampleTicket/_styles.scss | 10 ++ .../components/ExampleTicket/index.ts | 1 + .../ManagePolicyAutomationsModal/index.ts | 1 - .../OtherWorkflowsModal.tsx} | 161 +++++++++--------- .../_styles.scss | 9 +- .../components/OtherWorkflowsModal/index.ts | 1 + .../PreviewPayloadModal.tsx | 97 ----------- .../PreviewPayloadModal/_styles.scss | 54 ------ .../components/PreviewPayloadModal/index.ts | 1 - .../PreviewTicketModal/_styles.scss | 13 -- .../components/PreviewTicketModal/index.ts | 1 - 16 files changed, 185 insertions(+), 291 deletions(-) create mode 100644 frontend/pages/policies/ManagePoliciesPage/components/ExamplePayload/ExamplePayload.tsx create mode 100644 frontend/pages/policies/ManagePoliciesPage/components/ExamplePayload/_styles.scss create mode 100644 frontend/pages/policies/ManagePoliciesPage/components/ExamplePayload/index.ts rename frontend/pages/policies/ManagePoliciesPage/components/{PreviewTicketModal/PreviewTicketModal.tsx => ExampleTicket/ExampleTicket.tsx} (52%) create mode 100644 frontend/pages/policies/ManagePoliciesPage/components/ExampleTicket/_styles.scss create mode 100644 frontend/pages/policies/ManagePoliciesPage/components/ExampleTicket/index.ts delete mode 100644 frontend/pages/policies/ManagePoliciesPage/components/ManagePolicyAutomationsModal/index.ts rename frontend/pages/policies/ManagePoliciesPage/components/{ManagePolicyAutomationsModal/ManagePolicyAutomationsModal.tsx => OtherWorkflowsModal/OtherWorkflowsModal.tsx} (82%) rename frontend/pages/policies/ManagePoliciesPage/components/{ManagePolicyAutomationsModal => OtherWorkflowsModal}/_styles.scss (69%) create mode 100644 frontend/pages/policies/ManagePoliciesPage/components/OtherWorkflowsModal/index.ts delete mode 100644 frontend/pages/policies/ManagePoliciesPage/components/PreviewPayloadModal/PreviewPayloadModal.tsx delete mode 100644 frontend/pages/policies/ManagePoliciesPage/components/PreviewPayloadModal/_styles.scss delete mode 100644 frontend/pages/policies/ManagePoliciesPage/components/PreviewPayloadModal/index.ts delete mode 100644 frontend/pages/policies/ManagePoliciesPage/components/PreviewTicketModal/_styles.scss delete mode 100644 frontend/pages/policies/ManagePoliciesPage/components/PreviewTicketModal/index.ts diff --git a/frontend/pages/policies/ManagePoliciesPage/ManagePoliciesPage.tsx b/frontend/pages/policies/ManagePoliciesPage/ManagePoliciesPage.tsx index be95e222d7..ce359b5778 100644 --- a/frontend/pages/policies/ManagePoliciesPage/ManagePoliciesPage.tsx +++ b/frontend/pages/policies/ManagePoliciesPage/ManagePoliciesPage.tsx @@ -41,7 +41,7 @@ import TableDataError from "components/DataError"; import MainContent from "components/MainContent"; import PoliciesTable from "./components/PoliciesTable"; -import ManagePolicyAutomationsModal from "./components/ManagePolicyAutomationsModal"; +import OtherWorkflowsModal from "./components/OtherWorkflowsModal"; import AddPolicyModal from "./components/AddPolicyModal"; import DeletePolicyModal from "./components/DeletePolicyModal"; @@ -129,7 +129,6 @@ const ManagePolicyPage = ({ const [showManageAutomationsModal, setShowManageAutomationsModal] = useState( false ); - const [showPreviewPayloadModal, setShowPreviewPayloadModal] = useState(false); const [showAddPolicyModal, setShowAddPolicyModal] = useState(false); const [showDeletePolicyModal, setShowDeletePolicyModal] = useState(false); @@ -477,10 +476,6 @@ const ManagePolicyPage = ({ const toggleManageAutomationsModal = () => setShowManageAutomationsModal(!showManageAutomationsModal); - const togglePreviewPayloadModal = useCallback(() => { - setShowPreviewPayloadModal(!showPreviewPayloadModal); - }, [setShowPreviewPayloadModal, showPreviewPayloadModal]); - const toggleAddPolicyModal = () => setShowAddPolicyModal(!showAddPolicyModal); const toggleDeletePolicyModal = () => @@ -796,15 +791,13 @@ const ManagePolicyPage = ({ )} {config && automationsConfig && showManageAutomationsModal && ( - )} {showAddPolicyModal && ( diff --git a/frontend/pages/policies/ManagePoliciesPage/components/ExamplePayload/ExamplePayload.tsx b/frontend/pages/policies/ManagePoliciesPage/components/ExamplePayload/ExamplePayload.tsx new file mode 100644 index 0000000000..4dc1c2462c --- /dev/null +++ b/frontend/pages/policies/ManagePoliciesPage/components/ExamplePayload/ExamplePayload.tsx @@ -0,0 +1,64 @@ +import React, { useContext } from "react"; +import { syntaxHighlight } from "utilities/helpers"; + +import { AppContext } from "context/app"; +import { IPolicyWebhookPreviewPayload } from "interfaces/policy"; + +const baseClass = "example-payload"; + +interface IHostPreview { + id: number; + display_name: string; + url: string; +} + +interface IExamplePayload { + timestamp: string; + policy: IPolicyWebhookPreviewPayload; + hosts: IHostPreview[]; +} + +const ExamplePayload = (): JSX.Element => { + const { isFreeTier } = useContext(AppContext); + + const json: IExamplePayload = { + timestamp: "0000-00-00T00:00:00Z", + policy: { + id: 1, + name: "Is Gatekeeper enabled?", + query: "SELECT 1 FROM gatekeeper WHERE assessments_enabled = 1;", + description: "Checks if gatekeeper is enabled on macOS devices.", + author_id: 1, + author_name: "John", + author_email: "john@example.com", + resolution: "Turn on Gatekeeper feature in System Preferences.", + passing_host_count: 2000, + failing_host_count: 300, + critical: false, + }, + hosts: [ + { + id: 1, + display_name: "macbook-1", + url: "https://fleet.example.com/hosts/1", + }, + { + id: 2, + display_name: "macbbook-2", + url: "https://fleet.example.com/hosts/2", + }, + ], + }; + if (isFreeTier) { + delete json.policy.critical; + } + + return ( +
+
POST https://server.com/example
+
+    
+ ); +}; + +export default ExamplePayload; diff --git a/frontend/pages/policies/ManagePoliciesPage/components/ExamplePayload/_styles.scss b/frontend/pages/policies/ManagePoliciesPage/components/ExamplePayload/_styles.scss new file mode 100644 index 0000000000..2297445b92 --- /dev/null +++ b/frontend/pages/policies/ManagePoliciesPage/components/ExamplePayload/_styles.scss @@ -0,0 +1,9 @@ +.example-payload { + display: flex; + flex-direction: column; + gap: $pad-large; + + pre { + margin: 0; + } +} diff --git a/frontend/pages/policies/ManagePoliciesPage/components/ExamplePayload/index.ts b/frontend/pages/policies/ManagePoliciesPage/components/ExamplePayload/index.ts new file mode 100644 index 0000000000..a9ab7d050d --- /dev/null +++ b/frontend/pages/policies/ManagePoliciesPage/components/ExamplePayload/index.ts @@ -0,0 +1 @@ +export { default } from "./ExamplePayload"; diff --git a/frontend/pages/policies/ManagePoliciesPage/components/PreviewTicketModal/PreviewTicketModal.tsx b/frontend/pages/policies/ManagePoliciesPage/components/ExampleTicket/ExampleTicket.tsx similarity index 52% rename from frontend/pages/policies/ManagePoliciesPage/components/PreviewTicketModal/PreviewTicketModal.tsx rename to frontend/pages/policies/ManagePoliciesPage/components/ExampleTicket/ExampleTicket.tsx index c46d2e4e54..1ff58279f6 100644 --- a/frontend/pages/policies/ManagePoliciesPage/components/PreviewTicketModal/PreviewTicketModal.tsx +++ b/frontend/pages/policies/ManagePoliciesPage/components/ExampleTicket/ExampleTicket.tsx @@ -1,28 +1,24 @@ import React, { useContext } from "react"; import { AppContext } from "context/app"; -import Modal from "components/Modal"; -import Button from "components/buttons/Button"; -import CustomLink from "components/CustomLink"; import { IIntegrationType } from "interfaces/integration"; +import Card from "components/Card"; import JiraPreview from "../../../../../../assets/images/jira-policy-automation-preview-400x419@2x.png"; import ZendeskPreview from "../../../../../../assets/images/zendesk-policy-automation-preview-400x515@2x.png"; import JiraPreviewPremium from "../../../../../../assets/images/jira-policy-automation-preview-premium-400x316@2x.png"; import ZendeskPreviewPremium from "../../../../../../assets/images/zendesk-policy-automation-preview-premium-400x483@2x.png"; -const baseClass = "preview-ticket-modal"; +const baseClass = "example-ticket"; -interface IPreviewTicketModalProps { +interface IExampleTicketProps { integrationType?: IIntegrationType; - onCancel: () => void; } -const PreviewTicketModal = ({ +const ExampleTicket = ({ integrationType, - onCancel, -}: IPreviewTicketModalProps): JSX.Element => { +}: IExampleTicketProps): JSX.Element => { const { isPremiumTier } = useContext(AppContext); const screenshot = @@ -41,30 +37,10 @@ const PreviewTicketModal = ({ ); return ( - -
-

- Want to learn more about how automations in Fleet work?{" "} - -

-
{screenshot}
-
- -
-
-
+ + {screenshot} + ); }; -export default PreviewTicketModal; +export default ExampleTicket; diff --git a/frontend/pages/policies/ManagePoliciesPage/components/ExampleTicket/_styles.scss b/frontend/pages/policies/ManagePoliciesPage/components/ExampleTicket/_styles.scss new file mode 100644 index 0000000000..4212f33fa5 --- /dev/null +++ b/frontend/pages/policies/ManagePoliciesPage/components/ExampleTicket/_styles.scss @@ -0,0 +1,10 @@ +.example-ticket { + display: flex; + flex-direction: column; + align-items: center; + box-sizing: border-box; + + &__screenshot { + max-width: 400px; + } +} diff --git a/frontend/pages/policies/ManagePoliciesPage/components/ExampleTicket/index.ts b/frontend/pages/policies/ManagePoliciesPage/components/ExampleTicket/index.ts new file mode 100644 index 0000000000..3557097088 --- /dev/null +++ b/frontend/pages/policies/ManagePoliciesPage/components/ExampleTicket/index.ts @@ -0,0 +1 @@ +export { default } from "./ExampleTicket"; diff --git a/frontend/pages/policies/ManagePoliciesPage/components/ManagePolicyAutomationsModal/index.ts b/frontend/pages/policies/ManagePoliciesPage/components/ManagePolicyAutomationsModal/index.ts deleted file mode 100644 index d8e2cefbc9..0000000000 --- a/frontend/pages/policies/ManagePoliciesPage/components/ManagePolicyAutomationsModal/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from "./ManagePolicyAutomationsModal"; diff --git a/frontend/pages/policies/ManagePoliciesPage/components/ManagePolicyAutomationsModal/ManagePolicyAutomationsModal.tsx b/frontend/pages/policies/ManagePoliciesPage/components/OtherWorkflowsModal/OtherWorkflowsModal.tsx similarity index 82% rename from frontend/pages/policies/ManagePoliciesPage/components/ManagePolicyAutomationsModal/ManagePolicyAutomationsModal.tsx rename to frontend/pages/policies/ManagePoliciesPage/components/OtherWorkflowsModal/OtherWorkflowsModal.tsx index ae71c22cfe..907f4edb4f 100644 --- a/frontend/pages/policies/ManagePoliciesPage/components/ManagePolicyAutomationsModal/ManagePolicyAutomationsModal.tsx +++ b/frontend/pages/policies/ManagePoliciesPage/components/OtherWorkflowsModal/OtherWorkflowsModal.tsx @@ -19,22 +19,21 @@ import Dropdown from "components/forms/fields/Dropdown"; import InputField from "components/forms/fields/InputField"; import Radio from "components/forms/fields/Radio"; import validUrl from "components/forms/validators/valid_url"; +import RevealButton from "components/buttons/RevealButton"; +import CustomLink from "components/CustomLink"; +import ExampleTicket from "../ExampleTicket"; +import ExamplePayload from "../ExamplePayload"; -import PreviewPayloadModal from "../PreviewPayloadModal"; -import PreviewTicketModal from "../PreviewTicketModal"; - -interface IManagePolicyAutomationsModalProps { +interface IOtherWorkflowsModalProps { automationsConfig: IAutomationsConfig | ITeamAutomationsConfig; availableIntegrations: IIntegrations; availablePolicies: IPolicy[]; isUpdatingAutomations: boolean; - showPreviewPayloadModal: boolean; onExit: () => void; handleSubmit: (formData: { webhook_settings: Pick; integrations: IIntegrations; }) => void; - togglePreviewPayloadModal: () => void; } interface ICheckedPolicy { @@ -83,18 +82,16 @@ const useCheckboxListStateManagement = ( return { policyItems, updatePolicyItems }; }; -const baseClass = "manage-policy-automations-modal"; +const baseClass = "other-workflows-modal"; -const ManagePolicyAutomationsModal = ({ +const OtherWorkflowsModal = ({ automationsConfig, availableIntegrations, availablePolicies, isUpdatingAutomations, - showPreviewPayloadModal, onExit, handleSubmit, - togglePreviewPayloadModal: togglePreviewModal, -}: IManagePolicyAutomationsModalProps): JSX.Element => { +}: IOtherWorkflowsModalProps): JSX.Element => { const { webhook_settings: { failing_policies_webhook: webhook }, } = automationsConfig; @@ -131,6 +128,9 @@ const ManagePolicyAutomationsModal = ({ IIntegration | undefined >(serverEnabledIntegration); + const [showExamplePayload, setShowExamplePayload] = useState(false); + const [showExampleTicket, setShowExampleTicket] = useState(false); + const [errors, setErrors] = useState<{ [key: string]: string }>({}); const { policyItems, updatePolicyItems } = useCheckboxListStateManagement( @@ -218,13 +218,6 @@ const ManagePolicyAutomationsModal = ({ z.group_id === selectedIntegration?.group_id, })) || null; - // if ( - // !isPolicyAutomationsEnabled || - // (!isWebhookEnabled && !selectedIntegration) - // ) { - // newPolicyIds = []; - // } - const updatedEnabledPoliciesAcrossPages = () => { if (webhook.policy_ids) { // Array of policy ids on the page @@ -297,34 +290,52 @@ const ManagePolicyAutomationsModal = ({ placeholder="https://server.com/example" tooltip="Provide a URL to deliver a webhook request to." /> - + setShowExamplePayload(!showExamplePayload)} + /> + {showExamplePayload && } ); }; const renderIntegrations = () => { return jira?.length || zendesk?.length ? ( -
- +
+ +
+ setShowExampleTicket(!showExampleTicket)} /> - -
+ {showExampleTicket && ( + + )} + ) : (
You have no integrations.
@@ -338,22 +349,10 @@ const ManagePolicyAutomationsModal = ({ ); }; - const renderPreview = () => - !isWebhookEnabled ? ( - - ) : ( - - ); - - return showPreviewPayloadModal ? ( - renderPreview() - ) : ( + return ( @@ -372,12 +371,32 @@ const ManagePolicyAutomationsModal = ({ isPolicyAutomationsEnabled ? "enabled" : "disabled" }`} > +
+
Workflow
+ + +
+ {isWebhookEnabled ? renderWebhook() : renderIntegrations()}
{availablePolicies?.length ? ( <> -
- Choose which policies you would like to listen to: -
+
Policies:
{policyItems && policyItems.map((policyItem) => { const { isChecked, name, id } = policyItem; @@ -405,28 +424,14 @@ const ManagePolicyAutomationsModal = ({ )}
-
-
Workflow
- + The workflow will be triggered when hosts fail these policies.{" "} + - -
- {isWebhookEnabled ? renderWebhook() : renderIntegrations()} +

-
- - - ); -}; - -export default PreviewPayloadModal; diff --git a/frontend/pages/policies/ManagePoliciesPage/components/PreviewPayloadModal/_styles.scss b/frontend/pages/policies/ManagePoliciesPage/components/PreviewPayloadModal/_styles.scss deleted file mode 100644 index 0ff66f034f..0000000000 --- a/frontend/pages/policies/ManagePoliciesPage/components/PreviewPayloadModal/_styles.scss +++ /dev/null @@ -1,54 +0,0 @@ -.preview-payload-modal { - &__sandbox-info { - margin-top: $pad-medium; - - p { - margin: 0; - margin-bottom: $pad-medium; - } - - p:last-child { - margin-bottom: 0; - } - } - - &__info-header { - font-weight: $bold; - } - - &__advanced-options-button { - margin: $pad-medium 0; - color: $core-vibrant-blue; - font-weight: $bold; - font-size: $x-small; - } - - .downcaret { - &::after { - content: url("../assets/images/icon-chevron-blue-16x16@2x.png"); - transform: scale(0.5); - width: 16px; - border-radius: 0px; - padding: 0px; - padding-left: 2px; - margin-bottom: 2px; - } - } - - .upcaret { - &::after { - content: url("../assets/images/icon-chevron-blue-16x16@2x.png"); - transform: scale(0.5) rotate(180deg); - width: 16px; - border-radius: 0px; - padding: 0px; - padding-left: 2px; - margin-bottom: 4px; - margin-left: 14px; - } - } - - .Select-value-label { - font-size: $small; - } -} diff --git a/frontend/pages/policies/ManagePoliciesPage/components/PreviewPayloadModal/index.ts b/frontend/pages/policies/ManagePoliciesPage/components/PreviewPayloadModal/index.ts deleted file mode 100644 index bc08b4723d..0000000000 --- a/frontend/pages/policies/ManagePoliciesPage/components/PreviewPayloadModal/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from "./PreviewPayloadModal"; diff --git a/frontend/pages/policies/ManagePoliciesPage/components/PreviewTicketModal/_styles.scss b/frontend/pages/policies/ManagePoliciesPage/components/PreviewTicketModal/_styles.scss deleted file mode 100644 index 9024a73203..0000000000 --- a/frontend/pages/policies/ManagePoliciesPage/components/PreviewTicketModal/_styles.scss +++ /dev/null @@ -1,13 +0,0 @@ -.preview-ticket-modal { - &__example { - display: flex; - justify-content: center; - } - - &__screenshot { - width: 400px; - height: auto; - border-radius: 8px; - filter: drop-shadow(0px 4px 16px rgba(0, 0, 0, 0.1)); - } -} diff --git a/frontend/pages/policies/ManagePoliciesPage/components/PreviewTicketModal/index.ts b/frontend/pages/policies/ManagePoliciesPage/components/PreviewTicketModal/index.ts deleted file mode 100644 index 4d8716d447..0000000000 --- a/frontend/pages/policies/ManagePoliciesPage/components/PreviewTicketModal/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from "./PreviewTicketModal";