diff --git a/.github/workflows/Assign_Issue_Volunteer.yml b/.github/workflows/Assign_Issue_Volunteer.yml index 08f1e82701d0..23ef1d16ffc0 100644 --- a/.github/workflows/Assign_Issue_Volunteer.yml +++ b/.github/workflows/Assign_Issue_Volunteer.yml @@ -1,10 +1,10 @@ --- -name: 'Assign Issue to Volunteer' -on: [issue_comment] # yamllint disable-line rule:truthy +name: "Assign Issue to Volunteer" +on: [issue_comment] # yamllint disable-line rule:truthy jobs: build: - runs-on: ubuntu-latest + runs-on: ubuntu-slim steps: - uses: bhermann/issue-volunteer@v0.1.12 with: - GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' + GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.github/workflows/Check_for_Version_Update.yml b/.github/workflows/Check_for_Version_Update.yml index f8a7db0343f2..001dfdb4ffa5 100644 --- a/.github/workflows/Check_for_Version_Update.yml +++ b/.github/workflows/Check_for_Version_Update.yml @@ -8,7 +8,7 @@ jobs: build: if: github.repository_owner == 'KelvinTegelaar' name: "Check for Version Update" - runs-on: ubuntu-latest + runs-on: ubuntu-slim steps: - name: Check for Changed Files uses: brettcannon/check-for-changed-files@v1.1.0 diff --git a/.github/workflows/Close_Stale_Issues_and_PRs.yml b/.github/workflows/Close_Stale_Issues_and_PRs.yml index 88607a42675d..a90ac229be88 100644 --- a/.github/workflows/Close_Stale_Issues_and_PRs.yml +++ b/.github/workflows/Close_Stale_Issues_and_PRs.yml @@ -1,18 +1,18 @@ --- -name: 'Close stale issues and PRs' +name: "Close stale issues and PRs" on: schedule: - - cron: '30 1 * * *' + - cron: "30 1 * * *" jobs: stale: if: github.repository_owner == 'KelvinTegelaar' - runs-on: ubuntu-latest + runs-on: ubuntu-slim steps: - uses: actions/stale@v4 with: - stale-issue-message: 'This issue is stale because it has been open 10 days with no activity. We will close this issue soon. If you want this feature implemented you can contribute it. See: https://docs.cipp.app/dev-documentation/contributing-to-the-code . Please notify the team if you are working on this yourself.' - close-issue-message: 'This issue was closed because it has been stalled for 14 days with no activity.' - stale-issue-label: 'no-activity' - exempt-issue-labels: 'planned,bug,roadmap' + stale-issue-message: "This issue is stale because it has been open 10 days with no activity. We will close this issue soon. If you want this feature implemented you can contribute it. See: https://docs.cipp.app/dev-documentation/contributing-to-the-code . Please notify the team if you are working on this yourself." + close-issue-message: "This issue was closed because it has been stalled for 14 days with no activity." + stale-issue-label: "no-activity" + exempt-issue-labels: "planned,bug,roadmap" days-before-stale: 9 days-before-close: 5 diff --git a/.github/workflows/Comment_on_Issues.yml b/.github/workflows/Comment_on_Issues.yml index 8d83f6237d82..c408d8b38c84 100644 --- a/.github/workflows/Comment_on_Issues.yml +++ b/.github/workflows/Comment_on_Issues.yml @@ -7,7 +7,7 @@ on: jobs: add-comment_bug: if: github.repository_owner == 'KelvinTegelaar' && github.event.label.name == 'unconfirmed-by-user' - runs-on: ubuntu-latest + runs-on: ubuntu-slim permissions: issues: write steps: @@ -18,5 +18,5 @@ jobs: body: | Thank you for reporting a potential bug. If you would like to work on this bug, please comment: > I would like to work on this please! - + Thank you for helping us maintain the project! diff --git a/.github/workflows/Label_Issues.yml b/.github/workflows/Label_Issues.yml index 38865a62fae8..ebdc3992980f 100644 --- a/.github/workflows/Label_Issues.yml +++ b/.github/workflows/Label_Issues.yml @@ -7,23 +7,23 @@ on: jobs: label_issues_bugs: if: github.repository_owner == 'KelvinTegelaar' && contains(github.event.issue.title, 'Bug') - runs-on: ubuntu-latest + runs-on: ubuntu-slim permissions: issues: write steps: - name: Label Issues uses: andymckay/labeler@5c59dabdfd4dd5bd9c6e6d255b01b9d764af4414 with: - add-labels: 'not-assigned' + add-labels: "not-assigned" repo-token: ${{ secrets.GITHUB_TOKEN }} label_issues_frs: if: github.repository_owner == 'KelvinTegelaar' && contains(github.event.issue.title, 'Feature') - runs-on: ubuntu-latest + runs-on: ubuntu-slim permissions: issues: write steps: - name: Label Issues uses: andymckay/labeler@5c59dabdfd4dd5bd9c6e6d255b01b9d764af4414 with: - add-labels: 'enhancement, not-assigned' + add-labels: "enhancement, not-assigned" repo-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/auto_comments.yml b/.github/workflows/auto_comments.yml index 7d7b11b45474..6cd003a36ae8 100644 --- a/.github/workflows/auto_comments.yml +++ b/.github/workflows/auto_comments.yml @@ -7,7 +7,7 @@ on: jobs: handle_comment: - runs-on: ubuntu-latest + runs-on: ubuntu-slim # We need permissions to modify issue comments. # 'issues: write' is required for deleting comments. permissions: diff --git a/.github/workflows/label_sponsor_requests.yml b/.github/workflows/label_sponsor_requests.yml index b974cf66776f..bb9d6a31b427 100644 --- a/.github/workflows/label_sponsor_requests.yml +++ b/.github/workflows/label_sponsor_requests.yml @@ -6,13 +6,13 @@ on: jobs: label_issues_bugs: if: github.repository_owner == 'KelvinTegelaar' && contains(github.event.issue.title, 'Bug') - runs-on: ubuntu-latest + runs-on: ubuntu-slim permissions: issues: write steps: - name: Sponsor Labels uses: JasonEtco/is-sponsor-label-action@v1.2.0 with: - label: 'Sponsor Priority' + label: "Sponsor Priority" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/pr_check.yml b/.github/workflows/pr_check.yml index 0d9e2fd7abcd..08cce1de130b 100644 --- a/.github/workflows/pr_check.yml +++ b/.github/workflows/pr_check.yml @@ -16,7 +16,7 @@ permissions: jobs: check-branch: - runs-on: ubuntu-latest + runs-on: ubuntu-slim steps: - name: Check and Comment on PR # Only process fork PRs with specific branch conditions @@ -46,14 +46,14 @@ jobs: } message += '🔒 This PR will now be automatically closed due to the above rules.'; - + // Post the comment await github.rest.issues.createComment({ ...context.repo, issue_number: context.issue.number, body: message }); - + // Close the PR await github.rest.pulls.update({ ...context.repo, diff --git a/next.config.js b/next.config.js index 7a97a124b4bb..416f3f22d1df 100644 --- a/next.config.js +++ b/next.config.js @@ -4,12 +4,13 @@ const config = { images: { unoptimized: true, }, - webpack(config) { - config.module.rules.push({ - test: /\.svg$/, - use: ["@svgr/webpack"], - }); - return config; + turbopack: { + rules: { + "*.svg": { + loaders: ["@svgr/webpack"], + as: "*.js", + }, + }, }, async redirects() { return []; diff --git a/package.json b/package.json index bdcffddcdf11..e7a888033252 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cipp", - "version": "10.0.3", + "version": "10.0.6", "author": "CIPP Contributors", "homepage": "https://cipp.app/", "bugs": { @@ -32,9 +32,9 @@ "@monaco-editor/react": "^4.6.0", "@mui/icons-material": "7.3.2", "@mui/lab": "7.0.0-beta.17", - "@mui/material": "7.3.2", + "@mui/material": "7.3.7", "@mui/system": "7.3.2", - "@mui/x-date-pickers": "^8.11.1", + "@mui/x-date-pickers": "^8.25.0", "@musement/iso-duration": "^1.0.0", "@nivo/core": "^0.99.0", "@nivo/sankey": "^0.99.0", @@ -72,18 +72,18 @@ "material-react-table": "^3.0.1", "monaco-editor": "^0.53.0", "mui-tiptap": "^1.14.0", - "next": "^15.2.2", + "next": "^16.1.2", "nprogress": "0.2.0", "numeral": "2.0.6", "prop-types": "15.8.1", "punycode": "^2.3.1", - "react": "19.1.1", + "react": "19.2.3", "react-apexcharts": "1.7.0", "react-beautiful-dnd": "13.1.1", "react-copy-to-clipboard": "^5.1.0", - "react-dom": "19.1.1", + "react-dom": "19.2.3", "react-dropzone": "14.3.8", - "react-error-boundary": "^6.0.0", + "react-error-boundary": "^6.1.0", "react-grid-layout": "^1.5.0", "react-hook-form": "^7.53.0", "react-hot-toast": "2.6.0", diff --git a/public/version.json b/public/version.json index c05615499486..90d764a5ec57 100644 --- a/public/version.json +++ b/public/version.json @@ -1,3 +1,3 @@ { - "version": "10.0.3" -} + "version": "10.0.6" +} \ No newline at end of file diff --git a/src/components/CippCards/CippDomainCards.jsx b/src/components/CippCards/CippDomainCards.jsx index b6d8adb58bf4..9268fcd08f96 100644 --- a/src/components/CippCards/CippDomainCards.jsx +++ b/src/components/CippCards/CippDomainCards.jsx @@ -22,9 +22,9 @@ import WarningIcon from "@mui/icons-material/Warning"; import HelpIcon from "@mui/icons-material/Help"; import MoreVertIcon from "@mui/icons-material/MoreVert"; import { Controller, useForm } from "react-hook-form"; -import { ApiGetCall } from "/src/api/ApiCall"; -import CippButtonCard from "/src/components/CippCards/CippButtonCard"; -import { CippCodeBlock } from "/src/components/CippComponents/CippCodeBlock"; +import { ApiGetCall } from "../../api/ApiCall"; +import CippButtonCard from "./CippButtonCard"; +import { CippCodeBlock } from "../CippComponents/CippCodeBlock"; import { CippOffCanvas } from "../CippComponents/CippOffCanvas"; import { CippPropertyListCard } from "./CippPropertyListCard"; import { getCippFormatting } from "../../utils/get-cipp-formatting"; diff --git a/src/components/CippCards/CippExchangeInfoCard.jsx b/src/components/CippCards/CippExchangeInfoCard.jsx index 9a5dfb574ae7..60e7ac7ef063 100644 --- a/src/components/CippCards/CippExchangeInfoCard.jsx +++ b/src/components/CippCards/CippExchangeInfoCard.jsx @@ -10,8 +10,8 @@ import { CircularProgress, Alert, } from "@mui/material"; -import { PropertyList } from "/src/components/property-list"; -import { PropertyListItem } from "/src/components/property-list-item"; +import { PropertyList } from "../property-list"; +import { PropertyListItem } from "../property-list-item"; import { getCippFormatting } from "../../utils/get-cipp-formatting"; import { Check as CheckIcon, Close as CloseIcon, Sync } from "@mui/icons-material"; import { LinearProgressWithLabel } from "../linearProgressWithLabel"; diff --git a/src/components/CippCards/CippUserInfoCard.jsx b/src/components/CippCards/CippUserInfoCard.jsx index 0e866efb39ac..43e4d6d26cb2 100644 --- a/src/components/CippCards/CippUserInfoCard.jsx +++ b/src/components/CippCards/CippUserInfoCard.jsx @@ -12,8 +12,8 @@ import { CircularProgress, } from "@mui/material"; import { AccountCircle, PhotoCamera, Delete } from "@mui/icons-material"; -import { PropertyList } from "/src/components/property-list"; -import { PropertyListItem } from "/src/components/property-list-item"; +import { PropertyList } from "../property-list"; +import { PropertyListItem } from "../property-list-item"; import { getCippFormatting } from "../../utils/get-cipp-formatting"; import { Stack, Grid, Box } from "@mui/system"; import { useState, useRef, useCallback } from "react"; diff --git a/src/components/CippComponents/AuthMethodCard.jsx b/src/components/CippComponents/AuthMethodCard.jsx index 5fde4e6b48fd..97ade0f8d6c6 100644 --- a/src/components/CippComponents/AuthMethodCard.jsx +++ b/src/components/CippComponents/AuthMethodCard.jsx @@ -1,8 +1,11 @@ import { Box, Card, CardHeader, CardContent, Typography, Skeleton } from "@mui/material"; import { People as UsersIcon } from "@mui/icons-material"; import { CippSankey } from "./CippSankey"; +import { useRouter } from "next/router"; export const AuthMethodCard = ({ data, isLoading }) => { + const router = useRouter(); + const processData = () => { if (!data || !Array.isArray(data) || data.length === 0) { return null; @@ -110,8 +113,87 @@ export const AuthMethodCard = ({ data, isLoading }) => { const processedData = processData(); + const handleNodeClick = (node) => { + let filters = []; + + switch (node.id) { + case "Users": + filters = [{ id: "AccountEnabled", value: "Yes" }]; + break; + case "Single factor": + filters = [ + { id: "AccountEnabled", value: "Yes" }, + { id: "MFARegistration", value: "No" }, + ]; + break; + case "Multi factor": + // Per-user MFA enabled/enforced + filters = [{ id: "AccountEnabled", value: "Yes" }]; + break; + case "Phishable": + filters = [ + { id: "AccountEnabled", value: "Yes" }, + { id: "MFARegistration", value: "Yes" }, + ]; + break; + case "Phish resistant": + filters = [ + { id: "AccountEnabled", value: "Yes" }, + { id: "MFARegistration", value: "Yes" }, + ]; + break; + default: + return; + } + + router.push({ + pathname: "/identity/reports/mfa-report", + query: { filters: JSON.stringify(filters) }, + }); + }; + + const handleLinkClick = (link) => { + let filters = []; + + if (link.source.id === "Users" && link.target.id === "Single factor") { + filters = [ + { id: "AccountEnabled", value: "Yes" }, + { id: "MFARegistration", value: "No" }, + ]; + } else if (link.source.id === "Users" && link.target.id === "Multi factor") { + filters = [{ id: "AccountEnabled", value: "Yes" }]; + } else if (link.source.id === "Users" && link.target.id === "Phishable") { + filters = [ + { id: "AccountEnabled", value: "Yes" }, + { id: "MFARegistration", value: "Yes" }, + ]; + } else if (link.source.id === "Users" && link.target.id === "Phish resistant") { + filters = [ + { id: "AccountEnabled", value: "Yes" }, + { id: "MFARegistration", value: "Yes" }, + ]; + } else if (link.source.id === "Phishable") { + filters = [ + { id: "AccountEnabled", value: "Yes" }, + { id: "MFARegistration", value: "Yes" }, + ]; + } else if (link.source.id === "Phish resistant") { + filters = [ + { id: "AccountEnabled", value: "Yes" }, + { id: "MFARegistration", value: "Yes" }, + ]; + } + + if (filters.length > 0) { + router.push({ + pathname: "/identity/reports/mfa-report", + query: { filters: JSON.stringify(filters) }, + }); + } + }; + return ( - + @@ -126,7 +208,11 @@ export const AuthMethodCard = ({ data, isLoading }) => { {isLoading ? ( ) : processedData ? ( - + ) : ( { alignItems: "center", justifyContent: "center", height: "100%", + width: "100%", }} > diff --git a/src/components/CippComponents/BPASyncDialog.jsx b/src/components/CippComponents/BPASyncDialog.jsx index 43a16450416a..3add79b46f54 100644 --- a/src/components/CippComponents/BPASyncDialog.jsx +++ b/src/components/CippComponents/BPASyncDialog.jsx @@ -9,7 +9,7 @@ import { import { Sync } from "@mui/icons-material"; import { useForm, FormProvider } from "react-hook-form"; import { CippFormTenantSelector } from "./CippFormTenantSelector"; -import { ApiPostCall } from "/src/api/ApiCall"; +import { ApiPostCall } from "../../api/ApiCall"; import { CippApiResults } from "./CippApiResults"; export const BPASyncDialog = ({ createDialog }) => { diff --git a/src/components/CippComponents/BreachSearchDialog.jsx b/src/components/CippComponents/BreachSearchDialog.jsx index e089908ffb43..8a69cd40206c 100644 --- a/src/components/CippComponents/BreachSearchDialog.jsx +++ b/src/components/CippComponents/BreachSearchDialog.jsx @@ -2,7 +2,7 @@ import { useState } from "react"; import { Dialog, DialogContent, DialogTitle, Button, DialogActions } from "@mui/material"; import { Search } from "@mui/icons-material"; import { useForm, FormProvider } from "react-hook-form"; -import { ApiPostCall } from "/src/api/ApiCall"; +import { ApiPostCall } from "../../api/ApiCall"; import { CippApiResults } from "./CippApiResults"; import { useSettings } from "../../hooks/use-settings"; diff --git a/src/components/CippComponents/CIPPM365OAuthButton.jsx b/src/components/CippComponents/CIPPM365OAuthButton.jsx index 88e517a2139d..0818190ca1cc 100644 --- a/src/components/CippComponents/CIPPM365OAuthButton.jsx +++ b/src/components/CippComponents/CIPPM365OAuthButton.jsx @@ -1,7 +1,9 @@ import { useState, useEffect } from "react"; import { Alert, Button, Typography, CircularProgress, Box } from "@mui/material"; +import { Microsoft, Login, Refresh } from "@mui/icons-material"; import { ApiGetCall } from "../../api/ApiCall"; import { CippCopyToClipBoard } from "./CippCopyToClipboard"; +import { CippApiDialog } from "./CippApiDialog"; export const CIPPM365OAuthButton = ({ onAuthSuccess, @@ -14,12 +16,14 @@ export const CIPPM365OAuthButton = ({ applicationId = null, autoStartDeviceLogon = false, validateServiceAccount = true, + promptBeforeAuth = false, }) => { const [authInProgress, setAuthInProgress] = useState(false); const [authError, setAuthError] = useState(null); const [deviceCodeInfo, setDeviceCodeInfo] = useState(null); const [codeRetrievalInProgress, setCodeRetrievalInProgress] = useState(false); const [isServiceAccount, setIsServiceAccount] = useState(true); + const [promptDialog, setPromptDialog] = useState({ open: false }); const [tokens, setTokens] = useState({ accessToken: null, refreshToken: null, @@ -32,13 +36,10 @@ export const CIPPM365OAuthButton = ({ const appIdInfo = ApiGetCall({ url: `/api/ExecListAppId`, + queryKey: "listAppId", waiting: true, }); - useEffect(() => { - appIdInfo.refetch(); - }, []); - const handleCloseError = () => { setAuthError(null); }; @@ -55,8 +56,10 @@ export const CIPPM365OAuthButton = ({ setCodeRetrievalInProgress(true); setAuthError(null); - // Refetch appId to ensure we have the latest - await appIdInfo.refetch(); + // Only refetch appId if not already present + if (!applicationId && !appIdInfo?.data?.applicationId) { + await appIdInfo.refetch(); + } try { // Get the application ID to use @@ -66,8 +69,8 @@ export const CIPPM365OAuthButton = ({ // Request device code from our API endpoint const deviceCodeResponse = await fetch( `/api/ExecDeviceCodeLogon?operation=getDeviceCode&clientId=${appId}&scope=${encodeURIComponent( - scope - )}` + scope, + )}`, ); const deviceCodeData = await deviceCodeResponse.json(); @@ -95,8 +98,10 @@ export const CIPPM365OAuthButton = ({ // Device code authentication function - opens popup and starts polling const handleDeviceCodeAuthentication = async () => { - // Refetch appId to ensure we have the latest - await appIdInfo.refetch(); + // Only refetch appId if not already present + if (!applicationId && !appIdInfo?.data?.applicationId) { + await appIdInfo.refetch(); + } if (!deviceCodeInfo) { // If we don't have a device code yet, retrieve it first @@ -129,7 +134,7 @@ export const CIPPM365OAuthButton = ({ const popup = window.open( "https://microsoft.com/devicelogin", "deviceLoginPopup", - `width=${width},height=${height},left=${left},top=${top}` + `width=${width},height=${height},left=${left},top=${top}`, ); // Start polling for token @@ -155,7 +160,7 @@ export const CIPPM365OAuthButton = ({ try { // Poll for token using our API endpoint const tokenResponse = await fetch( - `/api/ExecDeviceCodeLogon?operation=checkToken&clientId=${appId}&deviceCode=${deviceCodeInfo.device_code}` + `/api/ExecDeviceCodeLogon?operation=checkToken&clientId=${appId}&deviceCode=${deviceCodeInfo.device_code}`, ); const tokenData = await tokenResponse.json(); @@ -263,7 +268,9 @@ export const CIPPM365OAuthButton = ({ }; // MSAL-like authentication function - const handleMsalAuthentication = async () => { + const handleMsalAuthentication = async (retryCount = 0) => { + const maxRetries = 3; + // Clear previous authentication state when starting a new authentication setAuthInProgress(true); setAuthError(null); @@ -277,10 +284,12 @@ export const CIPPM365OAuthButton = ({ onmicrosoftDomain: null, }); - // Refetch app ID info to ensure we have the latest - await appIdInfo.refetch(); + // Only refetch app ID if not already present + if (!applicationId && !appIdInfo?.data?.applicationId) { + await appIdInfo.refetch(); + } - // Get the application ID to use - now we're sure to have the latest after the await + // Get the application ID to use const appId = applicationId || appIdInfo?.data?.applicationId; // Generate MSAL-like authentication parameters @@ -327,7 +336,7 @@ export const CIPPM365OAuthButton = ({ const popup = window.open( authUrl, "msalAuthPopup", - `width=${width},height=${height},left=${left},top=${top}` + `width=${width},height=${height},left=${left},top=${top}`, ); // Function to actually exchange the authorization code for tokens @@ -356,20 +365,43 @@ export const CIPPM365OAuthButton = ({ }; // Make the token request through our API proxy to avoid origin header issues - const tokenResponse = await fetch(`/api/ExecTokenExchange`, { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - tokenRequest, - tokenUrl: "https://login.microsoftonline.com/common/oauth2/v2.0/token", - tenantId: appId, // Pass the tenant ID to retrieve the correct client secret - }), - }); + // Retry logic for AADSTS650051 (service principal already exists) + let retryCount = 0; + const maxRetries = 3; + let tokenResponse; + let tokenData; + + while (retryCount <= maxRetries) { + tokenResponse = await fetch(`/api/ExecTokenExchange`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + tokenRequest, + tokenUrl: "https://login.microsoftonline.com/common/oauth2/v2.0/token", + tenantId: appId, // Pass the tenant ID to retrieve the correct client secret + }), + }); - // Parse the token response - const tokenData = await tokenResponse.json(); + // Parse the token response + tokenData = await tokenResponse.json(); + + // Check if it's the AADSTS650051 error (service principal already exists) + if ( + tokenData.error === "invalid_client" && + tokenData.error_description?.includes("AADSTS650051") + ) { + retryCount++; + if (retryCount <= maxRetries) { + // Wait before retrying (exponential backoff) + await new Promise((resolve) => setTimeout(resolve, 2000 * retryCount)); + continue; + } + } + // If no error or different error, break out of retry loop + break; + } // Check if the response contains an error if (tokenData.error) { @@ -408,6 +440,9 @@ export const CIPPM365OAuthButton = ({ if (!refreshResponse.ok) { console.warn("Failed to store refresh token, but continuing with authentication"); + } else { + // Invalidate the listAppId and tenants-table queryKeys to refresh data + appIdInfo.refetch(); } } catch (error) { console.error("Failed to store refresh token:", error); @@ -502,7 +537,27 @@ export const CIPPM365OAuthButton = ({ const errorCode = urlParams.get("error"); const errorDescription = urlParams.get("error_description"); - // Set the error state + // Check if it's the AADSTS650051 error (service principal already exists during consent) + if ( + errorCode === "invalid_client" && + errorDescription?.includes("AADSTS650051") && + retryCount < maxRetries + ) { + // Close the popup + popup.close(); + setAuthInProgress(false); + + // Wait before retrying (exponential backoff) + setTimeout( + () => { + handleMsalAuthentication(retryCount + 1); + }, + 2000 * (retryCount + 1), + ); + return; + } + + // Set the error state for non-retryable errors const error = { errorCode: errorCode, errorMessage: errorDescription || "Unknown authentication error", @@ -550,9 +605,9 @@ export const CIPPM365OAuthButton = ({
{!applicationId && !appIdInfo.isLoading && - appIdInfo?.data && // Only check if data is available + appIdInfo?.data?.applicationId && // Only check if applicationId is present in data !/^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/.test( - appIdInfo?.data?.applicationId + appIdInfo?.data?.applicationId, ) && ( The Application ID is not valid. Please check your configuration. @@ -653,6 +708,30 @@ export const CIPPM365OAuthButton = ({ ) : null} )} + + {promptBeforeAuth !== false && ( + setPromptDialog({ open: false }), + }} + api={{ + type: "POST", + confirmText: promptBeforeAuth, + noConfirm: false, + customFunction: () => { + setPromptDialog({ open: false }); + const authFunction = useDeviceCode + ? handleDeviceCodeAuthentication + : handleMsalAuthentication; + authFunction(); + }, + }} + fields={[]} + /> + )} +
); diff --git a/src/components/CippComponents/CippAddEditTenantGroups.jsx b/src/components/CippComponents/CippAddEditTenantGroups.jsx index 9ba637d003c8..4208c18eaf7c 100644 --- a/src/components/CippComponents/CippAddEditTenantGroups.jsx +++ b/src/components/CippComponents/CippAddEditTenantGroups.jsx @@ -1,4 +1,4 @@ -import CippFormComponent from "/src/components/CippComponents/CippFormComponent"; +import CippFormComponent from "./CippFormComponent"; import { Typography } from "@mui/material"; import { Grid } from "@mui/system"; import { CippFormTenantSelector } from "./CippFormTenantSelector"; diff --git a/src/components/CippComponents/CippAddVacationModeDrawer.jsx b/src/components/CippComponents/CippAddVacationModeDrawer.jsx index 9434b456547e..bd6b4397d590 100644 --- a/src/components/CippComponents/CippAddVacationModeDrawer.jsx +++ b/src/components/CippComponents/CippAddVacationModeDrawer.jsx @@ -9,7 +9,7 @@ import { CippApiResults } from "./CippApiResults"; import { CippFormUserSelector } from "./CippFormUserSelector"; import { CippFormTenantSelector } from "./CippFormTenantSelector"; import { ApiPostCall, ApiGetCallWithPagination } from "../../api/ApiCall"; -import CippJsonView from "/src/components/CippFormPages/CippJSONView"; +import CippJsonView from "../CippFormPages/CippJSONView"; export const CippAddVacationModeDrawer = ({ buttonText = "Add Vacation Schedule", diff --git a/src/components/CippComponents/CippApiDialog.jsx b/src/components/CippComponents/CippApiDialog.jsx index 39f590570dd0..3748e4005376 100644 --- a/src/components/CippComponents/CippApiDialog.jsx +++ b/src/components/CippComponents/CippApiDialog.jsx @@ -364,6 +364,7 @@ export const CippApiDialog = (props) => { formControl={formHook} addedFieldData={addedFieldData} setAddedFieldData={setAddedFieldData} + row={row} {...fieldProps} />
diff --git a/src/components/CippComponents/CippAppPermissionBuilder.jsx b/src/components/CippComponents/CippAppPermissionBuilder.jsx index 46adfc153008..3ff6635eec32 100644 --- a/src/components/CippComponents/CippAppPermissionBuilder.jsx +++ b/src/components/CippComponents/CippAppPermissionBuilder.jsx @@ -17,7 +17,7 @@ import { Tab, } from "@mui/material"; import { Grid } from "@mui/system"; -import { ApiGetCall, ApiPostCall } from "/src/api/ApiCall"; +import { ApiGetCall, ApiPostCall } from "../../api/ApiCall"; import { CippDataTable } from "../CippTable/CippDataTable"; import { PlusIcon, ShieldCheckIcon, WrenchIcon } from "@heroicons/react/24/outline"; import CippFormComponent from "./CippFormComponent"; diff --git a/src/components/CippComponents/CippApplicationDeployDrawer.jsx b/src/components/CippComponents/CippApplicationDeployDrawer.jsx index 16384787e6ec..6b51f4889e57 100644 --- a/src/components/CippComponents/CippApplicationDeployDrawer.jsx +++ b/src/components/CippComponents/CippApplicationDeployDrawer.jsx @@ -8,7 +8,7 @@ import CippFormComponent from "./CippFormComponent"; import { CippFormTenantSelector } from "./CippFormTenantSelector"; import { CippFormCondition } from "./CippFormCondition"; import { CippApiResults } from "./CippApiResults"; -import languageList from "/src/data/languageList.json"; +import languageList from "../../data/languageList.json"; import { ApiPostCall } from "../../api/ApiCall"; export const CippApplicationDeployDrawer = ({ diff --git a/src/components/CippComponents/CippAuditLogDetails.jsx b/src/components/CippComponents/CippAuditLogDetails.jsx index b5a3077a0da6..44a291245cb7 100644 --- a/src/components/CippComponents/CippAuditLogDetails.jsx +++ b/src/components/CippComponents/CippAuditLogDetails.jsx @@ -1,10 +1,10 @@ import { useEffect } from "react"; -import { getCippTranslation } from "/src/utils/get-cipp-translation"; -import { getCippFormatting } from "/src/utils/get-cipp-formatting"; -import CippGeoLocation from "/src/components/CippComponents/CippGeoLocation"; +import { getCippTranslation } from "../../utils/get-cipp-translation"; +import { getCippFormatting } from "../../utils/get-cipp-formatting"; +import CippGeoLocation from "./CippGeoLocation"; import { Tooltip, CircularProgress, Stack } from "@mui/material"; -import { useGuidResolver } from "/src/hooks/use-guid-resolver"; -import { CippPropertyListCard } from "/src/components/CippCards/CippPropertyListCard"; +import { useGuidResolver } from "../../hooks/use-guid-resolver"; +import { CippPropertyListCard } from "../CippCards/CippPropertyListCard"; const CippAuditLogDetails = ({ row }) => { const { diff --git a/src/components/CippComponents/CippAuditLogSearchDrawer.jsx b/src/components/CippComponents/CippAuditLogSearchDrawer.jsx index 93628842b386..9c3179f0490d 100644 --- a/src/components/CippComponents/CippAuditLogSearchDrawer.jsx +++ b/src/components/CippComponents/CippAuditLogSearchDrawer.jsx @@ -6,7 +6,7 @@ import { CippOffCanvas } from "./CippOffCanvas"; import { ApiPostCall, ApiGetCallWithPagination } from "../../api/ApiCall"; import CippFormComponent from "./CippFormComponent"; import { CippApiResults } from "./CippApiResults"; -import { useSettings } from "/src/hooks/use-settings"; +import { useSettings } from "../../hooks/use-settings"; export const CippAuditLogSearchDrawer = ({ buttonText = "New Search", diff --git a/src/components/CippComponents/CippAutopilotProfileDrawer.jsx b/src/components/CippComponents/CippAutopilotProfileDrawer.jsx index f5b48ae54040..7edc95b46b60 100644 --- a/src/components/CippComponents/CippAutopilotProfileDrawer.jsx +++ b/src/components/CippComponents/CippAutopilotProfileDrawer.jsx @@ -7,7 +7,7 @@ import { CippOffCanvas } from "./CippOffCanvas"; import CippFormComponent from "./CippFormComponent"; import { CippFormTenantSelector } from "./CippFormTenantSelector"; import { CippApiResults } from "./CippApiResults"; -import languageList from "/src/data/languageList.json"; +import languageList from "../../data/languageList.json"; import { ApiPostCall } from "../../api/ApiCall"; export const CippAutopilotProfileDrawer = ({ diff --git a/src/components/CippComponents/CippBreadcrumbNav.jsx b/src/components/CippComponents/CippBreadcrumbNav.jsx index ff146073ae1c..98093aa34974 100644 --- a/src/components/CippComponents/CippBreadcrumbNav.jsx +++ b/src/components/CippComponents/CippBreadcrumbNav.jsx @@ -32,7 +32,7 @@ async function loadTabOptions() { for (const basePath of tabOptionPaths) { try { - const module = await import(`/src/pages${basePath}/tabOptions.json`); + const module = await import(`../../pages${basePath}/tabOptions.json`); const options = module.default || module; // Add each tab option with metadata diff --git a/src/components/CippComponents/CippBulkUserDrawer.jsx b/src/components/CippComponents/CippBulkUserDrawer.jsx index 7718ae957138..6fd62b106c38 100644 --- a/src/components/CippComponents/CippBulkUserDrawer.jsx +++ b/src/components/CippComponents/CippBulkUserDrawer.jsx @@ -11,7 +11,7 @@ import { CippApiResults } from "./CippApiResults"; import { useSettings } from "../../hooks/use-settings"; import { ApiPostCall } from "../../api/ApiCall"; import { getCippTranslation } from "../../utils/get-cipp-translation"; -import countryList from "/src/data/countryList.json"; +import countryList from "../../data/countryList.json"; export const CippBulkUserDrawer = ({ buttonText = "Bulk Add Users", diff --git a/src/components/CippComponents/CippCentralSearch.jsx b/src/components/CippComponents/CippCentralSearch.jsx index 0c7bf858e88b..2f0252fcaf11 100644 --- a/src/components/CippComponents/CippCentralSearch.jsx +++ b/src/components/CippComponents/CippCentralSearch.jsx @@ -14,8 +14,8 @@ import { } from "@mui/material"; import { Grid } from "@mui/system"; import { useRouter } from "next/router"; -import { nativeMenuItems } from "/src/layouts/config"; -import { usePermissions } from "/src/hooks/use-permissions"; +import { nativeMenuItems } from "../../layouts/config"; +import { usePermissions } from "../../hooks/use-permissions"; /** * Recursively collects only leaf items (those without sub-items). @@ -62,7 +62,7 @@ async function loadTabOptions() { for (const basePath of tabOptionPaths) { try { - const module = await import(`/src/pages${basePath}/tabOptions.json`); + const module = await import(`../../pages${basePath}/tabOptions.json`); const options = module.default || module; // Add each tab option with metadata @@ -172,7 +172,7 @@ export const CippCentralSearch = ({ handleClose, open }) => { const filteredMainMenu = filterItemsByPermissionsAndRoles( allLeafItems, userPermissions, - userRoles + userRoles, ).map((item) => { const rawBreadcrumbs = buildBreadcrumbPath(nativeMenuItems, item.path) || []; // Remove the leaf item's own title to avoid duplicate when rendering @@ -250,7 +250,7 @@ export const CippCentralSearch = ({ handleClose, open }) => { const inTitle = leaf.title?.toLowerCase().includes(normalizedSearch); const inPath = leaf.path?.toLowerCase().includes(normalizedSearch); const inBreadcrumbs = leaf.breadcrumbs?.some((crumb) => - crumb?.toLowerCase().includes(normalizedSearch) + crumb?.toLowerCase().includes(normalizedSearch), ); // If there's no search value, show no results (you could change this logic) return normalizedSearch ? inTitle || inPath || inBreadcrumbs : false; @@ -267,7 +267,7 @@ export const CippCentralSearch = ({ handleClose, open }) => { ) : ( part - ) + ), ); }; diff --git a/src/components/CippComponents/CippCustomVariables.jsx b/src/components/CippComponents/CippCustomVariables.jsx index b408deaae8ea..69b5975d1777 100644 --- a/src/components/CippComponents/CippCustomVariables.jsx +++ b/src/components/CippComponents/CippCustomVariables.jsx @@ -1,10 +1,10 @@ import { useState } from "react"; import { CardContent, Button, SvgIcon, Alert } from "@mui/material"; import { PlusIcon, TrashIcon, PencilIcon } from "@heroicons/react/24/outline"; -import { CippDataTable } from "/src/components/CippTable/CippDataTable"; -import { CippApiResults } from "/src/components/CippComponents/CippApiResults"; -import { CippApiDialog } from "/src/components/CippComponents/CippApiDialog"; -import { ApiPostCall } from "/src/api/ApiCall"; +import { CippDataTable } from "../CippTable/CippDataTable"; +import { CippApiResults } from "./CippApiResults"; +import { CippApiDialog } from "./CippApiDialog"; +import { ApiPostCall } from "../../api/ApiCall"; const CippCustomVariables = ({ id }) => { const [openAddDialog, setOpenAddDialog] = useState(false); diff --git a/src/components/CippComponents/CippExchangeActions.jsx b/src/components/CippComponents/CippExchangeActions.jsx index e88171a3f20f..a783b263a339 100644 --- a/src/components/CippComponents/CippExchangeActions.jsx +++ b/src/components/CippComponents/CippExchangeActions.jsx @@ -17,7 +17,7 @@ import { PersonAdd, Email, } from "@mui/icons-material"; -import { useSettings } from "/src/hooks/use-settings.js"; +import { useSettings } from "../../hooks/use-settings.js"; import { useMemo } from "react"; export const CippExchangeActions = () => { diff --git a/src/components/CippComponents/CippFormComponent.jsx b/src/components/CippComponents/CippFormComponent.jsx index 5e76c4152ad1..0ab4bbfc2164 100644 --- a/src/components/CippComponents/CippFormComponent.jsx +++ b/src/components/CippComponents/CippFormComponent.jsx @@ -56,6 +56,7 @@ export const CippFormComponent = (props) => { helperText, disableVariables = false, includeSystemVariables = false, + row, ...other } = props; const { errors } = useFormState({ control: formControl.control }); @@ -408,16 +409,32 @@ export const CippFormComponent = (props) => { ); - case "autoComplete": + case "autoComplete": { + // Resolve options if it's a function + const resolvedOptions = + typeof other.options === "function" ? other.options(row) : other.options; + + // Wrap validate function to pass row as third parameter + const resolvedValidators = validators + ? { + ...validators, + validate: + typeof validators.validate === "function" + ? (value, formValues) => validators.validate(value, formValues, row) + : validators.validate, + } + : validators; + return (
( { )}
); + } case "richText": { const editorInstanceRef = React.useRef(null); diff --git a/src/components/CippComponents/CippFormTenantSelector.jsx b/src/components/CippComponents/CippFormTenantSelector.jsx index 0ce271515d29..4f39e48868d4 100644 --- a/src/components/CippComponents/CippFormTenantSelector.jsx +++ b/src/components/CippComponents/CippFormTenantSelector.jsx @@ -2,7 +2,7 @@ import { useEffect, useState } from "react"; import { CippFormComponent } from "./CippFormComponent"; import { useSettings } from "../../hooks/use-settings"; import { GroupHeader, GroupItems } from "../CippComponents/CippAutocompleteGrouping"; -import { ApiGetCall } from "/src/api/ApiCall"; +import { ApiGetCall } from "../../api/ApiCall"; export const CippFormTenantSelector = ({ formControl, diff --git a/src/components/CippComponents/CippForwardingSection.jsx b/src/components/CippComponents/CippForwardingSection.jsx index df7fcba9b177..24a18345ddc5 100644 --- a/src/components/CippComponents/CippForwardingSection.jsx +++ b/src/components/CippComponents/CippForwardingSection.jsx @@ -3,7 +3,7 @@ import CippFormComponent from "./CippFormComponent"; import { CippFormCondition } from "./CippFormCondition"; import { Grid } from "@mui/system"; import { CippApiResults } from "./CippApiResults"; -import { getCippValidator } from "/src/utils/get-cipp-validator"; +import { getCippValidator } from "../../utils/get-cipp-validator"; const CippForwardingSection = ({ formControl, usersList, contactsList, postRequest, handleSubmit }) => { diff --git a/src/components/CippComponents/CippGeoLocation.jsx b/src/components/CippComponents/CippGeoLocation.jsx index e7a4be63ed66..1621f602ba1d 100644 --- a/src/components/CippComponents/CippGeoLocation.jsx +++ b/src/components/CippComponents/CippGeoLocation.jsx @@ -2,7 +2,7 @@ import { useEffect, useState } from "react"; import { Skeleton } from "@mui/material"; import { Grid } from "@mui/system"; import dynamic from "next/dynamic"; -import { ApiPostCall } from "/src/api/ApiCall"; +import { ApiPostCall } from "../../api/ApiCall"; import { CippPropertyList } from "./CippPropertyList"; import { getCippTranslation } from "../../utils/get-cipp-translation"; import { getCippFormatting } from "../../utils/get-cipp-formatting"; diff --git a/src/components/CippComponents/CippMap.jsx b/src/components/CippComponents/CippMap.jsx index 7f5be9bb4b92..5efed559ef70 100644 --- a/src/components/CippComponents/CippMap.jsx +++ b/src/components/CippComponents/CippMap.jsx @@ -1,11 +1,18 @@ import "leaflet/dist/leaflet.css"; import "react-leaflet-markercluster/styles"; -import "leaflet-defaulticon-compatibility/dist/leaflet-defaulticon-compatibility.webpack.css"; -import "leaflet-defaulticon-compatibility"; import { useEffect, useRef } from "react"; import { MapContainer, Marker, Popup, TileLayer } from "react-leaflet"; +import L from "leaflet"; import MarkerClusterGroup from "react-leaflet-markercluster"; +// Fix leaflet icon paths for Turbopack/Next.js +delete L.Icon.Default.prototype._getIconUrl; +L.Icon.Default.mergeOptions({ + iconRetinaUrl: "https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon-2x.png", + iconUrl: "https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon.png", + shadowUrl: "https://unpkg.com/leaflet@1.9.4/dist/images/marker-shadow.png", +}); + export default function CippMap({ markers = [], zoom = 11, diff --git a/src/components/CippComponents/CippMessageViewer.jsx b/src/components/CippComponents/CippMessageViewer.jsx index 366c17dcc507..e91530db384b 100644 --- a/src/components/CippComponents/CippMessageViewer.jsx +++ b/src/components/CippComponents/CippMessageViewer.jsx @@ -43,7 +43,7 @@ import { CippTimeAgo } from "./CippTimeAgo"; import { CippCodeBlock } from "./CippCodeBlock"; import DOMPurify from "dompurify"; import ReactHtmlParser from "react-html-parser"; -import { FileDropzone } from "/src/components/file-dropzone.js"; +import { FileDropzone } from "../file-dropzone.js"; import CippPageCard from "../CippCards/CippPageCard"; import { MoonIcon, @@ -51,7 +51,7 @@ import { ShieldExclamationIcon, SunIcon, } from "@heroicons/react/24/outline"; -import { useSettings } from "/src/hooks/use-settings"; +import { useSettings } from "../../hooks/use-settings"; import CippForefrontHeaderDialog from "./CippForefrontHeaderDialog"; export const CippMessageViewer = ({ emailSource }) => { diff --git a/src/components/CippComponents/CippPermissionSetDrawer.jsx b/src/components/CippComponents/CippPermissionSetDrawer.jsx index de9f45b6d58f..cd432409a144 100644 --- a/src/components/CippComponents/CippPermissionSetDrawer.jsx +++ b/src/components/CippComponents/CippPermissionSetDrawer.jsx @@ -6,7 +6,7 @@ import { Edit, Add } from "@mui/icons-material"; import { CippOffCanvas } from "./CippOffCanvas"; import CippFormComponent from "./CippFormComponent"; import { CippApiResults } from "./CippApiResults"; -import { ApiGetCall, ApiPostCall } from "/src/api/ApiCall"; +import { ApiGetCall, ApiPostCall } from "../../api/ApiCall"; import CippAppPermissionBuilder from "./CippAppPermissionBuilder"; export const CippPermissionSetDrawer = ({ diff --git a/src/components/CippComponents/CippSankey.jsx b/src/components/CippComponents/CippSankey.jsx index 9fd49e3bc712..eb583b801ac4 100644 --- a/src/components/CippComponents/CippSankey.jsx +++ b/src/components/CippComponents/CippSankey.jsx @@ -1,7 +1,7 @@ import { ResponsiveSankey } from "@nivo/sankey"; -import { useSettings } from "/src/hooks/use-settings"; +import { useSettings } from "../../hooks/use-settings"; -export const CippSankey = ({ data }) => { +export const CippSankey = ({ data, onNodeClick, onLinkClick }) => { const settings = useSettings(); const isDark = settings.currentTheme?.value === "dark"; @@ -27,7 +27,11 @@ export const CippSankey = ({ data }) => { return (
{ sort="input" legends={[]} valueFormat={(value) => `${value}`} + isInteractive={true} + onClick={(node, event) => { + if (onNodeClick && node.id) { + onNodeClick(node); + } else if (onLinkClick && node.source) { + onLinkClick(node); + } + }} />
); diff --git a/src/components/CippComponents/CippTablePage.jsx b/src/components/CippComponents/CippTablePage.jsx index 67bb962173da..b95db81b5a0c 100644 --- a/src/components/CippComponents/CippTablePage.jsx +++ b/src/components/CippComponents/CippTablePage.jsx @@ -3,7 +3,7 @@ import { Box, Container, Stack } from "@mui/system"; import { CippDataTable } from "../CippTable/CippDataTable"; import { useSettings } from "../../hooks/use-settings"; import { CippHead } from "./CippHead"; -import { useState } from "react"; +import { useState, useEffect } from "react"; export const CippTablePage = (props) => { const { @@ -24,11 +24,14 @@ export const CippTablePage = (props) => { tableFilter, tenantInTitle = true, filters, + initialFilters, sx = {}, ...other } = props; const tenant = useSettings().currentTenant; - const [tableFilters] = useState(filters || []); + + // Use initialFilters if provided, otherwise use regular filters + const activeFilters = initialFilters || filters; return ( <> @@ -63,15 +66,7 @@ export const CippTablePage = (props) => { columns={columns} columnsFromApi={columnsFromApi} offCanvas={offCanvas} - filters={tableFilters} - initialState={{ - columnFilters: filters - ? filters.map((filter) => ({ - id: filter.id || filter.columnId, - value: filter.value, - })) - : [], - }} + filters={activeFilters} {...other} />
diff --git a/src/components/CippComponents/CippTemplateEditor.jsx b/src/components/CippComponents/CippTemplateEditor.jsx index e223abf49962..bb2c38af8b53 100644 --- a/src/components/CippComponents/CippTemplateEditor.jsx +++ b/src/components/CippComponents/CippTemplateEditor.jsx @@ -2,11 +2,11 @@ import React, { useEffect, useState } from "react"; import { Box, Typography, Divider } from "@mui/material"; import { Grid } from "@mui/system"; import { useForm } from "react-hook-form"; -import CippFormPage from "/src/components/CippFormPages/CippFormPage"; -import CippFormComponent from "/src/components/CippComponents/CippFormComponent"; -import CippFormSkeleton from "/src/components/CippFormPages/CippFormSkeleton"; -import { ApiGetCall } from "/src/api/ApiCall"; -import { getCippTranslation } from "/src/utils/get-cipp-translation"; +import CippFormPage from "../CippFormPages/CippFormPage"; +import CippFormComponent from "./CippFormComponent"; +import CippFormSkeleton from "../CippFormPages/CippFormSkeleton"; +import { ApiGetCall } from "../../api/ApiCall"; +import { getCippTranslation } from "../../utils/get-cipp-translation"; const CippTemplateEditor = ({ templateId, diff --git a/src/components/CippComponents/CippTemplateFieldRenderer.jsx b/src/components/CippComponents/CippTemplateFieldRenderer.jsx index 7fae93ec413f..5f385bfdda64 100644 --- a/src/components/CippComponents/CippTemplateFieldRenderer.jsx +++ b/src/components/CippComponents/CippTemplateFieldRenderer.jsx @@ -1,9 +1,9 @@ import React from "react"; import { Typography, Divider } from "@mui/material"; import { Grid } from "@mui/system"; -import CippFormComponent from "/src/components/CippComponents/CippFormComponent"; -import { getCippTranslation } from "/src/utils/get-cipp-translation"; -import intuneCollection from "/src/data/intuneCollection.json"; +import CippFormComponent from "./CippFormComponent"; +import { getCippTranslation } from "../../utils/get-cipp-translation"; +import intuneCollection from "../../data/intuneCollection.json"; const CippTemplateFieldRenderer = ({ templateData, diff --git a/src/components/CippComponents/CippTextFieldWithVariables.jsx b/src/components/CippComponents/CippTextFieldWithVariables.jsx index 0f6abd9fea99..80d720ac9440 100644 --- a/src/components/CippComponents/CippTextFieldWithVariables.jsx +++ b/src/components/CippComponents/CippTextFieldWithVariables.jsx @@ -1,7 +1,7 @@ import React, { useState, useRef, useEffect, useMemo, useCallback } from "react"; import { TextField } from "@mui/material"; import { CippVariableAutocomplete } from "./CippVariableAutocomplete"; -import { useSettings } from "/src/hooks/use-settings.js"; +import { useSettings } from "../../hooks/use-settings.js"; /** * Enhanced TextField that supports custom variable autocomplete diff --git a/src/components/CippComponents/CippTranslations.jsx b/src/components/CippComponents/CippTranslations.jsx index 99d46a6e5182..af96b19cd027 100644 --- a/src/components/CippComponents/CippTranslations.jsx +++ b/src/components/CippComponents/CippTranslations.jsx @@ -52,4 +52,11 @@ export const CippTranslations = { includeTenantId: "Include Tenant ID in Notifications", logsToInclude: "Logs to Include in notifications", assignmentFilterManagementType: "Filter Type", + microsoftSupport: "Microsoft Support", + syndicatePartner: "Syndicate Partner", + breadthPartner: "Breadth Partner", + breadthPartnerDelegatedAdmin: "Breadth Partner (Delegated)", + resellerPartnerDelegatedAdmin: "Direct Reseller", + valueAddedResellerPartnerDelegatedAdmin: "Indirect Reseller", + unknownFutureValue: "Unknown", }; diff --git a/src/components/CippComponents/CippTransportRuleDrawer.jsx b/src/components/CippComponents/CippTransportRuleDrawer.jsx index b3beea3d0b1c..494ae0fdce1a 100644 --- a/src/components/CippComponents/CippTransportRuleDrawer.jsx +++ b/src/components/CippComponents/CippTransportRuleDrawer.jsx @@ -7,8 +7,8 @@ import { CippOffCanvas } from "./CippOffCanvas"; import CippFormComponent from "./CippFormComponent"; import { CippFormDomainSelector } from "./CippFormDomainSelector"; import { CippApiResults } from "./CippApiResults"; -import { useSettings } from "/src/hooks/use-settings"; -import { ApiGetCall, ApiPostCall } from "/src/api/ApiCall"; +import { useSettings } from "../../hooks/use-settings"; +import { ApiGetCall, ApiPostCall } from "../../api/ApiCall"; import { useQueryClient } from "@tanstack/react-query"; export const CippTransportRuleDrawer = ({ diff --git a/src/components/CippComponents/CippUserActions.jsx b/src/components/CippComponents/CippUserActions.jsx index 9b79b58fd32c..ac6bf04a952d 100644 --- a/src/components/CippComponents/CippUserActions.jsx +++ b/src/components/CippComponents/CippUserActions.jsx @@ -20,7 +20,7 @@ import { CloudSync, } from "@mui/icons-material"; import { getCippLicenseTranslation } from "../../utils/get-cipp-license-translation"; -import { useSettings } from "/src/hooks/use-settings.js"; +import { useSettings } from "../../hooks/use-settings.js"; import { usePermissions } from "../../hooks/use-permissions"; import { Tooltip, Box } from "@mui/material"; import CippFormComponent from "./CippFormComponent"; diff --git a/src/components/CippComponents/CippVariableAutocomplete.jsx b/src/components/CippComponents/CippVariableAutocomplete.jsx index 9910e9771afd..49e89fda27ee 100644 --- a/src/components/CippComponents/CippVariableAutocomplete.jsx +++ b/src/components/CippComponents/CippVariableAutocomplete.jsx @@ -9,9 +9,9 @@ import { useTheme, CircularProgress, } from "@mui/material"; -import { ApiGetCall } from "/src/api/ApiCall"; -import { useSettings } from "/src/hooks/use-settings.js"; -import { getCippError } from "/src/utils/get-cipp-error"; +import { ApiGetCall } from "../../api/ApiCall"; +import { useSettings } from "../../hooks/use-settings.js"; +import { getCippError } from "../../utils/get-cipp-error"; /** * Autocomplete component specifically for custom variables diff --git a/src/components/CippComponents/DomainAnalyserDialog.jsx b/src/components/CippComponents/DomainAnalyserDialog.jsx index 803baf43f154..ed5a6a948119 100644 --- a/src/components/CippComponents/DomainAnalyserDialog.jsx +++ b/src/components/CippComponents/DomainAnalyserDialog.jsx @@ -3,7 +3,7 @@ import { Dialog, DialogContent, DialogTitle, Button, DialogActions } from "@mui/ import { Refresh } from "@mui/icons-material"; import { useForm, FormProvider } from "react-hook-form"; import { CippFormTenantSelector } from "./CippFormTenantSelector"; -import { ApiPostCall } from "/src/api/ApiCall"; +import { ApiPostCall } from "../../api/ApiCall"; import { CippApiResults } from "./CippApiResults"; export const DomainAnalyserDialog = ({ createDialog }) => { diff --git a/src/components/CippComponents/LicenseCard.jsx b/src/components/CippComponents/LicenseCard.jsx index d6762196bc9b..dce02b1e12f6 100644 --- a/src/components/CippComponents/LicenseCard.jsx +++ b/src/components/CippComponents/LicenseCard.jsx @@ -90,7 +90,7 @@ export const LicenseCard = ({ data, isLoading }) => { const stats = calculateStats(); return ( - + diff --git a/src/components/CippComponents/MFACard.jsx b/src/components/CippComponents/MFACard.jsx index 3b2468415958..e166c3b496a0 100644 --- a/src/components/CippComponents/MFACard.jsx +++ b/src/components/CippComponents/MFACard.jsx @@ -1,8 +1,10 @@ import { Box, Card, CardHeader, CardContent, Typography, Skeleton } from "@mui/material"; import { Person as UserIcon } from "@mui/icons-material"; import { CippSankey } from "./CippSankey"; +import { useRouter } from "next/router"; export const MFACard = ({ data, isLoading }) => { + const router = useRouter(); // Process data inside component const processData = () => { if (!data || !Array.isArray(data) || data.length === 0) { @@ -106,8 +108,106 @@ export const MFACard = ({ data, isLoading }) => { const processedData = processData(); + const handleNodeClick = (node) => { + // Build filter based on clicked node + let filters = []; + + switch (node.id) { + case "Enabled users": + filters = [{ id: "AccountEnabled", value: "Yes" }]; + break; + case "MFA registered": + filters = [ + { id: "AccountEnabled", value: "Yes" }, + { id: "MFARegistration", value: "Yes" }, + ]; + break; + case "Not registered": + filters = [ + { id: "AccountEnabled", value: "Yes" }, + { id: "MFARegistration", value: "No" }, + ]; + break; + default: + // For other nodes, don't navigate + return; + } + + // Navigate to MFA report with filters + router.push({ + pathname: "/identity/reports/mfa-report", + query: { filters: JSON.stringify(filters) }, + }); + }; + + const handleLinkClick = (link) => { + // Build filters based on the link's source and target + let filters = []; + + if (link.source.id === "Enabled users" && link.target.id === "MFA registered") { + filters = [ + { id: "AccountEnabled", value: "Yes" }, + { id: "MFARegistration", value: "Yes" }, + ]; + } else if (link.source.id === "Enabled users" && link.target.id === "Not registered") { + filters = [ + { id: "AccountEnabled", value: "Yes" }, + { id: "MFARegistration", value: "No" }, + ]; + } else if (link.source.id === "MFA registered" && link.target.id === "CA policy") { + filters = [ + { id: "AccountEnabled", value: "Yes" }, + { id: "MFARegistration", value: "Yes" }, + ]; + // Note: We can't easily filter by CoveredByCA in the table since it needs complex logic + } else if (link.source.id === "MFA registered" && link.target.id === "Security defaults") { + filters = [ + { id: "AccountEnabled", value: "Yes" }, + { id: "MFARegistration", value: "Yes" }, + { id: "CoveredBySD", value: "Yes" }, + ]; + } else if (link.source.id === "MFA registered" && link.target.id === "Per-user MFA") { + filters = [{ id: "AccountEnabled", value: "Yes" }]; + // Note: Per-user MFA can be "enabled" or "enforced" + } else if (link.source.id === "MFA registered" && link.target.id === "No enforcement") { + filters = [ + { id: "AccountEnabled", value: "Yes" }, + { id: "MFARegistration", value: "Yes" }, + ]; + } else if (link.source.id === "Not registered" && link.target.id === "CA policy") { + filters = [ + { id: "AccountEnabled", value: "Yes" }, + { id: "MFARegistration", value: "No" }, + ]; + } else if (link.source.id === "Not registered" && link.target.id === "Security defaults") { + filters = [ + { id: "AccountEnabled", value: "Yes" }, + { id: "MFARegistration", value: "No" }, + { id: "CoveredBySD", value: "Yes" }, + ]; + } else if (link.source.id === "Not registered" && link.target.id === "Per-user MFA") { + filters = [ + { id: "AccountEnabled", value: "Yes" }, + { id: "MFARegistration", value: "No" }, + ]; + } else if (link.source.id === "Not registered" && link.target.id === "No enforcement") { + filters = [ + { id: "AccountEnabled", value: "Yes" }, + { id: "MFARegistration", value: "No" }, + ]; + } + + // Navigate to MFA report with filters + if (filters.length > 0) { + router.push({ + pathname: "/identity/reports/mfa-report", + query: { filters: JSON.stringify(filters) }, + }); + } + }; + return ( - + @@ -122,7 +222,11 @@ export const MFACard = ({ data, isLoading }) => { {isLoading ? ( ) : processedData ? ( - + ) : ( { alignItems: "center", justifyContent: "center", height: "100%", + width: "100%", }} > diff --git a/src/components/CippComponents/ScheduledTaskDetails.jsx b/src/components/CippComponents/ScheduledTaskDetails.jsx index c02cf9d8f3f6..51991b1b88a7 100644 --- a/src/components/CippComponents/ScheduledTaskDetails.jsx +++ b/src/components/CippComponents/ScheduledTaskDetails.jsx @@ -19,8 +19,8 @@ import { CippPropertyListCard } from "../CippCards/CippPropertyListCard"; import { ExpandMore, Sync, Search, Close } from "@mui/icons-material"; import { getCippFormatting } from "../../utils/get-cipp-formatting"; import { CippDataTable } from "../CippTable/CippDataTable"; -import { CippTimeAgo } from "/src/components/CippComponents/CippTimeAgo"; -import { ActionsMenu } from "/src/components/actions-menu"; +import { CippTimeAgo } from "./CippTimeAgo"; +import { ActionsMenu } from "../actions-menu"; import { CippScheduledTaskActions } from "./CippScheduledTaskActions"; import { CippApiLogsDrawer } from "./CippApiLogsDrawer"; diff --git a/src/components/CippComponents/SecureScoreCard.jsx b/src/components/CippComponents/SecureScoreCard.jsx index da849c069b3c..a26a3c466d20 100644 --- a/src/components/CippComponents/SecureScoreCard.jsx +++ b/src/components/CippComponents/SecureScoreCard.jsx @@ -12,7 +12,7 @@ import { export const SecureScoreCard = ({ data, isLoading }) => { return ( - + @@ -58,43 +58,65 @@ export const SecureScoreCard = ({ data, isLoading }) => { <> - new Date(a.createdDateTime) - new Date(b.createdDateTime)) - .map((score) => ({ - date: new Date(score.createdDateTime).toLocaleDateString("en-US", { - month: "short", - day: "numeric", - }), - score: score.currentScore, - percentage: Math.round((score.currentScore / score.maxScore) * 100), - }))} - margin={{ left: 12, right: 12, top: 10, bottom: 10 }} - > - - - - { - if (name === "score") return [value.toFixed(2), "Score"]; - if (name === "percentage") return [value + "%", "Percentage"]; - return value; - }} - /> - - + {(() => { + const sortedData = [...data].sort((a, b) => new Date(a.createdDateTime) - new Date(b.createdDateTime)); + const chartData = sortedData.map((score) => ({ + date: new Date(score.createdDateTime).toLocaleDateString("en-US", { + month: "short", + day: "numeric", + }), + score: score.currentScore, + percentage: Math.round((score.currentScore / score.maxScore) * 100), + })); + const ticks = chartData.map((d) => d.date); + return ( + + + + Math.round(value)} + /> + { + if (name === "score") return [value.toFixed(2), "Score"]; + if (name === "percentage") return [value + "%", "Percentage"]; + return value; + }} + /> + + + ); + })()} diff --git a/src/components/CippFormPages/CippAddAssignmentFilterForm.jsx b/src/components/CippFormPages/CippAddAssignmentFilterForm.jsx index 447b6ae4012d..551ec914e35b 100644 --- a/src/components/CippFormPages/CippAddAssignmentFilterForm.jsx +++ b/src/components/CippFormPages/CippAddAssignmentFilterForm.jsx @@ -1,7 +1,7 @@ import "@mui/material"; import { Grid } from "@mui/system"; import { useWatch } from "react-hook-form"; -import CippFormComponent from "/src/components/CippComponents/CippFormComponent"; +import CippFormComponent from "../CippComponents/CippFormComponent"; const DEVICE_PLATFORM_OPTIONS = [ { label: "Windows 10 and later", value: "windows10AndLater" }, diff --git a/src/components/CippFormPages/CippAddAssignmentFilterTemplateForm.jsx b/src/components/CippFormPages/CippAddAssignmentFilterTemplateForm.jsx index 2b43d8f4c6b6..626b15db6e7a 100644 --- a/src/components/CippFormPages/CippAddAssignmentFilterTemplateForm.jsx +++ b/src/components/CippFormPages/CippAddAssignmentFilterTemplateForm.jsx @@ -1,7 +1,7 @@ import "@mui/material"; import { Grid } from "@mui/system"; import { useWatch } from "react-hook-form"; -import CippFormComponent from "/src/components/CippComponents/CippFormComponent"; +import CippFormComponent from "../CippComponents/CippFormComponent"; const DEVICE_PLATFORM_OPTIONS = [ { label: "Windows 10 and later", value: "windows10AndLater" }, diff --git a/src/components/CippFormPages/CippAddEditContact.jsx b/src/components/CippFormPages/CippAddEditContact.jsx index cbc96616d37c..1e038f8231a5 100644 --- a/src/components/CippFormPages/CippAddEditContact.jsx +++ b/src/components/CippFormPages/CippAddEditContact.jsx @@ -1,8 +1,8 @@ import { Divider } from "@mui/material"; import { Grid } from "@mui/system"; -import CippFormComponent from "/src/components/CippComponents/CippFormComponent"; -import { getCippValidator } from "/src/utils/get-cipp-validator"; -import countryList from "/src/data/countryList.json"; +import CippFormComponent from "../CippComponents/CippFormComponent"; +import { getCippValidator } from "../../utils/get-cipp-validator"; +import countryList from "../../data/countryList.json"; const countryOptions = countryList.map(({ Code, Name }) => ({ label: Name, diff --git a/src/components/CippFormPages/CippAddEditGdapRoleTemplate.jsx b/src/components/CippFormPages/CippAddEditGdapRoleTemplate.jsx index 1ed0e4163f88..891935f0f99a 100644 --- a/src/components/CippFormPages/CippAddEditGdapRoleTemplate.jsx +++ b/src/components/CippFormPages/CippAddEditGdapRoleTemplate.jsx @@ -1,5 +1,5 @@ import { Alert, Box, Stack, Typography } from "@mui/material"; -import CippFormComponent from "/src/components/CippComponents/CippFormComponent"; +import CippFormComponent from "../CippComponents/CippFormComponent"; export const CippAddEditGdapRoleTemplate = (props) => { const { formControl, availableRoles } = props; diff --git a/src/components/CippFormPages/CippAddEditUser.jsx b/src/components/CippFormPages/CippAddEditUser.jsx index 79b42de33f6f..87e8088861a0 100644 --- a/src/components/CippFormPages/CippAddEditUser.jsx +++ b/src/components/CippFormPages/CippAddEditUser.jsx @@ -1,10 +1,10 @@ import { Alert, Divider, InputAdornment, Typography } from "@mui/material"; -import CippFormComponent from "/src/components/CippComponents/CippFormComponent"; -import { CippFormCondition } from "/src/components/CippComponents/CippFormCondition"; -import { CippFormDomainSelector } from "/src/components/CippComponents/CippFormDomainSelector"; -import { CippFormUserSelector } from "/src/components/CippComponents/CippFormUserSelector"; -import countryList from "/src/data/countryList.json"; -import { CippFormLicenseSelector } from "/src/components/CippComponents/CippFormLicenseSelector"; +import CippFormComponent from "../CippComponents/CippFormComponent"; +import { CippFormCondition } from "../CippComponents/CippFormCondition"; +import { CippFormDomainSelector } from "../CippComponents/CippFormDomainSelector"; +import { CippFormUserSelector } from "../CippComponents/CippFormUserSelector"; +import countryList from "../../data/countryList.json"; +import { CippFormLicenseSelector } from "../CippComponents/CippFormLicenseSelector"; import { Grid } from "@mui/system"; import { ApiGetCall } from "../../api/ApiCall"; import { useSettings } from "../../hooks/use-settings"; diff --git a/src/components/CippFormPages/CippAddGroupForm.jsx b/src/components/CippFormPages/CippAddGroupForm.jsx index 9644b0426faf..713bb414c638 100644 --- a/src/components/CippFormPages/CippAddGroupForm.jsx +++ b/src/components/CippFormPages/CippAddGroupForm.jsx @@ -1,7 +1,7 @@ import { InputAdornment } from "@mui/material"; import { Grid } from "@mui/system"; -import CippFormComponent from "/src/components/CippComponents/CippFormComponent"; -import { CippFormCondition } from "/src/components/CippComponents/CippFormCondition"; +import CippFormComponent from "../CippComponents/CippFormComponent"; +import { CippFormCondition } from "../CippComponents/CippFormCondition"; import { CippFormDomainSelector } from "../CippComponents/CippFormDomainSelector"; import { CippFormUserSelector } from "../CippComponents/CippFormUserSelector"; diff --git a/src/components/CippFormPages/CippAddGroupTemplateForm.jsx b/src/components/CippFormPages/CippAddGroupTemplateForm.jsx index 8db3b1ebea3f..36747ee70f32 100644 --- a/src/components/CippFormPages/CippAddGroupTemplateForm.jsx +++ b/src/components/CippFormPages/CippAddGroupTemplateForm.jsx @@ -1,8 +1,8 @@ import { useEffect } from "react"; import "@mui/material"; import { Grid } from "@mui/system"; -import CippFormComponent from "/src/components/CippComponents/CippFormComponent"; -import { CippFormCondition } from "/src/components/CippComponents/CippFormCondition"; +import CippFormComponent from "../CippComponents/CippFormComponent"; +import { CippFormCondition } from "../CippComponents/CippFormCondition"; const CippAddGroupTemplateForm = (props) => { const { formControl } = props; diff --git a/src/components/CippFormPages/CippCustomDataMappingForm.jsx b/src/components/CippFormPages/CippCustomDataMappingForm.jsx index f8dce65b8592..8a5d30af5da7 100644 --- a/src/components/CippFormPages/CippCustomDataMappingForm.jsx +++ b/src/components/CippFormPages/CippCustomDataMappingForm.jsx @@ -1,13 +1,13 @@ import { useWatch } from "react-hook-form"; import { Box, Stack, Typography, Divider } from "@mui/material"; import { Grid } from "@mui/system"; -import { CippFormComponent } from "/src/components/CippComponents/CippFormComponent"; -import { CippFormTenantSelector } from "/src/components/CippComponents/CippFormTenantSelector"; -import { CippFormCondition } from "/src/components/CippComponents/CippFormCondition"; -import { CippPropertyListCard } from "/src/components/CippCards/CippPropertyListCard"; -import { CippCopyToClipBoard } from "/src/components/CippComponents/CippCopyToClipboard"; -import extensionDataMapping from "/src/data/extensionDataMapping"; -import { getCippTranslation } from "/src/utils/get-cipp-translation"; +import { CippFormComponent } from "../CippComponents/CippFormComponent"; +import { CippFormTenantSelector } from "../CippComponents/CippFormTenantSelector"; +import { CippFormCondition } from "../CippComponents/CippFormCondition"; +import { CippPropertyListCard } from "../CippCards/CippPropertyListCard"; +import { CippCopyToClipBoard } from "../CippComponents/CippCopyToClipboard"; +import extensionDataMapping from "../../data/extensionDataMapping"; +import { getCippTranslation } from "../../utils/get-cipp-translation"; const CippCustomDataMappingForm = ({ formControl }) => { const selectedAttribute = useWatch({ control: formControl.control, name: "customDataAttribute" }); diff --git a/src/components/CippFormPages/CippExchangeSettingsForm.jsx b/src/components/CippFormPages/CippExchangeSettingsForm.jsx index db7c15da5af8..ee8bfc143074 100644 --- a/src/components/CippFormPages/CippExchangeSettingsForm.jsx +++ b/src/components/CippFormPages/CippExchangeSettingsForm.jsx @@ -13,7 +13,7 @@ import { IconButton, } from "@mui/material"; import { Check, Error, Sync } from "@mui/icons-material"; -import CippFormComponent from "/src/components/CippComponents/CippFormComponent"; +import CippFormComponent from "../CippComponents/CippFormComponent"; import { ApiGetCall, ApiPostCall } from "../../api/ApiCall"; import { useSettings } from "../../hooks/use-settings"; import { Grid } from "@mui/system"; diff --git a/src/components/CippFormPages/CippInviteGuest.jsx b/src/components/CippFormPages/CippInviteGuest.jsx index 7d62d071da0b..225c3282dd45 100644 --- a/src/components/CippFormPages/CippInviteGuest.jsx +++ b/src/components/CippFormPages/CippInviteGuest.jsx @@ -1,6 +1,6 @@ import "@mui/material"; import { Grid } from "@mui/system"; -import CippFormComponent from "/src/components/CippComponents/CippFormComponent"; +import CippFormComponent from "../CippComponents/CippFormComponent"; const CippInviteUser = (props) => { const { formControl, userSettingsDefaults } = props; diff --git a/src/components/CippFormPages/CippJSONView.jsx b/src/components/CippFormPages/CippJSONView.jsx index 0215385cbc89..4f082ef9ac33 100644 --- a/src/components/CippFormPages/CippJSONView.jsx +++ b/src/components/CippFormPages/CippJSONView.jsx @@ -19,7 +19,7 @@ import { PropertyList } from "../property-list"; import { getCippTranslation } from "../../utils/get-cipp-translation"; import { getCippFormatting } from "../../utils/get-cipp-formatting"; import { CippCodeBlock } from "../CippComponents/CippCodeBlock"; -import intuneCollection from "/src/data/intuneCollection.json"; +import intuneCollection from "../../data/intuneCollection.json"; import { useGuidResolver } from "../../hooks/use-guid-resolver"; const cleanObject = (obj) => { diff --git a/src/components/CippFormPages/CippSafeLinksPolicyRuleForm.jsx b/src/components/CippFormPages/CippSafeLinksPolicyRuleForm.jsx index ce25cc269028..2937aec1ae1a 100644 --- a/src/components/CippFormPages/CippSafeLinksPolicyRuleForm.jsx +++ b/src/components/CippFormPages/CippSafeLinksPolicyRuleForm.jsx @@ -1,15 +1,15 @@ import { useEffect, useState } from "react"; import { Grid } from "@mui/system"; -import CippFormComponent from "/src/components/CippComponents/CippFormComponent"; +import CippFormComponent from "../CippComponents/CippFormComponent"; import { Typography } from "@mui/material"; -import { CippFormUserSelector } from "/src/components/CippComponents/CippFormUserSelector"; -import { CippFormGroupSelector } from "/src/components/CippComponents/CippFormGroupSelector"; -import { CippFormDomainSelector } from "/src/components/CippComponents/CippFormDomainSelector"; -import { CippInfoCard } from "/src/components/CippCards/CippInfoCard"; +import { CippFormUserSelector } from "../CippComponents/CippFormUserSelector"; +import { CippFormGroupSelector } from "../CippComponents/CippFormGroupSelector"; +import { CippFormDomainSelector } from "../CippComponents/CippFormDomainSelector"; +import { CippInfoCard } from "../CippCards/CippInfoCard"; import { InformationCircleIcon } from "@heroicons/react/24/outline"; -import { getCippValidator } from "/src/utils/get-cipp-validator"; -import { ApiGetCall } from "/src/api/ApiCall"; -import { useSettings } from "/src/hooks/use-settings"; +import { getCippValidator } from "../../utils/get-cipp-validator"; +import { ApiGetCall } from "../../api/ApiCall"; +import { useSettings } from "../../hooks/use-settings"; // Utility functions for data processing export const safeLinksDataUtils = { diff --git a/src/components/CippFormPages/CippSchedulerForm.jsx b/src/components/CippFormPages/CippSchedulerForm.jsx index f134461bce8c..8857a9d427a5 100644 --- a/src/components/CippFormPages/CippSchedulerForm.jsx +++ b/src/components/CippFormPages/CippSchedulerForm.jsx @@ -14,15 +14,15 @@ import { } from "@mui/material"; import { Grid, Stack } from "@mui/system"; import { useWatch } from "react-hook-form"; -import CippFormComponent from "/src/components/CippComponents/CippFormComponent"; -import { CippFormTenantSelector } from "/src/components/CippComponents/CippFormTenantSelector"; -import { CippFormCondition } from "/src/components/CippComponents/CippFormCondition"; -import CippGraphResourceSelector from "/src/components/CippComponents/CippGraphResourceSelector"; -import CippGraphAttributeSelector from "/src/components/CippComponents/CippGraphAttributeSelector"; -import { getCippValidator } from "/src/utils/get-cipp-validator"; +import CippFormComponent from "../CippComponents/CippFormComponent"; +import { CippFormTenantSelector } from "../CippComponents/CippFormTenantSelector"; +import { CippFormCondition } from "../CippComponents/CippFormCondition"; +import CippGraphResourceSelector from "../CippComponents/CippGraphResourceSelector"; +import CippGraphAttributeSelector from "../CippComponents/CippGraphAttributeSelector"; +import { getCippValidator } from "../../utils/get-cipp-validator"; import { useRouter } from "next/router"; import Link from "next/link"; -import { ApiGetCall, ApiPostCall } from "/src/api/ApiCall"; +import { ApiGetCall, ApiPostCall } from "../../api/ApiCall"; import { useEffect, useState } from "react"; import CippFormInputArray from "../CippComponents/CippFormInputArray"; import { CippApiResults } from "../CippComponents/CippApiResults"; diff --git a/src/components/CippIntegrations/CippApiClientManagement.jsx b/src/components/CippIntegrations/CippApiClientManagement.jsx index 4f42eb3d99a7..829ad4413ce2 100644 --- a/src/components/CippIntegrations/CippApiClientManagement.jsx +++ b/src/components/CippIntegrations/CippApiClientManagement.jsx @@ -2,7 +2,7 @@ import { Button, Stack, SvgIcon, Menu, MenuItem, ListItemText, Alert } from "@mu import { useState } from "react"; import isEqual from "lodash/isEqual"; import { useForm } from "react-hook-form"; -import { ApiGetCall, ApiGetCallWithPagination, ApiPostCall } from "/src/api/ApiCall"; +import { ApiGetCall, ApiGetCallWithPagination, ApiPostCall } from "../../api/ApiCall"; import { CippDataTable } from "../CippTable/CippDataTable"; import { ChevronDownIcon, diff --git a/src/components/CippIntegrations/CippIntegrationFieldMapping.jsx b/src/components/CippIntegrations/CippIntegrationFieldMapping.jsx index ae0014d0e276..53a88787de19 100644 --- a/src/components/CippIntegrations/CippIntegrationFieldMapping.jsx +++ b/src/components/CippIntegrations/CippIntegrationFieldMapping.jsx @@ -8,13 +8,13 @@ import { Button, Alert, } from "@mui/material"; -import CippFormSection from "/src/components/CippFormPages/CippFormSection"; +import CippFormSection from "../CippFormPages/CippFormSection"; import { useForm } from "react-hook-form"; -import { ApiGetCall } from "/src/api/ApiCall"; +import { ApiGetCall } from "../../api/ApiCall"; import { useRouter } from "next/router"; -import extensions from "/src/data/Extensions.json"; +import extensions from "../../data/Extensions.json"; import React, { useEffect, useState } from "react"; -import CippFormComponent from "/src/components/CippComponents/CippFormComponent"; +import CippFormComponent from "../CippComponents/CippFormComponent"; import { Sync } from "@mui/icons-material"; import { Stack, Grid } from "@mui/system"; diff --git a/src/components/CippIntegrations/CippIntegrationSettings.jsx b/src/components/CippIntegrations/CippIntegrationSettings.jsx index 3ff5bea6f256..d0156df3897a 100644 --- a/src/components/CippIntegrations/CippIntegrationSettings.jsx +++ b/src/components/CippIntegrations/CippIntegrationSettings.jsx @@ -1,12 +1,12 @@ import { Box, CardContent } from "@mui/material"; import { Grid } from "@mui/system"; -import CippFormSection from "/src/components/CippFormPages/CippFormSection"; -import CippFormComponent from "/src/components/CippComponents/CippFormComponent"; +import CippFormSection from "../CippFormPages/CippFormSection"; +import CippFormComponent from "../CippComponents/CippFormComponent"; import { useForm } from "react-hook-form"; -import { useSettings } from "/src/hooks/use-settings"; -import { ApiGetCall } from "/src/api/ApiCall"; +import { useSettings } from "../../hooks/use-settings"; +import { ApiGetCall } from "../../api/ApiCall"; import { useRouter } from "next/router"; -import extensions from "/src/data/Extensions.json"; +import extensions from "../../data/Extensions.json"; import React, { useEffect } from "react"; import { CippFormCondition } from "../CippComponents/CippFormCondition"; diff --git a/src/components/CippIntegrations/CippIntegrationTenantMapping.jsx b/src/components/CippIntegrations/CippIntegrationTenantMapping.jsx index 57680d8bae7d..cfe214218139 100644 --- a/src/components/CippIntegrations/CippIntegrationTenantMapping.jsx +++ b/src/components/CippIntegrations/CippIntegrationTenantMapping.jsx @@ -12,9 +12,9 @@ import { import { Grid } from "@mui/system"; import { useState, useMemo } from "react"; import { useForm } from "react-hook-form"; -import { ApiGetCall, ApiPostCall } from "/src/api/ApiCall"; +import { ApiGetCall, ApiPostCall } from "../../api/ApiCall"; import { useRouter } from "next/router"; -import extensions from "/src/data/Extensions.json"; +import extensions from "../../data/Extensions.json"; import { useEffect } from "react"; import { CippDataTable } from "../CippTable/CippDataTable"; import { PlusSmallIcon, SparklesIcon, TrashIcon } from "@heroicons/react/24/outline"; diff --git a/src/components/CippSettings/CippBackendCard.jsx b/src/components/CippSettings/CippBackendCard.jsx index 2b0890b0f340..6c9465ae5a90 100644 --- a/src/components/CippSettings/CippBackendCard.jsx +++ b/src/components/CippSettings/CippBackendCard.jsx @@ -1,9 +1,9 @@ import { OpenInNew } from "@mui/icons-material"; -import CippButtonCard from "/src/components/CippCards/CippButtonCard"; +import CippButtonCard from "../CippCards/CippButtonCard"; import { Button, Stack, SvgIcon, Typography } from "@mui/material"; import { CippOffCanvas } from "../CippComponents/CippOffCanvas"; import { useState } from "react"; -import { getCippTranslation } from "/src/utils/get-cipp-translation"; +import { getCippTranslation } from "../../utils/get-cipp-translation"; export const CippBackendCard = ({ backendComponents, item, hosted }) => { const [open, setOpen] = useState(false); diff --git a/src/components/CippSettings/CippBackupRetentionSettings.jsx b/src/components/CippSettings/CippBackupRetentionSettings.jsx index bcd74ec4bb5d..38cd78ed2ceb 100644 --- a/src/components/CippSettings/CippBackupRetentionSettings.jsx +++ b/src/components/CippSettings/CippBackupRetentionSettings.jsx @@ -1,6 +1,6 @@ import { Button, ButtonGroup, SvgIcon, Typography, TextField, Box } from "@mui/material"; -import CippButtonCard from "/src/components/CippCards/CippButtonCard"; -import { ApiGetCall, ApiPostCall } from "/src/api/ApiCall"; +import CippButtonCard from "../CippCards/CippButtonCard"; +import { ApiGetCall, ApiPostCall } from "../../api/ApiCall"; import { History } from "@mui/icons-material"; import { useState, useEffect } from "react"; diff --git a/src/components/CippSettings/CippBackupSettings.jsx b/src/components/CippSettings/CippBackupSettings.jsx index 39663651f7d2..a7f56afe7d0f 100644 --- a/src/components/CippSettings/CippBackupSettings.jsx +++ b/src/components/CippSettings/CippBackupSettings.jsx @@ -1,7 +1,7 @@ import { Button, SvgIcon, Typography } from "@mui/material"; -import CippButtonCard from "/src/components/CippCards/CippButtonCard"; -import { ApiPostCall } from "/src/api/ApiCall"; -import { useDialog } from "/src/hooks/use-dialog"; +import CippButtonCard from "../CippCards/CippButtonCard"; +import { ApiPostCall } from "../../api/ApiCall"; +import { useDialog } from "../../hooks/use-dialog"; import { SettingsBackupRestore } from "@mui/icons-material"; import Link from "next/link"; diff --git a/src/components/CippSettings/CippBrandingSettings.jsx b/src/components/CippSettings/CippBrandingSettings.jsx index 88838995811a..b0e0f747ef35 100644 --- a/src/components/CippSettings/CippBrandingSettings.jsx +++ b/src/components/CippSettings/CippBrandingSettings.jsx @@ -1,9 +1,9 @@ import { useState } from "react"; import { Button, Typography, Box, Alert } from "@mui/material"; import { Palette, Upload } from "@mui/icons-material"; -import CippButtonCard from "/src/components/CippCards/CippButtonCard"; -import { ApiGetCall, ApiPostCall } from "/src/api/ApiCall"; -import { useSettings } from "/src/hooks/use-settings"; +import CippButtonCard from "../CippCards/CippButtonCard"; +import { ApiGetCall, ApiPostCall } from "../../api/ApiCall"; +import { useSettings } from "../../hooks/use-settings"; import { CippApiResults } from "../CippComponents/CippApiResults"; import CippFormComponent from "../CippComponents/CippFormComponent"; import { useForm } from "react-hook-form"; diff --git a/src/components/CippSettings/CippCacheSettings.jsx b/src/components/CippSettings/CippCacheSettings.jsx index ad736adf604f..3b9ebf55ec53 100644 --- a/src/components/CippSettings/CippCacheSettings.jsx +++ b/src/components/CippSettings/CippCacheSettings.jsx @@ -1,8 +1,8 @@ import { Button, SvgIcon, Typography } from "@mui/material"; -import CippButtonCard from "/src/components/CippCards/CippButtonCard"; -import { ApiPostCall } from "/src/api/ApiCall"; +import CippButtonCard from "../CippCards/CippButtonCard"; +import { ApiPostCall } from "../../api/ApiCall"; import { CippApiDialog } from "../CippComponents/CippApiDialog"; -import { useDialog } from "/src/hooks/use-dialog"; +import { useDialog } from "../../hooks/use-dialog"; import { TrashIcon } from "@heroicons/react/24/outline"; const CippCacheSettings = () => { diff --git a/src/components/CippSettings/CippDnsSettings.jsx b/src/components/CippSettings/CippDnsSettings.jsx index 847c0451bf87..666337169266 100644 --- a/src/components/CippSettings/CippDnsSettings.jsx +++ b/src/components/CippSettings/CippDnsSettings.jsx @@ -1,6 +1,6 @@ import { Button, ButtonGroup, SvgIcon, Typography } from "@mui/material"; -import CippButtonCard from "/src/components/CippCards/CippButtonCard"; -import { ApiGetCall, ApiPostCall } from "/src/api/ApiCall"; +import CippButtonCard from "../CippCards/CippButtonCard"; +import { ApiGetCall, ApiPostCall } from "../../api/ApiCall"; import { Dns } from "@mui/icons-material"; const CippDnsSettings = () => { @@ -23,7 +23,7 @@ const CippDnsSettings = () => { }; const DnsButtons = () => { - const resolvers = ["Google", "Cloudflare", "Quad9"]; + const resolvers = ["Google", "Cloudflare"]; return resolvers.map((resolver, index) => (