Skip to content

Commit 16d1cba

Browse files
github-actions[bot]chasprowebdevMarfuen
authored
MDM policy (#1727)
* feat(portal): add MDM policy on portal * fix(portal): show MDM policy only on macOS * fix(portal): update tooltip content for MDM policy --------- Co-authored-by: chasprowebdev <chasgarciaprowebdev@gmail.com> Co-authored-by: Mariano Fuentes <marfuen98@gmail.com>
1 parent fb3902b commit 16d1cba

2 files changed

Lines changed: 101 additions & 28 deletions

File tree

apps/portal/src/app/(app)/(home)/[orgId]/components/tasks/DeviceAgentAccordionItem.tsx

Lines changed: 91 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ import { Button } from '@comp/ui/button';
66
import { Card, CardContent, CardHeader, CardTitle } from '@comp/ui/card';
77
import { cn } from '@comp/ui/cn';
88
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@comp/ui/select';
9+
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@comp/ui/tooltip';
910
import type { Member } from '@db';
10-
import { CheckCircle2, Circle, Download, Loader2, XCircle } from 'lucide-react';
11+
import { CheckCircle2, Circle, Download, HelpCircle, Loader2, XCircle } from 'lucide-react';
1112
import Image from 'next/image';
1213
import { useEffect, useMemo, useState } from 'react';
1314
import { toast } from 'sonner';
@@ -32,10 +33,20 @@ export function DeviceAgentAccordionItem({
3233
[detectedOS],
3334
);
3435

36+
const mdmEnabledStatus = useMemo(() => {
37+
return {
38+
id: 'mdm',
39+
response: host?.mdm.enrollment_status === 'On' ? 'pass' : 'fail',
40+
name: 'MDM Enabled',
41+
};
42+
}, [host]);
43+
3544
const hasInstalledAgent = host !== null;
36-
const allPoliciesPass =
37-
fleetPolicies.length === 0 || fleetPolicies.every((policy) => policy.response === 'pass');
38-
const isCompleted = hasInstalledAgent && allPoliciesPass;
45+
const failedPoliciesCount = useMemo(() => {
46+
return fleetPolicies.filter((policy) => policy.response !== 'pass').length + (!isMacOS || mdmEnabledStatus.response === 'pass' ? 0 : 1);
47+
}, [fleetPolicies, mdmEnabledStatus, isMacOS]);
48+
49+
const isCompleted = hasInstalledAgent && failedPoliciesCount === 0;
3950

4051
const handleDownload = async () => {
4152
setIsDownloading(true);
@@ -130,9 +141,9 @@ export function DeviceAgentAccordionItem({
130141
<span className={cn('text-base', isCompleted && 'text-muted-foreground line-through')}>
131142
Download and install Comp AI Device Agent
132143
</span>
133-
{hasInstalledAgent && !allPoliciesPass && (
144+
{hasInstalledAgent && failedPoliciesCount > 0 && (
134145
<span className="text-amber-600 dark:text-amber-400 text-xs ml-auto">
135-
{fleetPolicies.filter((p) => p.response !== 'pass').length} policies failing
146+
{failedPoliciesCount} policies failing
136147
</span>
137148
)}
138149
</div>
@@ -245,28 +256,81 @@ export function DeviceAgentAccordionItem({
245256
</CardHeader>
246257
<CardContent className="space-y-3">
247258
{fleetPolicies.length > 0 ? (
248-
fleetPolicies.map((policy) => (
249-
<div
250-
key={policy.id}
251-
className={cn(
252-
'hover:bg-muted/50 flex items-center justify-between rounded-md border border-l-4 p-3 shadow-sm transition-colors',
253-
policy.response === 'pass' ? 'border-l-green-500' : 'border-l-red-500',
254-
)}
255-
>
256-
<p className="text-sm font-medium">{policy.name}</p>
257-
{policy.response === 'pass' ? (
258-
<div className="flex items-center gap-1 text-green-600 dark:text-green-400">
259-
<CheckCircle2 size={16} />
260-
<span className="text-sm">Pass</span>
261-
</div>
262-
) : (
263-
<div className="flex items-center gap-1 text-red-600 dark:text-red-400">
264-
<XCircle size={16} />
265-
<span className="text-sm">Fail</span>
259+
<>
260+
{fleetPolicies.map((policy) => (
261+
<div
262+
key={policy.id}
263+
className={cn(
264+
'hover:bg-muted/50 flex items-center justify-between rounded-md border border-l-4 p-3 shadow-sm transition-colors',
265+
policy.response === 'pass' ? 'border-l-green-500' : 'border-l-red-500',
266+
)}
267+
>
268+
<p className="text-sm font-medium">{policy.name}</p>
269+
{policy.response === 'pass' ? (
270+
<div className="flex items-center gap-1 text-green-600 dark:text-green-400">
271+
<CheckCircle2 size={16} />
272+
<span className="text-sm">Pass</span>
273+
</div>
274+
) : (
275+
<div className="flex items-center gap-1 text-red-600 dark:text-red-400">
276+
<XCircle size={16} />
277+
<span className="text-sm">Fail</span>
278+
</div>
279+
)}
280+
</div>
281+
))}
282+
{isMacOS && (
283+
<div
284+
className={cn(
285+
'hover:bg-muted/50 flex items-center justify-between rounded-md border border-l-4 p-3 shadow-sm transition-colors',
286+
mdmEnabledStatus.response === 'pass' ? 'border-l-green-500' : 'border-l-red-500',
287+
)}
288+
>
289+
<div className="flex items-center gap-2">
290+
<p className="text-sm font-medium">{mdmEnabledStatus.name}</p>
291+
{mdmEnabledStatus.response === 'fail' && host?.id && (
292+
<TooltipProvider>
293+
<Tooltip>
294+
<TooltipTrigger asChild>
295+
<button
296+
type="button"
297+
className="text-muted-foreground hover:text-foreground transition-colors"
298+
>
299+
<HelpCircle size={14} />
300+
</button>
301+
</TooltipTrigger>
302+
<TooltipContent className="max-w-xs">
303+
<p>
304+
There are additional steps required to enable MDM. Please check{' '}
305+
<a
306+
href="https://trycomp.ai/docs/device-agent#mdm-user-guide"
307+
target="_blank"
308+
rel="noopener noreferrer"
309+
className="text-blue-600 dark:text-blue-400 hover:underline"
310+
>
311+
this documentation
312+
</a>
313+
.
314+
</p>
315+
</TooltipContent>
316+
</Tooltip>
317+
</TooltipProvider>
318+
)}
266319
</div>
267-
)}
268-
</div>
269-
))
320+
{mdmEnabledStatus.response === 'pass' ? (
321+
<div className="flex items-center gap-1 text-green-600 dark:text-green-400">
322+
<CheckCircle2 size={16} />
323+
<span className="text-sm">Pass</span>
324+
</div>
325+
) : (
326+
<div className="flex items-center gap-1 text-red-600 dark:text-red-400">
327+
<XCircle size={16} />
328+
<span className="text-sm">Fail</span>
329+
</div>
330+
)}
331+
</div>
332+
)}
333+
</>
270334
) : (
271335
<p className="text-muted-foreground text-sm">
272336
No policies configured for this device.

apps/portal/src/app/(app)/(home)/[orgId]/types/index.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ export interface Host {
6666
gigs_total_disk_space: number;
6767
disk_encryption_enabled: boolean;
6868
issues: object;
69-
mdm: object;
69+
mdm: MDM;
7070
refetch_critical_queries_until: string | null;
7171
last_restarted_at: string;
7272
policies: FleetPolicy[];
@@ -80,3 +80,12 @@ export interface Host {
8080
display_text: string;
8181
display_name: string;
8282
}
83+
84+
export type MDM = {
85+
connected_to_fleet: boolean;
86+
dep_profile_error: boolean;
87+
encryption_key_available: boolean;
88+
enrollment_status: "Off" | "On";
89+
name?: string;
90+
server_url?: string;
91+
};

0 commit comments

Comments
 (0)