feat: Improve policy type badge system with definitive mapping
All checks were successful
Trigger Cloudarix Deploy / call-webhook (push) Successful in 1s

- Create PolicyTypeBadge component for consistent badge rendering
- Add POLICY_TYPE_MAP with explicit labels for all 7 policy types:
  - configurationProfile → 'Settings Catalog'
  - deviceConfiguration → 'Device Configuration'
  - compliancePolicy → 'Compliance Policy'
  - endpointSecurity → 'Endpoint Security'
  - windowsUpdateForBusiness → 'Windows Update'
  - enrollmentConfiguration → 'Enrollment'
  - appConfiguration → 'App Configuration'
- Update PolicyTable and PolicyDetailSheet to use new component
- Maintain fallback heuristic matching for unknown types
This commit is contained in:
Ahmed Darrazi 2025-12-08 11:31:45 +01:00
parent 56088ca6c0
commit 434f33ac8f
4 changed files with 79 additions and 16 deletions

View File

@ -8,6 +8,7 @@ import {
SheetTitle, SheetTitle,
} from '@/components/ui/sheet'; } from '@/components/ui/sheet';
import type { PolicySettingSearchResult } from '@/lib/actions/policySettings'; import type { PolicySettingSearchResult } from '@/lib/actions/policySettings';
import { PolicyTypeBadge } from './PolicyTypeBadge';
import { formatDistanceToNow } from 'date-fns'; import { formatDistanceToNow } from 'date-fns';
import { de } from 'date-fns/locale'; import { de } from 'date-fns/locale';
@ -68,9 +69,7 @@ export function PolicyDetailSheet({
<h3 className="text-sm font-medium text-muted-foreground mb-1"> <h3 className="text-sm font-medium text-muted-foreground mb-1">
Policy Type Policy Type
</h3> </h3>
<p className="text-sm capitalize"> <PolicyTypeBadge type={policy.policyType} />
{policy.policyType.replace(/([A-Z])/g, ' $1').trim()}
</p>
</div> </div>
{/* Setting Name */} {/* Setting Name */}

View File

@ -9,9 +9,8 @@ import {
TableRow, TableRow,
} from '@/components/ui/table'; } from '@/components/ui/table';
import { Card, CardContent } from '@/components/ui/card'; import { Card, CardContent } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';
import type { PolicySettingSearchResult } from '@/lib/actions/policySettings'; import type { PolicySettingSearchResult } from '@/lib/actions/policySettings';
import { getPolicyBadgeConfig } from '@/lib/utils/policyBadges'; import { PolicyTypeBadge } from './PolicyTypeBadge';
import { formatDistanceToNow } from 'date-fns'; import { formatDistanceToNow } from 'date-fns';
import { de } from 'date-fns/locale'; import { de } from 'date-fns/locale';
@ -54,14 +53,7 @@ export function PolicyTable({ policies, onRowClick }: PolicyTableProps) {
</TableCell> </TableCell>
<TableCell>{policy.policyName}</TableCell> <TableCell>{policy.policyName}</TableCell>
<TableCell> <TableCell>
{(() => { <PolicyTypeBadge type={policy.policyType} />
const badgeConfig = getPolicyBadgeConfig(policy.policyType);
return (
<Badge variant={badgeConfig.variant}>
{badgeConfig.label}
</Badge>
);
})()}
</TableCell> </TableCell>
<TableCell className="text-muted-foreground text-sm"> <TableCell className="text-muted-foreground text-sm">
{formatDistanceToNow(new Date(policy.lastSyncedAt), { {formatDistanceToNow(new Date(policy.lastSyncedAt), {

View File

@ -0,0 +1,20 @@
import { Badge } from "@/components/ui/badge";
import { getPolicyBadgeConfig } from "@/lib/utils/policyBadges";
interface PolicyTypeBadgeProps {
type: string;
}
/**
* Badge component for displaying policy types with consistent styling
* Maps Intune policy types to user-friendly labels and colors
*/
export function PolicyTypeBadge({ type }: PolicyTypeBadgeProps) {
const { variant, label } = getPolicyBadgeConfig(type);
return (
<Badge variant={variant}>
{label}
</Badge>
);
}

View File

@ -1,6 +1,6 @@
/** /**
* Policy Type Badge Configuration * Policy Type Badge Configuration
* Maps Intune policy types to Shadcn Badge variants and colors * Maps Intune policy types to Shadcn Badge variants and labels
*/ */
export type PolicyBadgeVariant = 'default' | 'secondary' | 'destructive' | 'outline'; export type PolicyBadgeVariant = 'default' | 'secondary' | 'destructive' | 'outline';
@ -10,11 +10,63 @@ interface PolicyBadgeConfig {
label: string; label: string;
} }
/**
* Definitive mapping of Intune policy types to badge configuration
*/
const POLICY_TYPE_MAP: Record<string, PolicyBadgeConfig> = {
// Device Configuration (Legacy)
deviceConfiguration: {
variant: 'secondary',
label: 'Device Configuration'
},
// Settings Catalog (Modern Configuration)
configurationProfile: {
variant: 'default',
label: 'Settings Catalog'
},
// Compliance Policies
compliancePolicy: {
variant: 'default',
label: 'Compliance Policy'
},
// Endpoint Security
endpointSecurity: {
variant: 'destructive',
label: 'Endpoint Security'
},
// Windows Update
windowsUpdateForBusiness: {
variant: 'outline',
label: 'Windows Update'
},
// Enrollment Configuration
enrollmentConfiguration: {
variant: 'secondary',
label: 'Enrollment'
},
// App Configuration
appConfiguration: {
variant: 'outline',
label: 'App Configuration'
}
};
/** /**
* Maps policy type to badge configuration * Maps policy type to badge configuration
* Based on Microsoft Intune policy categories
*/ */
export function getPolicyBadgeConfig(policyType: string): PolicyBadgeConfig { export function getPolicyBadgeConfig(policyType: string): PolicyBadgeConfig {
// Direct lookup for exact matches
if (POLICY_TYPE_MAP[policyType]) {
return POLICY_TYPE_MAP[policyType];
}
// Fallback to heuristic matching for unknown types
const type = policyType.toLowerCase(); const type = policyType.toLowerCase();
// Security & Protection // Security & Protection
@ -37,7 +89,7 @@ export function getPolicyBadgeConfig(policyType: string): PolicyBadgeConfig {
return { variant: 'outline', label: formatPolicyType(policyType) }; return { variant: 'outline', label: formatPolicyType(policyType) };
} }
// Default for unknown types // Default for completely unknown types
return { variant: 'secondary', label: formatPolicyType(policyType) }; return { variant: 'secondary', label: formatPolicyType(policyType) };
} }