Pipelines.svelte 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. <script lang="ts">
  2. import { v4 as uuidv4 } from 'uuid';
  3. import { getContext, onMount, tick } from 'svelte';
  4. import type { Writable } from 'svelte/store';
  5. import type { i18n as i18nType } from 'i18next';
  6. import { stringify } from 'postcss';
  7. import {
  8. getPipelineValves,
  9. getPipelineValvesSpec,
  10. updatePipelineValves,
  11. getPipelines
  12. } from '$lib/apis';
  13. import Spinner from '$lib/components/common/Spinner.svelte';
  14. import { toast } from 'svelte-sonner';
  15. const i18n: Writable<i18nType> = getContext('i18n');
  16. export let saveHandler: Function;
  17. let pipelines = null;
  18. let valves = null;
  19. let valves_spec = null;
  20. let selectedPipelineIdx = null;
  21. const updateHandler = async () => {
  22. const pipeline = pipelines[selectedPipelineIdx];
  23. if (pipeline && (pipeline?.pipeline?.valves ?? false)) {
  24. const res = await updatePipelineValves(localStorage.token, pipeline.id, valves).catch(
  25. (error) => {
  26. toast.error(error);
  27. }
  28. );
  29. if (res) {
  30. toast.success('Valves updated successfully');
  31. saveHandler();
  32. }
  33. } else {
  34. toast.error('No valves to update');
  35. }
  36. };
  37. onMount(async () => {
  38. pipelines = await getPipelines(localStorage.token);
  39. if (pipelines.length > 0) {
  40. selectedPipelineIdx = 0;
  41. }
  42. });
  43. </script>
  44. <form
  45. class="flex flex-col h-full justify-between space-y-3 text-sm"
  46. on:submit|preventDefault={async () => {
  47. updateHandler();
  48. }}
  49. >
  50. <div class=" space-y-2 pr-1.5 overflow-y-scroll max-h-80 h-full">
  51. {#if pipelines !== null && pipelines.length > 0}
  52. <div class="flex w-full justify-between mb-2">
  53. <div class=" self-center text-sm font-semibold">
  54. {$i18n.t('Pipelines')}
  55. </div>
  56. </div>
  57. <div class="space-y-1">
  58. {#if pipelines.length > 0}
  59. <div class="flex gap-2">
  60. <div class="flex-1 pb-1">
  61. <select
  62. class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
  63. bind:value={selectedPipelineIdx}
  64. placeholder={$i18n.t('Select a pipeline')}
  65. on:change={async () => {
  66. await tick();
  67. valves_spec = await getPipelineValvesSpec(
  68. localStorage.token,
  69. pipelines[selectedPipelineIdx].id
  70. );
  71. valves = await getPipelineValves(
  72. localStorage.token,
  73. pipelines[selectedPipelineIdx].id
  74. );
  75. }}
  76. >
  77. {#each pipelines as pipeline, idx}
  78. <option value={idx} class="bg-gray-100 dark:bg-gray-700"
  79. >{pipeline.name} ({pipeline.pipeline.type ?? 'pipe'})</option
  80. >
  81. {/each}
  82. </select>
  83. </div>
  84. </div>
  85. {/if}
  86. <div class="text-sm font-medium">{$i18n.t('Valves')}</div>
  87. <div class="space-y-1">
  88. {#if pipelines[selectedPipelineIdx].pipeline.valves}
  89. {#if valves}
  90. {#each Object.keys(valves_spec.properties) as property, idx}
  91. <div class=" py-0.5 w-full justify-between">
  92. <div class="flex w-full justify-between">
  93. <div class=" self-center text-xs font-medium">
  94. {valves_spec.properties[property].title}
  95. </div>
  96. <button
  97. class="p-1 px-3 text-xs flex rounded transition"
  98. type="button"
  99. on:click={() => {
  100. valves[property] = (valves[property] ?? null) === null ? '' : null;
  101. }}
  102. >
  103. {#if (valves[property] ?? null) === null}
  104. <span class="ml-2 self-center"> {$i18n.t('None')} </span>
  105. {:else}
  106. <span class="ml-2 self-center"> {$i18n.t('Custom')} </span>
  107. {/if}
  108. </button>
  109. </div>
  110. {#if (valves[property] ?? null) !== null}
  111. <div class="flex mt-0.5 space-x-2">
  112. <div class=" flex-1">
  113. <input
  114. class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
  115. type="text"
  116. placeholder={valves_spec.properties[property].title}
  117. bind:value={valves[property]}
  118. autocomplete="off"
  119. />
  120. </div>
  121. </div>
  122. {/if}
  123. </div>
  124. {/each}
  125. {:else}
  126. <Spinner className="size-5" />
  127. {/if}
  128. {:else}
  129. <div>No valves</div>
  130. {/if}
  131. </div>
  132. </div>
  133. {:else if pipelines !== null && pipelines.length === 0}
  134. <div>Pipelines Not Detected</div>
  135. {:else}
  136. <div class="flex h-full justify-center">
  137. <div class="my-auto">
  138. <Spinner className="size-6" />
  139. </div>
  140. </div>
  141. {/if}
  142. </div>
  143. <div class="flex justify-end pt-3 text-sm font-medium">
  144. <button
  145. class=" px-4 py-2 bg-emerald-700 hover:bg-emerald-800 text-gray-100 transition rounded-lg"
  146. type="submit"
  147. >
  148. Save
  149. </button>
  150. </div>
  151. </form>