diff --git a/apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/(home)/components/FrameworkProgress.tsx b/apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/(home)/components/FrameworkProgress.tsx index 87cf230595..c9c3b3cee6 100644 --- a/apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/(home)/components/FrameworkProgress.tsx +++ b/apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/(home)/components/FrameworkProgress.tsx @@ -106,7 +106,7 @@ export function FrameworkProgress({ frameworks }: Props) { {t("frameworks.overview.progress.empty.description")}
diff --git a/apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/(home)/components/RequirementStatusChart.tsx b/apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/(home)/components/RequirementStatusChart.tsx index c875b7a065..13345995f1 100644 --- a/apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/(home)/components/RequirementStatusChart.tsx +++ b/apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/(home)/components/RequirementStatusChart.tsx @@ -1,178 +1,177 @@ "use client"; import { useI18n } from "@/locales/client"; -import type { - Framework, - OrganizationFramework, -} from "@bubba/db/types"; +import type { Framework, OrganizationFramework } from "@bubba/db/types"; import { Card, CardContent, CardHeader, CardTitle } from "@bubba/ui/card"; import { Progress } from "@bubba/ui/progress"; import Link from "next/link"; import { useMemo } from "react"; import type { OrganizationControlType } from "../overview/frameworks/[frameworkId]/components/table/FrameworkControlsTableColumns"; import { useOrganizationCategories } from "../overview/frameworks/[frameworkId]/hooks/useOrganizationCategories"; +import { useParams } from "next/navigation"; interface Props { - frameworks: (OrganizationFramework & { - framework: Framework; - })[]; + frameworks: (OrganizationFramework & { + framework: Framework; + })[]; } // Helper function to check if a control is compliant based on its requirements const isControlCompliant = (control: OrganizationControlType) => { - // First, check if the control has the direct status of "compliant" - if (control.status === "compliant") { - return true; - } - - // Then check the requirements if they exist - const requirements = control.requirements; - - if (!requirements || requirements.length === 0) { - return false; - } - - const totalRequirements = requirements.length; - const completedRequirements = requirements.filter((req) => { - let isCompleted = false; - - switch (req.type) { - case "policy": - isCompleted = req.organizationPolicy?.status === "published"; - break; - case "file": - isCompleted = !!req.fileUrl; - break; - case "evidence": - isCompleted = req.organizationEvidence?.published === true; - break; - default: - isCompleted = req.published || false; - } - - return isCompleted; - }).length; - - return completedRequirements === totalRequirements; + // First, check if the control has the direct status of "compliant" + if (control.status === "compliant") { + return true; + } + + // Then check the requirements if they exist + const requirements = control.requirements; + + if (!requirements || requirements.length === 0) { + return false; + } + + const totalRequirements = requirements.length; + const completedRequirements = requirements.filter((req) => { + let isCompleted = false; + + switch (req.type) { + case "policy": + isCompleted = req.organizationPolicy?.status === "published"; + break; + case "file": + isCompleted = !!req.fileUrl; + break; + case "evidence": + isCompleted = req.organizationEvidence?.published === true; + break; + default: + isCompleted = req.published || false; + } + + return isCompleted; + }).length; + + return completedRequirements === totalRequirements; }; // Individual FrameworkCard component function FrameworkCard({ - framework, + framework, }: { framework: OrganizationFramework & { framework: Framework } }) { - const { data: organizationCategories, isLoading } = useOrganizationCategories( - framework.framework.id, - ); - - // Transform the organizationCategories into controls - const controls = useMemo(() => { - if (!organizationCategories) return []; - - return organizationCategories.flatMap((category) => - category.organizationControl.map((control) => ({ - code: control.control.code, - description: control.control.description, - name: control.control.name, - status: control.status, - id: control.id, - frameworkId: framework.framework.id, - category: category.name, - requirements: control.OrganizationControlRequirement, - })), - ); - }, [ - organizationCategories, - framework.framework.id, - ]) as OrganizationControlType[]; - - // Calculate framework compliance based on controls - const compliance = useMemo(() => { - if (isLoading || controls.length === 0) return 0; - - const totalControls = controls.length; - const compliantControls = controls.filter(isControlCompliant).length; - - return totalControls > 0 - ? Math.round((compliantControls / totalControls) * 100) - : 0; - }, [controls, isLoading]); - - if (isLoading) { - return ( -- Loading compliance data... -
-- {t("frameworks.overview.empty.description")} -
-+ Loading compliance data... +
++ {t("frameworks.overview.empty.description")} +
+- {hasFilters - ? t("common.empty_states.no_results.description_filters") - : t("common.empty_states.no_results.description_no_tasks")} -
-+ {hasFilters + ? t("common.empty_states.no_results.description_filters") + : t("common.empty_states.no_results.description_no_tasks")} +
+- {t("common.empty_states.no_results.description_no_tasks")} -
- -+ {t("common.empty_states.no_results.description_no_tasks")} +
+ +