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 #92

Merged
merged 2 commits into from
Feb 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion src/components/CippCards/CippBannerListCard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ export const CippBannerListCard = (props) => {
</Stack>
</Stack>
{isCollapsible && (
<Collapse in={isExpanded}>
<Collapse in={isExpanded} unmountOnExit>
<Divider />
<Stack spacing={1}>
{item?.propertyItems?.length > 0 && (
Expand Down
2 changes: 1 addition & 1 deletion src/components/CippCards/CippDomainCards.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,7 @@ export const CippDomainCards = ({ domain: propDomain = "", fullwidth = false })
</Button>
</Grid>
</Grid>
<Collapse in={optionsVisible}>
<Collapse in={optionsVisible} unmountOnExit>
<Stack direction="column" spacing={1} sx={{ mt: 1 }}>
<Controller
name="spfRecord"
Expand Down
3 changes: 3 additions & 0 deletions src/components/CippComponents/CippApiDialog.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,9 @@ export const CippApiDialog = (props) => {
<Grid container spacing={2}>
{fields &&
fields.map((fieldProps, index) => {
if (fieldProps?.api?.processFieldData) {
fieldProps.api.data = processActionData(fieldProps.api.data, row);
}
return (
<Grid item xs={12} key={index}>
<CippFormComponent
Expand Down
2 changes: 1 addition & 1 deletion src/components/CippComponents/CippApiResults.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ export const CippApiResults = (props) => {
))}
</>
)}
{apiObject.isSuccess || apiObject.isError ? (
{(apiObject.isSuccess || apiObject.isError) && finalResults.length > 0 ? (
<Box display="flex" flexDirection="row">
<Tooltip title="View Results">
<IconButton onClick={() => tableDialog.handleOpen()}>
Expand Down
2 changes: 1 addition & 1 deletion src/components/CippFormPages/CippExchangeSettingsForm.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,7 @@ const CippExchangeSettingsForm = (props) => {
</SvgIcon>
</IconButton>
</Box>
<Collapse in={isExpanded}>
<Collapse in={isExpanded} unmountOnExit>
<Divider />
<Box sx={{ p: 2 }}>{section.formContent}</Box>
</Collapse>
Expand Down
2 changes: 1 addition & 1 deletion src/components/CippSettings/CippPermissionCheck.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ const CippPermissionCheck = (props) => {
{(executeCheck.isSuccess || executeCheck.isLoading) && (
<>
{executeCheck.data?.Metadata?.AlertMessage && (
<Collapse in={showAlertMessage}>
<Collapse in={showAlertMessage} unmountOnExit>
<Alert
severity={executeCheck?.data?.Metadata?.AlertSeverity ?? "info"}
sx={{ mb: 2 }}
Expand Down
2 changes: 1 addition & 1 deletion src/components/CippStandards/CippStandardAccordion.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ const CippStandardAccordion = ({
</Stack>
</Stack>

<Collapse in={isExpanded}>
<Collapse in={isExpanded} unmountOnExit>
<Divider />
<Box sx={{ p: 3 }}>
<Grid container spacing={2}>
Expand Down
2 changes: 1 addition & 1 deletion src/data/Extensions.json
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,7 @@
"logo": "/assets/integrations/github.png",
"logoDark": "/assets/integrations/github_dark.png",
"description": "Enable the GitHub integration to manage your repositories from CIPP.",
"helpText": "This integration allows you to manage GitHub repositories from CIPP, including the Community Repositorities functionality. Requires a GitHub Personal Access Token (PAT) with a minimum of repo:public_repo permissions. You can create a PAT in your GitHub account settings, see the GitHub Token documentation for more info.",
"helpText": "This integration allows you to manage GitHub repositories from CIPP, including the Community Repositorities functionality. Requires a GitHub Personal Access Token (PAT) with a minimum of repo:public_repo permissions. If you plan on saving your templates to GitHub or accessing private/internal repositories, you will need to grant the whole repo scope. You can create a PAT in your GitHub account settings, see the GitHub Token documentation for more info. If you do not enable the extension, a read-only API will be provided.",
"links": [
{
"name": "GitHub Token",
Expand Down
33 changes: 32 additions & 1 deletion src/pages/tenant/standards/list-standards/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { CippTablePage } from "/src/components/CippComponents/CippTablePage.jsx"
import { Layout as DashboardLayout } from "/src/layouts/index.js"; // had to add an extra path here because I added an extra folder structure. We should switch to absolute pathing so we dont have to deal with relative.
import Link from "next/link";
import { EyeIcon } from "@heroicons/react/24/outline";
import { CopyAll, Delete, PlayArrow, AddBox, Visibility, Edit } from "@mui/icons-material";
import { CopyAll, Delete, PlayArrow, AddBox, Visibility, Edit, GitHub } from "@mui/icons-material";
import { ApiGetCall, ApiPostCall } from "../../../../api/ApiCall";
import { Grid } from "@mui/system";
import { CippApiResults } from "../../../../components/CippComponents/CippApiResults";
Expand Down Expand Up @@ -51,6 +51,37 @@ const Page = () => {
confirmText: "Are you sure you want to force a run of this template?",
multiPost: false,
},
{
label: "Save to GitHub",
type: "POST",
url: "/api/ExecCommunityRepo",
icon: <GitHub />,
data: {
Action: "UploadTemplate",
GUID: "GUID",
},
fields: [
{
label: "Repository",
name: "FullName",
type: "select",
api: {
url: "/api/ListCommunityRepos",
data: {
WriteAccess: true,
},
queryKey: "CommunityRepos-Write",
dataKey: "Results",
valueField: "FullName",
labelField: "FullName",
},
multiple: false,
createable: false,
},

],
confirmText: "Are you sure you want to save this template to the selected repository?",
},
{
label: "Delete Template",
type: "POST",
Expand Down
171 changes: 146 additions & 25 deletions src/pages/tools/community-repos/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import { Radio, RadioGroup, FormControlLabel } from "@mui/material";
import { CippFormCondition } from "/src/components/CippComponents/CippFormCondition";
import AddIcon from "@mui/icons-material/Add";
import { Box } from "@mui/system";
import { Add, OpenInNew } from "@mui/icons-material";
import { Add, ForkLeft, OpenInNew } from "@mui/icons-material";
import { CippApiResults } from "/src/components/CippComponents/CippApiResults";
import { ApiGetCall } from "../../../api/ApiCall";
import NextLink from "next/link";
Expand All @@ -39,6 +39,28 @@ const Page = () => {
const [repo, setRepo] = useState("");
const [user, setUser] = useState("");
const [org, setOrg] = useState("");
const [openCreate, setOpenCreate] = useState(false);
const createForm = useForm({ mode: "onChange", defaultValues: { Type: "user" } });

const createMutation = ApiPostCall({
urlFromData: true,
relatedQueryKeys: ["CommunityRepos"],
});

const handleCreateRepo = (values) => {
console.log(values);
createMutation.mutate({
url: "/api/ExecGitHubAction",
data: {
Action: "CreateRepo",
Type: values.type,
Name: values.repoName,
Org: values.orgName?.value,
Description: values.Description,
Private: values.Private,
},
});
};

const actions = [
{
Expand All @@ -56,19 +78,53 @@ const Page = () => {
multiPost: false,
queryKey: "CommunityRepos",
},
{
label: "Set Upload Branch",
type: "POST",
url: "/api/ExecCommunityRepo",
data: { Action: "SetBranch", Id: "Id" },
icon: <ForkLeft />,
fields: [
{
type: "select",
name: "Branch",
label: "Branch",
api: {
url: "/api/ExecGitHubAction",
type: "GET",
data: {
Action: "GetBranches",
FullName: "FullName",
},
dataKey: "Results",
labelField: "name",
valueField: "name",
processFieldData: true,
},
},
],
hideBulk: true,
confirmText: "Are you sure you want to set the branch for this repository?",
condition: (row) => row.WriteAccess === true,
},
];

const offCanvas = {
extendedInfoFields: ["Owner", "Name", "Description", "URL", "Visibility", "Permissions"],
extendedInfoFields: [
"Owner",
"Name",
"Description",
"URL",
"Visibility",
"DefaultBranch",
"UploadBranch",
"Permissions",
],
actions: actions,
};

const integrations = ApiGetCall({
url: "/api/ListExtensionsConfig",
queryKey: "Integrations",
});

const searchMutation = ApiPostCall({
urlFromData: true,
onResult: (resp) => {
setResults(resp?.Results || []);
},
Expand Down Expand Up @@ -109,32 +165,97 @@ const Page = () => {
<CippTablePage
title="Community Repositories"
tenantInTitle={false}
tableFilter={
<>
{integrations.isSuccess && !integrations.data?.GitHub?.Enabled && (
<Alert severity="info">
The community repositories feature requires the GitHub Integration to be enabled. Go
to the{" "}
<Link component={NextLink} href={"/cipp/integrations/configure?id=GitHub"}>
GitHub Integration
</Link>{" "}
page to enable it.
</Alert>
)}
</>
}
apiUrl="/api/ListCommunityRepos"
apiDataKey="Results"
queryKey="CommunityRepos"
actions={actions}
offCanvas={offCanvas}
simpleColumns={["Name", "Owner", "URL", "Visibility", "WriteAccess"]}
simpleColumns={["Name", "Owner", "URL", "Visibility", "WriteAccess", "UploadBranch"]}
cardButton={
<Button onClick={() => setOpenSearch(true)} startIcon={<Add />}>
Add Repo
</Button>
<>
<Button onClick={() => setOpenSearch(true)} startIcon={<Add />}>
Add Repo
</Button>
<Button onClick={() => setOpenCreate(true)} startIcon={<Add />}>
Create Repo
</Button>
</>
}
/>
<Dialog fullWidth maxWidth="md" open={openCreate} onClose={() => setOpenCreate(false)}>
<DialogTitle>Create New Repository</DialogTitle>
<DialogContent>
<FormProvider {...createForm}>
<RadioGroup
row
value={createForm.watch("Type")}
onChange={(e) => {
createForm.setValue("Type", e.target.value);
}}
>
<FormControlLabel value="user" control={<Radio />} label="User" />
<FormControlLabel value="org" control={<Radio />} label="Org" />
</RadioGroup>
<Stack spacing={1} sx={{ mt: 2 }}>
<CippFormCondition
field="Type"
compareType="is"
compareValue="org"
formControl={createForm}
>
<CippFormComponent
type="autoComplete"
name="orgName"
formControl={createForm}
label="Organization"
api={{
url: "/api/ExecGitHubAction",
data: {
Action: "GetOrgs",
},
queryKey: "GitHubOrgs",
dataKey: "Results",
labelField: "login",
valueField: "login",
}}
multiple={false}
/>
</CippFormCondition>
<CippFormComponent
type="textField"
name="repoName"
label="Repository Name"
formControl={createForm}
/>
<CippFormComponent
type="textField"
name="Description"
label="Description"
formControl={createForm}
/>
<CippFormComponent
type="switch"
name="Private"
label="Private"
formControl={createForm}
/>
</Stack>
</FormProvider>
<CippApiResults apiObject={createMutation} />
</DialogContent>
<DialogActions>
<Button variant="outlined" onClick={() => setOpenCreate(false)}>
Cancel
</Button>
<Button
variant="contained"
type="submit"
onClick={createForm.handleSubmit(handleCreateRepo)}
>
Create
</Button>
</DialogActions>
</Dialog>
<Dialog fullWidth maxWidth="md" open={openSearch} onClose={() => setOpenSearch(false)}>
<DialogTitle>Add Community Repositories from GitHub</DialogTitle>
<DialogContent>
Expand Down
17 changes: 0 additions & 17 deletions src/pages/tools/templatelib/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,6 @@ const TemplateLibrary = () => {
},
});

const integrations = ApiGetCall({
url: "/api/ListExtensionsConfig",
queryKey: "Integrations",
});

const templateRepo = useWatch({ control: formControl.control, name: "templateRepo" });

const customDataFormatter = (values) => {
Expand Down Expand Up @@ -81,17 +76,6 @@ const TemplateLibrary = () => {
<Alert severity="warning" sx={{ my: 2 }}>
Enabling this feature will overwrite templates with the same name.
</Alert>

{integrations.isSuccess && !integrations.data?.GitHub?.Enabled && (
<Alert severity="info">
The community repositories feature requires the GitHub Integration to be enabled. Go
to the{" "}
<Link component={NextLink} href={"/cipp/integrations/configure?id=GitHub"}>
GitHub Integration
</Link>{" "}
page to enable it.
</Alert>
)}
</Grid>

<Divider sx={{ mt: 2, width: "100%" }} />
Expand Down Expand Up @@ -136,7 +120,6 @@ const TemplateLibrary = () => {
}}
formControl={formControl}
multiple={false}
disabled={!integrations.data?.GitHub?.Enabled}
/>
</Box>
</Grid>
Expand Down