CodegenModal.vue 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. <template>
  2. <SmartModal
  3. v-if="show"
  4. :title="`${t('request.generate_code')}`"
  5. @close="hideModal"
  6. >
  7. <template #body>
  8. <div class="flex flex-col px-2">
  9. <label for="requestType" class="px-4 pb-4">
  10. {{ t("request.choose_language") }}
  11. </label>
  12. <tippy ref="options" interactive trigger="click" theme="popover" arrow>
  13. <template #trigger>
  14. <span class="select-wrapper">
  15. <ButtonSecondary
  16. :label="codegens.find((x) => x.id === codegenType).name"
  17. outline
  18. class="flex-1 pr-8"
  19. />
  20. </span>
  21. </template>
  22. <SmartItem
  23. v-for="(gen, index) in codegens"
  24. :key="`gen-${index}`"
  25. :label="gen.name"
  26. :info-icon="gen.id === codegenType ? 'done' : ''"
  27. :active-info-icon="gen.id === codegenType"
  28. @click.native="
  29. () => {
  30. codegenType = gen.id
  31. options.tippy().hide()
  32. }
  33. "
  34. />
  35. </tippy>
  36. <div class="flex flex-1 justify-between">
  37. <label for="generatedCode" class="p-4">
  38. {{ t("request.generated_code") }}
  39. </label>
  40. </div>
  41. <div
  42. v-if="codegenType"
  43. ref="generatedCode"
  44. class="border border-dividerLight rounded"
  45. ></div>
  46. </div>
  47. </template>
  48. <template #footer>
  49. <span class="flex">
  50. <ButtonPrimary
  51. :label="`${t('action.copy')}`"
  52. :svg="copyIcon"
  53. @click.native="copyRequestCode"
  54. />
  55. <ButtonSecondary
  56. :label="`${t('action.dismiss')}`"
  57. @click.native="hideModal"
  58. />
  59. </span>
  60. </template>
  61. </SmartModal>
  62. </template>
  63. <script setup lang="ts">
  64. import { computed, ref, watch } from "@nuxtjs/composition-api"
  65. import { codegens, generateCodegenContext } from "~/helpers/codegen/codegen"
  66. import { useCodemirror } from "~/helpers/editor/codemirror"
  67. import { copyToClipboard } from "~/helpers/utils/clipboard"
  68. import { getEffectiveRESTRequest } from "~/helpers/utils/EffectiveURL"
  69. import { getCurrentEnvironment } from "~/newstore/environments"
  70. import { getRESTRequest } from "~/newstore/RESTSession"
  71. import { useI18n, useToast } from "~/helpers/utils/composables"
  72. const t = useI18n()
  73. const props = defineProps<{
  74. show: boolean
  75. }>()
  76. const emit = defineEmits<{
  77. (e: "hide-modal"): void
  78. }>()
  79. const toast = useToast()
  80. const options = ref<any | null>(null)
  81. const request = ref(getRESTRequest())
  82. const codegenType = ref("curl")
  83. const copyIcon = ref("copy")
  84. const requestCode = computed(() => {
  85. const effectiveRequest = getEffectiveRESTRequest(
  86. request.value as any,
  87. getCurrentEnvironment()
  88. )
  89. return codegens
  90. .find((x) => x.id === codegenType.value)!
  91. .generator(generateCodegenContext(effectiveRequest))
  92. })
  93. const generatedCode = ref<any | null>(null)
  94. useCodemirror(generatedCode, requestCode, {
  95. extendedEditorConfig: {
  96. mode: "text/plain",
  97. readOnly: true,
  98. },
  99. linter: null,
  100. completer: null,
  101. })
  102. watch(
  103. () => props.show,
  104. (goingToShow) => {
  105. if (goingToShow) {
  106. request.value = getRESTRequest()
  107. }
  108. }
  109. )
  110. const hideModal = () => emit("hide-modal")
  111. const copyRequestCode = () => {
  112. copyToClipboard(requestCode.value)
  113. copyIcon.value = "check"
  114. toast.success(`${t("state.copied_to_clipboard")}`)
  115. setTimeout(() => (copyIcon.value = "copy"), 1000)
  116. }
  117. </script>