From 5e33595c12dd0c26a97e56d65242b0abc9fbe75a Mon Sep 17 00:00:00 2001 From: James George <25279263+jamesgeorge007@users.noreply.github.com> Date: Fri, 6 Jun 2025 23:38:11 +0530 Subject: [PATCH] feat(common): in app console UI enhancements (#5120) Co-authored-by: nivedin --- .../src/components/console/Item.vue | 6 +- .../src/components/console/Value.vue | 83 +++++++++++-------- 2 files changed, 51 insertions(+), 38 deletions(-) diff --git a/packages/hoppscotch-common/src/components/console/Item.vue b/packages/hoppscotch-common/src/components/console/Item.vue index 68e803d7..88c97878 100644 --- a/packages/hoppscotch-common/src/components/console/Item.vue +++ b/packages/hoppscotch-common/src/components/console/Item.vue @@ -3,10 +3,10 @@ class="flex items-start px-4 py-2 text-tiny text-secondaryDark rounded-md" :class="color" > - + -
-
{{ formattedTimestamp }}
+
+
{{ formattedTimestamp }}
-
+
{{ prettyStringified }}
+      v-else-if="parsedJSON"
+      class="overflow-auto max-h-96 p-4 bg-primary text-secondaryDark border !border-dividerLight rounded"
+      >{{ formattedJSONString }}
     
-
{{ formattedPrimitive }}
     
@@ -25,52 +27,51 @@ import { computed } from "vue" import VueJsonPretty from "vue-json-pretty" import "vue-json-pretty/lib/styles.css" +import { useColorMode } from "~/composables/theming" const props = defineProps<{ value: unknown }>() -const snippetColors = ` - border rounded-md bg-gray-50 text-black !border-gray-200 - dark:bg-gray-900 dark:text-gray-100 dark:!border-gray-700 -` +const theme = useColorMode() -const isObjectOrArray = computed(() => { - return typeof props.value === "object" && props.value !== null -}) +const isObjectOrArray = computed( + () => typeof props.value === "object" && props.value !== null +) + +const parsedJSON = computed(() => { + if (typeof props.value !== "string") { + return null + } -const isStringifiedObject = computed(() => { - if (typeof props.value !== "string") return false try { const parsed = JSON.parse(props.value) - return typeof parsed === "object" && parsed !== null + return typeof parsed === "object" && parsed !== null ? parsed : null } catch { - return false + return null } }) -const parsedValue = computed(() => { - if (isObjectOrArray.value) return props.value +const parsedValue = computed(() => + isObjectOrArray.value ? props.value : parsedJSON.value +) - if (isStringifiedObject.value && typeof props.value === "string") { - try { - return JSON.parse(props.value) - } catch { - return null - } +const formattedJSONString = computed(() => { + if (typeof props.value !== "string") { + return "" } - return null -}) + if (parsedJSON.value) { + // Return the original string if it looks already formatted + const hasNewlines = props.value.includes("\n") + const hasIndentation = props.value.match(/^\s{2,}["[{]/m) !== null -const prettyStringified = computed(() => { - if (typeof props.value === "string") { - try { - const parsed = JSON.parse(props.value) - return JSON.stringify(parsed, null, 2) - } catch { + if (hasNewlines || hasIndentation) { return props.value } + + return JSON.stringify(parsedJSON.value, null, 2) } - return "" + + return props.value }) const formattedPrimitive = computed(() => { @@ -98,4 +99,16 @@ const formattedPrimitive = computed(() => { return "[Unserializable]" } }) + +const isDarkTheme = computed(() => ["dark", "black"].includes(theme.value)) + +const treeViewTheme = computed(() => (isDarkTheme.value ? "dark" : "light")) + +