From d3e764d7f9321e5a778834766b9651187627a20d Mon Sep 17 00:00:00 2001
From: syuilo <syuilotan@yahoo.co.jp>
Date: Sun, 1 Nov 2020 22:43:19 +0900
Subject: [PATCH] Improve task manager

---
 .../components/taskmanager.api-window.vue     | 69 +++++++++++++++++++
 src/client/components/taskmanager.vue         | 14 +++-
 src/client/os.ts                              | 10 ++-
 3 files changed, 90 insertions(+), 3 deletions(-)
 create mode 100644 src/client/components/taskmanager.api-window.vue

diff --git a/src/client/components/taskmanager.api-window.vue b/src/client/components/taskmanager.api-window.vue
new file mode 100644
index 000000000..9cdc8227e
--- /dev/null
+++ b/src/client/components/taskmanager.api-window.vue
@@ -0,0 +1,69 @@
+<template>
+<XWindow ref="window"
+	:initial-width="370"
+	:initial-height="450"
+	:can-resize="true"
+	@close="$refs.window.close()"
+	@closed="$emit('closed')"
+>
+	<template #header>Req Viewer</template>
+
+	<div class="rlkneywz">
+		<MkTab v-model:value="tab" :items="[{ label: 'Request', value: 'req', }, { label: 'Response', value: 'res', }]" style="border-bottom: solid 1px var(--divider);"/>
+
+		<code v-if="tab === 'req'">{{ reqStr }}</code>
+		<code v-if="tab === 'res'">{{ resStr }}</code>
+	</div>
+</XWindow>
+</template>
+
+<script lang="ts">
+import { defineComponent } from 'vue';
+import * as JSON5 from 'json5';
+import XWindow from '@/components/ui/window.vue';
+import MkTab from '@/components/tab.vue';
+
+export default defineComponent({
+	components: {
+		XWindow,
+		MkTab,
+	},
+
+	props: {
+		req: {
+			required: true,
+		}
+	},
+
+	emits: ['closed'],
+
+	data() {
+		return {
+			tab: 'req',
+			reqStr: JSON5.stringify(this.req.req, null, '\t'),
+			resStr: JSON5.stringify(this.req.res, null, '\t'),
+		}
+	},
+
+	methods: {
+	}
+});
+</script>
+
+<style lang="scss" scoped>
+.rlkneywz {
+	display: flex;
+	flex-direction: column;
+	height: 100%;
+
+	> code {
+		display: block;
+		flex: 1;
+		padding: 8px;
+		overflow: auto;
+		tab-size: 2;
+		white-space: pre;
+		font-family: Fira code, Fira Mono, Consolas, Menlo, Courier, monospace;
+	}
+}
+</style>
diff --git a/src/client/components/taskmanager.vue b/src/client/components/taskmanager.vue
index 704e2d3e8..b81f26736 100644
--- a/src/client/components/taskmanager.vue
+++ b/src/client/components/taskmanager.vue
@@ -54,7 +54,7 @@
 					<div>Endpoint</div>
 					<div>State</div>
 				</div>
-				<div v-for="req in apiRequests">
+				<div v-for="req in apiRequests" @click="showReq(req)">
 					<div>#{{ req.id }}</div>
 					<div>{{ req.endpoint }}</div>
 					<div class="state" :class="req.state">{{ req.state }}</div>
@@ -119,6 +119,13 @@ export default defineComponent({
 			os.popups.value = os.popups.value.filter(x => x !== p);
 		};
 
+		const showReq = async req => {
+			os.popup(await import('./taskmanager.api-window.vue'), {
+				req: req
+			}, {
+			}, 'closed');
+		};
+
 		return {
 			tab: ref('stream'),
 			popups: os.popups,
@@ -126,6 +133,7 @@ export default defineComponent({
 			connections,
 			pools,
 			killPopup,
+			showReq,
 			faTerminal,
 		};
 	},
@@ -152,6 +160,10 @@ export default defineComponent({
 			> div {
 				display: table-row;
 
+				&:nth-child(even) {
+					//background: rgba(0, 0, 0, 0.1);
+				}
+
 				&.header {
 					opacity: 0.7;
 				}
diff --git a/src/client/os.ts b/src/client/os.ts
index a9b56e60f..5f21cc39f 100644
--- a/src/client/os.ts
+++ b/src/client/os.ts
@@ -13,6 +13,7 @@ export const isMobile = /mobile|iphone|ipad|android/.test(ua);
 export const stream = markRaw(new Stream());
 
 export const pendingApiRequestsCount = ref(0);
+let apiRequestsCount = 0; // for debug
 export const apiRequests = ref([]); // for debug
 
 export const windows = new Map();
@@ -25,12 +26,15 @@ export function api(endpoint: string, data: Record<string, any> = {}, token?: st
 	};
 
 	const log = debug ? reactive({
-		id: apiRequests.value.length,
+		id: ++apiRequestsCount,
 		endpoint,
-		state: 'pending'
+		req: markRaw(data),
+		res: null,
+		state: 'pending',
 	}) : null;
 	if (debug) {
 		apiRequests.value.push(log);
+		if (apiRequests.value.length > 128) apiRequests.value.shift();
 	}
 
 	const promise = new Promise((resolve, reject) => {
@@ -50,6 +54,7 @@ export function api(endpoint: string, data: Record<string, any> = {}, token?: st
 			if (res.status === 200) {
 				resolve(body);
 				if (debug) {
+					log.res = markRaw(body);
 					log.state = 'success';
 				}
 			} else if (res.status === 204) {
@@ -60,6 +65,7 @@ export function api(endpoint: string, data: Record<string, any> = {}, token?: st
 			} else {
 				reject(body.error);
 				if (debug) {
+					log.res = markRaw(body.error);
 					log.state = 'failed';
 				}
 			}