feat: persist line wrap setting (#3647)

Co-authored-by: jamesgeorge007 <jamesgeorge998001@gmail.com>
This commit is contained in:
Muhammed Ajmal M
2024-02-09 14:05:09 +05:30
committed by GitHub
parent 6a0e73fdec
commit 47226be6d0
21 changed files with 273 additions and 72 deletions

View File

@@ -22,9 +22,9 @@
<HoppButtonSecondary
v-tippy="{ theme: 'tooltip' }"
:title="t('state.linewrap')"
:class="{ '!text-accent': linewrapEnabled }"
:class="{ '!text-accent': WRAP_LINES }"
:icon="IconWrapText"
@click.prevent="linewrapEnabled = !linewrapEnabled"
@click.prevent="toggleNestedSetting('WRAP_LINES', 'cookie')"
/>
<HoppButtonSecondary
v-tippy="{ theme: 'tooltip', allowHTML: true }"
@@ -102,6 +102,8 @@ import {
useCopyResponse,
useDownloadResponse,
} from "~/composables/lens-actions"
import { useNestedSetting } from "~/composables/settings"
import { toggleNestedSetting } from "~/newstore/settings"
// TODO: Build Managed Mode!
@@ -122,7 +124,7 @@ const toast = useToast()
const cookieEditor = ref<HTMLElement>()
const rawCookieString = ref("")
const linewrapEnabled = ref(true)
const WRAP_LINES = useNestedSetting("WRAP_LINES", "cookie")
useCodemirror(
cookieEditor,
@@ -131,7 +133,7 @@ useCodemirror(
extendedEditorConfig: {
mode: "text/plain",
placeholder: `${t("cookies.modal.enter_cookie_string")}`,
lineWrapping: linewrapEnabled,
lineWrapping: WRAP_LINES,
},
linter: null,
completer: null,

View File

@@ -27,9 +27,9 @@
<HoppButtonSecondary
v-tippy="{ theme: 'tooltip' }"
:title="t('state.linewrap')"
:class="{ '!text-accent': linewrapEnabled }"
:class="{ '!text-accent': WRAP_LINES }"
:icon="IconWrapText"
@click.prevent="linewrapEnabled = !linewrapEnabled"
@click.prevent="toggleNestedSetting('WRAP_LINES', 'graphqlHeaders')"
/>
<HoppButtonSecondary
v-tippy="{ theme: 'tooltip' }"
@@ -315,6 +315,8 @@ import { commonHeaders } from "~/helpers/headers"
import { useCodemirror } from "@composables/codemirror"
import { objRemoveKey } from "~/helpers/functional/object"
import { useVModel } from "@vueuse/core"
import { useNestedSetting } from "~/composables/settings"
import { toggleNestedSetting } from "~/newstore/settings"
import { HoppGQLHeader } from "~/helpers/graphql"
import { throwError } from "~/helpers/functional/error"
import { HoppInheritedProperty } from "~/helpers/types/HoppInheritedProperties"
@@ -338,7 +340,7 @@ const request = useVModel(props, "modelValue", emit)
const idTicker = ref(0)
const linewrapEnabled = ref(false)
const WRAP_LINES = useNestedSetting("WRAP_LINES", "graphqlHeaders")
const bulkMode = ref(false)
const bulkHeaders = ref("")
@@ -353,7 +355,7 @@ useCodemirror(
extendedEditorConfig: {
mode: "text/x-yaml",
placeholder: `${t("state.bulk_mode_placeholder")}`,
lineWrapping: linewrapEnabled,
lineWrapping: WRAP_LINES,
},
linter: null,
completer: null,

View File

@@ -61,9 +61,9 @@
<HoppButtonSecondary
v-tippy="{ theme: 'tooltip' }"
:title="t('state.linewrap')"
:class="{ '!text-accent': linewrapEnabled }"
:class="{ '!text-accent': WRAP_LINES }"
:icon="IconWrapText"
@click.prevent="linewrapEnabled = !linewrapEnabled"
@click.prevent="toggleNestedSetting('WRAP_LINES', 'graphqlQuery')"
/>
<HoppButtonSecondary
v-tippy="{ theme: 'tooltip' }"
@@ -112,6 +112,8 @@ import {
socketDisconnect,
subscriptionState,
} from "~/helpers/graphql/connection"
import { useNestedSetting } from "~/composables/settings"
import { toggleNestedSetting } from "~/newstore/settings"
// Template refs
const queryEditor = ref<any | null>(null)
@@ -137,7 +139,7 @@ const prettifyQueryIcon = refAutoReset<
typeof IconWand | typeof IconCheck | typeof IconInfo
>(IconWand, 1000)
const linewrapEnabled = ref(true)
const WRAP_LINES = useNestedSetting("WRAP_LINES", "graphqlQuery")
const selectedOperation = ref<gql.OperationDefinitionNode | null>(null)
@@ -184,7 +186,7 @@ useCodemirror(
extendedEditorConfig: {
mode: "graphql",
placeholder: `${t("request.query")}`,
lineWrapping: linewrapEnabled,
lineWrapping: WRAP_LINES,
},
linter: createGQLQueryLinter(schema),
completer: queryCompleter(schema),

View File

@@ -16,9 +16,11 @@
<HoppButtonSecondary
v-tippy="{ theme: 'tooltip' }"
:title="t('state.linewrap')"
:class="{ '!text-accent': linewrapEnabled }"
:class="{ '!text-accent': WRAP_LINES }"
:icon="IconWrapText"
@click.prevent="linewrapEnabled = !linewrapEnabled"
@click.prevent="
toggleNestedSetting('WRAP_LINES', 'graphqlResponseBody')
"
/>
<HoppButtonSecondary
v-tippy="{ theme: 'tooltip', allowHTML: true }"
@@ -99,6 +101,8 @@ import { useI18n } from "@composables/i18n"
import { defineActionHandler } from "~/helpers/actions"
import { getPlatformSpecialKey as getSpecialKey } from "~/helpers/platformutils"
import { GQLResponseEvent } from "~/helpers/graphql/connection"
import { useNestedSetting } from "~/composables/settings"
import { toggleNestedSetting } from "~/newstore/settings"
import interfaceLanguages from "~/helpers/utils/interfaceLanguages"
import {
useCopyInterface,
@@ -133,8 +137,8 @@ const responseString = computed(() => {
})
const schemaEditor = ref<any | null>(null)
const WRAP_LINES = useNestedSetting("WRAP_LINES", "graphqlResponseBody")
const copyInterfaceTippyActions = ref<any | null>(null)
const linewrapEnabled = ref(true)
useCodemirror(
schemaEditor,
@@ -143,7 +147,7 @@ useCodemirror(
extendedEditorConfig: {
mode: "application/ld+json",
readOnly: true,
lineWrapping: linewrapEnabled,
lineWrapping: WRAP_LINES,
},
linter: null,
completer: null,

View File

@@ -127,9 +127,9 @@
<HoppButtonSecondary
v-tippy="{ theme: 'tooltip' }"
:title="t('state.linewrap')"
:class="{ '!text-accent': linewrapEnabled }"
:class="{ '!text-accent': WRAP_LINES }"
:icon="IconWrapText"
@click.prevent="linewrapEnabled = !linewrapEnabled"
@click.prevent="toggleNestedSetting('WRAP_LINES', 'graphqlSchema')"
/>
<HoppButtonSecondary
v-tippy="{ theme: 'tooltip' }"
@@ -202,6 +202,8 @@ import {
subscriptionFields,
} from "~/helpers/graphql/connection"
import { platform } from "~/platform"
import { useNestedSetting } from "~/composables/settings"
import { toggleNestedSetting } from "~/newstore/settings"
type NavigationTabs = "history" | "collection" | "docs" | "schema"
type GqlTabs = "queries" | "mutations" | "subscriptions" | "types"
@@ -349,7 +351,7 @@ const handleJumpToType = async (type: GraphQLType) => {
}
const schemaEditor = ref<any | null>(null)
const linewrapEnabled = ref(true)
const WRAP_LINES = useNestedSetting("WRAP_LINES", "graphqlSchema")
useCodemirror(
schemaEditor,
@@ -358,7 +360,7 @@ useCodemirror(
extendedEditorConfig: {
mode: "graphql",
readOnly: true,
lineWrapping: linewrapEnabled,
lineWrapping: WRAP_LINES,
},
linter: null,
completer: null,

View File

@@ -49,9 +49,9 @@
<HoppButtonSecondary
v-tippy="{ theme: 'tooltip' }"
:title="t('state.linewrap')"
:class="{ '!text-accent': linewrapEnabled }"
:class="{ '!text-accent': WRAP_LINES }"
:icon="IconWrapText"
@click.prevent="linewrapEnabled = !linewrapEnabled"
@click.prevent="toggleNestedSetting('WRAP_LINES', 'graphqlVariables')"
/>
<HoppButtonSecondary
v-tippy="{ theme: 'tooltip' }"
@@ -93,6 +93,8 @@ import {
socketDisconnect,
subscriptionState,
} from "~/helpers/graphql/connection"
import { useNestedSetting } from "~/composables/settings"
import { toggleNestedSetting } from "~/newstore/settings"
const t = useI18n()
const toast = useToast()
@@ -114,7 +116,7 @@ const variableString = useVModel(props, "modelValue", emit)
const variableEditor = ref<any | null>(null)
const linewrapEnabled = ref(false)
const WRAP_LINES = useNestedSetting("WRAP_LINES", "graphqlVariables")
const copyVariablesIcon = refAutoReset<typeof IconCopy | typeof IconCheck>(
IconCopy,
@@ -131,7 +133,7 @@ useCodemirror(
extendedEditorConfig: {
mode: "application/ld+json",
placeholder: `${t("request.variables")}`,
lineWrapping: linewrapEnabled,
lineWrapping: WRAP_LINES,
},
linter: computed(() =>
variableString.value.length > 0 ? jsonLinter : null

View File

@@ -86,9 +86,9 @@
<HoppButtonSecondary
v-tippy="{ theme: 'tooltip' }"
:title="t('state.linewrap')"
:class="{ '!text-accent': linewrapEnabled }"
:class="{ '!text-accent': WRAP_LINES }"
:icon="IconWrapText"
@click.prevent="linewrapEnabled = !linewrapEnabled"
@click.prevent="toggleNestedSetting('WRAP_LINES', 'codeGen')"
/>
<HoppButtonSecondary
v-tippy="{ theme: 'tooltip', allowHTML: true }"
@@ -161,6 +161,8 @@ import cloneDeep from "lodash-es/cloneDeep"
import { platform } from "~/platform"
import { RESTTabService } from "~/services/tab/rest"
import { useService } from "dioc/vue"
import { useNestedSetting } from "~/composables/settings"
import { toggleNestedSetting } from "~/newstore/settings"
const t = useI18n()
@@ -224,7 +226,7 @@ const requestCode = computed(() => {
// Template refs
const tippyActions = ref<any | null>(null)
const generatedCode = ref<any | null>(null)
const linewrapEnabled = ref(true)
const WRAP_LINES = useNestedSetting("WRAP_LINES", "codeGen")
useCodemirror(
generatedCode,
@@ -233,7 +235,7 @@ useCodemirror(
extendedEditorConfig: {
mode: "text/plain",
readOnly: true,
lineWrapping: linewrapEnabled,
lineWrapping: WRAP_LINES,
},
linter: null,
completer: null,

View File

@@ -29,9 +29,9 @@
v-if="bulkMode"
v-tippy="{ theme: 'tooltip' }"
:title="t('state.linewrap')"
:class="{ '!text-accent': linewrapEnabled }"
:class="{ '!text-accent': WRAP_LINES }"
:icon="IconWrapText"
@click.prevent="linewrapEnabled = !linewrapEnabled"
@click.prevent="toggleNestedSetting('WRAP_LINES', 'httpHeaders')"
/>
<HoppButtonSecondary
v-tippy="{ theme: 'tooltip' }"
@@ -332,6 +332,9 @@ import { useVModel } from "@vueuse/core"
import { useService } from "dioc/vue"
import { InspectionService, InspectorResult } from "~/services/inspection"
import { RESTTabService } from "~/services/tab/rest"
import { toggleSetting } from "~/newstore/settings"
import { useNestedSetting } from "~/composables/settings"
import { toggleNestedSetting } from "~/newstore/settings"
import { HoppInheritedProperty } from "~/helpers/types/HoppInheritedProperties"
const t = useI18n()
@@ -346,7 +349,7 @@ const idTicker = ref(0)
const bulkMode = ref(false)
const bulkHeaders = ref("")
const bulkEditor = ref<any | null>(null)
const linewrapEnabled = ref(true)
const WRAP_LINES = useNestedSetting("WRAP_LINES", "httpHeaders")
const deletionToast = ref<{ goAway: (delay: number) => void } | null>(null)
@@ -371,7 +374,7 @@ useCodemirror(
extendedEditorConfig: {
mode: "text/x-yaml",
placeholder: `${t("state.bulk_mode_placeholder")}`,
lineWrapping: linewrapEnabled,
lineWrapping: WRAP_LINES,
},
linter,
completer: null,

View File

@@ -22,9 +22,9 @@
<HoppButtonSecondary
v-tippy="{ theme: 'tooltip' }"
:title="t('state.linewrap')"
:class="{ '!text-accent': linewrapEnabled }"
:class="{ '!text-accent': WRAP_LINES }"
:icon="IconWrapText"
@click.prevent="linewrapEnabled = !linewrapEnabled"
@click.prevent="toggleNestedSetting('WRAP_LINES', 'importCurl')"
/>
<HoppButtonSecondary
v-tippy="{ theme: 'tooltip', allowHTML: true }"
@@ -96,6 +96,8 @@ import IconTrash2 from "~icons/lucide/trash-2"
import { platform } from "~/platform"
import { RESTTabService } from "~/services/tab/rest"
import { useService } from "dioc/vue"
import { useNestedSetting } from "~/composables/settings"
import { toggleNestedSetting } from "~/newstore/settings"
const t = useI18n()
@@ -106,7 +108,7 @@ const tabs = useService(RESTTabService)
const curl = ref("")
const curlEditor = ref<any | null>(null)
const linewrapEnabled = ref(true)
const WRAP_LINES = useNestedSetting("WRAP_LINES", "importCurl")
const props = defineProps<{ show: boolean; text: string }>()
@@ -117,7 +119,7 @@ useCodemirror(
extendedEditorConfig: {
mode: "application/x-sh",
placeholder: `${t("request.enter_curl")}`,
lineWrapping: linewrapEnabled,
lineWrapping: WRAP_LINES,
},
linter: null,
completer: null,

View File

@@ -24,9 +24,9 @@
v-if="bulkMode"
v-tippy="{ theme: 'tooltip' }"
:title="t('state.linewrap')"
:class="{ '!text-accent': linewrapEnabled }"
:class="{ '!text-accent': WRAP_LINES }"
:icon="IconWrapText"
@click.prevent="linewrapEnabled = !linewrapEnabled"
@click.prevent="toggleNestedSetting('WRAP_LINES', 'httpParams')"
/>
<HoppButtonSecondary
v-tippy="{ theme: 'tooltip' }"
@@ -205,6 +205,8 @@ import { useVModel } from "@vueuse/core"
import { useService } from "dioc/vue"
import { InspectionService, InspectorResult } from "~/services/inspection"
import { RESTTabService } from "~/services/tab/rest"
import { useNestedSetting } from "~/composables/settings"
import { toggleNestedSetting } from "~/newstore/settings"
const colorMode = useColorMode()
@@ -217,7 +219,7 @@ const idTicker = ref(0)
const bulkMode = ref(false)
const bulkParams = ref("")
const bulkEditor = ref<any | null>(null)
const linewrapEnabled = ref(true)
const WRAP_LINES = useNestedSetting("WRAP_LINES", "httpParams")
const deletionToast = ref<{ goAway: (delay: number) => void } | null>(null)
@@ -228,7 +230,7 @@ useCodemirror(
extendedEditorConfig: {
mode: "text/x-yaml",
placeholder: `${t("state.bulk_mode_placeholder")}`,
lineWrapping: linewrapEnabled,
lineWrapping: WRAP_LINES,
},
linter,
completer: null,

View File

@@ -23,9 +23,9 @@
<HoppButtonSecondary
v-tippy="{ theme: 'tooltip' }"
:title="t('state.linewrap')"
:class="{ '!text-accent': linewrapEnabled }"
:class="{ '!text-accent': WRAP_LINES }"
:icon="IconWrapText"
@click.prevent="linewrapEnabled = !linewrapEnabled"
@click.prevent="toggleNestedSetting('WRAP_LINES', 'httpPreRequest')"
/>
</div>
</div>
@@ -72,6 +72,8 @@ import linter from "~/helpers/editor/linting/preRequest"
import completer from "~/helpers/editor/completion/preRequest"
import { useI18n } from "@composables/i18n"
import { useVModel } from "@vueuse/core"
import { useNestedSetting } from "~/composables/settings"
import { toggleNestedSetting } from "~/newstore/settings"
const t = useI18n()
@@ -85,7 +87,7 @@ const emit = defineEmits<{
const preRequestScript = useVModel(props, "modelValue", emit)
const preRequestEditor = ref<any | null>(null)
const linewrapEnabled = ref(true)
const WRAP_LINES = useNestedSetting("WRAP_LINES", "httpPreRequest")
useCodemirror(
preRequestEditor,
@@ -93,7 +95,7 @@ useCodemirror(
reactive({
extendedEditorConfig: {
mode: "application/javascript",
lineWrapping: linewrapEnabled,
lineWrapping: WRAP_LINES,
placeholder: `${t("preRequest.javascript_code")}`,
},
linter,

View File

@@ -23,9 +23,9 @@
<HoppButtonSecondary
v-tippy="{ theme: 'tooltip' }"
:title="t('state.linewrap')"
:class="{ '!text-accent': linewrapEnabled }"
:class="{ '!text-accent': WRAP_LINES }"
:icon="IconWrapText"
@click.prevent="linewrapEnabled = !linewrapEnabled"
@click.prevent="toggleNestedSetting('WRAP_LINES', 'httpRequestBody')"
/>
<HoppButtonSecondary
v-if="
@@ -85,6 +85,8 @@ import { isJSONContentType } from "~/helpers/utils/contenttypes"
import jsonLinter from "~/helpers/editor/linting/json"
import { readFileAsText } from "~/helpers/functional/files"
import xmlFormat from "xml-formatter"
import { useNestedSetting } from "~/composables/settings"
import { toggleNestedSetting } from "~/newstore/settings"
type PossibleContentTypes = Exclude<
ValidContentTypes,
@@ -122,7 +124,7 @@ const langLinter = computed(() =>
isJSONContentType(body.value.contentType) ? jsonLinter : null
)
const linewrapEnabled = ref(true)
const WRAP_LINES = useNestedSetting("WRAP_LINES", "httpRequestBody")
const rawBodyParameters = ref<any | null>(null)
const codemirrorValue: Ref<string | undefined> =
@@ -148,7 +150,7 @@ useCodemirror(
codemirrorValue,
reactive({
extendedEditorConfig: {
lineWrapping: linewrapEnabled,
lineWrapping: WRAP_LINES,
mode: rawInputEditorLang,
placeholder: t("request.raw_body").toString(),
},

View File

@@ -23,9 +23,9 @@
<HoppButtonSecondary
v-tippy="{ theme: 'tooltip' }"
:title="t('state.linewrap')"
:class="{ '!text-accent': linewrapEnabled }"
:class="{ '!text-accent': WRAP_LINES }"
:icon="IconWrapText"
@click.prevent="linewrapEnabled = !linewrapEnabled"
@click.prevent="toggleNestedSetting('WRAP_LINES', 'httpTest')"
/>
</div>
</div>
@@ -72,6 +72,8 @@ import linter from "~/helpers/editor/linting/testScript"
import completer from "~/helpers/editor/completion/testScript"
import { useI18n } from "@composables/i18n"
import { useVModel } from "@vueuse/core"
import { useNestedSetting } from "~/composables/settings"
import { toggleNestedSetting } from "~/newstore/settings"
const t = useI18n()
@@ -81,7 +83,7 @@ const props = defineProps<{
const emit = defineEmits(["update:modelValue"])
const testScript = useVModel(props, "modelValue", emit)
const testScriptEditor = ref<any | null>(null)
const linewrapEnabled = ref(true)
const WRAP_LINES = useNestedSetting("WRAP_LINES", "httpTest")
useCodemirror(
testScriptEditor,
@@ -89,7 +91,7 @@ useCodemirror(
reactive({
extendedEditorConfig: {
mode: "application/javascript",
lineWrapping: linewrapEnabled,
lineWrapping: WRAP_LINES,
placeholder: `${t("test.javascript_code")}`,
},
linter,

View File

@@ -24,9 +24,9 @@
v-if="bulkMode"
v-tippy="{ theme: 'tooltip' }"
:title="t('state.linewrap')"
:class="{ '!text-accent': linewrapEnabled }"
:class="{ '!text-accent': WRAP_LINES }"
:icon="IconWrapText"
@click.prevent="linewrapEnabled = !linewrapEnabled"
@click.prevent="toggleNestedSetting('WRAP_LINES', 'httpUrlEncoded')"
/>
<HoppButtonSecondary
v-tippy="{ theme: 'tooltip' }"
@@ -196,6 +196,8 @@ import { useColorMode } from "@composables/theming"
import { objRemoveKey } from "~/helpers/functional/object"
import { throwError } from "~/helpers/functional/error"
import { useVModel } from "@vueuse/core"
import { useNestedSetting } from "~/composables/settings"
import { toggleNestedSetting } from "~/newstore/settings"
type Body = HoppRESTReqBody & {
contentType: "application/x-www-form-urlencoded"
@@ -220,7 +222,7 @@ const idTicker = ref(0)
const bulkMode = ref(false)
const bulkUrlEncodedParams = ref("")
const bulkEditor = ref<any | null>(null)
const linewrapEnabled = ref(true)
const WRAP_LINES = useNestedSetting("WRAP_LINES", "httpUrlEncoded")
const deletionToast = ref<{ goAway: (delay: number) => void } | null>(null)
@@ -231,7 +233,7 @@ useCodemirror(
extendedEditorConfig: {
mode: "text/x-yaml",
placeholder: `${t("state.bulk_mode_placeholder")}`,
lineWrapping: linewrapEnabled,
lineWrapping: WRAP_LINES,
},
linter,
completer: null,

View File

@@ -11,9 +11,9 @@
v-if="response.body"
v-tippy="{ theme: 'tooltip' }"
:title="t('state.linewrap')"
:class="{ '!text-accent': linewrapEnabled }"
:class="{ '!text-accent': WRAP_LINES }"
:icon="IconWrapText"
@click.prevent="linewrapEnabled = !linewrapEnabled"
@click.prevent="toggleNestedSetting('WRAP_LINES', 'httpResponseBody')"
/>
<HoppButtonSecondary
v-if="response.body"
@@ -76,6 +76,8 @@ import { useI18n } from "@composables/i18n"
import type { HoppRESTResponse } from "~/helpers/types/HoppRESTResponse"
import { defineActionHandler } from "~/helpers/actions"
import { getPlatformSpecialKey as getSpecialKey } from "~/helpers/platformutils"
import { useNestedSetting } from "~/composables/settings"
import { toggleNestedSetting } from "~/newstore/settings"
const t = useI18n()
@@ -84,7 +86,7 @@ const props = defineProps<{
}>()
const htmlResponse = ref<any | null>(null)
const linewrapEnabled = ref(true)
const WRAP_LINES = useNestedSetting("WRAP_LINES", "httpResponseBody")
const { responseBodyText } = useResponseBody(props.response)
const { downloadIcon, downloadResponse } = useDownloadResponse(
@@ -104,7 +106,7 @@ useCodemirror(
extendedEditorConfig: {
mode: "htmlmixed",
readOnly: true,
lineWrapping: linewrapEnabled,
lineWrapping: WRAP_LINES,
},
linter: null,
completer: null,

View File

@@ -14,9 +14,9 @@
v-if="response.body"
v-tippy="{ theme: 'tooltip' }"
:title="t('state.linewrap')"
:class="{ '!text-accent': linewrapEnabled }"
:class="{ '!text-accent': WRAP_LINES }"
:icon="IconWrapText"
@click.prevent="linewrapEnabled = !linewrapEnabled"
@click.prevent="toggleNestedSetting('WRAP_LINES', 'httpResponseBody')"
/>
<HoppButtonSecondary
v-if="response.body"
@@ -260,6 +260,8 @@ import {
} from "@composables/lens-actions"
import { defineActionHandler } from "~/helpers/actions"
import { getPlatformSpecialKey as getSpecialKey } from "~/helpers/platformutils"
import { useNestedSetting } from "~/composables/settings"
import { toggleNestedSetting } from "~/newstore/settings"
import interfaceLanguages from "~/helpers/utils/interfaceLanguages"
const t = useI18n()
@@ -371,8 +373,8 @@ const { downloadIcon, downloadResponse } = useDownloadResponse(
// Template refs
const tippyActions = ref<any | null>(null)
const jsonResponse = ref<any | null>(null)
const WRAP_LINES = useNestedSetting("WRAP_LINES", "httpResponseBody")
const copyInterfaceTippyActions = ref<any | null>(null)
const linewrapEnabled = ref(true)
const { cursor } = useCodemirror(
jsonResponse,
@@ -381,7 +383,7 @@ const { cursor } = useCodemirror(
extendedEditorConfig: {
mode: "application/ld+json",
readOnly: true,
lineWrapping: linewrapEnabled,
lineWrapping: WRAP_LINES,
},
linter: null,
completer: null,

View File

@@ -11,9 +11,9 @@
v-if="response.body"
v-tippy="{ theme: 'tooltip' }"
:title="t('state.linewrap')"
:class="{ '!text-accent': linewrapEnabled }"
:class="{ '!text-accent': WRAP_LINES }"
:icon="IconWrapText"
@click.prevent="linewrapEnabled = !linewrapEnabled"
@click.prevent="toggleNestedSetting('WRAP_LINES', 'httpResponseBody')"
/>
<HoppButtonSecondary
v-if="response.body"
@@ -58,6 +58,8 @@ import {
import { objFieldMatches } from "~/helpers/functional/object"
import { defineActionHandler } from "~/helpers/actions"
import { getPlatformSpecialKey as getSpecialKey } from "~/helpers/platformutils"
import { useNestedSetting } from "~/composables/settings"
import { toggleNestedSetting } from "~/newstore/settings"
const t = useI18n()
@@ -97,7 +99,7 @@ const { downloadIcon, downloadResponse } = useDownloadResponse(
const { copyIcon, copyResponse } = useCopyResponse(responseBodyText)
const rawResponse = ref<any | null>(null)
const linewrapEnabled = ref(true)
const WRAP_LINES = useNestedSetting("WRAP_LINES", "httpResponseBody")
useCodemirror(
rawResponse,
@@ -106,7 +108,7 @@ useCodemirror(
extendedEditorConfig: {
mode: "text/plain",
readOnly: true,
lineWrapping: linewrapEnabled,
lineWrapping: WRAP_LINES,
},
linter: null,
completer: null,

View File

@@ -11,9 +11,9 @@
v-if="response.body"
v-tippy="{ theme: 'tooltip' }"
:title="t('state.linewrap')"
:class="{ '!text-accent': linewrapEnabled }"
:class="{ '!text-accent': WRAP_LINES }"
:icon="IconWrapText"
@click.prevent="linewrapEnabled = !linewrapEnabled"
@click.prevent="toggleNestedSetting('WRAP_LINES', 'httpResponseBody')"
/>
<HoppButtonSecondary
v-if="response.body"
@@ -58,6 +58,8 @@ import {
import { defineActionHandler } from "~/helpers/actions"
import { getPlatformSpecialKey as getSpecialKey } from "~/helpers/platformutils"
import { objFieldMatches } from "~/helpers/functional/object"
import { useNestedSetting } from "~/composables/settings"
import { toggleNestedSetting } from "~/newstore/settings"
const t = useI18n()
@@ -91,7 +93,7 @@ const { downloadIcon, downloadResponse } = useDownloadResponse(
const { copyIcon, copyResponse } = useCopyResponse(responseBodyText)
const xmlResponse = ref<any | null>(null)
const linewrapEnabled = ref(true)
const WRAP_LINES = useNestedSetting("WRAP_LINES", "httpResponseBody")
useCodemirror(
xmlResponse,
@@ -100,7 +102,7 @@ useCodemirror(
extendedEditorConfig: {
mode: "application/xml",
readOnly: true,
lineWrapping: linewrapEnabled,
lineWrapping: WRAP_LINES,
},
linter: null,
completer: null,

View File

@@ -13,7 +13,36 @@ export function useSetting<K extends keyof SettingsDef>(
settingsStore.dispatch({
dispatcher: "applySetting",
payload: {
// @ts-expect-error TS is not able to understand the type semantics here
settingKey,
// @ts-expect-error TS is not able to understand the type semantics here
value,
},
})
}
)
}
export function useNestedSetting<
K extends keyof SettingsDef,
P extends keyof SettingsDef[K],
>(settingKey: K, property: P): Ref<SettingsDef[K][P]> {
return useStream(
settingsStore.subject$.pipe(
pluck(settingKey),
pluck(property),
distinctUntilChanged()
),
settingsStore.value[settingKey][property],
(value: SettingsDef[K][P]) => {
settingsStore.dispatch({
dispatcher: "applyNestedSetting",
payload: {
// @ts-expect-error TS is not able to understand the type semantics here
settingKey,
// @ts-expect-error TS is not able to understand the type semantics here
property,
// @ts-expect-error TS is not able to understand the type semantics here
value,
},
})
@@ -35,7 +64,9 @@ export function useSettingStatic<K extends keyof SettingsDef>(
settingsStore.dispatch({
dispatcher: "applySetting",
payload: {
// @ts-expect-error TS is not able to understand the type semantics here
settingKey,
// @ts-expect-error TS is not able to understand the type semantics here
value,
},
})

View File

@@ -30,6 +30,24 @@ export type SettingsDef = {
PROXY_URL: string
WRAP_LINES: {
httpRequestBody: boolean
httpResponseBody: boolean
httpHeaders: boolean
httpParams: boolean
httpUrlEncoded: boolean
httpPreRequest: boolean
httpTest: boolean
graphqlQuery: boolean
graphqlResponseBody: boolean
graphqlHeaders: boolean
graphqlVariables: boolean
graphqlSchema: boolean
importCurl: boolean
codeGen: boolean
cookie: boolean
}
CURRENT_INTERCEPTOR_ID: string
URL_EXCLUDES: {
@@ -53,6 +71,24 @@ export const getDefaultSettings = (): SettingsDef => ({
syncHistory: true,
syncEnvironments: true,
WRAP_LINES: {
httpRequestBody: true,
httpResponseBody: true,
httpHeaders: true,
httpParams: true,
httpUrlEncoded: true,
httpPreRequest: true,
httpTest: true,
graphqlQuery: true,
graphqlResponseBody: true,
graphqlHeaders: false,
graphqlVariables: false,
graphqlSchema: true,
importCurl: true,
codeGen: true,
cookie: true,
},
CURRENT_INTERCEPTOR_ID: "browser", // TODO: Allow the platform definition to take this place
// TODO: Interceptor related settings should move under the interceptor systems
@@ -80,6 +116,16 @@ type ApplySettingPayload = {
}
}[keyof SettingsDef]
type ApplyNestedSettingPayload = {
[K in KeysMatching<SettingsDef, Record<string, any>>]: {
[P in keyof SettingsDef[K]]: {
settingKey: K
property: P
value: SettingsDef[K][P]
}
}[keyof SettingsDef[K]]
}[KeysMatching<SettingsDef, Record<string, any>>]
const dispatchers = defineDispatchers({
bulkApplySettings(_currentState: SettingsDef, payload: Partial<SettingsDef>) {
return payload
@@ -100,6 +146,29 @@ const dispatchers = defineDispatchers({
return result
},
toggleNestedSetting(
currentState: SettingsDef,
{
settingKey,
property,
}: {
settingKey: KeysMatching<SettingsDef, Record<string, boolean>>
property: KeysMatching<SettingsDef[typeof settingKey], boolean>
}
) {
if (!has(currentState, [settingKey, property])) {
return {}
}
const result: Partial<SettingsDef> = {
[settingKey]: {
...currentState[settingKey],
[property]: !currentState[settingKey][property],
},
}
return result
},
applySetting(
_currentState: SettingsDef,
{ settingKey, value }: ApplySettingPayload
@@ -108,6 +177,18 @@ const dispatchers = defineDispatchers({
[settingKey]: value,
}
return result
},
applyNestedSetting(
_currentState: SettingsDef,
{ settingKey, property, value }: ApplyNestedSettingPayload
) {
const result: Partial<SettingsDef> = {
[settingKey]: {
[property]: value,
},
}
return result
},
})
@@ -144,6 +225,20 @@ export function toggleSetting(settingKey: KeysMatching<SettingsDef, boolean>) {
})
}
export function toggleNestedSetting<
K extends KeysMatching<SettingsDef, Record<string, boolean>>,
P extends keyof SettingsDef[K],
>(settingKey: K, property: P) {
settingsStore.dispatch({
dispatcher: "toggleNestedSetting",
payload: {
settingKey,
// @ts-expect-error TS is not able to understand the type semantics here
property,
},
})
}
export function applySetting<K extends keyof SettingsDef>(
settingKey: K,
value: SettingsDef[K]
@@ -159,6 +254,22 @@ export function applySetting<K extends keyof SettingsDef>(
})
}
export function applyNestedSetting<
K extends KeysMatching<SettingsDef, Record<string, any>>,
P extends keyof SettingsDef[K],
R extends SettingsDef[K][P],
>(settingKey: K, property: P, value: R) {
settingsStore.dispatch({
dispatcher: "applyNestedSetting",
payload: {
settingKey,
// @ts-expect-error TS is not able to understand the type semantics here
property,
value,
},
})
}
export function performSettingsDataMigrations(data: any): SettingsDef {
const source = cloneDeep(data)

View File

@@ -45,6 +45,26 @@ const SettingsDefSchema = z.object({
SIDEBAR: z.boolean(),
SIDEBAR_ON_LEFT: z.boolean(),
COLUMN_LAYOUT: z.boolean(),
WRAP_LINES: z.optional(
z.object({
httpRequestBody: z.boolean(),
httpResponseBody: z.boolean(),
httpHeaders: z.boolean(),
httpParams: z.boolean(),
httpUrlEncoded: z.boolean(),
httpPreRequest: z.boolean(),
httpTest: z.boolean(),
graphqlQuery: z.boolean(),
graphqlResponseBody: z.boolean(),
graphqlHeaders: z.boolean(),
graphqlVariables: z.boolean(),
graphqlSchema: z.boolean(),
importCurl: z.boolean(),
codeGen: z.boolean(),
cookie: z.boolean(),
})
),
})
// Common properties shared across REST & GQL collections