From e5780cc3d3a44068e4c91f2b3bee0ac3699547de Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Wed, 30 Aug 2023 20:26:55 +0200 Subject: [PATCH 01/38] group template --- src/views/tenant/standards/ListAppliedStandards.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/tenant/standards/ListAppliedStandards.js b/src/views/tenant/standards/ListAppliedStandards.js index 01cd41c41be2..94bcc688001b 100644 --- a/src/views/tenant/standards/ListAppliedStandards.js +++ b/src/views/tenant/standards/ListAppliedStandards.js @@ -482,7 +482,7 @@ const ListAppliedStandards = () => { name: template.Displayname, }))} placeholder="Select a template" - label="Choose your intune templates to apply" + label="Choose your group templates to apply" /> )} From 974e48682dc92be101fafa420af959f2ac0153a6 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Thu, 31 Aug 2023 12:36:44 +0200 Subject: [PATCH 02/38] webhook bulk removal fix --- src/views/tenant/administration/ListAlertsQueue.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/views/tenant/administration/ListAlertsQueue.js b/src/views/tenant/administration/ListAlertsQueue.js index 8b52ee6d9624..7888d38aac6e 100644 --- a/src/views/tenant/administration/ListAlertsQueue.js +++ b/src/views/tenant/administration/ListAlertsQueue.js @@ -255,7 +255,7 @@ const ListAlertsQueue = () => { label: 'Delete alerts', color: 'info', modal: true, - modalUrl: `/api/RemoveQueuedAlert?ID=!tenantId`, + modalUrl: `/api/RemoveQueuedAlert?ID=!tenantid`, modalMessage: 'Are you sure you want to delete these alerts?', }, ], @@ -281,7 +281,7 @@ const ListAlertsQueue = () => { label: 'Delete webhook', color: 'info', modal: true, - modalUrl: `/api/RemoveWebhookAlert?CIPPID=!CIPPID&tenantfilter=!tenantid`, + modalUrl: `/api/RemoveWebhookAlert?CIPPID=!CIPPID&tenantfilter=!tenantName`, modalMessage: 'Are you sure you want to delete this webhook alert?', }, ], From 06c0057800b3bf7aa0ea73a3211053963b3be407 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Sun, 3 Sep 2023 15:14:29 -0400 Subject: [PATCH 03/38] Tenant Selector Offcanvas --- .../utilities/CippTenantOffcanvas.js | 105 ++++++++++++++++++ src/components/utilities/TenantSelector.js | 62 ++++++----- src/views/tenant/administration/Tenants.js | 102 +---------------- 3 files changed, 143 insertions(+), 126 deletions(-) create mode 100644 src/components/utilities/CippTenantOffcanvas.js diff --git a/src/components/utilities/CippTenantOffcanvas.js b/src/components/utilities/CippTenantOffcanvas.js new file mode 100644 index 000000000000..1cb80cbacfeb --- /dev/null +++ b/src/components/utilities/CippTenantOffcanvas.js @@ -0,0 +1,105 @@ +import React, { useState } from 'react' +import { CButton } from '@coreui/react' +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' +import { faCog, faEdit, faEllipsisV, faBuilding } from '@fortawesome/free-solid-svg-icons' +import { CippActionsOffcanvas } from 'src/components/utilities' +import { useLazyGenericGetRequestQuery } from 'src/store/api/app' +import Skeleton from 'react-loading-skeleton' +import Portals from 'src/data/portals' + +export const CippTenantOffcanvasRow = (row, rowIndex, formatExtraData) => { + const tenant = row + console.log('tenant offcanvas row') + return CippTenantOffcanvas({ tenant: row }) +} + +function CippTenantOffcanvas({ tenant, buildingIcon = false }) { + const [getTenantDetails, tenantDetails] = useLazyGenericGetRequestQuery() + const [ocVisible, setOCVisible] = useState(false) + console.log(tenant) + function loadOffCanvasDetails(domainName) { + setOCVisible(true) + getTenantDetails({ path: `api/ListTenantDetails?tenantfilter=${domainName}` }) + } + + function tenantProperty(tenantDetails, propertyName) { + return ( + <> + {tenantDetails.isFetching && } + {!tenantDetails.isFetching && + tenantDetails.isSuccess && + (tenantDetails.data[propertyName]?.toString() ?? ' ')} + + ) + } + const actions = Portals.map((portal) => ({ + icon: , + label: portal.label, + external: true, + color: 'info', + link: portal.url.replace(portal.variable, tenant[portal.variable]), + })) + return ( + <> + loadOffCanvasDetails(tenant.defaultDomainName)} + > + + + , + label: 'Edit Tenant', + link: `/tenant/administration/tenants/Edit?tenantFilter=${tenant.defaultDomainName}&customerId=${tenant.customerId}`, + color: 'warning', + }, + ...actions, + ]} + placement="end" + visible={ocVisible} + id={tenant.id} + hideFunction={() => setOCVisible(false)} + /> + + ) +} + +export default CippTenantOffcanvas diff --git a/src/components/utilities/TenantSelector.js b/src/components/utilities/TenantSelector.js index bf4020eceb62..dfa54ac55ab6 100644 --- a/src/components/utilities/TenantSelector.js +++ b/src/components/utilities/TenantSelector.js @@ -4,11 +4,12 @@ import { useDispatch, useSelector } from 'react-redux' import PropTypes from 'prop-types' import { useListTenantsQuery } from 'src/store/api/tenants' import { setCurrentTenant } from 'src/store/features/app' -import { CDropdown, CDropdownMenu, CDropdownToggle } from '@coreui/react' +import { CButton, CDropdown, CDropdownMenu, CDropdownToggle } from '@coreui/react' import { useNavigate, useSearchParams } from 'react-router-dom' import { queryString } from 'src/helpers' import { faBuilding } from '@fortawesome/free-solid-svg-icons' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' +import CippTenantOffcanvas from './CippTenantOffcanvas' const TenantSelector = ({ action, showAllTenantSelector = true, NavSelector = false }) => { const currentTenant = useSelector((state) => state.app.currentTenant) @@ -57,7 +58,6 @@ const TenantSelector = ({ action, showAllTenantSelector = true, NavSelector = fa return t.customerId === customerId }) dispatch(setCurrentTenant({ tenant: selectedTenant[0] })) - if (typeof action === 'function') { action(selectedTenant[0]) } else { @@ -75,32 +75,38 @@ const TenantSelector = ({ action, showAllTenantSelector = true, NavSelector = fa return ( <> {NavSelector && ( - - - - {currentTenant?.defaultDomainName ? ( - <> - {currentTenant.displayName} - - ) : ( - placeholder - )} - - - ({ - value: customerId, - name: [displayName] + [` (${defaultDomainName})`], - }))} - /> - - + <> + + + {currentTenant?.customerId !== 'AllTenants' ? ( + + ) : ( + + )} + {currentTenant?.defaultDomainName ? ( + <> + {currentTenant.displayName} + + ) : ( + placeholder + )} + + + ({ + value: customerId, + name: [displayName] + [` (${defaultDomainName})`], + }))} + /> + + + )} {!NavSelector && ( { - const [getTenantDetails, tenantDetails] = useLazyGenericGetRequestQuery() - const [ocVisible, setOCVisible] = useState(false) - - function loadOffCanvasDetails(domainName) { - setOCVisible(true) - getTenantDetails({ path: `api/ListTenantDetails?tenantfilter=${domainName}` }) - } - - function tenantProperty(tenantDetails, propertyName) { - return ( - <> - {tenantDetails.isFetching && } - {!tenantDetails.isFetching && - tenantDetails.isSuccess && - (tenantDetails.data[propertyName]?.toString() ?? ' ')} - - ) - } - const actions = Portals.map((portal) => ({ - icon: , - label: portal.label, - external: true, - color: 'info', - link: portal.url.replace(portal.variable, row[portal.variable]), - })) - return ( - <> - loadOffCanvasDetails(row.defaultDomainName)}> - - - , - label: 'Edit Tenant', - link: `/tenant/administration/tenants/Edit?tenantFilter=${row.defaultDomainName}&customerId=${row.customerId}`, - color: 'warning', - }, - ...actions, - ]} - placement="end" - visible={ocVisible} - id={row.id} - hideFunction={() => setOCVisible(false)} - /> - - ) -} +import { CippTenantOffcanvasRow } from 'src/components/utilities/CippTenantOffcanvas' const TenantsList = () => { const TenantListSelector = useSelector((state) => state.app.TenantListSelector) @@ -148,7 +54,7 @@ const TenantsList = () => { { name: 'Actions', center: true, - cell: Offcanvas, + cell: CippTenantOffcanvasRow, }, ] const titleButton = ( From eecd749050f2876037abb07f1df0ab618891a816 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Sun, 3 Sep 2023 15:58:17 -0400 Subject: [PATCH 04/38] remove logging --- src/components/utilities/CippTenantOffcanvas.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/components/utilities/CippTenantOffcanvas.js b/src/components/utilities/CippTenantOffcanvas.js index 1cb80cbacfeb..b15a595b3a92 100644 --- a/src/components/utilities/CippTenantOffcanvas.js +++ b/src/components/utilities/CippTenantOffcanvas.js @@ -9,14 +9,12 @@ import Portals from 'src/data/portals' export const CippTenantOffcanvasRow = (row, rowIndex, formatExtraData) => { const tenant = row - console.log('tenant offcanvas row') return CippTenantOffcanvas({ tenant: row }) } function CippTenantOffcanvas({ tenant, buildingIcon = false }) { const [getTenantDetails, tenantDetails] = useLazyGenericGetRequestQuery() const [ocVisible, setOCVisible] = useState(false) - console.log(tenant) function loadOffCanvasDetails(domainName) { setOCVisible(true) getTenantDetails({ path: `api/ListTenantDetails?tenantfilter=${domainName}` }) From 1be36e0e5d5613536cf98e2502aafacd4268fd7d Mon Sep 17 00:00:00 2001 From: John Duprey Date: Sun, 3 Sep 2023 16:10:22 -0400 Subject: [PATCH 05/38] Tenant Dashboard Improvements - Hide tenant overview on All Tenants - Adjust breakpoints for smaller resolutions - Move delegatedAdminPrivilege formatter to components - Bring CellBadge with delegated admin privilege to tenant overview --- .../tables/CellDelegatedPrivilege.js | 25 ++ src/components/tables/index.js | 2 + src/views/cipp/CIPPSettings.js | 21 +- src/views/home/Home.js | 344 +++++++++--------- 4 files changed, 209 insertions(+), 183 deletions(-) create mode 100644 src/components/tables/CellDelegatedPrivilege.js diff --git a/src/components/tables/CellDelegatedPrivilege.js b/src/components/tables/CellDelegatedPrivilege.js new file mode 100644 index 000000000000..66d44d8a65c0 --- /dev/null +++ b/src/components/tables/CellDelegatedPrivilege.js @@ -0,0 +1,25 @@ +import PropTypes from 'prop-types' +import { CellBadge } from './CellBadge' + +export function CellDelegatedPrivilege({ cell }) { + if (!cell) { + return + } + if (cell.toLowerCase() == 'none') { + return + } + if (cell === 'delegatedAdminPrivileges') { + return + } + if (cell === 'delegatedAndGranularDelegetedAdminPrivileges') { + return + } + if (cell === 'granularDelegatedAdminPrivileges') { + return + } + return +} + +CellDelegatedPrivilege.propTypes = { + cell: PropTypes.string, +} diff --git a/src/components/tables/index.js b/src/components/tables/index.js index 3358c488e18b..6c45e48aa1c1 100644 --- a/src/components/tables/index.js +++ b/src/components/tables/index.js @@ -4,6 +4,7 @@ import { CellDate, cellDateFormatter } from 'src/components/tables/CellDate' import { CellTip, CellTipButton, CellTipIcon } from 'src/components/tables/CellTip' import { CellNullText, cellNullTextFormatter } from 'src/components/tables/CellNullText' import { CellProgressBar, cellProgressBarFormatter } from 'src/components/tables/CellProgressBar' +import { CellDelegatedPrivilege } from './CellDelegatedPrivilege' import CippDatatable from 'src/components/tables/CippDatatable' import CippOffcanvasTable from 'src/components/tables/CippOffcanvasTable' import CippTable from 'src/components/tables/CippTable' @@ -27,4 +28,5 @@ export { CippOffcanvasTable, CippTable, WizardTableField, + CellDelegatedPrivilege, } diff --git a/src/views/cipp/CIPPSettings.js b/src/views/cipp/CIPPSettings.js index f3206116d62d..827441ad2b1c 100644 --- a/src/views/cipp/CIPPSettings.js +++ b/src/views/cipp/CIPPSettings.js @@ -80,6 +80,7 @@ import { TitleButton } from 'src/components/buttons' import Skeleton from 'react-loading-skeleton' import { Buffer } from 'buffer' import Extensions from 'src/data/Extensions.json' +import { CellDelegatedPrivilege } from 'src/components/tables/CellDelegatedPrivilege' const CIPPSettings = () => { const [active, setActive] = useState(1) @@ -702,25 +703,7 @@ const ExcludedTenantsSettings = () => { name: 'Relationship Type', selector: (row) => row['delegatedPrivilegeStatus'], sortable: true, - cell: (row, index, column) => { - const cell = column.selector(row) - if (!cell) { - return - } - if (cell.toLowerCase() == 'none') { - return - } - if (cell === 'delegatedAdminPrivileges') { - return - } - if (cell === 'delegatedAndGranularDelegetedAdminPrivileges') { - return - } - if (cell === 'granularDelegatedAdminPrivileges') { - return - } - return - }, + cell: (row) => CellDelegatedPrivilege({ cell: row['delegatedPrivilegeStatus'] }), exportSelector: 'delegatedPrivilegeStatus', }, { diff --git a/src/views/home/Home.js b/src/views/home/Home.js index 9e3741288987..1f4602f210f6 100644 --- a/src/views/home/Home.js +++ b/src/views/home/Home.js @@ -25,6 +25,7 @@ import { ActionContentCard } from 'src/components/contentcards' import { useSelector } from 'react-redux' import allStandardsList from 'src/data/standards' import ReactTimeAgo from 'react-time-ago' +import { CellDelegatedPrivilege } from 'src/components/tables/CellDelegatedPrivilege' const Home = () => { const currentTenant = useSelector((state) => state.app.currentTenant) @@ -171,173 +172,188 @@ const Home = () => { - - - -
- {issuccessUserCounts && !isFetchingUserCount ? dashboard?.Users : } -
-
-
- - -
- {issuccessUserCounts && !isFetchingUserCount ? dashboard?.LicUsers : } -
-
-
- - -
{issuccessUserCounts && !isFetchingUserCount ? dashboard?.Gas : }
-
-
- - -
- {issuccessUserCounts && !isFetchingUserCount ? dashboard?.Guests : } -
-
-
-
- - - - - -

Tenant Name

- {currentTenant?.displayName} -
- -

Tenant ID

- {currentTenant?.customerId} -
- -

Default Domain Name

- {currentTenant?.defaultDomainName} -
-
- - -

Tenant Status

- {currentTenant?.delegatedPrivilegeStatus} -
- -

Creation Date

- {(isLoadingOrg || isFetchingOrg) && } - {organization && !isFetchingOrg && organization?.createdDateTime} -
- -

AD Connect Status

- {(isLoadingOrg || isFetchingOrg) && } - {!isLoadingOrg && !isFetchingOrg && organization?.onPremisesSyncEnabled ? ( - <> -
  • - Directory Sync: - {organization?.onPremisesLastSyncDateTime ? ( - - ) : ( - 'Never' - )} -
  • -
  • - Password Sync: - {organization?.onPremisesLastPasswordSyncDateTime ? ( - - ) : ( - 'Never' - )} -
  • - - ) : ( - 'Disabled' - )} -
    -
    - - -

    Domain(s)

    - {(isLoadingOrg || isFetchingOrg) && } - {!isFetchingOrg && - issuccessOrg && - organization?.verifiedDomains?.map((item) =>
  • {item.name}
  • )} -
    - -

    Capabilities

    - {(isLoadingOrg || isFetchingOrg) && } - {!isFetchingOrg && - issuccessOrg && - organization?.assignedPlans - ?.filter((p) => p.capabilityStatus == 'Enabled') - .reduce((plan, curr) => { - if (!plan.includes(curr.service)) { - plan.push(curr.service) - } - return plan - }, []) - .map((plan) => ( + {currentTenant?.customerId !== 'AllTenants' ? ( + <> + + + +
    + {issuccessUserCounts && !isFetchingUserCount ? dashboard?.Users : } +
    +
    +
    + + +
    + {issuccessUserCounts && !isFetchingUserCount ? dashboard?.LicUsers : } +
    +
    +
    + + +
    + {issuccessUserCounts && !isFetchingUserCount ? dashboard?.Gas : } +
    +
    +
    + + +
    + {issuccessUserCounts && !isFetchingUserCount ? dashboard?.Guests : } +
    +
    +
    +
    + + + + + +

    Tenant Name

    + {currentTenant?.displayName} +
    + +

    Tenant ID

    + {currentTenant?.customerId} +
    + +

    Default Domain Name

    + {currentTenant?.defaultDomainName} +
    +
    + + +

    Tenant Status

    + +
    + +

    Creation Date

    + {(isLoadingOrg || isFetchingOrg) && } + {organization && !isFetchingOrg && organization?.createdDateTime} +
    + +

    AD Connect Status

    + {(isLoadingOrg || isFetchingOrg) && } + {!isLoadingOrg && !isFetchingOrg && organization?.onPremisesSyncEnabled ? ( <> - {plan == 'exchange' &&
  • Exchange
  • } - {plan == 'AADPremiumService' &&
  • AAD Premium
  • } - {plan == 'WindowsDefenderATP' &&
  • Windows Defender
  • } +
  • + Directory Sync: + {organization?.onPremisesLastSyncDateTime ? ( + + ) : ( + 'Never' + )} +
  • +
  • + Password Sync: + {organization?.onPremisesLastPasswordSyncDateTime ? ( + + ) : ( + 'Never' + )} +
  • - ))} -
    - -

    Sharepoint Quota

    - {(isLoadingSPQuota || isFetchingSPQuota) && } - {sharepoint && !isFetchingSPQuota && sharepoint?.Dashboard} -
    - -

    Applied Standards

    - {(isLoadingStandards || isFetchingStandards) && } - {issuccessStandards && - !isFetchingStandards && - standards - .filter( - (p) => - p.displayName == 'AllTenants' || - p.displayName == currentTenant.defaultDomainName, - ) - .flatMap((tenant) => { - return Object.keys(tenant.standards).map((standard) => { - const standardDisplayname = allStandardsList.filter((p) => - p.name.includes(standard), - ) - return ( -
  • - {standardDisplayname[0]?.label} ({tenant.displayName}) -
  • + ) : ( + 'Disabled' + )} +
    +
    + + +

    Domain(s)

    + {(isLoadingOrg || isFetchingOrg) && } + {!isFetchingOrg && + issuccessOrg && + organization?.verifiedDomains?.map((item) =>
  • {item.name}
  • )} +
    + +

    Capabilities

    + {(isLoadingOrg || isFetchingOrg) && } + {!isFetchingOrg && + issuccessOrg && + organization?.assignedPlans + ?.filter((p) => p.capabilityStatus == 'Enabled') + .reduce((plan, curr) => { + if (!plan.includes(curr.service)) { + plan.push(curr.service) + } + return plan + }, []) + .map((plan) => ( + <> + {plan == 'exchange' &&
  • Exchange
  • } + {plan == 'AADPremiumService' &&
  • AAD Premium
  • } + {plan == 'WindowsDefenderATP' &&
  • Windows Defender
  • } + + ))} +
    + +

    Sharepoint Quota

    + {(isLoadingSPQuota || isFetchingSPQuota) && } + {sharepoint && !isFetchingSPQuota && sharepoint?.Dashboard} +
    + +

    Applied Standards

    + {(isLoadingStandards || isFetchingStandards) && } + {issuccessStandards && + !isFetchingStandards && + standards + .filter( + (p) => + p.displayName == 'AllTenants' || + p.displayName == currentTenant.defaultDomainName, ) - }) - })} -
    - -

    Partner Relationships

    - {(isLoadingPartners || isFetchingPartners) && } - {issuccessPartners && - !isFetchingPartners && - partners.map((partner) => { - if (partner.TenantInfo) { - return ( -
  • - {partner.TenantInfo.displayName} ({partner.TenantInfo.defaultDomainName}) -
  • - ) - } - })} -
    -
    -
    -
    -
    - - - - - - - - + .flatMap((tenant) => { + return Object.keys(tenant.standards).map((standard) => { + const standardDisplayname = allStandardsList.filter((p) => + p.name.includes(standard), + ) + return ( +
  • + {standardDisplayname[0]?.label} ({tenant.displayName}) +
  • + ) + }) + })} +
    + +

    Partner Relationships

    + {(isLoadingPartners || isFetchingPartners) && } + {issuccessPartners && + !isFetchingPartners && + partners.map((partner) => { + if (partner.TenantInfo) { + return ( +
  • + {partner.TenantInfo.displayName} ( + {partner.TenantInfo.defaultDomainName}) +
  • + ) + } + })} +
    +
    +
    +
    +
    + + + + + + + + + + ) : ( + + + + Select a Tenant to show the dashboard + + + + )} ) } From d273f25da2ed84c585939fe86d716d99104f3ce2 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Sun, 3 Sep 2023 18:49:15 -0400 Subject: [PATCH 06/38] FontAwesome Global Library - Import FontAwesome fas library in App.js - Add icon property to portals.json - Update dashboard portal links to use portals.json instead of static list - Update Tenant offcanvas to use icon property - Update tenant list to use icon property --- src/App.js | 4 ++ .../utilities/CippTenantOffcanvas.js | 3 +- src/data/portals.json | 24 ++++++--- src/views/home/Home.js | 50 +++---------------- src/views/tenant/administration/Tenants.js | 2 +- 5 files changed, 31 insertions(+), 52 deletions(-) diff --git a/src/App.js b/src/App.js index 3ed5f1f12ae4..f3fa887346d6 100644 --- a/src/App.js +++ b/src/App.js @@ -9,6 +9,10 @@ import Skeleton from 'react-loading-skeleton' import TimeAgo from 'javascript-time-ago' import en from 'javascript-time-ago/locale/en.json' TimeAgo.addDefaultLocale(en) +import { library } from '@fortawesome/fontawesome-svg-core' +import { fas } from '@fortawesome/free-solid-svg-icons' + +library.add(fas) // Containers const DefaultLayout = React.lazy(() => import('./layout/DefaultLayout')) diff --git a/src/components/utilities/CippTenantOffcanvas.js b/src/components/utilities/CippTenantOffcanvas.js index b15a595b3a92..d8c003fe99ba 100644 --- a/src/components/utilities/CippTenantOffcanvas.js +++ b/src/components/utilities/CippTenantOffcanvas.js @@ -31,7 +31,7 @@ function CippTenantOffcanvas({ tenant, buildingIcon = false }) { ) } const actions = Portals.map((portal) => ({ - icon: , + icon: , label: portal.label, external: true, color: 'info', @@ -84,6 +84,7 @@ function CippTenantOffcanvas({ tenant, buildingIcon = false }) { ]} actions={[ { + id: 'edittenant', icon: , label: 'Edit Tenant', link: `/tenant/administration/tenants/Edit?tenantFilter=${tenant.defaultDomainName}&customerId=${tenant.customerId}`, diff --git a/src/data/portals.json b/src/data/portals.json index 38851cfcff98..3c09331a2440 100644 --- a/src/data/portals.json +++ b/src/data/portals.json @@ -5,7 +5,8 @@ "url": "https://admin.microsoft.com/Partner/BeginClientSession.aspx?CTID=customerId&CSDEST=o365admincenter", "variable": "customerId", "target": "_blank", - "external": true + "external": true, + "icon": "cog" }, { "label": "Exchange Portal", @@ -13,7 +14,8 @@ "url": "https://admin.exchange.microsoft.com/?landingpage=homepage&form=mac_sidebar&delegatedOrg=defaultDomainName#", "variable": "defaultDomainName", "target": "_blank", - "external": true + "external": true, + "icon": "mail-bulk" }, { "label": "Entra Portal", @@ -21,7 +23,8 @@ "url": "https://entra.microsoft.com/defaultDomainName", "variable": "defaultDomainName", "target": "_blank", - "external": true + "external": true, + "icon": "users" }, { "label": "Teams Portal", @@ -29,7 +32,8 @@ "url": "https://admin.teams.microsoft.com/?delegatedOrg=defaultDomainName", "variable": "defaultDomainName", "target": "_blank", - "external": true + "external": true, + "icon": "comments" }, { "label": "Azure Portal", @@ -37,7 +41,8 @@ "url": "https://portal.azure.com/defaultDomainName", "variable": "defaultDomainName", "target": "_blank", - "external": true + "external": true, + "icon": "server" }, { "label": "Intune Portal", @@ -45,7 +50,8 @@ "url": "https://intune.microsoft.com/defaultDomainName", "variable": "defaultDomainName", "target": "_blank", - "external": true + "external": true, + "icon": "laptop-code" }, { "label": "Security Portal", @@ -53,7 +59,8 @@ "url": "https://security.microsoft.com/?tid=customerId", "variable": "customerId", "target": "_blank", - "external": true + "external": true, + "icon": "shield-alt" }, { "label": "Sharepoint Admin", @@ -61,6 +68,7 @@ "url": "https://admin.microsoft.com/Partner/beginclientsession.aspx?CTID=customerId&CSDEST=SharePoint", "variable": "customerId", "target": "_blank", - "external": true + "external": true, + "icon": "book" } ] diff --git a/src/views/home/Home.js b/src/views/home/Home.js index 1f4602f210f6..e3025e587fda 100644 --- a/src/views/home/Home.js +++ b/src/views/home/Home.js @@ -26,6 +26,8 @@ import { useSelector } from 'react-redux' import allStandardsList from 'src/data/standards' import ReactTimeAgo from 'react-time-ago' import { CellDelegatedPrivilege } from 'src/components/tables/CellDelegatedPrivilege' +import Portals from 'src/data/portals' +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' const Home = () => { const currentTenant = useSelector((state) => state.app.currentTenant) @@ -83,48 +85,12 @@ const Home = () => { }, }) - const actions1 = [ - { - label: 'M365 Admin', - link: `https://portal.office.com/Partner/BeginClientSession.aspx?CTID=${currentTenant.customerId}&CSDEST=o365admincenter`, - target: '_blank', - icon: faCog, - }, - { - label: 'Exchange', - link: `https://admin.exchange.microsoft.com/?landingpage=homepage&form=mac_sidebar&delegatedOrg=${currentTenant.defaultDomainName}#`, - target: '_blank', - icon: faMailBulk, - }, - { - label: 'Intune', - link: `https://intune.microsoft.com/${currentTenant.defaultDomainName}`, - target: '_blank', - icon: faLaptopCode, - }, - { - label: 'Entra', - link: `https://entra.microsoft.com/${currentTenant.defaultDomainName}`, - target: '_blank', - icon: faUsers, - }, - { - label: 'Security', - link: `https://security.microsoft.com/?tid=${currentTenant.customerId}`, - target: '_blank', - icon: faShieldAlt, - }, - { - label: 'Azure', - link: `https://portal.azure.com/#@${currentTenant.customerId}`, - icon: faServer, - }, - { - label: 'Sharepoint', - link: `https://admin.microsoft.com/Partner/beginclientsession.aspx?CTID=${currentTenant.customerId}&CSDEST=SharePoint`, - icon: faBook, - }, - ] + const actions1 = Portals.map((portal) => ({ + icon: portal.icon, + label: portal.label, + target: '_blank', + link: portal.url.replace(portal.variable, currentTenant[portal.variable]), + })) const actions2 = [ { diff --git a/src/views/tenant/administration/Tenants.js b/src/views/tenant/administration/Tenants.js index 2b99aaad1033..24b700a30f08 100644 --- a/src/views/tenant/administration/Tenants.js +++ b/src/views/tenant/administration/Tenants.js @@ -25,7 +25,7 @@ const TenantsList = () => { className="dlink" rel="noreferrer" > - + ), }) From 7e3140a4a92d62b4f3fde4b75ae6f940f96a1e1b Mon Sep 17 00:00:00 2001 From: John Duprey Date: Sun, 3 Sep 2023 18:50:06 -0400 Subject: [PATCH 07/38] Set footer position to sticky --- src/components/layout/AppFooter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/layout/AppFooter.js b/src/components/layout/AppFooter.js index ecfba658b219..967f7bb3d1ff 100644 --- a/src/components/layout/AppFooter.js +++ b/src/components/layout/AppFooter.js @@ -8,7 +8,7 @@ import netfriends from 'src/assets/images/netfriends.png' //todo: Add darkmode detection and change logos accordingly. const AppFooter = () => { return ( - +

    This application is sponsored by{' '} From 90dc81e533ef7939c23edd99a4ffcf29eda18ff1 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Sun, 3 Sep 2023 18:51:39 -0400 Subject: [PATCH 08/38] CippActionsOffcanvas - Refresh button - Add refreshFunction prop to CippActionsOffcanvas and CippOffcanvas - Add refresh function to Recent Jobs in AppHeaderDropdown --- src/components/header/AppHeaderDropdown.js | 15 +++++++++---- .../utilities/CippActionsOffcanvas.js | 3 ++- src/components/utilities/CippOffcanvas.js | 21 ++++++++++++++++--- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/src/components/header/AppHeaderDropdown.js b/src/components/header/AppHeaderDropdown.js index 568e03211542..93b9c499d493 100644 --- a/src/components/header/AppHeaderDropdown.js +++ b/src/components/header/AppHeaderDropdown.js @@ -18,24 +18,30 @@ const AppHeaderDropdown = () => { const [profileVisible, setProfileVisible] = useState(false) const [cippQueueExtendedInfo, setCippQueueExtendedInfo] = useState([]) const [cippQueueVisible, setCippQueueVisible] = useState(false) - const [cippQueueRefresh, setCippQueueRefresh] = useState('') + const [cippQueueRefresh, setCippQueueRefresh] = useState( + (Math.random() + 1).toString(36).substring(7), + ) const { data: profile } = authApi.endpoints.loadClientPrincipal.useQueryState() const [getCippQueueList, cippQueueList] = useLazyGenericGetRequestQuery() function loadCippQueue() { setCippQueueVisible(true) + getCippQueueList({ path: 'api/ListCippQueue', params: { refresh: cippQueueRefresh } }) + } + + function refreshCippQueue() { setCippQueueRefresh((Math.random() + 1).toString(36).substring(7)) - getCippQueueList({ path: `api/ListCippQueue?refresh=${cippQueueRefresh}` }) + loadCippQueue() } useEffect(() => { - if (cippQueueList.isFetching) { + if (cippQueueList.isFetching || cippQueueList.isLoading) { setCippQueueExtendedInfo([ { label: 'Fetching recent jobs', value: 'Please wait', - timpestamp: Date(), + timestamp: Date(), link: '#', }, ]) @@ -101,6 +107,7 @@ const AppHeaderDropdown = () => { title="Recent Jobs" extendedInfo={[]} cards={cippQueueExtendedInfo} + refreshFunction={refreshCippQueue} actions={[ { label: 'Clear History', diff --git a/src/components/utilities/CippActionsOffcanvas.js b/src/components/utilities/CippActionsOffcanvas.js index bdf28fae5cff..1bcf1773251f 100644 --- a/src/components/utilities/CippActionsOffcanvas.js +++ b/src/components/utilities/CippActionsOffcanvas.js @@ -101,7 +101,7 @@ export default function CippActionsOffcanvas(props) { try { cardContent = props.cards.map((action, index) => ( <> - + Report Name: {action.label} @@ -178,6 +178,7 @@ export default function CippActionsOffcanvas(props) { visible={props.visible} id={props.id} hideFunction={props.hideFunction} + refreshFunction={props.refreshFunction} > {getResults.isFetching && ( diff --git a/src/components/utilities/CippOffcanvas.js b/src/components/utilities/CippOffcanvas.js index 624f26c135ba..7a6590eb57d1 100644 --- a/src/components/utilities/CippOffcanvas.js +++ b/src/components/utilities/CippOffcanvas.js @@ -17,9 +17,23 @@ export default function CippOffcanvas(props) { >

    {props.title}

    - - - + + {props.refreshFunction && ( + { + console.log('refresh') + props.refreshFunction() + }} + > + + + )} + + + + {props.children} @@ -33,6 +47,7 @@ export const CippOffcanvasPropTypes = { visible: PropTypes.bool, id: PropTypes.string.isRequired, hideFunction: PropTypes.func.isRequired, + refreshFunction: PropTypes.func, } CippOffcanvas.propTypes = CippOffcanvasPropTypes From 16d7a1925f1f513477dd95ffae16922ed8cd78bb Mon Sep 17 00:00:00 2001 From: John Duprey Date: Sun, 3 Sep 2023 19:47:25 -0400 Subject: [PATCH 09/38] Add tooltips --- .../utilities/CippTenantOffcanvas.js | 20 +++++---- src/views/cipp/CIPPSettings.js | 45 +++++++++++-------- 2 files changed, 37 insertions(+), 28 deletions(-) diff --git a/src/components/utilities/CippTenantOffcanvas.js b/src/components/utilities/CippTenantOffcanvas.js index d8c003fe99ba..79f249452f6e 100644 --- a/src/components/utilities/CippTenantOffcanvas.js +++ b/src/components/utilities/CippTenantOffcanvas.js @@ -1,7 +1,7 @@ import React, { useState } from 'react' -import { CButton } from '@coreui/react' +import { CButton, CTooltip } from '@coreui/react' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faCog, faEdit, faEllipsisV, faBuilding } from '@fortawesome/free-solid-svg-icons' +import { faEdit, faEllipsisV, faBuilding } from '@fortawesome/free-solid-svg-icons' import { CippActionsOffcanvas } from 'src/components/utilities' import { useLazyGenericGetRequestQuery } from 'src/store/api/app' import Skeleton from 'react-loading-skeleton' @@ -39,13 +39,15 @@ function CippTenantOffcanvas({ tenant, buildingIcon = false }) { })) return ( <> - loadOffCanvasDetails(tenant.defaultDomainName)} - > - - + + loadOffCanvasDetails(tenant.defaultDomainName)} + > + + + { return ( <> {row.Excluded && ( - handleRemoveExclusion(row.defaultDomainName)} - > - - + + handleRemoveExclusion(row.defaultDomainName)} + > + + + )} {!row.Excluded && ( - handleConfirmExcludeTenant({ value: row.customerId })} - > - - + + handleConfirmExcludeTenant({ value: row.customerId })} + > + + + )} - handleCPVPermissions(row)}> - - + + handleCPVPermissions(row)}> + + + ) } From 598fbba0d6b22d6a321692d2b2d6a46be51e2119 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Sun, 3 Sep 2023 19:48:28 -0400 Subject: [PATCH 10/38] Update TenantSelector.js --- src/components/utilities/TenantSelector.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/utilities/TenantSelector.js b/src/components/utilities/TenantSelector.js index dfa54ac55ab6..686fdd0727e4 100644 --- a/src/components/utilities/TenantSelector.js +++ b/src/components/utilities/TenantSelector.js @@ -4,7 +4,7 @@ import { useDispatch, useSelector } from 'react-redux' import PropTypes from 'prop-types' import { useListTenantsQuery } from 'src/store/api/tenants' import { setCurrentTenant } from 'src/store/features/app' -import { CButton, CDropdown, CDropdownMenu, CDropdownToggle } from '@coreui/react' +import { CDropdown, CDropdownMenu, CDropdownToggle } from '@coreui/react' import { useNavigate, useSearchParams } from 'react-router-dom' import { queryString } from 'src/helpers' import { faBuilding } from '@fortawesome/free-solid-svg-icons' From ce3c999783f2b281c00c30eb316f3206fbf22a24 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Mon, 4 Sep 2023 23:15:48 -0400 Subject: [PATCH 11/38] BPA Field Builder - Added to Tools menu - Install @monaco-editor/react - Install @rjsf/core, @rjsf/utils, @rjsf/validator-ajv8 --- package-lock.json | 417 +++++++++++++++++- package.json | 4 + src/_nav.js | 5 + src/data/BPAField.schema.v1.json | 229 ++++++++++ src/data/BPAField.uischema.v1.json | 26 ++ src/routes.js | 6 + src/scss/_custom.scss | 24 + src/views/tenant/standards/BPAFieldBuilder.js | 56 +++ 8 files changed, 747 insertions(+), 20 deletions(-) create mode 100644 src/data/BPAField.schema.v1.json create mode 100644 src/data/BPAField.uischema.v1.json create mode 100644 src/views/tenant/standards/BPAFieldBuilder.js diff --git a/package-lock.json b/package-lock.json index f3e873c9bc78..a7f3bc927e18 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,8 +19,12 @@ "@fortawesome/free-regular-svg-icons": "^5.15.4", "@fortawesome/free-solid-svg-icons": "^5.15.4", "@fortawesome/react-fontawesome": "^0.1.16", + "@monaco-editor/react": "^4.5.2", "@popperjs/core": "^2.10.2", "@reduxjs/toolkit": "^1.7.0", + "@rjsf/core": "^5.12.1", + "@rjsf/utils": "^5.12.1", + "@rjsf/validator-ajv8": "^5.12.1", "@wojtekmaj/enzyme-adapter-react-17": "^0.6.3", "axios": "^0.24.0", "buffer": "^6.0.3", @@ -3057,6 +3061,30 @@ "dev": true, "license": "MIT" }, + "node_modules/@monaco-editor/loader": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.3.3.tgz", + "integrity": "sha512-6KKF4CTzcJiS8BJwtxtfyYt9shBiEv32ateQ9T4UVogwn4HM/uPo9iJd2Dmbkpz8CM6Y0PDUpjnZzCwC+eYo2Q==", + "dependencies": { + "state-local": "^1.0.6" + }, + "peerDependencies": { + "monaco-editor": ">= 0.21.0 < 1" + } + }, + "node_modules/@monaco-editor/react": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.5.2.tgz", + "integrity": "sha512-emcWu6vg1OpXPiYll4aPOaXe8bwYB4UaaNTwtArFLgMoNGBzRZb2Xn0Bra2HMIFM7QLgs7fCGunHO5LkfT2LBA==", + "dependencies": { + "@monaco-editor/loader": "^1.3.3" + }, + "peerDependencies": { + "monaco-editor": ">= 0.25.0 < 1", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "dev": true, @@ -3183,6 +3211,85 @@ "@babel/runtime": "^7.9.2" } }, + "node_modules/@rjsf/core": { + "version": "5.12.1", + "resolved": "https://registry.npmjs.org/@rjsf/core/-/core-5.12.1.tgz", + "integrity": "sha512-1YFhZ90/uHRx1akQmDdIjBxGMjs/5gtuTLUFwl6GbOwTm2fhZRh3qXRFyTXz81Oy6TGcbrxBJEYvFg2iHjYKCA==", + "dependencies": { + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "markdown-to-jsx": "^7.3.2", + "nanoid": "^3.3.6", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@rjsf/utils": "^5.8.x", + "react": "^16.14.0 || >=17" + } + }, + "node_modules/@rjsf/utils": { + "version": "5.12.1", + "resolved": "https://registry.npmjs.org/@rjsf/utils/-/utils-5.12.1.tgz", + "integrity": "sha512-/k8+7WdLwhaYsOQvH5BQINipj2IJvjEW3QQv4jQQ7sXtkpdUjieZayRfaE8DHfRdm9HjgJURJFDy3EODkWPl6A==", + "dependencies": { + "json-schema-merge-allof": "^0.8.1", + "jsonpointer": "^5.0.1", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "react-is": "^18.2.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": "^16.14.0 || >=17" + } + }, + "node_modules/@rjsf/utils/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, + "node_modules/@rjsf/validator-ajv8": { + "version": "5.12.1", + "resolved": "https://registry.npmjs.org/@rjsf/validator-ajv8/-/validator-ajv8-5.12.1.tgz", + "integrity": "sha512-m4QO44yp60LTIfd4RPUu/h07B8U9umbD3I4Nh4iv9oyUudncaZFFXRopKcBm08v30VkN0tjMwuu0SxGDpzMtHA==", + "dependencies": { + "ajv": "^8.12.0", + "ajv-formats": "^2.1.1", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@rjsf/utils": "^5.8.x" + } + }, + "node_modules/@rjsf/validator-ajv8/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@rjsf/validator-ajv8/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, "node_modules/@rollup/plugin-babel": { "version": "5.3.1", "dev": true, @@ -4723,7 +4830,6 @@ }, "node_modules/ajv-formats": { "version": "2.1.1", - "dev": true, "license": "MIT", "dependencies": { "ajv": "^8.0.0" @@ -4739,7 +4845,6 @@ }, "node_modules/ajv-formats/node_modules/ajv": { "version": "8.10.0", - "dev": true, "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", @@ -4754,7 +4859,6 @@ }, "node_modules/ajv-formats/node_modules/json-schema-traverse": { "version": "1.0.0", - "dev": true, "license": "MIT" }, "node_modules/ajv-keywords": { @@ -6074,6 +6178,27 @@ "dev": true, "license": "MIT" }, + "node_modules/compute-gcd": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/compute-gcd/-/compute-gcd-1.2.1.tgz", + "integrity": "sha512-TwMbxBNz0l71+8Sc4czv13h4kEqnchV9igQZBi6QUaz09dnz13juGnnaWWJTRsP3brxOoxeB4SA2WELLw1hCtg==", + "dependencies": { + "validate.io-array": "^1.0.3", + "validate.io-function": "^1.0.2", + "validate.io-integer-array": "^1.0.0" + } + }, + "node_modules/compute-lcm": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/compute-lcm/-/compute-lcm-1.1.2.tgz", + "integrity": "sha512-OFNPdQAXnQhDSKioX8/XYT6sdUlXwpeMjfd6ApxMJfyZ4GxmLR1xvMERctlYhlHwIiz6CSpBc2+qYKjHGZw4TQ==", + "dependencies": { + "compute-gcd": "^1.2.1", + "validate.io-array": "^1.0.3", + "validate.io-function": "^1.0.2", + "validate.io-integer-array": "^1.0.0" + } + }, "node_modules/concat-map": { "version": "0.0.1", "dev": true, @@ -11886,6 +12011,27 @@ "dev": true, "license": "(AFL-2.1 OR BSD-3-Clause)" }, + "node_modules/json-schema-compare": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/json-schema-compare/-/json-schema-compare-0.2.2.tgz", + "integrity": "sha512-c4WYmDKyJXhs7WWvAWm3uIYnfyWFoIp+JEoX34rctVvEkMYCPGhXtvmFFXiffBbxfZsvQ0RNnV5H7GvDF5HCqQ==", + "dependencies": { + "lodash": "^4.17.4" + } + }, + "node_modules/json-schema-merge-allof": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/json-schema-merge-allof/-/json-schema-merge-allof-0.8.1.tgz", + "integrity": "sha512-CTUKmIlPJbsWfzRRnOXz+0MjIqvnleIXwFTzz+t9T86HnYX/Rozria6ZVGLktAU9e+NygNljveP+yxqtQp/Q4w==", + "dependencies": { + "compute-lcm": "^1.1.2", + "json-schema-compare": "^0.2.2", + "lodash": "^4.17.20" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "license": "MIT" @@ -11923,9 +12069,9 @@ } }, "node_modules/jsonpointer": { - "version": "5.0.0", - "dev": true, - "license": "MIT", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", "engines": { "node": ">=0.10.0" } @@ -12078,6 +12224,11 @@ "version": "4.17.21", "license": "MIT" }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" + }, "node_modules/lodash.debounce": { "version": "4.0.8", "license": "MIT" @@ -12204,6 +12355,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/markdown-to-jsx": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-7.3.2.tgz", + "integrity": "sha512-B+28F5ucp83aQm+OxNrPkS8z0tMKaeHiy0lHJs3LqCyDQFtWuenaIrkaVTgAm1pf1AU85LXltva86hlaT17i8Q==", + "engines": { + "node": ">= 10" + }, + "peerDependencies": { + "react": ">= 0.14.0" + } + }, "node_modules/masonry-layout": { "version": "4.2.2", "license": "MIT", @@ -12485,6 +12647,12 @@ "node": "*" } }, + "node_modules/monaco-editor": { + "version": "0.41.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.41.0.tgz", + "integrity": "sha512-1o4olnZJsiLmv5pwLEAmzHTE/5geLKQ07BrGxlF4Ri/AXAc2yyDGZwHjiTqD8D/ROKUZmwMA28A+yEowLNOEcA==", + "peer": true + }, "node_modules/moo": { "version": "0.5.1", "license": "BSD-3-Clause" @@ -12506,9 +12674,15 @@ } }, "node_modules/nanoid": { - "version": "3.3.4", - "dev": true, - "license": "MIT", + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -15582,7 +15756,6 @@ }, "node_modules/require-from-string": { "version": "2.0.2", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -16378,6 +16551,11 @@ "dev": true, "license": "MIT" }, + "node_modules/state-local": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz", + "integrity": "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==" + }, "node_modules/statuses": { "version": "1.5.0", "dev": true, @@ -17586,6 +17764,38 @@ "spdx-expression-parse": "^3.0.0" } }, + "node_modules/validate.io-array": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/validate.io-array/-/validate.io-array-1.0.6.tgz", + "integrity": "sha512-DeOy7CnPEziggrOO5CZhVKJw6S3Yi7e9e65R1Nl/RTN1vTQKnzjfvks0/8kQ40FP/dsjRAOd4hxmJ7uLa6vxkg==" + }, + "node_modules/validate.io-function": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/validate.io-function/-/validate.io-function-1.0.2.tgz", + "integrity": "sha512-LlFybRJEriSuBnUhQyG5bwglhh50EpTL2ul23MPIuR1odjO7XaMLFV8vHGwp7AZciFxtYOeiSCT5st+XSPONiQ==" + }, + "node_modules/validate.io-integer": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/validate.io-integer/-/validate.io-integer-1.0.5.tgz", + "integrity": "sha512-22izsYSLojN/P6bppBqhgUDjCkr5RY2jd+N2a3DCAUey8ydvrZ/OkGvFPR7qfOpwR2LC5p4Ngzxz36g5Vgr/hQ==", + "dependencies": { + "validate.io-number": "^1.0.3" + } + }, + "node_modules/validate.io-integer-array": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/validate.io-integer-array/-/validate.io-integer-array-1.0.0.tgz", + "integrity": "sha512-mTrMk/1ytQHtCY0oNO3dztafHYyGU88KL+jRxWuzfOmQb+4qqnWmI+gykvGp8usKZOM0H7keJHEbRaFiYA0VrA==", + "dependencies": { + "validate.io-array": "^1.0.3", + "validate.io-integer": "^1.0.4" + } + }, + "node_modules/validate.io-number": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/validate.io-number/-/validate.io-number-1.0.3.tgz", + "integrity": "sha512-kRAyotcbNaSYoDnXvb4MHg/0a1egJdLwS6oJ38TJY7aw9n93Fl/3blIXdyYvPOp55CNxywooG/3BcrwNrBpcSg==" + }, "node_modules/vary": { "version": "1.1.2", "dev": true, @@ -20330,6 +20540,22 @@ "version": "2.0.3", "dev": true }, + "@monaco-editor/loader": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.3.3.tgz", + "integrity": "sha512-6KKF4CTzcJiS8BJwtxtfyYt9shBiEv32ateQ9T4UVogwn4HM/uPo9iJd2Dmbkpz8CM6Y0PDUpjnZzCwC+eYo2Q==", + "requires": { + "state-local": "^1.0.6" + } + }, + "@monaco-editor/react": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.5.2.tgz", + "integrity": "sha512-emcWu6vg1OpXPiYll4aPOaXe8bwYB4UaaNTwtArFLgMoNGBzRZb2Xn0Bra2HMIFM7QLgs7fCGunHO5LkfT2LBA==", + "requires": { + "@monaco-editor/loader": "^1.3.3" + } + }, "@nodelib/fs.scandir": { "version": "2.1.5", "dev": true, @@ -20391,6 +20617,66 @@ } } }, + "@rjsf/core": { + "version": "5.12.1", + "resolved": "https://registry.npmjs.org/@rjsf/core/-/core-5.12.1.tgz", + "integrity": "sha512-1YFhZ90/uHRx1akQmDdIjBxGMjs/5gtuTLUFwl6GbOwTm2fhZRh3qXRFyTXz81Oy6TGcbrxBJEYvFg2iHjYKCA==", + "requires": { + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "markdown-to-jsx": "^7.3.2", + "nanoid": "^3.3.6", + "prop-types": "^15.8.1" + } + }, + "@rjsf/utils": { + "version": "5.12.1", + "resolved": "https://registry.npmjs.org/@rjsf/utils/-/utils-5.12.1.tgz", + "integrity": "sha512-/k8+7WdLwhaYsOQvH5BQINipj2IJvjEW3QQv4jQQ7sXtkpdUjieZayRfaE8DHfRdm9HjgJURJFDy3EODkWPl6A==", + "requires": { + "json-schema-merge-allof": "^0.8.1", + "jsonpointer": "^5.0.1", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "react-is": "^18.2.0" + }, + "dependencies": { + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + } + } + }, + "@rjsf/validator-ajv8": { + "version": "5.12.1", + "resolved": "https://registry.npmjs.org/@rjsf/validator-ajv8/-/validator-ajv8-5.12.1.tgz", + "integrity": "sha512-m4QO44yp60LTIfd4RPUu/h07B8U9umbD3I4Nh4iv9oyUudncaZFFXRopKcBm08v30VkN0tjMwuu0SxGDpzMtHA==", + "requires": { + "ajv": "^8.12.0", + "ajv-formats": "^2.1.1", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21" + }, + "dependencies": { + "ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + } + } + }, "@rollup/plugin-babel": { "version": "5.3.1", "dev": true, @@ -21370,14 +21656,12 @@ }, "ajv-formats": { "version": "2.1.1", - "dev": true, "requires": { "ajv": "^8.0.0" }, "dependencies": { "ajv": { "version": "8.10.0", - "dev": true, "requires": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -21386,8 +21670,7 @@ } }, "json-schema-traverse": { - "version": "1.0.0", - "dev": true + "version": "1.0.0" } } }, @@ -22218,6 +22501,27 @@ } } }, + "compute-gcd": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/compute-gcd/-/compute-gcd-1.2.1.tgz", + "integrity": "sha512-TwMbxBNz0l71+8Sc4czv13h4kEqnchV9igQZBi6QUaz09dnz13juGnnaWWJTRsP3brxOoxeB4SA2WELLw1hCtg==", + "requires": { + "validate.io-array": "^1.0.3", + "validate.io-function": "^1.0.2", + "validate.io-integer-array": "^1.0.0" + } + }, + "compute-lcm": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/compute-lcm/-/compute-lcm-1.1.2.tgz", + "integrity": "sha512-OFNPdQAXnQhDSKioX8/XYT6sdUlXwpeMjfd6ApxMJfyZ4GxmLR1xvMERctlYhlHwIiz6CSpBc2+qYKjHGZw4TQ==", + "requires": { + "compute-gcd": "^1.2.1", + "validate.io-array": "^1.0.3", + "validate.io-function": "^1.0.2", + "validate.io-integer-array": "^1.0.0" + } + }, "concat-map": { "version": "0.0.1", "dev": true @@ -25866,6 +26170,24 @@ "version": "0.4.0", "dev": true }, + "json-schema-compare": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/json-schema-compare/-/json-schema-compare-0.2.2.tgz", + "integrity": "sha512-c4WYmDKyJXhs7WWvAWm3uIYnfyWFoIp+JEoX34rctVvEkMYCPGhXtvmFFXiffBbxfZsvQ0RNnV5H7GvDF5HCqQ==", + "requires": { + "lodash": "^4.17.4" + } + }, + "json-schema-merge-allof": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/json-schema-merge-allof/-/json-schema-merge-allof-0.8.1.tgz", + "integrity": "sha512-CTUKmIlPJbsWfzRRnOXz+0MjIqvnleIXwFTzz+t9T86HnYX/Rozria6ZVGLktAU9e+NygNljveP+yxqtQp/Q4w==", + "requires": { + "compute-lcm": "^1.1.2", + "json-schema-compare": "^0.2.2", + "lodash": "^4.17.20" + } + }, "json-schema-traverse": { "version": "0.4.1" }, @@ -25891,8 +26213,9 @@ } }, "jsonpointer": { - "version": "5.0.0", - "dev": true + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==" }, "jspdf": { "version": "2.5.1", @@ -25989,6 +26312,11 @@ "lodash": { "version": "4.17.21" }, + "lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" + }, "lodash.debounce": { "version": "4.0.8" }, @@ -26075,6 +26403,12 @@ "version": "4.3.0", "dev": true }, + "markdown-to-jsx": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-7.3.2.tgz", + "integrity": "sha512-B+28F5ucp83aQm+OxNrPkS8z0tMKaeHiy0lHJs3LqCyDQFtWuenaIrkaVTgAm1pf1AU85LXltva86hlaT17i8Q==", + "requires": {} + }, "masonry-layout": { "version": "4.2.2", "requires": { @@ -26246,6 +26580,12 @@ "moment": { "version": "2.29.4" }, + "monaco-editor": { + "version": "0.41.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.41.0.tgz", + "integrity": "sha512-1o4olnZJsiLmv5pwLEAmzHTE/5geLKQ07BrGxlF4Ri/AXAc2yyDGZwHjiTqD8D/ROKUZmwMA28A+yEowLNOEcA==", + "peer": true + }, "moo": { "version": "0.5.1" }, @@ -26261,8 +26601,9 @@ } }, "nanoid": { - "version": "3.3.4", - "dev": true + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==" }, "natural-compare": { "version": "1.4.0", @@ -28093,8 +28434,7 @@ "dev": true }, "require-from-string": { - "version": "2.0.2", - "dev": true + "version": "2.0.2" }, "requires-port": { "version": "1.0.0", @@ -28608,6 +28948,11 @@ "version": "1.2.1", "dev": true }, + "state-local": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz", + "integrity": "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==" + }, "statuses": { "version": "1.5.0", "dev": true @@ -29393,6 +29738,38 @@ "spdx-expression-parse": "^3.0.0" } }, + "validate.io-array": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/validate.io-array/-/validate.io-array-1.0.6.tgz", + "integrity": "sha512-DeOy7CnPEziggrOO5CZhVKJw6S3Yi7e9e65R1Nl/RTN1vTQKnzjfvks0/8kQ40FP/dsjRAOd4hxmJ7uLa6vxkg==" + }, + "validate.io-function": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/validate.io-function/-/validate.io-function-1.0.2.tgz", + "integrity": "sha512-LlFybRJEriSuBnUhQyG5bwglhh50EpTL2ul23MPIuR1odjO7XaMLFV8vHGwp7AZciFxtYOeiSCT5st+XSPONiQ==" + }, + "validate.io-integer": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/validate.io-integer/-/validate.io-integer-1.0.5.tgz", + "integrity": "sha512-22izsYSLojN/P6bppBqhgUDjCkr5RY2jd+N2a3DCAUey8ydvrZ/OkGvFPR7qfOpwR2LC5p4Ngzxz36g5Vgr/hQ==", + "requires": { + "validate.io-number": "^1.0.3" + } + }, + "validate.io-integer-array": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/validate.io-integer-array/-/validate.io-integer-array-1.0.0.tgz", + "integrity": "sha512-mTrMk/1ytQHtCY0oNO3dztafHYyGU88KL+jRxWuzfOmQb+4qqnWmI+gykvGp8usKZOM0H7keJHEbRaFiYA0VrA==", + "requires": { + "validate.io-array": "^1.0.3", + "validate.io-integer": "^1.0.4" + } + }, + "validate.io-number": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/validate.io-number/-/validate.io-number-1.0.3.tgz", + "integrity": "sha512-kRAyotcbNaSYoDnXvb4MHg/0a1egJdLwS6oJ38TJY7aw9n93Fl/3blIXdyYvPOp55CNxywooG/3BcrwNrBpcSg==" + }, "vary": { "version": "1.1.2", "dev": true diff --git a/package.json b/package.json index 6040e8710664..ccb4c6383316 100644 --- a/package.json +++ b/package.json @@ -38,8 +38,12 @@ "@fortawesome/free-regular-svg-icons": "^5.15.4", "@fortawesome/free-solid-svg-icons": "^5.15.4", "@fortawesome/react-fontawesome": "^0.1.16", + "@monaco-editor/react": "^4.5.2", "@popperjs/core": "^2.10.2", "@reduxjs/toolkit": "^1.7.0", + "@rjsf/core": "^5.12.1", + "@rjsf/utils": "^5.12.1", + "@rjsf/validator-ajv8": "^5.12.1", "@wojtekmaj/enzyme-adapter-react-17": "^0.6.3", "axios": "^0.24.0", "buffer": "^6.0.3", diff --git a/src/_nav.js b/src/_nav.js index 5f802d6144bc..415109e33280 100644 --- a/src/_nav.js +++ b/src/_nav.js @@ -171,6 +171,11 @@ const _nav = [ name: 'Individual Domain Check', to: '/tenant/standards/individual-domains', }, + { + component: CNavItem, + name: 'BPA Field Builder', + to: '/tenant/tools/bpa-field-builder', + }, ], }, { diff --git a/src/data/BPAField.schema.v1.json b/src/data/BPAField.schema.v1.json new file mode 100644 index 000000000000..56a6a07fd1de --- /dev/null +++ b/src/data/BPAField.schema.v1.json @@ -0,0 +1,229 @@ +{ + "title": "BPA Field Builder", + "type": "object", + "required": ["name", "API", "StoreAs"], + "properties": { + "name": { + "type": "string", + "title": "Field Name", + "description": "Identifier for each set or category of data." + }, + "UseExistingInfo": { + "type": "boolean", + "title": "Use Existing Info?", + "default": false + }, + "StoreAs": { + "type": "string", + "title": "Store As", + "description": "The format in which to store the fetched data.", + "anyOf": [ + { + "const": "JSON", + "title": "JSON - For structured data" + }, + { + "const": "bool", + "title": "Boolean - True/False values" + } + ] + }, + "ExtractFields": { + "title": "Extract Fields", + "description": "Lists the attributes or fields to extract from the returned data.", + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1 + }, + "where": { + "title": "Where", + "description": "A conditional filter to determine which data gets displayed or processed. Use PowerShell's Where-Object Filterscript format.", + "type": "string" + }, + "FrontendFields": { + "type": "array", + "title": "Frontend Fields", + "description": "Describes how each data attribute will be displayed in the report.", + "items": { + "type": "object", + "properties": { + "name": { + "title": "Name", + "description": "Label for the data in the report.", + "type": "string" + }, + "value": { + "title": "Value", + "description": "Reference to the data's location or attribute.", + "type": "string" + }, + "formatter": { + "title": "Formatter", + "description": "Specifies how the data will be formatted for display.", + "type": "string", + "anyOf": [ + { + "const": "string", + "title": "Display as plain text" + }, + { + "const": "bool", + "title": "Presents as True or False" + }, + { + "const": "warnBool", + "title": "Shows boolean values with potential visual warnings" + }, + { + "const": "reverseBool", + "title": "Inverts the boolean value for display" + }, + { + "const": "table", + "title": "Represents the data in a table format" + }, + { + "const": "number", + "title": "Displays as a numerical value" + } + ] + } + } + }, + "minItems": 1, + "required": ["name", "value", "formatter"] + }, + "desc": { + "title": "Field Description", + "description": "A description field shown on the end of the card on the tenant overview page", + "type": "string" + } + }, + "allOf": [ + { + "if": { + "properties": { + "UseExistingInfo": { + "enum": [false] + } + } + }, + "then": { + "properties": { + "API": { + "type": "string", + "title": "API", + "anyOf": [ + { + "const": "Graph", + "title": "Graph" + }, + { + "const": "Exchange", + "title": "Exchange" + }, + { + "const": "CIPPFunction", + "title": "CIPP Function" + } + ], + "default": "Graph", + "description": "Defines the source or type of API to fetch the data." + } + }, + "allOf": [ + { + "if": { + "properties": { + "API": { + "enum": ["CIPPFunction"] + } + } + }, + "then": { + "properties": { + "URL": { + "type": "string", + "description": "The endpoint for CIPP Function" + } + }, + "required": ["URL"] + } + }, + { + "if": { + "properties": { + "API": { + "enum": ["Exchange"] + } + } + }, + "then": { + "properties": { + "command": { + "type": "string", + "title": "Command", + "pattern": "^Get-", + "description": "Command for Exchange (Get only)" + } + }, + "required": ["command"] + } + }, + { + "if": { + "properties": { + "API": { + "enum": ["Graph"] + } + } + }, + "then": { + "properties": { + "parameters": { + "type": "object", + "title": "Parameters", + "description": "Additional settings or parameters required for the API call.", + "properties": { + "asApp": { + "title": "Use Application Permissions", + "type": "boolean" + } + }, + "additionalProperties": true + }, + "URL": { + "type": "string", + "pattern": "^https://graph.microsoft.com/", + "description": "The endpoint for Graph" + } + }, + "required": ["URL"] + } + }, + { + "if": { + "properties": { + "API": { + "enum": ["Exchange", "CIPPFunction"] + } + } + }, + "then": { + "properties": { + "parameters": { + "type": "object", + "title": "Parameters", + "description": "Additional settings or parameters required for the API call.", + "additionalProperties": true + } + } + } + } + ] + } + } + ] +} diff --git a/src/data/BPAField.uischema.v1.json b/src/data/BPAField.uischema.v1.json new file mode 100644 index 000000000000..4eeb72527109 --- /dev/null +++ b/src/data/BPAField.uischema.v1.json @@ -0,0 +1,26 @@ +{ + "ui:disabled": false, + "ui:readonly": false, + "ui:order": [ + "name", + "desc", + "UseExistingInfo", + "API", + "StoreAs", + "URL", + "command", + "parameters", + "where", + "ExtractFields", + "FrontendFields", + "*" + ], + "ui:submitButtonOptions": { + "submitText": "Validate", + "norender": false, + "props": { + "disabled": false, + "className": "btn btn-info" + } + } +} diff --git a/src/routes.js b/src/routes.js index 94181b42074f..2851d6e96eb7 100644 --- a/src/routes.js +++ b/src/routes.js @@ -71,6 +71,7 @@ const DeviceComplianceReport = React.lazy(() => const BestPracticeAnalyzer = React.lazy(() => import('src/views/tenant/standards/BestPracticeAnalyser'), ) +const BPAFieldBuilder = React.lazy(() => import('src/views/tenant/standards/BPAFieldBuilder')) const DomainsAnalyser = React.lazy(() => import('src/views/tenant/standards/DomainsAnalyser')) const OffboardingWizard = React.lazy(() => import('src/views/identity/administration/OffboardingWizard'), @@ -385,6 +386,11 @@ const routes = [ name: 'Geo IP Lookup', component: GeoIPLookup, }, + { + path: '/tenant/tools/bpa-field-builder', + name: 'BPA Field Builder', + component: BPAFieldBuilder, + }, { path: '/tenant/standards/alert-list', name: 'Alert List (Alpha)', component: ListAlerts }, { path: '/endpoint', name: 'Endpoint' }, { path: '/endpoint/applications', name: 'Applications' }, diff --git a/src/scss/_custom.scss b/src/scss/_custom.scss index 95f65a7aa949..5edc21372ec9 100644 --- a/src/scss/_custom.scss +++ b/src/scss/_custom.scss @@ -584,4 +584,28 @@ .teams-wide-card { width: 500px; +} + +i.glyphicon { + display: none; +} + +.btn-add::after { + content: 'Add'; +} + +.array-item-copy::after { + content: 'Copy'; +} + +.array-item-move-up::after { + content: 'Move Up'; +} + +.array-item-move-down::after { + content: 'Move Down'; +} + +.array-item-remove::after { + content: 'Remove'; } \ No newline at end of file diff --git a/src/views/tenant/standards/BPAFieldBuilder.js b/src/views/tenant/standards/BPAFieldBuilder.js new file mode 100644 index 000000000000..738c37946809 --- /dev/null +++ b/src/views/tenant/standards/BPAFieldBuilder.js @@ -0,0 +1,56 @@ +import React, { useState, useRef } from 'react' +import { CippPage } from 'src/components/layout' +import BPAFieldSchema from 'src/data/BPAField.schema.v1' +import BPAFieldUISchema from 'src/data/BPAField.uischema.v1' +import validator from '@rjsf/validator-ajv8' +import Form from '@rjsf/core' +import { CippContentCard } from 'src/components/layout' +import { CRow, CCol, CButton } from '@coreui/react' +import Editor from '@monaco-editor/react' +import { useSelector } from 'react-redux' + +const BPAFieldBuilder = () => { + const [formData, setFormData] = useState(null) + const editorRef = useRef(null) + const currentTheme = useSelector((state) => state.app.currentTheme) + function handleEditorChange(value, event) { + setFormData(JSON.parse(value)) + } + + return ( + + + + +
    setFormData(e.formData)} + enable={true} + showErrorList="bottom" + omitExtraData={true} + liveOmit={true} + /> + + + + + + + + + + ) +} + +export default BPAFieldBuilder From e7e3b65f34c9d9ef94a018b1107255e045fceb84 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Tue, 5 Sep 2023 17:52:34 -0400 Subject: [PATCH 12/38] Switch to BPA Report schema --- src/_nav.js | 4 +- src/data/BPAReport.schema.v1.json | 251 ++++++++++++++++++ src/data/BPAReport.uischema.v1.json | 36 +++ src/routes.js | 8 +- ...BPAFieldBuilder.js => BPAReportBuilder.js} | 21 +- 5 files changed, 304 insertions(+), 16 deletions(-) create mode 100644 src/data/BPAReport.schema.v1.json create mode 100644 src/data/BPAReport.uischema.v1.json rename src/views/tenant/standards/{BPAFieldBuilder.js => BPAReportBuilder.js} (74%) diff --git a/src/_nav.js b/src/_nav.js index 415109e33280..2f8d05e25f85 100644 --- a/src/_nav.js +++ b/src/_nav.js @@ -173,8 +173,8 @@ const _nav = [ }, { component: CNavItem, - name: 'BPA Field Builder', - to: '/tenant/tools/bpa-field-builder', + name: 'BPA Report Builder', + to: '/tenant/tools/bpa-report-builder', }, ], }, diff --git a/src/data/BPAReport.schema.v1.json b/src/data/BPAReport.schema.v1.json new file mode 100644 index 000000000000..45d6e0e56c2b --- /dev/null +++ b/src/data/BPAReport.schema.v1.json @@ -0,0 +1,251 @@ +{ + "title": "BPA Report Builder", + "type": "object", + "required": ["name", "style", "Fields"], + "properties": { + "name": { + "type": "string", + "title": "Report Name", + "description": "The title or name of the report." + }, + "style": { + "type": "string", + "title": "Report Style", + "default": "Table", + "enum": ["Table", "Tenant"], + "description": "Specifies the layout or presentation style of the report." + }, + "Fields": { + "title": "Report Fields", + "type": "array", + "minItems": 1, + "items": { + "required": ["name", "API", "StoreAs"], + "properties": { + "name": { + "type": "string", + "title": "Field Name", + "description": "Identifier for each set or category of data." + }, + "UseExistingInfo": { + "type": "boolean", + "title": "Use Existing Info?", + "default": false + }, + "StoreAs": { + "type": "string", + "title": "Store As", + "description": "The format in which to store the fetched data.", + "anyOf": [ + { + "const": "JSON", + "title": "JSON - For structured data" + }, + { + "const": "bool", + "title": "Boolean - True/False values" + } + ] + }, + "ExtractFields": { + "title": "Extract Fields", + "description": "Lists the attributes or fields to extract from the returned data.", + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1 + }, + "where": { + "title": "Where", + "description": "A conditional filter to determine which data gets displayed or processed. Use PowerShell's Where-Object Filterscript format.", + "type": "string" + }, + "FrontendFields": { + "type": "array", + "title": "Frontend Fields", + "description": "Describes how each data attribute will be displayed in the report.", + "items": { + "type": "object", + "properties": { + "name": { + "title": "Name", + "description": "Label for the data in the report.", + "type": "string" + }, + "value": { + "title": "Value", + "description": "Reference to the data's location or attribute.", + "type": "string" + }, + "formatter": { + "title": "Formatter", + "description": "Specifies how the data will be formatted for display.", + "type": "string", + "anyOf": [ + { + "const": "string", + "title": "Display as plain text" + }, + { + "const": "bool", + "title": "Presents as True or False" + }, + { + "const": "warnBool", + "title": "Shows boolean values with potential visual warnings" + }, + { + "const": "reverseBool", + "title": "Inverts the boolean value for display" + }, + { + "const": "table", + "title": "Represents the data in a table format" + }, + { + "const": "number", + "title": "Displays as a numerical value" + } + ] + } + } + }, + "minItems": 1, + "required": ["name", "value", "formatter"] + }, + "desc": { + "title": "Field Description", + "description": "A description field shown on the end of the card on the tenant overview page", + "type": "string" + } + }, + "allOf": [ + { + "if": { + "properties": { + "UseExistingInfo": { + "enum": [false] + } + } + }, + "then": { + "properties": { + "API": { + "type": "string", + "title": "API", + "anyOf": [ + { + "const": "Graph", + "title": "Graph" + }, + { + "const": "Exchange", + "title": "Exchange" + }, + { + "const": "CIPPFunction", + "title": "CIPP Function" + } + ], + "default": "Graph", + "description": "Defines the source or type of API to fetch the data." + } + }, + "allOf": [ + { + "if": { + "properties": { + "API": { + "enum": ["CIPPFunction"] + } + } + }, + "then": { + "properties": { + "URL": { + "type": "string", + "description": "The endpoint for CIPP Function" + } + }, + "required": ["URL"] + } + }, + { + "if": { + "properties": { + "API": { + "enum": ["Exchange"] + } + } + }, + "then": { + "properties": { + "Command": { + "type": "string", + "title": "Command", + "pattern": "^Get-", + "description": "Command for Exchange (Get only)" + } + }, + "required": ["Command"] + } + }, + { + "if": { + "properties": { + "API": { + "enum": ["Graph"] + } + } + }, + "then": { + "properties": { + "parameters": { + "type": "object", + "title": "Parameters", + "description": "Additional settings or parameters required for the API call.", + "properties": { + "asApp": { + "title": "Use Application Permissions", + "type": "boolean" + } + }, + "additionalProperties": true + }, + "URL": { + "type": "string", + "pattern": "^https://graph.microsoft.com/", + "description": "The endpoint for Graph" + } + }, + "required": ["URL"] + } + }, + { + "if": { + "properties": { + "API": { + "enum": ["Exchange", "CIPPFunction"] + } + } + }, + "then": { + "properties": { + "parameters": { + "type": "object", + "title": "Parameters", + "description": "Additional settings or parameters required for the API call.", + "additionalProperties": true + } + } + } + } + ] + } + } + ] + } + } + } +} diff --git a/src/data/BPAReport.uischema.v1.json b/src/data/BPAReport.uischema.v1.json new file mode 100644 index 000000000000..14c831199f2c --- /dev/null +++ b/src/data/BPAReport.uischema.v1.json @@ -0,0 +1,36 @@ +{ + "ui:disabled": false, + "ui:readonly": false, + "ui:order": ["name", "style", "*"], + "Fields": { + "items": { + "ui:order": [ + "name", + "desc", + "UseExistingInfo", + "StoreAs", + "API", + "URL", + "Command", + "parameters", + "where", + "ExtractFields", + "FrontendFields", + "*" + ] + } + }, + "ui:submitButtonOptions": { + "submitText": "Validate", + "norender": false, + "props": { + "disabled": false, + "className": "btn btn-info" + } + }, + "Fields": { + "items": { + "ui:classNames": "card card-title p-4 my-4" + } + } +} diff --git a/src/routes.js b/src/routes.js index 2851d6e96eb7..75079b327e2c 100644 --- a/src/routes.js +++ b/src/routes.js @@ -71,7 +71,7 @@ const DeviceComplianceReport = React.lazy(() => const BestPracticeAnalyzer = React.lazy(() => import('src/views/tenant/standards/BestPracticeAnalyser'), ) -const BPAFieldBuilder = React.lazy(() => import('src/views/tenant/standards/BPAFieldBuilder')) +const BPAReportBuilder = React.lazy(() => import('src/views/tenant/standards/BPAReportBuilder')) const DomainsAnalyser = React.lazy(() => import('src/views/tenant/standards/DomainsAnalyser')) const OffboardingWizard = React.lazy(() => import('src/views/identity/administration/OffboardingWizard'), @@ -387,9 +387,9 @@ const routes = [ component: GeoIPLookup, }, { - path: '/tenant/tools/bpa-field-builder', - name: 'BPA Field Builder', - component: BPAFieldBuilder, + path: '/tenant/tools/bpa-report-builder', + name: 'BPA Report Builder', + component: BPAReportBuilder, }, { path: '/tenant/standards/alert-list', name: 'Alert List (Alpha)', component: ListAlerts }, { path: '/endpoint', name: 'Endpoint' }, diff --git a/src/views/tenant/standards/BPAFieldBuilder.js b/src/views/tenant/standards/BPAReportBuilder.js similarity index 74% rename from src/views/tenant/standards/BPAFieldBuilder.js rename to src/views/tenant/standards/BPAReportBuilder.js index 738c37946809..660b1142229f 100644 --- a/src/views/tenant/standards/BPAFieldBuilder.js +++ b/src/views/tenant/standards/BPAReportBuilder.js @@ -1,15 +1,15 @@ import React, { useState, useRef } from 'react' import { CippPage } from 'src/components/layout' -import BPAFieldSchema from 'src/data/BPAField.schema.v1' -import BPAFieldUISchema from 'src/data/BPAField.uischema.v1' +import BPAReportSchema from 'src/data/BPAReport.schema.v1' +import BPAReportUISchema from 'src/data/BPAReport.uischema.v1' import validator from '@rjsf/validator-ajv8' import Form from '@rjsf/core' import { CippContentCard } from 'src/components/layout' -import { CRow, CCol, CButton } from '@coreui/react' +import { CRow, CCol } from '@coreui/react' import Editor from '@monaco-editor/react' import { useSelector } from 'react-redux' -const BPAFieldBuilder = () => { +const BPAReportBuilder = () => { const [formData, setFormData] = useState(null) const editorRef = useRef(null) const currentTheme = useSelector((state) => state.app.currentTheme) @@ -18,19 +18,19 @@ const BPAFieldBuilder = () => { } return ( - + setFormData(e.formData)} enable={true} - showErrorList="bottom" + showErrorList="none" omitExtraData={true} liveOmit={true} /> @@ -42,9 +42,10 @@ const BPAFieldBuilder = () => { defaultLanguage="json" value={JSON.stringify(formData, null, 2)} onChange={handleEditorChange} - schema={BPAFieldSchema} + schema={BPAReportSchema} validator={validator} theme={currentTheme == 'cyberdrain' ? 'vs-light' : 'vs-dark'} + height="700px" /> @@ -53,4 +54,4 @@ const BPAFieldBuilder = () => { ) } -export default BPAFieldBuilder +export default BPAReportBuilder From 038be3774fbd583d47506cc3625550b400fd42cb Mon Sep 17 00:00:00 2001 From: John Duprey Date: Tue, 5 Sep 2023 19:01:19 -0400 Subject: [PATCH 13/38] Update BPAReport.uischema.v1.json --- src/data/BPAReport.uischema.v1.json | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/data/BPAReport.uischema.v1.json b/src/data/BPAReport.uischema.v1.json index 14c831199f2c..f5d3db89270d 100644 --- a/src/data/BPAReport.uischema.v1.json +++ b/src/data/BPAReport.uischema.v1.json @@ -17,20 +17,14 @@ "ExtractFields", "FrontendFields", "*" - ] + ], + "FrontendFields": { + "ui:classNames": "card card-title p-4 my-4" + }, + "ui:classNames": "card card-title p-4 my-4" } }, "ui:submitButtonOptions": { - "submitText": "Validate", - "norender": false, - "props": { - "disabled": false, - "className": "btn btn-info" - } - }, - "Fields": { - "items": { - "ui:classNames": "card card-title p-4 my-4" - } + "norender": true } } From bcb1dcb74d79b022a0ca9a5d28cf9f25aaaf116e Mon Sep 17 00:00:00 2001 From: John Duprey Date: Tue, 5 Sep 2023 19:18:05 -0400 Subject: [PATCH 14/38] Update BPAReportBuilder.js --- src/views/tenant/standards/BPAReportBuilder.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/views/tenant/standards/BPAReportBuilder.js b/src/views/tenant/standards/BPAReportBuilder.js index 660b1142229f..003ac1e6f1a7 100644 --- a/src/views/tenant/standards/BPAReportBuilder.js +++ b/src/views/tenant/standards/BPAReportBuilder.js @@ -16,6 +16,9 @@ const BPAReportBuilder = () => { function handleEditorChange(value, event) { setFormData(JSON.parse(value)) } + const options = { + wordWrap: true, + } return ( @@ -42,10 +45,9 @@ const BPAReportBuilder = () => { defaultLanguage="json" value={JSON.stringify(formData, null, 2)} onChange={handleEditorChange} - schema={BPAReportSchema} - validator={validator} theme={currentTheme == 'cyberdrain' ? 'vs-light' : 'vs-dark'} height="700px" + options={options} /> From 409da1c7e927b5ff3b63ff9dd1ef236a0d620cae Mon Sep 17 00:00:00 2001 From: John Duprey Date: Tue, 5 Sep 2023 20:09:51 -0400 Subject: [PATCH 15/38] Add custom widgets --- .../tenant/standards/BPAReportBuilder.js | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/views/tenant/standards/BPAReportBuilder.js b/src/views/tenant/standards/BPAReportBuilder.js index 003ac1e6f1a7..a50f885400a4 100644 --- a/src/views/tenant/standards/BPAReportBuilder.js +++ b/src/views/tenant/standards/BPAReportBuilder.js @@ -8,6 +8,54 @@ import { CippContentCard } from 'src/components/layout' import { CRow, CCol } from '@coreui/react' import Editor from '@monaco-editor/react' import { useSelector } from 'react-redux' +import { WidgetProps, RegistryWidgetsType } from '@rjsf/utils' +import { CFormInput, CFormSelect, CFormSwitch } from '@coreui/react' + +const CippTextWidget = (props: WidgetProps) => { + return ( + props.onChange(event.target.value)} + /> + ) +} +const CippSelectWidget = (props: WidgetProps) => { + const options = props?.options.length > 0 ? props.options : props.options.enumOptions + console.log(options) + return ( + props.onChange(event.target.value)} + > + {options.map(({ label, value }, idx) => ( + + ))} + + ) +} + +const CippCheckboxWidget = (props: WidgetProps) => { + // not working yet + return ( + props.onChange(!props.value)} + /> + ) +} +const CippWidgets: RegistryWidgetsType = { + TextWidget: CippTextWidget, + SelectWidget: CippSelectWidget, +} const BPAReportBuilder = () => { const [formData, setFormData] = useState(null) @@ -36,6 +84,7 @@ const BPAReportBuilder = () => { showErrorList="none" omitExtraData={true} liveOmit={true} + widgets={CippWidgets} /> From a042dd6df1d936848230231d66688af0b9268bf8 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Wed, 6 Sep 2023 00:30:58 -0400 Subject: [PATCH 16/38] Report/schema tweaks --- src/data/BPAReport.schema.v1.json | 61 +++++++++++-------- .../tenant/standards/BPAReportBuilder.js | 24 +++++--- 2 files changed, 49 insertions(+), 36 deletions(-) diff --git a/src/data/BPAReport.schema.v1.json b/src/data/BPAReport.schema.v1.json index 45d6e0e56c2b..41eff446c312 100644 --- a/src/data/BPAReport.schema.v1.json +++ b/src/data/BPAReport.schema.v1.json @@ -20,7 +20,7 @@ "type": "array", "minItems": 1, "items": { - "required": ["name", "API", "StoreAs"], + "required": ["name", "API"], "properties": { "name": { "type": "string", @@ -32,21 +32,6 @@ "title": "Use Existing Info?", "default": false }, - "StoreAs": { - "type": "string", - "title": "Store As", - "description": "The format in which to store the fetched data.", - "anyOf": [ - { - "const": "JSON", - "title": "JSON - For structured data" - }, - { - "const": "bool", - "title": "Boolean - True/False values" - } - ] - }, "ExtractFields": { "title": "Extract Fields", "description": "Lists the attributes or fields to extract from the returned data.", @@ -56,11 +41,7 @@ }, "minItems": 1 }, - "where": { - "title": "Where", - "description": "A conditional filter to determine which data gets displayed or processed. Use PowerShell's Where-Object Filterscript format.", - "type": "string" - }, + "FrontendFields": { "type": "array", "title": "Frontend Fields", @@ -89,15 +70,15 @@ }, { "const": "bool", - "title": "Presents as True or False" + "title": "True/False" }, { "const": "warnBool", - "title": "Shows boolean values with potential visual warnings" + "title": "True/False values with potential visual warnings" }, { "const": "reverseBool", - "title": "Inverts the boolean value for display" + "title": "Inverts the True/False value for display" }, { "const": "table", @@ -131,6 +112,31 @@ }, "then": { "properties": { + "required": "StoreAs", + "where": { + "title": "Where", + "description": "A conditional filter to determine which data gets displayed or processed. Use PowerShell's Where-Object Filterscript format.", + "type": "string" + }, + "StoreAs": { + "type": "string", + "title": "Store As", + "description": "The format in which to store the fetched data.", + "anyOf": [ + { + "const": "string", + "title": "String - For plain text" + }, + { + "const": "JSON", + "title": "JSON - For structured data" + }, + { + "const": "bool", + "title": "Boolean - True/False values" + } + ] + }, "API": { "type": "string", "title": "API", @@ -163,12 +169,13 @@ }, "then": { "properties": { - "URL": { + "Command": { "type": "string", - "description": "The endpoint for CIPP Function" + "pattern": "^Get-CIPP", + "description": "Command for CIPP Function (Get-CIPP)" } }, - "required": ["URL"] + "required": ["Command"] } }, { diff --git a/src/views/tenant/standards/BPAReportBuilder.js b/src/views/tenant/standards/BPAReportBuilder.js index a50f885400a4..384c78d9e24c 100644 --- a/src/views/tenant/standards/BPAReportBuilder.js +++ b/src/views/tenant/standards/BPAReportBuilder.js @@ -8,10 +8,9 @@ import { CippContentCard } from 'src/components/layout' import { CRow, CCol } from '@coreui/react' import Editor from '@monaco-editor/react' import { useSelector } from 'react-redux' -import { WidgetProps, RegistryWidgetsType } from '@rjsf/utils' import { CFormInput, CFormSelect, CFormSwitch } from '@coreui/react' -const CippTextWidget = (props: WidgetProps) => { +const CippTextWidget = (props) => { return ( { /> ) } -const CippSelectWidget = (props: WidgetProps) => { +const CippSelectWidget = (props) => { const options = props?.options.length > 0 ? props.options : props.options.enumOptions - console.log(options) return ( { ) } -const CippCheckboxWidget = (props: WidgetProps) => { +const CippCheckboxWidget = (props) => { // not working yet + console.log(props) return ( props.onChange(!props.value)} + onChange={(event) => { + props.onChange(event.target.checked) + }} /> ) } -const CippWidgets: RegistryWidgetsType = { +const CippWidgets = { TextWidget: CippTextWidget, SelectWidget: CippSelectWidget, + CheckboxWidget: CippCheckboxWidget, } const BPAReportBuilder = () => { @@ -62,7 +64,11 @@ const BPAReportBuilder = () => { const editorRef = useRef(null) const currentTheme = useSelector((state) => state.app.currentTheme) function handleEditorChange(value, event) { - setFormData(JSON.parse(value)) + try { + setFormData(JSON.parse(value)) + } catch { + setFormData({}) + } } const options = { wordWrap: true, From c2efca5b38327467f45c6b7ae614c394f4b218d9 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Wed, 6 Sep 2023 00:37:30 -0400 Subject: [PATCH 17/38] Update BPAReport.schema.v1.json --- src/data/BPAReport.schema.v1.json | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/data/BPAReport.schema.v1.json b/src/data/BPAReport.schema.v1.json index 41eff446c312..f84418893481 100644 --- a/src/data/BPAReport.schema.v1.json +++ b/src/data/BPAReport.schema.v1.json @@ -20,7 +20,7 @@ "type": "array", "minItems": 1, "items": { - "required": ["name", "API"], + "required": ["name"], "properties": { "name": { "type": "string", @@ -32,16 +32,6 @@ "title": "Use Existing Info?", "default": false }, - "ExtractFields": { - "title": "Extract Fields", - "description": "Lists the attributes or fields to extract from the returned data.", - "type": "array", - "items": { - "type": "string" - }, - "minItems": 1 - }, - "FrontendFields": { "type": "array", "title": "Frontend Fields", @@ -111,8 +101,8 @@ } }, "then": { + "required": ["API", "StoreAs", "ExtractFields"], "properties": { - "required": "StoreAs", "where": { "title": "Where", "description": "A conditional filter to determine which data gets displayed or processed. Use PowerShell's Where-Object Filterscript format.", @@ -156,6 +146,15 @@ ], "default": "Graph", "description": "Defines the source or type of API to fetch the data." + }, + "ExtractFields": { + "title": "Extract Fields", + "description": "Lists the attributes or fields to extract from the returned data.", + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1 } }, "allOf": [ From be63aeac1c9e78af0ee803f67d39503cc759b3cd Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Wed, 6 Sep 2023 18:14:00 +0200 Subject: [PATCH 18/38] tmp bpa fix --- src/views/tenant/standards/BestPracticeAnalyser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/tenant/standards/BestPracticeAnalyser.js b/src/views/tenant/standards/BestPracticeAnalyser.js index 68356121e425..025095e1a48c 100644 --- a/src/views/tenant/standards/BestPracticeAnalyser.js +++ b/src/views/tenant/standards/BestPracticeAnalyser.js @@ -198,7 +198,7 @@ const BestPracticeAnalyser = () => { name: col.name, selector: (row) => getNestedValue(row, col.value), sortable: true, - exportSelector: col.value, + exportSelector: col.value.split('.').join('/'), cell: cellSelector, // Use the determined cell selector }) }) From 869fdf8f98f5a04b27dcb58786d625950d22f392 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Wed, 6 Sep 2023 18:35:02 +0200 Subject: [PATCH 19/38] fix spacing --- src/data/BPAField.uischema.v1.json | 2 +- src/views/tenant/standards/BPAReportBuilder.js | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/data/BPAField.uischema.v1.json b/src/data/BPAField.uischema.v1.json index 4eeb72527109..5d88206bb0aa 100644 --- a/src/data/BPAField.uischema.v1.json +++ b/src/data/BPAField.uischema.v1.json @@ -20,7 +20,7 @@ "norender": false, "props": { "disabled": false, - "className": "btn btn-info" + "className": "btn mb-3 btn-primary" } } } diff --git a/src/views/tenant/standards/BPAReportBuilder.js b/src/views/tenant/standards/BPAReportBuilder.js index 384c78d9e24c..39015265c675 100644 --- a/src/views/tenant/standards/BPAReportBuilder.js +++ b/src/views/tenant/standards/BPAReportBuilder.js @@ -14,6 +14,7 @@ const CippTextWidget = (props) => { return ( props.onChange(event.target.value)} @@ -26,6 +27,7 @@ const CippSelectWidget = (props) => { props.onChange(event.target.value)} > {options.map(({ label, value }, idx) => ( @@ -46,7 +48,7 @@ const CippCheckboxWidget = (props) => { id={props.name} label={props.label} checked={props.value} - className="my-2" + className="mb-3" onChange={(event) => { props.onChange(event.target.checked) }} From 9979c91c09a6303458d3da18388d18cae3cb6e61 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Wed, 6 Sep 2023 20:57:22 +0200 Subject: [PATCH 20/38] theming of bpa --- package-lock.json | 293 +++++++++++++++++- package.json | 1 + src/data/BPAField.uischema.v1.json | 2 +- src/data/BPAReport.uischema.v1.json | 3 +- .../tenant/standards/BPAReportBuilder.js | 5 +- 5 files changed, 292 insertions(+), 12 deletions(-) diff --git a/package-lock.json b/package-lock.json index a7f3bc927e18..acf2cd561d02 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,6 +22,7 @@ "@monaco-editor/react": "^4.5.2", "@popperjs/core": "^2.10.2", "@reduxjs/toolkit": "^1.7.0", + "@rjsf/bootstrap-4": "^5.12.1", "@rjsf/core": "^5.12.1", "@rjsf/utils": "^5.12.1", "@rjsf/validator-ajv8": "^5.12.1", @@ -3175,13 +3176,22 @@ } }, "node_modules/@popperjs/core": { - "version": "2.11.2", - "license": "MIT", + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", "funding": { "type": "opencollective", "url": "https://opencollective.com/popperjs" } }, + "node_modules/@react-icons/all-files": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@react-icons/all-files/-/all-files-4.1.0.tgz", + "integrity": "sha512-hxBI2UOuVaI3O/BhQfhtb4kcGn9ft12RWAFVMUeNjqqhLsHvFtzIkFaptBJpFDANTKoDfdVoHTKZDlwKCACbMQ==", + "peerDependencies": { + "react": "*" + } + }, "node_modules/@reduxjs/toolkit": { "version": "1.8.0", "license": "MIT", @@ -3211,6 +3221,44 @@ "@babel/runtime": "^7.9.2" } }, + "node_modules/@restart/context": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@restart/context/-/context-2.1.4.tgz", + "integrity": "sha512-INJYZQJP7g+IoDUh/475NlGiTeMfwTXUEr3tmRneckHIxNolGOW9CTq83S8cxq0CgJwwcMzMJFchxvlwe7Rk8Q==", + "peer": true, + "peerDependencies": { + "react": ">=16.3.2" + } + }, + "node_modules/@restart/hooks": { + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.11.tgz", + "integrity": "sha512-Ft/ncTULZN6ldGHiF/k5qt72O8JyRMOeg0tApvCni8LkoiEahO+z3TNxfXIVGy890YtWVDvJAl662dVJSJXvMw==", + "peer": true, + "dependencies": { + "dequal": "^2.0.3" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@rjsf/bootstrap-4": { + "version": "5.12.1", + "resolved": "https://registry.npmjs.org/@rjsf/bootstrap-4/-/bootstrap-4-5.12.1.tgz", + "integrity": "sha512-aUnijxIlYWza8klJ+GvgoYk4gFSaQQV97LLdujMQY096iLm12ryxWLEjyLyPPNOymyp4kdkNO4FCTiWMs2bh3Q==", + "dependencies": { + "@react-icons/all-files": "^4.1.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@rjsf/core": "^5.8.x", + "@rjsf/utils": "^5.8.x", + "react": "^16.14.0 || >=17", + "react-bootstrap": "^1.6.5" + } + }, "node_modules/@rjsf/core": { "version": "5.12.1", "resolved": "https://registry.npmjs.org/@rjsf/core/-/core-5.12.1.tgz", @@ -3767,6 +3815,12 @@ "@types/node": "*" } }, + "node_modules/@types/invariant": { + "version": "2.2.35", + "resolved": "https://registry.npmjs.org/@types/invariant/-/invariant-2.2.35.tgz", + "integrity": "sha512-DxX1V9P8zdJPYQat1gHyY0xj3efl8gnMVjiM9iCY6y27lj+PoQWkgjt8jDqmovPqULkKVpKRg8J36iQiA+EtEg==", + "peer": true + }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.4", "dev": true, @@ -3946,6 +4000,12 @@ "version": "2.0.6", "license": "MIT" }, + "node_modules/@types/warning": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.0.tgz", + "integrity": "sha512-t/Tvs5qR47OLOr+4E9ckN8AmP2Tf16gWq+/qA4iUGS/OOyHVO8wv2vjJuX8SNOUTJyWb+2t7wJm6cXILFnOROA==", + "peer": true + }, "node_modules/@types/ws": { "version": "8.5.2", "dev": true, @@ -6940,6 +7000,15 @@ "node": ">= 0.6" } }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "peer": true, + "engines": { + "node": ">=6" + } + }, "node_modules/desandro-matches-selector": { "version": "2.0.2", "license": "MIT" @@ -9686,7 +9755,6 @@ }, "node_modules/invariant": { "version": "2.2.4", - "dev": true, "license": "MIT", "dependencies": { "loose-envify": "^1.0.0" @@ -14643,6 +14711,25 @@ "react-is": "^16.13.1" } }, + "node_modules/prop-types-extra": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz", + "integrity": "sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==", + "peer": true, + "dependencies": { + "react-is": "^16.3.2", + "warning": "^4.0.0" + }, + "peerDependencies": { + "react": ">=0.14.0" + } + }, + "node_modules/prop-types-extra/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "peer": true + }, "node_modules/prop-types/node_modules/react-is": { "version": "16.13.1", "license": "MIT" @@ -14839,6 +14926,35 @@ "node": ">=10" } }, + "node_modules/react-bootstrap": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-1.6.7.tgz", + "integrity": "sha512-IzCYXuLSKDEjGFglbFWk0/iHmdhdcJzTmtS6lXxc0kaNFx2PFgrQf5jKnx5sarF2tiXh9Tgx3pSt3pdK7YwkMA==", + "peer": true, + "dependencies": { + "@babel/runtime": "^7.14.0", + "@restart/context": "^2.1.4", + "@restart/hooks": "^0.4.7", + "@types/invariant": "^2.2.33", + "@types/prop-types": "^15.7.3", + "@types/react": ">=16.14.8", + "@types/react-transition-group": "^4.4.1", + "@types/warning": "^3.0.0", + "classnames": "^2.3.1", + "dom-helpers": "^5.2.1", + "invariant": "^2.2.4", + "prop-types": "^15.7.2", + "prop-types-extra": "^1.1.0", + "react-overlays": "^5.1.2", + "react-transition-group": "^4.4.1", + "uncontrollable": "^7.2.1", + "warning": "^4.0.3" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, "node_modules/react-copy-to-clipboard": { "version": "5.0.4", "license": "MIT", @@ -15073,6 +15189,12 @@ "version": "17.0.2", "license": "MIT" }, + "node_modules/react-lifecycles-compat": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==", + "peer": true + }, "node_modules/react-loading-skeleton": { "version": "3.1.0", "license": "MIT", @@ -15115,6 +15237,26 @@ "react-dom": "^15.5.x || ^16.x || ^17.x || ^18.x" } }, + "node_modules/react-overlays": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-5.2.1.tgz", + "integrity": "sha512-GLLSOLWr21CqtJn8geSwQfoJufdt3mfdsnIiQswouuQ2MMPns+ihZklxvsTDKD3cR2tF8ELbi5xUsvqVhR6WvA==", + "peer": true, + "dependencies": { + "@babel/runtime": "^7.13.8", + "@popperjs/core": "^2.11.6", + "@restart/hooks": "^0.4.7", + "@types/warning": "^3.0.0", + "dom-helpers": "^5.2.0", + "prop-types": "^15.7.2", + "uncontrollable": "^7.2.1", + "warning": "^4.0.3" + }, + "peerDependencies": { + "react": ">=16.3.0", + "react-dom": ">=16.3.0" + } + }, "node_modules/react-papaparse": { "version": "3.18.2", "license": "MIT", @@ -17558,6 +17700,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/uncontrollable": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.2.1.tgz", + "integrity": "sha512-svtcfoTADIB0nT9nltgjujTi7BzVmwjZClOmskKu/E8FW9BXzg9os8OLr4f8Dlnk0rYWJIWr4wv9eKUXiQvQwQ==", + "peer": true, + "dependencies": { + "@babel/runtime": "^7.6.3", + "@types/react": ">=16.9.11", + "invariant": "^2.2.4", + "react-lifecycles-compat": "^3.0.4" + }, + "peerDependencies": { + "react": ">=15.0.0" + } + }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.0", "dev": true, @@ -20598,7 +20755,15 @@ } }, "@popperjs/core": { - "version": "2.11.2" + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==" + }, + "@react-icons/all-files": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@react-icons/all-files/-/all-files-4.1.0.tgz", + "integrity": "sha512-hxBI2UOuVaI3O/BhQfhtb4kcGn9ft12RWAFVMUeNjqqhLsHvFtzIkFaptBJpFDANTKoDfdVoHTKZDlwKCACbMQ==", + "requires": {} }, "@reduxjs/toolkit": { "version": "1.8.0", @@ -20617,6 +20782,30 @@ } } }, + "@restart/context": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@restart/context/-/context-2.1.4.tgz", + "integrity": "sha512-INJYZQJP7g+IoDUh/475NlGiTeMfwTXUEr3tmRneckHIxNolGOW9CTq83S8cxq0CgJwwcMzMJFchxvlwe7Rk8Q==", + "peer": true, + "requires": {} + }, + "@restart/hooks": { + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.11.tgz", + "integrity": "sha512-Ft/ncTULZN6ldGHiF/k5qt72O8JyRMOeg0tApvCni8LkoiEahO+z3TNxfXIVGy890YtWVDvJAl662dVJSJXvMw==", + "peer": true, + "requires": { + "dequal": "^2.0.3" + } + }, + "@rjsf/bootstrap-4": { + "version": "5.12.1", + "resolved": "https://registry.npmjs.org/@rjsf/bootstrap-4/-/bootstrap-4-5.12.1.tgz", + "integrity": "sha512-aUnijxIlYWza8klJ+GvgoYk4gFSaQQV97LLdujMQY096iLm12ryxWLEjyLyPPNOymyp4kdkNO4FCTiWMs2bh3Q==", + "requires": { + "@react-icons/all-files": "^4.1.0" + } + }, "@rjsf/core": { "version": "5.12.1", "resolved": "https://registry.npmjs.org/@rjsf/core/-/core-5.12.1.tgz", @@ -20981,6 +21170,12 @@ "@types/node": "*" } }, + "@types/invariant": { + "version": "2.2.35", + "resolved": "https://registry.npmjs.org/@types/invariant/-/invariant-2.2.35.tgz", + "integrity": "sha512-DxX1V9P8zdJPYQat1gHyY0xj3efl8gnMVjiM9iCY6y27lj+PoQWkgjt8jDqmovPqULkKVpKRg8J36iQiA+EtEg==", + "peer": true + }, "@types/istanbul-lib-coverage": { "version": "2.0.4", "dev": true @@ -21130,6 +21325,12 @@ "@types/unist": { "version": "2.0.6" }, + "@types/warning": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.0.tgz", + "integrity": "sha512-t/Tvs5qR47OLOr+4E9ckN8AmP2Tf16gWq+/qA4iUGS/OOyHVO8wv2vjJuX8SNOUTJyWb+2t7wJm6cXILFnOROA==", + "peer": true + }, "@types/ws": { "version": "8.5.2", "dev": true, @@ -22970,6 +23171,12 @@ "version": "1.1.2", "dev": true }, + "dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "peer": true + }, "desandro-matches-selector": { "version": "2.0.2" }, @@ -24714,7 +24921,6 @@ }, "invariant": { "version": "2.2.4", - "dev": true, "requires": { "loose-envify": "^1.0.0" } @@ -27707,6 +27913,24 @@ } } }, + "prop-types-extra": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz", + "integrity": "sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==", + "peer": true, + "requires": { + "react-is": "^16.3.2", + "warning": "^4.0.0" + }, + "dependencies": { + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "peer": true + } + } + }, "property-information": { "version": "5.6.0", "requires": { @@ -27823,6 +28047,31 @@ "whatwg-fetch": "^3.4.1" } }, + "react-bootstrap": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-1.6.7.tgz", + "integrity": "sha512-IzCYXuLSKDEjGFglbFWk0/iHmdhdcJzTmtS6lXxc0kaNFx2PFgrQf5jKnx5sarF2tiXh9Tgx3pSt3pdK7YwkMA==", + "peer": true, + "requires": { + "@babel/runtime": "^7.14.0", + "@restart/context": "^2.1.4", + "@restart/hooks": "^0.4.7", + "@types/invariant": "^2.2.33", + "@types/prop-types": "^15.7.3", + "@types/react": ">=16.14.8", + "@types/react-transition-group": "^4.4.1", + "@types/warning": "^3.0.0", + "classnames": "^2.3.1", + "dom-helpers": "^5.2.1", + "invariant": "^2.2.4", + "prop-types": "^15.7.2", + "prop-types-extra": "^1.1.0", + "react-overlays": "^5.1.2", + "react-transition-group": "^4.4.1", + "uncontrollable": "^7.2.1", + "warning": "^4.0.3" + } + }, "react-copy-to-clipboard": { "version": "5.0.4", "requires": { @@ -27973,6 +28222,12 @@ "react-is": { "version": "17.0.2" }, + "react-lifecycles-compat": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==", + "peer": true + }, "react-loading-skeleton": { "version": "3.1.0", "requires": {} @@ -27998,6 +28253,22 @@ "integrity": "sha512-NMXGa223OnsrGVp5dJHkuKxQ4czdLmXSp5jSV9OqiCky9LOpPATn3vLldc+q5fK3gKbEHvr7J1u0yhBh/xYkpA==", "requires": {} }, + "react-overlays": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-5.2.1.tgz", + "integrity": "sha512-GLLSOLWr21CqtJn8geSwQfoJufdt3mfdsnIiQswouuQ2MMPns+ihZklxvsTDKD3cR2tF8ELbi5xUsvqVhR6WvA==", + "peer": true, + "requires": { + "@babel/runtime": "^7.13.8", + "@popperjs/core": "^2.11.6", + "@restart/hooks": "^0.4.7", + "@types/warning": "^3.0.0", + "dom-helpers": "^5.2.0", + "prop-types": "^15.7.2", + "uncontrollable": "^7.2.1", + "warning": "^4.0.3" + } + }, "react-papaparse": { "version": "3.18.2", "requires": { @@ -29610,6 +29881,18 @@ "which-boxed-primitive": "^1.0.2" } }, + "uncontrollable": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.2.1.tgz", + "integrity": "sha512-svtcfoTADIB0nT9nltgjujTi7BzVmwjZClOmskKu/E8FW9BXzg9os8OLr4f8Dlnk0rYWJIWr4wv9eKUXiQvQwQ==", + "peer": true, + "requires": { + "@babel/runtime": "^7.6.3", + "@types/react": ">=16.9.11", + "invariant": "^2.2.4", + "react-lifecycles-compat": "^3.0.4" + } + }, "unicode-canonical-property-names-ecmascript": { "version": "2.0.0", "dev": true diff --git a/package.json b/package.json index ccb4c6383316..88f3735fcc05 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "@monaco-editor/react": "^4.5.2", "@popperjs/core": "^2.10.2", "@reduxjs/toolkit": "^1.7.0", + "@rjsf/bootstrap-4": "^5.12.1", "@rjsf/core": "^5.12.1", "@rjsf/utils": "^5.12.1", "@rjsf/validator-ajv8": "^5.12.1", diff --git a/src/data/BPAField.uischema.v1.json b/src/data/BPAField.uischema.v1.json index 5d88206bb0aa..bc36b81d44b2 100644 --- a/src/data/BPAField.uischema.v1.json +++ b/src/data/BPAField.uischema.v1.json @@ -20,7 +20,7 @@ "norender": false, "props": { "disabled": false, - "className": "btn mb-3 btn-primary" + "className": "btn btn-primary" } } } diff --git a/src/data/BPAReport.uischema.v1.json b/src/data/BPAReport.uischema.v1.json index f5d3db89270d..19e3c7d01237 100644 --- a/src/data/BPAReport.uischema.v1.json +++ b/src/data/BPAReport.uischema.v1.json @@ -20,8 +20,7 @@ ], "FrontendFields": { "ui:classNames": "card card-title p-4 my-4" - }, - "ui:classNames": "card card-title p-4 my-4" + } } }, "ui:submitButtonOptions": { diff --git a/src/views/tenant/standards/BPAReportBuilder.js b/src/views/tenant/standards/BPAReportBuilder.js index 39015265c675..a452eb1a6d4e 100644 --- a/src/views/tenant/standards/BPAReportBuilder.js +++ b/src/views/tenant/standards/BPAReportBuilder.js @@ -3,7 +3,7 @@ import { CippPage } from 'src/components/layout' import BPAReportSchema from 'src/data/BPAReport.schema.v1' import BPAReportUISchema from 'src/data/BPAReport.uischema.v1' import validator from '@rjsf/validator-ajv8' -import Form from '@rjsf/core' +import Form from '@rjsf/bootstrap-4' import { CippContentCard } from 'src/components/layout' import { CRow, CCol } from '@coreui/react' import Editor from '@monaco-editor/react' @@ -14,7 +14,6 @@ const CippTextWidget = (props) => { return ( props.onChange(event.target.value)} @@ -27,7 +26,6 @@ const CippSelectWidget = (props) => { props.onChange(event.target.value)} > {options.map(({ label, value }, idx) => ( @@ -48,7 +46,6 @@ const CippCheckboxWidget = (props) => { id={props.name} label={props.label} checked={props.value} - className="mb-3" onChange={(event) => { props.onChange(event.target.checked) }} From 7318fc36881122f63c2a58ca02040b7d3f2280c9 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Wed, 6 Sep 2023 23:48:23 +0200 Subject: [PATCH 21/38] added offcanvas and theming for code --- src/components/utilities/CippCodeOffcanvas.js | 60 +++++++++++++++++++ src/components/utilities/CippOffcanvas.js | 2 +- src/scss/_custom.scss | 8 ++- .../connectors/ListConnectorTemplates.js | 18 +++--- .../spamfilter/ListSpamfilterTemplates.js | 14 ++--- .../transport/ListTransportTemplates.js | 14 ++--- .../endpoint/intune/MEMListPolicyTemplates.js | 14 ++--- .../identity/administration/GroupTemplates.js | 14 ++--- .../tenant/conditional/ListCATemplates.js | 14 ++--- 9 files changed, 104 insertions(+), 54 deletions(-) create mode 100644 src/components/utilities/CippCodeOffcanvas.js diff --git a/src/components/utilities/CippCodeOffcanvas.js b/src/components/utilities/CippCodeOffcanvas.js new file mode 100644 index 000000000000..a36a23b8dae4 --- /dev/null +++ b/src/components/utilities/CippCodeOffcanvas.js @@ -0,0 +1,60 @@ +import React, { useState } from 'react' +import { CButton, CCallout, CCol, CRow, CSpinner } from '@coreui/react' +import { CippOffcanvas } from 'src/components/utilities' +import { useLazyGenericGetRequestQuery, useLazyGenericPostRequestQuery } from 'src/store/api/app' + +import { Editor } from '@monaco-editor/react' +import { useSelector } from 'react-redux' + +function CippCodeOffCanvas({ row, state, hideFunction, type }) { + const [SaveTemplate, templateDetails] = useLazyGenericPostRequestQuery() + const currentTheme = useSelector((state) => state.app.currentTheme) + const [templateData, setFormData] = useState(row) + function handleEditorChange(value, event) { + setFormData(JSON.parse(value)) + } + return ( + <> + + + + + + SaveTemplate({ + path: `/api/ExecEditTemplate?type=${type}`, + method: 'POST', + values: templateData, + }) + } + > + Save changes {templateDetails.isFetching && } + + + + {templateDetails.isSuccess && !templateDetails.isFetching && ( + {templateDetails.data.Results} + )} + + + ) +} + +export default CippCodeOffCanvas diff --git a/src/components/utilities/CippOffcanvas.js b/src/components/utilities/CippOffcanvas.js index 7a6590eb57d1..3148f5992ecb 100644 --- a/src/components/utilities/CippOffcanvas.js +++ b/src/components/utilities/CippOffcanvas.js @@ -8,7 +8,7 @@ export default function CippOffcanvas(props) { return ( { const tenant = useSelector((state) => state.app.currentTenant) - const [ExecuteGetRequest, getResults] = useLazyGenericGetRequestQuery() const Offcanvas = (row, rowIndex, formatExtraData) => { const [ocVisible, setOCVisible] = useState(false) @@ -44,15 +45,12 @@ const ConnectorListTemplates = () => { - setOCVisible(false)} - > - - + /> ) } diff --git a/src/views/email-exchange/spamfilter/ListSpamfilterTemplates.js b/src/views/email-exchange/spamfilter/ListSpamfilterTemplates.js index 13afb7fa99a4..076a7879c423 100644 --- a/src/views/email-exchange/spamfilter/ListSpamfilterTemplates.js +++ b/src/views/email-exchange/spamfilter/ListSpamfilterTemplates.js @@ -9,6 +9,7 @@ import { useLazyGenericGetRequestQuery } from 'src/store/api/app' import { CippPageList } from 'src/components/layout' import { ModalService } from 'src/components/utilities' import { TitleButton } from 'src/components/buttons' +import CippCodeOffCanvas from 'src/components/utilities/CippCodeOffcanvas' const SpamFilterListTemplates = () => { const tenant = useSelector((state) => state.app.currentTenant) @@ -44,15 +45,12 @@ const SpamFilterListTemplates = () => { - setOCVisible(false)} - > - - + /> ) } diff --git a/src/views/email-exchange/transport/ListTransportTemplates.js b/src/views/email-exchange/transport/ListTransportTemplates.js index 3a8cf38287bd..c0cfb1148979 100644 --- a/src/views/email-exchange/transport/ListTransportTemplates.js +++ b/src/views/email-exchange/transport/ListTransportTemplates.js @@ -9,6 +9,7 @@ import { useLazyGenericGetRequestQuery } from 'src/store/api/app' import { CippPageList } from 'src/components/layout' import { ModalService } from 'src/components/utilities' import { TitleButton } from 'src/components/buttons' +import CippCodeOffCanvas from 'src/components/utilities/CippCodeOffcanvas' const TransportListTemplates = () => { const tenant = useSelector((state) => state.app.currentTenant) @@ -44,15 +45,12 @@ const TransportListTemplates = () => { - setOCVisible(false)} - > - - + /> ) } diff --git a/src/views/endpoint/intune/MEMListPolicyTemplates.js b/src/views/endpoint/intune/MEMListPolicyTemplates.js index 73324c19b7f1..645744383d56 100644 --- a/src/views/endpoint/intune/MEMListPolicyTemplates.js +++ b/src/views/endpoint/intune/MEMListPolicyTemplates.js @@ -16,6 +16,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { useLazyGenericGetRequestQuery } from 'src/store/api/app' import { CippPage } from 'src/components/layout' import { ModalService } from 'src/components/utilities' +import CippCodeOffCanvas from 'src/components/utilities/CippCodeOffcanvas' //todo: expandable with RAWJson property. @@ -52,15 +53,12 @@ const AutopilotListTemplates = () => { > - setOCVisible(false)} - > - - + /> ) } diff --git a/src/views/identity/administration/GroupTemplates.js b/src/views/identity/administration/GroupTemplates.js index 67ce049e327c..590bf91cd3eb 100644 --- a/src/views/identity/administration/GroupTemplates.js +++ b/src/views/identity/administration/GroupTemplates.js @@ -9,6 +9,7 @@ import { useLazyGenericGetRequestQuery } from 'src/store/api/app' import { CippPageList } from 'src/components/layout' import { ModalService } from 'src/components/utilities' import { TitleButton } from 'src/components/buttons' +import CippCodeOffCanvas from 'src/components/utilities/CippCodeOffcanvas' const GroupTemplates = () => { const tenant = useSelector((state) => state.app.currentTenant) @@ -43,15 +44,12 @@ const GroupTemplates = () => { > - setOCVisible(false)} - > - - + /> ) } diff --git a/src/views/tenant/conditional/ListCATemplates.js b/src/views/tenant/conditional/ListCATemplates.js index f19472d10587..835ed3fef2ff 100644 --- a/src/views/tenant/conditional/ListCATemplates.js +++ b/src/views/tenant/conditional/ListCATemplates.js @@ -17,6 +17,7 @@ import { useLazyGenericGetRequestQuery } from 'src/store/api/app' import { CippPage } from 'src/components/layout' import { ModalService } from 'src/components/utilities' import { CellTip } from 'src/components/tables' +import CippCodeOffCanvas from 'src/components/utilities/CippCodeOffcanvas' //todo: expandable with RAWJson property. @@ -53,15 +54,12 @@ const AutopilotListTemplates = () => { > - setOCVisible(false)} - > - - + /> ) } From 46c7a4bba77bdd01617210291b56319aae4940ec Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Thu, 7 Sep 2023 00:18:00 +0200 Subject: [PATCH 22/38] added invalid json do not send marker --- src/components/utilities/CippCodeOffcanvas.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/components/utilities/CippCodeOffcanvas.js b/src/components/utilities/CippCodeOffcanvas.js index a36a23b8dae4..c8cdbf175d35 100644 --- a/src/components/utilities/CippCodeOffcanvas.js +++ b/src/components/utilities/CippCodeOffcanvas.js @@ -10,8 +10,15 @@ function CippCodeOffCanvas({ row, state, hideFunction, type }) { const [SaveTemplate, templateDetails] = useLazyGenericPostRequestQuery() const currentTheme = useSelector((state) => state.app.currentTheme) const [templateData, setFormData] = useState(row) + const [invalidJSON, setInvalid] = useState(false) + function handleEditorChange(value, event) { - setFormData(JSON.parse(value)) + try { + setFormData(JSON.parse(value)) + setInvalid(false) + } catch { + setInvalid(true) + } } return ( <> @@ -37,6 +44,7 @@ function CippCodeOffCanvas({ row, state, hideFunction, type }) { SaveTemplate({ path: `/api/ExecEditTemplate?type=${type}`, From 5563827e337df6aa6c709110602f65672f9a43bc Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Thu, 7 Sep 2023 11:08:34 +0200 Subject: [PATCH 23/38] added multi select to offboarding wizard --- src/views/identity/administration/OffboardingWizard.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/views/identity/administration/OffboardingWizard.js b/src/views/identity/administration/OffboardingWizard.js index 4e6318addf9d..58c425a52b2d 100644 --- a/src/views/identity/administration/OffboardingWizard.js +++ b/src/views/identity/administration/OffboardingWizard.js @@ -45,9 +45,9 @@ const OffboardingWizard = () => { TenantFilter: tenantDomain, OOO: values.OOO ? values.OOO : '', forward: values.forward ? values.forward.value : '', - OnedriveAccess: values.OnedriveAccess ? values.OnedriveAccess.value : '', - AccessNoAutomap: values.AccessNoAutomap ? values.AccessNoAutomap.value : '', - AccessAutomap: values.AccessAutomap ? values.AccessAutomap.value : '', + OnedriveAccess: values.OnedriveAccess ? values.OnedriveAccess : '', + AccessNoAutomap: values.AccessNoAutomap ? values.AccessNoAutomap : '', + AccessAutomap: values.AccessAutomap ? values.AccessAutomap : '', ConvertToShared: values.ConvertToShared, HideFromGAL: values.HideFromGAL, DisableSignIn: values.DisableSignIn, @@ -130,6 +130,7 @@ const OffboardingWizard = () => { x.mail) .map((user) => ({ @@ -143,6 +144,7 @@ const OffboardingWizard = () => { x.mail) .map((user) => ({ @@ -156,6 +158,7 @@ const OffboardingWizard = () => { x.mail) .map((user) => ({ From afadd686684f78df717e66cadd88fdd850d44d67 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Thu, 7 Sep 2023 12:57:22 +0200 Subject: [PATCH 24/38] improved search for tenant selector. --- src/components/utilities/CippFuzzySearch.js | 26 +++++++++++++++++++++ src/components/utilities/TenantSelector.js | 7 +++--- 2 files changed, 30 insertions(+), 3 deletions(-) create mode 100644 src/components/utilities/CippFuzzySearch.js diff --git a/src/components/utilities/CippFuzzySearch.js b/src/components/utilities/CippFuzzySearch.js new file mode 100644 index 000000000000..f4db1f1473cb --- /dev/null +++ b/src/components/utilities/CippFuzzySearch.js @@ -0,0 +1,26 @@ +var _fuse = _interopRequireDefault(require('fuse.js')) + +function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { default: obj } +} + +function CippfuzzySearch(options) { + var fuse = new _fuse['default'](options, { + keys: ['name', 'groupName', 'items.name'], + threshold: 0.2, + location: 0, + ignoreLocation: true, + useExtendedSearch: true, + }) + return function (value) { + if (!value.length) { + return options + } + + return fuse.search(value).map((_ref) => { + let { item } = _ref + return item + }) + } +} +export default CippfuzzySearch diff --git a/src/components/utilities/TenantSelector.js b/src/components/utilities/TenantSelector.js index 686fdd0727e4..570f2f30c002 100644 --- a/src/components/utilities/TenantSelector.js +++ b/src/components/utilities/TenantSelector.js @@ -10,6 +10,7 @@ import { queryString } from 'src/helpers' import { faBuilding } from '@fortawesome/free-solid-svg-icons' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import CippTenantOffcanvas from './CippTenantOffcanvas' +import CippfuzzySearch from './CippFuzzySearch' const TenantSelector = ({ action, showAllTenantSelector = true, NavSelector = false }) => { const currentTenant = useSelector((state) => state.app.currentTenant) @@ -95,13 +96,13 @@ const TenantSelector = ({ action, showAllTenantSelector = true, NavSelector = fa ({ value: customerId, - name: [displayName] + [` (${defaultDomainName})`], + name: `${displayName} (${defaultDomainName})`, }))} /> @@ -112,7 +113,7 @@ const TenantSelector = ({ action, showAllTenantSelector = true, NavSelector = fa Date: Thu, 7 Sep 2023 12:11:01 -0400 Subject: [PATCH 25/38] BPA Report Builder - Load/Publish - Add Load Existing Template - Add publish to GitHub button --- .../tenant/standards/BPAReportBuilder.js | 153 +++++++++++++++++- 1 file changed, 148 insertions(+), 5 deletions(-) diff --git a/src/views/tenant/standards/BPAReportBuilder.js b/src/views/tenant/standards/BPAReportBuilder.js index a452eb1a6d4e..52987e1dc3e5 100644 --- a/src/views/tenant/standards/BPAReportBuilder.js +++ b/src/views/tenant/standards/BPAReportBuilder.js @@ -1,14 +1,33 @@ -import React, { useState, useRef } from 'react' +import React, { useState, useEffect, useRef } from 'react' import { CippPage } from 'src/components/layout' import BPAReportSchema from 'src/data/BPAReport.schema.v1' import BPAReportUISchema from 'src/data/BPAReport.uischema.v1' import validator from '@rjsf/validator-ajv8' import Form from '@rjsf/bootstrap-4' import { CippContentCard } from 'src/components/layout' -import { CRow, CCol } from '@coreui/react' import Editor from '@monaco-editor/react' import { useSelector } from 'react-redux' -import { CFormInput, CFormSelect, CFormSwitch } from '@coreui/react' +import useQuery from 'src/hooks/useQuery' +import { + CFormInput, + CFormSelect, + CFormSwitch, + CRow, + CCol, + CCard, + CCardHeader, + CCardTitle, + CButton, + CCollapse, + CCardBody, + CForm, + CSpinner, + CFormLabel, + CTooltip, +} from '@coreui/react' +import { useGenericGetRequestQuery } from 'src/store/api/app' +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' +import CopyToClipboard from 'react-copy-to-clipboard' const CippTextWidget = (props) => { return ( @@ -38,8 +57,6 @@ const CippSelectWidget = (props) => { } const CippCheckboxWidget = (props) => { - // not working yet - console.log(props) return ( { + let query = useQuery() + const [refreshValue, setRefreshValue] = useState('') + const Report = query.get('Report') + const [filename, setFilename] = useState() + const [visibleA, setVisibleA] = useState(true) + const { data: templates = [], isLoading: templatesfetch } = useGenericGetRequestQuery({ + path: 'api/listBPATemplates?RawJson=true&Refresh=' + refreshValue, + }) const [formData, setFormData] = useState(null) const editorRef = useRef(null) const currentTheme = useSelector((state) => state.app.currentTheme) + + function handleRefresh() { + setRefreshValue((Math.random() + 1).toString(36).substring(7)) + } + function handleEditorChange(value, event) { try { setFormData(JSON.parse(value)) @@ -69,12 +99,125 @@ const BPAReportBuilder = () => { setFormData({}) } } + const handleSubmit = async (event) => { + event.preventDefault() + var reportTemplate = event.target.form[0].value + setVisibleA(false) + if (reportTemplate !== 'New') { + var template = templates.filter(function (tpl) { + return tpl.name == reportTemplate + }) + setFormData(template[0]) + } else { + setFormData({}) + } + } + useEffect(() => { + var reportName = formData?.name ? formData?.name?.replace(/[\W]/g, '') : 'NewReport' + var newfilename = reportName + '.BPATemplate.json' + setFilename(newfilename) + }, [filename, formData]) + + const handlePublish = async (event) => { + event.preventDefault() + const data = new FormData(event.target) + const ghuser = data.get('GitHubUser') + const reportfilename = data.get('ReportFilename') + const report = JSON.stringify(formData, null, 2) + const url = + 'https://github.com/' + ghuser + '/CIPP-API/new/master/Config?filename=' + reportfilename + window.open(url, '_blank') + } + const options = { wordWrap: true, } return ( + + + + + + Report Settings + setVisibleA(!visibleA)}> + + + + + + + + + + + + Load Existing Report + + + {templates.map((template, idx) => ( + + ))} + + + {templatesfetch && } + + + + + + Load Report + + + + + + + + + + + + + GitHub Username/Org Name + + Report Filename + + + + + + + + + + Publish + + + + + + + + + + + + + +
    From d9aa06d248e82b13bfc4e131d12c5d78e7927616 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Thu, 7 Sep 2023 12:36:54 -0400 Subject: [PATCH 26/38] Update BPAReportBuilder.js --- src/views/tenant/standards/BPAReportBuilder.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/tenant/standards/BPAReportBuilder.js b/src/views/tenant/standards/BPAReportBuilder.js index 52987e1dc3e5..46a4766bd25c 100644 --- a/src/views/tenant/standards/BPAReportBuilder.js +++ b/src/views/tenant/standards/BPAReportBuilder.js @@ -174,7 +174,7 @@ const BPAReportBuilder = () => { - + Load Report From 71945e1fe7ca315e39f2383374a6e3e0f4da58d6 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Thu, 7 Sep 2023 12:44:32 -0400 Subject: [PATCH 27/38] Add react-bootstrap --- package-lock.json | 310 +++++++++++++++++++++++++--------------------- package.json | 1 + 2 files changed, 173 insertions(+), 138 deletions(-) diff --git a/package-lock.json b/package-lock.json index acf2cd561d02..5af2243419af 100644 --- a/package-lock.json +++ b/package-lock.json @@ -42,6 +42,7 @@ "prop-types": "^15.7.2", "react": "^17.0.2", "react-app-polyfill": "^2.0.0", + "react-bootstrap": "^2.8.0", "react-copy-to-clipboard": "^5.0.4", "react-data-table-component": "^7.4.5", "react-datepicker": "^4.10.0", @@ -1776,10 +1777,11 @@ } }, "node_modules/@babel/runtime": { - "version": "7.17.2", - "license": "MIT", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.15.tgz", + "integrity": "sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA==", "dependencies": { - "regenerator-runtime": "^0.13.4" + "regenerator-runtime": "^0.14.0" }, "engines": { "node": ">=6.9.0" @@ -1797,6 +1799,11 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/runtime/node_modules/regenerator-runtime": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", + "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" + }, "node_modules/@babel/template": { "version": "7.16.7", "license": "MIT", @@ -3184,6 +3191,20 @@ "url": "https://opencollective.com/popperjs" } }, + "node_modules/@react-aria/ssr": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.7.1.tgz", + "integrity": "sha512-ovVPSD1WlRpZHt7GI9DqJrWG3OIYS+NXQ9y5HIewMJpSe+jPQmMQfyRmgX4EnvmxSlp0u04Wg/7oItcoSIb/RA==", + "dependencies": { + "@swc/helpers": "^0.5.0" + }, + "engines": { + "node": ">= 12" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + } + }, "node_modules/@react-icons/all-files": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/@react-icons/all-files/-/all-files-4.1.0.tgz", @@ -3221,20 +3242,10 @@ "@babel/runtime": "^7.9.2" } }, - "node_modules/@restart/context": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@restart/context/-/context-2.1.4.tgz", - "integrity": "sha512-INJYZQJP7g+IoDUh/475NlGiTeMfwTXUEr3tmRneckHIxNolGOW9CTq83S8cxq0CgJwwcMzMJFchxvlwe7Rk8Q==", - "peer": true, - "peerDependencies": { - "react": ">=16.3.2" - } - }, "node_modules/@restart/hooks": { "version": "0.4.11", "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.11.tgz", "integrity": "sha512-Ft/ncTULZN6ldGHiF/k5qt72O8JyRMOeg0tApvCni8LkoiEahO+z3TNxfXIVGy890YtWVDvJAl662dVJSJXvMw==", - "peer": true, "dependencies": { "dequal": "^2.0.3" }, @@ -3242,6 +3253,34 @@ "react": ">=16.8.0" } }, + "node_modules/@restart/ui": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/@restart/ui/-/ui-1.6.6.tgz", + "integrity": "sha512-eC3puKuWE1SRYbojWHXnvCNHGgf3uzHCb6JOhnF4OXPibOIPEkR1sqDSkL643ydigxwh+ruCa1CmYHlzk7ikKA==", + "dependencies": { + "@babel/runtime": "^7.21.0", + "@popperjs/core": "^2.11.6", + "@react-aria/ssr": "^3.5.0", + "@restart/hooks": "^0.4.9", + "@types/warning": "^3.0.0", + "dequal": "^2.0.3", + "dom-helpers": "^5.2.0", + "uncontrollable": "^8.0.1", + "warning": "^4.0.3" + }, + "peerDependencies": { + "react": ">=16.14.0", + "react-dom": ">=16.14.0" + } + }, + "node_modules/@restart/ui/node_modules/uncontrollable": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-8.0.4.tgz", + "integrity": "sha512-ulRWYWHvscPFc0QQXvyJjY6LIXU56f0h8pQFvhxiKk5V1fcI8gp9Ht9leVAhrVjzqMw0BgjspBINx9r6oyJUvQ==", + "peerDependencies": { + "react": ">=16.14.0" + } + }, "node_modules/@rjsf/bootstrap-4": { "version": "5.12.1", "resolved": "https://registry.npmjs.org/@rjsf/bootstrap-4/-/bootstrap-4-5.12.1.tgz", @@ -3651,6 +3690,14 @@ "url": "https://github.com/sponsors/gregberge" } }, + "node_modules/@swc/helpers": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.2.tgz", + "integrity": "sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==", + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@tootallnate/once": { "version": "1.1.2", "dev": true, @@ -3815,12 +3862,6 @@ "@types/node": "*" } }, - "node_modules/@types/invariant": { - "version": "2.2.35", - "resolved": "https://registry.npmjs.org/@types/invariant/-/invariant-2.2.35.tgz", - "integrity": "sha512-DxX1V9P8zdJPYQat1gHyY0xj3efl8gnMVjiM9iCY6y27lj+PoQWkgjt8jDqmovPqULkKVpKRg8J36iQiA+EtEg==", - "peer": true - }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.4", "dev": true, @@ -3938,8 +3979,9 @@ } }, "node_modules/@types/react-transition-group": { - "version": "4.4.4", - "license": "MIT", + "version": "4.4.6", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.6.tgz", + "integrity": "sha512-VnCdSxfcm08KjsJVQcfBmhEQAPnLB8G08hAxn39azX1qYBQ/5RVQuoHuKIcfKOdncuaUvEpFKFzEvbtIMsfVew==", "dependencies": { "@types/react": "*" } @@ -4003,8 +4045,7 @@ "node_modules/@types/warning": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.0.tgz", - "integrity": "sha512-t/Tvs5qR47OLOr+4E9ckN8AmP2Tf16gWq+/qA4iUGS/OOyHVO8wv2vjJuX8SNOUTJyWb+2t7wJm6cXILFnOROA==", - "peer": true + "integrity": "sha512-t/Tvs5qR47OLOr+4E9ckN8AmP2Tf16gWq+/qA4iUGS/OOyHVO8wv2vjJuX8SNOUTJyWb+2t7wJm6cXILFnOROA==" }, "node_modules/@types/ws": { "version": "8.5.2", @@ -6069,8 +6110,9 @@ "license": "MIT" }, "node_modules/classnames": { - "version": "2.3.1", - "license": "MIT" + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", + "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" }, "node_modules/clean-css": { "version": "5.2.4", @@ -7004,7 +7046,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "peer": true, "engines": { "node": ">=6" } @@ -14715,7 +14756,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz", "integrity": "sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==", - "peer": true, "dependencies": { "react-is": "^16.3.2", "warning": "^4.0.0" @@ -14727,8 +14767,7 @@ "node_modules/prop-types-extra/node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "peer": true + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "node_modules/prop-types/node_modules/react-is": { "version": "16.13.1", @@ -14927,32 +14966,32 @@ } }, "node_modules/react-bootstrap": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-1.6.7.tgz", - "integrity": "sha512-IzCYXuLSKDEjGFglbFWk0/iHmdhdcJzTmtS6lXxc0kaNFx2PFgrQf5jKnx5sarF2tiXh9Tgx3pSt3pdK7YwkMA==", - "peer": true, - "dependencies": { - "@babel/runtime": "^7.14.0", - "@restart/context": "^2.1.4", - "@restart/hooks": "^0.4.7", - "@types/invariant": "^2.2.33", - "@types/prop-types": "^15.7.3", - "@types/react": ">=16.14.8", - "@types/react-transition-group": "^4.4.1", - "@types/warning": "^3.0.0", - "classnames": "^2.3.1", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.8.0.tgz", + "integrity": "sha512-e/aNtxl0Z2ozrIaR82jr6Zz7ss9GSoaXpQaxmvtDUsTZIq/XalkduR/ZXP6vbQHz2T4syvjA+4FbtwELxxmpww==", + "dependencies": { + "@babel/runtime": "^7.21.0", + "@restart/hooks": "^0.4.9", + "@restart/ui": "^1.6.3", + "@types/react-transition-group": "^4.4.5", + "classnames": "^2.3.2", "dom-helpers": "^5.2.1", "invariant": "^2.2.4", - "prop-types": "^15.7.2", + "prop-types": "^15.8.1", "prop-types-extra": "^1.1.0", - "react-overlays": "^5.1.2", - "react-transition-group": "^4.4.1", + "react-transition-group": "^4.4.5", "uncontrollable": "^7.2.1", "warning": "^4.0.3" }, "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" + "@types/react": ">=16.14.8", + "react": ">=16.14.0", + "react-dom": ">=16.14.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, "node_modules/react-copy-to-clipboard": { @@ -15192,8 +15231,7 @@ "node_modules/react-lifecycles-compat": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", - "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==", - "peer": true + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" }, "node_modules/react-loading-skeleton": { "version": "3.1.0", @@ -15237,26 +15275,6 @@ "react-dom": "^15.5.x || ^16.x || ^17.x || ^18.x" } }, - "node_modules/react-overlays": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-5.2.1.tgz", - "integrity": "sha512-GLLSOLWr21CqtJn8geSwQfoJufdt3mfdsnIiQswouuQ2MMPns+ihZklxvsTDKD3cR2tF8ELbi5xUsvqVhR6WvA==", - "peer": true, - "dependencies": { - "@babel/runtime": "^7.13.8", - "@popperjs/core": "^2.11.6", - "@restart/hooks": "^0.4.7", - "@types/warning": "^3.0.0", - "dom-helpers": "^5.2.0", - "prop-types": "^15.7.2", - "uncontrollable": "^7.2.1", - "warning": "^4.0.3" - }, - "peerDependencies": { - "react": ">=16.3.0", - "react-dom": ">=16.3.0" - } - }, "node_modules/react-papaparse": { "version": "3.18.2", "license": "MIT", @@ -15534,8 +15552,9 @@ "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==" }, "node_modules/react-transition-group": { - "version": "4.4.2", - "license": "BSD-3-Clause", + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", "dependencies": { "@babel/runtime": "^7.5.5", "dom-helpers": "^5.0.1", @@ -17590,8 +17609,9 @@ } }, "node_modules/tslib": { - "version": "2.3.1", - "license": "0BSD" + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, "node_modules/tsutils": { "version": "3.21.0", @@ -17704,7 +17724,6 @@ "version": "7.2.1", "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.2.1.tgz", "integrity": "sha512-svtcfoTADIB0nT9nltgjujTi7BzVmwjZClOmskKu/E8FW9BXzg9os8OLr4f8Dlnk0rYWJIWr4wv9eKUXiQvQwQ==", - "peer": true, "dependencies": { "@babel/runtime": "^7.6.3", "@types/react": ">=16.9.11", @@ -19860,9 +19879,18 @@ } }, "@babel/runtime": { - "version": "7.17.2", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.15.tgz", + "integrity": "sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA==", "requires": { - "regenerator-runtime": "^0.13.4" + "regenerator-runtime": "^0.14.0" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", + "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" + } } }, "@babel/runtime-corejs3": { @@ -20759,6 +20787,14 @@ "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==" }, + "@react-aria/ssr": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.7.1.tgz", + "integrity": "sha512-ovVPSD1WlRpZHt7GI9DqJrWG3OIYS+NXQ9y5HIewMJpSe+jPQmMQfyRmgX4EnvmxSlp0u04Wg/7oItcoSIb/RA==", + "requires": { + "@swc/helpers": "^0.5.0" + } + }, "@react-icons/all-files": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/@react-icons/all-files/-/all-files-4.1.0.tgz", @@ -20782,22 +20818,38 @@ } } }, - "@restart/context": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@restart/context/-/context-2.1.4.tgz", - "integrity": "sha512-INJYZQJP7g+IoDUh/475NlGiTeMfwTXUEr3tmRneckHIxNolGOW9CTq83S8cxq0CgJwwcMzMJFchxvlwe7Rk8Q==", - "peer": true, - "requires": {} - }, "@restart/hooks": { "version": "0.4.11", "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.11.tgz", "integrity": "sha512-Ft/ncTULZN6ldGHiF/k5qt72O8JyRMOeg0tApvCni8LkoiEahO+z3TNxfXIVGy890YtWVDvJAl662dVJSJXvMw==", - "peer": true, "requires": { "dequal": "^2.0.3" } }, + "@restart/ui": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/@restart/ui/-/ui-1.6.6.tgz", + "integrity": "sha512-eC3puKuWE1SRYbojWHXnvCNHGgf3uzHCb6JOhnF4OXPibOIPEkR1sqDSkL643ydigxwh+ruCa1CmYHlzk7ikKA==", + "requires": { + "@babel/runtime": "^7.21.0", + "@popperjs/core": "^2.11.6", + "@react-aria/ssr": "^3.5.0", + "@restart/hooks": "^0.4.9", + "@types/warning": "^3.0.0", + "dequal": "^2.0.3", + "dom-helpers": "^5.2.0", + "uncontrollable": "^8.0.1", + "warning": "^4.0.3" + }, + "dependencies": { + "uncontrollable": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-8.0.4.tgz", + "integrity": "sha512-ulRWYWHvscPFc0QQXvyJjY6LIXU56f0h8pQFvhxiKk5V1fcI8gp9Ht9leVAhrVjzqMw0BgjspBINx9r6oyJUvQ==", + "requires": {} + } + } + }, "@rjsf/bootstrap-4": { "version": "5.12.1", "resolved": "https://registry.npmjs.org/@rjsf/bootstrap-4/-/bootstrap-4-5.12.1.tgz", @@ -21032,6 +21084,14 @@ "loader-utils": "^2.0.0" } }, + "@swc/helpers": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.2.tgz", + "integrity": "sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==", + "requires": { + "tslib": "^2.4.0" + } + }, "@tootallnate/once": { "version": "1.1.2", "dev": true @@ -21170,12 +21230,6 @@ "@types/node": "*" } }, - "@types/invariant": { - "version": "2.2.35", - "resolved": "https://registry.npmjs.org/@types/invariant/-/invariant-2.2.35.tgz", - "integrity": "sha512-DxX1V9P8zdJPYQat1gHyY0xj3efl8gnMVjiM9iCY6y27lj+PoQWkgjt8jDqmovPqULkKVpKRg8J36iQiA+EtEg==", - "peer": true - }, "@types/istanbul-lib-coverage": { "version": "2.0.4", "dev": true @@ -21273,7 +21327,9 @@ } }, "@types/react-transition-group": { - "version": "4.4.4", + "version": "4.4.6", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.6.tgz", + "integrity": "sha512-VnCdSxfcm08KjsJVQcfBmhEQAPnLB8G08hAxn39azX1qYBQ/5RVQuoHuKIcfKOdncuaUvEpFKFzEvbtIMsfVew==", "requires": { "@types/react": "*" } @@ -21328,8 +21384,7 @@ "@types/warning": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.0.tgz", - "integrity": "sha512-t/Tvs5qR47OLOr+4E9ckN8AmP2Tf16gWq+/qA4iUGS/OOyHVO8wv2vjJuX8SNOUTJyWb+2t7wJm6cXILFnOROA==", - "peer": true + "integrity": "sha512-t/Tvs5qR47OLOr+4E9ckN8AmP2Tf16gWq+/qA4iUGS/OOyHVO8wv2vjJuX8SNOUTJyWb+2t7wJm6cXILFnOROA==" }, "@types/ws": { "version": "8.5.2", @@ -22584,7 +22639,9 @@ "dev": true }, "classnames": { - "version": "2.3.1" + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", + "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" }, "clean-css": { "version": "5.2.4", @@ -23174,8 +23231,7 @@ "dequal": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "peer": true + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==" }, "desandro-matches-selector": { "version": "2.0.2" @@ -27917,7 +27973,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz", "integrity": "sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==", - "peer": true, "requires": { "react-is": "^16.3.2", "warning": "^4.0.0" @@ -27926,8 +27981,7 @@ "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "peer": true + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" } } }, @@ -28048,26 +28102,20 @@ } }, "react-bootstrap": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-1.6.7.tgz", - "integrity": "sha512-IzCYXuLSKDEjGFglbFWk0/iHmdhdcJzTmtS6lXxc0kaNFx2PFgrQf5jKnx5sarF2tiXh9Tgx3pSt3pdK7YwkMA==", - "peer": true, - "requires": { - "@babel/runtime": "^7.14.0", - "@restart/context": "^2.1.4", - "@restart/hooks": "^0.4.7", - "@types/invariant": "^2.2.33", - "@types/prop-types": "^15.7.3", - "@types/react": ">=16.14.8", - "@types/react-transition-group": "^4.4.1", - "@types/warning": "^3.0.0", - "classnames": "^2.3.1", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.8.0.tgz", + "integrity": "sha512-e/aNtxl0Z2ozrIaR82jr6Zz7ss9GSoaXpQaxmvtDUsTZIq/XalkduR/ZXP6vbQHz2T4syvjA+4FbtwELxxmpww==", + "requires": { + "@babel/runtime": "^7.21.0", + "@restart/hooks": "^0.4.9", + "@restart/ui": "^1.6.3", + "@types/react-transition-group": "^4.4.5", + "classnames": "^2.3.2", "dom-helpers": "^5.2.1", "invariant": "^2.2.4", - "prop-types": "^15.7.2", + "prop-types": "^15.8.1", "prop-types-extra": "^1.1.0", - "react-overlays": "^5.1.2", - "react-transition-group": "^4.4.1", + "react-transition-group": "^4.4.5", "uncontrollable": "^7.2.1", "warning": "^4.0.3" } @@ -28225,8 +28273,7 @@ "react-lifecycles-compat": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", - "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==", - "peer": true + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" }, "react-loading-skeleton": { "version": "3.1.0", @@ -28253,22 +28300,6 @@ "integrity": "sha512-NMXGa223OnsrGVp5dJHkuKxQ4czdLmXSp5jSV9OqiCky9LOpPATn3vLldc+q5fK3gKbEHvr7J1u0yhBh/xYkpA==", "requires": {} }, - "react-overlays": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-5.2.1.tgz", - "integrity": "sha512-GLLSOLWr21CqtJn8geSwQfoJufdt3mfdsnIiQswouuQ2MMPns+ihZklxvsTDKD3cR2tF8ELbi5xUsvqVhR6WvA==", - "peer": true, - "requires": { - "@babel/runtime": "^7.13.8", - "@popperjs/core": "^2.11.6", - "@restart/hooks": "^0.4.7", - "@types/warning": "^3.0.0", - "dom-helpers": "^5.2.0", - "prop-types": "^15.7.2", - "uncontrollable": "^7.2.1", - "warning": "^4.0.3" - } - }, "react-papaparse": { "version": "3.18.2", "requires": { @@ -28456,7 +28487,9 @@ } }, "react-transition-group": { - "version": "4.4.2", + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", "requires": { "@babel/runtime": "^7.5.5", "dom-helpers": "^5.0.1", @@ -29817,7 +29850,9 @@ } }, "tslib": { - "version": "2.3.1" + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, "tsutils": { "version": "3.21.0", @@ -29885,7 +29920,6 @@ "version": "7.2.1", "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.2.1.tgz", "integrity": "sha512-svtcfoTADIB0nT9nltgjujTi7BzVmwjZClOmskKu/E8FW9BXzg9os8OLr4f8Dlnk0rYWJIWr4wv9eKUXiQvQwQ==", - "peer": true, "requires": { "@babel/runtime": "^7.6.3", "@types/react": ">=16.9.11", diff --git a/package.json b/package.json index 88f3735fcc05..3a1b4acfb7c6 100644 --- a/package.json +++ b/package.json @@ -61,6 +61,7 @@ "prop-types": "^15.7.2", "react": "^17.0.2", "react-app-polyfill": "^2.0.0", + "react-bootstrap": "^2.8.0", "react-copy-to-clipboard": "^5.0.4", "react-data-table-component": "^7.4.5", "react-datepicker": "^4.10.0", From 3b067433e399d00cdb32f5d95c39a98fefdf585c Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Fri, 8 Sep 2023 01:06:37 +0200 Subject: [PATCH 28/38] sharepoint url stuff --- src/views/identity/administration/Users.js | 30 ++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/views/identity/administration/Users.js b/src/views/identity/administration/Users.js index da5db287e270..415274ae6406 100644 --- a/src/views/identity/administration/Users.js +++ b/src/views/identity/administration/Users.js @@ -113,6 +113,21 @@ const Offcanvas = (row, rowIndex, formatExtraData) => { modalUrl: `/api/ExecConvertToSharedMailbox?TenantFilter=${tenant.defaultDomainName}&ID=${row.userPrincipalName}`, modalMessage: 'Are you sure you want to convert this user to a shared mailbox?', }, + { + label: 'Add OneDrive Shortcut', + color: 'info', + modal: true, + modalType: 'POST', + modalBody: { + username: row.userPrincipalName, + userid: row.id, + TenantFilter: tenant.defaultDomainName, + message: row.message, + }, + modalUrl: `/api/ExecOneDriveShortCut`, + modalInput: true, + modalMessage: 'Enter a SharePoint URL to create a OneDrive shortcut for', + }, { label: 'Enable Online Archive', color: 'info', @@ -416,6 +431,21 @@ const Users = (row) => { modalUrl: `/api/ExecRevokeSessions?Enable=true&TenantFilter=!Tenant&ID=!userPrincipalName`, modalMessage: 'Are you sure you want to revoke all sessions for these users?', }, + { + label: 'Create OneDrive Shortcut', + color: 'info', + modal: true, + modalType: 'POST', + modalBody: { + username: '!userPrincipalName', + userid: '!id', + TenantFilter: tenant.defaultDomainName, + }, + modalUrl: `/api/ExecOneDriveShortCut`, + modalInput: true, + modalMessage: + 'Enter a SharePoint URL to create a OneDrive shortcut for and press continue.', + }, { label: 'Set Out of Office', color: 'info', From b0bb32ff353d7c415d6ec275648be2ea3fb7d11f Mon Sep 17 00:00:00 2001 From: John Duprey Date: Thu, 7 Sep 2023 20:00:44 -0400 Subject: [PATCH 29/38] Add stretched-link to collapses --- src/views/cipp/AppApproval.js | 7 ++++++- src/views/cipp/Logs.js | 7 ++++++- src/views/email-exchange/reports/MessageTrace.js | 7 ++++++- src/views/identity/reports/SignIns.js | 7 ++++++- src/views/tenant/administration/GraphExplorer.js | 7 ++++++- src/views/tenant/standards/BPAReportBuilder.js | 9 +++++++-- src/views/tenant/standards/BestPracticeAnalyser.js | 7 ++++++- 7 files changed, 43 insertions(+), 8 deletions(-) diff --git a/src/views/cipp/AppApproval.js b/src/views/cipp/AppApproval.js index 9c957db0707b..4c2752163e6b 100644 --- a/src/views/cipp/AppApproval.js +++ b/src/views/cipp/AppApproval.js @@ -112,7 +112,12 @@ const GraphExplorer = () => { Approval Settings - setVisibleA(!visibleA)}> + setVisibleA(!visibleA)} + > diff --git a/src/views/cipp/Logs.js b/src/views/cipp/Logs.js index e7733a152fff..6371ffef2a45 100644 --- a/src/views/cipp/Logs.js +++ b/src/views/cipp/Logs.js @@ -126,7 +126,12 @@ const Logs = () => { Logbook Settings - setVisibleA(!visibleA)}> + setVisibleA(!visibleA)} + > diff --git a/src/views/email-exchange/reports/MessageTrace.js b/src/views/email-exchange/reports/MessageTrace.js index c3ef99d51d4f..6eab5824f3f6 100644 --- a/src/views/email-exchange/reports/MessageTrace.js +++ b/src/views/email-exchange/reports/MessageTrace.js @@ -95,7 +95,12 @@ const MessageTrace = () => { Message Trace Settings - setVisibleA(!visibleA)}> + setVisibleA(!visibleA)} + > diff --git a/src/views/identity/reports/SignIns.js b/src/views/identity/reports/SignIns.js index 7e6ec7fe2488..926fe7570c9c 100644 --- a/src/views/identity/reports/SignIns.js +++ b/src/views/identity/reports/SignIns.js @@ -129,7 +129,12 @@ const SignInsReport = () => { Sign In log Settings - setVisibleA(!visibleA)}> + setVisibleA(!visibleA)} + > diff --git a/src/views/tenant/administration/GraphExplorer.js b/src/views/tenant/administration/GraphExplorer.js index 55d6c11c7af4..9c02146e679a 100644 --- a/src/views/tenant/administration/GraphExplorer.js +++ b/src/views/tenant/administration/GraphExplorer.js @@ -109,7 +109,12 @@ const GraphExplorer = () => { Report Settings - setVisibleA(!visibleA)}> + setVisibleA(!visibleA)} + > diff --git a/src/views/tenant/standards/BPAReportBuilder.js b/src/views/tenant/standards/BPAReportBuilder.js index 46a4766bd25c..a16ac2ca7a3a 100644 --- a/src/views/tenant/standards/BPAReportBuilder.js +++ b/src/views/tenant/standards/BPAReportBuilder.js @@ -141,7 +141,12 @@ const BPAReportBuilder = () => { Report Settings - setVisibleA(!visibleA)}> + setVisibleA(!visibleA)} + > @@ -174,7 +179,7 @@ const BPAReportBuilder = () => { - + Load Report diff --git a/src/views/tenant/standards/BestPracticeAnalyser.js b/src/views/tenant/standards/BestPracticeAnalyser.js index 025095e1a48c..086e53f2e925 100644 --- a/src/views/tenant/standards/BestPracticeAnalyser.js +++ b/src/views/tenant/standards/BestPracticeAnalyser.js @@ -226,7 +226,12 @@ const BestPracticeAnalyser = () => { Report Settings - setVisibleA(!visibleA)}> + setVisibleA(!visibleA)} + > From 0be3128a13549441a81a3a037c2f66ea9bf8934d Mon Sep 17 00:00:00 2001 From: John Duprey Date: Thu, 7 Sep 2023 20:11:41 -0400 Subject: [PATCH 30/38] Update BPAReportBuilder.js --- src/views/tenant/standards/BPAReportBuilder.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/tenant/standards/BPAReportBuilder.js b/src/views/tenant/standards/BPAReportBuilder.js index a16ac2ca7a3a..e837cb8715ce 100644 --- a/src/views/tenant/standards/BPAReportBuilder.js +++ b/src/views/tenant/standards/BPAReportBuilder.js @@ -179,7 +179,7 @@ const BPAReportBuilder = () => { - + Load Report From e6602ed3ea4eb830179d75ea8bafaf1ee68fba90 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Thu, 7 Sep 2023 20:34:06 -0400 Subject: [PATCH 31/38] Fix clickable areas --- src/views/cipp/AppApproval.js | 9 ++++++--- src/views/cipp/Logs.js | 9 ++++++--- src/views/email-exchange/reports/MessageTrace.js | 9 ++++++--- src/views/identity/reports/SignIns.js | 11 +++++++---- src/views/tenant/administration/GraphExplorer.js | 9 ++++++--- src/views/tenant/standards/BPAReportBuilder.js | 9 ++++++--- src/views/tenant/standards/BestPracticeAnalyser.js | 9 ++++++--- 7 files changed, 43 insertions(+), 22 deletions(-) diff --git a/src/views/cipp/AppApproval.js b/src/views/cipp/AppApproval.js index 4c2752163e6b..66d88991a92b 100644 --- a/src/views/cipp/AppApproval.js +++ b/src/views/cipp/AppApproval.js @@ -122,7 +122,10 @@ const GraphExplorer = () => { - + + + + { }} /> - - + +
    diff --git a/src/views/cipp/Logs.js b/src/views/cipp/Logs.js index 6371ffef2a45..b1e93e85d8c8 100644 --- a/src/views/cipp/Logs.js +++ b/src/views/cipp/Logs.js @@ -136,7 +136,10 @@ const Logs = () => {
    - + + + + { }} /> - - + +

    diff --git a/src/views/email-exchange/reports/MessageTrace.js b/src/views/email-exchange/reports/MessageTrace.js index 6eab5824f3f6..253aa6821beb 100644 --- a/src/views/email-exchange/reports/MessageTrace.js +++ b/src/views/email-exchange/reports/MessageTrace.js @@ -105,7 +105,10 @@ const MessageTrace = () => {
    - + + + + { }} /> - - + +

    diff --git a/src/views/identity/reports/SignIns.js b/src/views/identity/reports/SignIns.js index 926fe7570c9c..aea60797072b 100644 --- a/src/views/identity/reports/SignIns.js +++ b/src/views/identity/reports/SignIns.js @@ -125,7 +125,7 @@ const SignInsReport = () => { <> - + Sign In log Settings @@ -139,7 +139,10 @@ const SignInsReport = () => { - + + + + { }} /> - - + +
    diff --git a/src/views/tenant/administration/GraphExplorer.js b/src/views/tenant/administration/GraphExplorer.js index 9c02146e679a..4bb325b4f0ff 100644 --- a/src/views/tenant/administration/GraphExplorer.js +++ b/src/views/tenant/administration/GraphExplorer.js @@ -119,7 +119,10 @@ const GraphExplorer = () => { - + + + + { }} /> - - + +

    diff --git a/src/views/tenant/standards/BPAReportBuilder.js b/src/views/tenant/standards/BPAReportBuilder.js index e837cb8715ce..b649a86556d6 100644 --- a/src/views/tenant/standards/BPAReportBuilder.js +++ b/src/views/tenant/standards/BPAReportBuilder.js @@ -151,7 +151,10 @@ const BPAReportBuilder = () => { - + + + + @@ -218,8 +221,8 @@ const BPAReportBuilder = () => { - - + +
    diff --git a/src/views/tenant/standards/BestPracticeAnalyser.js b/src/views/tenant/standards/BestPracticeAnalyser.js index 086e53f2e925..a18f42909746 100644 --- a/src/views/tenant/standards/BestPracticeAnalyser.js +++ b/src/views/tenant/standards/BestPracticeAnalyser.js @@ -236,7 +236,10 @@ const BestPracticeAnalyser = () => { - + + + + { }} /> - - + +
    From 495193468e76ac482c8e9809f5f427a166752a5d Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Fri, 8 Sep 2023 15:41:58 +0200 Subject: [PATCH 32/38] added dropdown to OffCanvas buttons. --- .../utilities/CippActionsOffcanvas.js | 75 +++++++++++++++++-- src/views/identity/administration/Users.js | 8 +- 2 files changed, 76 insertions(+), 7 deletions(-) diff --git a/src/components/utilities/CippActionsOffcanvas.js b/src/components/utilities/CippActionsOffcanvas.js index 1bcf1773251f..371276f49375 100644 --- a/src/components/utilities/CippActionsOffcanvas.js +++ b/src/components/utilities/CippActionsOffcanvas.js @@ -8,6 +8,7 @@ import { CCardText, CCardTitle, CFormInput, + CFormSelect, CListGroup, CListGroupItem, COffcanvasTitle, @@ -20,17 +21,60 @@ import { useLazyGenericGetRequestQuery, useLazyGenericPostRequestQuery } from 's import { Link, useNavigate } from 'react-router-dom' import { stringCamelCase } from 'src/components/utilities/CippCamelCase' import ReactTimeAgo from 'react-time-ago' +import { useEffect } from 'react' +import { useState } from 'react' export default function CippActionsOffcanvas(props) { const inputRef = useRef('') const [genericGetRequest, getResults] = useLazyGenericGetRequestQuery() const [genericPostRequest, postResults] = useLazyGenericPostRequestQuery() + const [getDrowndownInfo, dropDownInfo] = useLazyGenericGetRequestQuery() + const [modalContent, setModalContent] = useState(null) + + useEffect(() => { + if (dropDownInfo.isFetching) { + handleModal( + , + modalContent.modalUrl, + modalContent.modalType, + modalContent.modalBody, + modalContent.modalInput, + modalContent.modalDropdown, + ) + } + if (dropDownInfo.isSuccess) { + handleModal( + modalContent.modalMessage, + modalContent.modalUrl, + modalContent.modalType, + modalContent.modalBody, + modalContent.modalInput, + modalContent.modalDropdown, + ) + } else if (dropDownInfo.isError) { + handleModal( + 'Error connecting to the API.', + modalContent.modalUrl, + modalContent.modalType, + modalContent.modalBody, + modalContent.modalInput, + modalContent.modalDropdown, + ) + } + }, [dropDownInfo]) const handleLink = useNavigate() const handleExternalLink = (link) => { window.open(link, '_blank') } - const handleModal = (modalMessage, modalUrl, modalType = 'GET', modalBody, modalInput) => { + const handleModal = ( + modalMessage, + modalUrl, + modalType = 'GET', + modalBody, + modalInput, + modalDropdown, + ) => { if (modalType === 'GET') { ModalService.confirm({ body: ( @@ -43,6 +87,7 @@ export default function CippActionsOffcanvas(props) { }) } else { ModalService.confirm({ + key: modalContent, body: (
    {modalInput && ( @@ -50,6 +95,19 @@ export default function CippActionsOffcanvas(props) {
    )} + {modalDropdown && ( +
    + {dropDownInfo.isSuccess && ( + ({ + value: data[modalDropdown.valueField], + label: data[modalDropdown.labelField], + }))} + /> + )} +
    + )}
    {modalMessage}
    ), @@ -72,6 +130,7 @@ export default function CippActionsOffcanvas(props) { modalType, modalBody, modalInput, + modalDropdown, ) => { if (link) { if (external) { @@ -80,7 +139,12 @@ export default function CippActionsOffcanvas(props) { handleLink(link) } } else if (modal) { - handleModal(modalMessage, modalUrl, modalType, modalBody, modalInput) + if (modalDropdown) { + getDrowndownInfo({ path: modalDropdown.url }) + } + setModalContent({ modalMessage, modalUrl, modalType, modalBody, modalInput, modalDropdown }) + + handleModal(modalMessage, modalUrl, modalType, modalBody, modalInput, modalDropdown) } } @@ -112,9 +176,7 @@ export default function CippActionsOffcanvas(props) { )) - } catch (error) { - console.error('An error occurred building OCanvas actions' + error.toString()) - } + } catch (error) {} const extendedInfoContent = let actionsContent @@ -134,6 +196,7 @@ export default function CippActionsOffcanvas(props) { action.modalType, action.modalBody, action.modalInput, + action.modalDropdown, ) } key={index} @@ -232,6 +295,7 @@ const CippActionsOffcanvasPropTypes = { modal: PropTypes.bool, modalUrl: PropTypes.string, modalBody: PropTypes.object, + modalDropdown: PropTypes.object, modalType: PropTypes.string, modalInput: PropTypes.bool, modalMessage: PropTypes.string, @@ -252,6 +316,7 @@ const CippActionsOffcanvasPropTypes = { modalType: PropTypes.string, modalInput: PropTypes.bool, modalMessage: PropTypes.string, + modalDropdown: PropTypes.object, external: PropTypes.bool, }), ), diff --git a/src/views/identity/administration/Users.js b/src/views/identity/administration/Users.js index 415274ae6406..4dac8d415cf2 100644 --- a/src/views/identity/administration/Users.js +++ b/src/views/identity/administration/Users.js @@ -125,8 +125,12 @@ const Offcanvas = (row, rowIndex, formatExtraData) => { message: row.message, }, modalUrl: `/api/ExecOneDriveShortCut`, - modalInput: true, - modalMessage: 'Enter a SharePoint URL to create a OneDrive shortcut for', + modalDropdown: { + url: `/api/listSites?TenantFilter=${tenant.defaultDomainName}&type=SharePointSiteUsage`, + labelField: 'URL', + valueField: 'URL', + }, + modalMessage: 'Select the sharepoint site to create a shortcut for', }, { label: 'Enable Online Archive', From 817eaf67d29028bb2fd5174f4542ffa267e2694f Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Fri, 8 Sep 2023 16:00:37 +0200 Subject: [PATCH 33/38] added dropdown to other locations too --- src/components/tables/CippTable.js | 210 ++++++++++++++------- src/views/identity/administration/Users.js | 8 +- 2 files changed, 146 insertions(+), 72 deletions(-) diff --git a/src/components/tables/CippTable.js b/src/components/tables/CippTable.js index 4cdad5b0c56f..fa11d257ea78 100644 --- a/src/components/tables/CippTable.js +++ b/src/components/tables/CippTable.js @@ -14,6 +14,7 @@ import { CModalBody, CModalTitle, CCallout, + CFormSelect, } from '@coreui/react' import DataTable, { createTheme } from 'react-data-table-component' import PropTypes from 'prop-types' @@ -24,6 +25,7 @@ import { cellGenericFormatter } from './CellGenericFormat' import { ModalService } from '../utilities' import { useLazyGenericGetRequestQuery, useLazyGenericPostRequestQuery } from 'src/store/api/app' import { ConfirmModal } from '../utilities/SharedModal' +import { useState } from 'react' const FilterComponent = ({ filterText, @@ -156,6 +158,40 @@ export default function CippTable({ const [selectedRows, setSelectedRows] = React.useState(false) const [genericGetRequest, getResults] = useLazyGenericGetRequestQuery() const [genericPostRequest, postResults] = useLazyGenericPostRequestQuery() + const [getDrowndownInfo, dropDownInfo] = useLazyGenericGetRequestQuery() + const [modalContent, setModalContent] = useState(null) + useEffect(() => { + if (dropDownInfo.isFetching) { + handleModal( + , + modalContent.item.modalUrl, + modalContent.item.modalType, + modalContent.item.modalBody, + modalContent.item.modalInput, + modalContent.item.modalDropdown, + ) + } + if (dropDownInfo.isSuccess) { + console.log(modalContent) + handleModal( + modalContent.item.modalMessage, + modalContent.item.modalUrl, + modalContent.item.modalType, + modalContent.item.modalBody, + modalContent.item.modalInput, + modalContent.item.modalDropdown, + ) + } else if (dropDownInfo.isError) { + handleModal( + 'Error connecting to the API.', + modalContent.item.modalUrl, + modalContent.item.modalType, + modalContent.item.modalBody, + modalContent.item.modalInput, + modalContent.item.modalDropdown, + ) + } + }, [dropDownInfo]) const handleSelectedChange = ({ selectedRows }) => { setSelectedRows(selectedRows) if (selectedRows.length < 1) { @@ -229,84 +265,118 @@ export default function CippTable({ }, }, } - const subHeaderComponentMemo = React.useMemo(() => { - const handleClear = () => { - if (filterText) { - setResetPaginationToggle(!resetPaginationToggle) - setFilterText('') - } - } - const handleModal = (modalMessage, modalUrl, modalType = 'GET', modalBody, modalInput) => { - if (modalType === 'GET') { - ModalService.confirm({ - body: ( -
    -
    {modalMessage}
    -
    - ), - title: 'Confirm', - onConfirm: async () => { - const resultsarr = [] - for (const row of selectedRows) { - setLoopRunning(true) - const urlParams = new URLSearchParams(modalUrl.split('?')[1]) - for (let [paramName, paramValue] of urlParams.entries()) { - if (paramValue.startsWith('!')) { - urlParams.set(paramName, row[paramValue.replace('!', '')]) - } + const handleModal = ( + modalMessage, + modalUrl, + modalType = 'GET', + modalBody, + modalInput, + modalDropdown, + ) => { + if (modalType === 'GET') { + ModalService.confirm({ + body: ( +
    +
    {modalMessage}
    +
    + ), + title: 'Confirm', + onConfirm: async () => { + const resultsarr = [] + for (const row of selectedRows) { + setLoopRunning(true) + const urlParams = new URLSearchParams(modalUrl.split('?')[1]) + for (let [paramName, paramValue] of urlParams.entries()) { + if (paramValue.startsWith('!')) { + urlParams.set(paramName, row[paramValue.replace('!', '')]) } - const NewModalUrl = `${modalUrl.split('?')[0]}?${urlParams.toString()}` - const results = await genericGetRequest({ path: NewModalUrl, refreshParam: row.id }) - resultsarr.push(results) - setMassResults(resultsarr) } - setLoopRunning(false) - }, - }) - } else { - ModalService.confirm({ - body: ( -
    - {modalInput && ( -
    - -
    - )} -
    {modalMessage}
    -
    - ), - title: 'Confirm', - onConfirm: async () => { - const resultsarr = [] - for (const row of selectedRows) { - setLoopRunning(true) - const urlParams = new URLSearchParams(modalUrl.split('?')[1]) - for (let [paramName, paramValue] of urlParams.entries()) { - if (paramValue.toString().startsWith('!')) { - urlParams.set(paramName, row[paramValue.replace('!', '')]) - } + const NewModalUrl = `${modalUrl.split('?')[0]}?${urlParams.toString()}` + const results = await genericGetRequest({ path: NewModalUrl, refreshParam: row.id }) + resultsarr.push(results) + setMassResults(resultsarr) + } + setLoopRunning(false) + }, + }) + } else { + ModalService.confirm({ + body: ( +
    + {modalInput && ( +
    + +
    + )} + {modalDropdown && ( +
    + {dropDownInfo.isSuccess && ( + ({ + value: data[modalDropdown.valueField], + label: data[modalDropdown.labelField], + }))} + /> + )} +
    + )} +
    {modalMessage}
    +
    + ), + title: 'Confirm', + onConfirm: async () => { + const resultsarr = [] + for (const row of selectedRows) { + setLoopRunning(true) + const urlParams = new URLSearchParams(modalUrl.split('?')[1]) + for (let [paramName, paramValue] of urlParams.entries()) { + if (paramValue.toString().startsWith('!')) { + urlParams.set(paramName, row[paramValue.replace('!', '')]) } - const newModalBody = {} - for (let [objName, objValue] of Object.entries(modalBody)) { - if (objValue.toString().startsWith('!')) { - newModalBody[objName] = row[objValue.replace('!', '')] - } + } + const newModalBody = {} + for (let [objName, objValue] of Object.entries(modalBody)) { + if (objValue.toString().startsWith('!')) { + newModalBody[objName] = row[objValue.replace('!', '')] } - const NewModalUrl = `${modalUrl.split('?')[0]}?${urlParams.toString()}` - const results = await genericPostRequest({ - path: NewModalUrl, - values: { ...modalBody, ...newModalBody, ...{ input: inputRef.current.value } }, - }) - resultsarr.push(results) - setMassResults(resultsarr) } - setLoopRunning(false) - }, - }) + const NewModalUrl = `${modalUrl.split('?')[0]}?${urlParams.toString()}` + const results = await genericPostRequest({ + path: NewModalUrl, + values: { ...modalBody, ...newModalBody, ...{ input: inputRef.current.value } }, + }) + resultsarr.push(results) + setMassResults(resultsarr) + } + setLoopRunning(false) + }, + }) + } + } + const subHeaderComponentMemo = React.useMemo(() => { + const handleClear = () => { + if (filterText) { + setResetPaginationToggle(!resetPaginationToggle) + setFilterText('') } } + const executeselectedAction = (item) => { - handleModal(item.modalMessage, item.modalUrl, item.modalType, item.modalBody, item.modalInput) + setModalContent({ + item, + }) + if (item.modalDropdown) { + getDrowndownInfo({ path: item.modalDropdown.url }) + } + handleModal( + item.modalMessage, + item.modalUrl, + item.modalType, + item.modalBody, + item.modalInput, + item.modalDropdown, + ) } const defaultActions = [] const dataKeys = () => { diff --git a/src/views/identity/administration/Users.js b/src/views/identity/administration/Users.js index 4dac8d415cf2..4f64168fa419 100644 --- a/src/views/identity/administration/Users.js +++ b/src/views/identity/administration/Users.js @@ -446,9 +446,13 @@ const Users = (row) => { TenantFilter: tenant.defaultDomainName, }, modalUrl: `/api/ExecOneDriveShortCut`, - modalInput: true, modalMessage: - 'Enter a SharePoint URL to create a OneDrive shortcut for and press continue.', + 'Select a SharePoint URL to create a OneDrive shortcut for and press continue.', + modalDropdown: { + url: `/api/listSites?TenantFilter=${tenant.defaultDomainName}&type=SharePointSiteUsage`, + labelField: 'URL', + valueField: 'URL', + }, }, { label: 'Set Out of Office', From 30a4fb3c33d61867a8e2e6af548960407caa7143 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Fri, 8 Sep 2023 16:52:36 +0200 Subject: [PATCH 34/38] latest release --- public/version_latest.txt | 2 +- version_latest.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/public/version_latest.txt b/public/version_latest.txt index 99eba4de9311..ef8d7569d677 100644 --- a/public/version_latest.txt +++ b/public/version_latest.txt @@ -1 +1 @@ -4.1.0 \ No newline at end of file +4.2.0 \ No newline at end of file diff --git a/version_latest.txt b/version_latest.txt index 99eba4de9311..ef8d7569d677 100644 --- a/version_latest.txt +++ b/version_latest.txt @@ -1 +1 @@ -4.1.0 \ No newline at end of file +4.2.0 \ No newline at end of file From 5f3fc7461f5fee8abb6ebc046f6e025cde9890cf Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Fri, 8 Sep 2023 16:58:14 +0200 Subject: [PATCH 35/38] text changes --- src/views/tenant/administration/AlertWizard.js | 10 ++++++++-- src/views/tenant/administration/ListAlertsQueue.js | 5 +++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/views/tenant/administration/AlertWizard.js b/src/views/tenant/administration/AlertWizard.js index 40a310af660d..b0d8a9dbdfbf 100644 --- a/src/views/tenant/administration/AlertWizard.js +++ b/src/views/tenant/administration/AlertWizard.js @@ -95,8 +95,8 @@ const AlertWizard = () => {

    - These alerts will be sent to the user or webhook configured in the CIPP notification - settings menu. + Alerts setup on this page will be sent to webhook configured in CIPPs settings, and be + delivered as messages

    { Microsoft sends them to CIPP. These alerts generate a ticket, email or webhook message per alert, with more information about the alert.

    + +

    + "Alerts setup on this page will be sent to the webhook configured in CIPPs settings, and + be delivered as raw json information. Warning: Teams, Slack, and Discord do not support + receiving raw json messages" +

    { const [ExecuteGetRequest, getResults] = useLazyGenericGetRequestQuery() @@ -75,24 +76,28 @@ const ListAlertsQueue = () => { selector: (row) => row['Expiration'], sortable: true, exportSelector: 'Expiration', + cell: (row) => CellTip(row['Expiration']), }, { name: 'Monitored Resource', selector: (row) => row['Resource'], sortable: true, exportSelector: 'Resource', + cell: (row) => CellTip(row['Resource']), }, { name: 'Monitored Actions', selector: (row) => row['Operations'], sortable: true, exportSelector: 'Operations', + cell: (row) => CellTip(row['Operations']), }, { name: 'Webhook URL', selector: (row) => row['WebhookNotificationUrl'], sortable: true, exportSelector: 'WebhookNotificationUrl', + cell: (row) => CellTip(row['WebhookNotificationUrl']), }, { name: 'Actions', From 81979afe45c1f91d33e7a46c3eef1239882a543d Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Fri, 8 Sep 2023 17:32:58 +0200 Subject: [PATCH 36/38] fixed package --- package-lock.json | 214 ++++++++++++++++++++-------------------------- package.json | 2 +- 2 files changed, 94 insertions(+), 122 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5af2243419af..2db89fb7513f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -42,7 +42,7 @@ "prop-types": "^15.7.2", "react": "^17.0.2", "react-app-polyfill": "^2.0.0", - "react-bootstrap": "^2.8.0", + "react-bootstrap": "^1.6.5", "react-copy-to-clipboard": "^5.0.4", "react-data-table-component": "^7.4.5", "react-datepicker": "^4.10.0", @@ -3191,20 +3191,6 @@ "url": "https://opencollective.com/popperjs" } }, - "node_modules/@react-aria/ssr": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.7.1.tgz", - "integrity": "sha512-ovVPSD1WlRpZHt7GI9DqJrWG3OIYS+NXQ9y5HIewMJpSe+jPQmMQfyRmgX4EnvmxSlp0u04Wg/7oItcoSIb/RA==", - "dependencies": { - "@swc/helpers": "^0.5.0" - }, - "engines": { - "node": ">= 12" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" - } - }, "node_modules/@react-icons/all-files": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/@react-icons/all-files/-/all-files-4.1.0.tgz", @@ -3242,6 +3228,14 @@ "@babel/runtime": "^7.9.2" } }, + "node_modules/@restart/context": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@restart/context/-/context-2.1.4.tgz", + "integrity": "sha512-INJYZQJP7g+IoDUh/475NlGiTeMfwTXUEr3tmRneckHIxNolGOW9CTq83S8cxq0CgJwwcMzMJFchxvlwe7Rk8Q==", + "peerDependencies": { + "react": ">=16.3.2" + } + }, "node_modules/@restart/hooks": { "version": "0.4.11", "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.11.tgz", @@ -3253,34 +3247,6 @@ "react": ">=16.8.0" } }, - "node_modules/@restart/ui": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/@restart/ui/-/ui-1.6.6.tgz", - "integrity": "sha512-eC3puKuWE1SRYbojWHXnvCNHGgf3uzHCb6JOhnF4OXPibOIPEkR1sqDSkL643ydigxwh+ruCa1CmYHlzk7ikKA==", - "dependencies": { - "@babel/runtime": "^7.21.0", - "@popperjs/core": "^2.11.6", - "@react-aria/ssr": "^3.5.0", - "@restart/hooks": "^0.4.9", - "@types/warning": "^3.0.0", - "dequal": "^2.0.3", - "dom-helpers": "^5.2.0", - "uncontrollable": "^8.0.1", - "warning": "^4.0.3" - }, - "peerDependencies": { - "react": ">=16.14.0", - "react-dom": ">=16.14.0" - } - }, - "node_modules/@restart/ui/node_modules/uncontrollable": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-8.0.4.tgz", - "integrity": "sha512-ulRWYWHvscPFc0QQXvyJjY6LIXU56f0h8pQFvhxiKk5V1fcI8gp9Ht9leVAhrVjzqMw0BgjspBINx9r6oyJUvQ==", - "peerDependencies": { - "react": ">=16.14.0" - } - }, "node_modules/@rjsf/bootstrap-4": { "version": "5.12.1", "resolved": "https://registry.npmjs.org/@rjsf/bootstrap-4/-/bootstrap-4-5.12.1.tgz", @@ -3690,14 +3656,6 @@ "url": "https://github.com/sponsors/gregberge" } }, - "node_modules/@swc/helpers": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.2.tgz", - "integrity": "sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==", - "dependencies": { - "tslib": "^2.4.0" - } - }, "node_modules/@tootallnate/once": { "version": "1.1.2", "dev": true, @@ -3862,6 +3820,11 @@ "@types/node": "*" } }, + "node_modules/@types/invariant": { + "version": "2.2.35", + "resolved": "https://registry.npmjs.org/@types/invariant/-/invariant-2.2.35.tgz", + "integrity": "sha512-DxX1V9P8zdJPYQat1gHyY0xj3efl8gnMVjiM9iCY6y27lj+PoQWkgjt8jDqmovPqULkKVpKRg8J36iQiA+EtEg==" + }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.4", "dev": true, @@ -14966,32 +14929,31 @@ } }, "node_modules/react-bootstrap": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.8.0.tgz", - "integrity": "sha512-e/aNtxl0Z2ozrIaR82jr6Zz7ss9GSoaXpQaxmvtDUsTZIq/XalkduR/ZXP6vbQHz2T4syvjA+4FbtwELxxmpww==", - "dependencies": { - "@babel/runtime": "^7.21.0", - "@restart/hooks": "^0.4.9", - "@restart/ui": "^1.6.3", - "@types/react-transition-group": "^4.4.5", - "classnames": "^2.3.2", + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-1.6.7.tgz", + "integrity": "sha512-IzCYXuLSKDEjGFglbFWk0/iHmdhdcJzTmtS6lXxc0kaNFx2PFgrQf5jKnx5sarF2tiXh9Tgx3pSt3pdK7YwkMA==", + "dependencies": { + "@babel/runtime": "^7.14.0", + "@restart/context": "^2.1.4", + "@restart/hooks": "^0.4.7", + "@types/invariant": "^2.2.33", + "@types/prop-types": "^15.7.3", + "@types/react": ">=16.14.8", + "@types/react-transition-group": "^4.4.1", + "@types/warning": "^3.0.0", + "classnames": "^2.3.1", "dom-helpers": "^5.2.1", "invariant": "^2.2.4", - "prop-types": "^15.8.1", + "prop-types": "^15.7.2", "prop-types-extra": "^1.1.0", - "react-transition-group": "^4.4.5", + "react-overlays": "^5.1.2", + "react-transition-group": "^4.4.1", "uncontrollable": "^7.2.1", "warning": "^4.0.3" }, "peerDependencies": { - "@types/react": ">=16.14.8", - "react": ">=16.14.0", - "react-dom": ">=16.14.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } + "react": ">=16.8.0", + "react-dom": ">=16.8.0" } }, "node_modules/react-copy-to-clipboard": { @@ -15275,6 +15237,25 @@ "react-dom": "^15.5.x || ^16.x || ^17.x || ^18.x" } }, + "node_modules/react-overlays": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-5.2.1.tgz", + "integrity": "sha512-GLLSOLWr21CqtJn8geSwQfoJufdt3mfdsnIiQswouuQ2MMPns+ihZklxvsTDKD3cR2tF8ELbi5xUsvqVhR6WvA==", + "dependencies": { + "@babel/runtime": "^7.13.8", + "@popperjs/core": "^2.11.6", + "@restart/hooks": "^0.4.7", + "@types/warning": "^3.0.0", + "dom-helpers": "^5.2.0", + "prop-types": "^15.7.2", + "uncontrollable": "^7.2.1", + "warning": "^4.0.3" + }, + "peerDependencies": { + "react": ">=16.3.0", + "react-dom": ">=16.3.0" + } + }, "node_modules/react-papaparse": { "version": "3.18.2", "license": "MIT", @@ -20787,14 +20768,6 @@ "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==" }, - "@react-aria/ssr": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.7.1.tgz", - "integrity": "sha512-ovVPSD1WlRpZHt7GI9DqJrWG3OIYS+NXQ9y5HIewMJpSe+jPQmMQfyRmgX4EnvmxSlp0u04Wg/7oItcoSIb/RA==", - "requires": { - "@swc/helpers": "^0.5.0" - } - }, "@react-icons/all-files": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/@react-icons/all-files/-/all-files-4.1.0.tgz", @@ -20818,6 +20791,12 @@ } } }, + "@restart/context": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@restart/context/-/context-2.1.4.tgz", + "integrity": "sha512-INJYZQJP7g+IoDUh/475NlGiTeMfwTXUEr3tmRneckHIxNolGOW9CTq83S8cxq0CgJwwcMzMJFchxvlwe7Rk8Q==", + "requires": {} + }, "@restart/hooks": { "version": "0.4.11", "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.11.tgz", @@ -20826,30 +20805,6 @@ "dequal": "^2.0.3" } }, - "@restart/ui": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/@restart/ui/-/ui-1.6.6.tgz", - "integrity": "sha512-eC3puKuWE1SRYbojWHXnvCNHGgf3uzHCb6JOhnF4OXPibOIPEkR1sqDSkL643ydigxwh+ruCa1CmYHlzk7ikKA==", - "requires": { - "@babel/runtime": "^7.21.0", - "@popperjs/core": "^2.11.6", - "@react-aria/ssr": "^3.5.0", - "@restart/hooks": "^0.4.9", - "@types/warning": "^3.0.0", - "dequal": "^2.0.3", - "dom-helpers": "^5.2.0", - "uncontrollable": "^8.0.1", - "warning": "^4.0.3" - }, - "dependencies": { - "uncontrollable": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-8.0.4.tgz", - "integrity": "sha512-ulRWYWHvscPFc0QQXvyJjY6LIXU56f0h8pQFvhxiKk5V1fcI8gp9Ht9leVAhrVjzqMw0BgjspBINx9r6oyJUvQ==", - "requires": {} - } - } - }, "@rjsf/bootstrap-4": { "version": "5.12.1", "resolved": "https://registry.npmjs.org/@rjsf/bootstrap-4/-/bootstrap-4-5.12.1.tgz", @@ -21084,14 +21039,6 @@ "loader-utils": "^2.0.0" } }, - "@swc/helpers": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.2.tgz", - "integrity": "sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==", - "requires": { - "tslib": "^2.4.0" - } - }, "@tootallnate/once": { "version": "1.1.2", "dev": true @@ -21230,6 +21177,11 @@ "@types/node": "*" } }, + "@types/invariant": { + "version": "2.2.35", + "resolved": "https://registry.npmjs.org/@types/invariant/-/invariant-2.2.35.tgz", + "integrity": "sha512-DxX1V9P8zdJPYQat1gHyY0xj3efl8gnMVjiM9iCY6y27lj+PoQWkgjt8jDqmovPqULkKVpKRg8J36iQiA+EtEg==" + }, "@types/istanbul-lib-coverage": { "version": "2.0.4", "dev": true @@ -28102,20 +28054,25 @@ } }, "react-bootstrap": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.8.0.tgz", - "integrity": "sha512-e/aNtxl0Z2ozrIaR82jr6Zz7ss9GSoaXpQaxmvtDUsTZIq/XalkduR/ZXP6vbQHz2T4syvjA+4FbtwELxxmpww==", - "requires": { - "@babel/runtime": "^7.21.0", - "@restart/hooks": "^0.4.9", - "@restart/ui": "^1.6.3", - "@types/react-transition-group": "^4.4.5", - "classnames": "^2.3.2", + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-1.6.7.tgz", + "integrity": "sha512-IzCYXuLSKDEjGFglbFWk0/iHmdhdcJzTmtS6lXxc0kaNFx2PFgrQf5jKnx5sarF2tiXh9Tgx3pSt3pdK7YwkMA==", + "requires": { + "@babel/runtime": "^7.14.0", + "@restart/context": "^2.1.4", + "@restart/hooks": "^0.4.7", + "@types/invariant": "^2.2.33", + "@types/prop-types": "^15.7.3", + "@types/react": ">=16.14.8", + "@types/react-transition-group": "^4.4.1", + "@types/warning": "^3.0.0", + "classnames": "^2.3.1", "dom-helpers": "^5.2.1", "invariant": "^2.2.4", - "prop-types": "^15.8.1", + "prop-types": "^15.7.2", "prop-types-extra": "^1.1.0", - "react-transition-group": "^4.4.5", + "react-overlays": "^5.1.2", + "react-transition-group": "^4.4.1", "uncontrollable": "^7.2.1", "warning": "^4.0.3" } @@ -28300,6 +28257,21 @@ "integrity": "sha512-NMXGa223OnsrGVp5dJHkuKxQ4czdLmXSp5jSV9OqiCky9LOpPATn3vLldc+q5fK3gKbEHvr7J1u0yhBh/xYkpA==", "requires": {} }, + "react-overlays": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-5.2.1.tgz", + "integrity": "sha512-GLLSOLWr21CqtJn8geSwQfoJufdt3mfdsnIiQswouuQ2MMPns+ihZklxvsTDKD3cR2tF8ELbi5xUsvqVhR6WvA==", + "requires": { + "@babel/runtime": "^7.13.8", + "@popperjs/core": "^2.11.6", + "@restart/hooks": "^0.4.7", + "@types/warning": "^3.0.0", + "dom-helpers": "^5.2.0", + "prop-types": "^15.7.2", + "uncontrollable": "^7.2.1", + "warning": "^4.0.3" + } + }, "react-papaparse": { "version": "3.18.2", "requires": { diff --git a/package.json b/package.json index 3a1b4acfb7c6..9d1cc1f15d02 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "prop-types": "^15.7.2", "react": "^17.0.2", "react-app-polyfill": "^2.0.0", - "react-bootstrap": "^2.8.0", + "react-bootstrap": "^1.6.5", "react-copy-to-clipboard": "^5.0.4", "react-data-table-component": "^7.4.5", "react-datepicker": "^4.10.0", From e897c6bc22888cf6c7f9a7b7524db2cfca3f39bb Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Fri, 8 Sep 2023 18:51:26 +0200 Subject: [PATCH 37/38] fix fuzzy search? --- src/components/utilities/CippFuzzySearch.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/utilities/CippFuzzySearch.js b/src/components/utilities/CippFuzzySearch.js index f4db1f1473cb..a97625dcd818 100644 --- a/src/components/utilities/CippFuzzySearch.js +++ b/src/components/utilities/CippFuzzySearch.js @@ -7,10 +7,13 @@ function _interopRequireDefault(obj) { function CippfuzzySearch(options) { var fuse = new _fuse['default'](options, { keys: ['name', 'groupName', 'items.name'], - threshold: 0.2, + threshold: 0.5, location: 0, ignoreLocation: true, useExtendedSearch: true, + includeMatches: true, + includeScore: true, + useExtendedSearch: true, }) return function (value) { if (!value.length) { From 98565c6504d3cbb88f9a11ae62f435871e7e6673 Mon Sep 17 00:00:00 2001 From: KelvinTegelaar Date: Fri, 8 Sep 2023 18:55:14 +0200 Subject: [PATCH 38/38] fix weird bug --- public/version_latest.txt | 2 +- version_latest.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/public/version_latest.txt b/public/version_latest.txt index ef8d7569d677..d87edbfc1069 100644 --- a/public/version_latest.txt +++ b/public/version_latest.txt @@ -1 +1 @@ -4.2.0 \ No newline at end of file +4.2.1 \ No newline at end of file diff --git a/version_latest.txt b/version_latest.txt index ef8d7569d677..d87edbfc1069 100644 --- a/version_latest.txt +++ b/version_latest.txt @@ -1 +1 @@ -4.2.0 \ No newline at end of file +4.2.1 \ No newline at end of file