Actions for JSON responses

This commit is contained in:
Liyas Thomas
2020-06-22 12:25:43 +05:30
parent b44ba30873
commit e04e82e81d
2 changed files with 148 additions and 21 deletions

View File

@@ -1,24 +1,72 @@
<template>
<ul>
<li>
<Editor
:value="responseBodyText"
:lang="'json'"
:options="{
maxLines: 16,
minLines: '16',
fontSize: '16px',
autoScrollEditorIntoView: true,
readOnly: true,
showPrintMargin: false,
useWorker: false,
}"
/>
<div class="flex-wrap">
<label for="body">{{ $t("response") }}</label>
<div>
<button
class="icon"
@click="ToggleExpandResponse"
ref="ToggleExpandResponse"
v-if="response.body"
v-tooltip="{
content: !expandResponse ? $t('expand_response') : $t('collapse_response'),
}"
>
<i class="material-icons">
{{ !expandResponse ? "unfold_more" : "unfold_less" }}
</i>
</button>
<button
class="icon"
ref="prettifyResponse"
@click="prettifyResponseBody"
v-tooltip="$t('prettify_body')"
v-if="response.body && this.responseType.endsWith('json')"
>
<i class="material-icons">photo_filter</i>
</button>
<button
class="icon"
@click="downloadResponse"
ref="downloadResponse"
v-if="response.body && canDownloadResponse"
v-tooltip="$t('download_file')"
>
<i class="material-icons">save_alt</i>
</button>
<button
class="icon"
@click="copyResponse"
ref="copyResponse"
v-if="response.body"
v-tooltip="$t('copy_response')"
>
<i class="material-icons">content_copy</i>
</button>
</div>
</div>
<div id="response-details-wrapper">
<Editor
:value="responseBodyText"
:lang="'json'"
:options="{
maxLines: responseBodyMaxLines,
minLines: '16',
fontSize: '16px',
autoScrollEditorIntoView: true,
readOnly: true,
showPrintMargin: false,
useWorker: false,
}"
/>
</div>
</li>
</ul>
</template>
<script>
import AceEditor from "../../ui/ace-editor"
import { isJSONContentType } from "~/helpers/utils/contenttypes"
export default {
components: {
@@ -27,17 +75,95 @@ export default {
props: {
response: {},
},
data() {
return {
expandResponse: false,
responseBodyMaxLines: 16,
doneButton: '<i class="material-icons">done</i>',
downloadButton: '<i class="material-icons">save_alt</i>',
copyButton: '<i class="material-icons">content_copy</i>',
}
},
computed: {
responseBodyText() {
responseBodyText: {
get: function () {
try {
return JSON.stringify(
JSON.parse(new TextDecoder("utf-8").decode(new Uint8Array(this.response.body))),
null,
2
)
} catch (e) {
// Most probs invalid JSON was returned, so drop prettification (should we warn ?)
return new TextDecoder("utf-8").decode(new Uint8Array(this.response.body))
}
},
set: function (newValue) {
return newValue
},
},
responseType() {
return (this.response.headers["content-type"] || "").split(";")[0].toLowerCase()
},
},
methods: {
ToggleExpandResponse() {
this.expandResponse = !this.expandResponse
this.responseBodyMaxLines = this.responseBodyMaxLines == Infinity ? 16 : Infinity
},
downloadResponse() {
const dataToWrite = this.responseBodyText
const file = new Blob([dataToWrite], { type: this.responseType })
const a = document.createElement("a")
const url = URL.createObjectURL(file)
a.href = url
// TODO get uri from meta
a.download = `response on ${Date()}`.replace(/\./g, "[dot]")
document.body.appendChild(a)
a.click()
this.$refs.downloadResponse.innerHTML = this.doneButton
this.$toast.success(this.$t("download_started"), {
icon: "done",
})
setTimeout(() => {
document.body.removeChild(a)
window.URL.revokeObjectURL(url)
this.$refs.downloadResponse.innerHTML = this.downloadButton
}, 1000)
},
canDownloadResponse() {
return (
this.response &&
this.response.headers &&
this.response.headers["content-type"] &&
isJSONContentType(this.response.headers["content-type"])
)
},
copyResponse() {
this.$refs.copyResponse.innerHTML = this.doneButton
this.$toast.success(this.$t("copied_to_clipboard"), {
icon: "done",
})
const aux = document.createElement("textarea")
const copy = this.responseBodyText
aux.innerText = copy
document.body.appendChild(aux)
aux.select()
document.execCommand("copy")
document.body.removeChild(aux)
setTimeout(() => (this.$refs.copyResponse.innerHTML = this.copyButton), 1000)
},
prettifyResponseBody() {
try {
return JSON.stringify(
JSON.parse(new TextDecoder("utf-8").decode(new Uint8Array(this.response.body))),
null,
2
)
const jsonObj = JSON.parse(this.responseBodyText)
this.responseBodyText = JSON.stringify(jsonObj, null, 2)
let oldIcon = this.$refs.prettifyResponse.innerHTML
this.$refs.prettifyResponse.innerHTML = this.doneButton
setTimeout(() => (this.$refs.prettifyResponse.innerHTML = oldIcon), 1000)
} catch (e) {
// Most probs invalid JSON was returned, so drop prettification (should we warn ?)
return new TextDecoder("utf-8").decode(new Uint8Array(this.response.body))
this.$toast.error(`${this.$t("json_prettify_invalid_body")}`, {
icon: "error",
})
}
},
},