Skip to content

Commit

Permalink
Merge pull request #41 from intuitem/ui/compliance-assessment-detail
Browse files Browse the repository at this point in the history
UI/compliance assessment detail
  • Loading branch information
eric-intuitem authored Feb 13, 2024
2 parents d53c95d + 6f40dd1 commit 73d1921
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import DonutChart from '$lib/components/Chart/DonutChart.svelte';
import { URL_MODEL_MAP } from '$lib/utils/crud';
import type { Node } from './types';
export let data: PageData;
breadcrumbObject.set(data.compliance_assessment);
Expand All @@ -27,18 +28,6 @@
`change_${requirementAssessmentModel.name}`
);
interface Node {
urn: string;
parent_urn: string | null;
name: string;
node_content: string;
assessable: boolean;
style: string;
description: string | null;
children?: Record<string, Node>;
status?: string; // Assuming that the status field exists in nodes similar to leaves
}
const countStatus = (
node: Node,
statusCounts: Record<string, number> = {}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,36 @@
<script lang="ts">
import { complianceColorMap } from './utils';
import { page } from '$app/stores';
import type { z } from 'zod';
import type { SecurityFunctionSchema, ThreatSchema } from '$lib/utils/schemas';
export let name: string;
export let description: string;
export let ra_id: string | undefined = undefined;
export let leaf_content: string;
export let threats: Record<string, any>[] | undefined = undefined;
export let security_functions: Record<string, any>[] | undefined = undefined;
export let threats: z.infer<typeof ThreatSchema>[] | undefined = undefined;
export let security_functions: z.infer<typeof SecurityFunctionSchema>[] | undefined = undefined;
export let children: Record<string, Record<string, unknown>> | undefined = undefined;
export let canEditRequirementAssessment: boolean;
// export let status: string | undefined = undefined;
export let status: string | undefined = undefined;
export let statusCounts: Record<string, number> | undefined;
export let assessable: boolean;
const node = {
name,
description,
ra_id,
leaf_content,
threats,
security_functions,
children,
canEditRequirementAssessment,
status,
statusCounts,
assessable
} as const;
type TreeViewItemNode = typeof node;
$: hasChildren = children && Object.keys(children).length > 0;
Expand All @@ -23,19 +42,20 @@
let showInfo = false;
const getLeaves = (children: Record<string, any>[] | undefined, leaves: any = []) => {
if (children?.length === 0) return leaves;
for (const value of Object.values(children)) {
if (value.children && Object.keys(value.children).length > 0) {
getLeaves(value.children, leaves);
} else {
leaves.push(value);
const getAssessableNodes = (
startNode: TreeViewItemNode,
assessableNodes: TreeViewItemNode[] = []
) => {
if (startNode.assessable) assessableNodes.push(startNode);
if (startNode.children) {
for (const value of Object.values(startNode.children) as TreeViewItemNode[]) {
getAssessableNodes(value, assessableNodes);
}
}
return leaves;
return assessableNodes;
};
const leaves = getLeaves(children) ?? [];
const assessableNodes = getAssessableNodes(node);
const REQUIREMENT_ASSESSMENT_STATUS = [
'compliant',
Expand All @@ -58,7 +78,7 @@
(status) => {
if (!statusCounts) return { status, percentage: { value: 0, display: '0' } };
const value = statusCounts[status] || 0;
const percentValue: number = (value / leaves.length) * 100;
const percentValue: number = (value / assessableNodes.length) * 100;
const percentage = {
value: percentValue,
display: percentValue.toFixed(0)
Expand All @@ -69,13 +89,14 @@
$: classesShowInfo = (show: boolean) => (!show ? 'hidden' : '');
$: classesShowInfoText = (show: boolean) => (show ? 'text-primary-500' : '');
$: classesPercentText = (statusColor: string) => (statusColor === '#000000' ? 'text-white' : '');
</script>

<div class="flex flex-row justify-between">
<div class="flex flex-col w-1/2">
<div class="flex flex-row justify-between space-x-8">
<div class="flex flex-1 max-w-[65ch] flex-col">
<span style="font-weight: {hasChildren ? 600 : 300};">
{#if !hasChildren && canEditRequirementAssessment}
<span class="w-full h-full flex p-4 rounded-token hover:text-primary-500">
{#if assessable && canEditRequirementAssessment}
<span class="w-full h-full flex rounded-token hover:text-primary-500">
<a href="/requirement-assessments/{ra_id}?next={$page.url.pathname}">
{content}
</a>
Expand All @@ -84,13 +105,21 @@
{content}
{/if}
</span>
{#if threats || security_functions}
{#if (threats && threats.length > 0) || (security_functions && security_functions.length > 0)}
<div
role="button"
tabindex="0"
class="underline text-sm hover:text-primary-400 {classesShowInfoText(showInfo)}"
on:click={(_) => (showInfo = !showInfo)}
on:keydown={(_) => (showInfo = !showInfo)}
class="select-none text-sm hover:text-primary-400 {classesShowInfoText(showInfo)}"
on:click={(e) => {
e.preventDefault();
showInfo = !showInfo;
}}
on:keydown={(e) => {
if (e.key === 'Enter') {
e.preventDefault();
showInfo = !showInfo;
}
}}
>
<i class="text-xs fa-solid fa-info-circle" /> Learn more
</div>
Expand Down Expand Up @@ -152,24 +181,16 @@
{/if}
</div>
{#if hasChildren}
<div class="flex flex-1 bg-gray-200 rounded-full overflow-hidden h-4 shrink">
<div class="flex max-w-96 grow bg-gray-200 rounded-full overflow-hidden h-4 shrink self-center">
{#each orderedStatusPercentages as sp}
{#if complianceColorMap[sp.status] === '#000000'}
<div
class="flex flex-col justify-center overflow-hidden text-white text-xs text-center bg-yellow-500"
style="width: {sp.percentage.value}%; background-color: {complianceColorMap[sp.status]}"
>
{sp.percentage.display}%
</div>
{:else}
<div
class="flex flex-col justify-center overflow-hidden text-black text-xs text-center bg-yellow-500"
style="width: {sp.percentage.value}%; background-color: {complianceColorMap[sp.status]}"
>
{sp.percentage.display}%
<!-- {sp.percentage?.display}% -->
</div>
{/if}
<div
class="flex flex-col justify-center overflow-hidden text-xs text-center {classesPercentText(
complianceColorMap[sp.status]
)}"
style="width: {sp.percentage.value}%; background-color: {complianceColorMap[sp.status]}"
>
{sp.percentage.display}%
</div>
{/each}
</div>
{/if}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<script lang="ts">
// export let status: string;
export let statusDisplay: string;
export let statusColor: string;
export let assessable: boolean;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export interface Node {
name: string;
description?: string;
urn: string;
parent_urn?: string;
node_content: string;
assessable: boolean;
style: string;
children?: Record<string, Node>;
status?: string; // Assuming that the status field exists in nodes similar to leaves
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,13 @@
}
const title =
data.compliance_assessment.name +
' - ' +
data.parent.display_short +
': ' +
(data.parent.display_short ? data.parent.display_short + ': ' : '') +
data.requirement.display_short;
breadcrumbObject.set({ id: data.requirementAssessment.id, name: title, email: '' });
breadcrumbObject.set({
id: data.requirementAssessment.id,
name: title ?? 'Requirement assessment',
email: ''
});
const schema = RequirementAssessmentSchema;
Expand Down

0 comments on commit 73d1921

Please sign in to comment.