Skip to content

Commit ae62119

Browse files
authored
Merge pull request #18 from smartondev/3-iframe-preview
enh: iframe preview #3
2 parents 65a746c + 9d5acd7 commit ae62119

File tree

6 files changed

+106
-28
lines changed

6 files changed

+106
-28
lines changed

gui_server.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ async def handle_download(request):
1818
content = proxy_log.get_content_storage().read(hash_value)
1919
if content is None:
2020
return web.Response(status=404)
21-
return web.Response(body=content, status=200, headers={'Content-Type': 'application/octet-stream'})
21+
content_type = request.query.get('content_type', 'application/octet-stream')
22+
return web.Response(body=content, status=200, headers={'Content-Type': content_type})
2223

2324

2425
def run_gui_server(environment: Environment, proxy_log: ProxyLog):

webapp/src/components/common/PlaceholderButton.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
</script>
44

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

99
<style scoped>

webapp/src/components/pages/RequestLog/components/CopyToClipboardButton.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ import {copyToClipboard} from "@/helpers/Clipboard";
44
import {isNotNullNorUndefined} from "@/helpers/ConditionHelper";
55
66
type Props = {
7-
title: string,
7+
title?: string | null,
88
content: string | undefined | null,
99
tooltip?: string | null,
1010
}
1111
1212
const props = withDefaults(defineProps<Props>(), {
13-
title: 'Copy to clipboard',
13+
title: null,
1414
content: null,
1515
tooltip: null,
1616
});

webapp/src/components/pages/RequestLog/components/DownloadOriginalContentButton.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ const downloadUrl = computed(() => {
3535
<a :href="downloadUrl" target="_blank" class="btn btn-sm btn-outline-primary me-2"
3636
v-if="isNotUndefined(body?.hash)"
3737
title="Download original content">
38-
<span class="bi bi-download"/> Download
38+
<span class="bi bi-download"/>
3939
</a>
4040
</template>
4141

webapp/src/components/pages/RequestLog/components/HttpBody.vue

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
import type {RequestLogBody} from "@/types/RequestLog";
44
import useExpand from "@/services/ui/Expand";
55
import {computed, defineProps} from "vue";
6-
import PlaceholderParagraph from "@/components/common/PlaceholderParagraph.vue";
76
import DownloadOriginalContentButton from "@/components/pages/RequestLog/components/DownloadOriginalContentButton.vue";
87
import CopyToClipboardButton from "@/components/pages/RequestLog/components/CopyToClipboardButton.vue";
98
import PlaceholderButton from "@/components/common/PlaceholderButton.vue";
9+
import HttpBodyTabs from "@/components/pages/RequestLog/components/HttpBodyTabs.vue";
1010
1111
type Props = {
1212
body?: RequestLogBody | undefined,
@@ -41,43 +41,31 @@ const show = computed(() => {
4141
<template>
4242
<div class="container-fluid mb-3 px-0 mx-0 placeholder-glow" v-if="show">
4343
<div class="row">
44-
<div class="col-12 cursor-pointer" @click="toggleExpanded">
44+
<div class="col cursor-pointer text-truncate" @click="toggleExpanded">
4545
<span class="fs-6 fw-bold me-2">{{ title }}</span>
4646
<span class="bi bi-caret-up-fill me-2" v-if="expandedState"/>
4747
<span class="bi bi-caret-down-fill me-2" v-else/>
4848

49-
<span class="fs-80 fst-italic" v-if="body?.contentType">( {{ body.contentType }} )</span>
50-
<span class="fs-80 col-2 placeholder" v-if="usePlaceholder"/>
49+
<span class="fs-80 fst-italic text-nowrap" v-if="body?.contentType">( {{ body.contentType }} )</span>
50+
<span class="fs-80 w-25 placeholder" v-if="usePlaceholder"/>
5151
</div>
52-
<div class="col-12 my-1" v-if="expandedState">
52+
<div class="col-auto text-end" v-if="expandedState">
5353
<div v-if="body?.hash">
5454
<DownloadOriginalContentButton :body="body"/>
55-
<CopyToClipboardButton :content="body?.previewContent" title="Copy to clipboard"
55+
<CopyToClipboardButton :content="body?.previewContent"
5656
tooltip="Copy preview content to clipboard"/>
5757
</div>
5858
<div v-else-if="usePlaceholder">
59-
<PlaceholderButton class="btn-sm btn-primary col-1 me-2"/>
60-
<PlaceholderButton class="btn-sm btn-secondary col-1 me-2"/>
59+
<PlaceholderButton class="btn-sm btn-primary me-2"/>
60+
<PlaceholderButton class="btn-sm btn-secondary me-2"/>
6161
</div>
6262
</div>
6363
</div>
64-
<div class="row ps-3" v-if="expandedState">
65-
<div class="col-12">
66-
<PlaceholderParagraph v-if="usePlaceholder"/>
67-
<pre v-else v-text="body?.previewContent"/>
68-
</div>
69-
</div>
70-
<div class="row ps-3 cursor-pointer" v-else @click="toggleExpanded">
71-
<div class="col-12 text-truncate fs-80">
72-
<span v-if="usePlaceholder" class="col-12 placeholder"/>
73-
<span v-else v-text="body?.previewContent"/>
74-
</div>
75-
</div>
64+
<HttpBodyTabs :body="body" :usePlaceholder="usePlaceholder" :expandedState="expandedState"
65+
@toggle-expanded="toggleExpanded"/>
7666
</div>
7767
</template>
7868

7969
<style scoped>
80-
pre {
81-
max-height: 400px;
82-
}
70+
8371
</style>
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<script setup lang="ts">
2+
3+
import {isNotUndefined} from "@/helpers/ConditionHelper";
4+
import {computed, ref} from "vue";
5+
import {getDownloadUrlPrefix} from "@/helpers/EnvironmentHelper";
6+
import type {RequestLogBody} from "@/types/RequestLog";
7+
import PlaceholderParagraph from "@/components/common/PlaceholderParagraph.vue";
8+
9+
type Props = {
10+
body: RequestLogBody | undefined,
11+
usePlaceholder: boolean,
12+
expandedState: boolean,
13+
}
14+
15+
const props = withDefaults(defineProps<Props>(), {
16+
body: undefined,
17+
usePlaceholder: false,
18+
expandedState: false,
19+
});
20+
21+
const TAB_KEY_PREVIEW = 'preview';
22+
const TAB_KEY_BROWSER_PREVIEW = 'browser-preview';
23+
const activeTab = ref(TAB_KEY_PREVIEW);
24+
25+
const tabs = computed(() => {
26+
return [
27+
{
28+
active: activeTab.value === TAB_KEY_PREVIEW,
29+
title: 'Preview',
30+
key: TAB_KEY_PREVIEW,
31+
}, {
32+
active: activeTab.value === TAB_KEY_BROWSER_PREVIEW,
33+
title: 'Browser preview',
34+
key: TAB_KEY_BROWSER_PREVIEW,
35+
}
36+
];
37+
})
38+
39+
const iframeSrc = computed(() => {
40+
if (props.body?.hash === null) {
41+
return '';
42+
}
43+
return getDownloadUrlPrefix() + `/${props.body?.hash}?content_type=${encodeURIComponent(props.body?.contentType ?? '')}`;
44+
})
45+
46+
defineEmits(['toggle-expanded']);
47+
48+
</script>
49+
50+
<template>
51+
<div class="ps-3">
52+
<div class="row">
53+
<div class="col-12" v-if="expandedState">
54+
<ul class="nav nav-tabs">
55+
<li class="nav-item" v-for="item in tabs" :key="item.key" @click="activeTab = item.key">
56+
<button class="nav-link" :class="{active: item.active}"
57+
v-if="!usePlaceholder" v-text="item.title"/>
58+
<button v-else class="nav-link bg-secondary placeholder text-secondary" href="#"
59+
v-text="item.title"/>
60+
</li>
61+
</ul>
62+
</div>
63+
</div>
64+
<div class="row" v-if="expandedState">
65+
<div class="col-12">
66+
<PlaceholderParagraph v-if="usePlaceholder"/>
67+
<div v-else-if="activeTab === TAB_KEY_PREVIEW">
68+
<pre v-if="isNotUndefined(body?.previewContent)" v-text="body?.previewContent"/>
69+
<b class="d-block text-info height-fix" v-else>Preview not available</b>
70+
</div>
71+
<iframe v-else-if="activeTab === TAB_KEY_BROWSER_PREVIEW" :src="iframeSrc"
72+
class="w-100" height="400"/>
73+
</div>
74+
</div>
75+
<div class="row ps-3 cursor-pointer" v-else @click="$emit('toggle-expanded')">
76+
<div class="col-12 text-truncate fs-80">
77+
<span v-if="usePlaceholder" class="col-12 placeholder"/>
78+
<span v-else v-text="body?.previewContent"/>
79+
</div>
80+
</div>
81+
</div>
82+
</template>
83+
84+
<style scoped>
85+
pre, .height-fix {
86+
max-height: 400px;
87+
min-height: 150px;
88+
}
89+
</style>

0 commit comments

Comments
 (0)