RawBody.vue 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. <template>
  2. <div>
  3. <div
  4. class="
  5. bg-primary
  6. border-b border-dividerLight
  7. flex flex-1
  8. top-upperTertiaryStickyFold
  9. pl-4
  10. z-10
  11. sticky
  12. items-center
  13. justify-between
  14. "
  15. >
  16. <label class="font-semibold text-secondaryLight">
  17. {{ $t("request.raw_body") }}
  18. </label>
  19. <div class="flex">
  20. <ButtonSecondary
  21. v-tippy="{ theme: 'tooltip' }"
  22. to="https://docs.hoppscotch.io/features/body"
  23. blank
  24. :title="$t('app.wiki')"
  25. svg="help-circle"
  26. />
  27. <ButtonSecondary
  28. v-tippy="{ theme: 'tooltip' }"
  29. :title="$t('state.linewrap')"
  30. :class="{ '!text-accent': linewrapEnabled }"
  31. svg="corner-down-left"
  32. @click.native.prevent="linewrapEnabled = !linewrapEnabled"
  33. />
  34. <ButtonSecondary
  35. v-tippy="{ theme: 'tooltip' }"
  36. :title="$t('action.clear')"
  37. svg="trash-2"
  38. @click.native="clearContent"
  39. />
  40. <ButtonSecondary
  41. v-if="contentType && contentType.endsWith('json')"
  42. ref="prettifyRequest"
  43. v-tippy="{ theme: 'tooltip' }"
  44. :title="$t('action.prettify')"
  45. :svg="prettifyIcon"
  46. @click.native="prettifyRequestBody"
  47. />
  48. <label for="payload">
  49. <ButtonSecondary
  50. v-tippy="{ theme: 'tooltip' }"
  51. :title="$t('import.json')"
  52. svg="file-plus"
  53. @click.native="$refs.payload.click()"
  54. />
  55. </label>
  56. <input
  57. ref="payload"
  58. class="input"
  59. name="payload"
  60. type="file"
  61. @change="uploadPayload"
  62. />
  63. </div>
  64. </div>
  65. <div ref="rawBodyParameters"></div>
  66. </div>
  67. </template>
  68. <script setup lang="ts">
  69. import { computed, reactive, ref, useContext } from "@nuxtjs/composition-api"
  70. import { useCodemirror } from "~/helpers/editor/codemirror"
  71. import { getEditorLangForMimeType } from "~/helpers/editorutils"
  72. import { pluckRef } from "~/helpers/utils/composables"
  73. import { useRESTRequestBody } from "~/newstore/RESTSession"
  74. const props = defineProps<{
  75. contentType: string
  76. }>()
  77. const {
  78. $toast,
  79. app: { i18n },
  80. } = useContext()
  81. const t = i18n.t.bind(i18n)
  82. const rawParamsBody = pluckRef(useRESTRequestBody(), "body")
  83. const prettifyIcon = ref("wand")
  84. const rawInputEditorLang = computed(() =>
  85. getEditorLangForMimeType(props.contentType)
  86. )
  87. const linewrapEnabled = ref(true)
  88. const rawBodyParameters = ref<any | null>(null)
  89. useCodemirror(
  90. rawBodyParameters,
  91. rawParamsBody,
  92. reactive({
  93. extendedEditorConfig: {
  94. lineWrapping: linewrapEnabled,
  95. mode: rawInputEditorLang,
  96. placeholder: t("request.raw_body"),
  97. },
  98. linter: null,
  99. completer: null,
  100. })
  101. )
  102. const clearContent = () => {
  103. rawParamsBody.value = ""
  104. }
  105. const uploadPayload = (e: InputEvent) => {
  106. const file = e.target.files[0]
  107. if (file !== undefined && file !== null) {
  108. const reader = new FileReader()
  109. reader.onload = ({ target }) => {
  110. rawParamsBody.value = target?.result
  111. }
  112. reader.readAsText(file)
  113. $toast.success(`${t("state.file_imported")}`, {
  114. icon: "attach_file",
  115. })
  116. } else {
  117. $toast.error(`${t("action.choose_file")}`, {
  118. icon: "attach_file",
  119. })
  120. }
  121. }
  122. const prettifyRequestBody = () => {
  123. try {
  124. const jsonObj = JSON.parse(rawParamsBody.value)
  125. rawParamsBody.value = JSON.stringify(jsonObj, null, 2)
  126. prettifyIcon.value = "check"
  127. setTimeout(() => (prettifyIcon.value = "wand"), 1000)
  128. } catch (e) {
  129. console.error(e)
  130. $toast.error(`${t("error.json_prettify_invalid_body")}`, {
  131. icon: "error_outline",
  132. })
  133. }
  134. }
  135. </script>