Skip to content

Commit

Permalink
Added simple prompt to add evaluation result (#28)
Browse files Browse the repository at this point in the history
For now a simple prompt, can be extended to a modal dialog

Fixes #27
  • Loading branch information
oxisto authored Jul 10, 2023
1 parent 7b9fd92 commit 6f0f27e
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 11 deletions.
21 changes: 19 additions & 2 deletions src/lib/api/evaluation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,22 @@ export interface ListEvaluationResultsResponse {
export type ComplianceStatus =
| 'EVALUATION_STATUS_NOT_COMPLIANT'
| 'EVALUATION_STATUS_COMPLIANT'
| 'EVALUATION_STATUS_PENDING';
| 'EVALUATION_STATUS_COMPLIANT_MANUALLY'
| 'EVALUATION_STATUS_PENDING'
| 'EVALUATION_STATUS_DELEGATED'
;

export interface EvaluationResult {
id: string
cloudServiceId: string
status: ComplianceStatus
resourceId: string
controlCatalogId: string
controlCategoryName?: string
controlId: string
parentControlId?: string
timestamp: string,
failingAssessmentResultIds: string[]
comment?: string
}

export async function startEvaluation(toe: TargetOfEvaluation): Promise<StartEvaluationResponse> {
Expand Down Expand Up @@ -77,4 +81,17 @@ export async function listEvaluationResults(
.then((response: ListEvaluationResultsResponse) => {
return response.results;
});
}

export async function createEvaluationResult(result: EvaluationResult, fetch = window.fetch): Promise<EvaluationResult> {
const apiUrl = clouditorize(`/v1/evaluation/results`);

return fetch(apiUrl, {
method: 'POST',
body: JSON.stringify(result),
headers: {
'Authorization': `Bearer ${localStorage.token}`,
}
}).then(throwError)
.then((res) => res.json());
}
9 changes: 5 additions & 4 deletions src/lib/components/ComplianceChart.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@
let canvas: HTMLCanvasElement;
onMount(() => {
let topLevelControls = toe.controlsInScope?.filter((c) => c.parentControlId === undefined);
const data = {
labels: ['Non Compliant', 'Compliant', 'Waiting for Data'],
labels: ['Non Compliant', 'Compliant', 'Manually set to Compliant', 'Waiting for Data'],
datasets: [
{
label: toe.catalogId,
Expand All @@ -21,10 +19,13 @@
Array.from(compliance.values()).filter(
(value) => value == 'EVALUATION_STATUS_COMPLIANT'
).length,
Array.from(compliance.values()).filter(
(value) => value == 'EVALUATION_STATUS_COMPLIANT_MANUALLY'
).length,
Array.from(compliance.values()).filter((value) => value == 'EVALUATION_STATUS_PENDING')
.length
],
backgroundColor: ['#991b1b', '#166534', '#d4d4d4'],
backgroundColor: ['#991b1b', '#166534', '#007fc3', '#d4d4d4'],
hoverOffset: 4
}
]
Expand Down
15 changes: 14 additions & 1 deletion src/lib/components/ControlComplianceItem.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,30 @@
import { DisclosureButton } from '@rgossiaux/svelte-headlessui';
import { CheckCircle, EllipsisHorizontalCircle, XCircle } from '@steeze-ui/heroicons';
import { Icon } from '@steeze-ui/svelte-icon';
import { createEventDispatcher } from 'svelte';
export let result: EvaluationResult;
export let control: Control | undefined;
const dispatch = createEventDispatcher<{ addResult: { control: Control } }>();
function addResult() {
if (control !== undefined) {
dispatch('addResult', { control: control });
}
}
</script>

<div class="flex">
<div class="mr-4 flex-shrink-0">
{#if result.status == 'EVALUATION_STATUS_COMPLIANT'}
<Icon src={CheckCircle} theme="solid" class="w-8 h-8 text-green-800" />
{:else if result.status == 'EVALUATION_STATUS_COMPLIANT_MANUALLY'}
<Icon src={CheckCircle} theme="solid" class="w-8 h-8 text-clouditor" />
{:else if result.status == 'EVALUATION_STATUS_PENDING'}
<Icon src={EllipsisHorizontalCircle} theme="solid" class="w-8 h-8 text-gray-400" />
<button on:click={addResult}>
<Icon src={EllipsisHorizontalCircle} theme="solid" class="w-8 h-8 text-gray-400" />
</button>
{:else}
<a href="../../assessments/?filterIds={result.failingAssessmentResultIds.join(',')}">
<Icon src={XCircle} theme="solid" class="w-8 h-8 text-red-800" />
Expand Down
34 changes: 30 additions & 4 deletions src/routes/(app)/cloud/[id]/compliance/[catalogId]/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
<script lang="ts">
import type { EvaluationResult } from '$lib/api/evaluation';
import { CheckCircle, ExclamationCircle, Minus, PauseCircle, Plus } from '@steeze-ui/heroicons';
import { createEvaluationResult, type EvaluationResult } from '$lib/api/evaluation';
import type { Control } from '$lib/api/orchestrator';
import ControlComplianceItem from '$lib/components/ControlComplianceItem.svelte';
import { Disclosure, DisclosureButton, DisclosurePanel } from '@rgossiaux/svelte-headlessui';
import { Minus, Plus } from '@steeze-ui/heroicons';
import { Icon } from '@steeze-ui/svelte-icon';
import type { PageData } from './$types';
import { Disclosure, DisclosureButton, DisclosurePanel } from '@rgossiaux/svelte-headlessui';
import ControlComplianceItem from '$lib/components/ControlComplianceItem.svelte';
import { invalidate } from '$app/navigation';
export let data: PageData;
Expand Down Expand Up @@ -45,6 +47,29 @@
return tree;
}
async function addResult(e: CustomEvent<{ control: Control }>) {
const comment = prompt('Please provide a message for this manual evaluation result');
if (comment === null) {
return;
}
let result: EvaluationResult = {
id: '',
controlId: e.detail.control.id,
cloudServiceId: data.service.id,
controlCategoryName: e.detail.control.categoryName,
controlCatalogId: data.catalog.id,
parentControlId: e.detail.control.parentControlId,
status: 'EVALUATION_STATUS_COMPLIANT_MANUALLY',
timestamp: new Date().toISOString(),
failingAssessmentResultIds: [],
comment: comment
};
result = await createEvaluationResult(result);
invalidate((url) => url.pathname == '/v1/evaluation/results');
}
</script>

<div class="border-b border-gray-200 pb-5">
Expand All @@ -62,6 +87,7 @@
<ControlComplianceItem
result={item.result}
control={data.controls.get(item.result.controlId)}
on:addResult={addResult}
/>
<DisclosureButton>
<span class="ml-6 flex h-7 items-center">
Expand Down

0 comments on commit 6f0f27e

Please sign in to comment.