Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[pull] dev from KelvinTegelaar:dev #70

Merged
merged 26 commits into from
Feb 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
45fa375
Add speed dial actions for bug reporting and feature requests
Jr7468 Jan 28, 2025
44798d7
Merge pull request #96 from KelvinTegelaar/dev
kris6673 Jan 29, 2025
e53fe8c
Merge branch 'KelvinTegelaar:dev' into dev
Jr7468 Jan 30, 2025
912bc12
Merge branch 'KelvinTegelaar:dev' into dev
Jr7468 Jan 31, 2025
32cbe02
Add Speed Dial component with help, bug report, and feedback actions
Jr7468 Jan 31, 2025
205fa4c
Prettier fix
Jr7468 Jan 31, 2025
65da8b6
Tested and works properly on my Dev Env now!
Jr7468 Jan 31, 2025
6c432d3
Add onClick handlers to Speed Dial GitHub links
Jr7468 Jan 31, 2025
d6eaf09
Add Discord link to Speed Dial component
Jr7468 Jan 31, 2025
5c538ca
Merge pull request #97 from KelvinTegelaar/dev
kris6673 Jan 31, 2025
fc243b9
Merge branch 'dev' of https://github.com/KelvinTegelaar/CIPP into dev
kris6673 Jan 31, 2025
63dfaef
Merge branch 'KelvinTegelaar:dev' into dev
kris6673 Feb 2, 2025
dc9c7c3
feat: Add Edit Contact page with form functionality
kris6673 Feb 3, 2025
3f7e051
move up
kris6673 Feb 3, 2025
fa7eda9
make it actually work
kris6673 Feb 4, 2025
b0e222d
Country selector
kris6673 Feb 4, 2025
7e2c987
fix: Update label for GAL visibility and disable creatable option for…
kris6673 Feb 4, 2025
23c3056
Merge branch 'dev' of https://github.com/KelvinTegelaar/CIPP into dev
kris6673 Feb 4, 2025
0bcf894
add conditional
kris6673 Feb 4, 2025
1236ee5
fix some wrong values
kris6673 Feb 4, 2025
671bc5a
fix state values for connector enable/disable logic
kris6673 Feb 4, 2025
0a82a3c
add template library options
KelvinTegelaar Feb 5, 2025
30b4e8f
Add some onprem sync stuff back
kris6673 Feb 5, 2025
42d6a73
Now with a null check too!
kris6673 Feb 5, 2025
7c115b1
Merge pull request #3574 from kris6673/connector-fixes
JohnDuprey Feb 5, 2025
be34d7b
Merge pull request #3500 from Jr7468/dev
JohnDuprey Feb 5, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions public/discord-mark-blue.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/components/CippComponents/CippFormCondition.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export const CippFormCondition = (props) => {
if (watcher.includes(compareValue)) {
return children;
}
} else if (typeof watcher === "object" && compareValue in watcher) {
} else if (typeof watcher === "object" && watcher !== null && compareValue in watcher) {
// Check if object contains the key
return children;
}
Expand Down
222 changes: 222 additions & 0 deletions src/components/CippComponents/CippSpeedDial.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
import React, { useState, useEffect } from "react";
import {
SpeedDial,
SpeedDialAction,
SpeedDialIcon,
Dialog,
DialogTitle,
DialogContent,
DialogActions,
Button,
Snackbar,
Alert,
CircularProgress,
} from "@mui/material";
import { Close as CloseIcon } from "@mui/icons-material";
import { useForm } from "react-hook-form";
import { CippFormComponent } from "../../components/CippComponents/CippFormComponent";

const CippSpeedDial = ({
actions = [],
position = { bottom: 16, right: 16 },
icon,
openIcon = <CloseIcon />,
}) => {
const [openDialogs, setOpenDialogs] = useState({});
const [loading, setLoading] = useState(false);
const [showSnackbar, setShowSnackbar] = useState(false);
const [speedDialOpen, setSpeedDialOpen] = useState(false);
const [isHovering, setIsHovering] = useState(false);
const [snackbarMessage, setSnackbarMessage] = useState("");

const formControls = actions.reduce((acc, action) => {
if (action.form) {
acc[action.id] = useForm({
mode: "onChange",
defaultValues: action.form.defaultValues || {},
});
}
return acc;
}, {});

const handleSpeedDialClose = () => {
if (!isHovering) {
setTimeout(() => {
setSpeedDialOpen(false);
}, 200);
}
};

const handleMouseEnter = () => {
setIsHovering(true);
setSpeedDialOpen(true);
};

const handleMouseLeave = () => {
setIsHovering(false);
handleSpeedDialClose();
};

const handleDialogOpen = (actionId) => {
setOpenDialogs((prev) => ({ ...prev, [actionId]: true }));
};

const handleDialogClose = (actionId) => {
setOpenDialogs((prev) => ({ ...prev, [actionId]: false }));
};

const handleSubmit = async (actionId, data) => {
if (!actions.find((a) => a.id === actionId)?.onSubmit) return;

setLoading(true);
try {
const action = actions.find((a) => a.id === actionId);
const result = await action.onSubmit(data);

if (result.success) {
formControls[actionId]?.reset();
handleDialogClose(actionId);
}
setSnackbarMessage(result.message);
setShowSnackbar(true);
} catch (error) {
console.error(`Error submitting ${actionId}:`, error);
setSnackbarMessage("An error occurred while submitting");
setShowSnackbar(true);
} finally {
setLoading(false);
}
};

useEffect(() => {
const handleClickOutside = (event) => {
if (speedDialOpen) {
const speedDial = document.querySelector('[aria-label="Navigation SpeedDial"]');
if (speedDial && !speedDial.contains(event.target)) {
setSpeedDialOpen(false);
}
}
};

document.addEventListener("click", handleClickOutside);
return () => {
document.removeEventListener("click", handleClickOutside);
};
}, [speedDialOpen]);

return (
<>
<SpeedDial
ariaLabel="Navigation SpeedDial"
sx={{
position: "fixed",
...position,
"& .MuiFab-primary": {
width: 46,
height: 46,
"&:hover": {
backgroundColor: "primary.dark",
},
},
}}
icon={<SpeedDialIcon icon={icon} openIcon={openIcon} />}
open={speedDialOpen}
onClose={handleSpeedDialClose}
onOpen={() => setSpeedDialOpen(true)}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
>
{actions.map((action) => (
<SpeedDialAction
key={action.id}
icon={action.icon}
tooltipTitle={action.name}
onClick={() => {
if (action.form) {
handleDialogOpen(action.id);
} else if (action.onClick) {
action.onClick();
}
setSpeedDialOpen(false);
}}
tooltipOpen
sx={{
"&.MuiSpeedDialAction-fab": {
backgroundColor: "background.paper",
"&:hover": {
backgroundColor: "action.hover",
},
},
"& .MuiSpeedDialAction-staticTooltipLabel": {
cursor: "pointer",
whiteSpace: "nowrap",
marginRight: "10px",
padding: "6px 10px",
"&:hover": {
backgroundColor: "action.hover",
},
},
}}
/>
))}
</SpeedDial>

{actions
.filter((action) => action.form)
.map((action) => (
<Dialog
key={action.id}
open={openDialogs[action.id] || false}
onClose={() => handleDialogClose(action.id)}
maxWidth="md"
fullWidth
>
<DialogTitle>{action.form.title}</DialogTitle>
<DialogContent>
<CippFormComponent
type="richText"
name={action.form.fieldName}
required
formControl={formControls[action.id]}
style={{ minHeight: "150px" }}
editorProps={{
attributes: {
style: "min-height: 150px; font-size: 1.1rem; padding: 1rem;",
},
}}
/>
</DialogContent>
<DialogActions>
<Button onClick={() => handleDialogClose(action.id)} disabled={loading}>
Cancel
</Button>
<Button
onClick={formControls[action.id]?.handleSubmit((data) =>
handleSubmit(action.id, data)
)}
variant="contained"
color="primary"
disabled={loading}
startIcon={loading ? <CircularProgress size={20} /> : null}
>
{loading ? "Submitting..." : action.form.submitText || "Submit"}
</Button>
</DialogActions>
</Dialog>
))}

<Snackbar
open={showSnackbar}
autoHideDuration={6000}
onClose={() => setShowSnackbar(false)}
anchorOrigin={{ vertical: "bottom", horizontal: "center" }}
>
<Alert onClose={() => setShowSnackbar(false)} severity="success" sx={{ width: "100%" }}>
{snackbarMessage}
</Alert>
</Snackbar>
</>
);
};

export default CippSpeedDial;
2 changes: 1 addition & 1 deletion src/components/CippComponents/CippUserActions.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ export const CippUserActions = () => {
},
confirmText: "Are you sure you want to clear the Immutable ID for this user?",
multiPost: false,
condition: (row) => row.onPremisesSyncEnabled,
condition: (row) => !row.onPremisesSyncEnabled && row?.onPremisesImmutableId,
},
{
label: "Revoke all user sessions",
Expand Down
40 changes: 40 additions & 0 deletions src/pages/_app.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@ import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";
import { AdapterDateFns } from "@mui/x-date-pickers/AdapterDateFns";
import TimeAgo from "javascript-time-ago";
import en from "javascript-time-ago/locale/en.json";
import CippSpeedDial from "../components/CippComponents/CippSpeedDial";
import {
Help as HelpIcon,
BugReport as BugReportIcon,
Feedback as FeedbackIcon,
} from "@mui/icons-material";
import { SvgIcon } from "@mui/material";
import discordIcon from "../../public/discord-mark-blue.svg";
import React from "react";
TimeAgo.addDefaultLocale(en);

Expand All @@ -36,6 +44,33 @@ const App = (props) => {
const getLayout = Component.getLayout ?? ((page) => page);
const preferredTheme = useMediaPredicate("(prefers-color-scheme: dark)") ? "dark" : "light";

const speedDialActions = [
{
id: "bug-report",
icon: <BugReportIcon />,
name: "Report Bug",
href: "https://github.com/KelvinTegelaar/CIPP/issues/new?template=bug.yml",
onClick: () => window.open("https://github.com/KelvinTegelaar/CIPP/issues/new?template=bug.yml", "_blank")
},
{
id: "feature-request",
icon: <FeedbackIcon />,
name: "Request Feature",
href: "https://github.com/KelvinTegelaar/CIPP/issues/new?template=feature.yml",
onClick: () => window.open("https://github.com/KelvinTegelaar/CIPP/issues/new?template=feature.yml", "_blank")
},
{
id: "discord",
icon: (
<SvgIcon component={discordIcon} viewBox="0 0 127.14 96.36" sx={{ fontSize: '1.5rem' }}>
</SvgIcon>
),
name: "Join the Discord!",
href: "https://discord.gg/cyberdrain",
onClick: () => window.open("https://discord.gg/cyberdrain", "_blank")
},
];

return (
<CacheProvider value={emotionCache}>
<Head>
Expand Down Expand Up @@ -69,6 +104,11 @@ const App = (props) => {
<PrivateRoute>{getLayout(<Component {...pageProps} />)}</PrivateRoute>
</ErrorBoundary>
<Toaster position="top-center" />
<CippSpeedDial
actions={speedDialActions}
icon={<HelpIcon />}
position={{ bottom: 16, right: 16 }}
/>
</RTL>
</ThemeProvider>
{settings?.showDevtools && (
Expand Down
8 changes: 4 additions & 4 deletions src/pages/email/transport/list-connectors/add.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ const AddPolicy = () => {
return (
<CippFormPage
formControl={formControl}
queryKey="AddTransportRule"
title="Add Transport Rule"
backButtonTitle="Transport Rules Overview"
queryKey="AddConnector"
title="Add Connector"
backButtonTitle="Connectors Overview"
postUrl="/api/AddExConnector"
>
<Grid container spacing={2} sx={{ mb: 2 }}>
Expand All @@ -55,7 +55,7 @@ const AddPolicy = () => {
formControl={formControl}
multiple={false}
api={{
queryKey: `TemplateListTransport`,
queryKey: `TemplateListConnectors`,
labelField: "name",
valueField: (option) => option,
url: "/api/ListExconnectorTemplates",
Expand Down
11 changes: 4 additions & 7 deletions src/pages/email/transport/list-connectors/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ const Page = () => {
type: "POST",
url: "/api/EditExConnector",
icon: <Check />,
condition: (row) => !row.Enabled,
data: {
State: "Enable",
State: "!Enable",
GUID: "Guid",
Type: "cippconnectortype",
},
Expand All @@ -35,8 +36,9 @@ const Page = () => {
type: "POST",
url: "/api/EditExConnector",
icon: <Block />,
condition: (row) => row.Enabled,
data: {
State: "Disable",
State: "!Disable",
GUID: "Guid",
Type: "cippconnectortype",
},
Expand Down Expand Up @@ -82,11 +84,6 @@ const Page = () => {
actions={actions}
offCanvas={offCanvas}
simpleColumns={simpleColumns}
titleButton={{
label: "Deploy Connector",
href: "/email/connectors/deploy-connector",
startIcon: <RocketLaunch />, // Added icon
}}
cardButton={
<>
<Button
Expand Down
5 changes: 3 additions & 2 deletions src/pages/identity/administration/users/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const Page = () => {
const offCanvas = {
extendedInfoFields: [
"createdDateTime", // Created Date (UTC)
"id", // Unique ID
"userPrincipalName", // UPN
"givenName", // Given Name
"surname", // Surname
Expand All @@ -42,7 +43,7 @@ const Page = () => {
"city", // City
"department", // Department
"onPremisesLastSyncDateTime", // OnPrem Last Sync
"id", // Unique ID
"onPremisesDistinguishedName", // OnPrem DN
"otherMails", // Alternate Email Addresses
],
actions: CippUserActions(),
Expand All @@ -69,7 +70,7 @@ const Page = () => {
Endpoint: "users",
manualPagination: true,
$select:
"id,accountEnabled,businessPhones,city,createdDateTime,companyName,country,department,displayName,faxNumber,givenName,isResourceAccount,jobTitle,mail,mailNickname,mobilePhone,onPremisesDistinguishedName,officeLocation,onPremisesLastSyncDateTime,otherMails,postalCode,preferredDataLocation,preferredLanguage,proxyAddresses,showInAddressList,state,streetAddress,surname,usageLocation,userPrincipalName,userType,assignedLicenses,onPremisesSyncEnabled",
"id,accountEnabled,businessPhones,city,createdDateTime,companyName,country,department,displayName,faxNumber,givenName,isResourceAccount,jobTitle,mail,mailNickname,mobilePhone,officeLocation,otherMails,postalCode,preferredDataLocation,preferredLanguage,proxyAddresses,showInAddressList,state,streetAddress,surname,usageLocation,userPrincipalName,userType,assignedLicenses,onPremisesSyncEnabled,OnPremisesImmutableId,onPremisesLastSyncDateTime,onPremisesDistinguishedName",
$count: true,
$orderby: "displayName",
$top: 999,
Expand Down
Loading