Skip to content

Commit

Permalink
Merge pull request #18 from smartondev/3-iframe-preview
Browse files Browse the repository at this point in the history
enh: iframe preview #3
  • Loading branch information
kamarton authored May 25, 2024
2 parents 65a746c + 9d5acd7 commit ae62119
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 28 deletions.
3 changes: 2 additions & 1 deletion gui_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ async def handle_download(request):
content = proxy_log.get_content_storage().read(hash_value)
if content is None:
return web.Response(status=404)
return web.Response(body=content, status=200, headers={'Content-Type': 'application/octet-stream'})
content_type = request.query.get('content_type', 'application/octet-stream')
return web.Response(body=content, status=200, headers={'Content-Type': content_type})


def run_gui_server(environment: Environment, proxy_log: ProxyLog):
Expand Down
2 changes: 1 addition & 1 deletion webapp/src/components/common/PlaceholderButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
</script>

<template>
<a href="#" class="btn disabled placeholder" aria-hidden="true" tabindex="-1"/>
<a href="#" class="btn disabled placeholder" aria-hidden="true" tabindex="-1">&nbsp;&nbsp;&nbsp;</a>
</template>

<style scoped>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import {copyToClipboard} from "@/helpers/Clipboard";
import {isNotNullNorUndefined} from "@/helpers/ConditionHelper";
type Props = {
title: string,
title?: string | null,
content: string | undefined | null,
tooltip?: string | null,
}
const props = withDefaults(defineProps<Props>(), {
title: 'Copy to clipboard',
title: null,
content: null,
tooltip: null,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const downloadUrl = computed(() => {
<a :href="downloadUrl" target="_blank" class="btn btn-sm btn-outline-primary me-2"
v-if="isNotUndefined(body?.hash)"
title="Download original content">
<span class="bi bi-download"/> Download
<span class="bi bi-download"/>
</a>
</template>
Expand Down
34 changes: 11 additions & 23 deletions webapp/src/components/pages/RequestLog/components/HttpBody.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
import type {RequestLogBody} from "@/types/RequestLog";
import useExpand from "@/services/ui/Expand";
import {computed, defineProps} from "vue";
import PlaceholderParagraph from "@/components/common/PlaceholderParagraph.vue";
import DownloadOriginalContentButton from "@/components/pages/RequestLog/components/DownloadOriginalContentButton.vue";
import CopyToClipboardButton from "@/components/pages/RequestLog/components/CopyToClipboardButton.vue";
import PlaceholderButton from "@/components/common/PlaceholderButton.vue";
import HttpBodyTabs from "@/components/pages/RequestLog/components/HttpBodyTabs.vue";
type Props = {
body?: RequestLogBody | undefined,
Expand Down Expand Up @@ -41,43 +41,31 @@ const show = computed(() => {
<template>
<div class="container-fluid mb-3 px-0 mx-0 placeholder-glow" v-if="show">
<div class="row">
<div class="col-12 cursor-pointer" @click="toggleExpanded">
<div class="col cursor-pointer text-truncate" @click="toggleExpanded">
<span class="fs-6 fw-bold me-2">{{ title }}</span>
<span class="bi bi-caret-up-fill me-2" v-if="expandedState"/>
<span class="bi bi-caret-down-fill me-2" v-else/>

<span class="fs-80 fst-italic" v-if="body?.contentType">( {{ body.contentType }} )</span>
<span class="fs-80 col-2 placeholder" v-if="usePlaceholder"/>
<span class="fs-80 fst-italic text-nowrap" v-if="body?.contentType">( {{ body.contentType }} )</span>
<span class="fs-80 w-25 placeholder" v-if="usePlaceholder"/>
</div>
<div class="col-12 my-1" v-if="expandedState">
<div class="col-auto text-end" v-if="expandedState">
<div v-if="body?.hash">
<DownloadOriginalContentButton :body="body"/>
<CopyToClipboardButton :content="body?.previewContent" title="Copy to clipboard"
<CopyToClipboardButton :content="body?.previewContent"
tooltip="Copy preview content to clipboard"/>
</div>
<div v-else-if="usePlaceholder">
<PlaceholderButton class="btn-sm btn-primary col-1 me-2"/>
<PlaceholderButton class="btn-sm btn-secondary col-1 me-2"/>
<PlaceholderButton class="btn-sm btn-primary me-2"/>
<PlaceholderButton class="btn-sm btn-secondary me-2"/>
</div>
</div>
</div>
<div class="row ps-3" v-if="expandedState">
<div class="col-12">
<PlaceholderParagraph v-if="usePlaceholder"/>
<pre v-else v-text="body?.previewContent"/>
</div>
</div>
<div class="row ps-3 cursor-pointer" v-else @click="toggleExpanded">
<div class="col-12 text-truncate fs-80">
<span v-if="usePlaceholder" class="col-12 placeholder"/>
<span v-else v-text="body?.previewContent"/>
</div>
</div>
<HttpBodyTabs :body="body" :usePlaceholder="usePlaceholder" :expandedState="expandedState"
@toggle-expanded="toggleExpanded"/>
</div>
</template>
<style scoped>
pre {
max-height: 400px;
}
</style>
89 changes: 89 additions & 0 deletions webapp/src/components/pages/RequestLog/components/HttpBodyTabs.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<script setup lang="ts">
import {isNotUndefined} from "@/helpers/ConditionHelper";
import {computed, ref} from "vue";
import {getDownloadUrlPrefix} from "@/helpers/EnvironmentHelper";
import type {RequestLogBody} from "@/types/RequestLog";
import PlaceholderParagraph from "@/components/common/PlaceholderParagraph.vue";
type Props = {
body: RequestLogBody | undefined,
usePlaceholder: boolean,
expandedState: boolean,
}
const props = withDefaults(defineProps<Props>(), {
body: undefined,
usePlaceholder: false,
expandedState: false,
});
const TAB_KEY_PREVIEW = 'preview';
const TAB_KEY_BROWSER_PREVIEW = 'browser-preview';
const activeTab = ref(TAB_KEY_PREVIEW);
const tabs = computed(() => {
return [
{
active: activeTab.value === TAB_KEY_PREVIEW,
title: 'Preview',
key: TAB_KEY_PREVIEW,
}, {
active: activeTab.value === TAB_KEY_BROWSER_PREVIEW,
title: 'Browser preview',
key: TAB_KEY_BROWSER_PREVIEW,
}
];
})
const iframeSrc = computed(() => {
if (props.body?.hash === null) {
return '';
}
return getDownloadUrlPrefix() + `/${props.body?.hash}?content_type=${encodeURIComponent(props.body?.contentType ?? '')}`;
})
defineEmits(['toggle-expanded']);
</script>

<template>
<div class="ps-3">
<div class="row">
<div class="col-12" v-if="expandedState">
<ul class="nav nav-tabs">
<li class="nav-item" v-for="item in tabs" :key="item.key" @click="activeTab = item.key">
<button class="nav-link" :class="{active: item.active}"
v-if="!usePlaceholder" v-text="item.title"/>
<button v-else class="nav-link bg-secondary placeholder text-secondary" href="#"
v-text="item.title"/>
</li>
</ul>
</div>
</div>
<div class="row" v-if="expandedState">
<div class="col-12">
<PlaceholderParagraph v-if="usePlaceholder"/>
<div v-else-if="activeTab === TAB_KEY_PREVIEW">
<pre v-if="isNotUndefined(body?.previewContent)" v-text="body?.previewContent"/>
<b class="d-block text-info height-fix" v-else>Preview not available</b>
</div>
<iframe v-else-if="activeTab === TAB_KEY_BROWSER_PREVIEW" :src="iframeSrc"
class="w-100" height="400"/>
</div>
</div>
<div class="row ps-3 cursor-pointer" v-else @click="$emit('toggle-expanded')">
<div class="col-12 text-truncate fs-80">
<span v-if="usePlaceholder" class="col-12 placeholder"/>
<span v-else v-text="body?.previewContent"/>
</div>
</div>
</div>
</template>
<style scoped>
pre, .height-fix {
max-height: 400px;
min-height: 150px;
}
</style>

0 comments on commit ae62119

Please sign in to comment.