RawBody.vue 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  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('action.clear')"
  30. svg="trash-2"
  31. @click.native="clearContent('rawParams', $event)"
  32. />
  33. <ButtonSecondary
  34. v-if="contentType && contentType.endsWith('json')"
  35. ref="prettifyRequest"
  36. v-tippy="{ theme: 'tooltip' }"
  37. :title="$t('action.prettify')"
  38. :svg="prettifyIcon"
  39. @click.native="prettifyRequestBody"
  40. />
  41. <label for="payload">
  42. <ButtonSecondary
  43. v-tippy="{ theme: 'tooltip' }"
  44. :title="$t('import.json')"
  45. svg="file-plus"
  46. @click.native="$refs.payload.click()"
  47. />
  48. </label>
  49. <input
  50. ref="payload"
  51. class="input"
  52. name="payload"
  53. type="file"
  54. @change="uploadPayload"
  55. />
  56. </div>
  57. </div>
  58. <div class="relative">
  59. <SmartAceEditor
  60. v-model="rawParamsBody"
  61. :lang="rawInputEditorLang"
  62. :options="{
  63. maxLines: Infinity,
  64. minLines: 16,
  65. autoScrollEditorIntoView: true,
  66. showPrintMargin: false,
  67. useWorker: false,
  68. }"
  69. styles="border-b border-dividerLight"
  70. />
  71. </div>
  72. </div>
  73. </template>
  74. <script>
  75. import { defineComponent } from "@nuxtjs/composition-api"
  76. import { getEditorLangForMimeType } from "~/helpers/editorutils"
  77. import { pluckRef } from "~/helpers/utils/composables"
  78. import { useRESTRequestBody } from "~/newstore/RESTSession"
  79. export default defineComponent({
  80. props: {
  81. contentType: {
  82. type: String,
  83. required: true,
  84. },
  85. },
  86. setup() {
  87. return {
  88. rawParamsBody: pluckRef(useRESTRequestBody(), "body"),
  89. prettifyIcon: "align-left",
  90. }
  91. },
  92. computed: {
  93. rawInputEditorLang() {
  94. return getEditorLangForMimeType(this.contentType)
  95. },
  96. },
  97. methods: {
  98. clearContent() {
  99. this.rawParamsBody = ""
  100. },
  101. uploadPayload() {
  102. const file = this.$refs.payload.files[0]
  103. if (file !== undefined && file !== null) {
  104. const reader = new FileReader()
  105. reader.onload = ({ target }) => {
  106. this.rawParamsBody = target.result
  107. }
  108. reader.readAsText(file)
  109. this.$toast.success(this.$t("state.file_imported"), {
  110. icon: "attach_file",
  111. })
  112. } else {
  113. this.$toast.error(this.$t("action.choose_file"), {
  114. icon: "attach_file",
  115. })
  116. }
  117. this.$refs.payload.value = ""
  118. },
  119. prettifyRequestBody() {
  120. try {
  121. const jsonObj = JSON.parse(this.rawParamsBody)
  122. this.rawParamsBody = JSON.stringify(jsonObj, null, 2)
  123. this.prettifyIcon = "check"
  124. setTimeout(() => (this.prettifyIcon = "align-left"), 1000)
  125. } catch (e) {
  126. console.error(e)
  127. this.$toast.error(`${this.$t("error.json_prettify_invalid_body")}`, {
  128. icon: "error_outline",
  129. })
  130. }
  131. },
  132. },
  133. })
  134. </script>