feat: implement automation feature

This commit is contained in:
Rotimi Best
2026-03-18 23:39:12 +01:00
parent 576d0366de
commit ef4424e267
121 changed files with 4544 additions and 1055 deletions
@@ -1,6 +1,7 @@
<script lang="ts">
import type { ExerciseQuestionRendererProps } from '@cio/question-types';
import { sanitizeHtml } from '../../../../tools/sanitize';
import { SafeHtmlContent } from '../../../safe-html-content';
import { getAnswerForQuestion, getSubmissionLabel } from '../submission-utils';
@@ -52,7 +53,7 @@
{#each responseRows as row, index (`${index}-${row.responses}`)}
<div class="ui:flex ui:items-start ui:justify-between ui:gap-3 ui:rounded-md ui:border ui:px-3 ui:py-2">
<div class="ui:min-w-0 ui:flex-1 ui:break-words ui:text-sm">
{@html row.html}
<SafeHtmlContent content={row.html} />
</div>
<span class="ui:text-muted-foreground ui:mt-0.5 ui:shrink-0 ui:text-xs">{row.responses}</span>
</div>
@@ -0,0 +1 @@
export { default as SafeHtmlContent } from './safe-html-content.svelte';
@@ -0,0 +1,38 @@
<script lang="ts">
import { splitHtmlAndSvg, type ContentSegment } from '../../tools/sanitize';
interface Props {
content: string;
}
let { content }: Props = $props();
const segments: ContentSegment[] = $derived(splitHtmlAndSvg(content));
function svgDimensions(svg: string): { width: string; height: string } {
const widthMatch = svg.match(/\bwidth\s*=\s*["'](\d+)/i);
const heightMatch = svg.match(/\bheight\s*=\s*["'](\d+)/i);
return {
width: widthMatch ? `${widthMatch[1]}px` : '100%',
height: heightMatch ? `${heightMatch[1]}px` : '150px'
};
}
function svgSrcdoc(rawSvg: string): string {
return `<!DOCTYPE html><html><head><style>body{margin:0;display:flex;justify-content:center}
</style></head><body>${rawSvg}</body></html>`;
}
</script>
{#each segments as segment}
{#if segment.type === 'html'}
{@html segment.content}
{:else}
{@const dims = svgDimensions(segment.content)}
<iframe
sandbox=""
srcdoc={svgSrcdoc(segment.content)}
title="Embedded diagram"
style="border:none;overflow:hidden;width:{dims.width};height:{dims.height}"
></iframe>
{/if}