CodeExecutionModal.svelte 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. <script lang="ts">
  2. import { getContext } from 'svelte';
  3. import CodeBlock from './CodeBlock.svelte';
  4. import Modal from '$lib/components/common/Modal.svelte';
  5. import Spinner from '$lib/components/common/Spinner.svelte';
  6. import Badge from '$lib/components/common/Badge.svelte';
  7. import XMark from '$lib/components/icons/XMark.svelte';
  8. const i18n = getContext('i18n');
  9. export let show = false;
  10. export let codeExecution = null;
  11. </script>
  12. <Modal size="lg" bind:show>
  13. <div>
  14. <div class="flex justify-between dark:text-gray-300 px-5 pt-4 pb-2">
  15. <div class="text-lg font-medium self-center flex flex-col gap-0.5 capitalize">
  16. {#if codeExecution?.result}
  17. <div>
  18. {#if codeExecution.result?.error}
  19. <Badge type="error" content="error" />
  20. {:else if codeExecution.result?.output}
  21. <Badge type="success" content="success" />
  22. {:else}
  23. <Badge type="warning" content="incomplete" />
  24. {/if}
  25. </div>
  26. {/if}
  27. <div class="flex gap-2 items-center">
  28. {#if !codeExecution?.result}
  29. <div>
  30. <Spinner className="size-4" />
  31. </div>
  32. {/if}
  33. <div>
  34. {#if codeExecution?.name}
  35. {$i18n.t('Code execution')}: {codeExecution?.name}
  36. {:else}
  37. {$i18n.t('Code execution')}
  38. {/if}
  39. </div>
  40. </div>
  41. </div>
  42. <button
  43. class="self-center"
  44. on:click={() => {
  45. show = false;
  46. codeExecution = null;
  47. }}
  48. >
  49. <XMark className={'size-5'} />
  50. </button>
  51. </div>
  52. <div class="flex flex-col md:flex-row w-full px-4 pb-5">
  53. <div
  54. class="flex flex-col w-full dark:text-gray-200 overflow-y-scroll max-h-[22rem] scrollbar-hidden"
  55. >
  56. <div class="flex flex-col w-full">
  57. <CodeBlock
  58. id="code-exec-{codeExecution?.id}-code"
  59. lang={codeExecution?.language ?? ''}
  60. code={codeExecution?.code ?? ''}
  61. className=""
  62. editorClassName={codeExecution?.result &&
  63. (codeExecution?.result?.error || codeExecution?.result?.output)
  64. ? 'rounded-b-none'
  65. : ''}
  66. stickyButtonsClassName="top-0"
  67. run={false}
  68. />
  69. </div>
  70. {#if codeExecution?.result && (codeExecution?.result?.error || codeExecution?.result?.output)}
  71. <div class="dark:bg-[#202123] dark:text-white px-4 py-4 rounded-b-lg flex flex-col gap-3">
  72. {#if codeExecution?.result?.error}
  73. <div>
  74. <div class=" text-gray-500 text-xs mb-1">{$i18n.t('ERROR')}</div>
  75. <div class="text-sm">{codeExecution?.result?.error}</div>
  76. </div>
  77. {/if}
  78. {#if codeExecution?.result?.output}
  79. <div>
  80. <div class=" text-gray-500 text-xs mb-1">{$i18n.t('OUTPUT')}</div>
  81. <div class="text-sm">{codeExecution?.result?.output}</div>
  82. </div>
  83. {/if}
  84. </div>
  85. {/if}
  86. {#if codeExecution?.result?.files && codeExecution?.result?.files.length > 0}
  87. <div class="flex flex-col w-full">
  88. <hr class="border-gray-100 dark:border-gray-850 my-2" />
  89. <div class=" text-sm font-medium dark:text-gray-300">
  90. {$i18n.t('Files')}
  91. </div>
  92. <ul class="mt-1 list-disc pl-4 text-xs">
  93. {#each codeExecution?.result?.files as file}
  94. <li>
  95. <a href={file.url} target="_blank">{file.name}</a>
  96. </li>
  97. {/each}
  98. </ul>
  99. </div>
  100. {/if}
  101. </div>
  102. </div>
  103. </div>
  104. </Modal>