|
| 1 | +import { useEffect, useState } from "react"; |
| 2 | +import { Button, Stack, Box } from "@mui/material"; |
| 3 | +import { RocketLaunch } from "@mui/icons-material"; |
| 4 | +import { useForm, useWatch } from "react-hook-form"; |
| 5 | +import { CippOffCanvas } from "./CippOffCanvas"; |
| 6 | +import { CippIntunePolicy } from "../CippWizard/CippIntunePolicy"; |
| 7 | +import { ApiGetCall, ApiPostCall } from "../../api/ApiCall"; |
| 8 | +import CippFormComponent from "./CippFormComponent"; |
| 9 | +import CippJsonView from "../CippFormPages/CippJSONView"; |
| 10 | +import { Grid } from "@mui/system"; |
| 11 | +import { CippFormCondition } from "./CippFormCondition"; |
| 12 | +import { CippApiResults } from "./CippApiResults"; |
| 13 | +import { useSettings } from "../../hooks/use-settings"; |
| 14 | +import { CippFormTenantSelector } from "./CippFormTenantSelector"; |
| 15 | + |
| 16 | +export const CippPolicyDeployDrawer = ({ |
| 17 | + buttonText = "Deploy Policy", |
| 18 | + requiredPermissions = [], |
| 19 | + PermissionButton = Button, |
| 20 | +}) => { |
| 21 | + const [drawerVisible, setDrawerVisible] = useState(false); |
| 22 | + const formControl = useForm(); |
| 23 | + const tenantFilter = useSettings()?.tenantFilter; |
| 24 | + const selectedTenants = useWatch({ control: formControl.control, name: "tenantFilter" }) || []; |
| 25 | + const CATemplates = ApiGetCall({ url: "/api/ListIntuneTemplates", queryKey: "IntuneTemplates" }); |
| 26 | + const [JSONData, setJSONData] = useState(); |
| 27 | + const watcher = useWatch({ control: formControl.control, name: "TemplateList" }); |
| 28 | + const jsonWatch = useWatch({ control: formControl.control, name: "RAWJson" }); |
| 29 | + useEffect(() => { |
| 30 | + if (CATemplates.isSuccess && watcher?.value) { |
| 31 | + const template = CATemplates.data.find((template) => template.GUID === watcher.value); |
| 32 | + if (template) { |
| 33 | + const jsonTemplate = template.RAWJson ? JSON.parse(template.RAWJson) : null; |
| 34 | + setJSONData(jsonTemplate); |
| 35 | + formControl.setValue("RAWJson", template.RAWJson); |
| 36 | + formControl.setValue("displayName", template.Displayname); |
| 37 | + formControl.setValue("description", template.Description); |
| 38 | + formControl.setValue("TemplateType", template.Type); |
| 39 | + } |
| 40 | + } |
| 41 | + }, [watcher]); |
| 42 | + const deployPolicy = ApiPostCall({ |
| 43 | + urlFromData: true, |
| 44 | + relatedQueryKeys: [ |
| 45 | + "IntuneTemplates", |
| 46 | + `Configuration Policies - ${tenantFilter}`, |
| 47 | + `Compliance Policies - ${tenantFilter}`, |
| 48 | + `Protection Policies - ${tenantFilter}`, |
| 49 | + ], |
| 50 | + }); |
| 51 | + |
| 52 | + const handleSubmit = () => { |
| 53 | + const formData = formControl.getValues(); |
| 54 | + console.log("Submitting form data:", formData); |
| 55 | + deployPolicy.mutate({ |
| 56 | + url: "/api/AddPolicy", |
| 57 | + relatedQueryKeys: [ |
| 58 | + "IntuneTemplates", |
| 59 | + "Configuration Policies", |
| 60 | + "Compliance Policies", |
| 61 | + "Protection Policies", |
| 62 | + ], |
| 63 | + data: { ...formData }, |
| 64 | + }); |
| 65 | + }; |
| 66 | + |
| 67 | + const handleCloseDrawer = () => { |
| 68 | + setDrawerVisible(false); |
| 69 | + formControl.reset(); |
| 70 | + }; |
| 71 | + |
| 72 | + return ( |
| 73 | + <> |
| 74 | + <PermissionButton |
| 75 | + requiredPermissions={requiredPermissions} |
| 76 | + onClick={() => setDrawerVisible(true)} |
| 77 | + startIcon={<RocketLaunch />} |
| 78 | + > |
| 79 | + {buttonText} |
| 80 | + </PermissionButton> |
| 81 | + <CippOffCanvas |
| 82 | + title="Deploy Policy" |
| 83 | + visible={drawerVisible} |
| 84 | + onClose={handleCloseDrawer} |
| 85 | + size="lg" |
| 86 | + footer={ |
| 87 | + <Stack direction="row" justifyContent="flex-start" spacing={2}> |
| 88 | + <Button |
| 89 | + variant="contained" |
| 90 | + color="primary" |
| 91 | + onClick={handleSubmit} |
| 92 | + disabled={deployPolicy.isLoading} |
| 93 | + > |
| 94 | + {deployPolicy.isLoading |
| 95 | + ? "Deploying..." |
| 96 | + : deployPolicy.isSuccess |
| 97 | + ? "Redeploy Policy" |
| 98 | + : "Deploy Policy"} |
| 99 | + </Button> |
| 100 | + <Button variant="outlined" onClick={handleCloseDrawer}> |
| 101 | + Close |
| 102 | + </Button> |
| 103 | + </Stack> |
| 104 | + } |
| 105 | + > |
| 106 | + <Stack spacing={3}> |
| 107 | + <CippFormTenantSelector |
| 108 | + formControl={formControl} |
| 109 | + name="tenantFilter" |
| 110 | + required={true} |
| 111 | + disableClearable={false} |
| 112 | + allTenants={true} |
| 113 | + type="multiple" |
| 114 | + /> |
| 115 | + <CippFormComponent |
| 116 | + type="autoComplete" |
| 117 | + name="TemplateList" |
| 118 | + label="Please choose a template to apply." |
| 119 | + isFetching={CATemplates.isLoading} |
| 120 | + multiple={false} |
| 121 | + formControl={formControl} |
| 122 | + options={ |
| 123 | + CATemplates.isSuccess |
| 124 | + ? CATemplates.data.map((template) => ({ |
| 125 | + label: template.Displayname, |
| 126 | + value: template.GUID, |
| 127 | + })) |
| 128 | + : [] |
| 129 | + } |
| 130 | + /> |
| 131 | + |
| 132 | + <CippFormComponent |
| 133 | + type="hidden" |
| 134 | + name="RAWJson" |
| 135 | + label="Conditional Access Parameters" |
| 136 | + placeholder="Enter the JSON information to use as parameters, or select from a template" |
| 137 | + formControl={formControl} |
| 138 | + /> |
| 139 | + <CippJsonView object={JSONData} type="intune" /> |
| 140 | + |
| 141 | + <Grid size={{ xs: 12 }}> |
| 142 | + <CippFormComponent |
| 143 | + type="radio" |
| 144 | + name="AssignTo" |
| 145 | + options={[ |
| 146 | + { label: "Do not assign", value: "On" }, |
| 147 | + { label: "Assign to all users", value: "allLicensedUsers" }, |
| 148 | + { label: "Assign to all devices", value: "AllDevices" }, |
| 149 | + { label: "Assign to all users and devices", value: "AllDevicesAndUsers" }, |
| 150 | + { label: "Assign to Custom Group", value: "customGroup" }, |
| 151 | + ]} |
| 152 | + formControl={formControl} |
| 153 | + /> |
| 154 | + </Grid> |
| 155 | + <CippFormCondition |
| 156 | + formControl={formControl} |
| 157 | + field="AssignTo" |
| 158 | + compareType="is" |
| 159 | + compareValue="customGroup" |
| 160 | + > |
| 161 | + <Grid size={{ xs: 12 }}> |
| 162 | + <CippFormComponent |
| 163 | + type="textField" |
| 164 | + label="Custom Group Names separated by comma. Wildcards (*) are allowed" |
| 165 | + name="customGroup" |
| 166 | + formControl={formControl} |
| 167 | + validators={{ required: "Please specify custom group names" }} |
| 168 | + /> |
| 169 | + </Grid> |
| 170 | + </CippFormCondition> |
| 171 | + <CippFormCondition |
| 172 | + formControl={formControl} |
| 173 | + field="RAWJson" |
| 174 | + compareType="regex" |
| 175 | + compareValue={/%(\w+)%/} |
| 176 | + > |
| 177 | + {(() => { |
| 178 | + const rawJson = jsonWatch ? jsonWatch : ""; |
| 179 | + const placeholderMatches = [...rawJson.matchAll(/%(\w+)%/g)].map((m) => m[1]); |
| 180 | + const uniquePlaceholders = Array.from(new Set(placeholderMatches)); |
| 181 | + if (uniquePlaceholders.length === 0 || selectedTenants.length === 0) { |
| 182 | + return null; |
| 183 | + } |
| 184 | + return uniquePlaceholders.map((placeholder) => ( |
| 185 | + <Grid key={placeholder} size={{ xs: 12 }}> |
| 186 | + {selectedTenants.map((tenant, idx) => ( |
| 187 | + <CippFormComponent |
| 188 | + key={`${tenant.value}-${placeholder}-${idx}`} |
| 189 | + type="textField" |
| 190 | + defaultValue={ |
| 191 | + //if the placeholder is tenantid then replace it with tenant.addedFields.customerId, if the placeholder is tenantdomain then replace it with tenant.addedFields.defaultDomainName. |
| 192 | + placeholder === "tenantid" |
| 193 | + ? tenant?.addedFields?.customerId |
| 194 | + : placeholder === "tenantdomain" |
| 195 | + ? tenant?.addedFields?.defaultDomainName |
| 196 | + : "" |
| 197 | + } |
| 198 | + name={`replacemap.${tenant.value}.%${placeholder}%`} |
| 199 | + label={`Value for '${placeholder}' in Tenant '${tenant.addedFields.defaultDomainName}'`} |
| 200 | + formControl={formControl} |
| 201 | + validators={{ required: `Please provide a value for ${placeholder}` }} |
| 202 | + sx={{ m: 1 }} |
| 203 | + /> |
| 204 | + ))} |
| 205 | + </Grid> |
| 206 | + )); |
| 207 | + })()} |
| 208 | + </CippFormCondition> |
| 209 | + <CippApiResults apiObject={deployPolicy} /> |
| 210 | + </Stack> |
| 211 | + </CippOffCanvas> |
| 212 | + </> |
| 213 | + ); |
| 214 | +}; |
0 commit comments