RawBody.vue 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  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. import "codemirror/mode/yaml/yaml"
  75. import "codemirror/mode/xml/xml"
  76. import "codemirror/mode/css/css"
  77. import "codemirror/mode/htmlmixed/htmlmixed"
  78. import "codemirror/mode/javascript/javascript"
  79. const props = defineProps<{
  80. contentType: string
  81. }>()
  82. const {
  83. $toast,
  84. app: { i18n },
  85. } = useContext()
  86. const t = i18n.t.bind(i18n)
  87. const rawParamsBody = pluckRef(useRESTRequestBody(), "body")
  88. const prettifyIcon = ref("align-left")
  89. const rawInputEditorLang = computed(() =>
  90. getEditorLangForMimeType(props.contentType)
  91. )
  92. const linewrapEnabled = ref(true)
  93. const rawBodyParameters = ref<any | null>(null)
  94. useCodemirror(
  95. rawBodyParameters,
  96. rawParamsBody,
  97. reactive({
  98. extendedEditorConfig: {
  99. lineWrapping: linewrapEnabled,
  100. mode: rawInputEditorLang,
  101. placeholder: t("request.raw_body"),
  102. },
  103. linter: null,
  104. completer: null,
  105. })
  106. )
  107. const clearContent = () => {
  108. rawParamsBody.value = ""
  109. }
  110. const uploadPayload = (e: InputEvent) => {
  111. const file = e.target.files[0]
  112. if (file !== undefined && file !== null) {
  113. const reader = new FileReader()
  114. reader.onload = ({ target }) => {
  115. rawParamsBody.value = target?.result
  116. }
  117. reader.readAsText(file)
  118. $toast.success(`${t("state.file_imported")}`, {
  119. icon: "attach_file",
  120. })
  121. } else {
  122. $toast.error(`${t("action.choose_file")}`, {
  123. icon: "attach_file",
  124. })
  125. }
  126. }
  127. const prettifyRequestBody = () => {
  128. try {
  129. const jsonObj = JSON.parse(rawParamsBody.value)
  130. rawParamsBody.value = JSON.stringify(jsonObj, null, 2)
  131. prettifyIcon.value = "check"
  132. setTimeout(() => (prettifyIcon.value = "align-left"), 1000)
  133. } catch (e) {
  134. console.error(e)
  135. $toast.error(`${t("error.json_prettify_invalid_body")}`, {
  136. icon: "error_outline",
  137. })
  138. }
  139. }
  140. </script>