XMLLensRenderer.vue 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. <template>
  2. <div>
  3. <div
  4. class="
  5. bg-primary
  6. border-b border-dividerLight
  7. flex flex-1
  8. top-lowerSecondaryStickyFold
  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("response.body") }}
  18. </label>
  19. <div class="flex">
  20. <ButtonSecondary
  21. v-if="response.body"
  22. ref="downloadResponse"
  23. v-tippy="{ theme: 'tooltip' }"
  24. :title="$t('action.download_file')"
  25. :svg="downloadIcon"
  26. @click.native="downloadResponse"
  27. />
  28. <ButtonSecondary
  29. v-if="response.body"
  30. ref="copyResponse"
  31. v-tippy="{ theme: 'tooltip' }"
  32. :title="$t('action.copy')"
  33. :svg="copyIcon"
  34. @click.native="copyResponse"
  35. />
  36. </div>
  37. </div>
  38. <div class="relative">
  39. <SmartAceEditor
  40. :value="responseBodyText"
  41. :lang="'xml'"
  42. :options="{
  43. maxLines: Infinity,
  44. minLines: 16,
  45. autoScrollEditorIntoView: true,
  46. readOnly: true,
  47. showPrintMargin: false,
  48. useWorker: false,
  49. }"
  50. styles="border-b border-dividerLight"
  51. />
  52. </div>
  53. </div>
  54. </template>
  55. <script>
  56. import { defineComponent } from "@nuxtjs/composition-api"
  57. import TextContentRendererMixin from "./mixins/TextContentRendererMixin"
  58. import { copyToClipboard } from "~/helpers/utils/clipboard"
  59. export default defineComponent({
  60. mixins: [TextContentRendererMixin],
  61. props: {
  62. response: { type: Object, default: () => {} },
  63. },
  64. data() {
  65. return {
  66. copyIcon: "copy",
  67. downloadIcon: "download",
  68. }
  69. },
  70. computed: {
  71. responseType() {
  72. return (
  73. this.response.headers.find(
  74. (h) => h.key.toLowerCase() === "content-type"
  75. ).value || ""
  76. )
  77. .split(";")[0]
  78. .toLowerCase()
  79. },
  80. },
  81. methods: {
  82. downloadResponse() {
  83. const dataToWrite = this.responseBodyText
  84. const file = new Blob([dataToWrite], { type: this.responseType })
  85. const a = document.createElement("a")
  86. const url = URL.createObjectURL(file)
  87. a.href = url
  88. // TODO get uri from meta
  89. a.download = `${url.split("/").pop().split("#")[0].split("?")[0]}`
  90. document.body.appendChild(a)
  91. a.click()
  92. this.downloadIcon = "check"
  93. this.$toast.success(this.$t("state.download_started"), {
  94. icon: "downloading",
  95. })
  96. setTimeout(() => {
  97. document.body.removeChild(a)
  98. URL.revokeObjectURL(url)
  99. this.downloadIcon = "download"
  100. }, 1000)
  101. },
  102. copyResponse() {
  103. copyToClipboard(this.responseBodyText)
  104. this.copyIcon = "check"
  105. this.$toast.success(this.$t("state.copied_to_clipboard"), {
  106. icon: "content_paste",
  107. })
  108. setTimeout(() => (this.copyIcon = "copy"), 1000)
  109. },
  110. },
  111. })
  112. </script>