Skip to content

Commit d894c9d

Browse files
authored
Merge pull request #78 from KelvinTegelaar/main
[pull] main from KelvinTegelaar:main
2 parents 7a19c36 + a5be2d2 commit d894c9d

File tree

25 files changed

+508
-290
lines changed

25 files changed

+508
-290
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "cipp",
3-
"version": "8.5.1",
3+
"version": "8.5.2",
44
"author": "CIPP Contributors",
55
"homepage": "https://cipp.app/",
66
"bugs": {

public/version.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
"version": "8.5.1"
3-
}
2+
"version": "8.5.2"
3+
}
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
import { useState, useEffect } from "react";
2+
import { Button, Divider } from "@mui/material";
3+
import { Grid } from "@mui/system";
4+
import { useForm, useFormState, useWatch } from "react-hook-form";
5+
import { RocketLaunch } from "@mui/icons-material";
6+
import { CippOffCanvas } from "./CippOffCanvas";
7+
import CippFormComponent from "./CippFormComponent";
8+
import { CippFormTenantSelector } from "./CippFormTenantSelector";
9+
import { CippApiResults } from "./CippApiResults";
10+
import { ApiPostCall } from "../../api/ApiCall";
11+
12+
export const CippAddConnectorDrawer = ({
13+
buttonText = "Deploy Connector",
14+
requiredPermissions = [],
15+
PermissionButton = Button,
16+
}) => {
17+
const [drawerVisible, setDrawerVisible] = useState(false);
18+
19+
const formControl = useForm({
20+
mode: "onChange",
21+
defaultValues: {
22+
selectedTenants: [],
23+
TemplateList: null,
24+
PowerShellCommand: "",
25+
},
26+
});
27+
28+
const { isValid } = useFormState({ control: formControl.control });
29+
const templateListVal = useWatch({ control: formControl.control, name: "TemplateList" });
30+
31+
const addConnector = ApiPostCall({
32+
urlFromData: true,
33+
});
34+
35+
// Update PowerShellCommand when template is selected
36+
useEffect(() => {
37+
if (templateListVal?.value) {
38+
formControl.setValue("PowerShellCommand", JSON.stringify(templateListVal?.value));
39+
}
40+
}, [templateListVal, formControl]);
41+
42+
// Reset form fields on successful creation
43+
useEffect(() => {
44+
if (addConnector.isSuccess) {
45+
const currentTenants = formControl.getValues("selectedTenants");
46+
formControl.reset({
47+
selectedTenants: currentTenants,
48+
TemplateList: null,
49+
PowerShellCommand: "",
50+
});
51+
}
52+
}, [addConnector.isSuccess, formControl]);
53+
54+
const handleSubmit = () => {
55+
formControl.trigger();
56+
// Check if the form is valid before proceeding
57+
if (!isValid) {
58+
return;
59+
}
60+
61+
const formData = formControl.getValues();
62+
63+
addConnector.mutate({
64+
url: "/api/AddExConnector",
65+
data: formData,
66+
});
67+
};
68+
69+
const handleCloseDrawer = () => {
70+
setDrawerVisible(false);
71+
formControl.reset({
72+
selectedTenants: [],
73+
TemplateList: null,
74+
PowerShellCommand: "",
75+
});
76+
};
77+
78+
return (
79+
<>
80+
<PermissionButton
81+
requiredPermissions={requiredPermissions}
82+
onClick={() => setDrawerVisible(true)}
83+
startIcon={<RocketLaunch />}
84+
>
85+
{buttonText}
86+
</PermissionButton>
87+
<CippOffCanvas
88+
title="Deploy Connector"
89+
visible={drawerVisible}
90+
onClose={handleCloseDrawer}
91+
size="lg"
92+
footer={
93+
<div style={{ display: "flex", gap: "8px", justifyContent: "flex-start" }}>
94+
<Button
95+
variant="contained"
96+
color="primary"
97+
onClick={handleSubmit}
98+
disabled={addConnector.isLoading || !isValid}
99+
>
100+
{addConnector.isLoading
101+
? "Deploying..."
102+
: addConnector.isSuccess
103+
? "Deploy Another"
104+
: "Deploy Connector"}
105+
</Button>
106+
<Button variant="outlined" onClick={handleCloseDrawer}>
107+
Close
108+
</Button>
109+
</div>
110+
}
111+
>
112+
<Grid container spacing={2}>
113+
{/* Tenant Selector */}
114+
<Grid size={{ xs: 12 }}>
115+
<CippFormTenantSelector
116+
label="Select Tenants"
117+
formControl={formControl}
118+
name="selectedTenants"
119+
type="multiple"
120+
allTenants={true}
121+
preselectedEnabled={true}
122+
validators={{ required: "At least one tenant must be selected" }}
123+
/>
124+
</Grid>
125+
126+
<Divider sx={{ my: 2, width: "100%" }} />
127+
128+
{/* Template List */}
129+
<Grid size={{ md: 12, xs: 12 }}>
130+
<CippFormComponent
131+
type="autoComplete"
132+
label="Select a template (optional)"
133+
name="TemplateList"
134+
formControl={formControl}
135+
multiple={false}
136+
api={{
137+
queryKey: `TemplateListConnectors`,
138+
labelField: "name",
139+
valueField: (option) => option,
140+
url: "/api/ListExconnectorTemplates",
141+
}}
142+
placeholder="Select a template or enter PowerShell JSON manually"
143+
/>
144+
</Grid>
145+
146+
<Divider sx={{ my: 2, width: "100%" }} />
147+
148+
{/* PowerShell Command */}
149+
<Grid size={{ xs: 12 }}>
150+
<CippFormComponent
151+
type="textField"
152+
label="Parameters (JSON)"
153+
name="PowerShellCommand"
154+
formControl={formControl}
155+
multiline
156+
rows={6}
157+
validators={{ required: "Please enter the PowerShell parameters as JSON." }}
158+
/>
159+
</Grid>
160+
161+
<CippApiResults apiObject={addConnector} />
162+
</Grid>
163+
</CippOffCanvas>
164+
</>
165+
);
166+
};
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
import { useState, useEffect } from "react";
2+
import { Button, Divider } from "@mui/material";
3+
import { Grid } from "@mui/system";
4+
import { useForm, useFormState, useWatch } from "react-hook-form";
5+
import { RocketLaunch } from "@mui/icons-material";
6+
import { CippOffCanvas } from "./CippOffCanvas";
7+
import CippFormComponent from "./CippFormComponent";
8+
import { CippFormTenantSelector } from "./CippFormTenantSelector";
9+
import { CippApiResults } from "./CippApiResults";
10+
import { ApiPostCall } from "../../api/ApiCall";
11+
12+
export const CippAddTransportRuleDrawer = ({
13+
buttonText = "Deploy Template",
14+
requiredPermissions = [],
15+
PermissionButton = Button,
16+
}) => {
17+
const [drawerVisible, setDrawerVisible] = useState(false);
18+
19+
const formControl = useForm({
20+
mode: "onChange",
21+
defaultValues: {
22+
selectedTenants: [],
23+
TemplateList: null,
24+
PowerShellCommand: "",
25+
},
26+
});
27+
28+
const { isValid } = useFormState({ control: formControl.control });
29+
const templateListVal = useWatch({ control: formControl.control, name: "TemplateList" });
30+
31+
const addTransportRule = ApiPostCall({
32+
urlFromData: true,
33+
});
34+
35+
// Update PowerShellCommand when template is selected
36+
useEffect(() => {
37+
if (templateListVal?.value) {
38+
formControl.setValue("PowerShellCommand", JSON.stringify(templateListVal?.value));
39+
}
40+
}, [templateListVal, formControl]);
41+
42+
// Reset form fields on successful creation
43+
useEffect(() => {
44+
if (addTransportRule.isSuccess) {
45+
const currentTenants = formControl.getValues("selectedTenants");
46+
formControl.reset({
47+
selectedTenants: currentTenants,
48+
TemplateList: null,
49+
PowerShellCommand: "",
50+
});
51+
}
52+
}, [addTransportRule.isSuccess, formControl]);
53+
54+
const handleSubmit = () => {
55+
formControl.trigger();
56+
// Check if the form is valid before proceeding
57+
if (!isValid) {
58+
return;
59+
}
60+
61+
const formData = formControl.getValues();
62+
63+
addTransportRule.mutate({
64+
url: "/api/AddTransportRule",
65+
data: formData,
66+
});
67+
};
68+
69+
const handleCloseDrawer = () => {
70+
setDrawerVisible(false);
71+
formControl.reset({
72+
selectedTenants: [],
73+
TemplateList: null,
74+
PowerShellCommand: "",
75+
});
76+
};
77+
78+
return (
79+
<>
80+
<PermissionButton
81+
requiredPermissions={requiredPermissions}
82+
onClick={() => setDrawerVisible(true)}
83+
startIcon={<RocketLaunch />}
84+
>
85+
{buttonText}
86+
</PermissionButton>
87+
<CippOffCanvas
88+
title="Deploy Transport Rule"
89+
visible={drawerVisible}
90+
onClose={handleCloseDrawer}
91+
size="lg"
92+
footer={
93+
<div style={{ display: "flex", gap: "8px", justifyContent: "flex-start" }}>
94+
<Button
95+
variant="contained"
96+
color="primary"
97+
onClick={handleSubmit}
98+
disabled={addTransportRule.isLoading || !isValid}
99+
>
100+
{addTransportRule.isLoading
101+
? "Deploying..."
102+
: addTransportRule.isSuccess
103+
? "Deploy Another"
104+
: "Deploy Transport Rule"}
105+
</Button>
106+
<Button variant="outlined" onClick={handleCloseDrawer}>
107+
Close
108+
</Button>
109+
</div>
110+
}
111+
>
112+
<Grid container spacing={2}>
113+
{/* Tenant Selector */}
114+
<Grid size={{ xs: 12 }}>
115+
<CippFormTenantSelector
116+
label="Select Tenants"
117+
formControl={formControl}
118+
name="selectedTenants"
119+
type="multiple"
120+
allTenants={true}
121+
preselectedEnabled={true}
122+
validators={{ required: "At least one tenant must be selected" }}
123+
/>
124+
</Grid>
125+
126+
<Divider sx={{ my: 2, width: "100%" }} />
127+
128+
{/* Template List */}
129+
<Grid size={{ md: 12, xs: 12 }}>
130+
<CippFormComponent
131+
type="autoComplete"
132+
label="Select a template (optional)"
133+
name="TemplateList"
134+
formControl={formControl}
135+
multiple={false}
136+
api={{
137+
queryKey: `TemplateListTransport`,
138+
labelField: "name",
139+
valueField: (option) => option,
140+
url: "/api/ListTransportRulesTemplates",
141+
}}
142+
placeholder="Select a template or enter PowerShell JSON manually"
143+
/>
144+
</Grid>
145+
146+
<Divider sx={{ my: 2, width: "100%" }} />
147+
148+
{/* PowerShell Command */}
149+
<Grid size={{ xs: 12 }}>
150+
<CippFormComponent
151+
type="textField"
152+
label="New-TransportRule parameters (JSON)"
153+
name="PowerShellCommand"
154+
formControl={formControl}
155+
multiline
156+
rows={6}
157+
validators={{ required: "Please enter the PowerShell parameters as JSON." }}
158+
/>
159+
</Grid>
160+
161+
<CippApiResults apiObject={addTransportRule} />
162+
</Grid>
163+
</CippOffCanvas>
164+
</>
165+
);
166+
};

0 commit comments

Comments
 (0)