CodegenModal.vue 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  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="px-4 pt-4 pb-4">
  38. {{ t("request.generated_code") }}
  39. </label>
  40. </div>
  41. <SmartAceEditor
  42. v-if="codegenType"
  43. ref="generatedCode"
  44. :value="requestCode"
  45. :lang="codegens.find((x) => x.id === codegenType).language"
  46. :options="{
  47. maxLines: 16,
  48. minLines: 8,
  49. autoScrollEditorIntoView: true,
  50. readOnly: true,
  51. showPrintMargin: false,
  52. useWorker: false,
  53. }"
  54. styles="border rounded border-dividerLight"
  55. />
  56. </div>
  57. </template>
  58. <template #footer>
  59. <ButtonPrimary
  60. ref="copyRequestCode"
  61. :label="t('action.copy')"
  62. :svg="copyIcon"
  63. @click.native="copyRequestCode"
  64. />
  65. <ButtonSecondary :label="t('action.dismiss')" @click.native="hideModal" />
  66. </template>
  67. </SmartModal>
  68. </template>
  69. <script setup lang="ts">
  70. import { computed, ref, useContext, watch } from "@nuxtjs/composition-api"
  71. import { codegens, generateCodegenContext } from "~/helpers/codegen/codegen"
  72. import { copyToClipboard } from "~/helpers/utils/clipboard"
  73. import { getEffectiveRESTRequest } from "~/helpers/utils/EffectiveURL"
  74. import { getCurrentEnvironment } from "~/newstore/environments"
  75. import { getRESTRequest } from "~/newstore/RESTSession"
  76. const props = defineProps<{
  77. show: boolean
  78. }>()
  79. const emit = defineEmits<{
  80. (e: "hide-modal"): void
  81. }>()
  82. const {
  83. $toast,
  84. app: { i18n },
  85. } = useContext()
  86. const t = i18n.t.bind(i18n)
  87. const options = ref<any | null>(null)
  88. const request = ref(getRESTRequest())
  89. const codegenType = ref("curl")
  90. const copyIcon = ref("copy")
  91. const requestCode = computed(() => {
  92. const effectiveRequest = getEffectiveRESTRequest(
  93. request.value as any,
  94. getCurrentEnvironment()
  95. )
  96. return codegens
  97. .find((x) => x.id === codegenType.value)!
  98. .generator(generateCodegenContext(effectiveRequest))
  99. })
  100. watch(
  101. () => props.show,
  102. (goingToShow) => {
  103. if (goingToShow) {
  104. request.value = getRESTRequest()
  105. }
  106. }
  107. )
  108. const hideModal = () => emit("hide-modal")
  109. const copyRequestCode = () => {
  110. copyToClipboard(requestCode.value)
  111. copyIcon.value = "check"
  112. $toast.success(t("state.copied_to_clipboard").toString(), {
  113. icon: "content_paste",
  114. })
  115. setTimeout(() => (copyIcon.value = "copy"), 1000)
  116. }
  117. </script>