CodeExecutionModal.svelte 3.5 KB

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