mirror of
https://github.com/okieselbach/AutopilotMonitor.git
synced 2026-10-24 12:42:38 +00:00
Validation disabling waring, and script links to Intune portal
This commit is contained in:
+88
-24
@@ -1,5 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
|
||||
interface AutopilotValidationSectionProps {
|
||||
validateAutopilotDevice: boolean;
|
||||
setValidateAutopilotDevice: (value: boolean) => void;
|
||||
@@ -20,6 +22,40 @@ export default function AutopilotValidationSection({
|
||||
onBeginConsent,
|
||||
}: AutopilotValidationSectionProps) {
|
||||
const anyValidationEnabled = validateAutopilotDevice || validateCorporateIdentifier;
|
||||
const [disableConfirm, setDisableConfirm] = useState<'autopilot' | 'corporate' | null>(null);
|
||||
|
||||
const handleToggleAutopilot = () => {
|
||||
if (validateAutopilotDevice) {
|
||||
setDisableConfirm('autopilot');
|
||||
} else {
|
||||
if (validateCorporateIdentifier) {
|
||||
setValidateAutopilotDevice(true);
|
||||
} else {
|
||||
onBeginConsent('autopilot');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleToggleCorporate = () => {
|
||||
if (validateCorporateIdentifier) {
|
||||
setDisableConfirm('corporate');
|
||||
} else {
|
||||
if (validateAutopilotDevice) {
|
||||
setValidateCorporateIdentifier(true);
|
||||
} else {
|
||||
onBeginConsent('corporate');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const confirmDisable = () => {
|
||||
if (disableConfirm === 'autopilot') {
|
||||
setValidateAutopilotDevice(false);
|
||||
} else if (disableConfirm === 'corporate') {
|
||||
setValidateCorporateIdentifier(false);
|
||||
}
|
||||
setDisableConfirm(null);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="bg-white rounded-lg shadow">
|
||||
@@ -50,18 +86,7 @@ export default function AutopilotValidationSection({
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
onClick={() => {
|
||||
if (validateAutopilotDevice) {
|
||||
setValidateAutopilotDevice(false);
|
||||
} else {
|
||||
// If corporate identifier is already on, consent exists — just enable
|
||||
if (validateCorporateIdentifier) {
|
||||
setValidateAutopilotDevice(true);
|
||||
} else {
|
||||
onBeginConsent('autopilot');
|
||||
}
|
||||
}
|
||||
}}
|
||||
onClick={handleToggleAutopilot}
|
||||
disabled={saving || autopilotConsentInProgress}
|
||||
className={`relative inline-flex h-6 w-11 shrink-0 items-center rounded-full transition-colors disabled:opacity-60 disabled:cursor-not-allowed ${validateAutopilotDevice ? 'bg-emerald-500' : 'bg-gray-300'}`}
|
||||
>
|
||||
@@ -82,18 +107,7 @@ export default function AutopilotValidationSection({
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
onClick={() => {
|
||||
if (validateCorporateIdentifier) {
|
||||
setValidateCorporateIdentifier(false);
|
||||
} else {
|
||||
// If autopilot is already on, consent exists — just enable
|
||||
if (validateAutopilotDevice) {
|
||||
setValidateCorporateIdentifier(true);
|
||||
} else {
|
||||
onBeginConsent('corporate');
|
||||
}
|
||||
}
|
||||
}}
|
||||
onClick={handleToggleCorporate}
|
||||
disabled={saving || autopilotConsentInProgress}
|
||||
className={`relative inline-flex h-6 w-11 shrink-0 items-center rounded-full transition-colors disabled:opacity-60 disabled:cursor-not-allowed ${validateCorporateIdentifier ? 'bg-emerald-500' : 'bg-gray-300'}`}
|
||||
>
|
||||
@@ -115,6 +129,56 @@ export default function AutopilotValidationSection({
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Disable Validation Confirmation Dialog */}
|
||||
{disableConfirm && (
|
||||
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4">
|
||||
<div className="bg-white rounded-lg shadow-xl max-w-md w-full p-6">
|
||||
<div className="flex items-center space-x-3 mb-4">
|
||||
<div className="w-12 h-12 bg-amber-100 rounded-full flex items-center justify-center flex-shrink-0">
|
||||
<svg className="w-6 h-6 text-amber-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-lg font-bold text-gray-900">Disable Validation</h3>
|
||||
<p className="text-sm text-amber-600 font-medium">
|
||||
{disableConfirm === 'autopilot' ? 'Autopilot Device Validation' : 'Corporate Identifier Validation'}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p className="text-sm text-gray-700 mb-2">
|
||||
Are you sure you want to disable this validation?
|
||||
</p>
|
||||
{disableConfirm === 'autopilot' && !validateCorporateIdentifier && (
|
||||
<div className="bg-red-50 border border-red-200 rounded-lg p-3 mb-4 text-sm text-red-800">
|
||||
This is the last active validation. Disabling it will cause the backend to <strong>reject all agent requests</strong> for this tenant.
|
||||
</div>
|
||||
)}
|
||||
{disableConfirm === 'corporate' && !validateAutopilotDevice && (
|
||||
<div className="bg-red-50 border border-red-200 rounded-lg p-3 mb-4 text-sm text-red-800">
|
||||
This is the last active validation. Disabling it will cause the backend to <strong>reject all agent requests</strong> for this tenant.
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="flex space-x-3 mt-4">
|
||||
<button
|
||||
onClick={() => setDisableConfirm(null)}
|
||||
className="flex-1 px-4 py-2 border border-gray-300 rounded-md text-gray-700 bg-white hover:bg-gray-50 transition-colors"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
onClick={confirmDisable}
|
||||
className="flex-1 px-4 py-2 bg-amber-600 text-white rounded-md hover:bg-amber-700 transition-colors"
|
||||
>
|
||||
Disable
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -135,6 +135,13 @@ export default function ScriptExecutions({ events, showScriptOutput }: ScriptExe
|
||||
);
|
||||
}
|
||||
|
||||
function getIntuneScriptUrl(policyId: string, scriptType: string): string {
|
||||
if (scriptType === "remediation") {
|
||||
return `https://intune.microsoft.com/#view/Microsoft_Intune_Enrollment/UXAnalyticsScriptMenu/~/overview/id/${policyId}`;
|
||||
}
|
||||
return `https://intune.microsoft.com/#view/Microsoft_Intune_DeviceSettings/ConfigureWMPolicyMenuBlade/~/overview/policyId/${policyId}/policyType/0`;
|
||||
}
|
||||
|
||||
function ScriptItemRow({ item, showScriptOutput }: { item: ScriptItem; showScriptOutput?: boolean }) {
|
||||
const [showDetails, setShowDetails] = useState(false);
|
||||
|
||||
@@ -143,6 +150,7 @@ function ScriptItemRow({ item, showScriptOutput }: { item: ScriptItem; showScrip
|
||||
: "bg-green-50 border border-green-200";
|
||||
|
||||
const shortId = item.policyId.length >= 8 ? item.policyId.substring(0, 8) : item.policyId;
|
||||
const intuneUrl = getIntuneScriptUrl(item.policyId, item.scriptType);
|
||||
|
||||
// Build label: "Platform Script" or "Remediation Detection" / "Remediation"
|
||||
let label: string;
|
||||
@@ -178,7 +186,7 @@ function ScriptItemRow({ item, showScriptOutput }: { item: ScriptItem; showScrip
|
||||
</svg>
|
||||
)}
|
||||
<span className="text-sm font-medium text-gray-900 truncate">{label}</span>
|
||||
<span className="text-xs font-mono text-gray-500">{shortId}…</span>
|
||||
<a href={intuneUrl} target="_blank" rel="noopener noreferrer" className="text-xs font-mono text-blue-600 hover:text-blue-800 hover:underline" title="Open in Intune portal">{shortId}…</a>
|
||||
<span className={`text-xs px-2 py-0.5 rounded-full font-medium ${
|
||||
item.scriptType === "remediation"
|
||||
? "bg-amber-100 text-amber-700"
|
||||
@@ -212,7 +220,7 @@ function ScriptItemRow({ item, showScriptOutput }: { item: ScriptItem; showScrip
|
||||
<div className="mt-3 space-y-2">
|
||||
{/* Metadata */}
|
||||
<div className="flex flex-wrap gap-x-4 gap-y-1 text-xs text-gray-600">
|
||||
<span><span className="font-medium text-gray-700">Policy ID:</span> <span className="font-mono">{item.policyId}</span></span>
|
||||
<span><span className="font-medium text-gray-700">Policy ID:</span> <a href={intuneUrl} target="_blank" rel="noopener noreferrer" className="font-mono text-blue-600 hover:text-blue-800 hover:underline">{item.policyId}</a></span>
|
||||
{item.runContext && <span><span className="font-medium text-gray-700">Context:</span> {item.runContext}</span>}
|
||||
{item.exitCode != null && <span><span className="font-medium text-gray-700">Exit Code:</span> <span className="font-mono">{item.exitCode}</span></span>}
|
||||
{item.result && <span><span className="font-medium text-gray-700">Result:</span> {item.result}</span>}
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user