From 252a1cfef593a8ddb7063a9847d3ded344074d41 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Tue, 11 Feb 2025 19:24:43 -0500 Subject: [PATCH 1/2] tweaks and features unmount collapse on close add more functionality to community repos add save to github button on standards --- .../CippCards/CippBannerListCard.jsx | 2 +- src/components/CippCards/CippDomainCards.jsx | 2 +- .../CippComponents/CippApiResults.jsx | 2 +- .../CippExchangeSettingsForm.jsx | 2 +- .../CippSettings/CippPermissionCheck.jsx | 2 +- .../CippStandards/CippStandardAccordion.jsx | 2 +- src/data/Extensions.json | 2 +- .../tenant/standards/list-standards/index.js | 33 ++++- src/pages/tools/community-repos/index.js | 127 +++++++++++++++--- src/pages/tools/templatelib/index.jsx | 17 --- 10 files changed, 144 insertions(+), 47 deletions(-) diff --git a/src/components/CippCards/CippBannerListCard.jsx b/src/components/CippCards/CippBannerListCard.jsx index aa7fc42a8bca..32e8aee05e8d 100644 --- a/src/components/CippCards/CippBannerListCard.jsx +++ b/src/components/CippCards/CippBannerListCard.jsx @@ -143,7 +143,7 @@ export const CippBannerListCard = (props) => { {isCollapsible && ( - + {item?.propertyItems?.length > 0 && ( diff --git a/src/components/CippCards/CippDomainCards.jsx b/src/components/CippCards/CippDomainCards.jsx index 0da5fb61de97..286e7cc35808 100644 --- a/src/components/CippCards/CippDomainCards.jsx +++ b/src/components/CippCards/CippDomainCards.jsx @@ -510,7 +510,7 @@ export const CippDomainCards = ({ domain: propDomain = "", fullwidth = false }) - + { ))} )} - {apiObject.isSuccess || apiObject.isError ? ( + {(apiObject.isSuccess || apiObject.isError) && !errorsOnly ? ( tableDialog.handleOpen()}> diff --git a/src/components/CippFormPages/CippExchangeSettingsForm.jsx b/src/components/CippFormPages/CippExchangeSettingsForm.jsx index 3f755ca3b804..66d8bb4b6ecb 100644 --- a/src/components/CippFormPages/CippExchangeSettingsForm.jsx +++ b/src/components/CippFormPages/CippExchangeSettingsForm.jsx @@ -515,7 +515,7 @@ const CippExchangeSettingsForm = (props) => { - + {section.formContent} diff --git a/src/components/CippSettings/CippPermissionCheck.jsx b/src/components/CippSettings/CippPermissionCheck.jsx index 5ad0f5d0a502..db0c81c7ad38 100644 --- a/src/components/CippSettings/CippPermissionCheck.jsx +++ b/src/components/CippSettings/CippPermissionCheck.jsx @@ -142,7 +142,7 @@ const CippPermissionCheck = (props) => { {(executeCheck.isSuccess || executeCheck.isLoading) && ( <> {executeCheck.data?.Metadata?.AlertMessage && ( - + - + diff --git a/src/data/Extensions.json b/src/data/Extensions.json index 64c5bb8f59df..ab1dc4c20c95 100644 --- a/src/data/Extensions.json +++ b/src/data/Extensions.json @@ -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", diff --git a/src/pages/tenant/standards/list-standards/index.js b/src/pages/tenant/standards/list-standards/index.js index 2d9b4493d975..40a215deac87 100644 --- a/src/pages/tenant/standards/list-standards/index.js +++ b/src/pages/tenant/standards/list-standards/index.js @@ -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"; @@ -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: , + 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", diff --git a/src/pages/tools/community-repos/index.js b/src/pages/tools/community-repos/index.js index 044fe1c8e035..9faebdc1a1f6 100644 --- a/src/pages/tools/community-repos/index.js +++ b/src/pages/tools/community-repos/index.js @@ -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 = [ { @@ -63,12 +85,8 @@ const Page = () => { actions: actions, }; - const integrations = ApiGetCall({ - url: "/api/ListExtensionsConfig", - queryKey: "Integrations", - }); - const searchMutation = ApiPostCall({ + urlFromData: true, onResult: (resp) => { setResults(resp?.Results || []); }, @@ -109,20 +127,6 @@ const Page = () => { - {integrations.isSuccess && !integrations.data?.GitHub?.Enabled && ( - - The community repositories feature requires the GitHub Integration to be enabled. Go - to the{" "} - - GitHub Integration - {" "} - page to enable it. - - )} - - } apiUrl="/api/ListCommunityRepos" apiDataKey="Results" queryKey="CommunityRepos" @@ -130,11 +134,90 @@ const Page = () => { offCanvas={offCanvas} simpleColumns={["Name", "Owner", "URL", "Visibility", "WriteAccess"]} cardButton={ - + <> + + + } /> + setOpenCreate(false)}> + Create New Repository + + + { + createForm.setValue("Type", e.target.value); + }} + > + } label="User" /> + } label="Org" /> + + + + + + + + + + + + + + + + + setOpenSearch(false)}> Add Community Repositories from GitHub diff --git a/src/pages/tools/templatelib/index.jsx b/src/pages/tools/templatelib/index.jsx index e05689adf61f..5fa63b3bbf9b 100644 --- a/src/pages/tools/templatelib/index.jsx +++ b/src/pages/tools/templatelib/index.jsx @@ -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) => { @@ -81,17 +76,6 @@ const TemplateLibrary = () => { Enabling this feature will overwrite templates with the same name. - - {integrations.isSuccess && !integrations.data?.GitHub?.Enabled && ( - - The community repositories feature requires the GitHub Integration to be enabled. Go - to the{" "} - - GitHub Integration - {" "} - page to enable it. - - )} @@ -136,7 +120,6 @@ const TemplateLibrary = () => { }} formControl={formControl} multiple={false} - disabled={!integrations.data?.GitHub?.Enabled} /> From 89c860ec50554f0ce591636e20c9585789a6e8a4 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Tue, 11 Feb 2025 21:10:03 -0500 Subject: [PATCH 2/2] Add Set Upload Branch action Tweak API dialog Tweak API results --- .../CippComponents/CippApiDialog.jsx | 3 ++ .../CippComponents/CippApiResults.jsx | 2 +- src/pages/tools/community-repos/index.js | 44 +++++++++++++++++-- 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/src/components/CippComponents/CippApiDialog.jsx b/src/components/CippComponents/CippApiDialog.jsx index 0a23dc3cb982..d5e15d9bccff 100644 --- a/src/components/CippComponents/CippApiDialog.jsx +++ b/src/components/CippComponents/CippApiDialog.jsx @@ -325,6 +325,9 @@ export const CippApiDialog = (props) => { {fields && fields.map((fieldProps, index) => { + if (fieldProps?.api?.processFieldData) { + fieldProps.api.data = processActionData(fieldProps.api.data, row); + } return ( { ))} )} - {(apiObject.isSuccess || apiObject.isError) && !errorsOnly ? ( + {(apiObject.isSuccess || apiObject.isError) && finalResults.length > 0 ? ( tableDialog.handleOpen()}> diff --git a/src/pages/tools/community-repos/index.js b/src/pages/tools/community-repos/index.js index 9faebdc1a1f6..56cfd7a62e30 100644 --- a/src/pages/tools/community-repos/index.js +++ b/src/pages/tools/community-repos/index.js @@ -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"; @@ -78,10 +78,48 @@ const Page = () => { multiPost: false, queryKey: "CommunityRepos", }, + { + label: "Set Upload Branch", + type: "POST", + url: "/api/ExecCommunityRepo", + data: { Action: "SetBranch", Id: "Id" }, + icon: , + 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, }; @@ -132,7 +170,7 @@ const Page = () => { queryKey="CommunityRepos" actions={actions} offCanvas={offCanvas} - simpleColumns={["Name", "Owner", "URL", "Visibility", "WriteAccess"]} + simpleColumns={["Name", "Owner", "URL", "Visibility", "WriteAccess", "UploadBranch"]} cardButton={ <>